Implement NewGRF Station var 0x42 (rail type) for unbuilt stations

pull/73/head
Jonathan G Rennison 6 years ago
parent 743802974c
commit 76a7b70cad

@ -280,7 +280,7 @@ TownScopeResolver *StationResolverObject::GetTown()
case 0x46:
case 0x47:
case 0x49: return 0x2110000; // Platforms, tracks & position
case 0x42: return 0; // Rail type (XXX Get current type from GUI?)
case 0x42: return GetReverseRailTypeTranslation (this->rt, this->statspec->grf_prop.grffile) << 8; // Rail type
case 0x43: return GetCompanyInfo(_current_company); // Station owner
case 0x44: return 2; // PBS status
case 0x67: // Land info of nearby tile
@ -534,14 +534,15 @@ uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, byte variable,
* @param statspec Station (type) specification.
* @param st Instance of the station.
* @param tile %Tile of the station.
* @param rt %RailType of the station (unbuilt stations only).
* @param callback Callback ID.
* @param callback_param1 First parameter (var 10) of the callback.
* @param callback_param2 Second parameter (var 18) of the callback.
*/
StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile,
StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt,
CallbackID callback, uint32 callback_param1, uint32 callback_param2)
: ResolverObject(statspec->grf_prop.grffile, callback, callback_param1, callback_param2),
station_scope(*this, statspec, st, tile), town_scope(NULL)
station_scope(*this, statspec, st, tile, rt), town_scope(NULL)
{
/* Invalidate all cached vars */
_svc.valid = 0;
@ -583,12 +584,13 @@ StationResolverObject::~StationResolverObject()
* @param statspec Station spec
* @param st Station (NULL in GUI)
* @param tile Station tile being drawn (INVALID_TILE in GUI)
* @param rt %RailType of the station (unbuilt stations only).
* @param var10 Value to put in variable 10; normally 0; 1 when resolving the groundsprite and SSF_SEPARATE_GROUND is set.
* @return First sprite of the Action 1 spriteset to use, minus an offset of 0x42D to accommodate for weird NewGRF specs.
*/
SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32 var10)
SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt, uint32 var10)
{
StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, var10);
StationResolverObject object(statspec, st, tile, rt, CBID_NO_CALLBACK, var10);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_RESULT) return 0;
return group->GetResult() - 0x42D;
@ -606,7 +608,7 @@ SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st
SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint layout, uint edge_info)
{
/* callback_param1 == 2 means we are resolving the foundation sprites. */
StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, 2, layout | (edge_info << 16));
StationResolverObject object(statspec, st, tile, INVALID_RAILTYPE, CBID_NO_CALLBACK, 2, layout | (edge_info << 16));
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_RESULT) return 0;
@ -616,9 +618,9 @@ SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseS
}
uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile)
uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt)
{
StationResolverObject object(statspec, st, tile, callback, param1, param2);
StationResolverObject object(statspec, st, tile, rt, callback, param1, param2);
return object.ResolveCallback();
}
@ -632,12 +634,12 @@ uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, con
* @param numtracks Number of platforms.
* @return Succeeded or failed command.
*/
CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, const StationSpec *statspec, Axis axis, byte plat_len, byte numtracks)
CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, RailType rt, const StationSpec *statspec, Axis axis, byte plat_len, byte numtracks)
{
TileIndexDiff diff = cur_tile - north_tile;
Slope slope = GetTileSlope(cur_tile);
StationResolverObject object(statspec, NULL, cur_tile, CBID_STATION_LAND_SLOPE_CHECK,
StationResolverObject object(statspec, NULL, cur_tile, rt, CBID_STATION_LAND_SLOPE_CHECK,
(slope << 4) | (slope ^ (axis == AXIS_Y && HasBit(slope, CORNER_W) != HasBit(slope, CORNER_E) ? SLOPE_EW : 0)),
(numtracks << 24) | (plat_len << 16) | (axis == AXIS_Y ? TileX(diff) << 8 | TileY(diff) : TileY(diff) << 8 | TileX(diff)));
object.station_scope.axis = axis;
@ -771,7 +773,7 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID
if (statspec == NULL) return false;
if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) {
uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE);
uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE, railtype);
if (callback != CALLBACK_FAILED) tile = callback;
}
@ -797,7 +799,7 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID
uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground);
uint8 var10;
FOR_EACH_SET_BIT(var10, var10_values) {
uint32 var10_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, var10);
uint32 var10_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, railtype, var10);
layout->ProcessRegisters(var10, var10_relocation, separate_ground);
}
@ -806,9 +808,9 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID
total_offset = 0;
} else {
/* Simple sprite layout */
ground_relocation = relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, 0);
ground_relocation = relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, railtype, 0);
if (HasBit(sprites->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
ground_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, 1);
ground_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, railtype, 1);
}
ground_relocation += rti->fallback_railtype;
}
@ -884,7 +886,7 @@ bool CanStationTileHaveWires(TileIndex tile)
/** Wrapper for animation control, see #GetStationCallback. */
uint16 GetAnimStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, int extra_data)
{
return GetStationCallback(callback, param1, param2, statspec, st, tile);
return GetStationCallback(callback, param1, param2, statspec, st, tile, INVALID_RAILTYPE);
}
/** Helper class for animation control. */
@ -990,7 +992,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg
}
if (cargo_type == CT_INVALID || HasBit(ss->cargo_triggers, cargo_type)) {
StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0);
StationResolverObject object(ss, st, tile, INVALID_RAILTYPE, CBID_RANDOM_TRIGGER, 0);
object.waiting_triggers = st->waiting_triggers;
const SpriteGroup *group = object.Resolve();

@ -29,6 +29,7 @@ struct StationScopeResolver : public ScopeResolver {
const struct StationSpec *statspec; ///< Station (type) specification.
CargoID cargo_type; ///< Type of cargo of the station.
Axis axis; ///< Station axis, used only for the slope check callback.
RailType rt; ///< %RailType of the station (unbuilt stations only).
/**
* Constructor for station scopes.
@ -36,9 +37,10 @@ struct StationScopeResolver : public ScopeResolver {
* @param statspec Station (type) specification.
* @param st Instance of the station.
* @param tile %Tile of the station.
* @param rt %RailType of the station (unbuilt stations only).
*/
StationScopeResolver(ResolverObject &ro, const StationSpec *statspec, BaseStation *st, TileIndex tile)
: ScopeResolver(ro), tile(tile), st(st), statspec(statspec), cargo_type(CT_INVALID), axis(INVALID_AXIS)
StationScopeResolver(ResolverObject &ro, const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt)
: ScopeResolver(ro), tile(tile), st(st), statspec(statspec), cargo_type(CT_INVALID), axis(INVALID_AXIS), rt(rt)
{
}
@ -53,7 +55,7 @@ struct StationResolverObject : public ResolverObject {
StationScopeResolver station_scope; ///< The station scope resolver.
TownScopeResolver *town_scope; ///< The town scope resolver (created on the first call).
StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile,
StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt,
CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
~StationResolverObject();
@ -179,10 +181,10 @@ const StationSpec *GetStationSpec(TileIndex t);
/* Evaluate a tile's position within a station, and return the result a bitstuffed format. */
uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred);
SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32 var10 = 0);
SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt, uint32 var10 = 0);
SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint layout, uint edge_info);
uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile);
CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, const StationSpec *statspec, Axis axis, byte plat_len, byte numtracks);
uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt);
CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, RailType rt, const StationSpec *statspec, Axis axis, byte plat_len, byte numtracks);
/* Allocate a StationSpec to a Station. This is called once per build operation. */
int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec);

@ -90,7 +90,7 @@ static bool IsStationAvailable(const StationSpec *statspec)
{
if (statspec == NULL || !HasBit(statspec->callback_mask, CBM_STATION_AVAIL)) return true;
uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE);
uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE, _cur_railtype);
if (cb_res == CALLBACK_FAILED) return true;
return Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res);

@ -805,7 +805,7 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl
if (slope_cb) {
/* Do slope check if requested. */
ret = PerformStationTileSlopeCheck(tile_area.tile, tile_cur, statspec, axis, plat_len, numtracks);
ret = PerformStationTileSlopeCheck(tile_area.tile, tile_cur, rt, statspec, axis, plat_len, numtracks);
if (ret.Failed()) return ret;
}
@ -1289,7 +1289,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32
/* Check if the station is buildable */
if (HasBit(statspec->callback_mask, CBM_STATION_AVAIL)) {
uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE);
uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE, rt);
if (cb_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res)) return CMD_ERROR;
}
}
@ -1360,7 +1360,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32
uint32 platinfo = GetPlatformInfo(AXIS_X, GetStationGfx(tile), plat_len, numtracks_orig, plat_len - w, numtracks_orig - numtracks, false);
/* As the station is not yet completely finished, the station does not yet exist. */
uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, NULL, tile);
uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, NULL, tile, rt);
if (callback != CALLBACK_FAILED) {
if (callback < 8) {
SetStationGfx(tile, (callback & ~1) + axis);
@ -2844,7 +2844,7 @@ static void DrawTile_Station(TileInfo *ti)
tile_layout = GetStationGfx(ti->tile);
if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) {
uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile, INVALID_RAILTYPE);
if (callback != CALLBACK_FAILED) tile_layout = (callback & ~1) + GetRailStationAxis(ti->tile);
}
@ -3002,7 +3002,7 @@ draw_default_foundation:
uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground);
uint8 var10;
FOR_EACH_SET_BIT(var10, var10_values) {
uint32 var10_relocation = GetCustomStationRelocation(statspec, st, ti->tile, var10);
uint32 var10_relocation = GetCustomStationRelocation(statspec, st, ti->tile, INVALID_RAILTYPE, var10);
layout->ProcessRegisters(var10, var10_relocation, separate_ground);
}
tmp_rail_layout.seq = layout->GetLayout(&tmp_rail_layout.ground);
@ -3010,9 +3010,9 @@ draw_default_foundation:
total_offset = 0;
} else if (statspec != NULL) {
/* Simple sprite layout */
ground_relocation = relocation = GetCustomStationRelocation(statspec, st, ti->tile, 0);
ground_relocation = relocation = GetCustomStationRelocation(statspec, st, ti->tile, INVALID_RAILTYPE, 0);
if (HasBit(statspec->flags, SSF_SEPARATE_GROUND)) {
ground_relocation = GetCustomStationRelocation(statspec, st, ti->tile, 1);
ground_relocation = GetCustomStationRelocation(statspec, st, ti->tile, INVALID_RAILTYPE, 1);
}
ground_relocation += rti->fallback_railtype;
}

@ -154,7 +154,7 @@ class NIHStation : public NIHelper {
/* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const
{
StationResolverObject ro(GetStationSpec(index), Station::GetByTile(index), index);
StationResolverObject ro(GetStationSpec(index), Station::GetByTile(index), index, INVALID_RAILTYPE);
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
}
};

Loading…
Cancel
Save