Changeset - r812:2f2818d6d63d
[Not reviewed]
master
0 10 0
truelight - 19 years ago 2004-12-27 18:18:44
truelight@openttd.org
(svn r1283) -Add: AutoRenew is now a client-side patch instead of a game-side patch
Note: this is the first commit that breaks compatibility with 0.3.5!
-Fix: Bufferoverflow with autorenew_money. It is now a 32-bit integer.
10 files changed with 116 insertions and 71 deletions:
0 comments (0 inline, 0 general)
aircraft_cmd.c
Show inline comments
 
@@ -100,7 +100,7 @@ static bool AllocateVehicles(Vehicle **v
 
	return success;
 
}
 

	
 
static int32 EstimateAircraftCost(uint16 engine_type)
 
int32 EstimateAircraftCost(uint16 engine_type)
 
{
 
	return AircraftVehInfo(engine_type)->base_cost * (_price.aircraft_base>>3)>>5;
 
}
 
@@ -1157,7 +1157,7 @@ static void AircraftEnterHangar(Vehicle 
 

	
 
	ServiceAircraft(v);
 

	
 
	MaybeRenewVehicle(v, EstimateAircraftCost(v->engine_type));
 
	MaybeRenewVehicle(v);
 

	
 
	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 

	
command.c
Show inline comments
 
@@ -167,6 +167,8 @@ DEF_COMMAND(CmdStartScenario);
 

	
 
DEF_COMMAND(CmdBuildManySignals);
 

	
 
DEF_COMMAND(CmdRenewVehicle);
 

	
 
/* The master command table */
 
static CommandProc * const _command_proc_table[] = {
 
	CmdBuildRailroadTrack,				/* 0  */
 
@@ -307,6 +309,7 @@ static CommandProc * const _command_proc
 
	CmdDestroyCompanyHQ,					/* 111 */
 
	CmdGiveMoney,									/* 112 */
 
	CmdChangePatchSetting,				/* 113 */
 
	CmdRenewVehicle,							/* 114 */
 
};
 

	
 
int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
command.h
Show inline comments
 
@@ -148,6 +148,8 @@ enum {
 
	CMD_DESTROY_COMPANY_HQ = 111,
 
	CMD_GIVE_MONEY = 112,
 
	CMD_CHANGE_PATCH_SETTING = 113,
 

	
 
	CMD_RENEW_VEHICLE = 114,
 
};
 

	
 
enum {
roadveh_cmd.c
Show inline comments
 
@@ -100,7 +100,7 @@ void DrawRoadVehEngineInfo(int engine, i
 
	DrawStringMultiCenter(x, y, STR_902A_COST_SPEED_RUNNING_COST, maxw);
 
}
 

	
 
static int32 EstimateRoadVehCost(byte engine_type)
 
int32 EstimateRoadVehCost(byte engine_type)
 
{
 
	return ((_price.roadveh_base >> 3) * RoadVehInfo(engine_type)->base_cost) >> 5;
 
}
 
@@ -1379,7 +1379,7 @@ void RoadVehEnterDepot(Vehicle *v)
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 

	
 
	MaybeRenewVehicle(v, EstimateRoadVehCost(v->engine_type));
 
	MaybeRenewVehicle(v);
 

	
 
	VehicleServiceInDepot(v);
 

	
settings.c
Show inline comments
 
@@ -822,6 +822,10 @@ static const SettingDesc patch_player_se
 

	
 
	{"window_snap_radius",  SDT_UINT8,  (void*)10,    &_patches.window_snap_radius,   NULL},
 

	
 
	{"autorenew",						SDT_BOOL,		(void*)false,	&_patches.autorenew,						NULL},
 
	{"autorenew_months",		SDT_INT16,	(void*)-6,		&_patches.autorenew_months,			NULL},
 
	{"autorenew_money",			SDT_INT32,	(void*)100000,&_patches.autorenew_money,			NULL},
 

	
 
	{NULL,									0,					NULL,					NULL,																						NULL}
 
};
 

	
 
@@ -870,10 +874,6 @@ const SettingDesc patch_settings[] = {
 
	{"servint_ships",				SDT_UINT16, (void*)360,		&_patches.servint_ships,				NULL},
 
	{"servint_aircraft",		SDT_UINT16, (void*)100,		&_patches.servint_aircraft,			NULL},
 

	
 
	{"autorenew",						SDT_BOOL,		(void*)false,	&_patches.autorenew,						NULL},
 
	{"autorenew_months",		SDT_INT16,	(void*)-6,		&_patches.autorenew_months,			NULL},
 
	{"autorenew_money",			SDT_INT32,	(void*)100000,&_patches.autorenew_money,			NULL},
 

	
 
	{"new_pathfinding",			SDT_BOOL,		(void*)true,	&_patches.new_pathfinding,			NULL},
 
	{"pf_maxlength",				SDT_UINT16, (void*)512,		&_patches.pf_maxlength,					NULL},
 
	{"pf_maxdepth",					SDT_UINT8,	(void*)16,		&_patches.pf_maxdepth,					NULL},
settings_gui.c
Show inline comments
 
@@ -624,9 +624,9 @@ static const PatchEntry _patches_vehicle
 
	{PE_BOOL,		0, STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES, "never_expire_vehicles", &_patches.never_expire_vehicles,0,0,0, NULL},
 

	
 
	{PE_UINT16, PF_0ISDIS | PF_PLAYERBASED, STR_CONFIG_PATCHES_LOST_TRAIN_DAYS, "lost_train_days", &_patches.lost_train_days,	180,720, 60, NULL},
 
	{PE_BOOL,		0, STR_CONFIG_PATCHES_AUTORENEW_VEHICLE,"autorenew", &_patches.autorenew,								0,  0,  0, NULL},
 
	{PE_INT16,	0, STR_CONFIG_PATCHES_AUTORENEW_MONTHS, "autorenew_months", &_patches.autorenew_months,				-12, 12,  1, NULL},
 
	{PE_CURRENCY, 0, STR_CONFIG_PATCHES_AUTORENEW_MONEY,"autorenew_money", &_patches.autorenew_money,					0, 2000000, 100000, NULL},
 
	{PE_BOOL,		PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_VEHICLE,"autorenew", &_patches.autorenew,								0,  0,  0, NULL},
 
	{PE_INT16,	PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_MONTHS, "autorenew_months", &_patches.autorenew_months,				-12, 12,  1, NULL},
 
	{PE_CURRENCY, PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_MONEY,"autorenew_money", &_patches.autorenew_money,					0, 2000000, 100000, NULL},
 

	
 
	{PE_UINT8,	0, STR_CONFIG_PATCHES_MAX_TRAINS,				"max_trains", &_patches.max_trains,								0,240, 10, NULL},
 
	{PE_UINT8,	0, STR_CONFIG_PATCHES_MAX_ROADVEH,			"max_roadveh", &_patches.max_roadveh,							0,240, 10, NULL},
 
@@ -700,7 +700,7 @@ static int32 ReadPE(const PatchEntry*pe)
 
	case PE_INT16:  return *(int16*)pe->variable;
 
	case PE_UINT16: return *(uint16*)pe->variable;
 
	case PE_INT32:  return *(int32*)pe->variable;
 
	case PE_CURRENCY:  return (*(int64*)pe->variable) * GetCurrentCurrencyRate();
 
	case PE_CURRENCY:  return (*(int32*)pe->variable) * GetCurrentCurrencyRate();
 
	default:
 
		NOT_REACHED();
 
	}
 
@@ -744,6 +744,7 @@ static void WritePE(const PatchEntry *pe
 
									*(uint16*)pe->variable = (uint16)val;
 
								break;
 

	
 
	case PE_CURRENCY:
 
	case PE_INT32: if ((int32)val > (int32)pe->max)
 
									*(int32*)pe->variable = (int32)pe->max;
 
								else if ((int32)val < (int32)pe->min)
 
@@ -751,14 +752,6 @@ static void WritePE(const PatchEntry *pe
 
								else
 
									*(int32*)pe->variable = val;
 
								break;
 

	
 
	case PE_CURRENCY: if ((int64)val > (int64)pe->max)
 
									*(int64*)pe->variable = (int64)pe->max;
 
								else if ((int64)val < (int64)pe->min)
 
									*(int64*)pe->variable = (int64)pe->min;
 
								else
 
									*(int64*)pe->variable = val;
 
								break;
 
	default:
 
		NOT_REACHED();
 
	}
 
@@ -1400,7 +1393,7 @@ static void CustCurrencyWndProc(Window *
 
				}
 
			break;
 
		}
 
		
 

	
 
		if(edittext) {
 
			WP(w,def_d).data_2 = line;
 
			ShowQueryString(
 
@@ -1412,7 +1405,7 @@ static void CustCurrencyWndProc(Window *
 
			w->window_number);
 
			if (str !=  STR_CONFIG_PATCHES_INT32) DeleteName(str);
 
		}
 
		
 

	
 
		w->flags4 |= 5 << WF_TIMEOUT_SHL;
 
		SetWindowDirty(w);
 
	} break;
 
@@ -1444,8 +1437,8 @@ static void CustCurrencyWndProc(Window *
 
				break;
 
			}
 
		MarkWholeScreenDirty();
 
			
 
		
 

	
 

	
 
	} break;
 

	
 
	case WE_TIMEOUT:
ship_cmd.c
Show inline comments
 
@@ -387,7 +387,7 @@ static bool ShipAccelerate(Vehicle *v)
 
}
 

	
 

	
 
static int32 EstimateShipCost(uint16 engine_type);
 
int32 EstimateShipCost(uint16 engine_type);
 

	
 
static void ShipEnterDepot(Vehicle *v)
 
{
 
@@ -400,7 +400,7 @@ static void ShipEnterDepot(Vehicle *v)
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 

	
 
	MaybeRenewVehicle(v, EstimateShipCost(v->engine_type));
 
	MaybeRenewVehicle(v);
 

	
 
	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 

	
 
@@ -680,7 +680,7 @@ static void ShipController(Vehicle *v)
 

	
 
					/* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */
 
					st = DEREF_STATION(v->current_order.station);
 
					if (!(st->had_vehicle_of_type & HVOT_BUOY) 
 
					if (!(st->had_vehicle_of_type & HVOT_BUOY)
 
							&& (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */
 
						v->current_order.type = OT_LOADING;
 
						v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD;
 
@@ -796,7 +796,7 @@ void ShipsYearlyLoop()
 
	}
 
}
 

	
 
static int32 EstimateShipCost(uint16 engine_type)
 
int32 EstimateShipCost(uint16 engine_type)
 
{
 
	return ShipVehInfo(engine_type)->base_cost * (_price.ship_base>>3)>>5;
 
}
train_cmd.c
Show inline comments
 
@@ -364,7 +364,7 @@ static const byte _railveh_score[] = {
 
};
 

	
 

	
 
static int32 EstimateTrainCost(const RailVehicleInfo *rvi)
 
int32 EstimateTrainCost(const RailVehicleInfo *rvi)
 
{
 
	return (rvi->base_cost * (_price.build_railvehicle >> 3)) >> 5;
 
}
 
@@ -2618,7 +2618,7 @@ void TrainEnterDepot(Vehicle *v, uint ti
 
	v->load_unload_time_rem = 0;
 
	v->cur_speed = 0;
 

	
 
	MaybeRenewVehicle(v, EstimateTrainCost(RailVehInfo(v->engine_type)));
 
	MaybeRenewVehicle(v);
 

	
 
	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 

	
vehicle.c
Show inline comments
 
@@ -25,8 +25,8 @@ void VehicleServiceInDepot(Vehicle *v)
 

	
 
bool VehicleNeedsService(const Vehicle *v)
 
{
 
	return _patches.servint_ispercent ? 
 
		(v->reliability < _engines[v->engine_type].reliability * (100 - v->service_interval) / 100) : 
 
	return _patches.servint_ispercent ?
 
		(v->reliability < _engines[v->engine_type].reliability * (100 - v->service_interval) / 100) :
 
		(v->date_of_last_service + v->service_interval < _date);
 
}
 

	
 
@@ -1358,6 +1358,7 @@ static void ShowVehicleGettingOld(Vehicl
 
{
 
	if (v->owner != _local_player)
 
		return;
 

	
 
	// Do not show getting-old message if autorenew is active
 
	if (_patches.autorenew)
 
		return;
 
@@ -1389,9 +1390,89 @@ void AgeVehicle(Vehicle *v)
 
	}
 
}
 

	
 
void MaybeRenewVehicle(Vehicle *v, int32 build_cost)
 
extern int32 EstimateTrainCost(const RailVehicleInfo *rvi);
 
extern int32 EstimateRoadVehCost(byte engine_type);
 
extern int32 EstimateShipCost(uint16 engine_type);
 
extern int32 EstimateAircraftCost(uint16 engine_type);
 

	
 
/* Renews a vehicle
 
    p1 - Index of vehicle
 
    p2 - Type of new engine */
 
int32 CmdRenewVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Engine *e;
 
	byte new_engine_type = p2;
 
	Vehicle *v = DEREF_VEHICLE(p1);
 
	int cost, build_cost;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 
	switch (v->type) {
 
		case VEH_Train:    build_cost = EstimateTrainCost(RailVehInfo(v->engine_type)); break;
 
		case VEH_Road:     build_cost = EstimateRoadVehCost(new_engine_type);           break;
 
		case VEH_Ship:     build_cost = EstimateShipCost(v->engine_type);               break;
 
		case VEH_Aircraft: build_cost = EstimateAircraftCost(new_engine_type);          break;
 
		default: return CMD_ERROR;
 
	}
 

	
 
	/* In a rare situation, when 2 clients are connected to 1 company and have the same
 
	    settings, a vehicle can be replaced twice.. check if this is the situation here */
 
	if (v->age == 0)
 
		return CMD_ERROR;
 

	
 
	/* Check if there is money for the upgrade.. if not, give a nice news-item
 
	    (that is needed, because this CMD is called automaticly) */
 
	if (DEREF_PLAYER(v->owner)->money64 < _patches.autorenew_money + build_cost - v->value) {
 
		if (_local_player == v->owner) {
 
			int message;
 
			SetDParam(0, v->unitnumber);
 
			switch (v->type) {
 
				case VEH_Train:    message = STR_TRAIN_AUTORENEW_FAILED;       break;
 
				case VEH_Road:     message = STR_ROADVEHICLE_AUTORENEW_FAILED; break;
 
				case VEH_Ship:     message = STR_SHIP_AUTORENEW_FAILED;        break;
 
				case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED;    break;
 
				// This should never happen
 
				default: message = 0; break;
 
			}
 

	
 
			AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
 
		}
 

	
 
		return CMD_ERROR;
 
	}
 

	
 
	cost = build_cost - v->value;
 

	
 
	if (flags & DC_QUERY_COST)
 
		return cost;
 

	
 
	if (flags & DC_EXEC) {
 
		Engine *e;
 

	
 
		/* We do not really buy a new vehicle, we upgrade the old one */
 
		if (v->engine_type != new_engine_type) {
 
			/* XXX - We need to do some more stuff here, when we are going to upgrade
 
			    to a new engine! */
 
		}
 
		e = &_engines[new_engine_type];
 
		v->reliability = e->reliability;
 
		v->reliability_spd_dec = e->reliability_spd_dec;
 
		v->age = 0;
 

	
 
		v->date_of_last_service = _date;
 
		v->build_year = _cur_year;
 

	
 
		v->value = build_cost;
 

	
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
	}
 

	
 
	return cost;
 
}
 

	
 
void MaybeRenewVehicle(Vehicle *v)
 
{
 
	if (v->owner != _local_player)
 
		return;
 

	
 
	// A vehicle is autorenewed when it it gets the amount of months
 
	//  give by _patches.autorenew_months away for his max age.
 
@@ -1400,42 +1481,8 @@ void MaybeRenewVehicle(Vehicle *v, int32
 
	if (!_patches.autorenew || v->age - v->max_age < (_patches.autorenew_months * 30))
 
		return;
 

	
 
	if (DEREF_PLAYER(v->owner)->money64 < _patches.autorenew_money + build_cost - v->value) {
 
		if (v->owner == _local_player) {
 
			int message;
 
			SetDParam(0, v->unitnumber);
 
			switch (v->type) {
 
				case VEH_Train: message = STR_TRAIN_AUTORENEW_FAILED; break;
 
				case VEH_Road: message = STR_ROADVEHICLE_AUTORENEW_FAILED; break;
 
				case VEH_Ship: message = STR_SHIP_AUTORENEW_FAILED; break;
 
				case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED; break;
 
				// This should never happen
 
				default: message = 0; break;
 
			}
 

	
 
			AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
 
		}
 
		return;
 
	}
 

	
 
	// Withdraw the money from the right player ;)
 
	_current_player = v->owner;
 

	
 
	e = &_engines[v->engine_type];
 
	v->reliability = e->reliability;
 
	v->reliability_spd_dec = e->reliability_spd_dec;
 
	v->age = 0;
 

	
 
	v->date_of_last_service = _date;
 
	v->build_year = _cur_year;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 
	SubtractMoneyFromPlayer(build_cost - v->value);
 
	v->value = build_cost;
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 

	
 
	_current_player = OWNER_NONE;
 
	/* Now renew the vehicle */
 
	DoCommandP(v->tile, v->index, v->engine_type, NULL, CMD_RENEW_VEHICLE);
 
}
 

	
 

	
vehicle.h
Show inline comments
 
@@ -361,7 +361,7 @@ Vehicle *CheckClickOnVehicle(ViewPort *v
 
void DecreaseVehicleValue(Vehicle *v);
 
void CheckVehicleBreakdown(Vehicle *v);
 
void AgeVehicle(Vehicle *v);
 
void MaybeRenewVehicle(Vehicle *v, int32 build_cost);
 
void MaybeRenewVehicle(Vehicle *v);
 

	
 
void DeleteCommandFromVehicleSchedule(Order cmd);
 

	
0 comments (0 inline, 0 general)