static uint32 RailTypeGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { TileIndex tile = object->u.routes.tile; if (tile == INVALID_TILE) { switch (variable) { case 0x40: return 0; case 0x41: return 0; case 0x42: return 0; case 0x43: return _date; } } switch (variable) { case 0x40: return GetTerrainType(tile, object->u.routes.context); case 0x41: return 0; case 0x42: return IsLevelCrossingTile(tile) && IsCrossingBarred(tile); case 0x43: if (IsRailDepotTile(tile)) return Depot::GetByTile(tile)->build_date; return _date; } DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable); *available = false; return UINT_MAX; }
static uint32 CanalGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { TileIndex tile = object->u.canal.tile; switch (variable) { /* Height of tile */ case 0x80: { uint z = GetTileZ(tile) / TILE_HEIGHT; /* Return consistent height within locks */ if (IsTileType(tile, MP_WATER) && IsLock(tile) && GetSection(tile) >= 8) z--; return z; } /* Terrain type */ case 0x81: return GetTerrainType(tile); /* Random data for river or canal tiles, otherwise zero */ case 0x83: return IsTileType(tile, MP_WATER) ? GetWaterTileRandomBits(tile) : 0; } DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable); *available = false; return UINT_MAX; }
/* virtual */ uint32 RailTypeScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { if (this->tile == INVALID_TILE) { switch (variable) { case 0x40: return 0; case 0x41: return 0; case 0x42: return 0; case 0x43: return _date; case 0x44: return HZB_TOWN_EDGE; } } switch (variable) { case 0x40: return GetTerrainType(this->tile, this->context); case 0x41: return 0; case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile); case 0x43: if (IsRailDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date; return _date; case 0x44: { const Town *t = NULL; if (IsRailDepotTile(this->tile)) { t = Depot::GetByTile(this->tile)->town; } else if (IsLevelCrossingTile(this->tile)) { t = ClosestTownFromTile(this->tile, UINT_MAX); } return t != NULL ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE; } } DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable); *available = false; return UINT_MAX; }
// Flugente: determine wether a fortification can be built on this position BOOLEAN IsFortificationPossibleAtGridNo( INT32 sGridNo ) { INT8 bOverTerrainType = GetTerrainType( sGridNo ); if( bOverTerrainType == MED_WATER || bOverTerrainType == DEEP_WATER || bOverTerrainType == LOW_WATER ) return FALSE; STRUCTURE * pStructure = NULL; pStructure = FindStructure( sGridNo, (STRUCTURE_OBSTACLE|STRUCTURE_PERSON) ); return( pStructure == NULL ); }
/* virtual */ uint32 CanalScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { switch (variable) { /* Height of tile */ case 0x80: { int z = GetTileZ(this->tile); /* Return consistent height within locks */ if (IsTileType(this->tile, MP_WATER) && IsLock(this->tile) && GetLockPart(this->tile) == LOCK_PART_UPPER) z--; return z; } /* Terrain type */ case 0x81: return GetTerrainType(this->tile); /* Dike map: Connectivity info for river and canal tiles * * Assignment of bits to directions defined in agreement with * http://projects.tt-forums.net/projects/ttdpatch/repository/revisions/2367/entry/trunk/patches/water.asm#L879 * 7 * 3 0 * 6 * 4 * 2 1 * 5 */ case 0x82: { uint32 connectivity = (!IsWateredTile(TILE_ADDXY(tile, -1, 0), DIR_SW) << 0) // NE + (!IsWateredTile(TILE_ADDXY(tile, 0, 1), DIR_NW) << 1) // SE + (!IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2) // SW + (!IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3) // NW + (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W) << 4) // E + (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N) << 5) // S + (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E) << 6) // W + (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S) << 7); // N return connectivity; } /* Random data for river or canal tiles, otherwise zero */ case 0x83: return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0; } DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable); *available = false; return UINT_MAX; }
static uint32 CanalGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { TileIndex tile = object->u.canal.tile; switch (variable) { /* Height of tile */ case 0x80: return GetTileZ(tile) / TILE_HEIGHT; /* Terrain type */ case 0x81: return GetTerrainType(tile); /* Random data for river or canal tiles, otherwise zero */ case 0x83: return GetWaterTileRandomBits(tile); } DEBUG(grf, 1, "Unhandled canal property 0x%02X", variable); *available = false; return UINT_MAX; }
/* virtual */ uint32 CanalScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { switch (variable) { /* Height of tile */ case 0x80: { int z = GetTileZ(this->tile); /* Return consistent height within locks */ if (IsTileType(this->tile, MP_WATER) && IsLock(this->tile) && GetLockPart(this->tile) == LOCK_PART_UPPER) z--; return z; } /* Terrain type */ case 0x81: return GetTerrainType(this->tile); /* Random data for river or canal tiles, otherwise zero */ case 0x83: return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0; } DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable); *available = false; return UINT_MAX; }
/// Return true if the terrain type is water bool Node::CheckForWater() { return (GetTerrainType() == Node::WATER); }
/** * @note Used by the resolver to get values for feature 07 deterministic spritegroups. */ /* virtual */ uint32 HouseScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { switch (variable) { /* Construction stage. */ case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2; /* Building age. */ case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0; /* Town zone */ case 0x42: return GetTownRadiusGroup(this->town, this->tile); /* Terrain type */ case 0x43: return GetTerrainType(this->tile); /* Number of this type of building on the map. */ case 0x44: return GetNumHouses(this->house_id, this->town); /* Whether the town is being created or just expanded. */ case 0x45: return _generating_world ? 1 : 0; /* Current animation frame. */ case 0x46: return IsTileType(this->tile, MP_HOUSE) ? GetAnimationFrame(this->tile) : 0; /* Position of the house */ case 0x47: return TileY(this->tile) << 16 | TileX(this->tile); /* Building counts for old houses with id = parameter. */ case 0x60: return parameter < NEW_HOUSE_OFFSET ? GetNumHouses(parameter, this->town) : 0; /* Building counts for new houses with id = parameter. */ case 0x61: { const HouseSpec *hs = HouseSpec::Get(this->house_id); if (hs->grf_prop.grffile == NULL) return 0; HouseID new_house = _house_mngr.GetID(parameter, hs->grf_prop.grffile->grfid); return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, this->town); } /* Land info for nearby tiles. */ case 0x62: return GetNearbyTileInformation(parameter, this->tile, this->ro->grffile->grf_version >= 8); /* Current animation frame of nearby house tiles */ case 0x63: { TileIndex testtile = GetNearbyTile(parameter, this->tile); return IsTileType(testtile, MP_HOUSE) ? GetAnimationFrame(testtile) : 0; } /* Cargo acceptance history of nearby stations */ case 0x64: { CargoID cid = GetCargoTranslation(parameter, this->ro->grffile); if (cid == CT_INVALID) return 0; /* Extract tile offset. */ int8 x_offs = GB(GetRegister(0x100), 0, 8); int8 y_offs = GB(GetRegister(0x100), 8, 8); TileIndex testtile = TILE_MASK(this->tile + TileDiffXY(x_offs, y_offs)); StationFinder stations(TileArea(testtile, 1, 1)); const StationList *sl = stations.GetStations(); /* Collect acceptance stats. */ uint32 res = 0; for (Station * const * st_iter = sl->Begin(); st_iter != sl->End(); st_iter++) { const Station *st = *st_iter; if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_EVER_ACCEPTED)) SetBit(res, 0); if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_LAST_MONTH)) SetBit(res, 1); if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_CURRENT_MONTH)) SetBit(res, 2); if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(res, 3); } /* Cargo triggered CB 148? */ if (HasBit(this->watched_cargo_triggers, cid)) SetBit(res, 4); return res; } /* Distance test for some house types */ case 0x65: return GetDistanceFromNearbyHouse(parameter, this->tile, this->house_id); /* Class and ID of nearby house tile */ case 0x66: { TileIndex testtile = GetNearbyTile(parameter, this->tile); if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF; HouseSpec *hs = HouseSpec::Get(GetHouseType(testtile)); /* Information about the grf local classid if the house has a class */ uint houseclass = 0; if (hs->class_id != HOUSE_NO_CLASS) { houseclass = (hs->grf_prop.grffile == this->ro->grffile ? 1 : 2) << 8; houseclass |= _class_mapping[hs->class_id].class_id; } /* old house type or grf-local houseid */ uint local_houseid = 0; if (this->house_id < NEW_HOUSE_OFFSET) { local_houseid = this->house_id; } else { local_houseid = (hs->grf_prop.grffile == this->ro->grffile ? 1 : 2) << 8; local_houseid |= hs->grf_prop.local_id; } return houseclass << 16 | local_houseid; } /* GRFID of nearby house tile */ case 0x67: { TileIndex testtile = GetNearbyTile(parameter, this->tile); if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF; HouseID house_id = GetHouseType(testtile); if (house_id < NEW_HOUSE_OFFSET) return 0; /* Checking the grffile information via HouseSpec doesn't work * in case the newgrf was removed. */ return _house_mngr.GetGRFID(house_id); } } DEBUG(grf, 1, "Unhandled house variable 0x%X", variable); *available = false; return UINT_MAX; }
/* virtual */ uint32 StationScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { if (this->st == NULL) { /* Station does not exist, so we're in a purchase list or the land slope check callback. */ switch (variable) { case 0x40: case 0x41: case 0x46: case 0x47: case 0x49: return 0x2110000; // Platforms, tracks & position case 0x42: return 0; // Rail type (XXX Get current type from GUI?) case 0x43: return GetCompanyInfo(_current_company); // Station owner case 0x44: return 2; // PBS status case 0x67: // Land info of nearby tile if (this->axis != INVALID_AXIS && this->tile != INVALID_TILE) { TileIndex tile = this->tile; if (parameter != 0) tile = GetNearbyTile(parameter, tile, true, this->axis); // only perform if it is required Slope tileh = GetTileSlope(tile); bool swap = (this->axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E)); return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0); } break; case 0xFA: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Build date, clamped to a 16 bit value } *available = false; return UINT_MAX; } switch (variable) { /* Calculated station variables */ case 0x40: if (!HasBit(_svc.valid, 0)) { _svc.v40 = GetPlatformInfoHelper(this->tile, false, false, false); SetBit(_svc.valid, 0); } return _svc.v40; case 0x41: if (!HasBit(_svc.valid, 1)) { _svc.v41 = GetPlatformInfoHelper(this->tile, true, false, false); SetBit(_svc.valid, 1); } return _svc.v41; case 0x42: return GetTerrainType(this->tile) | (GetReverseRailTypeTranslation(GetRailType(this->tile), this->statspec->grf_prop.grffile) << 8); case 0x43: return GetCompanyInfo(this->st->owner); // Station owner case 0x44: return HasStationReservation(this->tile) ? 7 : 4; // PBS status case 0x45: if (!HasBit(_svc.valid, 2)) { _svc.v45 = GetRailContinuationInfo(this->tile); SetBit(_svc.valid, 2); } return _svc.v45; case 0x46: if (!HasBit(_svc.valid, 3)) { _svc.v46 = GetPlatformInfoHelper(this->tile, false, false, true); SetBit(_svc.valid, 3); } return _svc.v46; case 0x47: if (!HasBit(_svc.valid, 4)) { _svc.v47 = GetPlatformInfoHelper(this->tile, true, false, true); SetBit(_svc.valid, 4); } return _svc.v47; case 0x49: if (!HasBit(_svc.valid, 5)) { _svc.v49 = GetPlatformInfoHelper(this->tile, false, true, false); SetBit(_svc.valid, 5); } return _svc.v49; case 0x4A: // Animation frame of tile return GetAnimationFrame(this->tile); /* Variables which use the parameter */ /* Variables 0x60 to 0x65 and 0x69 are handled separately below */ case 0x66: { // Animation frame of nearby tile TileIndex tile = this->tile; if (parameter != 0) tile = GetNearbyTile(parameter, tile); return this->st->TileBelongsToRailStation(tile) ? GetAnimationFrame(tile) : UINT_MAX; } case 0x67: { // Land info of nearby tile Axis axis = GetRailStationAxis(this->tile); TileIndex tile = this->tile; if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required Slope tileh = GetTileSlope(tile); bool swap = (axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E)); return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0); } case 0x68: { // Station info of nearby tiles TileIndex nearby_tile = GetNearbyTile(parameter, this->tile); if (!HasStationTileRail(nearby_tile)) return 0xFFFFFFFF; uint32 grfid = this->st->speclist[GetCustomStationSpecIndex(this->tile)].grfid; bool perpendicular = GetRailStationAxis(this->tile) != GetRailStationAxis(nearby_tile); bool same_station = this->st->TileBelongsToRailStation(nearby_tile); uint32 res = GB(GetStationGfx(nearby_tile), 1, 2) << 12 | !!perpendicular << 11 | !!same_station << 10; if (IsCustomStationSpecIndex(nearby_tile)) { const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)]; res |= 1 << (ssl.grfid != grfid ? 9 : 8) | ssl.localidx; } return res; } /* General station variables */ case 0x82: return 50; case 0x84: return this->st->string_id; case 0x86: return 0; case 0xF0: return this->st->facilities; case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); } return this->st->GetNewGRFVariable(this->ro, variable, parameter, available); }
static uint32 StationGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { const BaseStation *st = object->u.station.st; TileIndex tile = object->u.station.tile; if (object->scope == VSG_SCOPE_PARENT) { /* Pass the request on to the town of the station */ const Town *t; if (st != NULL) { t = st->town; } else if (tile != INVALID_TILE) { t = ClosestTownFromTile(tile, UINT_MAX); } else { *available = false; return UINT_MAX; } return TownGetVariable(variable, parameter, available, t); } if (st == NULL) { /* Station does not exist, so we're in a purchase list */ switch (variable) { case 0x40: case 0x41: case 0x46: case 0x47: case 0x49: return 0x2110000; // Platforms, tracks & position case 0x42: return 0; // Rail type (XXX Get current type from GUI?) case 0x43: return _current_company; // Station owner case 0x44: return 2; // PBS status case 0xFA: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Build date, clamped to a 16 bit value } *available = false; return UINT_MAX; } switch (variable) { /* Calculated station variables */ case 0x40: if (!HasBit(_svc.valid, 0)) { _svc.v40 = GetPlatformInfoHelper(tile, false, false, false); SetBit(_svc.valid, 0); } return _svc.v40; case 0x41: if (!HasBit(_svc.valid, 1)) { _svc.v41 = GetPlatformInfoHelper(tile, true, false, false); SetBit(_svc.valid, 1); } return _svc.v41; case 0x42: return GetTerrainType(tile) | (GetReverseRailTypeTranslation(GetRailType(tile), object->u.station.statspec->grf_prop.grffile) << 8); case 0x43: return st->owner; // Station owner case 0x44: return HasStationReservation(tile) ? 7 : 4; // PBS status case 0x45: if (!HasBit(_svc.valid, 2)) { _svc.v45 = GetRailContinuationInfo(tile); SetBit(_svc.valid, 2); } return _svc.v45; case 0x46: if (!HasBit(_svc.valid, 3)) { _svc.v46 = GetPlatformInfoHelper(tile, false, false, true); SetBit(_svc.valid, 3); } return _svc.v46; case 0x47: if (!HasBit(_svc.valid, 4)) { _svc.v47 = GetPlatformInfoHelper(tile, true, false, true); SetBit(_svc.valid, 4); } return _svc.v47; case 0x49: if (!HasBit(_svc.valid, 5)) { _svc.v49 = GetPlatformInfoHelper(tile, false, true, false); SetBit(_svc.valid, 5); } return _svc.v49; case 0x4A: // Animation frame of tile return GetAnimationFrame(tile); /* Variables which use the parameter */ /* Variables 0x60 to 0x65 are handled separately below */ case 0x66: // Animation frame of nearby tile if (parameter != 0) tile = GetNearbyTile(parameter, tile); return st->TileBelongsToRailStation(tile) ? GetAnimationFrame(tile) : UINT_MAX; case 0x67: { // Land info of nearby tile Axis axis = GetRailStationAxis(tile); if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required Slope tileh = GetTileSlope(tile, NULL); bool swap = (axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E)); return GetNearbyTileInformation(tile) ^ (swap ? SLOPE_EW : 0); } case 0x68: { // Station info of nearby tiles TileIndex nearby_tile = GetNearbyTile(parameter, tile); if (!HasStationTileRail(nearby_tile)) return 0xFFFFFFFF; uint32 grfid = st->speclist[GetCustomStationSpecIndex(tile)].grfid; bool perpendicular = GetRailStationAxis(tile) != GetRailStationAxis(nearby_tile); bool same_station = st->TileBelongsToRailStation(nearby_tile); uint32 res = GB(GetStationGfx(nearby_tile), 1, 2) << 12 | !!perpendicular << 11 | !!same_station << 10; if (IsCustomStationSpecIndex(nearby_tile)) { const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)]; res |= 1 << (ssl.grfid != grfid ? 9 : 8) | ssl.localidx; } return res; } /* General station variables */ case 0x82: return 50; case 0x84: return st->string_id; case 0x86: return 0; case 0xF0: return st->facilities; case 0xFA: return Clamp(st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); } return st->GetNewGRFVariable(object, variable, parameter, available); }
BOOLEAN HandleNextTile( SOLDIERTYPE *pSoldier, INT8 bDirection, INT16 sGridNo, INT16 sFinalDestTile ) { INT8 bBlocked; INT16 bOverTerrainType; // Check for blocking if in realtime ///if ( ( gTacticalStatus.uiFlags & REALTIME ) || !( gTacticalStatus.uiFlags & INCOMBAT ) ) // ATE: If not on visible tile, return clear ( for path out of map ) if ( !GridNoOnVisibleWorldTile( sGridNo ) ) { return( TRUE ); } // If animation state is crow, iall is clear if ( pSoldier->usAnimState == CROW_FLY ) { return( TRUE ); } { bBlocked = TileIsClear( pSoldier, bDirection, sGridNo, pSoldier->bLevel ); // Check if we are blocked... if ( bBlocked != MOVE_TILE_CLEAR ) { // Is the next gridno our destination? // OK: Let's check if we are NOT walking off screen if ( sGridNo == sFinalDestTile && pSoldier->ubWaitActionToDo == 0 && (pSoldier->bTeam == gbPlayerNum || pSoldier->sAbsoluteFinalDestination == NOWHERE) ) { // Yah, well too bad, stop here. SetFinalTile( pSoldier, pSoldier->sGridNo, FALSE ); return( FALSE ); } // CHECK IF they are stationary else if ( bBlocked == MOVE_TILE_STATIONARY_BLOCKED ) { // Stationary, { INT16 sOldFinalDest; // Maintain sFinalDest.... sOldFinalDest = pSoldier->sFinalDestination; #ifdef JA2BETAVERSION if ( gTacticalStatus.uiFlags & INCOMBAT ) { OutputDebugInfoForTurnBasedNextTileWaiting( pSoldier ); } #endif EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); // Restore... pSoldier->sFinalDestination = sOldFinalDest; SetDelayedTileWaiting( pSoldier, sGridNo, 1 ); return( FALSE ); } } else { { INT16 sOldFinalDest; // Maintain sFinalDest.... sOldFinalDest = pSoldier->sFinalDestination; #ifdef JA2BETAVERSION if ( gTacticalStatus.uiFlags & INCOMBAT ) { OutputDebugInfoForTurnBasedNextTileWaiting( pSoldier ); } #endif EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); // Restore... pSoldier->sFinalDestination = sOldFinalDest; // Setting to two means: try and wait until this tile becomes free.... SetDelayedTileWaiting( pSoldier, sGridNo, 100 ); } return( FALSE ); } } else { // Mark this tile as reserverd ( until we get there! ) if ( !( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) ) ) { MarkMovementReserved( pSoldier, sGridNo ); } bOverTerrainType = GetTerrainType( sGridNo ); // Check if we are going into water! if ( bOverTerrainType == LOW_WATER || bOverTerrainType == MED_WATER || bOverTerrainType == DEEP_WATER ) { // Check if we are of prone or crawl height and change stance accordingly.... switch( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { case ANIM_PRONE: case ANIM_CROUCH: // Change height to stand pSoldier->fContinueMoveAfterStanceChange = TRUE; SendChangeSoldierStanceEvent( pSoldier, ANIM_STAND ); break; } // Check animation // Change to walking if ( pSoldier->usAnimState == RUNNING ) { ChangeSoldierState( pSoldier, WALKING, 0 , FALSE ); } } } } return( TRUE ); }
/** * HouseGetVariable(): * * Used by the resolver to get values for feature 07 deterministic spritegroups. */ static uint32 HouseGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { const Town *town = object->u.house.town; TileIndex tile = object->u.house.tile; HouseID house_id = object->u.house.house_id; if (object->scope == VSG_SCOPE_PARENT) { return TownGetVariable(variable, parameter, available, town); } switch (variable) { /* Construction stage. */ case 0x40: return (IsTileType(tile, MP_HOUSE) ? GetHouseBuildingStage(tile) : 0) | TileHash2Bit(TileX(tile), TileY(tile)) << 2; /* Building age. */ case 0x41: return IsTileType(tile, MP_HOUSE) ? GetHouseAge(tile) : 0; /* Town zone */ case 0x42: return GetTownRadiusGroup(town, tile); /* Terrain type */ case 0x43: return GetTerrainType(tile); /* Number of this type of building on the map. */ case 0x44: return GetNumHouses(house_id, town); /* Whether the town is being created or just expanded. */ case 0x45: return _generating_world ? 1 : 0; /* Current animation frame. */ case 0x46: return IsTileType(tile, MP_HOUSE) ? GetHouseAnimationFrame(tile) : 0; /* Position of the house */ case 0x47: return TileY(tile) << 16 | TileX(tile); /* Building counts for old houses with id = parameter. */ case 0x60: return GetNumHouses(parameter, town); /* Building counts for new houses with id = parameter. */ case 0x61: { const HouseSpec *hs = HouseSpec::Get(house_id); if (hs->grffile == NULL) return 0; HouseID new_house = _house_mngr.GetID(parameter, hs->grffile->grfid); return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, town); } /* Land info for nearby tiles. */ case 0x62: return GetNearbyTileInformation(parameter, tile); /* Current animation frame of nearby house tiles */ case 0x63: { TileIndex testtile = GetNearbyTile(parameter, tile); return IsTileType(testtile, MP_HOUSE) ? GetHouseAnimationFrame(testtile) : 0; } /* Cargo acceptance history of nearby stations */ /*case 0x64: not implemented yet */ /* Distance test for some house types */ case 0x65: return GetDistanceFromNearbyHouse(parameter, tile, object->u.house.house_id); /* Class and ID of nearby house tile */ case 0x66: { TileIndex testtile = GetNearbyTile(parameter, tile); if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF; HouseSpec *hs = HouseSpec::Get(GetHouseType(testtile)); /* Information about the grf local classid if the house has a class */ uint houseclass = 0; if (hs->class_id != HOUSE_NO_CLASS) { houseclass = (hs->grffile == object->grffile ? 1 : 2) << 8; houseclass |= _class_mapping[hs->class_id].class_id; } /* old house type or grf-local houseid */ uint local_houseid = 0; if (house_id < NEW_HOUSE_OFFSET) { local_houseid = house_id; } else { local_houseid = (hs->grffile == object->grffile ? 1 : 2) << 8; local_houseid |= hs->local_id; } return houseclass << 16 | local_houseid; } /* GRFID of nearby house tile */ case 0x67: { TileIndex testtile = GetNearbyTile(parameter, tile); if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF; HouseID house_id = GetHouseType(testtile); if (house_id < NEW_HOUSE_OFFSET) return 0; /* Checking the grffile information via HouseSpec doesn't work * in case the newgrf was removed. */ return _house_mngr.mapping_ID[house_id].grfid; } } DEBUG(grf, 1, "Unhandled house property 0x%X", variable); *available = false; return UINT_MAX; }
INT32 NewSmokeEffect( INT16 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubOwner ) { SMOKEEFFECT *pSmoke; INT32 iSmokeIndex; INT8 bSmokeEffectType=0; UINT8 ubDuration=0; UINT8 ubStartRadius=0; if( ( iSmokeIndex = GetFreeSmokeEffect() )==(-1) ) return(-1); memset( &gSmokeEffectData[ iSmokeIndex ], 0, sizeof( SMOKEEFFECT ) ); pSmoke = &gSmokeEffectData[ iSmokeIndex ]; // Set some values... pSmoke->sGridNo = sGridNo; pSmoke->usItem = usItem; pSmoke->uiTimeOfLastUpdate = GetWorldTotalSeconds( ); // Are we indoors? if ( GetTerrainType( sGridNo ) == FLAT_FLOOR ) { pSmoke->bFlags |= SMOKE_EFFECT_INDOORS; } switch( usItem ) { case MUSTARD_GRENADE: bSmokeEffectType = MUSTARDGAS_SMOKE_EFFECT; ubDuration = 5; ubStartRadius = 1; break; case TEARGAS_GRENADE: case GL_TEARGAS_GRENADE: bSmokeEffectType = TEARGAS_SMOKE_EFFECT; ubDuration = 5; ubStartRadius = 1; break; case BIG_TEAR_GAS: bSmokeEffectType = TEARGAS_SMOKE_EFFECT; ubDuration = 5; ubStartRadius = 1; break; case SMOKE_GRENADE: case GL_SMOKE_GRENADE: bSmokeEffectType = NORMAL_SMOKE_EFFECT; ubDuration = 5; ubStartRadius = 1; break; case SMALL_CREATURE_GAS: bSmokeEffectType = CREATURE_SMOKE_EFFECT; ubDuration = 3; ubStartRadius = 1; break; case LARGE_CREATURE_GAS: bSmokeEffectType = CREATURE_SMOKE_EFFECT; ubDuration = 3; ubStartRadius = Explosive[ Item[ LARGE_CREATURE_GAS ].ubClassIndex ].ubRadius; break; case VERY_SMALL_CREATURE_GAS: bSmokeEffectType = CREATURE_SMOKE_EFFECT; ubDuration = 2; ubStartRadius = 0; break; } pSmoke->ubDuration = ubDuration; pSmoke->ubRadius = ubStartRadius; pSmoke->bAge = 0; pSmoke->fAllocated = TRUE; pSmoke->bType = bSmokeEffectType; pSmoke->ubOwner = ubOwner; if ( pSmoke->bFlags & SMOKE_EFFECT_INDOORS ) { // Duration is increased by 2 turns...indoors pSmoke->ubDuration += 3; } if ( bLevel ) { pSmoke->bFlags |= SMOKE_EFFECT_ON_ROOF; } // ATE: FALSE into subsequent-- it's the first one! SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, FALSE, bLevel, iSmokeIndex ); return( iSmokeIndex ); }