summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2012-12-09 16:55:03 +0000
committerfrosch <frosch@openttd.org>2012-12-09 16:55:03 +0000
commit0e4b212c4539afb9d8622862d7e03bf2217058f8 (patch)
tree676292ccfbd04f4b61e621682f9546535e2a479d
parent2bb54f09d8ad249f009ab10c9b398fc8b444e5b3 (diff)
downloadopenttd-0e4b212c4539afb9d8622862d7e03bf2217058f8.tar.xz
(svn r24810) -Fix: Make engine preview offers more robust wrt. changes in the company ranking.
-rw-r--r--src/engine.cpp71
-rw-r--r--src/engine_base.h5
-rw-r--r--src/engine_type.h1
-rw-r--r--src/saveload/engine_sl.cpp15
-rw-r--r--src/saveload/oldloader_sl.cpp5
-rw-r--r--src/saveload/saveload.cpp3
6 files changed, 52 insertions, 48 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
index c1f55bb4e..289549604 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -740,7 +740,8 @@ static void AcceptEnginePreview(EngineID eid, CompanyID company)
SetBit(c->avail_roadtypes, HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
}
- e->preview_company_rank = 0xFF;
+ e->preview_company = INVALID_COMPANY;
+ e->preview_asked = (CompanyMask)-1;
if (company == _local_company) {
AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
}
@@ -751,32 +752,23 @@ static void AcceptEnginePreview(EngineID eid, CompanyID company)
}
/**
- * Get the N-th best company.
- * @param pp Value N, 1 means best, 2 means second best, etc.
- * @return N-th best company if it exists, #INVALID_COMPANY otherwise.
+ * Get the best company for an engine preview.
+ * @param e Engine to preview.
+ * @return Best company if it exists, #INVALID_COMPANY otherwise.
*/
-static CompanyID GetBestCompany(uint8 pp)
+static CompanyID GetPreviewCompany(Engine *e)
{
- CompanyID best_company;
- CompanyMask mask = 0;
+ CompanyID best_company = INVALID_COMPANY;
- do {
- int32 best_hist = -1;
- best_company = INVALID_COMPANY;
-
- const Company *c;
- FOR_ALL_COMPANIES(c) {
- if (c->block_preview == 0 && !HasBit(mask, c->index) &&
- c->old_economy[0].performance_history > best_hist) {
- best_hist = c->old_economy[0].performance_history;
- best_company = c->index;
- }
+ int32 best_hist = -1;
+ const Company *c;
+ FOR_ALL_COMPANIES(c) {
+ if (c->block_preview == 0 && !HasBit(e->preview_asked, c->index) &&
+ c->old_economy[0].performance_history > best_hist) {
+ best_hist = c->old_economy[0].performance_history;
+ best_company = c->index;
}
-
- if (best_company == INVALID_COMPANY) return INVALID_COMPANY;
-
- SetBit(mask, best_company);
- } while (--pp != 0);
+ }
return best_company;
}
@@ -811,29 +803,28 @@ void EnginesDailyLoop()
FOR_ALL_ENGINES(e) {
EngineID i = e->index;
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) {
- if (e->flags & ENGINE_OFFER_WINDOW_OPEN) {
- if (e->preview_company_rank != 0xFF && !--e->preview_wait) {
- e->flags &= ~ENGINE_OFFER_WINDOW_OPEN;
+ if (e->preview_company != INVALID_COMPANY) {
+ if (!--e->preview_wait) {
DeleteWindowById(WC_ENGINE_PREVIEW, i);
- e->preview_company_rank++;
+ e->preview_company = INVALID_COMPANY;
}
- } else if (e->preview_company_rank != 0xFF) {
- CompanyID best_company = GetBestCompany(e->preview_company_rank);
+ } else if (CountBits(e->preview_asked) < MAX_COMPANIES) {
+ e->preview_company = GetPreviewCompany(e);
- if (best_company == INVALID_COMPANY) {
- e->preview_company_rank = 0xFF;
+ if (e->preview_company == INVALID_COMPANY) {
+ e->preview_asked = (CompanyMask)-1;
continue;
}
- e->flags |= ENGINE_OFFER_WINDOW_OPEN;
+ SetBit(e->preview_asked, e->preview_company);
e->preview_wait = 20;
/* AIs are intentionally not skipped for preview even if they cannot build a certain
* vehicle type. This is done to not give poor performing human companies an "unfair"
* boost that they wouldn't have gotten against other human companies. The check on
* the line below is just to make AIs not notice that they have a preview if they
* cannot build the vehicle. */
- if (!IsVehicleTypeDisabled(e->type, true)) AI::NewEvent(best_company, new ScriptEventEnginePreview(i));
- if (IsInteractiveCompany(best_company)) ShowEnginePreviewWindow(i);
+ if (!IsVehicleTypeDisabled(e->type, true)) AI::NewEvent(e->preview_company, new ScriptEventEnginePreview(i));
+ if (IsInteractiveCompany(e->preview_company)) ShowEnginePreviewWindow(i);
}
}
}
@@ -852,7 +843,7 @@ void EnginesDailyLoop()
CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Engine *e = Engine::GetIfValid(p1);
- if (e == NULL || GetBestCompany(e->preview_company_rank) != _current_company) return CMD_ERROR;
+ if (e == NULL || e->preview_company != _current_company) return CMD_ERROR;
if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_company);
@@ -953,13 +944,13 @@ void EnginesMonthlyLoop()
* make sense to show the preview dialog to any company. */
if (IsVehicleTypeDisabled(e->type, false)) continue;
+ /* Do not introduce new rail wagons */
+ if (IsWagon(e->index)) continue;
+
/* Show preview dialog to one of the companies. */
e->flags |= ENGINE_EXCLUSIVE_PREVIEW;
-
- /* Do not introduce new rail wagons */
- if (!IsWagon(e->index)) {
- e->preview_company_rank = 1; // Give to the company with the highest rating.
- }
+ e->preview_company = INVALID_COMPANY;
+ e->preview_asked = 0;
}
}
diff --git a/src/engine_base.h b/src/engine_base.h
index af57d3717..789a26d1a 100644
--- a/src/engine_base.h
+++ b/src/engine_base.h
@@ -33,8 +33,9 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> {
uint16 duration_phase_2; ///< Second reliability phase in months, keeping #reliability_max.
uint16 duration_phase_3; ///< Third reliability phase on months, decaying to #reliability_final.
byte flags; ///< Flags of the engine. @see EngineFlags
- uint8 preview_company_rank; ///< Rank of the company that is offered a preview. \c 0xFF means no company.
- byte preview_wait; ///< Daily countdown timer for timeout of offering the engine to the #preview_company_rank company.
+ CompanyMask preview_asked; ///< Bit for each company which has already been offered a preview.
+ CompanyByte preview_company;///< Company which is currently being offered a preview \c INVALID_COMPANY means no company.
+ byte preview_wait; ///< Daily countdown timer for timeout of offering the engine to the #preview_company company.
CompanyMask company_avail; ///< Bit for each company whether the engine is available for that company.
uint8 original_image_index; ///< Original vehicle image index, thus the image index of the overridden vehicle
VehicleType type; ///< %Vehicle type, ie #VEH_ROAD, #VEH_TRAIN, etc.
diff --git a/src/engine_type.h b/src/engine_type.h
index b02795322..aeebcb352 100644
--- a/src/engine_type.h
+++ b/src/engine_type.h
@@ -166,7 +166,6 @@ enum EngineMiscFlags {
enum EngineFlags {
ENGINE_AVAILABLE = 1, ///< This vehicle is available to everyone.
ENGINE_EXCLUSIVE_PREVIEW = 2, ///< This vehicle is in the exclusive preview stage, either being used or being offered to a company.
- ENGINE_OFFER_WINDOW_OPEN = 4, ///< The exclusive offer window is currently open for a company.
};
static const uint MAX_LENGTH_ENGINE_NAME_CHARS = 32; ///< The maximum length of an engine name in characters including '\0'
diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp
index 188db2dea..d02264cd6 100644
--- a/src/saveload/engine_sl.cpp
+++ b/src/saveload/engine_sl.cpp
@@ -30,7 +30,9 @@ static const SaveLoad _engine_desc[] = {
SLE_CONDNULL(1, 0, 120),
SLE_VAR(Engine, flags, SLE_UINT8),
- SLE_VAR(Engine, preview_company_rank,SLE_UINT8),
+ SLE_CONDNULL(1, 0, 178), // old preview_company_rank
+ SLE_CONDVAR(Engine, preview_asked, SLE_UINT16, 179, SL_MAX_VERSION),
+ SLE_CONDVAR(Engine, preview_company, SLE_UINT8, 179, SL_MAX_VERSION),
SLE_VAR(Engine, preview_wait, SLE_UINT8),
SLE_CONDNULL(1, 0, 44),
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
@@ -67,6 +69,14 @@ static void Load_ENGN()
while ((index = SlIterateArray()) != -1) {
Engine *e = GetTempDataEngine(index);
SlObject(e, _engine_desc);
+
+ if (IsSavegameVersionBefore(179)) {
+ /* preview_company_rank was replaced with preview_company and preview_asked.
+ * Just cancel any previews. */
+ e->flags &= ~4; // ENGINE_OFFER_WINDOW_OPEN
+ e->preview_company = INVALID_COMPANY;
+ e->preview_asked = (CompanyMask)-1;
+ }
}
}
@@ -91,7 +101,8 @@ void CopyTempEngineData()
e->duration_phase_2 = se->duration_phase_2;
e->duration_phase_3 = se->duration_phase_3;
e->flags = se->flags;
- e->preview_company_rank= se->preview_company_rank;
+ e->preview_asked = se->preview_asked;
+ e->preview_company = se->preview_company;
e->preview_wait = se->preview_wait;
e->company_avail = se->company_avail;
if (se->name != NULL) e->name = strdup(se->name);
diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp
index d36ba54f8..0ee7eea2b 100644
--- a/src/saveload/oldloader_sl.cpp
+++ b/src/saveload/oldloader_sl.cpp
@@ -445,7 +445,8 @@ static bool FixTTOEngines()
e->info.climates = 1;
}
- e->preview_company_rank = 0;
+ e->preview_company = INVALID_COMPANY;
+ e->preview_asked = (CompanyMask)-1;
e->preview_wait = 0;
e->name = NULL;
}
@@ -1401,7 +1402,7 @@ static const OldChunks engine_chunk[] = {
OCL_NULL( 1 ), // lifelength
OCL_SVAR( OC_UINT8, Engine, flags ),
- OCL_SVAR( OC_UINT8, Engine, preview_company_rank ),
+ OCL_NULL( 1 ), // preview_company_rank
OCL_SVAR( OC_UINT8, Engine, preview_wait ),
OCL_CNULL( OC_TTD, 2 ), ///< railtype + junk
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
index 6a6f8db13..ac8a7e81b 100644
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -242,8 +242,9 @@
* 176 24446
* 177 24619
* 178 24789
+ * 179 24810
*/
-extern const uint16 SAVEGAME_VERSION = 178; ///< Current savegame version of OpenTTD.
+extern const uint16 SAVEGAME_VERSION = 179; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading