mirror of https://github.com/OpenTTD/OpenTTD
(svn r9761) -Codechange: refactor cargo payment out of LoadUnloadVehicle.
parent
a4e045a3fb
commit
f25a168c98
194
src/economy.cpp
194
src/economy.cpp
|
@ -1378,8 +1378,17 @@ static bool LoadWait(const Vehicle* v, const Vehicle* u)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
/**
|
||||||
|
* Performs the vehicle payment _and_ marks the vehicle to be unloaded.
|
||||||
|
* @param front_v the vehicle to be unloaded
|
||||||
|
* @return what windows need to be updated;
|
||||||
|
* bit 0 set: only vehicle details,
|
||||||
|
* bit 1 set: vehicle details and station details
|
||||||
|
*/
|
||||||
|
static int VehiclePayment(Vehicle *front_v)
|
||||||
{
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
int profit = 0;
|
int profit = 0;
|
||||||
int total_veh_profit = 0; // accumulates the profit across the vehicle chain (used by trains)
|
int total_veh_profit = 0; // accumulates the profit across the vehicle chain (used by trains)
|
||||||
int32 route_profit = 0; // the grand total amount for the route. A-D of transfer chain A-B-C-D
|
int32 route_profit = 0; // the grand total amount for the route. A-D of transfer chain A-B-C-D
|
||||||
|
@ -1387,83 +1396,36 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
||||||
int virtual_profit_total = 0; // virtual profit for entire vehicle chain
|
int virtual_profit_total = 0; // virtual profit for entire vehicle chain
|
||||||
int total_cargo_feeder_share = 0; // the feeder cash amount for the goods being loaded/unloaded in this load step
|
int total_cargo_feeder_share = 0; // the feeder cash amount for the goods being loaded/unloaded in this load step
|
||||||
|
|
||||||
int unloading_time = 20;
|
int all_vehicles_cargo_feeder_share = front_v->cargo_feeder_share; // used to hold transfer value of complete vehicle chain - used by trains
|
||||||
Vehicle *u = v;
|
|
||||||
int result = 0;
|
|
||||||
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);
|
StationID last_visited = front_v->last_station_visited;
|
||||||
|
|
||||||
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->vehicle_flags, VF_LOADING_FINISHED);
|
|
||||||
|
|
||||||
old_player = _current_player;
|
|
||||||
_current_player = v->owner;
|
|
||||||
|
|
||||||
StationID last_visited = v->last_station_visited;
|
|
||||||
Station *st = GetStation(last_visited);
|
Station *st = GetStation(last_visited);
|
||||||
|
|
||||||
int all_vehicles_cargo_feeder_share = v->cargo_feeder_share; // used to hold transfer value of complete vehicle chain - used by trains
|
for (Vehicle *v = front_v; v != NULL; v = v->next) {
|
||||||
|
|
||||||
for (; v != NULL; v = v->next) {
|
|
||||||
GoodsEntry* ge;
|
|
||||||
load_amount = EngInfo(v->engine_type)->load_amount;
|
|
||||||
if (_patches.gradual_loading && HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_LOAD_AMOUNT)) {
|
|
||||||
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 (v->cargo_cap == 0) continue;
|
||||||
|
|
||||||
/* If the vehicle has just arrived, set it to unload. */
|
SETBIT(v->vehicle_flags, VF_CARGO_UNLOADING);
|
||||||
if (just_arrived) SETBIT(v->vehicle_flags, VF_CARGO_UNLOADING);
|
if (v->cargo_count == v->cargo_paid_for) continue;
|
||||||
|
|
||||||
ge = &st->goods[v->cargo_type];
|
GoodsEntry *ge = &st->goods[v->cargo_type];
|
||||||
count = GB(ge->waiting_acceptance, 0, 12);
|
|
||||||
|
|
||||||
/* unload? */
|
if (v->cargo_source != last_visited &&
|
||||||
if (v->cargo_count != 0 && HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING)) {
|
HASBIT(ge->waiting_acceptance, 15) &&
|
||||||
uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count;
|
(front_v->current_order.flags & OF_TRANSFER) == 0) {
|
||||||
|
/* Deliver goods to the station */
|
||||||
CLRBIT(u->vehicle_flags, VF_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;
|
st->time_since_unload = 0;
|
||||||
|
|
||||||
unloading_time += v->cargo_count; // TTDBUG: bug in original TTD
|
|
||||||
|
|
||||||
/* handle end of route payment */
|
/* handle end of route payment */
|
||||||
if (just_arrived && v->cargo_paid_for < v->cargo_count) {
|
|
||||||
profit += DeliverGoods(v->cargo_count - v->cargo_paid_for, v->cargo_type, v->cargo_source, last_visited, v->cargo_source_xy, v->cargo_days);
|
profit += DeliverGoods(v->cargo_count - v->cargo_paid_for, v->cargo_type, v->cargo_source, last_visited, v->cargo_source_xy, v->cargo_days);
|
||||||
v->cargo_paid_for = v->cargo_count;
|
v->cargo_paid_for = v->cargo_count;
|
||||||
route_profit = profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D
|
route_profit = profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D
|
||||||
total_veh_profit = profit - all_vehicles_cargo_feeder_share; // whole vehicle is not payed for transfers picked up earlier
|
total_veh_profit = profit - all_vehicles_cargo_feeder_share; // whole vehicle is not payed for transfers picked up earlier
|
||||||
total_cargo_feeder_share = -all_vehicles_cargo_feeder_share; // total of transfer fees in vehicle chain needs to be zero at end of unload
|
total_cargo_feeder_share = -all_vehicles_cargo_feeder_share; // total of transfer fees in vehicle chain needs to be zero at end of unload
|
||||||
|
|
||||||
v->cargo_feeder_share = 0; // clear transfer cost per vehicle
|
v->cargo_feeder_share = 0; // clear transfer cost per vehicle
|
||||||
}
|
|
||||||
result |= 1;
|
result |= 1;
|
||||||
v->cargo_count -= amount_unloaded;
|
} else if (front_v->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) {
|
||||||
v->cargo_paid_for -= min(amount_unloaded, v->cargo_paid_for);
|
if ((front_v->current_order.flags & OF_TRANSFER) != 0) {
|
||||||
if (_patches.gradual_loading) continue;
|
|
||||||
|
|
||||||
} else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) {
|
|
||||||
|
|
||||||
/* unload goods and let it wait at the station */
|
|
||||||
st->time_since_unload = 0;
|
|
||||||
|
|
||||||
/* handle transfer */
|
|
||||||
if (just_arrived && (u->current_order.flags & OF_TRANSFER) && v->cargo_paid_for < v->cargo_count) {
|
|
||||||
virtual_profit = GetTransportedGoodsIncome(
|
virtual_profit = GetTransportedGoodsIncome(
|
||||||
v->cargo_count - v->cargo_paid_for,
|
v->cargo_count - v->cargo_paid_for,
|
||||||
/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
|
/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
|
||||||
|
@ -1481,6 +1443,95 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
||||||
virtual_profit_total += virtual_profit; // accumulate transfer profits for whole vehicle
|
virtual_profit_total += virtual_profit; // accumulate transfer profits for whole vehicle
|
||||||
v->cargo_paid_for = v->cargo_count; // record how much of the cargo has been paid for to eliminate double counting
|
v->cargo_paid_for = v->cargo_count; // record how much of the cargo has been paid for to eliminate double counting
|
||||||
}
|
}
|
||||||
|
result |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure a negative total is only applied to the vehicle if there is value to reduce. */
|
||||||
|
front_v->cargo_feeder_share = max(front_v->cargo_feeder_share + total_cargo_feeder_share, 0);
|
||||||
|
|
||||||
|
if (virtual_profit_total > 0) {
|
||||||
|
ShowFeederIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, virtual_profit_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route_profit != 0) {
|
||||||
|
front_v->profit_this_year += total_veh_profit;
|
||||||
|
SubtractMoneyFromPlayer(-route_profit);
|
||||||
|
|
||||||
|
if (IsLocalPlayer() && !PlayVehicleSound(front_v, VSE_LOAD_UNLOAD)) {
|
||||||
|
SndPlayVehicleFx(SND_14_CASHTILL, front_v);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowCostOrIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, -total_veh_profit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
||||||
|
{
|
||||||
|
int unloading_time = 20;
|
||||||
|
Vehicle *u = v;
|
||||||
|
int result = 0;
|
||||||
|
int t;
|
||||||
|
uint count, cap;
|
||||||
|
PlayerID old_player;
|
||||||
|
bool completely_empty = true;
|
||||||
|
byte load_amount;
|
||||||
|
bool anything_loaded = false;
|
||||||
|
int total_cargo_feeder_share = 0; // the feeder cash amount for the goods being loaded/unloaded in this load step
|
||||||
|
|
||||||
|
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->vehicle_flags, VF_LOADING_FINISHED);
|
||||||
|
|
||||||
|
old_player = _current_player;
|
||||||
|
_current_player = v->owner;
|
||||||
|
|
||||||
|
StationID last_visited = v->last_station_visited;
|
||||||
|
Station *st = GetStation(last_visited);
|
||||||
|
|
||||||
|
if (just_arrived) result |= VehiclePayment(v);
|
||||||
|
|
||||||
|
for (; v != NULL; v = v->next) {
|
||||||
|
GoodsEntry* ge;
|
||||||
|
load_amount = EngInfo(v->engine_type)->load_amount;
|
||||||
|
if (_patches.gradual_loading && HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_LOAD_AMOUNT)) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
ge = &st->goods[v->cargo_type];
|
||||||
|
count = GB(ge->waiting_acceptance, 0, 12);
|
||||||
|
|
||||||
|
/* unload? */
|
||||||
|
if (v->cargo_count != 0 && HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING)) {
|
||||||
|
uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count;
|
||||||
|
|
||||||
|
CLRBIT(u->vehicle_flags, VF_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
|
||||||
|
|
||||||
|
result |= 1;
|
||||||
|
v->cargo_count -= amount_unloaded;
|
||||||
|
v->cargo_paid_for -= min(amount_unloaded, v->cargo_paid_for);
|
||||||
|
if (_patches.gradual_loading) continue;
|
||||||
|
|
||||||
|
} else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) {
|
||||||
|
/* unload goods and let it wait at the station */
|
||||||
|
st->time_since_unload = 0;
|
||||||
|
|
||||||
unloading_time += v->cargo_count;
|
unloading_time += v->cargo_count;
|
||||||
t = GB(ge->waiting_acceptance, 0, 12);
|
t = GB(ge->waiting_acceptance, 0, 12);
|
||||||
|
@ -1505,10 +1556,6 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
||||||
* else deduct amount actually unloaded from unload_pending */
|
* else deduct amount actually unloaded from unload_pending */
|
||||||
SB(ge->unload_pending, 0, 12, max(GB(ge->unload_pending, 0, 12) - amount_unloaded, 0U));
|
SB(ge->unload_pending, 0, 12, max(GB(ge->unload_pending, 0, 12) - amount_unloaded, 0U));
|
||||||
|
|
||||||
if (u->current_order.flags & OF_TRANSFER) {
|
|
||||||
ge->feeder_profit += virtual_profit;
|
|
||||||
u->profit_this_year += virtual_profit;
|
|
||||||
}
|
|
||||||
result |= 2;
|
result |= 2;
|
||||||
v->cargo_count -= amount_unloaded;
|
v->cargo_count -= amount_unloaded;
|
||||||
v->cargo_paid_for -= min(amount_unloaded, v->cargo_paid_for);
|
v->cargo_paid_for -= min(amount_unloaded, v->cargo_paid_for);
|
||||||
|
@ -1593,8 +1640,6 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
||||||
|
|
||||||
v = u;
|
v = u;
|
||||||
|
|
||||||
/* Ensure a negative total is only applied to the vehicle if there is value to reduce. */
|
|
||||||
if (!((v->cargo_feeder_share == 0) && (total_cargo_feeder_share < 0)))
|
|
||||||
v->cargo_feeder_share += total_cargo_feeder_share;
|
v->cargo_feeder_share += total_cargo_feeder_share;
|
||||||
|
|
||||||
if (_patches.gradual_loading) {
|
if (_patches.gradual_loading) {
|
||||||
|
@ -1612,10 +1657,6 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virtual_profit_total > 0) {
|
|
||||||
ShowFeederIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, virtual_profit_total);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v->type == VEH_TRAIN) {
|
if (v->type == VEH_TRAIN) {
|
||||||
/* Each platform tile is worth 2 rail vehicles. */
|
/* Each platform tile is worth 2 rail vehicles. */
|
||||||
int overhang = v->u.rail.cached_total_length - st->GetPlatformLength(v->tile) * TILE_SIZE;
|
int overhang = v->u.rail.cached_total_length - st->GetPlatformLength(v->tile) * TILE_SIZE;
|
||||||
|
@ -1636,17 +1677,6 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
|
||||||
st->MarkTilesDirty();
|
st->MarkTilesDirty();
|
||||||
|
|
||||||
if (result & 2) InvalidateWindow(WC_STATION_VIEW, last_visited);
|
if (result & 2) InvalidateWindow(WC_STATION_VIEW, last_visited);
|
||||||
|
|
||||||
if (route_profit != 0) {
|
|
||||||
v->profit_this_year += total_veh_profit;
|
|
||||||
SubtractMoneyFromPlayer(-route_profit);
|
|
||||||
|
|
||||||
if (IsLocalPlayer() && !PlayVehicleSound(v, VSE_LOAD_UNLOAD)) {
|
|
||||||
SndPlayVehicleFx(SND_14_CASHTILL, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, -total_veh_profit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_current_player = old_player;
|
_current_player = old_player;
|
||||||
|
|
Loading…
Reference in New Issue