Changeset - r4845:2200ed004c20
[Not reviewed]
master
0 12 0
Darkvater - 18 years ago 2006-10-14 15:15:56
darkvater@openttd.org
(svn r6771) -Codechange: Replace two macros with functions. IS_HUMAN_PLAYER and
IS_INTERACTIVE_PLAYER
12 files changed with 39 insertions and 32 deletions:
0 comments (0 inline, 0 general)
ai/default/default.c
Show inline comments
 
@@ -3752,85 +3752,85 @@ static AiStateAction * const _ai_actions
 
	AiStateCheckShipStuff,
 
	AiStateBuildDefaultShipBlocks,
 
	AiStateDoShipStuff,
 

	
 
	AiStateSellVeh,
 
	AiStateRemoveStation,
 
	AiStateRemoveTrack,
 

	
 
	AiStateRemoveSingleRailTile
 
};
 

	
 
extern void ShowBuyCompanyDialog(uint player);
 

	
 
static void AiHandleTakeover(Player *p)
 
{
 
	if (p->bankrupt_timeout != 0) {
 
		p->bankrupt_timeout -= 8;
 
		if (p->bankrupt_timeout > 0) return;
 
		p->bankrupt_timeout = 0;
 
		DeleteWindowById(WC_BUY_COMPANY, _current_player);
 
		if (IsLocalPlayer()) {
 
			AskExitToGameMenu();
 
			return;
 
		}
 
		if (IS_HUMAN_PLAYER(_current_player)) return;
 
		if (IsHumanPlayer(_current_player)) return;
 
	}
 

	
 
	if (p->bankrupt_asked == 255) return;
 

	
 
	{
 
		uint asked = p->bankrupt_asked;
 
		Player *pp, *best_pl = NULL;
 
		int32 best_val = -1;
 
		uint old_p;
 

	
 
		// Ask the guy with the highest performance hist.
 
		FOR_ALL_PLAYERS(pp) {
 
			if (pp->is_active &&
 
					!(asked&1) &&
 
					pp->bankrupt_asked == 0 &&
 
					best_val < pp->old_economy[1].performance_history) {
 
				best_val = pp->old_economy[1].performance_history;
 
				best_pl = pp;
 
			}
 
			asked>>=1;
 
		}
 

	
 
		// Asked all players?
 
		if (best_val == -1) {
 
			p->bankrupt_asked = 255;
 
			return;
 
		}
 

	
 
		SETBIT(p->bankrupt_asked, best_pl->index);
 

	
 
		if (best_pl->index == _local_player) {
 
			p->bankrupt_timeout = 4440;
 
			ShowBuyCompanyDialog(_current_player);
 
			return;
 
		}
 
		if (IS_HUMAN_PLAYER(best_pl->index)) return;
 
		if (IsHumanPlayer(best_pl->index)) return;
 

	
 
		// Too little money for computer to buy it?
 
		if (best_pl->player_money >> 1 >= p->bankrupt_value) {
 
			// Computer wants to buy it.
 
			old_p = _current_player;
 
			_current_player = p->index;
 
			DoCommand(0, old_p, 0, DC_EXEC, CMD_BUY_COMPANY);
 
			_current_player = old_p;
 
		}
 
	}
 
}
 

	
 
static void AiAdjustLoan(const Player* p)
 
{
 
	int32 base = AiGetBasePrice(p);
 

	
 
	if (p->player_money > base * 1400) {
 
		// Decrease loan
 
		if (p->current_loan != 0) {
 
			DoCommand(0, 0, 0, DC_EXEC, CMD_DECREASE_LOAN);
 
		}
 
	} else if (p->player_money < base * 500) {
 
		// Increase loan
 
		if (p->current_loan < _economy.max_loan &&
 
@@ -3845,49 +3845,49 @@ static void AiBuildCompanyHQ(Player *p)
 
{
 
	TileIndex tile;
 

	
 
	if (p->location_of_house == 0 &&
 
			p->last_build_coordinate != 0) {
 
		tile = AdjustTileCoordRandomly(p->last_build_coordinate, 8);
 
		DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ);
 
	}
 
}
 

	
 

	
 
void AiDoGameLoop(Player *p)
 
{
 
	if (p->bankrupt_asked != 0) {
 
		AiHandleTakeover(p);
 
		return;
 
	}
 

	
 
	// Ugly hack to make sure the service interval of the AI is good, not looking
 
	//  to the patch-setting
 
	// Also, it takes into account the setting if the service-interval is in days
 
	//  or in %
 
	_ai_service_interval = _patches.servint_ispercent?80:180;
 

	
 
	if (IS_HUMAN_PLAYER(_current_player)) return;
 
	if (IsHumanPlayer(_current_player)) return;
 

	
 
	AiAdjustLoan(p);
 
	AiBuildCompanyHQ(p);
 

	
 
#if 0
 
	{
 
		static byte old_state = 99;
 
		static bool hasdots = false;
 
		char *_ai_state_names[]={
 
			"AiCase0",
 
			"AiCase1",
 
			"AiStateVehLoop",
 
			"AiStateCheckReplaceVehicle",
 
			"AiStateDoReplaceVehicle",
 
			"AiStateWantNewRoute",
 
			"AiStateBuildDefaultRailBlocks",
 
			"AiStateBuildRail",
 
			"AiStateBuildRailVeh",
 
			"AiStateDeleteRailBlocks",
 
			"AiStateBuildDefaultRoadBlocks",
 
			"AiStateBuildRoad",
 
			"AiStateBuildRoadVehicles",
 
			"AiStateDeleteRoadBlocks",
 
			"AiStateAirportStuff",
aircraft_cmd.c
Show inline comments
 
@@ -606,49 +606,49 @@ int32 CmdRefitAircraft(TileIndex tile, u
 
	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
 
		/* Back up the existing cargo type */
 
		CargoID temp_cid = v->cargo_type;
 
		byte temp_subtype = v->cargo_subtype;
 
		v->cargo_type = new_cid;
 
		v->cargo_subtype = new_subtype;
 

	
 
		callback = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
 

	
 
		/* Restore the cargo type */
 
		v->cargo_type = temp_cid;
 
		v->cargo_subtype = temp_subtype;
 
	}
 

	
 
	if (callback == CALLBACK_FAILED) {
 
		/* If the callback failed, or wasn't executed, use the aircraft's
 
		 * default cargo capacity */
 
		pass = AircraftDefaultCargoCapacity(new_cid, v->engine_type);
 
	} else {
 
		pass = callback;
 
	}
 
	_returned_refit_capacity = pass;
 

	
 
	cost = 0;
 
	if (IS_HUMAN_PLAYER(v->owner) && new_cid != v->cargo_type) {
 
	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
 
		cost = GetRefitCost(v->engine_type);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		Vehicle *u;
 
		v->cargo_cap = pass;
 

	
 
		u = v->next;
 
		mail = (new_cid != CT_PASSENGERS) ? 0 : avi->mail_capacity;
 
		u->cargo_cap = mail;
 
		if (v->cargo_type == new_cid) {
 
			v->cargo_count = min(pass, v->cargo_count);
 
			u->cargo_count = min(mail, u->cargo_count);
 
		} else {
 
			v->cargo_count = 0;
 
			u->cargo_count = 0;
 
		}
 
		v->cargo_type = new_cid;
 
		v->cargo_subtype = new_subtype;
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		RebuildVehicleLists();
 
	}
 

	
disaster_cmd.c
Show inline comments
 
@@ -7,49 +7,49 @@
 
#include "station_map.h"
 
#include "table/strings.h"
 
#include "map.h"
 
#include "tile.h"
 
#include "vehicle.h"
 
#include "command.h"
 
#include "news.h"
 
#include "station.h"
 
#include "waypoint.h"
 
#include "town.h"
 
#include "industry.h"
 
#include "player.h"
 
#include "airport.h"
 
#include "sound.h"
 
#include "variables.h"
 
#include "table/sprites.h"
 
#include "date.h"
 

	
 
static void DisasterClearSquare(TileIndex tile)
 
{
 
	if (!EnsureNoVehicle(tile)) return;
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_RAILWAY:
 
			if (IS_HUMAN_PLAYER(GetTileOwner(tile)) && !IsRailWaypoint(tile)) {
 
			if (IsHumanPlayer(GetTileOwner(tile)) && !IsRailWaypoint(tile)) {
 
				PlayerID p = _current_player;
 
				_current_player = OWNER_WATER;
 
				DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
				_current_player = p;
 
			}
 
			break;
 

	
 
		case MP_HOUSE: {
 
			PlayerID p = _current_player;
 
			_current_player = OWNER_NONE;
 
			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
			_current_player = p;
 
			break;
 
		}
 

	
 
		case MP_TREES:
 
		case MP_CLEAR:
 
			DoClearSquare(tile);
 
			break;
 

	
 
		default:
 
			break;
 
	}
 
}
 
@@ -167,150 +167,150 @@ static void DisasterTick_Zeppeliner(Vehi
 

	
 
	if (v->current_order.dest < 2) {
 
		if (v->tick_counter&1)
 
			return;
 

	
 
		GetNewVehiclePos(v, &gp);
 

	
 
		SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
 

	
 
		if (v->current_order.dest == 1) {
 
			if (++v->age == 38) {
 
				v->current_order.dest = 2;
 
				v->age = 0;
 
			}
 

	
 
			if ((v->tick_counter&7)==0) {
 
				CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE);
 
			}
 
		} else if (v->current_order.dest == 0) {
 
			tile = v->tile; /**/
 

	
 
			if (IsValidTile(tile) &&
 
					IsTileType(tile, MP_STATION) &&
 
					IsAirport(tile) &&
 
					IS_HUMAN_PLAYER(GetTileOwner(tile))) {
 
					IsHumanPlayer(GetTileOwner(tile))) {
 
				v->current_order.dest = 1;
 
				v->age = 0;
 

	
 
				SetDParam(0, GetStationIndex(tile));
 
				AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT,
 
					NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
 
					v->index,
 
					0);
 
			}
 
		}
 
		if (v->y_pos >= ((int)MapSizeY() + 9) * TILE_SIZE - 1)
 
			DeleteDisasterVeh(v);
 
		return;
 
	}
 

	
 
	if (v->current_order.dest > 2) {
 
		if (++v->age <= 13320)
 
			return;
 

	
 
		tile = v->tile; /**/
 

	
 
		if (IsValidTile(tile) &&
 
				IsTileType(tile, MP_STATION) &&
 
				IsAirport(tile) &&
 
				IS_HUMAN_PLAYER(GetTileOwner(tile))) {
 
				IsHumanPlayer(GetTileOwner(tile))) {
 
			st = GetStationByTile(tile);
 
			CLRBITS(st->airport_flags, RUNWAY_IN_block);
 
		}
 

	
 
		SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos);
 
		DeleteDisasterVeh(v);
 
		return;
 
	}
 

	
 
	x = v->x_pos;
 
	y = v->y_pos;
 
	z = GetSlopeZ(x,y);
 
	if (z < v->z_pos)
 
		z = v->z_pos - 1;
 
	SetDisasterVehiclePos(v, x, y, z);
 

	
 
	if (++v->age == 1) {
 
		CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
 
		SndPlayVehicleFx(SND_12_EXPLOSION, v);
 
		v->u.disaster.image_override = SPR_BLIMP_CRASHING;
 
	} else if (v->age == 70) {
 
		v->u.disaster.image_override = SPR_BLIMP_CRASHED;
 
	} else if (v->age <= 300) {
 
		if (!(v->tick_counter&7)) {
 
			uint32 r = Random();
 

	
 
			CreateEffectVehicleRel(v,
 
				GB(r, 0, 4) - 7,
 
				GB(r, 4, 4) - 7,
 
				GB(r, 8, 3) + 5,
 
				EV_EXPLOSION_SMALL);
 
		}
 
	} else if (v->age == 350) {
 
		v->current_order.dest = 3;
 
		v->age = 0;
 
	}
 

	
 
	tile = v->tile;/**/
 
	if (IsValidTile(tile) &&
 
			IsTileType(tile, MP_STATION) &&
 
			IsAirport(tile) &&
 
			IS_HUMAN_PLAYER(GetTileOwner(tile))) {
 
			IsHumanPlayer(GetTileOwner(tile))) {
 
		st = GetStationByTile(tile);
 
		SETBITS(st->airport_flags, RUNWAY_IN_block);
 
	}
 
}
 

	
 
// UFO starts in the middle, and flies around a bit until it locates
 
// a road vehicle which it targets.
 
static void DisasterTick_UFO(Vehicle *v)
 
{
 
	GetNewVehiclePosResult gp;
 
	Vehicle *u;
 
	uint dist;
 
	byte z;
 

	
 
	v->u.disaster.image_override = (++v->tick_counter & 8) ? SPR_UFO_SMALL_SCOUT_DARKER : SPR_UFO_SMALL_SCOUT;
 

	
 
	if (v->current_order.dest == 0) {
 
// fly around randomly
 
		int x = TileX(v->dest_tile) * TILE_SIZE;
 
		int y = TileY(v->dest_tile) * TILE_SIZE;
 
		if (abs(x - v->x_pos) + abs(y - v->y_pos) >= TILE_SIZE) {
 
			v->direction = GetDirectionTowards(v, x, y);
 
			GetNewVehiclePos(v, &gp);
 
			SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
 
			return;
 
		}
 
		if (++v->age < 6) {
 
			v->dest_tile = RandomTile();
 
			return;
 
		}
 
		v->current_order.dest = 1;
 

	
 
		FOR_ALL_VEHICLES(u) {
 
			if (u->type == VEH_Road && IS_HUMAN_PLAYER(u->owner)) {
 
			if (u->type == VEH_Road && IsHumanPlayer(u->owner)) {
 
				v->dest_tile = u->index;
 
				v->age = 0;
 
				return;
 
			}
 
		}
 

	
 
		DeleteDisasterVeh(v);
 
	} else {
 
// target a vehicle
 
		u = GetVehicle(v->dest_tile);
 
		if (u->type != VEH_Road) {
 
			DeleteDisasterVeh(v);
 
			return;
 
		}
 

	
 
		dist = abs(v->x_pos - u->x_pos) + abs(v->y_pos - u->y_pos);
 

	
 
		if (dist < TILE_SIZE && !(u->vehstatus&VS_HIDDEN) && u->breakdown_ctr==0) {
 
			u->breakdown_ctr = 3;
 
			u->breakdown_delay = 140;
 
		}
 

	
 
		v->direction = GetDirectionTowards(v, u->x_pos, u->y_pos);
 
		GetNewVehiclePos(v, &gp);
 
@@ -574,49 +574,49 @@ static void DisasterTick_4(Vehicle *v)
 
		u->next = w;
 
		InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, 12);
 
		w->vehstatus |= VS_SHADOW;
 
	} else if (v->current_order.dest < 1) {
 

	
 
		int x = TileX(v->dest_tile) * TILE_SIZE;
 
		int y = TileY(v->dest_tile) * TILE_SIZE;
 
		if (abs(x - v->x_pos) + abs(y - v->y_pos) >= TILE_SIZE) {
 
			v->direction = GetDirectionTowards(v, x, y);
 
			GetNewVehiclePos(v, &gp);
 
			SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
 
			return;
 
		}
 

	
 
		if (++v->age < 6) {
 
			v->dest_tile = RandomTile();
 
			return;
 
		}
 
		v->current_order.dest = 1;
 

	
 
		tile_org = tile = RandomTile();
 
		do {
 
			if (IsTileType(tile, MP_RAILWAY) &&
 
					IsPlainRailTile(tile) &&
 
					IS_HUMAN_PLAYER(GetTileOwner(tile))) {
 
					IsHumanPlayer(GetTileOwner(tile))) {
 
				break;
 
			}
 
			tile = TILE_MASK(tile+1);
 
		} while (tile != tile_org);
 
		v->dest_tile = tile;
 
		v->age = 0;
 
	} else {
 
		return;
 
	}
 
}
 

	
 
// The plane which will shoot down the UFO
 
static void DisasterTick_4b(Vehicle *v)
 
{
 
	GetNewVehiclePosResult gp;
 
	Vehicle *u;
 
	int i;
 

	
 
	v->tick_counter++;
 

	
 
	GetNewVehiclePos(v, &gp);
 
	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
 

	
 
	if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
 
@@ -705,49 +705,49 @@ void DisasterVehicle_Tick(Vehicle *v)
 

	
 

	
 
void OnNewDay_DisasterVehicle(Vehicle *v)
 
{
 
	// not used
 
}
 

	
 
typedef void DisasterInitProc(void);
 

	
 
// Zeppeliner which crashes on a small airport
 
static void Disaster0_Init(void)
 
{
 
	Vehicle *v = ForceAllocateSpecialVehicle(), *u;
 
	Station *st;
 
	int x;
 

	
 
	if (v == NULL) return;
 

	
 
	/* Pick a random place, unless we find a small airport */
 
	x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
 

	
 
	FOR_ALL_STATIONS(st) {
 
		if (st->airport_tile != 0 &&
 
				st->airport_type <= 1 &&
 
				IS_HUMAN_PLAYER(st->owner)) {
 
				IsHumanPlayer(st->owner)) {
 
			x = (TileX(st->xy) + 2) * TILE_SIZE;
 
			break;
 
		}
 
	}
 

	
 
	InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, 0);
 

	
 
	// Allocate shadow too?
 
	u = ForceAllocateSpecialVehicle();
 
	if (u != NULL) {
 
		v->next = u;
 
		InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, 1);
 
		u->vehstatus |= VS_SHADOW;
 
	}
 
}
 

	
 
static void Disaster1_Init(void)
 
{
 
	Vehicle *v = ForceAllocateSpecialVehicle(), *u;
 
	int x;
 

	
 
	if (v == NULL) return;
 

	
 
	x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
economy.c
Show inline comments
 
@@ -367,110 +367,110 @@ void ChangeOwnershipOfPlayerItems(Player
 

	
 
static void PlayersCheckBankrupt(Player *p)
 
{
 
	PlayerID owner;
 
	int64 val;
 

	
 
	// If the player has money again, it does not go bankrupt
 
	if (p->player_money >= 0) {
 
		p->quarters_of_bankrupcy = 0;
 
		return;
 
	}
 

	
 
	p->quarters_of_bankrupcy++;
 

	
 
	owner = p->index;
 

	
 
	switch (p->quarters_of_bankrupcy) {
 
		case 2:
 
			AddNewsItem( (StringID)(owner + 16),
 
				NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
 
			break;
 
		case 3: {
 
			/* XXX - In multiplayer, should we ask other players if it wants to take
 
		          over when it is a human company? -- TrueLight */
 
			if (IS_HUMAN_PLAYER(owner)) {
 
			if (IsHumanPlayer(owner)) {
 
				AddNewsItem( (StringID)(owner + 16),
 
					NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
 
				break;
 
			}
 

	
 
			// Check if the company has any value.. if not, declare it bankrupt
 
			//  right now
 
			val = CalculateCompanyValue(p);
 
			if (val > 0) {
 
				p->bankrupt_value = val;
 
				p->bankrupt_asked = 1 << owner; // Don't ask the owner
 
				p->bankrupt_timeout = 0;
 
				break;
 
			}
 
			// Else, falltrue to case 4...
 
		}
 
		case 4: {
 
			// Close everything the owner has open
 
			DeletePlayerWindows(owner);
 

	
 
//		Show bankrupt news
 
			SetDParam(0, p->name_1);
 
			SetDParam(1, p->name_2);
 
			AddNewsItem( (StringID)(owner + 16*3), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
 

	
 
			// If the player is human, and it is no network play, leave the player playing
 
			if (IS_HUMAN_PLAYER(owner) && !_networking) {
 
			if (IsHumanPlayer(owner) && !_networking) {
 
				p->bankrupt_asked = 255;
 
				p->bankrupt_timeout = 0x456;
 
			} else {
 
#ifdef ENABLE_NETWORK
 
				if (IS_HUMAN_PLAYER(owner) && _network_server) {
 
				if (IsHumanPlayer(owner) && _network_server) {
 
					// If we are the server, make sure it is clear that his player is no
 
					//  longer with us!
 
					NetworkClientInfo *ci;
 
					NetworkClientState *cs;
 
					/* Find all clients that were in control of this company */
 
					FOR_ALL_CLIENTS(cs) {
 
						ci = DEREF_CLIENT_INFO(cs);
 
						if ((ci->client_playas-1) == owner) {
 
							ci->client_playas = OWNER_SPECTATOR;
 
							// Send the new info to all the clients
 
							NetworkUpdateClientInfo(_network_own_client_index);
 
						}
 
					}
 
				}
 
				// Make sure the player no longer controls the company
 
				if (IS_HUMAN_PLAYER(owner) && owner == _local_player) {
 
				if (IsHumanPlayer(owner) && owner == _local_player) {
 
					// Switch the player to spectator..
 
					_local_player = OWNER_SPECTATOR;
 
				}
 
#endif /* ENABLE_NETWORK */
 

	
 
				/* Remove the player */
 
				ChangeOwnershipOfPlayerItems(owner, OWNER_SPECTATOR);
 
				// Register the player as not-active
 
				p->is_active = false;
 

	
 
				if (!IS_HUMAN_PLAYER(owner) && (!_networking || _network_server) && _ai.enabled)
 
				if (!IsHumanPlayer(owner) && (!_networking || _network_server) && _ai.enabled)
 
					AI_PlayerDied(owner);
 
				if (IS_HUMAN_PLAYER(owner) && owner == _local_player && _ai.network_client)
 
				if (IsHumanPlayer(owner) && owner == _local_player && _ai.network_client)
 
					AI_PlayerDied(owner);
 
			}
 
		}
 
	}
 
}
 

	
 
void DrawNewsBankrupcy(Window *w)
 
{
 
	Player *p;
 

	
 
	DrawNewsBorder(w);
 

	
 
	p = GetPlayer(WP(w,news_d).ni->string_id & 15);
 
	DrawPlayerFace(p->face, p->player_color, 2, 23);
 
	GfxFillRect(3, 23, 3+91, 23+118, 0x323 | USE_COLORTABLE);
 

	
 
	SetDParam(0, p->president_name_1);
 
	SetDParam(1, p->president_name_2);
 

	
 
	DrawStringMultiCenter(49, 148, STR_7058_PRESIDENT, 94);
 

	
 
	switch (WP(w,news_d).ni->string_id >> 4) {
 
	case 1:
 
		DrawStringCentered(w->width>>1, 1, STR_7056_TRANSPORT_COMPANY_IN_TROUBLE, 0);
engine.c
Show inline comments
 
@@ -247,55 +247,55 @@ static PlayerID GetBestPlayer(PlayerID p
 
void EnginesDailyLoop(void)
 
{
 
	EngineID i;
 

	
 
	if (_cur_year >= YEAR_ENGINE_AGING_STOPS) return;
 

	
 
	for (i = 0; i != lengthof(_engines); i++) {
 
		Engine *e = &_engines[i];
 

	
 
		if (e->flags & ENGINE_INTRODUCING) {
 
			if (e->flags & ENGINE_PREVIEWING) {
 
				if (e->preview_player != 0xFF && !--e->preview_wait) {
 
					e->flags &= ~ENGINE_PREVIEWING;
 
					DeleteWindowById(WC_ENGINE_PREVIEW, i);
 
					e->preview_player++;
 
				}
 
			} else if (e->preview_player != 0xFF) {
 
				PlayerID best_player = GetBestPlayer(e->preview_player);
 

	
 
				if (best_player == OWNER_SPECTATOR) {
 
					e->preview_player = 0xFF;
 
					continue;
 
				}
 

	
 
				if (!IS_HUMAN_PLAYER(best_player)) {
 
				if (!IsHumanPlayer(best_player)) {
 
					/* XXX - TTDBUG: TTD has a bug here ???? */
 
					AcceptEnginePreview(e, best_player);
 
				} else {
 
					e->flags |= ENGINE_PREVIEWING;
 
					e->preview_wait = 20;
 
					if (IS_INTERACTIVE_PLAYER(best_player)) ShowEnginePreviewWindow(i);
 
					if (IsInteractivePlayer(best_player)) ShowEnginePreviewWindow(i);
 
				}
 
			}
 
		}
 
	}
 
}
 

	
 
/** Accept an engine prototype. XXX - it is possible that the top-player
 
 * changes while you are waiting to accept the offer? Then it becomes invalid
 
 * @param tile unused
 
 * @param p1 engine-prototype offered
 
 * @param p2 unused
 
 */
 
int32 CmdWantEnginePreview(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Engine *e;
 

	
 
	if (!IsEngineIndex(p1)) return CMD_ERROR;
 
	e = GetEngine(p1);
 
	if (GetBestPlayer(e->preview_player) != _current_player) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) AcceptEnginePreview(e, _current_player);
 

	
 
	return 0;
 
}
misc_cmd.c
Show inline comments
 
@@ -105,83 +105,83 @@ int32 CmdSetPlayerColor(TileIndex tile, 
 
		}
 
		MarkWholeScreenDirty();
 
	}
 
	return 0;
 
}
 

	
 
/** Increase the loan of your company.
 
 * @param tile unused
 
 * @param p1 unused
 
 * @param p2 when set, loans the maximum amount in one go (press CTRL)
 
 */
 
int32 CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p;
 

	
 
	p = GetPlayer(_current_player);
 

	
 
	if (p->current_loan >= _economy.max_loan) {
 
		SetDParam(0, _economy.max_loan);
 
		return_cmd_error(STR_702B_MAXIMUM_PERMITTED_LOAN);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		/* Loan the maximum amount or not? */
 
		int32 loan = (p2) ? _economy.max_loan - p->current_loan : (IS_HUMAN_PLAYER(_current_player) || _patches.ainew_active) ? 10000 : 50000;
 
		int32 loan = (p2) ? _economy.max_loan - p->current_loan : (IsHumanPlayer(_current_player) || _patches.ainew_active) ? 10000 : 50000;
 

	
 
		p->money64 += loan;
 
		p->current_loan += loan;
 
		UpdatePlayerMoney32(p);
 
		InvalidatePlayerWindows(p);
 
	}
 

	
 
	return 0;
 
}
 

	
 
/** Decrease the loan of your company.
 
 * @param tile unused
 
 * @param p1 unused
 
 * @param p2 when set, pays back the maximum loan permitting money (press CTRL)
 
 */
 
int32 CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p;
 
	int32 loan;
 

	
 
	p = GetPlayer(_current_player);
 

	
 
	if (p->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED);
 

	
 
	loan = p->current_loan;
 

	
 
	/* p2 is true while CTRL is pressed (repay all possible loan, or max money you have)
 
	 * Repay any loan in chunks of 10.000 pounds */
 
	if (p2) {
 
		loan = min(loan, p->player_money);
 
		loan = max(loan, 10000);
 
		loan -= loan % 10000;
 
	} else {
 
		loan = min(loan, (IS_HUMAN_PLAYER(_current_player) || _patches.ainew_active) ? 10000 : 50000);
 
		loan = min(loan, (IsHumanPlayer(_current_player) || _patches.ainew_active) ? 10000 : 50000);
 
	}
 

	
 
	if (p->player_money < loan) {
 
		SetDParam(0, loan);
 
		return_cmd_error(STR_702E_REQUIRED);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		p->money64 -= loan;
 
		p->current_loan -= loan;
 
		UpdatePlayerMoney32(p);
 
		InvalidatePlayerWindows(p);
 
	}
 
	return 0;
 
}
 

	
 
/** Change the name of the company.
 
 * @param tile unused
 
 * @param p1 unused
 
 * @param p2 unused
 
 */
 
int32 CmdChangeCompanyName(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	StringID str;
oldloader.c
Show inline comments
 
@@ -976,49 +976,49 @@ static bool LoadOldPlayer(LoadgameState 
 
			p->name_1 = STR_SV_UNNAMED;
 
	} else {
 
		/* Beside some multiplayer maps (1 on 1), which we don't official support,
 
		all other players are an AI.. mark them as such */
 
		p->is_ai = true;
 
	}
 

	
 
	/* Sometimes it is better to not ask.. in old scenarios, the money
 
	was always 893288 pounds. In the newer versions this is correct,
 
	but correct for those oldies
 
	Ps: this also means that if you had exact 893288 pounds, you will go back
 
	to 10000.. this is a very VERY small chance ;) */
 
	if (p->player_money == 893288)
 
		p->money64 = p->player_money = p->current_loan = 100000;
 

	
 
	_player_colors[num] = p->player_color;
 
	p->inaugurated_year = _old_inaugurated_year;
 
	if (p->location_of_house == 0xFFFF)
 
		p->location_of_house = 0;
 

	
 
	/* State 20 for AI players is sell vehicle. Since the AI struct is not
 
	 * really figured out as of now, p->ai.cur_veh; needed for 'sell vehicle'
 
	 * is NULL and the function will crash. To fix this, just change the state
 
	 * to some harmless state, like 'loop vehicle'; 1 */
 
	if (!IS_HUMAN_PLAYER(num) && p->ai.state == 20) p->ai.state = 1;
 
	if (!IsHumanPlayer(num) && p->ai.state == 20) p->ai.state = 1;
 

	
 
	if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
 
		AI_StartNewAI(p->index);
 

	
 
	return true;
 
}
 

	
 
static uint32 _old_order_ptr;
 
static uint16 _old_next_ptr;
 
static uint32 _current_vehicle_id;
 

	
 
static const OldChunks vehicle_train_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, VehicleRail, track ),
 
	OCL_SVAR(  OC_UINT8, VehicleRail, force_proceed ),
 
	OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
 
	OCL_SVAR(  OC_UINT8, VehicleRail, railtype ),
 

	
 
	OCL_NULL( 5 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static const OldChunks vehicle_road_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, VehicleRoad, state ),
order_cmd.c
Show inline comments
 
@@ -331,49 +331,49 @@ int32 CmdInsertOrder(TileIndex tile, uin
 
				case 0: break;
 

	
 
				case OF_NON_STOP:
 
					if (v->type != VEH_Train) return CMD_ERROR;
 
					break;
 

	
 
				default: return CMD_ERROR;
 
			}
 
			break;
 
		}
 

	
 
		default: return CMD_ERROR;
 
	}
 

	
 
	if (sel_ord > v->num_orders) return CMD_ERROR;
 

	
 
	if (IsOrderPoolFull()) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
 

	
 
	/* XXX - This limit is only here because the backuppedorders can't
 
	 * handle any more then this.. */
 
	if (v->num_orders >= MAX_BACKUP_ORDER_COUNT) return_cmd_error(STR_8832_TOO_MANY_ORDERS);
 

	
 
	/* For ships, make sure that the station is not too far away from the
 
	 * previous destination, for human players with new pathfinding disabled */
 
	if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) &&
 
	if (v->type == VEH_Ship && IsHumanPlayer(v->owner) &&
 
		sel_ord != 0 && GetVehicleOrder(v, sel_ord - 1)->type == OT_GOTO_STATION
 
		&& !_patches.new_pathfinding_all) {
 

	
 
		int dist = DistanceManhattan(
 
			GetStation(GetVehicleOrder(v, sel_ord - 1)->dest)->xy,
 
			GetStation(new_order.dest)->xy // XXX type != OT_GOTO_STATION?
 
		);
 
		if (dist >= 130)
 
			return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		Vehicle *u;
 
		Order *new = AllocateOrder();
 
		AssignOrder(new, new_order);
 

	
 
		/* Create new order and link in list */
 
		if (v->orders == NULL) {
 
			v->orders = new;
 
		} else {
 
			/* Try to get the previous item (we are inserting above the
 
			    selected) */
 
			Order *order = GetVehicleOrder(v, sel_ord - 1);
 

	
player.h
Show inline comments
 
@@ -227,68 +227,75 @@ static inline byte ActivePlayerCount(voi
 

	
 
	return count;
 
}
 

	
 
static inline Player* GetPlayer(PlayerID i)
 
{
 
	assert(i < lengthof(_players));
 
	return &_players[i];
 
}
 

	
 
static inline bool IsLocalPlayer(void)
 
{
 
	return _local_player == _current_player;
 
}
 

	
 
void DeletePlayerWindows(PlayerID pi);
 
byte GetPlayerRailtypes(PlayerID p);
 

	
 
/** Finds out if a Player has a certain railtype available */
 
static inline bool HasRailtypeAvail(const Player *p, RailType Railtype)
 
{
 
	return HASBIT(p->avail_railtypes, Railtype);
 
}
 

	
 
static inline bool IsHumanPlayer(PlayerID pi)
 
{
 
	return !GetPlayer(pi)->is_ai;
 
}
 

	
 
static inline bool IsInteractivePlayer(PlayerID pi)
 
{
 
	return pi == _local_player;
 
}
 

	
 
/* Validate functions for rail building */
 
static inline bool ValParamRailtype(uint32 rail) { return HASBIT(GetPlayer(_current_player)->avail_railtypes, rail);}
 

	
 
/** Returns the "best" railtype a player can build.
 
 * As the AI doesn't know what the BEST one is, we have our own priority list
 
 * here. When adding new railtypes, modify this function
 
 * @param p the player "in action"
 
 * @return The "best" railtype a player has available
 
 */
 
static inline RailType GetBestRailtype(const Player* p)
 
{
 
	if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV;
 
	if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO;
 
	if (HasRailtypeAvail(p, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC;
 
	return RAILTYPE_RAIL;
 
}
 

	
 
#define IS_HUMAN_PLAYER(p) (!GetPlayer(p)->is_ai)
 
#define IS_INTERACTIVE_PLAYER(p) ((p) == _local_player)
 

	
 
typedef struct HighScore {
 
	char company[100];
 
	StringID title; // NO_SAVE, has troubles with changing string-numbers.
 
	uint16 score;   // do NOT change type, will break hs.dat
 
} HighScore;
 

	
 
VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5
 
void SaveToHighScore(void);
 
void LoadFromHighScore(void);
 
int8 SaveHighScoreValue(const Player *p);
 
int8 SaveHighScoreValueNetwork(void);
 

	
 
/* Engine Replacement Functions */
 

	
 
/**
 
 * Remove all engine replacement settings for the given player.
 
 * @param p Player.
 
 */
 
static inline void RemoveAllEngineReplacementForPlayer(Player *p) { RemoveAllEngineReplacement(&p->engine_renew_list); }
 

	
 
/**
 
 * Retrieve the engine replacement for the given player and original engine type.
 
 * @param p Player.
 
 * @param engine Engine type.
players.c
Show inline comments
 
@@ -320,49 +320,49 @@ static void GenerateCompanyName(Player *
 
	if (tile == 0) return;
 

	
 
	t = ClosestTownFromTile(tile, (uint)-1);
 

	
 
	if (IS_INT_INSIDE(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST+1)) {
 
		str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
 
		strp = t->townnameparts;
 

	
 
verify_name:;
 
		// No player must have this name already
 
		FOR_ALL_PLAYERS(pp) {
 
			if (pp->name_1 == str && pp->name_2 == strp) goto bad_town_name;
 
		}
 

	
 
		GetString(buffer, str);
 
		if (strlen(buffer) >= 32 || GetStringBoundingBox(buffer).width >= 150)
 
			goto bad_town_name;
 

	
 
set_name:;
 
		p->name_1 = str;
 
		p->name_2 = strp;
 

	
 
		MarkWholeScreenDirty();
 

	
 
		if (!IS_HUMAN_PLAYER(p->index)) {
 
		if (!IsHumanPlayer(p->index)) {
 
			SetDParam(0, t->index);
 
			AddNewsItem(p->index + (4 << 4), NEWS_FLAGS(NM_CALLBACK, NF_TILE, NT_COMPANY_INFO, DNC_BANKRUPCY), p->last_build_coordinate, 0);
 
		}
 
		return;
 
	}
 
bad_town_name:;
 

	
 
	if (p->president_name_1 == SPECSTR_PRESIDENT_NAME) {
 
		str = SPECSTR_ANDCO_NAME;
 
		strp = p->president_name_2;
 
		goto set_name;
 
	} else {
 
		str = SPECSTR_ANDCO_NAME;
 
		strp = Random();
 
		goto verify_name;
 
	}
 
}
 

	
 
#define COLOR_SWAP(i,j) do { byte t=colors[i];colors[i]=colors[j];colors[j]=t; } while(0)
 

	
 
static const byte _color_sort[16] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
 
static const byte _color_similar_1[16] = {8, 6, 255, 12,  255, 0, 1, 1, 0, 13,  11,  10, 3,   9,  15, 14};
 
static const byte _color_similar_2[16] = {5, 7, 255, 255, 255, 8, 7, 6, 5, 12, 255, 255, 9, 255, 255, 255};
 

	
 
@@ -563,49 +563,49 @@ void InitializePlayers(void)
 
	uint i;
 

	
 
	memset(_players, 0, sizeof(_players));
 
	for (i = 0; i != MAX_PLAYERS; i++) _players[i].index = i;
 
	_cur_player_tick_index = 0;
 
}
 

	
 
void OnTick_Players(void)
 
{
 
	Player *p;
 

	
 
	if (_game_mode == GM_EDITOR) return;
 

	
 
	p = GetPlayer(_cur_player_tick_index);
 
	_cur_player_tick_index = (_cur_player_tick_index + 1) % MAX_PLAYERS;
 
	if (p->name_1 != 0) GenerateCompanyName(p);
 

	
 
	if (AI_AllowNewAI() && _game_mode != GM_MENU && !--_next_competitor_start)
 
		MaybeStartNewPlayer();
 
}
 

	
 
// index is the next parameter in _decode_parameters to set up
 
StringID GetPlayerNameString(PlayerID player, uint index)
 
{
 
	if (IS_HUMAN_PLAYER(player) && player < MAX_PLAYERS) {
 
	if (IsHumanPlayer(player) && player < MAX_PLAYERS) {
 
		SetDParam(index, player+1);
 
		return STR_7002_PLAYER;
 
	}
 
	return STR_EMPTY;
 
}
 

	
 
extern void ShowPlayerFinances(int player);
 

	
 
void PlayersYearlyLoop(void)
 
{
 
	Player *p;
 

	
 
	// Copy statistics
 
	FOR_ALL_PLAYERS(p) {
 
		if (p->is_active) {
 
			memmove(&p->yearly_expenses[1], &p->yearly_expenses[0], sizeof(p->yearly_expenses) - sizeof(p->yearly_expenses[0]));
 
			memset(&p->yearly_expenses[0], 0, sizeof(p->yearly_expenses[0]));
 
			InvalidateWindow(WC_FINANCES, p->index);
 
		}
 
	}
 

	
 
	if (_patches.show_finances && _local_player != OWNER_SPECTATOR) {
 
		ShowPlayerFinances(_local_player);
 
		p = GetPlayer(_local_player);
 
@@ -896,49 +896,49 @@ int32 CmdPlayerCtrl(TileIndex tile, uint
 
			 * DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
 
			NetworkClientInfo *ci = &_network_client_info[pid];
 
			ci->client_playas = OWNER_SPECTATOR;
 
			NetworkUpdateClientInfo(ci->client_index);
 
#endif /* ENABLE_NETWORK */
 
		}
 
	} break;
 

	
 
	case 1: /* Make a new AI player */
 
		if (!(flags & DC_EXEC)) return 0;
 

	
 
		DoStartupNewPlayer(true);
 
		break;
 

	
 
	case 2: { /* Delete a player */
 
		Player *p;
 

	
 
		if (p2 >= MAX_PLAYERS) return CMD_ERROR;
 

	
 
		if (!(flags & DC_EXEC)) return 0;
 

	
 
		p = GetPlayer(p2);
 

	
 
		/* Only allow removal of HUMAN companies */
 
		if (IS_HUMAN_PLAYER(p->index)) {
 
		if (IsHumanPlayer(p->index)) {
 
			/* Delete any open window of the company */
 
			DeletePlayerWindows(p->index);
 

	
 
			/* Show the bankrupt news */
 
			SetDParam(0, p->name_1);
 
			SetDParam(1, p->name_2);
 
			AddNewsItem( (StringID)(p->index + 16*3), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
 

	
 
			/* Remove the company */
 
			ChangeOwnershipOfPlayerItems(p->index, OWNER_SPECTATOR);
 
			p->is_active = false;
 
		}
 
		RemoveAllEngineReplacementForPlayer(p);
 

	
 
	} break;
 

	
 
	case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */
 
		PlayerID pid_old = GB(p2,  0, 16);
 
		PlayerID pid_new = GB(p2, 16, 16);
 

	
 
		if (pid_old >= MAX_PLAYERS || pid_new >= MAX_PLAYERS) return CMD_ERROR;
 

	
 
		if (!(flags & DC_EXEC)) return CMD_ERROR;
 

	
 
@@ -1247,49 +1247,49 @@ static const SaveLoad _player_ai_build_r
 
	    SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, unk6,              SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, unk7,              SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, buildcmd_a,        SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, buildcmd_b,        SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, direction,         SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, cargo,             SLE_UINT8),
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _player_livery_desc[] = {
 
	SLE_CONDVAR(Livery, in_use,  SLE_BOOL,  34, SL_MAX_VERSION),
 
	SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
 
	SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
 
	SLE_END()
 
};
 

	
 
static void SaveLoad_PLYR(Player* p)
 
{
 
	int i;
 

	
 
	SlObject(p, _player_desc);
 

	
 
	// Write AI?
 
	if (!IS_HUMAN_PLAYER(p->index)) {
 
	if (!IsHumanPlayer(p->index)) {
 
		SlObject(&p->ai, _player_ai_desc);
 
		for (i = 0; i != p->ai.num_build_rec; i++) {
 
			SlObject(&p->ai.src + i, _player_ai_build_rec_desc);
 
		}
 
	}
 

	
 
	// Write economy
 
	SlObject(&p->cur_economy, _player_economy_desc);
 

	
 
	// Write old economy entries.
 
	for (i = 0; i < p->num_valid_stat_ent; i++) {
 
		SlObject(&p->old_economy[i], _player_economy_desc);
 
	}
 

	
 
	// Write each livery entry.
 
	for (i = 0; i < LS_END; i++) {
 
		SlObject(&p->livery[i], _player_livery_desc);
 
	}
 
}
 

	
 
static void Save_PLYR(void)
 
{
 
	Player *p;
 
	FOR_ALL_PLAYERS(p) {
roadveh_cmd.c
Show inline comments
 
@@ -1783,40 +1783,40 @@ int32 CmdRefitRoadVeh(TileIndex tile, ui
 
		const RoadVehicleInfo *rvi = RoadVehInfo(v->engine_type);
 

	
 
		CargoID old_cid = rvi->cargo_type;
 
		/* normally, the capacity depends on the cargo type, a vehicle can
 
		 * carry twice as much mail/goods as normal cargo, and four times as
 
		 * many passengers
 
		 */
 
		capacity = rvi->capacity;
 
		switch (old_cid) {
 
			case CT_PASSENGERS: break;
 
			case CT_MAIL:
 
			case CT_GOODS: capacity *= 2; break;
 
			default:       capacity *= 4; break;
 
		}
 
		switch (new_cid) {
 
			case CT_PASSENGERS: break;
 
			case CT_MAIL:
 
			case CT_GOODS: capacity /= 2; break;
 
			default:       capacity /= 4; break;
 
		}
 
	}
 
	_returned_refit_capacity = capacity;
 

	
 
	cost = 0;
 
	if (IS_HUMAN_PLAYER(v->owner) && new_cid != v->cargo_type) {
 
	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
 
		cost = GetRefitCost(v->engine_type);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		v->cargo_cap = capacity;
 
		v->cargo_count = (v->cargo_type == new_cid) ? min(capacity, v->cargo_count) : 0;
 
		v->cargo_type = new_cid;
 
		v->cargo_subtype = new_subtype;
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		RebuildVehicleLists();
 
	}
 

	
 
	return cost;
 
}
ship_cmd.c
Show inline comments
 
@@ -1068,41 +1068,41 @@ int32 CmdRefitShip(TileIndex tile, uint3
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
 

	
 
	/* Check the refit capacity callback */
 
	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
 
		/* Back up the existing cargo type */
 
		CargoID temp_cid = v->cargo_type;
 
		byte temp_subtype = v->cargo_subtype;
 
		v->cargo_type = new_cid;
 
		v->cargo_subtype = new_subtype;
 

	
 
		capacity = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
 

	
 
		/* Restore the cargo type */
 
		v->cargo_type = temp_cid;
 
		v->cargo_subtype = temp_subtype;
 
	}
 

	
 
	if (capacity == CALLBACK_FAILED) {
 
		capacity = ShipVehInfo(v->engine_type)->capacity;
 
	}
 
	_returned_refit_capacity = capacity;
 

	
 
	cost = 0;
 
	if (IS_HUMAN_PLAYER(v->owner) && new_cid != v->cargo_type) {
 
	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
 
		cost = GetRefitCost(v->engine_type);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		v->cargo_cap = capacity;
 
		v->cargo_count = (v->cargo_type == new_cid) ? min(v->cargo_cap, v->cargo_count) : 0;
 
		v->cargo_type = new_cid;
 
		v->cargo_subtype = new_subtype;
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		RebuildVehicleLists();
 
	}
 

	
 
	return cost;
 

	
 
}
0 comments (0 inline, 0 general)