# HG changeset patch
# Parent f0e1386dbf71a9aeffb5b40fe83e99f266788f25
# User oberhuemer
diff -r f0e1386dbf71 projects/openttd_vs100.vcxproj
--- a/projects/openttd_vs100.vcxproj Mon Sep 19 05:37:11 2011 +0000
+++ b/projects/openttd_vs100.vcxproj Wed Sep 21 21:58:36 2011 -0400
@@ -1,4 +1,4 @@
-
+
@@ -87,6 +87,10 @@
$(SolutionDir)..\objs\$(Platform)\$(Configuration)\
$(ProjectDir)..\bin
+ D:\TTD\OpenTTD\useful-openttd\shared\include;$(IncludePath)
+ D:\TTD\OpenTTD\useful-openttd\win32\library;$(LibraryPath)
+ D:\TTD\OpenTTD\useful-openttd\shared\include;$(IncludePath)
+ D:\TTD\OpenTTD\useful-openttd\win32\library;$(LibraryPath)
@@ -102,7 +106,7 @@
Size
true
..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)
- WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;ENABLE_AI;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)
+ WIN32;NDEBUG;_CONSOLE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;ENABLE_AI;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)
true
Sync
MultiThreaded
@@ -296,6 +300,7 @@
+
@@ -386,6 +391,10 @@
+
+
+
+
@@ -572,6 +581,7 @@
+
@@ -636,6 +646,7 @@
+
@@ -717,6 +728,7 @@
+
@@ -1074,6 +1086,7 @@
+
@@ -1121,4 +1134,4 @@
-
+
\ No newline at end of file
diff -r f0e1386dbf71 projects/openttd_vs100.vcxproj.filters
--- a/projects/openttd_vs100.vcxproj.filters Mon Sep 19 05:37:11 2011 +0000
+++ b/projects/openttd_vs100.vcxproj.filters Wed Sep 21 21:58:36 2011 -0400
@@ -108,6 +108,9 @@
Source Files
+
+ Source Files
+
Source Files
@@ -378,6 +381,18 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
Header Files
@@ -936,6 +951,9 @@
Header Files
+
+ Header Files
+
Header Files
@@ -1128,6 +1146,9 @@
GUI Source Code
+
+ GUI Source Code
+
GUI Source Code
@@ -1371,6 +1392,9 @@
Save/Load handlers
+
+ Save/Load handlers
+
Save/Load handlers
@@ -2442,6 +2466,9 @@
YAPF
+
+ YAPF
+
YAPF
diff -r f0e1386dbf71 projects/openttd_vs80.vcproj
--- a/projects/openttd_vs80.vcproj Mon Sep 19 05:37:11 2011 +0000
+++ b/projects/openttd_vs80.vcproj Wed Sep 21 21:58:36 2011 -0400
@@ -455,6 +455,10 @@
>
+
+
@@ -819,6 +823,22 @@
>
+
+
+
+
+
+
+
+
@@ -1563,6 +1583,10 @@
>
+
+
@@ -1827,6 +1851,10 @@
>
+
+
@@ -2163,6 +2191,10 @@
>
+
+
@@ -3663,6 +3695,10 @@
>
+
+
diff -r f0e1386dbf71 projects/openttd_vs90.vcproj
--- a/projects/openttd_vs90.vcproj Mon Sep 19 05:37:11 2011 +0000
+++ b/projects/openttd_vs90.vcproj Wed Sep 21 21:58:36 2011 -0400
@@ -452,6 +452,10 @@
>
+
+
@@ -816,6 +820,22 @@
>
+
+
+
+
+
+
+
+
@@ -1560,6 +1580,10 @@
>
+
+
@@ -1824,6 +1848,10 @@
>
+
+
@@ -2160,6 +2188,10 @@
>
+
+
@@ -3660,6 +3692,10 @@
>
+
+
diff -r f0e1386dbf71 source.list
--- a/source.list Mon Sep 19 05:37:11 2011 +0000
+++ b/source.list Wed Sep 21 21:58:36 2011 -0400
@@ -4,6 +4,7 @@
articulated_vehicles.cpp
autoreplace.cpp
bmp.cpp
+cargodest.cpp
cargopacket.cpp
cargotype.cpp
cheat.cpp
@@ -119,6 +120,10 @@
bmp.h
bridge.h
cargo_type.h
+cargodest_base.h
+cargodest_func.h
+cargodest_gui.h
+cargodest_type.h
cargopacket.h
cargotype.h
cheat_func.h
@@ -305,6 +310,7 @@
tilearea_type.h
tilehighlight_func.h
tilehighlight_type.h
+tilematrix_type.hpp
timetable.h
toolbar_gui.h
town.h
@@ -388,6 +394,7 @@
autoreplace_gui.cpp
bridge_gui.cpp
build_vehicle_gui.cpp
+cargodest_gui.cpp
cheat_gui.cpp
company_gui.cpp
console_gui.cpp
@@ -475,6 +482,7 @@
saveload/airport_sl.cpp
saveload/animated_tile_sl.cpp
saveload/autoreplace_sl.cpp
+saveload/cargodest_sl.cpp
saveload/cargopacket_sl.cpp
saveload/cheat_sl.cpp
saveload/company_sl.cpp
@@ -875,6 +883,7 @@
pathfinder/yapf/yapf.hpp
pathfinder/yapf/yapf_base.hpp
pathfinder/yapf/yapf_cache.h
+pathfinder/yapf/yapf_cargo.cpp
pathfinder/yapf/yapf_common.hpp
pathfinder/yapf/yapf_costbase.hpp
pathfinder/yapf/yapf_costcache.hpp
diff -r f0e1386dbf71 src/ai/api/ai_town.cpp
--- a/src/ai/api/ai_town.cpp Mon Sep 19 05:37:11 2011 +0000
+++ b/src/ai/api/ai_town.cpp Wed Sep 21 21:58:36 2011 -0400
@@ -71,8 +71,8 @@
const Town *t = ::Town::Get(town_id);
switch (AICargo::GetTownEffect(cargo_id)) {
- case AICargo::TE_PASSENGERS: return t->max_pass;
- case AICargo::TE_MAIL: return t->max_mail;
+ case AICargo::TE_PASSENGERS: return t->pass.old_max;
+ case AICargo::TE_MAIL: return t->mail.old_max;
default: return -1;
}
}
@@ -85,8 +85,8 @@
const Town *t = ::Town::Get(town_id);
switch (AICargo::GetTownEffect(cargo_id)) {
- case AICargo::TE_PASSENGERS: return t->act_pass;
- case AICargo::TE_MAIL: return t->act_mail;
+ case AICargo::TE_PASSENGERS: return t->pass.old_act;
+ case AICargo::TE_MAIL: return t->mail.old_act;
default: return -1;
}
}
diff -r f0e1386dbf71 src/aircraft_cmd.cpp
--- a/src/aircraft_cmd.cpp Mon Sep 19 05:37:11 2011 +0000
+++ b/src/aircraft_cmd.cpp Wed Sep 21 21:58:36 2011 -0400
@@ -35,6 +35,7 @@
#include "engine_base.h"
#include "core/random_func.hpp"
#include "core/backup_type.hpp"
+#include "cargotype.h"
#include "table/strings.h"
@@ -554,6 +555,13 @@
v->vcache.cached_cargo_age_period = GetVehicleProperty(v, PROP_AIRCRAFT_CARGO_AGE_PERIOD, EngInfo(v->engine_type)->cargo_age_period);
Aircraft *u = v->Next(); // Shadow for mail
u->vcache.cached_cargo_age_period = GetVehicleProperty(u, PROP_AIRCRAFT_CARGO_AGE_PERIOD, EngInfo(u->engine_type)->cargo_age_period);
+
+ /* Cache carried cargo types. */
+ uint32 cargo_mask = 0;
+ for (Aircraft *u = v; u != NULL; u = u->Next()) {
+ if (u->cargo_type != INVALID_CARGO && u->cargo_cap > 0) SetBit(cargo_mask, u->cargo_type);
+ }
+ v->vcache.cached_cargo_mask = cargo_mask;
}
@@ -1202,7 +1210,6 @@
if (v->current_order.IsType(OT_GOTO_DEPOT)) return;
Station *st = Station::Get(v->targetairport);
- v->last_station_visited = v->targetairport;
/* Check if station was ever visited before */
if (!(st->had_vehicle_of_type & HVOT_AIRCRAFT)) {
@@ -1218,7 +1225,7 @@
AI::NewEvent(v->owner, new AIEventStationFirstVehicle(st->index, v->index));
}
- v->BeginLoading();
+ v->BeginLoading(v->targetairport);
}
/**
diff -r f0e1386dbf71 src/base_station_base.h
--- a/src/base_station_base.h Mon Sep 19 05:37:11 2011 +0000
+++ b/src/base_station_base.h Wed Sep 21 21:58:36 2011 -0400
@@ -39,6 +39,7 @@
StationRect();
void MakeEmpty();
bool PtInExtendedRect(int x, int y, int distance = 0) const;
+ bool AreaInExtendedRect(const TileArea& area, int distance = 0) const;
bool IsEmpty() const;
CommandCost BeforeAddTile(TileIndex tile, StationRectMode mode);
CommandCost BeforeAddRect(TileIndex tile, int w, int h, StationRectMode mode);
diff -r f0e1386dbf71 src/cargopacket.cpp
--- a/src/cargopacket.cpp Mon Sep 19 05:37:11 2011 +0000
+++ b/src/cargopacket.cpp Wed Sep 21 21:58:36 2011 -0400
@@ -12,6 +12,10 @@
#include "stdafx.h"
#include "core/pool_func.hpp"
#include "economy_base.h"
+#include "station_base.h"
+#include "cargodest_func.h"
+#include "cargodest_base.h"
+#include "settings_type.h"
/* Initialize the cargopacket-pool */
CargoPacketPool _cargopacket_pool("CargoPacket");
@@ -24,6 +28,12 @@
{
this->source_type = ST_INDUSTRY;
this->source_id = INVALID_SOURCE;
+ this->dest_xy = INVALID_TILE;
+ this->dest_id = INVALID_SOURCE;
+ this->dest_type = ST_INDUSTRY;
+ this->flags = 0;
+ this->next_order = INVALID_ORDER;
+ this->next_station = INVALID_STATION;
}
/**
@@ -33,21 +43,33 @@
* @param count Number of cargo entities to put in this packet.
* @param source_type 'Type' of source the packet comes from (for subsidies).
* @param source_id Actual source of the packet (for subsidies).
+ * @param dest_xy Destination location of the packet.
+ * @param dest_type 'Type' of the destination.
+ * @param dest_id Actual destination of the packet.
+ * @param next_order Desired next hop of the packet.
+ * @param next_station Station to unload the packet next.
+ * @param flags Routing flags of the packet.
* @pre count != 0
* @note We have to zero memory ourselves here because we are using a 'new'
* that, in contrary to all other pools, does not memset to 0.
*/
-CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16 count, SourceType source_type, SourceID source_id) :
+CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16 count, SourceType source_type, SourceID source_id, TileIndex dest_xy, SourceType dest_type, SourceID dest_id, OrderID next_order, StationID next_station, byte flags) :
feeder_share(0),
count(count),
days_in_transit(0),
source_id(source_id),
source(source),
source_xy(source_xy),
- loaded_at_xy(0)
+ loaded_at_xy(0),
+ dest_xy(dest_xy),
+ dest_id(dest_id),
+ flags(flags),
+ next_order(next_order),
+ next_station(next_station)
{
assert(count != 0);
this->source_type = source_type;
+ this->dest_type = dest_type;
}
/**
@@ -61,20 +83,32 @@
* @param feeder_share Feeder share the packet has already accumulated.
* @param source_type 'Type' of source the packet comes from (for subsidies).
* @param source_id Actual source of the packet (for subsidies).
+ * @param dest_xy Destination location of the packet.
+ * @param dest_type 'Type' of the destination.
+ * @param dest_id Actual destination of the packet.
+ * @param next_order Desired next hop of the packet.
+ * @param next_station Station to unload the packet next.
+ * @param flags Routing flags of the packet.
* @note We have to zero memory ourselves here because we are using a 'new'
* that, in contrary to all other pools, does not memset to 0.
*/
-CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share, SourceType source_type, SourceID source_id) :
+CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share, SourceType source_type, SourceID source_id, TileIndex dest_xy, SourceType dest_type, SourceID dest_id, OrderID next_order, StationID next_station, byte flags) :
feeder_share(feeder_share),
count(count),
days_in_transit(days_in_transit),
source_id(source_id),
source(source),
source_xy(source_xy),
- loaded_at_xy(loaded_at_xy)
+ loaded_at_xy(loaded_at_xy),
+ dest_xy(dest_xy),
+ dest_id(dest_id),
+ flags(flags),
+ next_order(next_order),
+ next_station(next_station)
{
assert(count != 0);
this->source_type = source_type;
+ this->dest_type = dest_type;
}
/**
@@ -87,7 +121,7 @@
if (!CargoPacket::CanAllocateItem()) return NULL;
Money fs = this->feeder_share * new_size / static_cast(this->count);
- CargoPacket *cp_new = new CargoPacket(new_size, this->days_in_transit, this->source, this->source_xy, this->loaded_at_xy, fs, this->source_type, this->source_id);
+ CargoPacket *cp_new = new CargoPacket(new_size, this->days_in_transit, this->source, this->source_xy, this->loaded_at_xy, fs, this->source_type, this->source_id, this->dest_xy, this->dest_type, this->dest_id, this->next_order, this->next_station, this->flags);
this->feeder_share -= fs;
this->count -= new_size;
return cp_new;
@@ -111,9 +145,16 @@
*/
/* static */ void CargoPacket::InvalidateAllFrom(SourceType src_type, SourceID src)
{
+ /* Clear next hop of those packets that loose their destination. */
+ StationCargoList::InvalidateAllTo(src_type, src);
+
CargoPacket *cp;
FOR_ALL_CARGOPACKETS(cp) {
if (cp->source_type == src_type && cp->source_id == src) cp->source_id = INVALID_SOURCE;
+ if (cp->dest_type == src_type && cp->dest_id == src) {
+ cp->dest_id = INVALID_SOURCE;
+ cp->dest_xy = INVALID_TILE;
+ }
}
}
@@ -126,6 +167,7 @@
CargoPacket *cp;
FOR_ALL_CARGOPACKETS(cp) {
if (cp->source == sid) cp->source = INVALID_STATION;
+ if (cp->next_station == sid) cp->next_station = INVALID_STATION;
}
}
@@ -229,6 +271,7 @@
uint diff = local_count - max_remaining;
this->count -= diff;
this->cargo_days_in_transit -= cp->days_in_transit * diff;
+ static_cast(this)->RemoveFromCacheLocal(cp, diff);
cp->count = max_remaining;
max_remaining = 0;
} else {
@@ -245,56 +288,121 @@
* - MTA_CARGO_LOAD: Sets the loaded_at_xy value of the moved packets.
* - MTA_TRANSFER: Just move without side effects.
* - MTA_UNLOAD: Just move without side effects.
+ * - MTA_NO_ACTION: Does nothing for packets without destination, otherwise either like MTA_TRANSFER or MTA_FINAL_DELIVERY.
* @param dest Destination to move the cargo to.
* @param max_move Amount of cargo entities to move.
* @param mta How to handle the moving (side effects).
- * @param data Depending on mta the data of this variable differs:
- * - MTA_FINAL_DELIVERY - Station ID of packet's origin not to remove.
- * - MTA_CARGO_LOAD - Station's tile index of load.
- * - MTA_TRANSFER - Unused.
- * - MTA_UNLOAD - Unused.
+ * @param st Station ID where we are loading/unloading or STATION_INVALID for move from vehicle to vehicle.
* @param payment The payment helper.
+ * @param cur_order The current order of the loading vehicle.
+ * @param did_transfer Set to true if some cargo was transfered.
*
* @pre mta == MTA_FINAL_DELIVERY || dest != NULL
* @pre mta == MTA_UNLOAD || mta == MTA_CARGO_LOAD || payment != NULL
+ * @pre st != INVALID_STATION || (mta != MTA_CARGO_LOAD && payment == NULL)
* @return True if there are still packets that might be moved from this cargo list.
*/
template
template
-bool CargoList::MoveTo(Tother_inst *dest, uint max_move, MoveToAction mta, CargoPayment *payment, uint data)
+bool CargoList::MoveTo(Tother_inst *dest, uint max_move, MoveToAction mta, CargoPayment *payment, StationID st, OrderID cur_order, CargoID cid, bool *did_transfer)
{
assert(mta == MTA_FINAL_DELIVERY || dest != NULL);
assert(mta == MTA_UNLOAD || mta == MTA_CARGO_LOAD || payment != NULL);
+ assert(st != INVALID_STATION || (mta != MTA_CARGO_LOAD && payment == NULL));
+restart:;
Iterator it(this->packets.begin());
while (it != this->packets.end() && max_move > 0) {
CargoPacket *cp = *it;
- if (cp->source == data && mta == MTA_FINAL_DELIVERY) {
- /* Skip cargo that originated from this station. */
+ MoveToAction cp_mta = mta;
+ OrderID current_next_order = cp->NextHop();
+ StationID current_next_unload = cp->NextStation();
+
+ if (cp_mta == MTA_CARGO_LOAD) {
+ /* Invalid next hop but valid destination? Recompute next hop. */
+ if (current_next_order == INVALID_ORDER && cp->DestinationID() != INVALID_SOURCE) {
+ if (!this->UpdateCargoNextHop(cp, Station::Get(st), cid)) {
+ /* Failed to find destination, drop packet. */
+ it = this->packets.erase(it);
+ continue;
+ }
+ current_next_order = cp->NextHop();
+ current_next_unload = cp->NextStation();
+ }
+
+ /* Loading and not for the current vehicle? Skip. */
+ if (current_next_order != cur_order) {
+ ++it;
+ continue;
+ }
+ }
+
+ /* Has this packet a destination and are we unloading to a station (not autoreplace)? */
+ if (cp->DestinationID() != INVALID_SOURCE && cp_mta != MTA_CARGO_LOAD && payment != NULL) {
+ /* Not forced unload and not for unloading at this station? Skip the packet. */
+ if (cp_mta != MTA_UNLOAD && cp->NextStation() != INVALID_STATION && cp->NextStation() != st) {
+ ++it;
+ continue;
+ }
+
+ Station *station = Station::Get(st);
+
+ bool found;
+ StationID next_unload;
+ RouteLink *link = FindRouteLinkForCargo(station, cid, cp, &next_unload, cur_order, &found);
+ if (!found) {
+ /* Sorry, link to destination vanished, make cargo disappear. */
+ static_cast(this)->RemoveFromCache(cp);
+ delete cp;
+ it = this->packets.erase(it);
+ continue;
+ }
+
+ if (link != NULL) {
+ /* Not final destination. */
+ if (link->GetOriginOrderId() == cur_order && cp_mta != MTA_UNLOAD) {
+ /* Cargo should stay on the vehicle and not forced unloading? Skip. */
+ ++it;
+ continue;
+ }
+ /* Force transfer and update next hop. */
+ cp_mta = MTA_TRANSFER;
+ current_next_order = link->GetOriginOrderId();
+ current_next_unload = next_unload;
+ } else {
+ /* Final destination, deliver. */
+ cp_mta = MTA_FINAL_DELIVERY;
+ }
+ } else if (cp_mta == MTA_NO_ACTION || (cp->source == st && cp_mta == MTA_FINAL_DELIVERY)) {
+ /* Skip cargo that is not accepted or originated from this station. */
++it;
continue;
}
+ if (did_transfer != NULL && cp_mta == MTA_TRANSFER) *did_transfer = true;
+
if (cp->count <= max_move) {
/* Can move the complete packet */
max_move -= cp->count;
it = this->packets.erase(it);
static_cast(this)->RemoveFromCache(cp);
- switch (mta) {
+ cp->next_order = current_next_order;
+ cp->next_station = current_next_unload;
+ switch (cp_mta) {
case MTA_FINAL_DELIVERY:
payment->PayFinalDelivery(cp, cp->count);
delete cp;
continue; // of the loop
case MTA_CARGO_LOAD:
- cp->loaded_at_xy = data;
+ cp->loaded_at_xy = Station::Get(st)->xy;
break;
case MTA_TRANSFER:
cp->feeder_share += payment->PayTransfer(cp, cp->count);
break;
- case MTA_UNLOAD:
+ default:
break;
}
dest->Append(cp);
@@ -302,7 +410,7 @@
}
/* Can move only part of the packet */
- if (mta == MTA_FINAL_DELIVERY) {
+ if (cp_mta == MTA_FINAL_DELIVERY) {
/* Final delivery doesn't need package splitting. */
payment->PayFinalDelivery(cp, max_move);
@@ -323,12 +431,14 @@
if (cp_new == NULL) return false;
static_cast(this)->RemoveFromCache(cp_new); // this reflects the changes in cp.
+ cp_new->next_order = current_next_order;
+ cp_new->next_station = current_next_unload;
- if (mta == MTA_TRANSFER) {
+ if (cp_mta == MTA_TRANSFER) {
/* Add the feeder share before inserting in dest. */
cp_new->feeder_share += payment->PayTransfer(cp_new, max_move);
- } else if (mta == MTA_CARGO_LOAD) {
- cp_new->loaded_at_xy = data;
+ } else if (cp_mta == MTA_CARGO_LOAD) {
+ cp_new->loaded_at_xy = Station::Get(st)->xy;
}
dest->Append(cp_new);
@@ -337,6 +447,12 @@
max_move = 0;
}
+ if (max_move > 0 && mta == MTA_CARGO_LOAD && cur_order != INVALID_ORDER && Station::Get(st)->goods[cid].cargo.CountForNextHop(INVALID_ORDER) > 0) {
+ /* We loaded all packets for the next hop, now load all packets without destination. */
+ cur_order = INVALID_ORDER;
+ goto restart;
+ }
+
return it != packets.end();
}
@@ -396,6 +512,158 @@
this->Parent::InvalidateCache();
}
+/** Invalidate next unload station of all cargo packets. */
+void VehicleCargoList::InvalidateNextStation()
+{
+ for (VehicleCargoList::ConstIterator it = this->packets.begin(); it != this->packets.end(); ++it) {
+ (*it)->next_station = INVALID_STATION;
+ }
+}
+
+/**
+ * Update the local next-hop count cache.
+ * @param cp Packet the be removed.
+ * @param amount Cargo amount to be removed.
+ */
+void StationCargoList::RemoveFromCacheLocal(const CargoPacket *cp, uint amount)
+{
+ this->order_cache[cp->next_order] -= amount;
+ if (this->order_cache[cp->next_order] == 0) this->order_cache.erase(cp->next_order);
+}
+
+/**
+ * Update the cached values to reflect the removal of this packet.
+ * Decreases count and days_in_transit.
+ * @param cp Packet to be removed from cache.
+ */
+void StationCargoList::RemoveFromCache(const CargoPacket *cp)
+{
+ this->RemoveFromCacheLocal(cp, cp->count);
+ this->Parent::RemoveFromCache(cp);
+}
+
+/**
+ * Update the cache to reflect adding of this packet.
+ * Increases count and days_in_transit.
+ * @param cp New packet to be inserted.
+ */
+void StationCargoList::AddToCache(const CargoPacket *cp)
+{
+ this->order_cache[cp->next_order] += cp->count;
+ this->Parent::AddToCache(cp);
+}
+
+/** Invalidates the cached data and rebuild it. */
+void StationCargoList::InvalidateCache()
+{
+ this->order_cache.clear();
+ this->Parent::InvalidateCache();
+}
+
+/**
+ * Recompute the desired next hop of a cargo packet.
+ * @param cp Cargo packet to update.
+ * @param st Station of this list.
+ * @param cid Cargo type of this list.
+ * @return False if the packet was deleted, true otherwise.
+ */
+bool StationCargoList::UpdateCargoNextHop(CargoPacket *cp, Station *st, CargoID cid)
+{
+ StationID next_unload;
+ RouteLink *l = FindRouteLinkForCargo(st, cid, cp, &next_unload);
+
+ if (l == NULL) {
+ /* No link to destination, drop packet. */
+ this->RemoveFromCache(cp);
+ delete cp;
+ return false;
+ }
+
+ /* Update next hop info. */
+ this->RemoveFromCache(cp);
+ cp->next_station = next_unload;
+ cp->next_order = l->GetOriginOrderId();
+ this->AddToCache(cp);
+
+ return true;
+}
+
+/**
+ * Recompute the desired next hop of all cargo packets.
+ * @param st Station of this list.
+ * @param cid Cargo type of this list.
+ */
+void StationCargoList::UpdateCargoNextHop(Station *st, CargoID cid)
+{
+ uint count = 0;
+ StationCargoList::Iterator iter;
+ for (iter = this->packets.begin(); count < this->next_start + _settings_game.economy.cargodest.route_recalc_chunk && iter != this->packets.end(); count++) {
+ if (count < this->next_start) continue;
+ if ((*iter)->DestinationID() != INVALID_SOURCE) {
+ if (this->UpdateCargoNextHop(*iter, st, cid)) {
+ ++iter;
+ } else {
+ iter = this->packets.erase(iter);
+ }
+ } else {
+ ++iter;
+ }
+ }
+
+ /* Update start counter for next loop. */
+ this->next_start = count;
+ if (this->next_start >= this->packets.size()) this->next_start = 0;
+}
+
+/**
+ * Invalidates the next hop info of all cargo packets with a given next order or unload station.
+ * @param order Next order to invalidate.
+ * @param st_unload Unload station to invalidate.
+ */
+/* static */ void StationCargoList::InvalidateAllTo(OrderID order, StationID st_unload)
+{
+ Station *st;
+ FOR_ALL_STATIONS(st) {
+ for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
+ for (StationCargoList::Iterator it = st->goods[cid].cargo.packets.begin(); it != st->goods[cid].cargo.packets.end(); ++it) {
+ CargoPacket *cp = *it;
+ if (cp->next_order == order || cp->next_station == st_unload) {
+ /* Invalidate both order and unload station as both likely
+ * don't make sense anymore. */
+ st->goods[cid].cargo.RemoveFromCache(cp);
+ cp->next_order = INVALID_ORDER;
+ cp->next_station = INVALID_STATION;
+ st->goods[cid].cargo.AddToCache(cp);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Invalidates the next hop info of all cargo packets for a given destination.
+ * @param order Next order to invalidate.
+ */
+/* static */ void StationCargoList::InvalidateAllTo(SourceType type, SourceID dest)
+{
+ Station *st;
+ FOR_ALL_STATIONS(st) {
+ for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
+ for (StationCargoList::Iterator it = st->goods[cid].cargo.packets.begin(); it != st->goods[cid].cargo.packets.end(); ++it) {
+ CargoPacket *cp = *it;
+ if (cp->dest_id == dest && cp->dest_type == type) {
+ /* Invalidate both next order and unload station as we
+ * want the packets to be not routed anymore. */
+ st->goods[cid].cargo.RemoveFromCache(cp);
+ cp->next_order = INVALID_ORDER;
+ cp->next_station = INVALID_STATION;
+ st->goods[cid].cargo.AddToCache(cp);
+ }
+ }
+ }
+ }
+}
+
/*
* We have to instantiate everything we want to be usable.
*/
@@ -403,8 +671,8 @@
template class CargoList;
/** Autoreplace Vehicle -> Vehicle 'transfer'. */
-template bool CargoList::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data);
+template bool CargoList::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, StationID st, OrderID cur_order, CargoID cid, bool *did_transfer);
/** Cargo unloading at a station. */
-template bool CargoList::MoveTo(StationCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data);
+template bool CargoList::MoveTo(StationCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, StationID st, OrderID cur_order, CargoID cid, bool *did_transfer);
/** Cargo loading at a station. */
-template bool CargoList::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data);
+template bool CargoList::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, StationID st, OrderID cur_order, CargoID cid, bool *did_transfer);
diff -r f0e1386dbf71 src/cargopacket.h
--- a/src/cargopacket.h Mon Sep 19 05:37:11 2011 +0000
+++ b/src/cargopacket.h Wed Sep 21 21:58:36 2011 -0400
@@ -17,7 +17,10 @@
#include "station_type.h"
#include "cargo_type.h"
#include "vehicle_type.h"
+#include "order_type.h"
+#include "cargotype.h"
#include
+#include