diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1476,14 +1476,14 @@ > + + - - diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -1473,14 +1473,14 @@ > + + - - diff --git a/source.list b/source.list --- a/source.list +++ b/source.list @@ -297,8 +297,8 @@ string_func.h string_type.h strings_func.h strings_type.h +subsidy_base.h subsidy_func.h -subsidy_type.h tar_type.h terraform_gui.h textbuf_gui.h diff --git a/src/ai/api/ai_subsidy.cpp b/src/ai/api/ai_subsidy.cpp --- a/src/ai/api/ai_subsidy.cpp +++ b/src/ai/api/ai_subsidy.cpp @@ -4,27 +4,27 @@ #include "ai_subsidy.hpp" #include "ai_date.hpp" -#include "../../subsidy_type.h" +#include "../../subsidy_base.h" #include "../../station_base.h" #include "../../cargotype.h" /* static */ bool AISubsidy::IsValidSubsidy(SubsidyID subsidy_id) { - return subsidy_id < lengthof(_subsidies) && _subsidies[subsidy_id].cargo_type != CT_INVALID; + return Subsidy::IsValidID(subsidy_id); } /* static */ bool AISubsidy::IsAwarded(SubsidyID subsidy_id) { if (!IsValidSubsidy(subsidy_id)) return false; - return _subsidies[subsidy_id].age >= 12; + return Subsidy::Get(subsidy_id)->age >= 12; } /* static */ AICompany::CompanyID AISubsidy::GetAwardedTo(SubsidyID subsidy_id) { if (!IsAwarded(subsidy_id)) return AICompany::COMPANY_INVALID; - return (AICompany::CompanyID)((byte)Station::Get(_subsidies[subsidy_id].from)->owner); + return (AICompany::CompanyID)((byte)Station::Get(Subsidy::Get(subsidy_id)->from)->owner); } /* static */ int32 AISubsidy::GetExpireDate(SubsidyID subsidy_id) @@ -35,9 +35,9 @@ int month = AIDate::GetMonth(AIDate::GetCurrentDate()); if (IsAwarded(subsidy_id)) { - month += 24 - _subsidies[subsidy_id].age; + month += 24 - Subsidy::Get(subsidy_id)->age; } else { - month += 12 - _subsidies[subsidy_id].age; + month += 12 - Subsidy::Get(subsidy_id)->age; } year += (month - 1) / 12; @@ -50,7 +50,7 @@ { if (!IsValidSubsidy(subsidy_id)) return CT_INVALID; - return _subsidies[subsidy_id].cargo_type; + return Subsidy::Get(subsidy_id)->cargo_type; } /* static */ bool AISubsidy::SourceIsTown(SubsidyID subsidy_id) @@ -65,7 +65,7 @@ { if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION; - return _subsidies[subsidy_id].from; + return Subsidy::Get(subsidy_id)->from; } /* static */ bool AISubsidy::DestinationIsTown(SubsidyID subsidy_id) @@ -87,5 +87,5 @@ { if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION; - return _subsidies[subsidy_id].to; + return Subsidy::Get(subsidy_id)->to; } diff --git a/src/ai/api/ai_subsidylist.cpp b/src/ai/api/ai_subsidylist.cpp --- a/src/ai/api/ai_subsidylist.cpp +++ b/src/ai/api/ai_subsidylist.cpp @@ -4,12 +4,12 @@ #include "ai_subsidylist.hpp" #include "ai_subsidy.hpp" -#include "../../subsidy_type.h" +#include "../../subsidy_base.h" AISubsidyList::AISubsidyList() { const Subsidy *s; FOR_ALL_SUBSIDIES(s) { - this->AddItem(s - _subsidies); + this->AddItem(s->Index()); } } diff --git a/src/economy.cpp b/src/economy.cpp --- a/src/economy.cpp +++ b/src/economy.cpp @@ -33,6 +33,7 @@ #include "autoreplace_func.h" #include "company_gui.h" #include "signs_base.h" +#include "subsidy_base.h" #include "subsidy_func.h" #include "station_base.h" #include "economy_base.h" diff --git a/src/misc.cpp b/src/misc.cpp --- a/src/misc.cpp +++ b/src/misc.cpp @@ -42,6 +42,7 @@ void InitializeAirportGui(); void InitializeDockGui(); void InitializeIndustries(); void InitializeTowns(); +void InitializeSubsidies(); void InitializeTrees(); void InitializeSigns(); void InitializeStations(); @@ -91,6 +92,7 @@ void InitializeGame(uint size_x, uint si InitializeAirportGui(); InitializeDockGui(); InitializeTowns(); + InitializeSubsidies(); InitializeTrees(); InitializeSigns(); InitializeStations(); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -31,7 +31,7 @@ #include "../town.h" #include "../economy_base.h" #include "../animated_tile_func.h" -#include "../subsidy_type.h" +#include "../subsidy_base.h" #include "table/strings.h" diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -12,7 +12,7 @@ #include "../train.h" #include "../signs_base.h" #include "../station_base.h" -#include "../subsidy_type.h" +#include "../subsidy_base.h" #include "../debug.h" #include "../depot_base.h" #include "../newgrf_config.h" @@ -1475,7 +1475,7 @@ static const OldChunks subsidy_chunk[] = static bool LoadOldSubsidy(LoadgameState *ls, int num) { - return LoadChunk(ls, &_subsidies[num], subsidy_chunk); + return LoadChunk(ls, &Subsidy::array[num], subsidy_chunk); } static const OldChunks game_difficulty_chunk[] = { diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.cpp @@ -3,7 +3,7 @@ /** @file subsidy_sl.cpp Code handling saving and loading of subsidies */ #include "../stdafx.h" -#include "../subsidy_type.h" +#include "../subsidy_base.h" #include "saveload.h" @@ -21,7 +21,7 @@ void Save_SUBS() { Subsidy *s; FOR_ALL_SUBSIDIES(s) { - SlSetArrayIndex(s - _subsidies); + SlSetArrayIndex(s->Index()); SlObject(s, _subsidies_desc); } } @@ -29,8 +29,9 @@ void Save_SUBS() void Load_SUBS() { int index; - while ((index = SlIterateArray()) != -1) - SlObject(&_subsidies[index], _subsidies_desc); + while ((index = SlIterateArray()) != -1) { + SlObject(&Subsidy::array[index], _subsidies_desc); + } } extern const ChunkHandler _subsidy_chunk_handlers[] = { diff --git a/src/subsidy.cpp b/src/subsidy.cpp --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -13,11 +13,43 @@ #include "cargotype.h" #include "strings_func.h" #include "window_func.h" -#include "subsidy_type.h" +#include "subsidy_base.h" #include "table/strings.h" -Subsidy _subsidies[MAX_COMPANIES]; +/* static */ Subsidy Subsidy::array[MAX_COMPANIES]; + +/** + * Allocates one subsidy + * @return pointer to first invalid subsidy, NULL if there is none + */ +/* static */ Subsidy *Subsidy::AllocateItem() +{ + for (Subsidy *s = Subsidy::array; s < endof(Subsidy::array); s++) { + if (!s->IsValid()) return s; + } + + return NULL; +} + +/** + * Resets the array of subsidies marking all invalid + */ +/* static */ void Subsidy::Clean() +{ + memset(Subsidy::array, 0, sizeof(Subsidy::array)); + for (Subsidy *s = Subsidy::array; s < endof(Subsidy::array); s++) { + s->cargo_type = CT_INVALID; + } +} + +/** + * Initializes subsidies, files don't have to include subsidy_base,h this way + */ +void InitializeSubsidies() +{ + Subsidy::Clean(); +} Pair SetupSubsidyDecodeParam(const Subsidy *s, bool mode) { @@ -220,7 +252,7 @@ void SubsidyMonthlyLoop() AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->from, (NewsReferenceType)reftype.b, s->to); s->cargo_type = CT_INVALID; modified = true; - AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s - _subsidies)); + AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s->Index())); } else if (s->age == 2 * 12 - 1) { st = Station::Get(s->to); if (st->owner == _local_company) { @@ -229,7 +261,7 @@ void SubsidyMonthlyLoop() } s->cargo_type = CT_INVALID; modified = true; - AI::BroadcastNewEvent(new AIEventSubsidyExpired(s - _subsidies)); + AI::BroadcastNewEvent(new AIEventSubsidyExpired(s->Index())); } else { s->age++; } @@ -238,11 +270,8 @@ void SubsidyMonthlyLoop() /* 25% chance to go on */ if (Chance16(1, 4)) { /* Find a free slot*/ - s = _subsidies; - while (s->cargo_type != CT_INVALID) { - if (++s == endof(_subsidies)) - goto no_add; - } + s = Subsidy::AllocateItem(); + if (s == NULL) goto no_add; n = 1000; do { @@ -266,7 +295,7 @@ void SubsidyMonthlyLoop() s->age = 0; Pair reftype = SetupSubsidyDecodeParam(s, 0); AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->from, (NewsReferenceType)reftype.b, s->to); - AI::BroadcastNewEvent(new AIEventSubsidyOffer(s - _subsidies)); + AI::BroadcastNewEvent(new AIEventSubsidyOffer(s->Index())); modified = true; break; } @@ -340,7 +369,7 @@ bool CheckSubsidised(const Station *from (NewsReferenceType)reftype.a, s->from, (NewsReferenceType)reftype.b, s->to, company_name ); - AI::BroadcastNewEvent(new AIEventSubsidyAwarded(s - _subsidies)); + AI::BroadcastNewEvent(new AIEventSubsidyAwarded(s->Index())); InvalidateWindow(WC_SUBSIDIES_LIST, 0); return true; diff --git a/src/subsidy_base.h b/src/subsidy_base.h new file mode 100644 --- /dev/null +++ b/src/subsidy_base.h @@ -0,0 +1,77 @@ +/* $Id$ */ + +/** @file subsidy_base.h Subsidy base class. */ + +#ifndef SUBSIDY_BASE_H +#define SUBSIDY_BASE_H + +#include "cargo_type.h" +#include "company_type.h" + +/** Struct about subsidies, offered and awarded */ +struct Subsidy { + CargoID cargo_type; ///< Cargo type involved in this subsidy, CT_INVALID for invalid subsidy + byte age; ///< Subsidy age; < 12 is unawarded, >= 12 is awarded + uint16 from; ///< Index of source. Either TownID, IndustryID or StationID, when awarded + uint16 to; ///< Index of destination. Either TownID, IndustryID or StationID, when awarded + + /** + * Determines index of this subsidy + * @return index (in the Subsidy::array array) + */ + FORCEINLINE size_t Index() const + { + return this - Subsidy::array; + } + + /** + * Tests for validity of this subsidy + * @return is this subsidy valid? + */ + FORCEINLINE bool IsValid() const + { + return this->cargo_type != CT_INVALID; + } + + + static Subsidy array[MAX_COMPANIES]; ///< Array holding all subsidies + + /** + * Total number of subsidies, both valid and invalid + * @return length of Subsidy::array + */ + static FORCEINLINE size_t GetArraySize() + { + return lengthof(Subsidy::array); + } + + /** + * Tests whether given index is an index of valid subsidy + * @param index index to check + * @return can this index be used to access a valid subsidy? + */ + static FORCEINLINE bool IsValidID(size_t index) + { + return index < Subsidy::GetArraySize() && Subsidy::Get(index)->IsValid(); + } + + /** + * Returns pointer to subsidy with given index + * @param index index of subsidy + * @return pointer to subsidy with given index + */ + static FORCEINLINE Subsidy *Get(size_t index) + { + assert(index < Subsidy::GetArraySize()); + return &Subsidy::array[index]; + } + + static Subsidy *AllocateItem(); + static void Clean(); +}; + +#define FOR_ALL_SUBSIDIES_FROM(var, start) for (size_t subsidy_index = start; var = NULL, subsidy_index < Subsidy::GetArraySize(); subsidy_index++) \ + if ((var = Subsidy::Get(subsidy_index))->IsValid()) +#define FOR_ALL_SUBSIDIES(var) FOR_ALL_SUBSIDIES_FROM(var, 0) + +#endif /* SUBSIDY_BASE_H */ diff --git a/src/subsidy_func.h b/src/subsidy_func.h --- a/src/subsidy_func.h +++ b/src/subsidy_func.h @@ -10,9 +10,8 @@ #include "town_type.h" #include "industry_type.h" #include "company_type.h" -#include "subsidy_type.h" -Pair SetupSubsidyDecodeParam(const Subsidy *s, bool mode); +Pair SetupSubsidyDecodeParam(const struct Subsidy *s, bool mode); void DeleteSubsidyWithTown(TownID index); void DeleteSubsidyWithIndustry(IndustryID index); void DeleteSubsidyWithStation(StationID index); diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -15,6 +15,7 @@ #include "gfx_func.h" #include "gui.h" #include "subsidy_func.h" +#include "subsidy_base.h" #include "table/strings.h" diff --git a/src/subsidy_type.h b/src/subsidy_type.h deleted file mode 100644 --- a/src/subsidy_type.h +++ /dev/null @@ -1,25 +0,0 @@ -/* $Id$ */ - -/** @file subsidy_type.h Types related to subsidies. */ - -#ifndef SUBSIDY_TYPE_H -#define SUBSIDY_TYPE_H - -#include "cargo_type.h" -#include "company_type.h" - -/** Struct about subsidies, both offered and awarded */ -struct Subsidy { - CargoID cargo_type; ///< Cargo type involved in this subsidy, CT_INVALID for invalid subsidy - byte age; ///< Subsidy age; < 12 is unawarded, >= 12 is awarded - uint16 from; ///< Index of source. Either TownID, IndustryID or StationID, when awarded. - uint16 to; ///< Index of destination. Either TownID, IndustryID or StationID, when awarded. -}; - -extern Subsidy _subsidies[MAX_COMPANIES]; - -#define FOR_ALL_SUBSIDIES_FROM(var, start) for (var = &_subsidies[start]; var < endof(_subsidies); var++) \ - if (var->cargo_type != CT_INVALID) -#define FOR_ALL_SUBSIDIES(var) FOR_ALL_SUBSIDIES_FROM(var, 0) - -#endif /* SUBSIDY_TYPE_H */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2869,11 +2869,6 @@ void TownsYearlyLoop() void InitializeTowns() { _town_pool.CleanPool(); - - memset(_subsidies, 0, sizeof(_subsidies)); - for (Subsidy *s = _subsidies; s != endof(_subsidies); s++) { - s->cargo_type = CT_INVALID; - } } static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new)