mirror of https://github.com/OpenTTD/OpenTTD
(svn r12871) [0.6] -Backport from trunk r12819, r12818, r12759:
- Fix: Inconsistent use of 8/15-bitness of NewGRF callback results with respect to TTDP's implementation of the specification (r12819, r12818, r12759)release/0.6
parent
f126c2e66f
commit
9241c4649d
|
@ -529,7 +529,7 @@ CommandCost CmdStartStopAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32
|
||||||
/* Check if this aircraft can be started/stopped. The callback will fail or
|
/* Check if this aircraft can be started/stopped. The callback will fail or
|
||||||
* return 0xFF if it can. */
|
* return 0xFF if it can. */
|
||||||
uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
||||||
if (callback != CALLBACK_FAILED && callback != 0xFF) {
|
if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
|
||||||
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
||||||
return_cmd_error(error);
|
return_cmd_error(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
|
||||||
uint i;
|
uint i;
|
||||||
for (i = 1; i < MAX_UVALUE(EngineID); i++) {
|
for (i = 1; i < MAX_UVALUE(EngineID); i++) {
|
||||||
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine_type, v);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine_type, v);
|
||||||
if (callback == CALLBACK_FAILED || callback == 0xFF) break;
|
if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete v;
|
delete v;
|
||||||
|
@ -53,7 +53,7 @@ uint16 *GetCapacityOfArticulatedParts(EngineID engine, VehicleType type)
|
||||||
|
|
||||||
for (uint i = 1; i < MAX_UVALUE(EngineID); i++) {
|
for (uint i = 1; i < MAX_UVALUE(EngineID); i++) {
|
||||||
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine, NULL);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine, NULL);
|
||||||
if (callback == CALLBACK_FAILED || callback == 0xFF) break;
|
if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) break;
|
||||||
|
|
||||||
EngineID artic_engine = GetFirstEngineOfType(type) + GB(callback, 0, 7);
|
EngineID artic_engine = GetFirstEngineOfType(type) + GB(callback, 0, 7);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ void AddArticulatedParts(Vehicle **vl, VehicleType type)
|
||||||
|
|
||||||
for (uint i = 1; i < MAX_UVALUE(EngineID); i++) {
|
for (uint i = 1; i < MAX_UVALUE(EngineID); i++) {
|
||||||
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, v->engine_type, v);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, v->engine_type, v);
|
||||||
if (callback == CALLBACK_FAILED || callback == 0xFF) return;
|
if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) return;
|
||||||
|
|
||||||
/* Attempt to use pre-allocated vehicles until they run out. This can happen
|
/* Attempt to use pre-allocated vehicles until they run out. This can happen
|
||||||
* if the callback returns different values depending on the cargo type. */
|
* if the callback returns different values depending on the cargo type. */
|
||||||
|
|
|
@ -1597,7 +1597,7 @@ static void LoadUnloadVehicle(Vehicle *v, int *cargo_left)
|
||||||
byte load_amount = EngInfo(v->engine_type)->load_amount;
|
byte load_amount = EngInfo(v->engine_type)->load_amount;
|
||||||
if (_patches.gradual_loading && HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_LOAD_AMOUNT)) {
|
if (_patches.gradual_loading && HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_LOAD_AMOUNT)) {
|
||||||
uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
|
uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
|
||||||
if (cb_load_amount != CALLBACK_FAILED && cb_load_amount != 0) load_amount = cb_load_amount & 0xFF;
|
if (cb_load_amount != CALLBACK_FAILED && GB(cb_load_amount, 0, 8) != 0) load_amount = GB(cb_load_amount, 0, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
GoodsEntry *ge = &st->goods[v->cargo_type];
|
GoodsEntry *ge = &st->goods[v->cargo_type];
|
||||||
|
|
|
@ -175,5 +175,7 @@ uint16 GetAiPurchaseCallbackResult(uint8 feature, CargoID cargo_type, uint8 defa
|
||||||
object.u.generic.count = count;
|
object.u.generic.count = count;
|
||||||
object.u.generic.station_size = station_size;
|
object.u.generic.station_size = station_size;
|
||||||
|
|
||||||
return GetGenericCallbackResult(feature, &object, file);
|
uint16 callback = GetGenericCallbackResult(feature, &object, file);
|
||||||
|
if (callback != CALLBACK_FAILED) callback = GB(callback, 0, 8);
|
||||||
|
return callback;
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,7 +521,7 @@ bool NewHouseTileLoop(TileIndex tile)
|
||||||
/* Check callback 21, which determines if a house should be destroyed. */
|
/* Check callback 21, which determines if a house should be destroyed. */
|
||||||
if (HasBit(hs->callback_mask, CBM_HOUSE_DESTRUCTION)) {
|
if (HasBit(hs->callback_mask, CBM_HOUSE_DESTRUCTION)) {
|
||||||
uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
|
uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
|
||||||
if (callback_res != CALLBACK_FAILED && callback_res > 0) {
|
if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) > 0) {
|
||||||
ClearTownHouse(GetTownByTile(tile), tile);
|
ClearTownHouse(GetTownByTile(tile), tile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,37 +80,6 @@ void InitializeSpriteGroupPool()
|
||||||
TemporaryStorageArray<uint32, 0x110> _temp_store;
|
TemporaryStorageArray<uint32, 0x110> _temp_store;
|
||||||
|
|
||||||
|
|
||||||
static inline bool Is8BitCallback(const ResolverObject *object)
|
|
||||||
{
|
|
||||||
/* Var 0x7E procedure results are always 15 bit */
|
|
||||||
if (object == NULL || object->procedure_call) return false;
|
|
||||||
|
|
||||||
switch (object->callback) {
|
|
||||||
/* All these functions are 15 bit callbacks */
|
|
||||||
case CBID_STATION_SPRITE_LAYOUT:
|
|
||||||
case CBID_VEHICLE_REFIT_CAPACITY:
|
|
||||||
case CBID_HOUSE_COLOUR:
|
|
||||||
case CBID_HOUSE_CARGO_ACCEPTANCE:
|
|
||||||
case CBID_INDUSTRY_LOCATION:
|
|
||||||
case CBID_HOUSE_ACCEPT_CARGO:
|
|
||||||
case CBID_INDTILE_CARGO_ACCEPTANCE:
|
|
||||||
case CBID_INDTILE_ACCEPT_CARGO:
|
|
||||||
case CBID_VEHICLE_COLOUR_MAPPING:
|
|
||||||
case CBID_HOUSE_PRODUCE_CARGO:
|
|
||||||
case CBID_INDTILE_SHAPE_CHECK:
|
|
||||||
case CBID_VEHICLE_SOUND_EFFECT:
|
|
||||||
case CBID_VEHICLE_MODIFY_PROPERTY: // depends on queried property
|
|
||||||
case CBID_CARGO_PROFIT_CALC:
|
|
||||||
case CBID_SOUNDS_AMBIENT_EFFECT:
|
|
||||||
case CBID_CARGO_STATION_RATING_CALC:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* The rest is a 8 bit callback, which should be truncated properly */
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
||||||
{
|
{
|
||||||
/* First handle variables common with Action7/9/D */
|
/* First handle variables common with Action7/9/D */
|
||||||
|
@ -236,7 +205,7 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol
|
||||||
if (group->g.determ.num_ranges == 0) {
|
if (group->g.determ.num_ranges == 0) {
|
||||||
/* nvar == 0 is a special case -- we turn our value into a callback result */
|
/* nvar == 0 is a special case -- we turn our value into a callback result */
|
||||||
nvarzero.type = SGT_CALLBACK;
|
nvarzero.type = SGT_CALLBACK;
|
||||||
nvarzero.g.callback.result = GB(value, 0, Is8BitCallback(object) ? 8 : 15);
|
nvarzero.g.callback.result = value;
|
||||||
return &nvarzero;
|
return &nvarzero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,14 +263,6 @@ const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
|
||||||
case SGT_REAL: return object->ResolveReal(object, group);
|
case SGT_REAL: return object->ResolveReal(object, group);
|
||||||
case SGT_DETERMINISTIC: return ResolveVariable(group, object);
|
case SGT_DETERMINISTIC: return ResolveVariable(group, object);
|
||||||
case SGT_RANDOMIZED: return ResolveRandom(group, object);
|
case SGT_RANDOMIZED: return ResolveRandom(group, object);
|
||||||
case SGT_CALLBACK: {
|
|
||||||
if (!Is8BitCallback(object)) return group;
|
|
||||||
|
|
||||||
static SpriteGroup result8bit;
|
|
||||||
result8bit.type = SGT_CALLBACK;
|
|
||||||
result8bit.g.callback.result = GB(group->g.callback.result, 0, 8);
|
|
||||||
return &result8bit;
|
|
||||||
}
|
|
||||||
default: return group;
|
default: return group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -932,7 +932,7 @@ static void StationBuildWndProc(Window *w, WindowEvent *e)
|
||||||
const StationSpec *statspec = GetCustomStationSpec(_railstation.station_class, i);
|
const StationSpec *statspec = GetCustomStationSpec(_railstation.station_class, i);
|
||||||
|
|
||||||
if (statspec != NULL && statspec->name != 0) {
|
if (statspec != NULL && statspec->name != 0) {
|
||||||
if (HasBit(statspec->callbackmask, CBM_STATION_AVAIL) && GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
|
if (HasBit(statspec->callbackmask, CBM_STATION_AVAIL) && GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
|
||||||
GfxFillRect(8, y - 2, 127, y + 10, (1 << PALETTE_MODIFIER_GREYOUT));
|
GfxFillRect(8, y - 2, 127, y + 10, (1 << PALETTE_MODIFIER_GREYOUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1077,7 @@ static void StationBuildWndProc(Window *w, WindowEvent *e)
|
||||||
statspec = GetCustomStationSpec(_railstation.station_class, y);
|
statspec = GetCustomStationSpec(_railstation.station_class, y);
|
||||||
if (statspec != NULL &&
|
if (statspec != NULL &&
|
||||||
HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
|
HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
|
||||||
GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) return;
|
GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
|
||||||
|
|
||||||
_railstation.station_type = y;
|
_railstation.station_type = y;
|
||||||
|
|
||||||
|
@ -1495,7 +1495,7 @@ static void BuildWaypointWndProc(Window *w, WindowEvent *e)
|
||||||
|
|
||||||
if (statspec != NULL &&
|
if (statspec != NULL &&
|
||||||
HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
|
HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
|
||||||
GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
|
GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
|
||||||
GfxFillRect(4 + i * 68, 18, 67 + i * 68, 75, (1 << PALETTE_MODIFIER_GREYOUT));
|
GfxFillRect(4 + i * 68, 18, 67 + i * 68, 75, (1 << PALETTE_MODIFIER_GREYOUT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1515,7 +1515,7 @@ static void BuildWaypointWndProc(Window *w, WindowEvent *e)
|
||||||
const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, type);
|
const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, type);
|
||||||
if (statspec != NULL &&
|
if (statspec != NULL &&
|
||||||
HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
|
HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
|
||||||
GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) return;
|
GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
|
||||||
|
|
||||||
_cur_waypoint_type = type;
|
_cur_waypoint_type = type;
|
||||||
SndPlayFx(SND_15_BEEP);
|
SndPlayFx(SND_15_BEEP);
|
||||||
|
|
|
@ -292,19 +292,16 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
*/
|
*/
|
||||||
CommandCost CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
CommandCost CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
Vehicle *v;
|
|
||||||
uint16 callback;
|
|
||||||
|
|
||||||
if (!IsValidVehicleID(p1)) return CMD_ERROR;
|
if (!IsValidVehicleID(p1)) return CMD_ERROR;
|
||||||
|
|
||||||
v = GetVehicle(p1);
|
Vehicle *v = GetVehicle(p1);
|
||||||
|
|
||||||
if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
|
if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
|
||||||
|
|
||||||
/* Check if this road veh can be started/stopped. The callback will fail or
|
/* Check if this road veh can be started/stopped. The callback will fail or
|
||||||
* return 0xFF if it can. */
|
* return 0xFF if it can. */
|
||||||
callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
||||||
if (callback != CALLBACK_FAILED && callback != 0xFF) {
|
if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
|
||||||
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
||||||
return_cmd_error(error);
|
return_cmd_error(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -935,19 +935,16 @@ CommandCost CmdSellShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
*/
|
*/
|
||||||
CommandCost CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
CommandCost CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
Vehicle *v;
|
|
||||||
uint16 callback;
|
|
||||||
|
|
||||||
if (!IsValidVehicleID(p1)) return CMD_ERROR;
|
if (!IsValidVehicleID(p1)) return CMD_ERROR;
|
||||||
|
|
||||||
v = GetVehicle(p1);
|
Vehicle *v = GetVehicle(p1);
|
||||||
|
|
||||||
if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
|
if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
|
||||||
|
|
||||||
/* Check if this ship can be started/stopped. The callback will fail or
|
/* Check if this ship can be started/stopped. The callback will fail or
|
||||||
* return 0xFF if it can. */
|
* return 0xFF if it can. */
|
||||||
callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
||||||
if (callback != CALLBACK_FAILED && callback != 0xFF) {
|
if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
|
||||||
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
||||||
return_cmd_error(error);
|
return_cmd_error(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1012,7 +1012,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the station is buildable */
|
/* Check if the station is buildable */
|
||||||
if (HasBit(statspec->callbackmask, CBM_STATION_AVAIL) && GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
|
if (HasBit(statspec->callbackmask, CBM_STATION_AVAIL) && GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1905,7 +1905,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||||
|
|
||||||
if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
|
if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
|
||||||
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile);
|
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile);
|
||||||
if (callback_res != CALLBACK_FAILED && callback_res == 0) continue;
|
if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ void TrainConsistChanged(Vehicle* v)
|
||||||
if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) {
|
if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) {
|
||||||
uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
|
uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
|
||||||
|
|
||||||
if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
|
if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = GB(callback, 0, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
|
if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
|
||||||
|
@ -1302,7 +1302,7 @@ CommandCost CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
|
||||||
/* Check if this train can be started/stopped. The callback will fail or
|
/* Check if this train can be started/stopped. The callback will fail or
|
||||||
* return 0xFF if it can. */
|
* return 0xFF if it can. */
|
||||||
uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
||||||
if (callback != CALLBACK_FAILED && callback != 0xFF) {
|
if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
|
||||||
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
|
||||||
return_cmd_error(error);
|
return_cmd_error(error);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue