Changeset - r1060:0d48734e0533
[Not reviewed]
master
0 3 0
bjarni - 20 years ago 2005-01-18 23:27:06
bjarni@openttd.org
(svn r1561) Fix: autoreplacing a singleheaded engine into a dualheaded engine now adds the the rear engine
autoreplacing a dualheaded engine into a singleheaded engine now sells the rear engine
as a sideeffect of this, the price for replacing both engines are now added and displayed once from the depot(instead of two identical numbers written on top of each other, looking like one)
fix: cost for autorenew dualheaded engines were doubled and their value where doubled too
3 files changed with 111 insertions and 53 deletions:
0 comments (0 inline, 0 general)
train_cmd.c
Show inline comments
 
@@ -362,12 +362,41 @@ static const byte _railveh_score[] = {
 

	
 
int32 EstimateTrainCost(const RailVehicleInfo *rvi)
 
{
 
	return (rvi->base_cost * (_price.build_railvehicle >> 3)) >> 5;
 
}
 

	
 
void AddRearEngineToMultiheadedTrain(Vehicle *v, Vehicle *u, bool building) 
 
{
 
	u->direction = v->direction;
 
	u->owner = v->owner;
 
	u->tile = v->tile;
 
	u->x_pos = v->x_pos;
 
	u->y_pos = v->y_pos;
 
	u->z_pos = v->z_pos;
 
	u->z_height = 6;
 
	u->u.rail.track = 0x80;
 
	v->u.rail.first_engine = 0xffff;
 
	u->vehstatus = v->vehstatus & ~VS_STOPPED;
 
	u->subtype = 2;
 
	u->spritenum = v->spritenum + 1;
 
	u->cargo_type = v->cargo_type;
 
	u->cargo_cap = v->cargo_cap;
 
	u->u.rail.railtype = v->u.rail.railtype;
 
	if (building) v->next = u;
 
	u->engine_type = v->engine_type;
 
	u->build_year = v->build_year;
 
	if (building) 
 
		v->value = u->value = v->value >> 1;
 
	else
 
		u->value = v->value;
 
	u->type = VEH_Train;
 
	u->cur_image = 0xAC2;
 
	VehiclePositionChanged(u);
 
}
 

	
 
/* Build a railroad vehicle
 
 * p1 = vehicle type id
 
 */
 

	
 
int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
@@ -439,38 +468,14 @@ int32 CmdBuildRailVehicle(int x, int y, 
 
			v->build_year = _cur_year;
 
			v->type = VEH_Train;
 
			v->cur_image = 0xAC2;
 

	
 
			VehiclePositionChanged(v);
 

	
 
			if (rvi->flags&RVI_MULTIHEAD && (u=AllocateVehicle()) != NULL) {
 
				u->direction = v->direction;
 
				u->owner = v->owner;
 
				u->tile = v->tile;
 
				u->x_pos = v->x_pos;
 
				u->y_pos = v->y_pos;
 
				u->z_pos = v->z_pos;
 
				u->z_height = 6;
 
				u->u.rail.track = 0x80;
 
				v->u.rail.first_engine = 0xffff;
 
				u->vehstatus = VS_HIDDEN | VS_DEFPAL;
 
				u->subtype = 2;
 
				u->spritenum = v->spritenum + 1;
 
				u->cargo_type = v->cargo_type;
 
				u->cargo_cap = v->cargo_cap;
 
				u->u.rail.railtype = v->u.rail.railtype;
 
//				u->next_in_chain = 0xffff;
 
				v->next = u;
 
				u->engine_type = v->engine_type;
 
				u->build_year = v->build_year;
 
				v->value = u->value = v->value >> 1;
 
//				u->day_counter = 0;
 
				u->type = VEH_Train;
 
				u->cur_image = 0xAC2;
 
				VehiclePositionChanged(u);
 
			}
 
			if (rvi->flags&RVI_MULTIHEAD && (u = AllocateVehicle()) != NULL)
 
				AddRearEngineToMultiheadedTrain(v, u, true);
 

	
 
			UpdateTrainAcceleration(v);
 
			NormalizeTrainVehInDepot(v);
 

	
 
			InvalidateWindow(WC_VEHICLE_DEPOT, tile);
 
			RebuildVehicleLists();
vehicle.c
Show inline comments
 
@@ -1318,13 +1318,15 @@ int32 CmdReplaceVehicle(int x, int y, ui
 
	 This way the max is 6553 millions and it is more than the 32 bit that is stored in _patches
 
	 This is a nice way to send 32 bit and only use 16 bit
 
	 the last 8 bit is the engine. The 8 bits in front of the engine is free so it have room for 16 bit engine entries */
 
	uint16 new_engine_type = (uint16)(p2 & 0xFFFF);
 
	uint32 autorefit_money = (p2  >> 16) * 100000;
 
	Vehicle *v = GetVehicle(p1);
 
	int cost, build_cost;
 
	int cost, build_cost, rear_engine_cost = 0;
 
	Vehicle *u = v;
 
	byte old_engine_type = v->engine_type;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 

	
 
	// first we make sure that it's a valid type the user requested
 
	// check that it's an engine that is in the engine array
 
@@ -1344,18 +1346,48 @@ int32 CmdReplaceVehicle(int x, int y, ui
 
		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->engine_type == new_engine_type && v->age == 0)
 
	if (old_engine_type == new_engine_type && v->age == 0)
 
		return CMD_ERROR;
 
		
 
	if ( v->type == VEH_Train ) {
 
		u = GetLastVehicleInChain(v);
 
		if ( RailVehInfo(new_engine_type)->flags & RVI_MULTIHEAD )
 
			build_cost = build_cost >> 1;   //multiheaded engines have EstimateTrainCost() for both engines
 
		
 
		if ( old_engine_type != new_engine_type ) {
 
		
 
			// prevent that the rear engine can get replaced to something else than the front engine
 
			if ( v->u.rail.first_engine != 0xffff && RailVehInfo(old_engine_type)->flags & RVI_MULTIHEAD && RailVehInfo(old_engine_type)->flags ) {
 
				Vehicle *first = GetFirstVehicleInChain(v);
 
				if ( first->engine_type != new_engine_type ) return CMD_ERROR;
 
			}
 
			
 
			// checks if the engine is the first one
 
			if ( v->u.rail.first_engine == 0xffff ) {
 
				if ( RailVehInfo(new_engine_type)->flags & RVI_MULTIHEAD ) {
 
					if ( u->engine_type == old_engine_type && v->next != NULL) {
 
						rear_engine_cost = build_cost - u->value;
 
					} else {
 
						rear_engine_cost = build_cost;
 
					}
 
				} else {
 
					if ( u->engine_type == old_engine_type && RailVehInfo(old_engine_type)->flags & RVI_MULTIHEAD) {
 
						if (v->next != NULL) rear_engine_cost = -u->value;
 
					}
 
				}
 
			 }
 
		}
 
	}
 

	
 
	/* 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 < (int32)(autorefit_money + build_cost - v->value)) {
 
	if ( DEREF_PLAYER(v->owner)->money64 < (int32)(autorefit_money + build_cost + rear_engine_cost - v->value)) {
 
		if (( _local_player == v->owner ) && ( v->unitnumber != 0 )) {  //v->unitnumber = 0 for train cars
 
			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;
 
@@ -1367,45 +1399,54 @@ int32 CmdReplaceVehicle(int x, int y, ui
 

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

	
 
		return CMD_ERROR;
 
	}
 
	cost = build_cost - v->value;
 
	cost = build_cost - v->value + rear_engine_cost;
 

	
 

	
 
	if (flags & DC_EXEC) {
 
		/* We do not really buy a new vehicle, we upgrade the old one */
 
		Engine *e;
 
		e = DEREF_ENGINE(new_engine_type);
 

	
 
		// TODO make it check if refit is possible before actually doing it
 
		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;
 

	
 
		/* We do not really buy a new vehicle, we upgrade the old one */
 
		v->value = build_cost;
 

	
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 

	
 
	
 
		if (v->engine_type != new_engine_type) {
 
			byte old_engine = v->engine_type;
 
			byte sprite = v->spritenum;
 
			byte cargo_type = v->cargo_type;
 
			v->engine_type = new_engine_type;
 
			v->max_age = e->lifelength * 366;
 

	
 
			/* Update limits of the vehicle (for when upgraded) */
 
			switch (v->type) {
 
			case VEH_Train:
 
			// using if (true) to declare the const
 
				{
 
				const RailVehicleInfo *rvi = RailVehInfo(new_engine_type);
 
				const RailVehicleInfo *rvi2 = RailVehInfo(old_engine);
 
				const RailVehicleInfo *rvi2 = RailVehInfo(old_engine_type);
 
				byte capacity = rvi->capacity;
 
				Vehicle *first = GetFirstVehicleInChain(v);
 

	
 
				/* rvi->image_index is the new sprite for the engine. Adding +1 makes the engine head the other way
 
				if it is a multiheaded engine (rear engine)
 
				(rvi->flags & RVI_MULTIHEAD && sprite - rvi2->image_index) is true if the engine is heading the other way, otherwise 0*/
 
				v->spritenum = rvi->image_index + (( rvi->flags & RVI_MULTIHEAD && sprite - rvi2->image_index) ? 1 : 0);
 

	
 
				// turn the last engine in a multiheaded train if needed
 
				if ( v->next == NULL && rvi->flags & RVI_MULTIHEAD && v->spritenum == rvi->image_index )
 
				if ( v->next == NULL && v->u.rail.first_engine != 0xffff && rvi->flags & RVI_MULTIHEAD && v->spritenum == rvi->image_index )
 
					v->spritenum++;
 

	
 
				v->cargo_type = rvi->cargo_type;
 
				v->cargo_cap = rvi->capacity;
 
				v->max_speed = rvi->max_speed;
 

	
 
@@ -1417,28 +1458,50 @@ int32 CmdReplaceVehicle(int x, int y, ui
 
					// BUG: somehow v->index is not transfered properly
 
					//CmdRefitRailVehicle(v->x_pos, v->y_pos, DC_EXEC, v->index , cargo_type + 0x0100 );
 
					v->cargo_type = cargo_type; // workaround, but it do not check the refit table
 
				} else {
 
					v->cargo_type = rvi->cargo_type;
 
				}
 
				
 
				if ( rvi2->flags & RVI_MULTIHEAD && !(rvi->flags & RVI_MULTIHEAD) &&  v->index == first->index) {
 
					if (old_engine_type == u->engine_type ) {
 
						u = GetLastVehicleInChain(v);
 
						Vehicle *w = GetPrevVehicleInChain(u);
 
						w->next = NULL;
 
						DeleteVehicle(u);
 
					}
 
				}
 
				
 
				if ( rvi->flags & RVI_MULTIHEAD && rvi2->flags & RVI_MULTIHEAD &&  v->index == first->index ) {
 
					CmdReplaceVehicle(x, y, flags, u->index, p2);
 
				}
 
				
 
				if ( rvi->flags & RVI_MULTIHEAD && !(rvi2->flags & RVI_MULTIHEAD) &&  v->index == first->index ) {
 
					if ( old_engine_type != u->engine_type ) {
 
						Vehicle *w;
 
						if ( (w=AllocateVehicle()) != NULL ) {
 
							AddRearEngineToMultiheadedTrain(v,w, false);
 
							u->next = w;
 
						}
 
					}
 
				}
 
				
 
				break;
 
				}
 
			case VEH_Road:
 
			// using if (true) to declare the const
 
				if (true) {
 
				{
 
				const RoadVehicleInfo *rvi = RoadVehInfo(new_engine_type);
 

	
 
				v->spritenum = rvi->image_index;
 
				v->cargo_type = rvi->cargo_type;
 
				v->cargo_cap = rvi->capacity;
 
				v->max_speed = rvi->max_speed;
 
				break;
 
				}
 
			case VEH_Ship:
 
			// using if (true) to declare the const
 
				if (true) {
 
				{
 
				const ShipVehicleInfo *svi = ShipVehInfo(new_engine_type);
 

	
 
				v->spritenum = svi->image_index;
 
				v->cargo_type = svi->cargo_type;
 
				v->cargo_cap = svi->capacity;
 
				v->max_speed = svi->max_speed;
 
@@ -1447,14 +1510,13 @@ int32 CmdReplaceVehicle(int x, int y, ui
 
				// since we do not stop it for autorefitting
 
				if (v->cargo_type != cargo_type)
 
					CmdRefitShip(v->x_pos, v->y_pos, DC_EXEC, v->index , cargo_type + 0x0100 );
 
				break;
 
				}
 
			case VEH_Aircraft:
 
			// using if (true) to declare the const
 
				if (true) {
 
				{
 
				const AircraftVehicleInfo *avi = AircraftVehInfo(new_engine_type);
 
				Vehicle *u;
 

	
 
				v->max_speed = avi->max_speed;
 
				v->acceleration = avi->acceleration;
 
				v->spritenum = avi->image_index;
 
@@ -1477,23 +1539,12 @@ int32 CmdReplaceVehicle(int x, int y, ui
 
				if ( v->cargo_type != cargo_type )
 
					v->cargo_count = 0;
 
				else if ( v->cargo_count > v->cargo_cap )
 
					v->cargo_count = v->cargo_cap;
 
			}
 
		}
 

	
 
		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);
 
	}
 
	//needs to be down here because refitting will change SET_EXPENSES_TYPE if called
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 
	return cost;
 
}
vehicle.h
Show inline comments
 
@@ -281,12 +281,14 @@ bool IsRoadDepotTile(TileIndex tile);
 
bool CanFillVehicle(Vehicle *v);
 

	
 
void ViewportAddVehicles(DrawPixelInfo *dpi);
 

	
 
void TrainEnterDepot(Vehicle *v, uint tile);
 

	
 
void AddRearEngineToMultiheadedTrain(Vehicle *v, Vehicle *u, bool building) ;
 

	
 
/* train_cmd.h */
 
int GetTrainImage(Vehicle *v, byte direction);
 
int GetAircraftImage(Vehicle *v, byte direction);
 
int GetRoadVehImage(Vehicle *v, byte direction);
 
int GetShipImage(Vehicle *v, byte direction);
 

	
0 comments (0 inline, 0 general)