Changeset - r12258:ecb1674e7807
[Not reviewed]
master
0 4 1
rubidium - 15 years ago 2009-06-28 15:12:59
rubidium@openttd.org
(svn r16683) -Codechange: move the cargo payment handling to a seperate class. Based on ideas of fonso/fonsinchen.
5 files changed with 129 insertions and 38 deletions:
0 comments (0 inline, 0 general)
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -960,6 +960,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\economy_base.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\economy_func.h"
 
				>
 
			</File>
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -957,6 +957,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\economy_base.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\economy_func.h"
 
				>
 
			</File>
source.list
Show inline comments
 
@@ -168,6 +168,7 @@ direction_func.h
 
direction_type.h
 
music/dmusic.h
 
driver.h
 
economy_base.h
 
economy_func.h
 
economy_type.h
 
effectvehicle_base.h
src/economy.cpp
Show inline comments
 
@@ -35,6 +35,7 @@
 
#include "signs_base.h"
 
#include "subsidy_func.h"
 
#include "station_base.h"
 
#include "economy_base.h"
 

	
 
#include "table/strings.h"
 
#include "table/sprites.h"
 
@@ -1141,6 +1142,83 @@ static void TriggerIndustryProduction(In
 
}
 

	
 
/**
 
 * Makes us a new cargo payment helper.
 
 * @param front The front of the train
 
 * @param destinations List to add the destinations of 'our' cargo to
 
 */
 
CargoPayment::CargoPayment(Vehicle *front) :
 
	front(front),
 
	route_profit(0),
 
	visual_profit(0),
 
	owner(NULL),
 
	current_station(front->last_station_visited)
 
{
 
}
 

	
 
CargoPayment::~CargoPayment()
 
{
 
	if (this->visual_profit == 0) return;
 

	
 
	CompanyID old_company = _current_company;
 
	_current_company = this->front->owner;
 

	
 
	SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit));
 

	
 
	if (this->route_profit != 0) {
 
		if (IsLocalCompany() && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
 
			SndPlayVehicleFx(SND_14_CASHTILL, this->front);
 
		}
 

	
 
		ShowCostOrIncomeAnimation(this->front->x_pos, this->front->y_pos, this->front->z_pos, -this->visual_profit);
 
	} else {
 
		ShowFeederIncomeAnimation(this->front->x_pos, this->front->y_pos, this->front->z_pos, this->visual_profit);
 
	}
 

	
 
	_current_company = old_company;
 
}
 

	
 
/**
 
 * Handle payment for final delivery of the given cargo packet.
 
 * @param cp The cargo packet to pay for.
 
 * @param count The number of packets to pay for.
 
 */
 
void CargoPayment::PayFinalDelivery(CargoPacket *cp, uint count)
 
{
 
	if (this->owner == NULL) {
 
		this->owner = Company::Get(this->front->owner);
 
	}
 

	
 
	/* Handle end of route payment */
 
	Money profit = DeliverGoods(count, this->ct, cp->source, this->current_station, cp->source_xy, cp->days_in_transit, this->owner);
 
	this->route_profit += profit;
 

	
 
	/* The vehicle's profit is whatever route profit there is minus feeder shares. */
 
	this->visual_profit += profit - cp->feeder_share;
 

	
 
	cp->paid_for = true;
 
}
 

	
 
/**
 
 * Handle payment for transfer of the given cargo packet.
 
 * @param cp The cargo packet to pay for.
 
 * @param count The number of packets to pay for.
 
 */
 
void CargoPayment::PayTransfer(CargoPacket *cp, uint count)
 
{
 
	Money profit = GetTransportedGoodsIncome(
 
		count,
 
		/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
 
		DistanceManhattan(cp->loaded_at_xy, Station::Get(this->current_station)->xy),
 
		cp->days_in_transit,
 
		this->ct);
 

	
 
	this->visual_profit += profit; // accumulate transfer profits for whole vehicle
 
	cp->feeder_share    += profit; // account for the (virtual) profit already made for the cargo packet
 

	
 
	cp->paid_for = true;
 
}
 

	
 
/**
 
 * Performs the vehicle payment _and_ marks the vehicle to be unloaded.
 
 * @param front_v the vehicle to be unloaded
 
 */
 
@@ -1154,11 +1232,6 @@ void VehiclePayment(Vehicle *front_v)
 

	
 
	StationID last_visited = front_v->last_station_visited;
 
	Station *st = Station::Get(last_visited);
 
	Company *company = Company::Get(front_v->owner);
 

	
 
	/* The owner of the train wants to be paid */
 
	CompanyID old_company = _current_company;
 
	_current_company = front_v->owner;
 

	
 
	/* At this moment loading cannot be finished */
 
	ClrBit(front_v->vehicle_flags, VF_LOADING_FINISHED);
 
@@ -1166,6 +1239,8 @@ void VehiclePayment(Vehicle *front_v)
 
	/* Start unloading in at the first possible moment */
 
	front_v->load_unload_time_rem = 1;
 

	
 
	CargoPayment payment(front_v);
 

	
 
	for (Vehicle *v = front_v; v != NULL; v = v->Next()) {
 
		/* No cargo to unload */
 
		if (v->cargo_cap == 0 || v->cargo.Empty() || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD)) continue;
 
@@ -1179,6 +1254,8 @@ void VehiclePayment(Vehicle *front_v)
 
		GoodsEntry *ge = &st->goods[v->cargo_type];
 
		const CargoList::List *cargos = v->cargo.Packets();
 

	
 
		payment.SetCargo(v->cargo_type);
 

	
 
		for (CargoList::List::const_iterator it = cargos->begin(); it != cargos->end(); it++) {
 
			CargoPacket *cp = *it;
 
			if (!cp->paid_for &&
 
@@ -1188,28 +1265,14 @@ void VehiclePayment(Vehicle *front_v)
 
				/* Deliver goods to the station */
 
				st->time_since_unload = 0;
 

	
 
				/* handle end of route payment */
 
				Money profit = DeliverGoods(cp->count, v->cargo_type, cp->source, last_visited, cp->source_xy, cp->days_in_transit, company);
 
				cp->paid_for = true;
 
				route_profit   += profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D
 
				vehicle_profit += profit - cp->feeder_share;                    // whole vehicle is not payed for transfers picked up earlier
 
				payment.PayFinalDelivery(cp, cp->count);
 

	
 
				result |= 1;
 

	
 
				SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
 
			} else if (front_v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) {
 
				if (!cp->paid_for && (front_v->current_order.GetUnloadType() & OUFB_TRANSFER) != 0) {
 
					Money profit = GetTransportedGoodsIncome(
 
						cp->count,
 
						/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
 
						DistanceManhattan(cp->loaded_at_xy, Station::Get(last_visited)->xy),
 
						cp->days_in_transit,
 
						v->cargo_type);
 

	
 
					front_v->profit_this_year += profit << 8;
 
					virtual_profit   += profit; // accumulate transfer profits for whole vehicle
 
					cp->feeder_share += profit; // account for the (virtual) profit already made for the cargo packet
 
					cp->paid_for      = true;   // record that the cargo has been paid for to eliminate double counting
 
					payment.PayTransfer(cp, cp->count);
 
				}
 
				result |= 2;
 

	
 
@@ -1225,23 +1288,6 @@ void VehiclePayment(Vehicle *front_v)
 
		TriggerIndustryProduction(*iid);
 
	}
 
	_cargo_delivery_destinations.Clear();
 

	
 
	if (virtual_profit > 0) {
 
		ShowFeederIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, virtual_profit);
 
	}
 

	
 
	if (route_profit != 0) {
 
		front_v->profit_this_year += vehicle_profit << 8;
 
		SubtractMoneyFromCompany(CommandCost(front_v->GetExpenseType(true), -route_profit));
 

	
 
		if (IsLocalCompany() && !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, -vehicle_profit);
 
	}
 

	
 
	_current_company = old_company;
 
}
 

	
 
/**
src/economy_base.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file economy_base.h Base classes related to the economy. */
 

	
 
#ifndef ECONOMY_BASE_H
 
#define ECONOMY_BASE_H
 

	
 
#include "cargopacket.h"
 

	
 
/**
 
 * Helper class to perform the cargo payment.
 
 */
 
struct CargoPayment {
 
	Vehicle *front;      ///< The front vehicle to do the payment of
 
	Money route_profit;  ///< The amount of money to add/remove from the bank account
 
	Money visual_profit; ///< The visual profit to show
 

	
 
	Company *owner;            ///< The owner of the vehicle
 
	StationID current_station; ///< The current station
 
	CargoID ct;                ///< The currently handled cargo type
 

	
 
	/** Constructor for pool saveload */
 
	CargoPayment(Vehicle *front);
 
	~CargoPayment();
 

	
 
	void PayTransfer(CargoPacket *cp, uint count);
 
	void PayFinalDelivery(CargoPacket *cp, uint count);
 

	
 
	/**
 
	 * Sets the currently handled cargo type.
 
	 * @param ct the cargo type to handle from now on.
 
	 */
 
	void SetCargo(CargoID ct) { this->ct = ct; }
 
};
 

	
 
#endif /* ECONOMY_BASE_H */
0 comments (0 inline, 0 general)