1
0
Fork 0

Compare commits

...

9 Commits

Author SHA1 Message Date
PeterN a0b2f28f9c
Codechange: Use std::copy/fill pattern to initialize rail and road specs. (#11285)
This avoids use of lengthof and array indices.
2023-09-10 23:01:08 +00:00
Patric Stout 7e3cdbaf62 Fix: mark next_station as INVALID_STATION when loading from older savegames 2023-09-11 00:25:47 +02:00
Patric Stout 9e3763cfb3 Fix b0e73277: save/load next_station for CargoPacket again 2023-09-11 00:25:47 +02:00
Patric Stout 1243c331b6 Fix: don't compare next_station when trying to merge CargoPackets
For vehicle packets they shouldn't be compared, and for station
packets they are already in a bucket per next_station.
2023-09-11 00:25:47 +02:00
Patric Stout 9f8c1ea552 Codechange: rename next_station to next_hop to avoid confusing with another next_station 2023-09-11 00:25:47 +02:00
Patric Stout a0f6983be4 Codechange: remove parameter from VehicleCargoList::Reassign that is always INVALID_STATION 2023-09-11 00:25:47 +02:00
PeterN 6643c010bd
Fix: NewGRF house class mappings were not reset between games. (#11279) 2023-09-10 18:55:37 +01:00
Michael Lutz 1c620b349f Feature: [NewGRF] Related Act2 objects for airports and airport tiles.
Airports are similar two stations and industries, both of which have the town as related object.
Airport tiles are similar to industry tiles, which have the industry as related object.
This seems a sensible structure, so let's make it Airport Tile -> Airport -> Town.
2023-09-10 19:38:18 +02:00
Michael Lutz a6f2f3c042 Add: [NewGRF] Inspection window for airports.
As as the station window combines all station types, accessing the
debug view is via the parent of the airport tile only.
2023-09-10 19:38:18 +02:00
18 changed files with 173 additions and 96 deletions

View File

@ -167,7 +167,7 @@ bool CargoTransfer::operator()(CargoPacket *cp)
if (cp_new == nullptr) return false; if (cp_new == nullptr) return false;
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
/* No transfer credits here as they were already granted during Stage(). */ /* No transfer credits here as they were already granted during Stage(). */
this->destination->Append(cp_new, cp_new->GetNextStation()); this->destination->Append(cp_new, cp_new->GetNextHop());
return cp_new == cp; return cp_new == cp;
} }
@ -217,8 +217,8 @@ bool VehicleCargoReroute::operator()(CargoPacket *cp)
{ {
CargoPacket *cp_new = this->Preprocess(cp); CargoPacket *cp_new = this->Preprocess(cp);
if (cp_new == nullptr) cp_new = cp; if (cp_new == nullptr) cp_new = cp;
if (cp_new->GetNextStation() == this->avoid || cp_new->GetNextStation() == this->avoid2) { if (cp_new->GetNextHop() == this->avoid || cp_new->GetNextHop() == this->avoid2) {
cp->SetNextStation(this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2)); cp->SetNextHop(this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2));
} }
if (this->source != this->destination) { if (this->source != this->destination) {
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());

View File

@ -57,7 +57,7 @@ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t
* @param count Number of cargo entities to put in this packet. * @param count Number of cargo entities to put in this packet.
* @param periods_in_transit Number of cargo aging periods the cargo has been in transit. * @param periods_in_transit Number of cargo aging periods the cargo has been in transit.
* @param first_station Station the cargo was initially loaded. * @param first_station Station the cargo was initially loaded.
* @param next_station Next station the cargo wants to go. * @param next_hop Next station the cargo wants to go.
* @param source_xy Station location the cargo was initially loaded. * @param source_xy Station location the cargo was initially loaded.
* @param feeder_share Feeder share the packet has already accumulated. * @param feeder_share Feeder share the packet has already accumulated.
* @param source_type 'Type' of source the packet comes from (for subsidies). * @param source_type 'Type' of source the packet comes from (for subsidies).
@ -65,7 +65,7 @@ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t
* @note We have to zero memory ourselves here because we are using a 'new' * @note We have to zero memory ourselves here because we are using a 'new'
* that, in contrary to all other pools, does not memset to 0. * that, in contrary to all other pools, does not memset to 0.
*/ */
CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_station, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_hop, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) :
count(count), count(count),
periods_in_transit(periods_in_transit), periods_in_transit(periods_in_transit),
feeder_share(feeder_share), feeder_share(feeder_share),
@ -73,7 +73,7 @@ CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID
source_id(source_id), source_id(source_id),
source_type(source_type), source_type(source_type),
first_station(first_station), first_station(first_station),
next_station(next_station) next_hop(next_hop)
{ {
assert(count != 0); assert(count != 0);
} }
@ -88,7 +88,7 @@ CargoPacket *CargoPacket::Split(uint new_size)
if (!CargoPacket::CanAllocateItem()) return nullptr; if (!CargoPacket::CanAllocateItem()) return nullptr;
Money fs = this->GetFeederShare(new_size); Money fs = this->GetFeederShare(new_size);
CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->next_station, this->source_xy, fs, this->source_type, this->source_id); CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->next_hop, this->source_xy, fs, this->source_type, this->source_id);
this->feeder_share -= fs; this->feeder_share -= fs;
this->count -= new_size; this->count -= new_size;
return cp_new; return cp_new;
@ -501,7 +501,7 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID
share = payment->PayTransfer(cp, cp->count); share = payment->PayTransfer(cp, cp->count);
cp->AddFeederShare(share); cp->AddFeederShare(share);
this->feeder_share += share; this->feeder_share += share;
cp->next_station = cargo_next; cp->next_hop = cargo_next;
break; break;
default: default:
NOT_REACHED(); NOT_REACHED();
@ -533,7 +533,7 @@ void VehicleCargoList::InvalidateCache()
* @return Amount of cargo actually reassigned. * @return Amount of cargo actually reassigned.
*/ */
template<VehicleCargoList::MoveToAction Tfrom, VehicleCargoList::MoveToAction Tto> template<VehicleCargoList::MoveToAction Tfrom, VehicleCargoList::MoveToAction Tto>
uint VehicleCargoList::Reassign(uint max_move, StationID) uint VehicleCargoList::Reassign(uint max_move)
{ {
static_assert(Tfrom != MTA_TRANSFER && Tto != MTA_TRANSFER); static_assert(Tfrom != MTA_TRANSFER && Tto != MTA_TRANSFER);
static_assert(Tfrom - Tto == 1 || Tto - Tfrom == 1); static_assert(Tfrom - Tto == 1 || Tto - Tfrom == 1);
@ -547,11 +547,10 @@ uint VehicleCargoList::Reassign(uint max_move, StationID)
* Reassign cargo from MTA_DELIVER to MTA_TRANSFER and take care of the next * Reassign cargo from MTA_DELIVER to MTA_TRANSFER and take care of the next
* station the cargo wants to visit. * station the cargo wants to visit.
* @param max_move Maximum amount of cargo to reassign. * @param max_move Maximum amount of cargo to reassign.
* @param next_station Station to record as next hop in the reassigned packets.
* @return Amount of cargo actually reassigned. * @return Amount of cargo actually reassigned.
*/ */
template<> template<>
uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(uint max_move, StationID next_station) uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(uint max_move)
{ {
max_move = std::min(this->action_counts[MTA_DELIVER], max_move); max_move = std::min(this->action_counts[MTA_DELIVER], max_move);
@ -565,7 +564,7 @@ uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList:
sum -= cp_split->Count(); sum -= cp_split->Count();
this->packets.insert(it, cp_split); this->packets.insert(it, cp_split);
} }
cp->next_station = next_station; cp->next_hop = INVALID_STATION;
} }
this->action_counts[MTA_DELIVER] -= max_move; this->action_counts[MTA_DELIVER] -= max_move;
@ -844,4 +843,4 @@ uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID
*/ */
template class CargoList<VehicleCargoList, CargoPacketList>; template class CargoList<VehicleCargoList, CargoPacketList>;
template class CargoList<StationCargoList, StationCargoPacketMap>; template class CargoList<StationCargoList, StationCargoPacketMap>;
template uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_KEEP>(uint, StationID); template uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_KEEP>(uint);

View File

@ -49,7 +49,7 @@ private:
SourceType source_type{SourceType::Industry}; ///< Type of \c source_id. SourceType source_type{SourceType::Industry}; ///< Type of \c source_id.
StationID first_station{INVALID_STATION}; ///< The station where the cargo came from first. StationID first_station{INVALID_STATION}; ///< The station where the cargo came from first.
StationID next_station{INVALID_STATION}; ///< Station where the cargo wants to go next. StationID next_hop{INVALID_STATION}; ///< Station where the cargo wants to go next.
/** The CargoList caches, thus needs to know about it. */ /** The CargoList caches, thus needs to know about it. */
template <class Tinst, class Tcont> friend class CargoList; template <class Tinst, class Tcont> friend class CargoList;
@ -74,11 +74,11 @@ public:
/** /**
* Sets the station where the packet is supposed to go next. * Sets the station where the packet is supposed to go next.
* @param next_station Next station the packet should go to. * @param next_hop Next station the packet should go to.
*/ */
void SetNextStation(StationID next_station) void SetNextHop(StationID next_hop)
{ {
this->next_station = next_station; this->next_hop = next_hop;
} }
/** /**
@ -172,9 +172,9 @@ public:
* Gets the ID of station the cargo wants to go next. * Gets the ID of station the cargo wants to go next.
* @return Next station for this packets. * @return Next station for this packets.
*/ */
inline StationID GetNextStation() const inline StationID GetNextHop() const
{ {
return this->next_station; return this->next_hop;
} }
static void InvalidateAllFrom(SourceType src_type, SourceID src); static void InvalidateAllFrom(SourceType src_type, SourceID src);
@ -403,7 +403,7 @@ public:
* applicable), return value is amount of cargo actually moved. */ * applicable), return value is amount of cargo actually moved. */
template<MoveToAction Tfrom, MoveToAction Tto> template<MoveToAction Tfrom, MoveToAction Tto>
uint Reassign(uint max_move, StationID update = INVALID_STATION); uint Reassign(uint max_move);
uint Return(uint max_move, StationCargoList *dest, StationID next_station); uint Return(uint max_move, StationCargoList *dest, StationID next_station);
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment); uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment);
uint Shift(uint max_move, VehicleCargoList *dest); uint Shift(uint max_move, VehicleCargoList *dest);
@ -422,7 +422,6 @@ public:
return cp1->source_xy == cp2->source_xy && return cp1->source_xy == cp2->source_xy &&
cp1->periods_in_transit == cp2->periods_in_transit && cp1->periods_in_transit == cp2->periods_in_transit &&
cp1->source_type == cp2->source_type && cp1->source_type == cp2->source_type &&
cp1->next_station == cp2->next_station &&
cp1->source_id == cp2->source_id; cp1->source_id == cp2->source_id;
} }
}; };
@ -537,7 +536,6 @@ public:
return cp1->source_xy == cp2->source_xy && return cp1->source_xy == cp2->source_xy &&
cp1->periods_in_transit == cp2->periods_in_transit && cp1->periods_in_transit == cp2->periods_in_transit &&
cp1->source_type == cp2->source_type && cp1->source_type == cp2->source_type &&
cp1->next_station == cp2->next_station &&
cp1->source_id == cp2->source_id; cp1->source_id == cp2->source_id;
} }
}; };

View File

@ -1689,7 +1689,7 @@ static void LoadUnloadVehicle(Vehicle *front)
if (front->current_order.GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) { if (front->current_order.GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) {
/* Transfer instead of delivering. */ /* Transfer instead of delivering. */
v->cargo.Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>( v->cargo.Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(
v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER), INVALID_STATION); v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER));
} else { } else {
uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER); uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER);
if (v->cargo_cap < new_remaining) { if (v->cargo_cap < new_remaining) {

View File

@ -14,53 +14,10 @@
#include "newgrf_text.h" #include "newgrf_text.h"
#include "station_base.h" #include "station_base.h"
#include "newgrf_class_func.h" #include "newgrf_class_func.h"
#include "town.h"
#include "safeguards.h" #include "safeguards.h"
/** Resolver for the airport scope. */
struct AirportScopeResolver : public ScopeResolver {
struct Station *st; ///< Station of the airport for which the callback is run, or \c nullptr for build gui.
byte airport_id; ///< Type of airport for which the callback is run.
byte layout; ///< Layout of the airport to build.
TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks.
/**
* Constructor of the scope resolver for an airport.
* @param ro Surrounding resolver.
* @param tile %Tile for the callback, only valid for airporttile callbacks.
* @param st %Station of the airport for which the callback is run, or \c nullptr for build gui.
* @param airport_id Type of airport for which the callback is run.
* @param layout Layout of the airport to build.
*/
AirportScopeResolver(ResolverObject &ro, TileIndex tile, Station *st, byte airport_id, byte layout)
: ScopeResolver(ro), st(st), airport_id(airport_id), layout(layout), tile(tile)
{
}
uint32_t GetRandomBits() const override;
uint32_t GetVariable(byte variable, uint32_t parameter, bool *available) const override;
void StorePSA(uint pos, int32_t value) override;
};
/** Resolver object for airports. */
struct AirportResolverObject : public ResolverObject {
AirportScopeResolver airport_scope;
AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout,
CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0);
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override
{
switch (scope) {
case VSG_SCOPE_SELF: return &this->airport_scope;
default: return ResolverObject::GetScope(scope, relative);
}
}
GrfSpecFeature GetFeature() const override;
uint32_t GetDebugID() const override;
};
/** /**
* Reset airport classes to their default state. * Reset airport classes to their default state.
* This includes initialising the defaults classes with an empty * This includes initialising the defaults classes with an empty
@ -254,6 +211,26 @@ uint32_t AirportResolverObject::GetDebugID() const
this->st->airport.psa->StoreValue(pos, value); this->st->airport.psa->StoreValue(pos, value);
} }
/**
* Get the town scope associated with a station, if it exists.
* On the first call, the town scope is created (if possible).
* @return Town scope, if available.
*/
TownScopeResolver *AirportResolverObject::GetTown()
{
if (!this->town_scope) {
Town *t = nullptr;
if (this->airport_scope.st != nullptr) {
t = this->airport_scope.st->town;
} else if (this->airport_scope.tile != INVALID_TILE) {
t = ClosestTownFromTile(this->airport_scope.tile, UINT_MAX);
}
if (t == nullptr) return nullptr;
this->town_scope.reset(new TownScopeResolver(*this, t, this->airport_scope.st == nullptr));
}
return this->town_scope.get();
}
/** /**
* Constructor of the airport resolver. * Constructor of the airport resolver.
* @param tile %Tile for the callback, only valid for airporttile callbacks. * @param tile %Tile for the callback, only valid for airporttile callbacks.

View File

@ -14,6 +14,8 @@
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
#include "newgrf_class.h" #include "newgrf_class.h"
#include "newgrf_commons.h" #include "newgrf_commons.h"
#include "newgrf_spritegroup.h"
#include "newgrf_town.h"
#include "tilearea_type.h" #include "tilearea_type.h"
/** Copy from station_map.h */ /** Copy from station_map.h */
@ -143,6 +145,60 @@ typedef NewGRFClass<AirportSpec, AirportClassID, APC_MAX> AirportClass;
void BindAirportSpecs(); void BindAirportSpecs();
/** Resolver for the airport scope. */
struct AirportScopeResolver : public ScopeResolver {
struct Station *st; ///< Station of the airport for which the callback is run, or \c nullptr for build gui.
byte airport_id; ///< Type of airport for which the callback is run.
byte layout; ///< Layout of the airport to build.
TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks.
/**
* Constructor of the scope resolver for an airport.
* @param ro Surrounding resolver.
* @param tile %Tile for the callback, only valid for airporttile callbacks.
* @param st %Station of the airport for which the callback is run, or \c nullptr for build gui.
* @param airport_id Type of airport for which the callback is run.
* @param layout Layout of the airport to build.
*/
AirportScopeResolver(ResolverObject &ro, TileIndex tile, Station *st, byte airport_id, byte layout)
: ScopeResolver(ro), st(st), airport_id(airport_id), layout(layout), tile(tile)
{
}
uint32_t GetRandomBits() const override;
uint32_t GetVariable(byte variable, uint32_t parameter, bool *available) const override;
void StorePSA(uint pos, int32_t value) override;
};
/** Resolver object for airports. */
struct AirportResolverObject : public ResolverObject {
AirportScopeResolver airport_scope;
std::unique_ptr<TownScopeResolver> town_scope; ///< The town scope resolver (created on the first call).
AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout,
CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0);
TownScopeResolver *GetTown();
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override
{
switch (scope) {
case VSG_SCOPE_SELF: return &this->airport_scope;
case VSG_SCOPE_PARENT:
{
TownScopeResolver *tsr = this->GetTown();
if (tsr != nullptr) return tsr;
FALLTHROUGH;
}
default: return ResolverObject::GetScope(scope, relative);
}
}
GrfSpecFeature GetFeature() const override;
uint32_t GetDebugID() const override;
};
StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16_t callback); StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16_t callback);
#endif /* NEWGRF_AIRPORT_H */ #endif /* NEWGRF_AIRPORT_H */

View File

@ -214,7 +214,9 @@ static uint32_t GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint
*/ */
AirportTileResolverObject::AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, AirportTileResolverObject::AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st,
CallbackID callback, uint32_t callback_param1, uint32_t callback_param2) CallbackID callback, uint32_t callback_param1, uint32_t callback_param2)
: ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), tiles_scope(*this, ats, tile, st) : ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2),
tiles_scope(*this, ats, tile, st),
airport_scope(*this, tile, st, st != nullptr ? st->airport.type : (byte)AT_DUMMY, st != nullptr ? st->airport.layout : 0)
{ {
this->root_spritegroup = ats->grf_prop.spritegroup[0]; this->root_spritegroup = ats->grf_prop.spritegroup[0];
} }

View File

@ -44,6 +44,7 @@ struct AirportTileScopeResolver : public ScopeResolver {
/** Resolver for tiles of an airport. */ /** Resolver for tiles of an airport. */
struct AirportTileResolverObject : public ResolverObject { struct AirportTileResolverObject : public ResolverObject {
AirportTileScopeResolver tiles_scope; ///< Scope resolver for the tiles. AirportTileScopeResolver tiles_scope; ///< Scope resolver for the tiles.
AirportScopeResolver airport_scope; ///< Scope resolver for the airport owning the tile.
AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st,
CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0); CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0);
@ -52,6 +53,7 @@ struct AirportTileResolverObject : public ResolverObject {
{ {
switch (scope) { switch (scope) {
case VSG_SCOPE_SELF: return &tiles_scope; case VSG_SCOPE_SELF: return &tiles_scope;
case VSG_SCOPE_PARENT: return &airport_scope;
default: return ResolverObject::GetScope(scope, relative); default: return ResolverObject::GetScope(scope, relative);
} }
} }

View File

@ -28,6 +28,7 @@
#include "train.h" #include "train.h"
#include "roadveh.h" #include "roadveh.h"
#include "newgrf_airport.h"
#include "newgrf_airporttiles.h" #include "newgrf_airporttiles.h"
#include "newgrf_debug.h" #include "newgrf_debug.h"
#include "newgrf_object.h" #include "newgrf_object.h"

View File

@ -25,7 +25,7 @@
#include "safeguards.h" #include "safeguards.h"
static BuildingCounts<uint32_t> _building_counts; static BuildingCounts<uint32_t> _building_counts;
static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX]; static std::array<HouseClassMapping, HOUSE_CLASS_MAX> _class_mapping;
HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, NUM_HOUSES, INVALID_HOUSE_ID); HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, NUM_HOUSES, INVALID_HOUSE_ID);
@ -72,6 +72,11 @@ uint32_t HouseResolverObject::GetDebugID() const
return HouseSpec::Get(this->house_scope.house_id)->grf_prop.local_id; return HouseSpec::Get(this->house_scope.house_id)->grf_prop.local_id;
} }
void ResetHouseClassIDs()
{
_class_mapping = {};
}
HouseClassID AllocateHouseClassID(byte grf_class_id, uint32_t grfid) HouseClassID AllocateHouseClassID(byte grf_class_id, uint32_t grfid)
{ {
/* Start from 1 because 0 means that no class has been assigned. */ /* Start from 1 because 0 means that no class has been assigned. */

View File

@ -87,6 +87,7 @@ struct HouseClassMapping {
uint8_t class_id; ///< The class id within the grf file uint8_t class_id; ///< The class id within the grf file
}; };
void ResetHouseClassIDs();
HouseClassID AllocateHouseClassID(byte grf_class_id, uint32_t grfid); HouseClassID AllocateHouseClassID(byte grf_class_id, uint32_t grfid);
void InitializeBuildingCounts(); void InitializeBuildingCounts();

View File

@ -66,18 +66,8 @@ void ResetRailTypes()
{ {
static_assert(lengthof(_original_railtypes) <= lengthof(_railtypes)); static_assert(lengthof(_original_railtypes) <= lengthof(_railtypes));
uint i = 0; auto insert = std::copy(std::begin(_original_railtypes), std::end(_original_railtypes), std::begin(_railtypes));
for (; i < lengthof(_original_railtypes); i++) _railtypes[i] = _original_railtypes[i]; std::fill(insert, std::end(_railtypes), RailtypeInfo{});
static const RailtypeInfo empty_railtype = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,{}},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0},
0, RAILTYPES_NONE, RAILTYPES_NONE, 0, 0, 0, RTFB_NONE, 0, 0, 0, 0, 0,
RailTypeLabelList(), 0, 0, RAILTYPES_NONE, RAILTYPES_NONE, 0,
{}, {} };
for (; i < lengthof(_railtypes); i++) _railtypes[i] = empty_railtype;
_railtypes_hidden_mask = RAILTYPES_NONE; _railtypes_hidden_mask = RAILTYPES_NONE;
} }

View File

@ -67,17 +67,8 @@ void ResetRoadTypes()
{ {
static_assert(lengthof(_original_roadtypes) <= lengthof(_roadtypes)); static_assert(lengthof(_original_roadtypes) <= lengthof(_roadtypes));
uint i = 0; auto insert = std::copy(std::begin(_original_roadtypes), std::end(_original_roadtypes), std::begin(_roadtypes));
for (; i < lengthof(_original_roadtypes); i++) _roadtypes[i] = _original_roadtypes[i]; std::fill(insert, std::end(_roadtypes), RoadTypeInfo{});
static const RoadTypeInfo empty_roadtype = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, 0, {}, {} },
ROADTYPES_NONE, ROTFB_NONE, 0, 0, 0, 0,
RoadTypeLabelList(), 0, 0, ROADTYPES_NONE, ROADTYPES_NONE, 0,
{}, {} };
for (; i < lengthof(_roadtypes); i++) _roadtypes[i] = empty_roadtype;
_roadtypes_hidden_mask = ROADTYPES_NONE; _roadtypes_hidden_mask = ROADTYPES_NONE;
_roadtypes_type = ROADTYPES_TRAM; _roadtypes_type = ROADTYPES_TRAM;

View File

@ -88,6 +88,8 @@ SaveLoadTable GetCargoPacketDesc()
static const SaveLoad _cargopacket_desc[] = { static const SaveLoad _cargopacket_desc[] = {
SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16), SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16),
SLE_VAR(CargoPacket, source_xy, SLE_UINT32), SLE_VAR(CargoPacket, source_xy, SLE_UINT32),
SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_REMOVE_LOADED_AT_XY),
SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_UINT16, SLV_REMOVE_LOADED_AT_XY, SL_MAX_VERSION),
SLE_VAR(CargoPacket, count, SLE_UINT16), SLE_VAR(CargoPacket, count, SLE_UINT16),
SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE),
SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME),

View File

@ -16,7 +16,7 @@
const SaveLoadCompat _cargopacket_sl_compat[] = { const SaveLoadCompat _cargopacket_sl_compat[] = {
SLC_VAR("source"), SLC_VAR("source"),
SLC_VAR("source_xy"), SLC_VAR("source_xy"),
SLC_NULL(4, SL_MIN_VERSION, SLV_REMOVE_LOADED_AT_XY), SLC_VAR("loaded_at_xy"),
SLC_VAR("count"), SLC_VAR("count"),
SLC_VAR("days_in_transit"), SLC_VAR("days_in_transit"),
SLC_VAR("feeder_share"), SLC_VAR("feeder_share"),

View File

@ -710,7 +710,7 @@ static bool LoadOldGood(LoadgameState *ls, int num)
SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15)); SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
SB(ge->status, GoodsEntry::GES_RATING, 1, _cargo_source != 0xFF); SB(ge->status, GoodsEntry::GES_RATING, 1, _cargo_source != 0xFF);
if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) { if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) {
ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0), ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, INVALID_STATION, 0),
INVALID_STATION); INVALID_STATION);
} }

View File

@ -494,7 +494,7 @@ static const NICallback _nic_airporttiles[] = {
class NIHAirportTile : public NIHelper { class NIHAirportTile : public NIHelper {
bool IsInspectable(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile != nullptr; } bool IsInspectable(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile != nullptr; }
uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_AIRPORTS, GetStationIndex(index)); }
const void *GetInstance(uint index)const override { return nullptr; } const void *GetInstance(uint index)const override { return nullptr; }
const void *GetSpec(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index)); } const void *GetSpec(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index)); }
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); } void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); }
@ -515,6 +515,57 @@ static const NIFeature _nif_airporttile = {
}; };
/*** NewGRF airports ***/
static const NIVariable _niv_airports[] = {
NIV(0x40, "Layout number"),
NIV(0x48, "bitmask of accepted cargoes"),
NIV(0x60, "amount of cargo waiting"),
NIV(0x61, "time since last cargo pickup"),
NIV(0x62, "rating of cargo"),
NIV(0x63, "time spent on route"),
NIV(0x64, "information about last vehicle picking cargo up"),
NIV(0x65, "amount of cargo acceptance"),
NIV(0x69, "information about cargo accepted in the past"),
NIV(0xF1, "type of the airport"),
NIV(0xF6, "airport block status"),
NIV(0xFA, "built date"),
NIV_END()
};
class NIHAiport : public NIHelper {
bool IsInspectable(uint index) const override { return AirportSpec::Get(Station::Get(index)->airport.type)->grf_prop.grffile != nullptr; }
uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::Get(index)->town->index); }
const void *GetInstance(uint index)const override { return Station::Get(index); }
const void *GetSpec(uint index) const override { return AirportSpec::Get(Station::Get(index)->airport.type); }
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, index, Station::Get(index)->airport.tile); }
uint32_t GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? AirportSpec::Get(Station::Get(index)->airport.type)->grf_prop.grffile->grfid : 0; }
uint Resolve(uint index, uint var, uint param, bool *avail) const override
{
Station *st = Station::Get(index);
AirportResolverObject ro(st->airport.tile, st, st->airport.type, st->airport.layout);
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
}
uint GetPSASize(uint index, uint32_t grfid) const override { return cpp_lengthof(PersistentStorage, storage); }
const int32_t *GetPSAFirstPosition(uint index, uint32_t grfid) const override
{
const Station *st = (const Station *)this->GetInstance(index);
if (st->airport.psa == nullptr) return nullptr;
return (int32_t *)(&st->airport.psa->storage);
}
};
static const NIFeature _nif_airport = {
nullptr,
nullptr,
_niv_airports,
new NIHAiport(),
};
/*** NewGRF towns ***/ /*** NewGRF towns ***/
static const NIVariable _niv_towns[] = { static const NIVariable _niv_towns[] = {
@ -680,7 +731,7 @@ static const NIFeature * const _nifeatures[] = {
&_nif_industry, // GSF_INDUSTRIES &_nif_industry, // GSF_INDUSTRIES
nullptr, // GSF_CARGOES (has no "physical" objects) nullptr, // GSF_CARGOES (has no "physical" objects)
nullptr, // GSF_SOUNDFX (has no "physical" objects) nullptr, // GSF_SOUNDFX (has no "physical" objects)
nullptr, // GSF_AIRPORTS (feature not implemented) &_nif_airport, // GSF_AIRPORTS
nullptr, // GSF_SIGNALS (feature not implemented) nullptr, // GSF_SIGNALS (feature not implemented)
&_nif_object, // GSF_OBJECTS &_nif_object, // GSF_OBJECTS
&_nif_railtype, // GSF_RAILTYPES &_nif_railtype, // GSF_RAILTYPES

View File

@ -3842,6 +3842,8 @@ HouseSpec _house_specs[NUM_HOUSES];
void ResetHouses() void ResetHouses()
{ {
ResetHouseClassIDs();
auto insert = std::copy(std::begin(_original_house_specs), std::end(_original_house_specs), std::begin(_house_specs)); auto insert = std::copy(std::begin(_original_house_specs), std::end(_original_house_specs), std::begin(_house_specs));
std::fill(insert, std::end(_house_specs), HouseSpec{}); std::fill(insert, std::end(_house_specs), HouseSpec{});