meridian59/include/roomtype.h
David Klawitter 894bd15267
feat: Add point-in-sector utility to check for presence in room sectors (#1189)
This PR adds a new `IsPointInSector` function that lets you check if a
specific point (by coordinates) is inside one or more sectors in a room.
The function takes an array of IDs (sometimes called server IDs), so you
can check multiple sectors at once. The main reason for adding this is
to help catch players who hang around too long in guild hall door
sectors, but it’s flexible enough to be useful in other situations too.

### Sector Geometry Loading on Startup
When the server starts up, it loads sector geometry from the room files.
Each sector’s polygons get stored as arrays of vertex coordinates.

### IsPointInSector Coordinate Lookup Process
`IsPointInSector` converts Blakod coordinates to fine coordinates, grabs
the room data, and loops through the sectors. It looks for sectors with
IDs matching any of the provided user IDs, and for each match, uses
ray-casting to see if the point is inside the sector’s polygon.

### Memory Usage Changes
**BEFORE:**
Memory Allocated: 30096561 bytes

**AFTER:**
Memory Allocated: 34324621 bytes

**DIFFERENCE:** 4,228,060 bytes / 4.22806 Megabytes

### Example: Guild Hall 11 (`guildh11`) (removed)
As a demo, I’ve updated `ghall.kod` and `guildh11.kod` to use this new
function. To try it out: open the hall’s entrance door and stand in
either of the two door sectors. Let the door close, and after a short
delay, you’ll be teleported to the foyer. Modify `plDoorSectors` to test
other scenarios, like an invalid sector id or a single integer:

```
plDoorSectors = [ MAINDOOR, MAINDOOR2 ]; // original
plDoorSectors = MAINDOOR; // single sector check
plDoorSectors = [ MAINDOOR, MAINDOOR2, "foo" ]; // invalid sector id, should still work
```

### Usage Examples
A single usage example was originally included included but removed in
favor of a follow-up PR. The following is an example of how this could
be used, though there's a bit more work needed to support it that can be
seen in
https://github.com/Meridian59/Meridian59/pull/1189/changes/a936b59e0027042d3d2fb2f92a75287cb9fb4809

```
// Check single user ID
if IsPointInSector(prmRoom, 
    Send(who,@GetRow), 
    Send(who,@GetCol), 
    Send(who,@GetFineRow), 
    Send(who,@GetFineCol), 
    DOOR_SECTOR_ID) 
{
    // Point is in sector for this user
}
```
2026-01-22 11:20:20 -08:00

50 lines
1.6 KiB
C++

// Meridian 59, Copyright 1994-2012 Andrew Kirmse and Chris Kirmse.
// All rights reserved.
//
// This software is distributed under a license that is described in
// the LICENSE file that accompanies it.
//
// Meridian is a registered trademark.
/*
* roomtype.h:
*/
#ifndef _ROOMTYPE_H
#define _ROOMTYPE_H
#include <vector>
struct server_polygon {
int num_vertices;
int *vertices_x;
int *vertices_y;
};
// Stores polygon data for a single sector
struct server_sector
{
int id; // server id of the sector
std::vector<server_polygon> polygons; // array of sector polygons
};
/* Room contents to draw */
typedef struct
{
short rows; /* Size of room in grid squares */
short cols;
int width, height; /* Size of room in FINENESS units */
unsigned char **grid; /* Array that tells whether its legal to move between adjacent squares
* (used only in server) */
unsigned char **flags; /* Array that gives per-square flags
* (used only in server) */
unsigned char **monster_grid; /* Array that tells whether its legal for monsters to move between adjacent squares (used only in server) */
int bkgnd; /* Resource ID of background bitmap; 0 if none */
unsigned char ambient_light; /* Intensity of ambient light, 0 = min, 15 = max */
int security; /* Security number, unique to each roo file, to ensure that client
loads the correct roo file */
std::vector<server_sector> sectors;
} room_type;
#endif /* #ifndef _ROOMTYPE_H */