Add NewGRF bridge property to prevent town or AI/GS building bridge type

pull/199/head
Jonathan G Rennison 4 years ago
parent 0c0c6c7531
commit 14adcbac80

@ -203,6 +203,16 @@
</table>
</p>
<p>This is indicated by the feature name: <font face="monospace">action0_bridge_pillar_flags</font>, version 1</p>
<h4>Bridge availability flags (mappable property: bridge_availability_flags)</h4>
<p>This property sets the availability flags for this bridge type.<br />
The property length is 1 byte. The format is:
<table>
<tr><th>Bit</th><th>Value</th><th>Meaning</th></tr>
<tr><td>0</td><td>1</td><td>Towns may not build this bridge type</td></tr>
<tr><td>1</td><td>2</td><td>Scripts (AI/GS) may not build this bridge type</td></tr>
</table>
</p>
<p>This is indicated by the feature name: <font face="monospace">action0_bridge_availability_flags</font>, version 1</p>
<h4>More bridges (16 instead of 13)</h4>
<p>This is indicated by the feature name: <font face="monospace">more_bridge_types</font>, version 1</p>
<h3><a href="https://newgrf-specs.tt-wiki.net/wiki/Action0/Railtypes">Action 0 - Railtypes</a></h3>

@ -54,6 +54,8 @@ DECLARE_ENUM_AS_BIT_SET(BridgePiecePillarFlags)
enum BridgeSpecCtrlFlags {
BSCF_CUSTOM_PILLAR_FLAGS,
BSCF_INVALID_PILLAR_FLAGS,
BSCF_NOT_AVAILABLE_TOWN,
BSCF_NOT_AVAILABLE_AI_GS,
};
/**
@ -94,6 +96,7 @@ static inline const BridgeSpec *GetBridgeSpec(BridgeType i)
void DrawBridgeMiddle(const TileInfo *ti);
CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoCommandFlag flags = DC_NONE);
bool MayTownBuildBridgeType(BridgeType bridge_type);
int CalcBridgeLenCostFactor(int x);
BridgePiecePillarFlags GetBridgeTilePillarFlags(TileIndex tile, TileIndex northern_bridge_end, TileIndex southern_bridge_end, BridgeType bridge_type, TransportType bridge_transport_type);

@ -2310,6 +2310,14 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, const
SetBit(bridge->ctrl_flags, BSCF_CUSTOM_PILLAR_FLAGS);
break;
case A0RPI_BRIDGE_AVAILABILITY_FLAGS: {
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
byte flags = buf->ReadByte();
SB(bridge->ctrl_flags, BSCF_NOT_AVAILABLE_TOWN, 1, HasBit(flags, 0) ? 1 : 0);
SB(bridge->ctrl_flags, BSCF_NOT_AVAILABLE_AI_GS, 1, HasBit(flags, 1) ? 1 : 0);
break;
}
default:
ret = HandleAction0PropertyDefault(buf, prop);
break;
@ -8369,6 +8377,7 @@ static const GRFFeatureInfo _grf_feature_list[] = {
GRFFeatureInfo("more_bridge_types", 1),
GRFFeatureInfo("action0_bridge_prop14", 1),
GRFFeatureInfo("action0_bridge_pillar_flags", 1),
GRFFeatureInfo("action0_bridge_availability_flags", 1),
GRFFeatureInfo("action5_programmable_signals", 1),
GRFFeatureInfo("action0_railtype_programmable_signals", 1),
GRFFeatureInfo("action0_railtype_restricted_signals", 1),
@ -8487,6 +8496,7 @@ static const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = {
GRFPropertyMapDefinition(GSF_STATIONS, A0RPI_STATION_DISALLOWED_BRIDGE_PILLARS, "station_disallowed_bridge_pillars"),
GRFPropertyMapDefinition(GSF_BRIDGES, A0RPI_BRIDGE_MENU_ICON, "bridge_menu_icon"),
GRFPropertyMapDefinition(GSF_BRIDGES, A0RPI_BRIDGE_PILLAR_FLAGS, "bridge_pillar_flags"),
GRFPropertyMapDefinition(GSF_BRIDGES, A0RPI_BRIDGE_AVAILABILITY_FLAGS, "bridge_availability_flags"),
GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_ENABLE_PROGRAMMABLE_SIGNALS, "railtype_enable_programmable_signals"),
GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_ENABLE_RESTRICTED_SIGNALS, "railtype_enable_restricted_signals"),
GRFPropertyMapDefinition(),

@ -114,6 +114,7 @@ enum Action0RemapPropertyIds {
A0RPI_STATION_DISALLOWED_BRIDGE_PILLARS,
A0RPI_BRIDGE_MENU_ICON,
A0RPI_BRIDGE_PILLAR_FLAGS,
A0RPI_BRIDGE_AVAILABILITY_FLAGS,
A0RPI_RAILTYPE_ENABLE_PROGRAMMABLE_SIGNALS,
A0RPI_RAILTYPE_ENABLE_RESTRICTED_SIGNALS,
};

@ -20,7 +20,9 @@
/* static */ bool ScriptBridge::IsValidBridge(BridgeID bridge_id)
{
return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= _cur_year;
if (bridge_id >= MAX_BRIDGES) return false;
const BridgeSpec *b = ::GetBridgeSpec(bridge_id);
return b->avail_year <= _cur_year && !HasBit(b->ctrl_flags, BSCF_NOT_AVAILABLE_AI_GS);
}
/* static */ bool ScriptBridge::IsBridgeTile(TileIndex tile)
@ -77,7 +79,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType()));
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD);
uint type = 0;
uint type = (1 << 17);
switch (vehicle_type) {
case ScriptVehicle::VT_ROAD:
type |= (TRANSPORT_ROAD << 15);

@ -1303,7 +1303,7 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi
for (;;) {
/* Can we actually build the bridge? */
RoadType rt = GetTownRoadType(t);
if (DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE).Succeeded()) {
if (MayTownBuildBridgeType(bridge_type) && DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE).Succeeded()) {
DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE);
_grow_town_result = GROWTH_SUCCEED;
return true;

@ -274,6 +274,14 @@ CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoC
return_cmd_error(STR_ERROR_BRIDGE_TOO_LONG);
}
bool MayTownBuildBridgeType(BridgeType bridge_type)
{
if (bridge_type >= MAX_BRIDGES) return false;
const BridgeSpec *b = GetBridgeSpec(bridge_type);
return !HasBit(b->ctrl_flags, BSCF_NOT_AVAILABLE_TOWN);
}
/**
* Build a Bridge
* @param end_tile end tile
@ -283,6 +291,7 @@ CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoC
* - p2 = (bit 0- 7) - bridge type (hi bh)
* - p2 = (bit 8-13) - rail type or road types.
* - p2 = (bit 15-16) - transport type.
* - p2 = (bit 17) - script command
* @param text unused
* @return the cost of this operation or an error
*/
@ -300,6 +309,8 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
TransportType transport_type = Extract<TransportType, 15, 2>(p2);
bool script_cmd = HasBit(p2, 17);
/* type of bridge */
switch (transport_type) {
case TRANSPORT_ROAD:
@ -354,6 +365,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
/* set and test bridge length, availability */
CommandCost ret = CheckBridgeAvailability(bridge_type, bridge_len, flags);
if (ret.Failed()) return ret;
if (script_cmd && HasBit(GetBridgeSpec(bridge_type)->ctrl_flags, BSCF_NOT_AVAILABLE_AI_GS)) return CMD_ERROR;
} else {
if (bridge_len > _settings_game.construction.max_bridge_length) return_cmd_error(STR_ERROR_BRIDGE_TOO_LONG);
}

Loading…
Cancel
Save