1
0
Fork 0

Codechange: Implement tile proc handler to test for building bridge over tile.

pull/14477/head
Peter Nelson 2025-07-24 02:10:00 +01:00
parent 614a01907a
commit cdadfd8e83
No known key found for this signature in database
GPG Key ID: 8EF8F0A467DF75ED
12 changed files with 68 additions and 40 deletions

View File

@ -390,6 +390,11 @@ static CommandCost TerraformTile_Clear(TileIndex tile, DoCommandFlags flags, int
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
static CommandCost CheckBuildAbove_Clear(TileIndex, DoCommandFlags, Axis, int)
{
return CommandCost();
}
extern const TileTypeProcs _tile_type_clear_procs = {
DrawTile_Clear, ///< draw_tile_proc
GetSlopePixelZ_Clear, ///< get_slope_z_proc
@ -405,4 +410,5 @@ extern const TileTypeProcs _tile_type_clear_procs = {
nullptr, ///< vehicle_enter_tile_proc
GetFoundation_Clear, ///< get_foundation_proc
TerraformTile_Clear, ///< terraform_tile_proc
CheckBuildAbove_Clear, // check_build_above_proc
};

View File

@ -3205,6 +3205,7 @@ extern const TileTypeProcs _tile_type_industry_procs = {
nullptr, // vehicle_enter_tile_proc
GetFoundation_Industry, // get_foundation_proc
TerraformTile_Industry, // terraform_tile_proc
nullptr, // check_build_above_proc
};
bool IndustryCompare::operator() (const IndustryListEntry &lhs, const IndustryListEntry &rhs) const

View File

@ -929,6 +929,16 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlags flags, in
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
static CommandCost CheckBuildAbove_Object(TileIndex tile, DoCommandFlags flags, Axis, int height)
{
const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
if (spec->flags.Test(ObjectFlag::AllowUnderBridge) && GetTileMaxZ(tile) + spec->height <= height) {
return CommandCost();
}
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
extern const TileTypeProcs _tile_type_object_procs = {
DrawTile_Object, // draw_tile_proc
GetSlopePixelZ_Object, // get_slope_z_proc
@ -944,4 +954,5 @@ extern const TileTypeProcs _tile_type_object_procs = {
nullptr, // vehicle_enter_tile_proc
GetFoundation_Object, // get_foundation_proc
TerraformTile_Object, // terraform_tile_proc
CheckBuildAbove_Object, // check_build_above_proc
};

View File

@ -3070,6 +3070,11 @@ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlags flags, int
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
static CommandCost CheckBuildAbove_Track(TileIndex tile, DoCommandFlags flags, Axis, int)
{
if (IsPlainRail(tile)) return CommandCost();
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
extern const TileTypeProcs _tile_type_rail_procs = {
DrawTile_Track, // draw_tile_proc
@ -3086,4 +3091,5 @@ extern const TileTypeProcs _tile_type_rail_procs = {
VehicleEnter_Track, // vehicle_enter_tile_proc
GetFoundation_Track, // get_foundation_proc
TerraformTile_Track, // terraform_tile_proc
CheckBuildAbove_Track, // check_build_above_proc
};

View File

@ -2616,6 +2616,11 @@ CommandCost CmdConvertRoad(DoCommandFlags flags, TileIndex tile, TileIndex area_
return found_convertible_road ? cost : error;
}
static CommandCost CheckBuildAbove_Road(TileIndex tile, DoCommandFlags flags, Axis, int)
{
if (!IsRoadDepot(tile)) return CommandCost();
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
/** Tile callback functions for road tiles */
extern const TileTypeProcs _tile_type_road_procs = {
@ -2633,4 +2638,5 @@ extern const TileTypeProcs _tile_type_road_procs = {
VehicleEnter_Road, // vehicle_enter_tile_proc
GetFoundation_Road, // get_foundation_proc
TerraformTile_Road, // terraform_tile_proc
CheckBuildAbove_Road, // check_build_above_proc
};

View File

@ -5177,4 +5177,5 @@ extern const TileTypeProcs _tile_type_station_procs = {
VehicleEnter_Station, // vehicle_enter_tile_proc
GetFoundation_Station, // get_foundation_proc
TerraformTile_Station, // terraform_tile_proc
nullptr, // check_build_above_proc
};

View File

@ -135,6 +135,8 @@ typedef Foundation GetFoundationProc(TileIndex tile, Slope tileh);
*/
typedef CommandCost TerraformTileProc(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new);
using CheckBuildAboveProc = CommandCost(TileIndex tile, DoCommandFlags flags, Axis axis, int height);
/**
* Set of callback functions for performing tile operations of a given tile type.
* @see TileType
@ -154,6 +156,7 @@ struct TileTypeProcs {
VehicleEnterTileProc *vehicle_enter_tile_proc; ///< Called when a vehicle enters a tile
GetFoundationProc *get_foundation_proc;
TerraformTileProc *terraform_tile_proc; ///< Called when a terraforming operation is about to take place
CheckBuildAboveProc *check_build_above_proc;
};
extern const TileTypeProcs * const _tile_type_procs[16];

View File

@ -4130,6 +4130,7 @@ extern const TileTypeProcs _tile_type_town_procs = {
nullptr, // vehicle_enter_tile_proc
GetFoundation_Town, // get_foundation_proc
TerraformTile_Town, // terraform_tile_proc
nullptr, // check_build_above_proc
};
std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()

View File

@ -1031,4 +1031,5 @@ extern const TileTypeProcs _tile_type_trees_procs = {
nullptr, // vehicle_enter_tile_proc
GetFoundation_Trees, // get_foundation_proc
TerraformTile_Trees, // terraform_tile_proc
nullptr, // check_build_above_proc
};

View File

@ -12,7 +12,6 @@
*/
#include "stdafx.h"
#include "newgrf_object.h"
#include "viewport_func.h"
#include "command_func.h"
#include "town.h"
@ -20,7 +19,6 @@
#include "ship.h"
#include "roadveh.h"
#include "pathfinder/yapf/yapf_cache.h"
#include "pathfinder/water_regions.h"
#include "newgrf_sound.h"
#include "autoslope.h"
#include "tunnelbridge_map.h"
@ -39,7 +37,6 @@
#include "object_base.h"
#include "water.h"
#include "company_gui.h"
#include "station_func.h"
#include "tunnelbridge_cmd.h"
#include "landscape_cmd.h"
#include "terraform_cmd.h"
@ -278,6 +275,16 @@ static Money TunnelBridgeClearCost(TileIndex tile, Price base_price)
return base_cost;
}
static CommandCost CheckBuildAbove(TileIndex tile, DoCommandFlags flags, Axis axis, int height)
{
if (_tile_type_procs[GetTileType(tile)]->check_build_above_proc != nullptr) {
return _tile_type_procs[GetTileType(tile)]->check_build_above_proc(tile, flags, axis, height);
}
/* A tile without a handler must be cleared. */
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
/**
* Build a Bridge
* @param flags type of operation
@ -484,43 +491,9 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t
return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
}
switch (GetTileType(tile)) {
case MP_WATER:
if (!IsWater(tile) && !IsCoast(tile)) goto not_valid_below;
break;
case MP_RAILWAY:
if (!IsPlainRail(tile)) goto not_valid_below;
break;
case MP_ROAD:
if (IsRoadDepot(tile)) goto not_valid_below;
break;
case MP_TUNNELBRIDGE:
if (IsTunnel(tile)) break;
if (direction == DiagDirToAxis(GetTunnelBridgeDirection(tile))) goto not_valid_below;
if (z_start < GetBridgeHeight(tile)) goto not_valid_below;
break;
case MP_OBJECT: {
const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
if (!spec->flags.Test(ObjectFlag::AllowUnderBridge)) goto not_valid_below;
if (GetTileMaxZ(tile) + spec->height > z_start) goto not_valid_below;
break;
}
case MP_CLEAR:
break;
default:
not_valid_below:;
/* try and clear the middle landscape */
ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
if (ret.Failed()) return ret;
cost.AddCost(ret.GetCost());
break;
}
ret = CheckBuildAbove(tile, flags, direction, z_start);
if (ret.Failed()) return ret;
cost.AddCost(ret.GetCost());
if (flags.Test(DoCommandFlag::Execute)) {
/* We do this here because when replacing a bridge with another
@ -2084,6 +2057,17 @@ static CommandCost TerraformTile_TunnelBridge(TileIndex tile, DoCommandFlags fla
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
static CommandCost CheckBuildAbove_TunnelBridge(TileIndex tile, DoCommandFlags flags, Axis axis, int height)
{
if (IsTunnel(tile)) return CommandCost();
if (axis != DiagDirToAxis(GetTunnelBridgeDirection(tile)) && height >= GetBridgeHeight(tile)) {
return CommandCost();
}
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
extern const TileTypeProcs _tile_type_tunnelbridge_procs = {
DrawTile_TunnelBridge, // draw_tile_proc
GetSlopePixelZ_TunnelBridge, // get_slope_z_proc
@ -2099,4 +2083,5 @@ extern const TileTypeProcs _tile_type_tunnelbridge_procs = {
VehicleEnter_TunnelBridge, // vehicle_enter_tile_proc
GetFoundation_TunnelBridge, // get_foundation_proc
TerraformTile_TunnelBridge, // terraform_tile_proc
CheckBuildAbove_TunnelBridge, // check_build_above_proc
};

View File

@ -87,4 +87,5 @@ extern const TileTypeProcs _tile_type_void_procs = {
nullptr, // vehicle_enter_tile_proc
GetFoundation_Void, // get_foundation_proc
TerraformTile_Void, // terraform_tile_proc
nullptr, // check_build_above_proc
};

View File

@ -1410,6 +1410,11 @@ static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlags flags, int
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
static CommandCost CheckBuildAbove_Water(TileIndex tile, DoCommandFlags flags, Axis, int)
{
if (IsWater(tile) || IsCoast(tile)) return CommandCost();
return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
}
extern const TileTypeProcs _tile_type_water_procs = {
DrawTile_Water, // draw_tile_proc
@ -1426,4 +1431,5 @@ extern const TileTypeProcs _tile_type_water_procs = {
VehicleEnter_Water, // vehicle_enter_tile_proc
GetFoundation_Water, // get_foundation_proc
TerraformTile_Water, // terraform_tile_proc
CheckBuildAbove_Water, // check_build_above_proc
};