1435
* Performs the vehicle payment _and_ marks the vehicle to be unloaded.
1451
* Makes us a new cargo payment helper.
1452
* @param front The front of the train
1453
* @param destinations List to add the destinations of 'our' cargo to
1455
CargoPayment::CargoPayment(Vehicle *front) :
1457
current_station(front->last_station_visited)
1461
CargoPayment::~CargoPayment()
1463
if (this->CleaningPool()) return;
1465
this->front->cargo_payment = NULL;
1467
if (this->visual_profit == 0) {
1472
CompanyID old_company = _current_company;
1473
_current_company = this->front->owner;
1475
SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit));
1476
this->front->profit_this_year += this->visual_profit << 8;
1478
if (this->route_profit != 0) {
1479
if (IsLocalCompany() && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
1480
SndPlayVehicleFx(SND_14_CASHTILL, this->front);
1483
ShowCostOrIncomeAnimation(this->front->x_pos, this->front->y_pos, this->front->z_pos, -this->visual_profit);
1485
ShowFeederIncomeAnimation(this->front->x_pos, this->front->y_pos, this->front->z_pos, this->visual_profit);
1488
_current_company = old_company;
1494
* Handle payment for final delivery of the given cargo packet.
1495
* @param cp The cargo packet to pay for.
1496
* @param count The number of packets to pay for.
1498
void CargoPayment::PayFinalDelivery(CargoPacket *cp, uint count)
1500
if (this->owner == NULL) {
1501
this->owner = GetCompany(this->front->owner);
1504
/* Handle end of route payment */
1505
Money profit = DeliverGoods(count, this->ct, cp->source, this->current_station, cp->source_xy, cp->days_in_transit, this->owner);
1506
this->route_profit += profit;
1508
/* The vehicle's profit is whatever route profit there is minus feeder shares. */
1509
this->visual_profit += profit - cp->feeder_share;
1513
* Handle payment for transfer of the given cargo packet.
1514
* @param cp The cargo packet to pay for.
1515
* @param count The number of packets to pay for.
1517
void CargoPayment::PayTransfer(CargoPacket *cp, uint count)
1519
Money profit = GetTransportedGoodsIncome(
1521
/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
1522
DistanceManhattan(cp->loaded_at_xy, GetStation(this->current_station)->xy),
1523
cp->days_in_transit,
1526
this->visual_profit += profit; // accumulate transfer profits for whole vehicle
1527
cp->feeder_share += profit; // account for the (virtual) profit already made for the cargo packet
1531
* Prepare the vehicle to be unloaded.
1436
1532
* @param front_v the vehicle to be unloaded
1438
void VehiclePayment(Vehicle *front_v)
1534
void PrepareUnload(Vehicle *front_v)
1442
Money vehicle_profit = 0; // Money paid to the train
1443
Money route_profit = 0; // The grand total amount for the route. A-D of transfer chain A-B-C-D
1444
Money virtual_profit = 0; // The virtual profit for entire vehicle chain
1446
StationID last_visited = front_v->last_station_visited;
1447
Station *st = GetStation(last_visited);
1449
/* The owner of the train wants to be paid */
1450
CompanyID old_company = _current_company;
1451
_current_company = front_v->owner;
1453
1536
/* At this moment loading cannot be finished */
1454
1537
ClrBit(front_v->vehicle_flags, VF_LOADING_FINISHED);
1456
1539
/* Start unloading in at the first possible moment */
1457
1540
front_v->load_unload_time_rem = 1;
1459
/* Collect delivered industries */
1460
static SmallIndustryList industry_set;
1461
industry_set.Clear();
1463
for (Vehicle *v = front_v; v != NULL; v = v->Next()) {
1464
/* No cargo to unload */
1465
if (v->cargo_cap == 0 || v->cargo.Empty() || front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) continue;
1467
/* All cargo has already been paid for, no need to pay again */
1468
if (!v->cargo.UnpaidCargo()) {
1469
SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
1473
GoodsEntry *ge = &st->goods[v->cargo_type];
1474
const CargoList::List *cargos = v->cargo.Packets();
1476
for (CargoList::List::const_iterator it = cargos->begin(); it != cargos->end(); it++) {
1477
CargoPacket *cp = *it;
1478
if (!cp->paid_for &&
1479
cp->source != last_visited &&
1480
HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) &&
1481
(front_v->current_order.GetUnloadType() & OUFB_TRANSFER) == 0) {
1482
/* Deliver goods to the station */
1483
st->time_since_unload = 0;
1485
/* handle end of route payment */
1486
Money profit = DeliverGoods(cp->count, v->cargo_type, cp->source, last_visited, cp->source_xy, cp->days_in_transit, &industry_set);
1487
cp->paid_for = true;
1488
route_profit += profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D
1489
vehicle_profit += profit - cp->feeder_share; // whole vehicle is not payed for transfers picked up earlier
1493
SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
1494
} else if (front_v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) {
1495
if (!cp->paid_for && (front_v->current_order.GetUnloadType() & OUFB_TRANSFER) != 0) {
1496
Money profit = GetTransportedGoodsIncome(
1498
/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
1499
DistanceManhattan(cp->loaded_at_xy, GetStation(last_visited)->xy),
1500
cp->days_in_transit,
1503
front_v->profit_this_year += profit << 8;
1504
virtual_profit += profit; // accumulate transfer profits for whole vehicle
1505
cp->feeder_share += profit; // account for the (virtual) profit already made for the cargo packet
1506
cp->paid_for = true; // record that the cargo has been paid for to eliminate double counting
1542
if ((front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
1543
for (Vehicle *v = front_v; v != NULL; v = v->Next()) {
1544
if (v->cargo_cap > 0 && !v->cargo.Empty()) {
1510
1545
SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
1513
v->cargo.InvalidateCache();
1516
/* Call the production machinery of industries only once for every vehicle chain */
1517
const Industry * const *isend = industry_set.End();
1518
for (Industry **iid = industry_set.Begin(); iid != isend; iid++) {
1519
TriggerIndustryProduction(*iid);
1522
if (virtual_profit > 0) {
1523
ShowFeederIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, virtual_profit);
1526
if (route_profit != 0) {
1527
front_v->profit_this_year += vehicle_profit << 8;
1528
SubtractMoneyFromCompany(CommandCost(front_v->GetExpenseType(true), -route_profit));
1530
if (IsLocalCompany() && !PlayVehicleSound(front_v, VSE_LOAD_UNLOAD)) {
1531
SndPlayVehicleFx(SND_14_CASHTILL, front_v);
1534
ShowCostOrIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, -vehicle_profit);
1537
_current_company = old_company;
1550
assert(front_v->cargo_payment == NULL);
1551
front_v->cargo_payment = new CargoPayment(front_v);