/* $Id$ */ /* * This file is part of OpenTTD. * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . */ /** @file tbtr_template_vehicle.cpp Template-based train replacement: template vehicle. */ #include "stdafx.h" #include "company_func.h" #include "train.h" #include "command_func.h" #include "engine_func.h" #include "vehicle_func.h" #include "autoreplace_func.h" #include "autoreplace_gui.h" #include "group.h" #include "articulated_vehicles.h" #include "core/random_func.hpp" #include "core/pool_type.hpp" #include "engine_type.h" #include "group_type.h" #include "core/pool_func.hpp" #include "table/strings.h" #include "newgrf.h" #include "vehicle_type.h" #include "vehicle_base.h" #include "vehicle_func.h" #include "table/train_cmd.h" #include "tbtr_template_vehicle.h" // since doing stuff with sprites #include "newgrf_spritegroup.h" #include "newgrf_engine.h" #include "newgrf_cargo.h" #include "safeguards.h" TemplatePool _template_pool("TemplatePool"); INSTANTIATE_POOL_METHODS(Template) TemplateReplacementPool _template_replacement_pool("TemplateReplacementPool"); INSTANTIATE_POOL_METHODS(TemplateReplacement) void TemplateVehicleImageDimensions::SetFromTrain(const Train *t) { this->reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; this->vehicle_pitch = 0; this->cached_veh_length = t->gcache.cached_veh_length; const Engine *e = t->GetEngine(); if (e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) { this->reference_width = e->GetGRF()->traininfo_vehicle_width; this->vehicle_pitch = e->GetGRF()->traininfo_vehicle_pitch; } } TemplateVehicle::TemplateVehicle(VehicleType ty, EngineID eid, byte subtypeflag, Owner current_owner) { this->type = ty; this->engine_type = eid; this->reuse_depot_vehicles = true; this->keep_remaining_vehicles = true; this->first = this; this->next = 0x0; this->previous = 0x0; this->sprite_seq.Set(SPR_IMG_QUERY); this->owner = current_owner; this->real_consist_length = 0; } TemplateVehicle::~TemplateVehicle() { TemplateVehicle *v = this->Next(); this->SetNext(nullptr); delete v; } /** getting */ void TemplateVehicle::SetNext(TemplateVehicle *v) { this->next = v; } void TemplateVehicle::SetPrev(TemplateVehicle *v) { this->previous = v; } void TemplateVehicle::SetFirst(TemplateVehicle *v) { this->first = v; } TemplateVehicle* TemplateVehicle::GetNextUnit() const { TemplateVehicle *tv = this->Next(); while (tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART)) { tv = tv->Next(); } if (tv && HasBit(tv->subtype, GVSF_MULTIHEADED) && !HasBit(tv->subtype, GVSF_ENGINE)) tv = tv->Next(); return tv; } TemplateVehicle* TemplateVehicle::GetPrevUnit() { TemplateVehicle *tv = this->Prev(); while (tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART|GVSF_ENGINE)) { tv = tv->Prev(); } if (tv && HasBit(tv->subtype, GVSF_MULTIHEADED|GVSF_ENGINE)) tv = tv->Prev(); return tv; } /** Length() * @return: length of vehicle, including current part */ int TemplateVehicle::Length() const { int l = 1; const TemplateVehicle *tmp = this; while (tmp->Next()) { tmp = tmp->Next(); l++; } return l; } TemplateReplacement* GetTemplateReplacementByGroupID(GroupID gid) { TemplateReplacement *tr; FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { if (tr->Group() == gid) { return tr; } } return nullptr; } bool IssueTemplateReplacement(GroupID gid, TemplateID tid) { TemplateReplacement *tr = GetTemplateReplacementByGroupID(gid); if (tr) { /* Then set the new TemplateVehicle and return */ tr->SetTemplate(tid); return true; } else if (TemplateReplacement::CanAllocateItem()) { tr = new TemplateReplacement(gid, tid); return true; } else return false; } short TemplateVehicle::NumGroupsUsingTemplate() const { short amount = 0; const TemplateReplacement *tr; FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { if (tr->sel_template == this->index) { amount++; } } return amount; } short DeleteTemplateReplacementsByGroupID(GroupID g_id) { short del_amount = 0; const TemplateReplacement *tr; FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { if (tr->group == g_id) { delete tr; del_amount++; } } return del_amount; }