bool MapObjectIsTileOKStrict( const MapObject *obj, const unsigned short tile, const bool isEmpty, const unsigned short tileAbove, const unsigned short tileBelow, const int numWallsAdjacent, const int numWallsAround) { if (!MapObjectIsTileOK(obj, tile, isEmpty, tileAbove)) { return 0; } unsigned short tileAccess = tile & MAP_MASKACCESS; if (tile & MAP_LEAVEFREE) { return 0; } if (obj->Flags & (1 << PLACEMENT_OUTSIDE) && tileAccess == MAP_ROOM) { return false; } if ((obj->Flags & (1 << PLACEMENT_INSIDE)) && tileAccess != MAP_ROOM) { return false; } if ((obj->Flags & (1 << PLACEMENT_NO_WALLS)) && numWallsAround != 0) { return false; } if ((obj->Flags & (1 << PLACEMENT_ONE_WALL)) && numWallsAdjacent != 1) { return false; } if ((obj->Flags & (1 << PLACEMENT_ONE_OR_MORE_WALLS)) && numWallsAdjacent < 1) { return false; } if ((obj->Flags & (1 << PLACEMENT_FREE_IN_FRONT)) && (tileBelow & MAP_MASKACCESS) != MAP_FLOOR && (tileBelow & MAP_MASKACCESS) != MAP_SQUARE && (tileBelow & MAP_MASKACCESS) != MAP_ROOM) { return false; } return true; }
static bool TryAddMapObject( Mission *m, const MapObject *mo, const Vec2i pos, CArray *objs) { CASSERT(m->Type == MAPTYPE_STATIC, "invalid map type"); const unsigned short tile = MissionGetTile(m, pos); // Remove any items already there TryRemoveMapObjectAt(pos, objs); if (MapObjectIsTileOK( mo, tile, 1, MissionGetTile(m, Vec2iNew(pos.x, pos.y - 1)))) { // Check if the item already has an entry, and add to its list // of positions bool hasAdded = false; for (int i = 0; i < (int)objs->size; i++) { MapObjectPositions *mop = CArrayGet(objs, i); if (mop->M == mo) { CArrayPushBack(&mop->Positions, &pos); hasAdded = true; break; } } // If not, create a new entry if (!hasAdded) { MapObjectPositions mop; mop.M = mo; CArrayInit(&mop.Positions, sizeof(Vec2i)); CArrayPushBack(&mop.Positions, &pos); CArrayPushBack(objs, &mop); } return true; } return false; }