Changeset - r8556:c5860d29500d
[Not reviewed]
master
0 14 0
smatz - 16 years ago 2008-02-13 19:24:40
smatz@openttd.org
(svn r12134) -Change: count the number of ticks a vehicle was running this day to calculate running cost
-Fix [FS#1739]: vehicle profit is now counted with 8bit fract, so it is now shown properly in the vehicle details window
14 files changed with 76 insertions and 50 deletions:
0 comments (0 inline, 0 general)
src/ai/default/default.cpp
Show inline comments
 
@@ -103,26 +103,26 @@ static void AiStateVehLoop(Player *p)
 
				(v->type == VEH_AIRCRAFT && IsNormalAircraft(v)) ||
 
				v->type == VEH_SHIP) {
 
			/* replace engine? */
 
			if (v->type == VEH_TRAIN && v->engine_type < 3 &&
 
					(_price.build_railvehicle >> 3) < p->player_money) {
 
				_players_ai[p->index].state = AIS_VEH_CHECK_REPLACE_VEHICLE;
 
				_players_ai[p->index].cur_veh = v;
 
				return;
 
			}
 

	
 
			/* not profitable? */
 
			if (v->age >= 730 &&
 
					v->profit_last_year < _price.station_value * 5 &&
 
					v->profit_this_year < _price.station_value * 5) {
 
					v->profit_last_year >> 8 < _price.station_value * 5 &&
 
					v->profit_this_year >> 8 < _price.station_value * 5) {
 
				_players_ai[p->index].state_counter = 0;
 
				_players_ai[p->index].state = AIS_SELL_VEHICLE;
 
				_players_ai[p->index].cur_veh = v;
 
				return;
 
			}
 

	
 
			/* not reliable? */
 
			if (v->age >= v->max_age || (
 
						v->age != 0 &&
 
						GetEngine(v->engine_type)->reliability < 35389
 
					)) {
 
				_players_ai[p->index].state = AIS_VEH_CHECK_REPLACE_VEHICLE;
src/ai/trolly/trolly.cpp
Show inline comments
 
@@ -1243,25 +1243,25 @@ static void AiNew_State_RepayMoney(Playe
 
}
 

	
 

	
 
static void AiNew_CheckVehicle(Player *p, Vehicle *v)
 
{
 
	// When a vehicle is under the 6 months, we don't check for anything
 
	if (v->age < 180) return;
 

	
 
	// When a vehicle is older then 1 year, it should make money...
 
	if (v->age > 360) {
 
		// If both years together are not more than AI_MINIMUM_ROUTE_PROFIT,
 
		//  it is not worth the line I guess...
 
		if (v->profit_last_year + v->profit_this_year < AI_MINIMUM_ROUTE_PROFIT ||
 
		if ((v->profit_last_year + v->profit_this_year) >> 8 < AI_MINIMUM_ROUTE_PROFIT ||
 
				(v->reliability * 100 >> 16) < 40) {
 
			// There is a possibility that the route is fucked up...
 
			if (v->cargo.DaysInTransit() > AI_VEHICLE_LOST_DAYS) {
 
				// The vehicle is lost.. check the route, or else, get the vehicle
 
				//  back to a depot
 
				// TODO: make this piece of code
 
			}
 

	
 

	
 
			// We are already sending him back
 
			if (AiNew_GetSpecialVehicleFlag(p, v) & AI_VEHICLEFLAG_SELL) {
 
				if (v->type == VEH_ROAD && IsTileDepotType(v->tile, TRANSPORT_ROAD) &&
src/aircraft_cmd.cpp
Show inline comments
 
@@ -312,24 +312,26 @@ CommandCost CmdBuildAircraft(TileIndex t
 
		v->tile = tile;
 
//		u->tile = 0;
 

	
 
		uint x = TileX(tile) * TILE_SIZE + 5;
 
		uint y = TileY(tile) * TILE_SIZE + 3;
 

	
 
		v->x_pos = u->x_pos = x;
 
		v->y_pos = u->y_pos = y;
 

	
 
		u->z_pos = GetSlopeZ(x, y);
 
		v->z_pos = u->z_pos + 1;
 

	
 
		v->running_ticks = 0;
 

	
 
//		u->delta_x = u->delta_y = 0;
 

	
 
		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 
		u->vehstatus = VS_HIDDEN | VS_UNCLICKABLE | VS_SHADOW;
 

	
 
		v->spritenum = avi->image_index;
 
//		v->cargo_count = u->number_of_pieces = 0;
 

	
 
		v->cargo_cap = avi->passenger_capacity;
 
		u->cargo_cap = avi->mail_capacity;
 

	
 
		v->cargo_type = CT_PASSENGERS;
 
@@ -726,29 +728,30 @@ static void CheckIfAircraftNeedsService(
 
void Aircraft::OnNewDay()
 
{
 
	if (!IsNormalAircraft(this)) return;
 

	
 
	if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
 

	
 
	CheckOrders(this);
 

	
 
	CheckVehicleBreakdown(this);
 
	AgeVehicle(this);
 
	CheckIfAircraftNeedsService(this);
 

	
 
	if (this->vehstatus & VS_STOPPED) return;
 
	if (this->running_ticks == 0) return;
 

	
 
	CommandCost cost = CommandCost(EXPENSES_AIRCRAFT_RUN, GetVehicleProperty(this, 0x0E, AircraftVehInfo(this->engine_type)->running_cost) * _price.aircraft_running / 364);
 
	CommandCost cost(EXPENSES_AIRCRAFT_RUN, GetVehicleProperty(this, 0x0E, AircraftVehInfo(this->engine_type)->running_cost) * _price.aircraft_running * this->running_ticks / (364 * DAY_TICKS));
 

	
 
	this->profit_this_year -= cost.GetCost() >> 8;
 
	this->profit_this_year -= cost.GetCost();
 
	this->running_ticks = 0;
 

	
 
	SubtractMoneyFromPlayerFract(this->owner, cost);
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
 
}
 

	
 
void AircraftYearlyLoop()
 
{
 
	Vehicle *v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
@@ -2137,24 +2140,26 @@ static void AircraftEventHandler(Vehicle
 
	ProcessAircraftOrder(v);
 
	v->HandleLoading(loop != 0);
 

	
 
	if (v->current_order.type >= OT_LOADING) return;
 

	
 
	AirportGoToNextPosition(v);
 
}
 

	
 
void Aircraft::Tick()
 
{
 
	if (!IsNormalAircraft(this)) return;
 

	
 
	if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
 

	
 
	if (this->subtype == AIR_HELICOPTER) HelicopterTickHandler(this);
 

	
 
	AgeAircraftCargo(this);
 

	
 
	for (uint i = 0; i != 2; i++) {
 
		AircraftEventHandler(this, i);
 
		if (this->type != VEH_AIRCRAFT) // In case it was deleted
 
			break;
 
	}
 
}
 

	
 

	
src/economy.cpp
Show inline comments
 
@@ -154,29 +154,27 @@ int UpdateCompanyRatingAndValue(Player *
 
	{
 
		Vehicle *v;
 
		Money min_profit = 0;
 
		bool min_profit_first = true;
 
		uint num = 0;
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->owner != owner) continue;
 
			if (IsPlayerBuildableVehicleType(v->type) && v->IsPrimaryVehicle()) {
 
				num++;
 
				if (v->age > 730) {
 
					/* Find the vehicle with the lowest amount of profit */
 
					if (min_profit_first == true) {
 
						min_profit = v->profit_last_year;
 
					if (min_profit_first || min_profit > v->profit_last_year >> 8) {
 
						min_profit = v->profit_last_year >> 8;
 
						min_profit_first = false;
 
					} else if (min_profit > v->profit_last_year) {
 
						min_profit = v->profit_last_year;
 
					}
 
				}
 
			}
 
		}
 

	
 
		_score_part[owner][SCORE_VEHICLES] = num;
 
		/* Don't allow negative min_profit to show */
 
		if (min_profit > 0)
 
			_score_part[owner][SCORE_MIN_PROFIT] = ClampToI32(min_profit);
 
	}
 

	
 
/* Count stations */
 
@@ -1496,43 +1494,43 @@ void VehiclePayment(Vehicle *front_v)
 
				result |= 1;
 

	
 
				SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
 
			} else if (front_v->current_order.flags & (OFB_UNLOAD | OFB_TRANSFER)) {
 
				if (!cp->paid_for && (front_v->current_order.flags & OFB_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, GetStation(last_visited)->xy),
 
						cp->days_in_transit,
 
						v->cargo_type);
 

	
 
					front_v->profit_this_year += profit;
 
					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
 
				}
 
				result |= 2;
 

	
 
				SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
 
			}
 
		}
 
		v->cargo.InvalidateCache();
 
	}
 

	
 
	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;
 
		front_v->profit_this_year += vehicle_profit << 8;
 
		SubtractMoneyFromPlayer(CommandCost(front_v->GetExpenseType(true), -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, -vehicle_profit);
 
	}
 

	
 
	_current_player = old_player;
 
}
 

	
src/group_gui.cpp
Show inline comments
 
@@ -474,26 +474,26 @@ static void GroupWndProc(Window *w, Wind
 
				const Vehicle* v = gv->sort_list[i];
 

	
 
				assert(v->type == gv->vehicle_type && v->owner == owner);
 

	
 
				DrawVehicleImage(v, x + 19, y2 + 6, gv->vehicle_sel, w->hscroll.cap, 0);
 
				DrawVehicleProfitButton(v, x, y2 + 13);
 

	
 
				SetDParam(0, v->unitnumber);
 
				DrawString(x, y2 + 2, v->IsInDepot() ? STR_021F : (v->age > v->max_age - 366 ? STR_00E3 : STR_00E2), TC_FROMSTRING);
 

	
 
				if (w->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG2) DrawSmallOrderList(v, x + 138, y2);
 

	
 
				SetDParam(0, v->profit_this_year);
 
				SetDParam(1, v->profit_last_year);
 
				SetDParam(0, v->profit_this_year >> 8);
 
				SetDParam(1, v->profit_last_year >> 8);
 
				DrawString(x + 19, y2 + w->resize.step_height - 8, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, TC_FROMSTRING);
 

	
 
				if (IsValidGroupID(v->group_id)) {
 
					SetDParam(0, v->group_id);
 
					DrawString(x + 19, y2, STR_GROUP_TINY_NAME, TC_BLACK);
 
				}
 

	
 
				y2 += w->resize.step_height;
 
			}
 

	
 
			break;
 
		}
src/newgrf_engine.cpp
Show inline comments
 
@@ -685,32 +685,32 @@ static uint32 VehicleGetVariable(const R
 
		case 0x46: return v->engine_type;
 
		case 0x47: return GB(v->engine_type, 8, 8);
 
		case 0x48: return v->spritenum;
 
		case 0x49: return v->day_counter;
 
		case 0x4A: return v->breakdowns_since_last_service;
 
		case 0x4B: return v->breakdown_ctr;
 
		case 0x4C: return v->breakdown_delay;
 
		case 0x4D: return v->breakdown_chance;
 
		case 0x4E: return v->reliability;
 
		case 0x4F: return GB(v->reliability, 8, 8);
 
		case 0x50: return v->reliability_spd_dec;
 
		case 0x51: return GB(v->reliability_spd_dec, 8, 8);
 
		case 0x52: return ClampToI32(v->profit_this_year);
 
		case 0x53: return GB(ClampToI32(v->profit_this_year),  8, 24);
 
		case 0x54: return GB(ClampToI32(v->profit_this_year), 16, 16);
 
		case 0x55: return GB(ClampToI32(v->profit_this_year), 24,  8);
 
		case 0x56: return ClampToI32(v->profit_last_year);
 
		case 0x57: return GB(ClampToI32(v->profit_last_year),  8, 24);
 
		case 0x58: return GB(ClampToI32(v->profit_last_year), 16, 16);
 
		case 0x59: return GB(ClampToI32(v->profit_last_year), 24,  8);
 
		case 0x52: return ClampToI32(v->profit_this_year >> 8);
 
		case 0x53: return GB(ClampToI32(v->profit_this_year >> 8),  8, 24);
 
		case 0x54: return GB(ClampToI32(v->profit_this_year >> 8), 16, 16);
 
		case 0x55: return GB(ClampToI32(v->profit_this_year >> 8), 24,  8);
 
		case 0x56: return ClampToI32(v->profit_last_year >> 8);
 
		case 0x57: return GB(ClampToI32(v->profit_last_year >> 8),  8, 24);
 
		case 0x58: return GB(ClampToI32(v->profit_last_year >> 8), 16, 16);
 
		case 0x59: return GB(ClampToI32(v->profit_last_year >> 8), 24,  8);
 
		case 0x5A: return v->Next() == NULL ? INVALID_VEHICLE : v->Next()->index;
 
		case 0x5C: return ClampToI32(v->value);
 
		case 0x5D: return GB(ClampToI32(v->value),  8, 24);
 
		case 0x5E: return GB(ClampToI32(v->value), 16, 16);
 
		case 0x5F: return GB(ClampToI32(v->value), 24,  8);
 
		case 0x72: return v->cargo_subtype;
 
		case 0x7A: return v->random_bits;
 
		case 0x7B: return v->waiting_triggers;
 
	}
 

	
 
	/* Vehicle specific properties */
 
	switch (v->type) {
src/openttd.cpp
Show inline comments
 
@@ -2410,24 +2410,34 @@ bool AfterLoadGame()
 
			_patches.pathfinder_for_roadvehs = VPF_YAPF;
 
		} else {
 
			_patches.pathfinder_for_roadvehs = (_patches.new_pathfinding_all ? VPF_NPF : VPF_OPF);
 
		}
 

	
 
		if (_patches.yapf.ship_use_yapf) {
 
			_patches.pathfinder_for_ships = VPF_YAPF;
 
		} else {
 
			_patches.pathfinder_for_ships = (_patches.new_pathfinding_all ? VPF_NPF : VPF_OPF);
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(88)) {
 
		/* Profits are now with 8 bit fract */
 
		Vehicle *v;
 
		FOR_ALL_VEHICLES(v) {
 
			v->profit_this_year <<= 8;
 
			v->profit_last_year <<= 8;
 
			v->running_ticks = 0;
 
		}
 
	}
 

	
 
	return InitializeWindowsAndCaches();
 
}
 

	
 
/** Reload all NewGRF files during a running game. This is a cut-down
 
 * version of AfterLoadGame().
 
 * XXX - We need to reset the vehicle position hash because with a non-empty
 
 * hash AfterLoadVehicles() will loop infinitely. We need AfterLoadVehicles()
 
 * to recalculate vehicle data as some NewGRF vehicle sets could have been
 
 * removed or added and changed statistics */
 
void ReloadNewGRFData()
 
{
 
	/* reload grf data */
src/roadveh_cmd.cpp
Show inline comments
 
@@ -210,24 +210,26 @@ CommandCost CmdBuildRoadVeh(TileIndex ti
 
		v = new (v) RoadVehicle();
 
		v->unitnumber = unit_num;
 
		v->direction = DiagDirToDir(GetRoadDepotDirection(tile));
 
		v->owner = _current_player;
 

	
 
		v->tile = tile;
 
		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
 
		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
 
		v->x_pos = x;
 
		v->y_pos = y;
 
		v->z_pos = GetSlopeZ(x, y);
 

	
 
		v->running_ticks = 0;
 

	
 
		v->u.road.state = RVSB_IN_DEPOT;
 
		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 

	
 
		v->spritenum = rvi->image_index;
 
		v->cargo_type = rvi->cargo_type;
 
		v->cargo_subtype = 0;
 
		v->cargo_cap = rvi->capacity;
 
//		v->cargo_count = 0;
 
		v->value = cost.GetCost();
 
//		v->day_counter = 0;
 
//		v->next_order_param = v->next_order = 0;
 
//		v->load_unload_time_rem = 0;
 
@@ -1957,25 +1959,28 @@ static void RoadVehController(Vehicle *v
 
}
 

	
 
static void AgeRoadVehCargo(Vehicle *v)
 
{
 
	if (_age_cargo_skip_counter != 0) return;
 
	v->cargo.AgeCargo();
 
}
 

	
 
void RoadVehicle::Tick()
 
{
 
	AgeRoadVehCargo(this);
 

	
 
	if (IsRoadVehFront(this)) RoadVehController(this);
 
	if (IsRoadVehFront(this)) {
 
		if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
 
		RoadVehController(this);
 
	}
 
}
 

	
 
static void CheckIfRoadVehNeedsService(Vehicle *v)
 
{
 
	/* If we already got a slot at a stop, use that FIRST, and go to a depot later */
 
	if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !VehicleNeedsService(v)) return;
 
	if (v->IsInDepot()) {
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	/* XXX If we already have a depot order, WHY do we search over and over? */
 
@@ -1999,47 +2004,43 @@ static void CheckIfRoadVehNeedsService(V
 
	if (v->current_order.type == OT_LOADING) v->LeaveStation();
 
	ClearSlot(v);
 

	
 
	v->current_order.type = OT_GOTO_DEPOT;
 
	v->current_order.flags = OFB_NON_STOP;
 
	v->current_order.dest = depot->index;
 
	v->dest_tile = depot->xy;
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
}
 

	
 
void RoadVehicle::OnNewDay()
 
{
 
	CommandCost cost(EXPENSES_ROADVEH_RUN);
 

	
 
	if (!IsRoadVehFront(this)) return;
 

	
 
	if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
 
	if (this->u.road.blocked_ctr == 0) CheckVehicleBreakdown(this);
 

	
 
	AgeVehicle(this);
 
	CheckIfRoadVehNeedsService(this);
 

	
 
	CheckOrders(this);
 

	
 
	/* Current slot has expired */
 
	if (this->current_order.type == OT_GOTO_STATION && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) {
 
		DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X",
 
			this->unitnumber, this->index, this->u.road.slot->xy);
 
		ClearSlot(this);
 
	}
 

	
 
	if (this->vehstatus & VS_STOPPED) return;
 

	
 
	/* update destination */
 
	if (this->current_order.type == OT_GOTO_STATION && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) {
 
	if (!(this->vehstatus & VS_STOPPED) && this->current_order.type == OT_GOTO_STATION && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) {
 
		Station *st = GetStation(this->current_order.dest);
 
		RoadStop *rs = st->GetPrimaryRoadStop(this);
 
		RoadStop *best = NULL;
 

	
 
		if (rs != NULL) {
 
			/* We try to obtain a slot if:
 
			 * 1) we're reasonably close to the primary road stop
 
			 * or
 
			 * 2) we're somewhere close to the station rectangle (to make sure we do assign
 
			 *    slots even if the station and its road stops are incredibly spread out)
 
			 */
 
			if (DistanceManhattan(this->tile, rs->xy) < 16 || st->rect.PtInExtendedRect(TileX(this->tile), TileY(this->tile), 2)) {
 
@@ -2079,27 +2080,30 @@ void RoadVehicle::OnNewDay()
 
					DEBUG(ms, 3, "Could not find a suitable stop");
 
				}
 
			} else {
 
				DEBUG(ms, 5, "Distance from station too far. Postponing slotting for vehicle %d (index %d) at station %d, (0x%X)",
 
						this->unitnumber, this->index, st->index, st->xy);
 
			}
 
		} else {
 
			DEBUG(ms, 4, "No road stop for vehicle %d (index %d) at station %d (0x%X)",
 
					this->unitnumber, this->index, st->index, st->xy);
 
		}
 
	}
 

	
 
	cost = CommandCost(EXPENSES_ROADVEH_RUN, RoadVehInfo(this->engine_type)->running_cost * _price.roadveh_running / 364);
 
	if (this->running_ticks == 0) return;
 

	
 
	this->profit_this_year -= cost.GetCost() >> 8;
 
	CommandCost cost(EXPENSES_ROADVEH_RUN, RoadVehInfo(this->engine_type)->running_cost * _price.roadveh_running * this->running_ticks / (364 * DAY_TICKS));
 

	
 
	this->profit_this_year -= cost.GetCost();
 
	this->running_ticks = 0;
 

	
 
	SubtractMoneyFromPlayerFract(this->owner, cost);
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	InvalidateWindowClasses(WC_ROADVEH_LIST);
 
}
 

	
 

	
 
void RoadVehiclesYearlyLoop()
 
{
 
	Vehicle *v;
 

	
src/saveload.cpp
Show inline comments
 
@@ -25,25 +25,25 @@
 
#include "window_func.h"
 
#include "strings_func.h"
 
#include "gfx_func.h"
 
#include "core/alloc_func.hpp"
 
#include "functions.h"
 
#include "core/endian_func.hpp"
 
#include "vehicle_base.h"
 
#include "autoreplace_base.h"
 
#include <list>
 

	
 
#include "table/strings.h"
 

	
 
extern const uint16 SAVEGAME_VERSION = 87;
 
extern const uint16 SAVEGAME_VERSION = 88;
 
uint16 _sl_version;       ///< the major savegame version identifier
 
byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
 

	
 
typedef void WriterProc(uint len);
 
typedef uint ReaderProc();
 

	
 
/** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
 
static struct {
 
	bool save;                           ///< are we doing a save or a load atm. True when saving
 
	byte need_length;                    ///< ???
 
	byte block_mode;                     ///< ???
 
	bool error;                          ///< did an error occur or not
src/ship_cmd.cpp
Show inline comments
 
@@ -161,39 +161,39 @@ static void CheckIfShipNeedsService(Vehi
 
		return;
 
	}
 

	
 
	v->current_order.type = OT_GOTO_DEPOT;
 
	v->current_order.flags = OFB_NON_STOP;
 
	v->current_order.dest = depot->index;
 
	v->dest_tile = depot->xy;
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
}
 

	
 
void Ship::OnNewDay()
 
{
 
	CommandCost cost(EXPENSES_SHIP_RUN);
 

	
 
	if ((++this->day_counter & 7) == 0)
 
		DecreaseVehicleValue(this);
 

	
 
	CheckVehicleBreakdown(this);
 
	AgeVehicle(this);
 
	CheckIfShipNeedsService(this);
 

	
 
	CheckOrders(this);
 

	
 
	if (this->vehstatus & VS_STOPPED) return;
 
	if (this->running_ticks == 0) return;
 

	
 
	cost.AddCost(GetVehicleProperty(this, 0x0F, ShipVehInfo(this->engine_type)->running_cost) * _price.ship_running / 364);
 
	this->profit_this_year -= cost.GetCost() >> 8;
 
	CommandCost cost(EXPENSES_SHIP_RUN, GetVehicleProperty(this, 0x0F, ShipVehInfo(this->engine_type)->running_cost) * _price.ship_running * this->running_ticks / (364 * DAY_TICKS));
 

	
 
	this->profit_this_year -= cost.GetCost();
 
	this->running_ticks = 0;
 

	
 
	SubtractMoneyFromPlayerFract(this->owner, cost);
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	/* we need this for the profit */
 
	InvalidateWindowClasses(WC_SHIPS_LIST);
 
}
 

	
 
static void HandleBrokenShip(Vehicle *v)
 
{
 
	if (v->breakdown_ctr != 1) {
 
		v->breakdown_ctr = 1;
 
@@ -772,24 +772,26 @@ reverse_direction:
 
	v->direction = dir;
 
	goto getout;
 
}
 

	
 
static void AgeShipCargo(Vehicle *v)
 
{
 
	if (_age_cargo_skip_counter != 0) return;
 
	v->cargo.AgeCargo();
 
}
 

	
 
void Ship::Tick()
 
{
 
	if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
 

	
 
	AgeShipCargo(this);
 
	ShipController(this);
 
}
 

	
 

	
 
void ShipsYearlyLoop()
 
{
 
	Vehicle *v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_SHIP) {
 
			v->profit_last_year = v->profit_this_year;
 
@@ -834,24 +836,26 @@ CommandCost CmdBuildShip(TileIndex tile,
 

	
 
		Vehicle *v = new Ship();
 
		v->unitnumber = unit_num;
 

	
 
		v->owner = _current_player;
 
		v->tile = tile;
 
		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
 
		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
 
		v->x_pos = x;
 
		v->y_pos = y;
 
		v->z_pos = GetSlopeZ(x, y);
 

	
 
		v->running_ticks = 0;
 

	
 
		v->UpdateDeltaXY(v->direction);
 
		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 

	
 
		v->spritenum = svi->image_index;
 
		v->cargo_type = svi->cargo_type;
 
		v->cargo_subtype = 0;
 
		v->cargo_cap = svi->capacity;
 
		v->value = value.GetCost();
 

	
 
		v->last_station_visited = INVALID_STATION;
 
		v->max_speed = svi->max_speed;
 
		v->engine_type = p1;
src/train_cmd.cpp
Show inline comments
 
@@ -726,24 +726,25 @@ CommandCost CmdBuildRailVehicle(TileInde
 
			DiagDirection dir = GetRailDepotDirection(tile);
 
			int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir];
 
			int y = TileY(tile) * TILE_SIZE + _vehicle_initial_y_fract[dir];
 

	
 
			v = new (v) Train();
 
			v->unitnumber = unit_num;
 
			v->direction = DiagDirToDir(dir);
 
			v->tile = tile;
 
			v->owner = _current_player;
 
			v->x_pos = x;
 
			v->y_pos = y;
 
			v->z_pos = GetSlopeZ(x, y);
 
			v->running_ticks = 0;
 
			v->u.rail.track = TRACK_BIT_DEPOT;
 
			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 
			v->spritenum = rvi->image_index;
 
			v->cargo_type = rvi->cargo_type;
 
			v->cargo_subtype = 0;
 
			v->cargo_cap = rvi->capacity;
 
			v->max_speed = rvi->max_speed;
 
			v->value = value.GetCost();
 
			v->last_station_visited = INVALID_STATION;
 
			v->dest_tile = 0;
 

	
 
			v->engine_type = p1;
 
@@ -3586,24 +3587,25 @@ Money Train::GetRunningCost() const
 

	
 
	return cost;
 
}
 

	
 

	
 
void Train::Tick()
 
{
 
	if (_age_cargo_skip_counter == 0) this->cargo.AgeCargo();
 

	
 
	this->tick_counter++;
 

	
 
	if (IsFrontEngine(this)) {
 
		if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
 
		this->current_order_time++;
 

	
 
		TrainLocoHandler(this, false);
 

	
 
		/* make sure vehicle wasn't deleted. */
 
		if (this->type == VEH_TRAIN && IsFrontEngine(this))
 
			TrainLocoHandler(this, true);
 
	} else if (IsFreeWagon(this) && HASBITS(this->vehstatus, VS_CRASHED)) {
 
		/* Delete flooded standalone wagon chain */
 
		if (++this->u.rail.crash_anim_pos >= 4400) DeleteVehicleChain(this);
 
	}
 
}
 
@@ -3656,29 +3658,30 @@ void Train::OnNewDay()
 
		AgeVehicle(this);
 

	
 
		CheckIfTrainNeedsService(this);
 

	
 
		CheckOrders(this);
 

	
 
		/* update destination */
 
		if (this->current_order.type == OT_GOTO_STATION) {
 
			TileIndex tile = GetStation(this->current_order.dest)->train_tile;
 
			if (tile != 0) this->dest_tile = tile;
 
		}
 

	
 
		if ((this->vehstatus & VS_STOPPED) == 0) {
 
		if (this->running_ticks != 0) {
 
			/* running costs */
 
			CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() / 364);
 

	
 
			this->profit_this_year -= cost.GetCost() >> 8;
 
			CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (364 * DAY_TICKS));
 

	
 
			this->profit_this_year -= cost.GetCost();
 
			this->running_ticks = 0;
 

	
 
			SubtractMoneyFromPlayerFract(this->owner, cost);
 

	
 
			InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
			InvalidateWindowClasses(WC_TRAINS_LIST);
 
		}
 
	} else if (IsTrainEngine(this)) {
 
		/* Also age engines that aren't front engines */
 
		AgeVehicle(this);
 
	}
 
}
 

	
src/vehicle.cpp
Show inline comments
 
@@ -2788,24 +2788,25 @@ static const SaveLoad _common_veh_desc[]
 
	     SLE_VAR(Vehicle, cargo_type,           SLE_UINT8),
 
	 SLE_CONDVAR(Vehicle, cargo_subtype,        SLE_UINT8,                  35, SL_MAX_VERSION),
 
	SLEG_CONDVAR(         _cargo_days,          SLE_UINT8,                   0, 67),
 
	SLEG_CONDVAR(         _cargo_source,        SLE_FILE_U8  | SLE_VAR_U16,  0, 6),
 
	SLEG_CONDVAR(         _cargo_source,        SLE_UINT16,                  7, 67),
 
	SLEG_CONDVAR(         _cargo_source_xy,     SLE_UINT32,                 44, 67),
 
	     SLE_VAR(Vehicle, cargo_cap,            SLE_UINT16),
 
	SLEG_CONDVAR(         _cargo_count,         SLE_UINT16,                  0, 67),
 
	 SLE_CONDLST(Vehicle, cargo,                REF_CARGO_PACKET,           68, SL_MAX_VERSION),
 

	
 
	    SLE_VAR(Vehicle, day_counter,          SLE_UINT8),
 
	    SLE_VAR(Vehicle, tick_counter,         SLE_UINT8),
 
	SLE_CONDVAR(Vehicle, running_ticks,        SLE_UINT8,                   88, SL_MAX_VERSION),
 

	
 
	    SLE_VAR(Vehicle, cur_order_index,      SLE_UINT8),
 
	    SLE_VAR(Vehicle, num_orders,           SLE_UINT8),
 

	
 
	/* This next line is for version 4 and prior compatibility.. it temporarily reads
 
	    type and flags (which were both 4 bits) into type. Later on this is
 
	    converted correctly */
 
	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8,                 0, 4),
 
	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
 

	
 
	/* Orders for version 5 and on */
 
	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type),  SLE_UINT8,  5, SL_MAX_VERSION),
src/vehicle_base.h
Show inline comments
 
@@ -240,26 +240,27 @@ public:
 
	byte progress;
 
	uint32 motion_counter;
 

	
 
	byte vehstatus;          // Status
 
	StationID last_station_visited;
 

	
 
	CargoID cargo_type;      // type of cargo this vehicle is carrying
 
	uint16 cargo_cap;        // total capacity
 
	byte cargo_subtype;      ///< Used for livery refits (NewGRF variations)
 
	CargoList cargo;         ///< The cargo this vehicle is carrying
 

	
 

	
 
	byte day_counter;        // increased by one for each day
 
	byte tick_counter;       // increased by one for each tick
 
	byte day_counter;        ///< Increased by one for each day
 
	byte tick_counter;       ///< Increased by one for each tick
 
	byte running_ticks;      ///< Number of ticks this vehicle was not stopped this day
 

	
 
	/* Begin Order-stuff */
 
	Order current_order;     ///< The current order (+ status, like: loading)
 
	VehicleOrderID cur_order_index; ///< The index to the current order
 

	
 
	Order *orders;           ///< Pointer to the first order for this vehicle
 
	VehicleOrderID num_orders;      ///< How many orders there are in the list
 

	
 
	Vehicle *next_shared;    ///< If not NULL, this points to the next vehicle that shared the order
 
	Vehicle *prev_shared;    ///< If not NULL, this points to the prev vehicle that shared the order
 
	/* End Order-stuff */
 

	
 
@@ -282,26 +283,26 @@ public:
 
	uint16 reliability_spd_dec;
 
	byte breakdown_ctr;
 
	byte breakdown_delay;
 
	byte breakdowns_since_last_service;
 
	byte breakdown_chance;
 
	Year build_year;
 

	
 
	bool leave_depot_instantly; // NOSAVE: stores if the vehicle needs to leave the depot it just entered. Used by autoreplace
 

	
 
	uint16 load_unload_time_rem;
 
	byte vehicle_flags;         // Used for gradual loading and other miscellaneous things (@see VehicleFlags enum)
 

	
 
	Money profit_this_year;
 
	Money profit_last_year;
 
	Money profit_this_year;        ///< Profit this year << 8, low 8 bits are fract
 
	Money profit_last_year;        ///< Profit last year << 8, low 8 bits are fract
 
	Money value;
 

	
 
	GroupID group_id;              ///< Index of group Pool array
 

	
 
	/* Used for timetabling. */
 
	uint32 current_order_time;     ///< How many ticks have passed since this order started.
 
	int32 lateness_counter;        ///< How many ticks late (or early if negative) this vehicle is.
 

	
 
	SpriteID colormap; // NOSAVE: cached color mapping
 

	
 
	union {
 
		VehicleRail rail;
src/vehicle_gui.cpp
Show inline comments
 
@@ -164,25 +164,25 @@ void DepotSortList(Vehicle **v, uint16 l
 
}
 

	
 
/** draw the vehicle profit button in the vehicle list window. */
 
void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
 
{
 
	SpriteID pal;
 

	
 
	/* draw profit-based colored icons */
 
	if (v->age <= 365 * 2) {
 
		pal = PALETTE_TO_GREY;
 
	} else if (v->profit_last_year < 0) {
 
		pal = PALETTE_TO_RED;
 
	} else if (v->profit_last_year < 10000) {
 
	} else if (v->profit_last_year >> 8 < 10000) {
 
		pal = PALETTE_TO_YELLOW;
 
	} else {
 
		pal = PALETTE_TO_GREEN;
 
	}
 
	DrawSprite(SPR_BLOT, pal, x, y);
 
}
 

	
 
struct RefitOption {
 
	CargoID cargo;
 
	byte subtype;
 
	uint16 value;
 
	EngineID engine;
 
@@ -589,25 +589,25 @@ static int CDECL VehicleProfitThisYearSo
 
	const Vehicle* vb = *(const Vehicle**)b;
 
	int r = ClampToI32(va->profit_this_year - vb->profit_this_year);
 

	
 
	VEHICLEUNITNUMBERSORTER(r, va, vb);
 

	
 
	return (_internal_sort_order & 1) ? -r : r;
 
}
 

	
 
static int CDECL VehicleProfitLastYearSorter(const void *a, const void *b)
 
{
 
	const Vehicle* va = *(const Vehicle**)a;
 
	const Vehicle* vb = *(const Vehicle**)b;
 
	int r = ClampToI32(va->profit_last_year - vb->profit_last_year);
 
	int r = ClampToI32((va->profit_last_year - vb->profit_last_year) >> 8);
 

	
 
	VEHICLEUNITNUMBERSORTER(r, va, vb);
 

	
 
	return (_internal_sort_order & 1) ? -r : r;
 
}
 

	
 
static int CDECL VehicleCargoSorter(const void *a, const void *b)
 
{
 
	const Vehicle* va = *(const Vehicle**)a;
 
	const Vehicle* vb = *(const Vehicle**)b;
 
	const Vehicle* v;
 
	AcceptedCargo cargoa;
 
@@ -974,26 +974,26 @@ static void DrawVehicleListWindow(Window
 
	DrawWindowWidgets(w);
 

	
 
	/* draw sorting criteria string */
 
	DrawString(85, 15, _vehicle_sort_listing[vl->l.sort_type], TC_BLACK);
 
	/* draw arrow pointing up/down for ascending/descending sorting */
 
	DrawSortButtonState(w, VLW_WIDGET_SORT_ORDER, vl->l.flags & VL_DESC ? SBS_DOWN : SBS_UP);
 

	
 
	max = min(w->vscroll.pos + w->vscroll.cap, vl->l.list_length);
 
	for (i = w->vscroll.pos; i < max; ++i) {
 
		const Vehicle *v = vl->sort_list[i];
 
		StringID str;
 

	
 
		SetDParam(0, v->profit_this_year);
 
		SetDParam(1, v->profit_last_year);
 
		SetDParam(0, v->profit_this_year >> 8);
 
		SetDParam(1, v->profit_last_year >> 8);
 

	
 
		DrawVehicleImage(v, x + 19, y + 6, INVALID_VEHICLE, w->widget[VLW_WIDGET_LIST].right - w->widget[VLW_WIDGET_LIST].left - 20, 0);
 
		DrawString(x + 19, y + w->resize.step_height - 8, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, TC_FROMSTRING);
 

	
 
		if (v->name != NULL) {
 
			/* The vehicle got a name so we will print it */
 
			SetDParam(0, v->index);
 
			DrawString(x + 19, y, STR_01AB, TC_FROMSTRING);
 
		}
 

	
 
		if (w->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG) DrawSmallOrderList(v, x + 138, y);
 

	
 
@@ -1491,26 +1491,26 @@ static void DrawVehicleDetailsWindow(Win
 

	
 
		case VEH_ROAD:
 
		case VEH_SHIP:
 
		case VEH_AIRCRAFT:
 
			SetDParam(0, v->GetDisplayMaxSpeed());
 
			DrawString(2, 25, _vehicle_translation_table[VST_VEHICLE_MAX_SPEED][v->type], TC_FROMSTRING);
 
			break;
 

	
 
		default: NOT_REACHED();
 
	}
 

	
 
	/* Draw profit */
 
	SetDParam(0, v->profit_this_year);
 
	SetDParam(1, v->profit_last_year);
 
	SetDParam(0, v->profit_this_year >> 8);
 
	SetDParam(1, v->profit_last_year >> 8);
 
	DrawString(2, 35, _vehicle_translation_table[VST_VEHICLE_PROFIT_THIS_YEAR_LAST_YEAR][v->type], TC_FROMSTRING);
 

	
 
	/* Draw breakdown & reliability */
 
	SetDParam(0, v->reliability * 100 >> 16);
 
	SetDParam(1, v->breakdowns_since_last_service);
 
	DrawString(2, 45, _vehicle_translation_table[VST_VEHICLE_RELIABILITY_BREAKDOWNS][v->type], TC_FROMSTRING);
 

	
 
	/* Draw service interval text */
 
	SetDParam(0, v->service_interval);
 
	SetDParam(1, v->date_of_last_service);
 
	DrawString(13, w->height - (v->type != VEH_TRAIN ? 11 : 23), _patches.servint_ispercent ? STR_SERVICING_INTERVAL_PERCENT : STR_883C_SERVICING_INTERVAL_DAYS, TC_FROMSTRING);
 

	
0 comments (0 inline, 0 general)