File diff r12647:3ada08b745f5 → r12648:24c912bd53f6
src/economy.cpp
Show inline comments
 
@@ -307,53 +307,55 @@ void ChangeOwnershipOfCompanyItems(Owner
 

	
 
		/* Sell all the shares that people have on this company */
 
		c = Company::Get(old_owner);
 
		for (i = 0; i < 4; i++) {
 
			_current_company = c->share_owners[i];
 
			if (_current_company != INVALID_OWNER) {
 
				/* Sell the shares */
 
				CommandCost res = DoCommand(0, old_owner, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY);
 
				/* Because we are in a DoCommand, we can't just execute an other one and
 
				 *  expect the money to be removed. We need to do it ourself! */
 
				SubtractMoneyFromCompany(res);
 
			}
 
		}
 
	}
 

	
 
	_current_company = old_owner;
 

	
 
	/* Temporarily increase the company's money, to be sure that
 
	 * removing his/her property doesn't fail because of lack of money.
 
	 * Not too drastically though, because it could overflow */
 
	if (new_owner == INVALID_OWNER) {
 
		Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p
 
	}
 

	
 
	if (new_owner == INVALID_OWNER) {
 
		Subsidy *s;
 
		FOR_ALL_SUBSIDIES(s) {
 
			if (s->IsAwarded() && Station::Get(s->dst)->owner == old_owner) {
 
				s->cargo_type = CT_INVALID;
 
	Subsidy *s;
 
	FOR_ALL_SUBSIDIES(s) {
 
		if (s->awarded == old_owner) {
 
			if (new_owner == INVALID_OWNER) {
 
				DeleteSubsidy(s);
 
			} else {
 
				s->awarded = new_owner;
 
			}
 
		}
 
	}
 

	
 
	/* Take care of rating in towns */
 
	FOR_ALL_TOWNS(t) {
 
		/* If a company takes over, give the ratings to that company. */
 
		if (new_owner != INVALID_OWNER) {
 
			if (HasBit(t->have_ratings, old_owner)) {
 
				if (HasBit(t->have_ratings, new_owner)) {
 
					/* use max of the two ratings. */
 
					t->ratings[new_owner] = max(t->ratings[new_owner], t->ratings[old_owner]);
 
				} else {
 
					SetBit(t->have_ratings, new_owner);
 
					t->ratings[new_owner] = t->ratings[old_owner];
 
				}
 
			}
 
		}
 

	
 
		/* Reset the ratings for the old owner */
 
		t->ratings[old_owner] = RATING_INITIAL;
 
		ClrBit(t->have_ratings, old_owner);
 
	}
 

	
 
@@ -895,87 +897,80 @@ static void DeliverGoodsToIndustry(const
 
		for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
 
			if (cargo_type == ind->accepts_cargo[cargo_index]) break;
 
		}
 
		/* Check if matching cargo has been found */
 
		if (cargo_index >= lengthof(ind->accepts_cargo)) continue;
 

	
 
		/* Check if industry temporarily refuses acceptance */
 
		if (HasBit(indspec->callback_flags, CBM_IND_REFUSE_CARGO)) {
 
			uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO, 0, GetReverseCargoTranslation(cargo_type, indspec->grf_prop.grffile), ind, ind->type, ind->xy);
 
			if (res == 0) continue;
 
		}
 

	
 
		/* Insert the industry into _cargo_delivery_destinations, if not yet contained */
 
		_cargo_delivery_destinations.Include(ind);
 

	
 
		ind->incoming_cargo_waiting[cargo_index] = min(num_pieces + ind->incoming_cargo_waiting[cargo_index], 0xFFFF);
 

	
 
		return;
 
	}
 
}
 

	
 
/**
 
 * Delivers goods to industries/towns and calculates the payment
 
 * @param num_pieces amount of cargo delivered
 
 * @param source Originstation of the cargo
 
 * @param dest Station the cargo has been unloaded
 
 * @param source_tile The origin of the cargo for distance calculation
 
 * @param days_in_transit Travel time
 
 * @param company The company delivering the cargo
 
 * The cargo is just added to the stockpile of the industry. It is due to the caller to trigger the industry's production machinery
 
 * @param src_type Type of source of cargo (industry, town, headquarters)
 
 * @param src Index of source of cargo
 
 * @return Revenue for delivering cargo
 
 * @note The cargo is just added to the stockpile of the industry. It is due to the caller to trigger the industry's production machinery
 
 */
 
static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID source, StationID dest, TileIndex source_tile, byte days_in_transit, Company *company)
 
static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, TileIndex source_tile, byte days_in_transit, Company *company, SourceType src_type, SourceID src)
 
{
 
	bool subsidised = false;
 

	
 
	assert(num_pieces > 0);
 

	
 
	/* Update company statistics */
 
	company->cur_economy.delivered_cargo += num_pieces;
 
	SetBit(company->cargo_types, cargo_type);
 

	
 
	const Station *s_to = Station::Get(dest);
 

	
 
	if (source != INVALID_STATION) {
 
		const Station *s_from = Station::Get(source);
 

	
 
		/* Check if a subsidy applies. */
 
		subsidised = CheckSubsidised(s_from, s_to, cargo_type, company->index);
 
	}
 
	const Station *st = Station::Get(dest);
 

	
 
	/* Increase town's counter for some special goods types */
 
	const CargoSpec *cs = CargoSpec::Get(cargo_type);
 
	if (cs->town_effect == TE_FOOD) s_to->town->new_act_food += num_pieces;
 
	if (cs->town_effect == TE_WATER) s_to->town->new_act_water += num_pieces;
 
	if (cs->town_effect == TE_FOOD) st->town->new_act_food += num_pieces;
 
	if (cs->town_effect == TE_WATER) st->town->new_act_water += num_pieces;
 

	
 
	/* Give the goods to the industry. */
 
	DeliverGoodsToIndustry(s_to, cargo_type, num_pieces);
 
	DeliverGoodsToIndustry(st, cargo_type, num_pieces);
 

	
 
	/* Determine profit */
 
	Money profit = GetTransportedGoodsIncome(num_pieces, DistanceManhattan(source_tile, s_to->xy), days_in_transit, cargo_type);
 
	Money profit = GetTransportedGoodsIncome(num_pieces, DistanceManhattan(source_tile, st->xy), days_in_transit, cargo_type);
 

	
 
	/* Modify profit if a subsidy is in effect */
 
	if (subsidised) {
 
	if (CheckSubsidised(cargo_type, company->index, src_type, src, st))  {
 
		switch (_settings_game.difficulty.subsidy_multiplier) {
 
			case 0:  profit += profit >> 1; break;
 
			case 1:  profit *= 2; break;
 
			case 2:  profit *= 3; break;
 
			default: profit *= 4; break;
 
		}
 
	}
 

	
 
	return profit;
 
}
 

	
 
/**
 
 * Inform the industry about just delivered cargo
 
 * DeliverGoodsToIndustry() silently incremented incoming_cargo_waiting, now it is time to do something with the new cargo.
 
 * @param i The industry to process
 
 */
 
static void TriggerIndustryProduction(Industry *i)
 
{
 
	const IndustrySpec *indspec = GetIndustrySpec(i->type);
 
	uint16 callback = indspec->callback_flags;
 

	
 
	i->was_cargo_delivered = true;
 
	i->last_cargo_accepted_at = _date;
 

	
 
@@ -1030,49 +1025,49 @@ CargoPayment::~CargoPayment()
 
		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);
 
	Money profit = DeliverGoods(count, this->ct, this->current_station, cp->source_xy, cp->days_in_transit, this->owner, cp->source_type, cp->source_id);
 
	this->route_profit += profit;
 

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

	
 
/**
 
 * 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
 
}