From 0e4b212c4539afb9d8622862d7e03bf2217058f8 Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 9 Dec 2012 16:55:03 +0000 Subject: [PATCH] (svn r24810) -Fix: Make engine preview offers more robust wrt. changes in the company ranking. --- src/engine.cpp | 71 +++++++++++++++-------------------- src/engine_base.h | 5 ++- src/engine_type.h | 1 - src/saveload/engine_sl.cpp | 15 +++++++- src/saveload/oldloader_sl.cpp | 5 ++- src/saveload/saveload.cpp | 3 +- 6 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index c1f55bb4e0..2895496042 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 af57d3717f..789a26d1a6 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 b02795322c..aeebcb3522 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 188db2deab..d02264cd6b 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 d36ba54f8f..0ee7eea2bc 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 6a6f8db136..ac8a7e81b9 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