Update: Translations from eints
[openttd-github.git] / src / script / api / script_stationlist.cpp
blob04bb8c07b1ef28a80ab4cf209842fec7f7c6f900
1 /*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <http://www.gnu.org/licenses/>.
6 */
8 /** @file script_stationlist.cpp Implementation of ScriptStationList and friends. */
10 #include "../../stdafx.h"
11 #include "script_stationlist.hpp"
12 #include "script_vehicle.hpp"
13 #include "script_cargo.hpp"
14 #include "../../station_base.h"
15 #include "../../vehicle_base.h"
17 #include "../../safeguards.h"
19 ScriptStationList::ScriptStationList(ScriptStation::StationType station_type)
21 EnforceDeityOrCompanyModeValid_Void();
22 bool is_deity = ScriptCompanyMode::IsDeity();
23 CompanyID owner = ScriptObject::GetCompany();
24 ScriptList::FillList<Station>(this,
25 [is_deity, owner, station_type](const Station *st) {
26 return (is_deity || st->owner == owner) && (st->facilities & static_cast<StationFacility>(station_type)) != 0;
31 ScriptStationList_Vehicle::ScriptStationList_Vehicle(VehicleID vehicle_id)
33 if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return;
35 const Vehicle *v = ::Vehicle::Get(vehicle_id);
37 for (Order *o = v->GetFirstOrder(); o != nullptr; o = o->next) {
38 if (o->IsType(OT_GOTO_STATION)) this->AddItem(o->GetDestination());
42 ScriptStationList_Cargo::ScriptStationList_Cargo(ScriptStationList_Cargo::CargoMode mode,
43 ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
44 StationID other_station)
46 switch (mode) {
47 case CM_WAITING:
48 ScriptStationList_CargoWaiting(selector, station_id, cargo, other_station).SwapList(this);
49 break;
50 case CM_PLANNED:
51 ScriptStationList_CargoPlanned(selector, station_id, cargo, other_station).SwapList(this);
52 break;
53 default:
54 NOT_REACHED();
58 ScriptStationList_CargoWaiting::ScriptStationList_CargoWaiting(
59 ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
60 StationID other_station)
62 switch (selector) {
63 case CS_BY_FROM:
64 ScriptStationList_CargoWaitingByFrom(station_id, cargo).SwapList(this);
65 break;
66 case CS_VIA_BY_FROM:
67 ScriptStationList_CargoWaitingViaByFrom(station_id, cargo, other_station).SwapList(this);
68 break;
69 case CS_BY_VIA:
70 ScriptStationList_CargoWaitingByVia(station_id, cargo).SwapList(this);
71 break;
72 case CS_FROM_BY_VIA:
73 ScriptStationList_CargoWaitingFromByVia(station_id, cargo, other_station).SwapList(this);
74 break;
75 default:
76 NOT_REACHED();
80 ScriptStationList_CargoPlanned::ScriptStationList_CargoPlanned(
81 ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
82 StationID other_station)
84 switch (selector) {
85 case CS_BY_FROM:
86 ScriptStationList_CargoPlannedByFrom(station_id, cargo).SwapList(this);
87 break;
88 case CS_VIA_BY_FROM:
89 ScriptStationList_CargoPlannedViaByFrom(station_id, cargo, other_station).SwapList(this);
90 break;
91 case CS_BY_VIA:
92 ScriptStationList_CargoPlannedByVia(station_id, cargo).SwapList(this);
93 break;
94 case CS_FROM_BY_VIA:
95 ScriptStationList_CargoPlannedFromByVia(station_id, cargo, other_station).SwapList(this);
96 break;
97 default:
98 NOT_REACHED();
102 class CargoCollector {
103 public:
104 CargoCollector(ScriptStationList_Cargo *parent, StationID station_id, CargoID cargo,
105 StationID other);
106 ~CargoCollector() ;
108 template<ScriptStationList_Cargo::CargoSelector Tselector>
109 void Update(StationID from, StationID via, uint amount);
110 const GoodsEntry *GE() const { return ge; }
112 private:
113 void SetValue();
115 ScriptStationList_Cargo *list;
116 const GoodsEntry *ge;
117 StationID other_station;
119 StationID last_key;
120 uint amount;
123 CargoCollector::CargoCollector(ScriptStationList_Cargo *parent,
124 StationID station_id, CargoID cargo, StationID other) :
125 list(parent), ge(nullptr), other_station(other), last_key(INVALID_STATION), amount(0)
127 if (!ScriptStation::IsValidStation(station_id)) return;
128 if (!ScriptCargo::IsValidCargo(cargo)) return;
129 this->ge = &(Station::Get(station_id)->goods[cargo]);
132 CargoCollector::~CargoCollector()
134 this->SetValue();
137 void CargoCollector::SetValue()
139 if (this->amount > 0) {
140 if (this->list->HasItem(this->last_key)) {
141 this->list->SetValue(this->last_key,
142 this->list->GetValue(this->last_key) + this->amount);
143 } else {
144 this->list->AddItem(this->last_key, this->amount);
149 template<ScriptStationList_Cargo::CargoSelector Tselector>
150 void CargoCollector::Update(StationID from, StationID via, uint amount)
152 StationID key = INVALID_STATION;
153 switch (Tselector) {
154 case ScriptStationList_Cargo::CS_VIA_BY_FROM:
155 if (via != this->other_station) return;
156 [[fallthrough]];
157 case ScriptStationList_Cargo::CS_BY_FROM:
158 key = from;
159 break;
160 case ScriptStationList_Cargo::CS_FROM_BY_VIA:
161 if (from != this->other_station) return;
162 [[fallthrough]];
163 case ScriptStationList_Cargo::CS_BY_VIA:
164 key = via;
165 break;
167 if (key == this->last_key) {
168 this->amount += amount;
169 } else {
170 this->SetValue();
171 this->amount = amount;
172 this->last_key = key;
177 template<ScriptStationList_Cargo::CargoSelector Tselector>
178 void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoID cargo, StationID other_station)
180 CargoCollector collector(this, station_id, cargo, other_station);
181 if (collector.GE() == nullptr) return;
183 StationCargoList::ConstIterator iter = collector.GE()->cargo.Packets()->begin();
184 StationCargoList::ConstIterator end = collector.GE()->cargo.Packets()->end();
185 for (; iter != end; ++iter) {
186 collector.Update<Tselector>((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count());
191 template<ScriptStationList_Cargo::CargoSelector Tselector>
192 void ScriptStationList_CargoPlanned::Add(StationID station_id, CargoID cargo, StationID other_station)
194 CargoCollector collector(this, station_id, cargo, other_station);
195 if (collector.GE() == nullptr) return;
197 FlowStatMap::const_iterator iter = collector.GE()->flows.begin();
198 FlowStatMap::const_iterator end = collector.GE()->flows.end();
199 for (; iter != end; ++iter) {
200 const FlowStat::SharesMap *shares = iter->second.GetShares();
201 uint prev = 0;
202 for (FlowStat::SharesMap::const_iterator flow_iter = shares->begin();
203 flow_iter != shares->end(); ++flow_iter) {
204 collector.Update<Tselector>(iter->first, flow_iter->second, flow_iter->first - prev);
205 prev = flow_iter->first;
210 ScriptStationList_CargoWaitingByFrom::ScriptStationList_CargoWaitingByFrom(StationID station_id,
211 CargoID cargo)
213 this->Add<CS_BY_FROM>(station_id, cargo);
216 ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom(
217 StationID station_id, CargoID cargo, StationID via)
219 CargoCollector collector(this, station_id, cargo, via);
220 if (collector.GE() == nullptr) return;
222 std::pair<StationCargoList::ConstIterator, StationCargoList::ConstIterator> range =
223 collector.GE()->cargo.Packets()->equal_range(via);
224 for (StationCargoList::ConstIterator iter = range.first; iter != range.second; ++iter) {
225 collector.Update<CS_VIA_BY_FROM>((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count());
230 ScriptStationList_CargoWaitingByVia::ScriptStationList_CargoWaitingByVia(StationID station_id,
231 CargoID cargo)
233 this->Add<CS_BY_VIA>(station_id, cargo);
236 ScriptStationList_CargoWaitingFromByVia::ScriptStationList_CargoWaitingFromByVia(
237 StationID station_id, CargoID cargo, StationID from)
239 this->Add<CS_FROM_BY_VIA>(station_id, cargo, from);
242 ScriptStationList_CargoPlannedByFrom::ScriptStationList_CargoPlannedByFrom(StationID station_id,
243 CargoID cargo)
245 this->Add<CS_BY_FROM>(station_id, cargo);
248 ScriptStationList_CargoPlannedViaByFrom::ScriptStationList_CargoPlannedViaByFrom(
249 StationID station_id, CargoID cargo, StationID via)
251 this->Add<CS_VIA_BY_FROM>(station_id, cargo, via);
255 ScriptStationList_CargoPlannedByVia::ScriptStationList_CargoPlannedByVia(StationID station_id,
256 CargoID cargo)
258 this->Add<CS_BY_VIA>(station_id, cargo);
262 ScriptStationList_CargoPlannedFromByVia::ScriptStationList_CargoPlannedFromByVia(
263 StationID station_id, CargoID cargo, StationID from)
265 CargoCollector collector(this, station_id, cargo, from);
266 if (collector.GE() == nullptr) return;
268 FlowStatMap::const_iterator iter = collector.GE()->flows.find(from);
269 if (iter == collector.GE()->flows.end()) return;
270 const FlowStat::SharesMap *shares = iter->second.GetShares();
271 uint prev = 0;
272 for (FlowStat::SharesMap::const_iterator flow_iter = shares->begin();
273 flow_iter != shares->end(); ++flow_iter) {
274 collector.Update<CS_FROM_BY_VIA>(iter->first, flow_iter->second, flow_iter->first - prev);
275 prev = flow_iter->first;