diff options
author | frosch <frosch@openttd.org> | 2008-08-10 15:02:21 +0000 |
---|---|---|
committer | frosch <frosch@openttd.org> | 2008-08-10 15:02:21 +0000 |
commit | 4eae917c1ce88d30e81a80230f653cfe7761ea99 (patch) | |
tree | 71f1b3a72f2c6f8bfcd5f92e59b693bd3ad4ad7b | |
parent | b1ed3bad58d892b38e9a99f6ae7df2df5d1a034d (diff) | |
download | openttd-4eae917c1ce88d30e81a80230f653cfe7761ea99.tar.xz |
(svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
-rw-r--r-- | src/autoreplace_cmd.cpp | 63 | ||||
-rw-r--r-- | src/autoreplace_func.h | 2 | ||||
-rw-r--r-- | src/autoreplace_gui.cpp | 26 | ||||
-rw-r--r-- | src/players.cpp | 16 |
4 files changed, 67 insertions, 40 deletions
diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index f4c7c9c81..8710ac171 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -24,6 +24,69 @@ #include "table/strings.h" +/** Figure out if two engines got at least one type of cargo in common (refitting if needed) + * @param engine_a one of the EngineIDs + * @param engine_b the other EngineID + * @param type the type of the engines + * @return true if they can both carry the same type of cargo (or at least one of them got no capacity at all) + */ +static bool EnginesGotCargoInCommon(EngineID engine_a, EngineID engine_b, VehicleType type) +{ + uint32 available_cargos_a = GetUnionOfArticulatedRefitMasks(engine_a, type, true); + uint32 available_cargos_b = GetUnionOfArticulatedRefitMasks(engine_b, type, true); + return (available_cargos_a == 0 || available_cargos_b == 0 || (available_cargos_a & available_cargos_b) != 0); +} + +/** + * Checks some basic properties whether autoreplace is allowed + * @param from Origin engine + * @param to Destination engine + * @param player Player to check for + * @return true if autoreplace is allowed + */ +bool CheckAutoreplaceValidity(EngineID from, EngineID to, PlayerID player) +{ + /* First we make sure that it's a valid type the user requested + * check that it's an engine that is in the engine array */ + if (!IsEngineIndex(from) || !IsEngineIndex(to)) return false; + + /* we can't replace an engine into itself (that would be autorenew) */ + if (from == to) return false; + + VehicleType type = GetEngine(from)->type; + + /* check that the new vehicle type is available to the player and its type is the same as the original one */ + if (!IsEngineBuildable(to, type, player)) return false; + + switch (type) { + case VEH_TRAIN: { + const RailVehicleInfo *rvi_from = RailVehInfo(from); + const RailVehicleInfo *rvi_to = RailVehInfo(to); + + /* make sure the railtypes are compatible */ + if ((GetRailTypeInfo(rvi_from->railtype)->compatible_railtypes & GetRailTypeInfo(rvi_to->railtype)->compatible_railtypes) == 0) return false; + + /* make sure we do not replace wagons with engines or vise versa */ + if ((rvi_from->railveh_type == RAILVEH_WAGON) != (rvi_to->railveh_type == RAILVEH_WAGON)) return false; + break; + } + + case VEH_ROAD: + /* make sure that we do not replace a tram with a normal road vehicles or vise versa */ + if (HasBit(EngInfo(from)->misc_flags, EF_ROAD_TRAM) != HasBit(EngInfo(to)->misc_flags, EF_ROAD_TRAM)) return false; + break; + + case VEH_AIRCRAFT: + /* make sure that we do not replace a plane with a helicopter or vise versa */ + if ((AircraftVehInfo(from)->subtype & AIR_CTOL) != (AircraftVehInfo(to)->subtype & AIR_CTOL)) return false; + break; + + default: break; + } + + /* the engines needs to be able to carry the same cargo */ + return EnginesGotCargoInCommon(from, to, type); +} /* * move the cargo from one engine to another if possible diff --git a/src/autoreplace_func.h b/src/autoreplace_func.h index e640b84bc..0b5129818 100644 --- a/src/autoreplace_func.h +++ b/src/autoreplace_func.h @@ -100,4 +100,6 @@ static inline CommandCost RemoveEngineReplacementForPlayer(Player *p, EngineID e return RemoveEngineReplacement(&p->engine_renew_list, engine, group, flags); } +bool CheckAutoreplaceValidity(EngineID from, EngineID to, PlayerID player); + #endif /* AUTOREPLACE_FUNC_H */ diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 1db675c24..1268cf18b 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -23,7 +23,6 @@ #include "engine_base.h" #include "window_gui.h" #include "engine_gui.h" -#include "articulated_vehicles.h" #include "table/sprites.h" #include "table/strings.h" @@ -99,19 +98,6 @@ void AddRemoveEngineFromAutoreplaceAndBuildWindows(VehicleType type) InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well } -/** Figure out if two engines got at least one type of cargo in common (refitting if needed) - * @param engine_a one of the EngineIDs - * @param engine_b the other EngineID - * @param type the type of the engines - * @return true if they can both carry the same type of cargo (or at least one of them got no capacity at all) - */ -static bool EnginesGotCargoInCommon(EngineID engine_a, EngineID engine_b, VehicleType type) -{ - uint32 available_cargos_a = GetUnionOfArticulatedRefitMasks(engine_a, type, true); - uint32 available_cargos_b = GetUnionOfArticulatedRefitMasks(engine_b, type, true); - return (available_cargos_a == 0 || available_cargos_b == 0 || (available_cargos_a & available_cargos_b) != 0); -} - /** * Window for the autoreplacing of vehicles. */ @@ -143,10 +129,6 @@ class ReplaceVehicleWindow : public Window { if (draw_left && show_engines) { /* Ensure that the railtype is specific to the selected one */ if (rvi->railtype != this->sel_railtype) return false; - } else { - /* Ensure that it's a compatible railtype to the selected one (like electric <-> diesel) - * The vehicle do not have to have power on the railtype in question, only able to drive (pulled if needed) */ - if (!IsCompatibleRail(rvi->railtype, this->sel_railtype)) return false; } return true; } @@ -177,13 +159,7 @@ class ReplaceVehicleWindow : public Window { /* Skip drawing the engines we don't have any of and haven't set for replacement */ if (num_engines == 0 && EngineReplacementForPlayer(GetPlayer(_local_player), eid, selected_group) == INVALID_ENGINE) continue; } else { - /* This is for engines we can replace to and they should depend on what we selected to replace from */ - if (!IsEngineBuildable(eid, type, _local_player)) continue; // we need to be able to build the engine - if (!EnginesGotCargoInCommon(eid, this->sel_engine[0], type)) continue; // the engines needs to be able to carry the same cargo - - /* Road vehicles can't be replaced by trams and vice-versa */ - if (type == VEH_ROAD && HasBit(EngInfo(this->sel_engine[0])->misc_flags, EF_ROAD_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue; - if (eid == this->sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew) + if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_player)) continue; } *list->Append() = eid; diff --git a/src/players.cpp b/src/players.cpp index cf1dca355..c3bef5c3c 100644 --- a/src/players.cpp +++ b/src/players.cpp @@ -717,21 +717,7 @@ CommandCost CmdSetAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2 if (!IsValidGroupID(id_g) && !IsAllGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR; if (new_engine_type != INVALID_ENGINE) { - /* First we make sure that it's a valid type the user requested - * check that it's an engine that is in the engine array */ - if (!IsEngineIndex(new_engine_type)) return CMD_ERROR; - - /* check that the new vehicle type is the same as the original one */ - if (GetEngine(old_engine_type)->type != GetEngine(new_engine_type)->type) return CMD_ERROR; - - /* make sure that we do not replace a plane with a helicopter or vise versa */ - if (GetEngine(new_engine_type)->type == VEH_AIRCRAFT && - (AircraftVehInfo(old_engine_type)->subtype & AIR_CTOL) != (AircraftVehInfo(new_engine_type)->subtype & AIR_CTOL)) { - return CMD_ERROR; - } - - /* make sure that the player can actually buy the new engine */ - if (!HasBit(GetEngine(new_engine_type)->player_avail, _current_player)) return CMD_ERROR; + if (!CheckAutoreplaceValidity(old_engine_type, new_engine_type, _current_player)) return CMD_ERROR; cost = AddEngineReplacementForPlayer(p, old_engine_type, new_engine_type, id_g, flags); } else { |