diff --git a/src/command_func.h b/src/command_func.h index e20d686886..4b0830b5f0 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -130,7 +130,7 @@ CommandCallback CcStartStopVehicle; /* tbtr_template_gui_create.cpp */ CommandCallback CcSetVirtualTrain; -CommandCallback CcVirtualTrainWaggonsMoved; +CommandCallback CcVirtualTrainWagonsMoved; CommandCallback CcDeleteVirtualTrain; /* build_vehicle_gui.cpp */ diff --git a/src/economy.cpp b/src/economy.cpp index a0171a2158..b469e52e73 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -52,6 +52,7 @@ #include "story_base.h" #include "linkgraph/refresh.h" #include "tracerestrict.h" +#include "tbtr_template_vehicle.h" #include "table/strings.h" #include "table/pricebase.h" @@ -499,6 +500,27 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } TraceRestrictUpdateCompanyID(old_owner, new_owner); + /* Change ownership of template vehicles */ + if (new_owner == INVALID_OWNER) { + TemplateVehicle *tv; + FOR_ALL_TEMPLATES(tv) { + if (tv->owner == old_owner) { + TemplateReplacement *tr; + FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { + if (tr->Template() == tv->index) { + delete tr; + } + } + delete tv; + } + } + } else { + TemplateVehicle *tv; + FOR_ALL_TEMPLATES(tv) { + if (tv->owner == old_owner) tv->owner = new_owner; + } + } + /* Change ownership of tiles */ { TileIndex tile = 0; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 5f09c1c1fe..3a31b85edf 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -350,7 +350,7 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 VehicleType vt = g->vehicle_type; /* Delete all template replacements using the just deleted group */ - deleteIllegalTemplateReplacements(g->index); + DeleteTemplateReplacementsByGroupID(g->index); /* notify tracerestrict that group is about to be deleted */ TraceRestrictRemoveGroupID(g->index); @@ -766,7 +766,10 @@ void RemoveAllGroupsForCompany(const CompanyID company) Group *g; FOR_ALL_GROUPS(g) { - if (company == g->owner) delete g; + if (company == g->owner) { + DeleteTemplateReplacementsByGroupID(g->index); + delete g; + } } } diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 2f217c2b08..9920fe137c 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -53,7 +53,7 @@ static CommandCallback * const _callback_table[] = { /* 0x1B */ CcAddVehicleNewGroup, /* 0x1C */ CcAddPlan, /* 0x1D */ CcSetVirtualTrain, - /* 0x1E */ CcVirtualTrainWaggonsMoved, + /* 0x1E */ CcVirtualTrainWagonsMoved, /* 0x1F */ CcDeleteVirtualTrain, /* 0x20 */ CcAddVirtualEngine, }; diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 132f0b7496..0d2ab22d37 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -68,7 +68,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", NULL, NULL, NULL }, { XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", NULL, NULL, NULL }, { XSLFI_LINKGRAPH_DAY_SCALE, XSCF_NULL, 1, 1, "linkgraph_day_scale", NULL, NULL, NULL }, - { XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 2, 2, "template_replacement", NULL, NULL, "TRPL,TMPL" }, + { XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 3, 3, "template_replacement", NULL, NULL, "TRPL,TMPL" }, { XSLFI_MORE_RAIL_TYPES, XSCF_NULL, 1, 1, "more_rail_types", NULL, NULL, NULL }, { XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 2, 2, "cargo_type_orders", NULL, NULL, "ORDX,VEOX" }, { XSLFI_EXTENDED_GAMELOG, XSCF_NULL, 1, 1, "extended_gamelog", NULL, NULL, NULL }, diff --git a/src/saveload/tbtr_template_veh_sl.cpp b/src/saveload/tbtr_template_veh_sl.cpp index f17607401e..cfc1b55dff 100644 --- a/src/saveload/tbtr_template_veh_sl.cpp +++ b/src/saveload/tbtr_template_veh_sl.cpp @@ -3,6 +3,7 @@ #include "../tbtr_template_vehicle.h" #include "../tbtr_template_vehicle_func.h" #include "../train.h" +#include "../company_base.h" #include "../core/backup_type.hpp" #include "../core/random_func.hpp" @@ -107,6 +108,15 @@ void AfterLoadTemplateVehiclesUpdateImage() SavedRandomSeeds saved_seeds; SaveRandomSeeds(&saved_seeds); + if (!SlXvIsFeaturePresent(XSLFI_TEMPLATE_REPLACEMENT, 3)) { + FOR_ALL_TEMPLATES(tv) { + if (tv->Prev() == NULL && !Company::IsValidID(tv->owner)) { + // clean up leftover template vehicles which no longer have a valid owner + delete tv; + } + } + } + FOR_ALL_TEMPLATES(tv) { if (tv->Prev() == NULL) { Backup cur_company(_current_company, tv->owner, FILE_LINE); diff --git a/src/tbtr_template_gui_create.cpp b/src/tbtr_template_gui_create.cpp index ee404d14fe..a21c168636 100644 --- a/src/tbtr_template_gui_create.cpp +++ b/src/tbtr_template_gui_create.cpp @@ -122,7 +122,7 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh if (wagon == v) return; DoCommandP(v->tile, v->index | ((_ctrl_pressed ? 1 : 0) << 20) | (1 << 21) , wagon == NULL ? INVALID_VEHICLE : wagon->index, - CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), CcVirtualTrainWaggonsMoved); + CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), CcVirtualTrainWagonsMoved); } class TemplateCreateWindow : public Window { @@ -569,7 +569,7 @@ void CcSetVirtualTrain(const CommandCost &result, TileIndex tile, uint32 p1, uin } } -void CcVirtualTrainWaggonsMoved(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcVirtualTrainWagonsMoved(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) { if (result.Failed()) return; diff --git a/src/tbtr_template_vehicle.cpp b/src/tbtr_template_vehicle.cpp index d0310b0495..102df3ddaa 100644 --- a/src/tbtr_template_vehicle.cpp +++ b/src/tbtr_template_vehicle.cpp @@ -103,27 +103,6 @@ TemplateVehicle* TemplateVehicle::GetPrevUnit() return tv; } -/** setting */ -void appendTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv) -{ - if (!orig) return; - while (orig->Next()) orig = orig->Next(); - orig->SetNext(newv); - newv->SetPrev(orig); - newv->SetFirst(orig->First()); -} - -void insertTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv, TemplateVehicle *insert_after) -{ - if (!orig || !insert_after) return; - TemplateVehicle *insert_before = insert_after->Next(); - insert_after->SetNext(newv); - insert_before->SetPrev(newv); - newv->SetPrev(insert_after); - newv->SetNext(insert_before); - newv->SetFirst(insert_after); -} - /** Length() * @return: length of vehicle, including current part */ @@ -177,19 +156,7 @@ short TemplateVehicle::NumGroupsUsingTemplate() const return amount; } -short TemplateVehicle::CountEnginesInChain() -{ - TemplateVehicle *tv = this->first; - short count = 0; - for (; tv != NULL; tv = tv->GetNextUnit()) { - if (HasBit(tv->subtype, GVSF_ENGINE)) { - count++; - } - } - return count; -} - -short deleteIllegalTemplateReplacements(GroupID g_id) +short DeleteTemplateReplacementsByGroupID(GroupID g_id) { short del_amount = 0; const TemplateReplacement *tr; diff --git a/src/tbtr_template_vehicle.h b/src/tbtr_template_vehicle.h index 760ef88ef8..24d176cf75 100644 --- a/src/tbtr_template_vehicle.h +++ b/src/tbtr_template_vehicle.h @@ -156,16 +156,8 @@ public: short NumGroupsUsingTemplate() const; - short CountEnginesInChain(); - }; -void appendTemplateVehicle(TemplateVehicle*, TemplateVehicle*); -void insertTemplateVehicle(TemplateVehicle*, TemplateVehicle*, TemplateVehicle*); - -void NeutralizeVehicleStatus(Train*); -void SplitVehicleRemainders(Train*); - // TemplateReplacement stuff typedef Pool TemplateReplacementPool; @@ -202,6 +194,6 @@ struct TemplateReplacement : TemplateReplacementPool::PoolItem<&_template_replac TemplateReplacement* GetTemplateReplacementByGroupID(GroupID); bool IssueTemplateReplacement(GroupID, TemplateID); -short deleteIllegalTemplateReplacements(GroupID); +short DeleteTemplateReplacementsByGroupID(GroupID); #endif /* TEMPLATE_VEH_H */ diff --git a/src/tbtr_template_vehicle_func.cpp b/src/tbtr_template_vehicle_func.cpp index c68d9be2e5..3c5ead2592 100644 --- a/src/tbtr_template_vehicle_func.cpp +++ b/src/tbtr_template_vehicle_func.cpp @@ -196,34 +196,6 @@ TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt) return tmp->First(); } -// return last in a chain (really last, so even a singular articulated part of a vehicle if the last one is artic) -inline TemplateVehicle* Last(TemplateVehicle *chain) -{ - if (!chain) return NULL; - while (chain->Next()) { - chain = chain->Next(); - } - return chain; -} - -inline Train* Last(Train *chain) -{ - if (!chain) return NULL; - while (chain->GetNextUnit()) { - chain = chain->GetNextUnit(); - } - return chain; -} - -// return: pointer to former vehicle -TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle *todel) -{ - if (!todel) return NULL; - TemplateVehicle *cur = todel; - delete todel; - return cur; -} - // forward declaration, defined in train_cmd.cpp CommandCost CmdSellRailWagon(DoCommandFlag, Vehicle*, uint16, uint32); @@ -239,24 +211,15 @@ Train* DeleteVirtualTrain(Train *chain, Train *to_del) { } } -// retrieve template vehicle from templatereplacement that belongs to the given group +// retrieve template vehicle from template replacement that belongs to the given group TemplateVehicle* GetTemplateVehicleByGroupID(GroupID gid) { + if (gid >= NEW_GROUP) return NULL; TemplateReplacement *tr; - // first try to find a templatereplacement issued for the given groupid FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { if (tr->Group() == gid) { return TemplateVehicle::GetIfValid(tr->Template()); // there can be only one } } - // if that didn't work, try to find a templatereplacement for ALL_GROUP - if (gid != ALL_GROUP) { - FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { - if (tr->Group() == ALL_GROUP) { - return TemplateVehicle::GetIfValid(tr->Template()); - } - } - } - // if all failed, just return null return NULL; } @@ -323,18 +286,6 @@ Train* DepotContainsEngine(TileIndex tile, EngineID eid, Train *not_in = NULL) return NULL; } -void CopyStatus(Train *from, Train *to) -{ - DoCommand(to->tile, from->group_id, to->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP); - to->cargo_type = from->cargo_type; - to->cargo_subtype = from->cargo_subtype; - - // swap names - char *tmp = to->name; - to->name = from->name; - from->name = tmp; -} - void NeutralizeStatus(Train *t) { DoCommand(t->tile, DEFAULT_GROUP, t->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP); @@ -389,84 +340,6 @@ void BreakUpRemainders(Train *t) } } -short CountEnginesInChain(Train *t) -{ - short count = 0; - for (; t != NULL; t = t->GetNextUnit()) { - if (HasBit(t->subtype, GVSF_ENGINE)) { - count++; - } - } - return count; -} - -int countOccurrencesInTrain(Train *t, EngineID eid) -{ - int count = 0; - Train *tmp = t; - for (; tmp != NULL; tmp = tmp->GetNextUnit()) { - if (tmp->engine_type == eid) { - count++; - } - } - return count; -} - -int countOccurrencesInTemplateVehicle(TemplateVehicle *contain, EngineID eid) -{ - int count = 0; - for (; contain; contain=contain->GetNextUnit()) { - if (contain->engine_type == eid) { - count++; - } - } - return count; -} - -int countOccurrencesInDepot(TileIndex tile, EngineID eid, Train *not_in = NULL) -{ - int count = 0; - Vehicle *v; - FOR_ALL_VEHICLES(v) { - // conditions: v is stopped in the given depot, has the right engine and if 'not_in' is given v must not be contained within 'not_in' - // if 'not_in' is NULL, no check is needed - if (v->tile == tile && v->IsStoppedInDepot() && v->engine_type == eid && - (not_in == 0 || ChainContainsVehicle(not_in, (Train*)v) == false)) { - count++; - } - } - return count; -} - -// basically does the same steps as CmdTemplateReplaceVehicle but without actually moving things around -CommandCost CalculateTemplateReplacementCost(Train *incoming) -{ - TileIndex tile = incoming->tile; - TemplateVehicle *tv = GetTemplateVehicleByGroupID(incoming->group_id); - CommandCost estimate(EXPENSES_NEW_VEHICLES); - - // count for each different eid in the incoming train - std::map unique_eids; - for (TemplateVehicle *tmp = tv; tmp != NULL; tmp = tmp->GetNextUnit()) { - unique_eids[tmp->engine_type]++; - } - std::map::iterator it = unique_eids.begin(); - for (; it != unique_eids.end(); it++) { - it->second -= countOccurrencesInTrain(incoming, it->first); - it->second -= countOccurrencesInDepot(incoming->tile, it->first, incoming); - if (it->second < 0) it->second = 0; - } - - // get overall buying cost - for (it = unique_eids.begin(); it != unique_eids.end(); it++) { - for (int j = 0; j < it->second; j++) { - estimate.AddCost(DoCommand(tile, it->first, 0, DC_NONE, CMD_BUILD_VEHICLE)); - } - } - - return estimate; -} - // make sure the real train wagon has the right cargo void CopyWagonStatus(TemplateVehicle *from, Train *to) { diff --git a/src/tbtr_template_vehicle_func.h b/src/tbtr_template_vehicle_func.h index 7e3bfa36bf..3cb562c815 100644 --- a/src/tbtr_template_vehicle_func.h +++ b/src/tbtr_template_vehicle_func.h @@ -19,31 +19,14 @@ Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv, StringID &err); -void DrawTemplateVehicle(const TemplateVehicle*, int, int, int, VehicleID, int, VehicleID); - void BuildTemplateGuiList(GUITemplateList*, Scrollbar*, Owner, RailType); Money CalculateOverallTemplateCost(const TemplateVehicle*); -void DrawTemplateTrain(const TemplateVehicle*, int, int, int); - -SpriteID GetSpriteID(EngineID, bool); - void DrawTemplate(const TemplateVehicle*, int, int, int); -int GetTemplateDisplayImageWidth(EngineID); - -TemplateVehicle *CreateNewTemplateVehicle(EngineID); - -void setupVirtTrain(const TemplateVehicle*, Train*); - TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt); -inline TemplateVehicle* Last(TemplateVehicle*); - -TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle*); - -Train* DeleteVirtualTrainPart(Train*, Train*); Train* DeleteVirtualTrain(Train*, Train *); CommandCost CmdTemplateReplaceVehicle(Train*, bool, DoCommandFlag); @@ -63,14 +46,11 @@ Train* DepotContainsEngine(TileIndex, EngineID, Train*); int NumTrainsNeedTemplateReplacement(GroupID, TemplateVehicle*); -CommandCost CalculateTemplateReplacementCost(Train*); CommandCost TestBuyAllTemplateVehiclesInChain(TemplateVehicle *tv, TileIndex tile); void CmdRefitTrainFromTemplate(Train *t, TemplateVehicle *tv, DoCommandFlag); void BreakUpRemainders(Train *t); -short CountEnginesInChain(Train*); - bool TemplateVehicleContainsEngineOfRailtype(const TemplateVehicle*, RailType); void TransferCargoForTrain(Train*, Train*);