|
@@ -1314,16 +1314,22 @@ int LoadUnloadVehicle(Vehicle *v, bool j
|
|
|
Station *st;
|
|
|
int t;
|
|
|
uint count, cap;
|
|
|
PlayerID old_player;
|
|
|
bool completely_empty = true;
|
|
|
byte load_amount;
|
|
|
bool anything_loaded = false;
|
|
|
|
|
|
assert(v->current_order.type == OT_LOADING);
|
|
|
|
|
|
v->cur_speed = 0;
|
|
|
|
|
|
/* Loading can only have finished when all the cargo has been unloaded, and
|
|
|
* there is nothing left to load. It's easier to clear this if the
|
|
|
* conditions haven't been met than attempting to check them all before
|
|
|
* enabling though. */
|
|
|
SETBIT(v->load_status, LS_LOADING_FINISHED);
|
|
|
|
|
|
old_player = _current_player;
|
|
|
_current_player = v->owner;
|
|
|
|
|
|
last_visited = v->last_station_visited;
|
|
@@ -1336,46 +1342,48 @@ int LoadUnloadVehicle(Vehicle *v, bool j
|
|
|
uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
|
|
|
if (cb_load_amount != CALLBACK_FAILED) load_amount = cb_load_amount & 0xFF;
|
|
|
}
|
|
|
|
|
|
if (v->cargo_cap == 0) continue;
|
|
|
|
|
|
/* If the train has just arrived, set it to unload. */
|
|
|
/* If the vehicle has just arrived, set it to unload. */
|
|
|
if (just_arrived) SETBIT(v->load_status, LS_CARGO_UNLOADING);
|
|
|
|
|
|
ge = &st->goods[v->cargo_type];
|
|
|
count = GB(ge->waiting_acceptance, 0, 12);
|
|
|
|
|
|
/* unload? */
|
|
|
if (v->cargo_count != 0 && HASBIT(v->load_status, LS_CARGO_UNLOADING)) {
|
|
|
uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count;
|
|
|
|
|
|
CLRBIT(u->load_status, LS_LOADING_FINISHED);
|
|
|
|
|
|
if (v->cargo_source != last_visited && ge->waiting_acceptance & 0x8000 && !(u->current_order.flags & OF_TRANSFER)) {
|
|
|
// deliver goods to the station
|
|
|
st->time_since_unload = 0;
|
|
|
|
|
|
unloading_time += v->cargo_count; /* TTDBUG: bug in original TTD */
|
|
|
if (just_arrived) profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
|
|
|
if (just_arrived && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) {
|
|
|
profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
|
|
|
SETBIT(v->load_status, LS_CARGO_PAID_FOR);
|
|
|
}
|
|
|
result |= 1;
|
|
|
if (_patches.gradual_loading) {
|
|
|
v->cargo_count -= min(load_amount, v->cargo_count);
|
|
|
if (v->cargo_count != 0 || (count != 0 && !(u->current_order.flags & OF_UNLOAD))) CLRBIT(u->load_status, LS_LOADING_FINISHED);
|
|
|
continue;
|
|
|
} else {
|
|
|
v->cargo_count = 0;
|
|
|
}
|
|
|
v->cargo_count -= amount_unloaded;
|
|
|
if (_patches.gradual_loading) continue;
|
|
|
} else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) {
|
|
|
uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count;
|
|
|
/* unload goods and let it wait at the station */
|
|
|
st->time_since_unload = 0;
|
|
|
if (just_arrived && (u->current_order.flags & OF_TRANSFER)) {
|
|
|
if (just_arrived && (u->current_order.flags & OF_TRANSFER) && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) {
|
|
|
v_profit = GetTransportedGoodsIncome(
|
|
|
v->cargo_count,
|
|
|
DistanceManhattan(GetStation(v->cargo_source)->xy, GetStation(last_visited)->xy),
|
|
|
v->cargo_days,
|
|
|
v->cargo_type) * 3 / 2;
|
|
|
|
|
|
v_profit_total += v_profit;
|
|
|
SETBIT(v->load_status, LS_CARGO_PAID_FOR);
|
|
|
}
|
|
|
|
|
|
unloading_time += v->cargo_count;
|
|
|
t = GB(ge->waiting_acceptance, 0, 12);
|
|
|
if (t == 0) {
|
|
|
// No goods waiting at station
|
|
@@ -1394,28 +1402,26 @@ int LoadUnloadVehicle(Vehicle *v, bool j
|
|
|
if (u->current_order.flags & OF_TRANSFER) {
|
|
|
ge->feeder_profit += v_profit;
|
|
|
u->profit_this_year += v_profit;
|
|
|
}
|
|
|
result |= 2;
|
|
|
v->cargo_count -= amount_unloaded;
|
|
|
if (_patches.gradual_loading) {
|
|
|
if (v->cargo_count != 0 || (count != 0 && !(u->current_order.flags & OF_UNLOAD))) CLRBIT(u->load_status, LS_LOADING_FINISHED);
|
|
|
continue;
|
|
|
}
|
|
|
if (_patches.gradual_loading) continue;
|
|
|
}
|
|
|
|
|
|
if (v->cargo_count != 0) completely_empty = false;
|
|
|
}
|
|
|
|
|
|
/* The vehicle must have been unloaded because it is either empty, or
|
|
|
* the UNLOADING bit is already clear in v->load_status. */
|
|
|
CLRBIT(v->load_status, LS_CARGO_UNLOADING);
|
|
|
CLRBIT(v->load_status, LS_CARGO_PAID_FOR);
|
|
|
|
|
|
/* don't pick up goods that we unloaded */
|
|
|
if (u->current_order.flags & OF_UNLOAD) continue;
|
|
|
|
|
|
/* The vehicle must have been unloaded because it is either empty, or
|
|
|
* v->cargo_unloading is already false. */
|
|
|
CLRBIT(v->load_status, LS_CARGO_UNLOADING);
|
|
|
|
|
|
/* update stats */
|
|
|
ge->days_since_pickup = 0;
|
|
|
switch (u->type) {
|
|
|
case VEH_Train: t = u->u.rail.cached_max_speed; break;
|
|
|
case VEH_Road: t = u->max_speed / 2; break;
|
|
|
default: t = u->max_speed; break;
|
|
@@ -1444,12 +1450,13 @@ int LoadUnloadVehicle(Vehicle *v, bool j
|
|
|
* loading them. Since this will cause
|
|
|
* VEHICLE_TRIGGER_EMPTY to be called at the time when
|
|
|
* the whole vehicle chain is really totally empty, the
|
|
|
* @completely_empty assignment can then be safely
|
|
|
* removed; that's how TTDPatch behaves too. --pasky */
|
|
|
completely_empty = false;
|
|
|
anything_loaded = true;
|
|
|
|
|
|
if (cap > count) cap = count;
|
|
|
if (_patches.gradual_loading) cap = min(cap, load_amount);
|
|
|
if (cap < count) CLRBIT(u->load_status, LS_LOADING_FINISHED);
|
|
|
cargoshare = cap * 10000 / ge->waiting_acceptance;
|
|
|
feeder_profit_share = ge->feeder_profit * cargoshare / 10000;
|
|
@@ -1473,13 +1480,19 @@ int LoadUnloadVehicle(Vehicle *v, bool j
|
|
|
if (_patches.gradual_loading) {
|
|
|
/* The time it takes to load one 'slice' of cargo or passengers depends
|
|
|
* on the vehicle type - the values here are those found in TTDPatch */
|
|
|
uint gradual_loading_wait_time[] = { 40, 20, 10, 20 };
|
|
|
|
|
|
unloading_time = gradual_loading_wait_time[v->type - VEH_Train];
|
|
|
if (HASBIT(v->load_status, LS_LOADING_FINISHED)) unloading_time += 20;
|
|
|
if (HASBIT(v->load_status, LS_LOADING_FINISHED)) {
|
|
|
if (anything_loaded) {
|
|
|
unloading_time += 20;
|
|
|
} else {
|
|
|
unloading_time = 20;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (v_profit_total > 0) {
|
|
|
ShowFeederIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, v_profit_total);
|
|
|
}
|
|
|
|