diff --git a/src/subsidy.cpp b/src/subsidy.cpp --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -15,10 +15,12 @@ #include "window_func.h" #include "subsidy_base.h" #include "subsidy_func.h" +#include "core/pool_func.hpp" #include "table/strings.h" -/* static */ Subsidy Subsidy::array[MAX_COMPANIES]; +SubsidyPool _subsidy_pool("Subsidy"); +INSTANTIATE_POOL_METHODS(Subsidy) /** * Marks subsidy as awarded, creates news and AI event @@ -46,44 +48,17 @@ void Subsidy::AwardTo(CompanyID company) (NewsReferenceType)reftype.a, this->src, (NewsReferenceType)reftype.b, this->dst, company_name ); - AI::BroadcastNewEvent(new AIEventSubsidyAwarded(this->Index())); + AI::BroadcastNewEvent(new AIEventSubsidyAwarded(this->index)); InvalidateWindow(WC_SUBSIDIES_LIST, 0); } /** - * 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()) { - s->awarded = INVALID_COMPANY; - 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(); + _subsidy_pool.CleanPool(); } Pair SetupSubsidyDecodeParam(const Subsidy *s, bool mode) @@ -157,12 +132,6 @@ void RebuildSubsidisedSourceAndDestinati } } -void DeleteSubsidy(Subsidy *s) -{ - s->cargo_type = CT_INVALID; - RebuildSubsidisedSourceAndDestinationCache(); -} - void DeleteSubsidyWith(SourceType type, SourceID index) { bool dirty = false; @@ -170,12 +139,15 @@ void DeleteSubsidyWith(SourceType type, Subsidy *s; FOR_ALL_SUBSIDIES(s) { if ((s->src_type == type && s->src == index) || (s->dst_type == type && s->dst == index)) { - s->cargo_type = CT_INVALID; + delete s; dirty = true; } } - if (dirty) InvalidateWindow(WC_SUBSIDIES_LIST, 0); + if (dirty) { + InvalidateWindow(WC_SUBSIDIES_LIST, 0); + RebuildSubsidisedSourceAndDestinationCache(); + } } struct FoundRoute { @@ -267,7 +239,7 @@ static bool CheckSubsidyDuplicate(Subsid if (s != ss && ss->cargo_type == s->cargo_type && ss->src_type == s->src_type && ss->src == s->src && ss->dst_type == s->dst_type && ss->dst == s->dst) { - s->cargo_type = CT_INVALID; + delete s; return true; } } @@ -285,30 +257,29 @@ void SubsidyMonthlyLoop() if (!s->IsAwarded()) { Pair reftype = SetupSubsidyDecodeParam(s, 1); AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst); - AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s->Index())); + AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s->index)); } else { if (s->awarded == _local_company) { Pair reftype = SetupSubsidyDecodeParam(s, 1); AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst); } - AI::BroadcastNewEvent(new AIEventSubsidyExpired(s->Index())); + AI::BroadcastNewEvent(new AIEventSubsidyExpired(s->index)); } - DeleteSubsidy(s); + delete s; modified = true; } } + if (modified) RebuildSubsidisedSourceAndDestinationCache(); + /* 25% chance to go on */ - if (Chance16(1, 4)) { - /* Find a free slot*/ - s = Subsidy::AllocateItem(); - if (s == NULL) goto no_add; - + if (Subsidy::CanAllocateItem() && Chance16(1, 4)) { uint n = 1000; do { FoundRoute fr; FindSubsidyPassengerRoute(&fr); if (fr.distance <= SUBSIDY_MAX_DISTANCE) { + s = new Subsidy(); s->cargo_type = CT_PASSENGERS; s->src_type = s->dst_type = ST_TOWN; s->src = ((Town *)fr.from)->index; @@ -317,6 +288,7 @@ void SubsidyMonthlyLoop() } FindSubsidyCargoRoute(&fr); if (fr.distance <= SUBSIDY_MAX_DISTANCE) { + s = new Subsidy(); s->cargo_type = fr.cargo; s->src_type = ST_INDUSTRY; s->src = ((Industry *)fr.from)->index; @@ -333,20 +305,20 @@ void SubsidyMonthlyLoop() add_subsidy: if (!CheckSubsidyDuplicate(s)) { s->remaining = SUBSIDY_OFFER_MONTHS; + s->awarded = INVALID_COMPANY; Pair reftype = SetupSubsidyDecodeParam(s, 0); AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst); SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC); SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST); - AI::BroadcastNewEvent(new AIEventSubsidyOffer(s->Index())); + AI::BroadcastNewEvent(new AIEventSubsidyOffer(s->index)); modified = true; break; } } } while (n--); } -no_add:; - if (modified) - InvalidateWindow(WC_SUBSIDIES_LIST, 0); + + if (modified) InvalidateWindow(WC_SUBSIDIES_LIST, 0); } /**