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)