From 57992d5eacc97f9e8577ae9da2e1fc9f437aafc1 Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 21 Sep 2009 15:41:58 +0000 Subject: [PATCH] (svn r17598) [0.7] -Backport from trunk: - Fix: Vehicle image was not always updated when needed (r17594) - Fix: [NoAI] Could not query the size of small airports when they could not be build anymore [FS#3212] (r17591) - Fix: Erroneous message about changing the difficulty level [FS#3220] (r17588) - Fix: Assertion triggered when the second vehicle in a 101+ (or 11+ if mammoth trains is disabled) vehicle free wagon chain is an engine and the first vehicle is moved to another chain [FS#3208] (r17576) --- bin/ai/regression/regression.nut | 9 +-- bin/ai/regression/regression.txt | 99 ++++++++++++++++++-------------- src/ai/api/ai_airport.cpp | 15 +++-- src/ai/api/ai_airport.hpp | 16 ++++++ src/ai/api/ai_airport.hpp.sq | 29 +++++----- src/ai/api/ai_changelog.hpp | 3 +- src/aircraft_cmd.cpp | 1 + src/roadveh_cmd.cpp | 2 + src/settings_gui.cpp | 6 +- src/ship_cmd.cpp | 2 + src/train_cmd.cpp | 11 ++++ src/vehicle.cpp | 1 + src/vehicle_cmd.cpp | 1 + 13 files changed, 124 insertions(+), 71 deletions(-) diff --git a/bin/ai/regression/regression.nut b/bin/ai/regression/regression.nut index a5bf58794b..dfdf99b1a6 100644 --- a/bin/ai/regression/regression.nut +++ b/bin/ai/regression/regression.nut @@ -213,10 +213,11 @@ function Regression::Airport() print(" GetAirportType(): " + AIAirport.GetAirportType(32116)); for (local i = -1; i < 10; i++) { - print(" IsValidAirportType(" + i + "): " + AIAirport.IsValidAirportType(i)); - print(" GetAirportWidth(" + i + "): " + AIAirport.GetAirportWidth(i)); - print(" GetAirportHeight(" + i + "): " + AIAirport.GetAirportHeight(i)); - print(" GetAirportCoverageRadius(" + i + "): " + AIAirport.GetAirportCoverageRadius(i)); + print(" IsAirportInformationAvailable(" + i + "): " + AIAirport.IsAirportInformationAvailable(i)); + print(" IsValidAirportType(" + i + "): " + AIAirport.IsValidAirportType(i)); + print(" GetAirportWidth(" + i + "): " + AIAirport.GetAirportWidth(i)); + print(" GetAirportHeight(" + i + "): " + AIAirport.GetAirportHeight(i)); + print(" GetAirportCoverageRadius(" + i + "): " + AIAirport.GetAirportCoverageRadius(i)); } print(" GetBankBalance(): " + AICompany.GetBankBalance(AICompany.COMPANY_SELF)); diff --git a/bin/ai/regression/regression.txt b/bin/ai/regression/regression.txt index 26aa544677..2ecfb68853 100644 --- a/bin/ai/regression/regression.txt +++ b/bin/ai/regression/regression.txt @@ -575,50 +575,61 @@ IsAirportTile(): false GetHangarOfAirport(): -1 GetAirportType(): 255 - IsValidAirportType(-1): false - GetAirportWidth(-1): -1 - GetAirportHeight(-1): -1 - GetAirportCoverageRadius(-1): -1 - IsValidAirportType(0): true - GetAirportWidth(0): 4 - GetAirportHeight(0): 3 - GetAirportCoverageRadius(0): 4 - IsValidAirportType(1): false - GetAirportWidth(1): -1 - GetAirportHeight(1): -1 - GetAirportCoverageRadius(1): -1 - IsValidAirportType(2): false - GetAirportWidth(2): -1 - GetAirportHeight(2): -1 - GetAirportCoverageRadius(2): -1 - IsValidAirportType(3): false - GetAirportWidth(3): -1 - GetAirportHeight(3): -1 - GetAirportCoverageRadius(3): -1 - IsValidAirportType(4): false - GetAirportWidth(4): -1 - GetAirportHeight(4): -1 - GetAirportCoverageRadius(4): -1 - IsValidAirportType(5): false - GetAirportWidth(5): -1 - GetAirportHeight(5): -1 - GetAirportCoverageRadius(5): -1 - IsValidAirportType(6): false - GetAirportWidth(6): -1 - GetAirportHeight(6): -1 - GetAirportCoverageRadius(6): -1 - IsValidAirportType(7): false - GetAirportWidth(7): -1 - GetAirportHeight(7): -1 - GetAirportCoverageRadius(7): -1 - IsValidAirportType(8): false - GetAirportWidth(8): -1 - GetAirportHeight(8): -1 - GetAirportCoverageRadius(8): -1 - IsValidAirportType(9): false - GetAirportWidth(9): -1 - GetAirportHeight(9): -1 - GetAirportCoverageRadius(9): -1 + IsAirportInformationAvailable(-1): false + IsValidAirportType(-1): false + GetAirportWidth(-1): -1 + GetAirportHeight(-1): -1 + GetAirportCoverageRadius(-1): -1 + IsAirportInformationAvailable(0): true + IsValidAirportType(0): true + GetAirportWidth(0): 4 + GetAirportHeight(0): 3 + GetAirportCoverageRadius(0): 4 + IsAirportInformationAvailable(1): true + IsValidAirportType(1): false + GetAirportWidth(1): 6 + GetAirportHeight(1): 6 + GetAirportCoverageRadius(1): 5 + IsAirportInformationAvailable(2): true + IsValidAirportType(2): false + GetAirportWidth(2): 1 + GetAirportHeight(2): 1 + GetAirportCoverageRadius(2): 4 + IsAirportInformationAvailable(3): true + IsValidAirportType(3): false + GetAirportWidth(3): 6 + GetAirportHeight(3): 6 + GetAirportCoverageRadius(3): 6 + IsAirportInformationAvailable(4): true + IsValidAirportType(4): false + GetAirportWidth(4): 7 + GetAirportHeight(4): 7 + GetAirportCoverageRadius(4): 8 + IsAirportInformationAvailable(5): true + IsValidAirportType(5): false + GetAirportWidth(5): 5 + GetAirportHeight(5): 4 + GetAirportCoverageRadius(5): 4 + IsAirportInformationAvailable(6): true + IsValidAirportType(6): false + GetAirportWidth(6): 2 + GetAirportHeight(6): 2 + GetAirportCoverageRadius(6): 4 + IsAirportInformationAvailable(7): true + IsValidAirportType(7): false + GetAirportWidth(7): 9 + GetAirportHeight(7): 11 + GetAirportCoverageRadius(7): 10 + IsAirportInformationAvailable(8): true + IsValidAirportType(8): false + GetAirportWidth(8): 4 + GetAirportHeight(8): 2 + GetAirportCoverageRadius(8): 4 + IsAirportInformationAvailable(9): false + IsValidAirportType(9): false + GetAirportWidth(9): -1 + GetAirportHeight(9): -1 + GetAirportCoverageRadius(9): -1 GetBankBalance(): 100000 GetPrice(): 84 BuildAirport(): true diff --git a/src/ai/api/ai_airport.cpp b/src/ai/api/ai_airport.cpp index 819880f97a..c3a9377e54 100644 --- a/src/ai/api/ai_airport.cpp +++ b/src/ai/api/ai_airport.cpp @@ -12,7 +12,12 @@ /* static */ bool AIAirport::IsValidAirportType(AirportType type) { - return type >= AT_SMALL && type <= AT_HELISTATION && HasBit(::GetValidAirports(), type); + return IsAirportInformationAvailable(type) && HasBit(::GetValidAirports(), type); +} + +/* static */ bool AIAirport::IsAirportInformationAvailable(AirportType type) +{ + return type >= 0 && type <= AT_HELISTATION; } /* static */ Money AIAirport::GetPrice(AirportType type) @@ -39,21 +44,21 @@ /* static */ int32 AIAirport::GetAirportWidth(AirportType type) { - if (!IsValidAirportType(type)) return -1; + if (!IsAirportInformationAvailable(type)) return -1; return ::GetAirport(type)->size_x; } /* static */ int32 AIAirport::GetAirportHeight(AirportType type) { - if (!IsValidAirportType(type)) return -1; + if (!IsAirportInformationAvailable(type)) return -1; return ::GetAirport(type)->size_y; } /* static */ int32 AIAirport::GetAirportCoverageRadius(AirportType type) { - if (!IsValidAirportType(type)) return -1; + if (!IsAirportInformationAvailable(type)) return -1; return _settings_game.station.modified_catchment ? ::GetAirport(type)->catchment : (uint)CA_UNMODIFIED; } @@ -136,7 +141,7 @@ extern Town *AirportGetNearestTown(const AirportFTAClass *afc, TileIndex airport_tile); if (!::IsValidTile(tile)) return INVALID_TOWN; - if (!IsValidAirportType(type)) return INVALID_TOWN; + if (!IsAirportInformationAvailable(type)) return INVALID_TOWN; return AirportGetNearestTown(GetAirport(type), tile)->index; } diff --git a/src/ai/api/ai_airport.hpp b/src/ai/api/ai_airport.hpp index fc9fd2acf8..aca8dfe0b2 100644 --- a/src/ai/api/ai_airport.hpp +++ b/src/ai/api/ai_airport.hpp @@ -50,12 +50,24 @@ public: * Checks whether the given AirportType is valid and available. * @param type The AirportType to check. * @return True if and only if the AirportType is valid and available. + * @post return value == true -> IsAirportInformationAvailable returns true. */ static bool IsValidAirportType(AirportType type); + /** + * Can you get information on this airport type? As opposed to + * IsValidAirportType this will return also return true when + * an airport type is no longer buildable. + * @param type The AirportType to check. + * @return True if and only if the AirportType is valid. + * @post return value == false -> IsValidAirportType returns false. + */ + static bool IsAirportInformationAvailable(AirportType type); + /** * Get the cost to build this AirportType. * @param type The AirportType to check. + * @pre AirportAvailable(type). * @return The cost of building this AirportType. */ static Money GetPrice(AirportType type); @@ -79,6 +91,7 @@ public: /** * Get the width of this type of airport. * @param type The type of airport. + * @pre IsAirportInformationAvailable(type). * @return The width in tiles. */ static int32 GetAirportWidth(AirportType type); @@ -86,6 +99,7 @@ public: /** * Get the height of this type of airport. * @param type The type of airport. + * @pre IsAirportInformationAvailable(type). * @return The height in tiles. */ static int32 GetAirportHeight(AirportType type); @@ -93,6 +107,7 @@ public: /** * Get the coverage radius of this type of airport. * @param type The type of airport. + * @pre IsAirportInformationAvailable(type). * @return The radius in tiles. */ static int32 GetAirportCoverageRadius(AirportType type); @@ -167,6 +182,7 @@ public: * an airport at some tile. * @param tile The tile to check. * @param type The AirportType to check. + * @pre IsAirportInformationAvailable(type). * @return The TownID of the town closest to the tile. */ static TownID GetNearestTown(TileIndex tile, AirportType type); diff --git a/src/ai/api/ai_airport.hpp.sq b/src/ai/api/ai_airport.hpp.sq index 3825c29ae2..377c11ca21 100644 --- a/src/ai/api/ai_airport.hpp.sq +++ b/src/ai/api/ai_airport.hpp.sq @@ -38,20 +38,21 @@ void SQAIAirport_Register(Squirrel *engine) { SQAIAirport.DefSQConst(engine, AIAirport::PT_BIG_PLANE, "PT_BIG_PLANE"); SQAIAirport.DefSQConst(engine, AIAirport::PT_INVALID, "PT_INVALID"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsValidAirportType, "IsValidAirportType", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetPrice, "GetPrice", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsHangarTile, "IsHangarTile", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsAirportTile, "IsAirportTile", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportWidth, "GetAirportWidth", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportHeight, "GetAirportHeight", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportCoverageRadius, "GetAirportCoverageRadius", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNumHangars, "GetNumHangars", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetHangarOfAirport, "GetHangarOfAirport", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::BuildAirport, "BuildAirport", 4, ".iii"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::RemoveAirport, "RemoveAirport", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportType, "GetAirportType", 2, ".i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNoiseLevelIncrease, "GetNoiseLevelIncrease", 3, ".ii"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNearestTown, "GetNearestTown", 3, ".ii"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsValidAirportType, "IsValidAirportType", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsAirportInformationAvailable, "IsAirportInformationAvailable", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetPrice, "GetPrice", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsHangarTile, "IsHangarTile", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsAirportTile, "IsAirportTile", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportWidth, "GetAirportWidth", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportHeight, "GetAirportHeight", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportCoverageRadius, "GetAirportCoverageRadius", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNumHangars, "GetNumHangars", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetHangarOfAirport, "GetHangarOfAirport", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::BuildAirport, "BuildAirport", 4, ".iii"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::RemoveAirport, "RemoveAirport", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportType, "GetAirportType", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNoiseLevelIncrease, "GetNoiseLevelIncrease", 3, ".ii"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNearestTown, "GetNearestTown", 3, ".ii"); SQAIAirport.PostRegister(engine); } diff --git a/src/ai/api/ai_changelog.hpp b/src/ai/api/ai_changelog.hpp index b1d0aa1613..8b964c7632 100644 --- a/src/ai/api/ai_changelog.hpp +++ b/src/ai/api/ai_changelog.hpp @@ -19,6 +19,7 @@ * API additions: * \li AIAbstractList::SORT_ASCENDING * \li AIAbstractList::SORT_DESCENDING + * \li AIAirport::IsAirportInformationAvailable * \li AICompany::GetPresidentGender * \li AICompany::SetPresidentGender * \li AIEngine::GetDesignDate @@ -27,7 +28,7 @@ * Other changes: * \li AIs are now killed when they execute a DoCommand or Sleep at a time * they are not allowed to do so. - * \li When the API requests a string as parameter you can give ever squirrel + * \li When the API requests a string as parameter you can give every squirrel * type and it'll be converted to a string * \li AIs can create subclasses of API classes and use API constants as part * of their own constants diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index fe79756757..b652b26a90 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1303,6 +1303,7 @@ static void CrashAirplane(Vehicle *v) CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); InvalidateWindow(WC_VEHICLE_VIEW, v->index); + v->MarkDirty(); uint amt = 2; if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) amt += v->cargo.Count(); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 504168837b..8c7179fe6f 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -651,6 +651,7 @@ static void HandleBrokenRoadVeh(Vehicle *v) InvalidateWindow(WC_VEHICLE_VIEW, v->index); InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + v->MarkDirty(); if (!PlayVehicleSound(v, VSE_BREAKDOWN)) { SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ? @@ -667,6 +668,7 @@ static void HandleBrokenRoadVeh(Vehicle *v) if (--v->breakdown_delay == 0) { v->breakdown_ctr = 0; InvalidateWindow(WC_VEHICLE_VIEW, v->index); + v->MarkDirty(); } } } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index b3ce74de2f..174fdb2464 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -551,6 +551,9 @@ public: GameSettings *opt_ptr = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game; uint i; + GetSettingFromName("difficulty.diff_level", &i); + DoCommandP(0, i, this->opt_mod_temp.difficulty.diff_level, CMD_CHANGE_SETTING); + const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i); for (uint btn = 0; btn != GAME_DIFFICULTY_NUM; btn++, sd++) { int32 new_val = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv); @@ -560,9 +563,6 @@ public: DoCommandP(0, i + btn, new_val, CMD_CHANGE_SETTING); } } - - GetSettingFromName("difficulty.diff_level", &i); - DoCommandP(0, i, this->opt_mod_temp.difficulty.diff_level, CMD_CHANGE_SETTING); delete this; /* If we are in the editor, we should reload the economy. * This way when you load a game, the max loan and interest rate diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 39a74fab0c..0581327650 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -189,6 +189,7 @@ static void HandleBrokenShip(Vehicle *v) InvalidateWindow(WC_VEHICLE_VIEW, v->index); InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + v->MarkDirty(); if (!PlayVehicleSound(v, VSE_BREAKDOWN)) { SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ? @@ -205,6 +206,7 @@ static void HandleBrokenShip(Vehicle *v) if (!--v->breakdown_delay) { v->breakdown_ctr = 0; InvalidateWindow(WC_VEHICLE_VIEW, v->index); + v->MarkDirty(); } } } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index dbba10639a..2249715a25 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1061,6 +1061,15 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED); } + if (src_head == src && !HasBit(p2, 0)) { + /* Moving of a *single* vehicle at the front of the train. + * If the next vehicle is an engine a new train will be created + * instead of removing a vehicle from a free chain. The newly + * created train may not be too long. */ + const Vehicle *u = GetNextVehicle(src_head); + if (u != NULL && IsTrainEngine(u) && (src_len - 1) > max_len) return_cmd_error(STR_8819_TRAIN_TOO_LONG); + } + /* We are moving between rows, so only count the wagons from the source * row that are being moved. */ if (HasBit(p2, 0)) { @@ -4048,6 +4057,7 @@ static void HandleBrokenTrain(Vehicle *v) InvalidateWindow(WC_VEHICLE_VIEW, v->index); InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + v->MarkDirty(); if (!PlayVehicleSound(v, VSE_BREAKDOWN)) { SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ? @@ -4064,6 +4074,7 @@ static void HandleBrokenTrain(Vehicle *v) if (!--v->breakdown_delay) { v->breakdown_ctr = 0; InvalidateWindow(WC_VEHICLE_VIEW, v->index); + v->MarkDirty(); } } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 3fc43b0be4..35d284e21f 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1734,6 +1734,7 @@ void StopAllVehicles() v->vehstatus |= VS_STOPPED; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); + v->MarkDirty(); } } diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index a6fd969362..a987b93485 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -115,6 +115,7 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); InvalidateWindowClasses(vehicle_list[v->type]); + v->MarkDirty(); } return CommandCost(); }