src/newgrf_engine.cpp
changeset 6674 64f4781b4653
parent 6585 7da94b26498a
child 6715 ce1614834bc3
child 6977 67b989528f3d
child 9601 b499fdd106d5
equal deleted inserted replaced
6673:c3f85858d5e5 6674:64f4781b4653
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file newgrf_engine.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 #include "variables.h"
     7 #include "variables.h"
     6 #include "debug.h"
     8 #include "debug.h"
    64 static const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine)
    66 static const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine)
    65 {
    67 {
    66 	const WagonOverrides *wos = &_engine_wagon_overrides[engine];
    68 	const WagonOverrides *wos = &_engine_wagon_overrides[engine];
    67 	int i;
    69 	int i;
    68 
    70 
    69 	// XXX: This could turn out to be a timesink on profiles. We could
    71 	/* XXX: This could turn out to be a timesink on profiles. We could
    70 	// always just dedicate 65535 bytes for an [engine][train] trampoline
    72 	 * always just dedicate 65535 bytes for an [engine][train] trampoline
    71 	// for O(1). Or O(logMlogN) and searching binary tree or smt. like
    73 	 * for O(1). Or O(logMlogN) and searching binary tree or smt. like
    72 	// that. --pasky
    74 	 * that. --pasky */
    73 
    75 
    74 	for (i = 0; i < wos->overrides_count; i++) {
    76 	for (i = 0; i < wos->overrides_count; i++) {
    75 		const WagonOverride *wo = &wos->overrides[i];
    77 		const WagonOverride *wo = &wos->overrides[i];
    76 		int j;
    78 		int j;
    77 
    79 
   258 
   260 
   259 			/* This condition only occurs for helicopters, before starting descent,
   261 			/* This condition only occurs for helicopters, before starting descent,
   260 			 * to a landing by the hanger of an international airport. */
   262 			 * to a landing by the hanger of an international airport. */
   261 			if (amdflag & AMED_SLOWTURN) return AMS_TTDP_FLIGHT_TO_TOWER;
   263 			if (amdflag & AMED_SLOWTURN) return AMS_TTDP_FLIGHT_TO_TOWER;
   262 
   264 
   263 			// The final two conditions apply to helicopters or aircraft.
   265 			/* The final two conditions apply to helicopters or aircraft.
   264 			/* Has reached hanger? */
   266 			 * Has reached hanger? */
   265 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_HANGAR;
   267 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_HANGAR;
   266 
   268 
   267 			// Still moving towards hanger.
   269 			/* Still moving towards hanger. */
   268 			return AMS_TTDP_TO_HANGAR;
   270 			return AMS_TTDP_TO_HANGAR;
   269 
   271 
   270 		case TERM1:
   272 		case TERM1:
   271 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD1;
   273 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD1;
   272 			return AMS_TTDP_TO_JUNCTION;
   274 			return AMS_TTDP_TO_JUNCTION;
   316 		case LANDING: // Descent
   318 		case LANDING: // Descent
   317 			return AMS_TTDP_FLIGHT_DESCENT;
   319 			return AMS_TTDP_FLIGHT_DESCENT;
   318 
   320 
   319 		case ENDLANDING: // On the runway braking
   321 		case ENDLANDING: // On the runway braking
   320 			if (amdflag & AMED_BRAKE) return AMS_TTDP_BRAKING;
   322 			if (amdflag & AMED_BRAKE) return AMS_TTDP_BRAKING;
   321 			// Landed - moving off runway
   323 			/* Landed - moving off runway */
   322 			return AMS_TTDP_TO_INWAY;
   324 			return AMS_TTDP_TO_INWAY;
   323 
   325 
   324 		case HELILANDING:
   326 		case HELILANDING:
   325 		case HELIENDLANDING: // Helicoptor is decending.
   327 		case HELIENDLANDING: // Helicoptor is decending.
   326 			if (amdflag & AMED_HELI_LOWER) {
   328 			if (amdflag & AMED_HELI_LOWER) {
   391 
   393 
   392 		case TAKEOFF:      // Moving to takeoff position
   394 		case TAKEOFF:      // Moving to takeoff position
   393 		case STARTTAKEOFF: // Accelerating down runway
   395 		case STARTTAKEOFF: // Accelerating down runway
   394 		case ENDTAKEOFF:   // Ascent
   396 		case ENDTAKEOFF:   // Ascent
   395 		case HELITAKEOFF:
   397 		case HELITAKEOFF:
   396 			// TODO Need to find which terminal (or hanger) we've come from. How?
   398 			/* @todo Need to find which terminal (or hanger) we've come from. How? */
   397 			return AMA_TTDP_PAD1_TO_TAKEOFF;
   399 			return AMA_TTDP_PAD1_TO_TAKEOFF;
   398 
   400 
   399 		case FLYING:
   401 		case FLYING:
   400 			return AMA_TTDP_IN_FLIGHT;
   402 			return AMA_TTDP_IN_FLIGHT;
   401 
   403 
   402 		case LANDING:    // Descent
   404 		case LANDING:    // Descent
   403 		case ENDLANDING: // On the runway braking
   405 		case ENDLANDING: // On the runway braking
   404 		case HELILANDING:
   406 		case HELILANDING:
   405 		case HELIENDLANDING:
   407 		case HELIENDLANDING:
   406 			// TODO Need to check terminal we're landing to. Is it known yet?
   408 			/* @todo Need to check terminal we're landing to. Is it known yet? */
   407 			return (v->current_order.type == OT_GOTO_DEPOT) ?
   409 			return (v->current_order.type == OT_GOTO_DEPOT) ?
   408 				AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_LANDING_TO_PAD1;
   410 				AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_LANDING_TO_PAD1;
   409 
   411 
   410 		default:
   412 		default:
   411 			return AMA_TTDP_IN_HANGAR;
   413 			return AMA_TTDP_IN_HANGAR;
   471 	const Vehicle *v = GRV(object);
   473 	const Vehicle *v = GRV(object);
   472 
   474 
   473 	if (v == NULL) {
   475 	if (v == NULL) {
   474 		/* Vehicle does not exist, so we're in a purchase list */
   476 		/* Vehicle does not exist, so we're in a purchase list */
   475 		switch (variable) {
   477 		switch (variable) {
   476 			case 0x43: return _current_player; /* Owner information */
   478 			case 0x43: return _current_player; // Owner information
   477 			case 0x46: return 0;               /* Motion counter */
   479 			case 0x46: return 0;               // Motion counter
   478 			case 0x48: return GetEngine(object->u.vehicle.self_type)->flags; /* Vehicle Type Info */
   480 			case 0x48: return GetEngine(object->u.vehicle.self_type)->flags; // Vehicle Type Info
   479 			case 0xC4: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; /* Build year */
   481 			case 0xC4: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year
   480 			case 0xDA: return INVALID_VEHICLE; /* Next vehicle */
   482 			case 0xDA: return INVALID_VEHICLE; // Next vehicle
   481 			case 0x7F: return GetGRFParameter(object->u.vehicle.self_type, parameter); /* Read GRF parameter */
   483 			case 0x7F: return GetGRFParameter(object->u.vehicle.self_type, parameter); // Read GRF parameter
   482 		}
   484 		}
   483 
   485 
   484 		*available = false;
   486 		*available = false;
   485 		return UINT_MAX;
   487 		return UINT_MAX;
   486 	}
   488 	}
   487 
   489 
   488 	/* Calculated vehicle parameters */
   490 	/* Calculated vehicle parameters */
   489 	switch (variable) {
   491 	switch (variable) {
   490 		case 0x40: /* Get length of consist */
   492 		case 0x40: // Get length of consist
   491 		case 0x41: /* Get length of same consecutive wagons */
   493 		case 0x41: // Get length of same consecutive wagons
   492 			if (v->type != VEH_TRAIN) return 1;
   494 			if (v->type != VEH_TRAIN) return 1;
   493 
   495 
   494 			{
   496 			{
   495 				const Vehicle* u;
   497 				const Vehicle* u;
   496 				byte chain_before = 0;
   498 				byte chain_before = 0;
   507 				}
   509 				}
   508 
   510 
   509 				return chain_before | chain_after << 8 | (chain_before + chain_after + (variable == 0x41)) << 16;
   511 				return chain_before | chain_after << 8 | (chain_before + chain_after + (variable == 0x41)) << 16;
   510 			}
   512 			}
   511 
   513 
   512 		case 0x42: { /* Consist cargo information */
   514 		case 0x42: { // Consist cargo information
   513 			/* XXX Missing support for common refit cycle and property 25 */
   515 			/* XXX Missing support for common refit cycle and property 25 */
   514 			const Vehicle *u;
   516 			const Vehicle *u;
   515 			byte cargo_classes = 0;
   517 			byte cargo_classes = 0;
   516 			uint common_cargo_best = 0;
   518 			uint common_cargo_best = 0;
   517 			uint common_cargos[NUM_CARGO];
   519 			uint common_cargos[NUM_CARGO];
   539 			}
   541 			}
   540 
   542 
   541 			return cargo_classes | (common_cargo_type << 8) | (user_def_data << 24);
   543 			return cargo_classes | (common_cargo_type << 8) | (user_def_data << 24);
   542 		}
   544 		}
   543 
   545 
   544 		case 0x43: /* Player information */
   546 		case 0x43: // Player information
   545 			return v->owner;
   547 			return v->owner;
   546 
   548 
   547 		case 0x44: /* Aircraft information */
   549 		case 0x44: // Aircraft information
   548 			if (v->type != VEH_AIRCRAFT) return UINT_MAX;
   550 			if (v->type != VEH_AIRCRAFT) return UINT_MAX;
   549 
   551 
   550 			{
   552 			{
   551 				const Vehicle *w = v->next;
   553 				const Vehicle *w = v->next;
   552 				uint16 altitude = v->z_pos - w->z_pos; /* Aircraft height - shadow height */
   554 				uint16 altitude = v->z_pos - w->z_pos; // Aircraft height - shadow height
   553 				byte airporttype;
   555 				byte airporttype;
   554 
   556 
   555 				switch (GetStation(v->u.air.targetairport)->airport_type) {
   557 				switch (GetStation(v->u.air.targetairport)->airport_type) {
   556 					/* Note, Helidepot and Helistation are treated as small airports
   558 					/* Note, Helidepot and Helistation are treated as small airports
   557 					 * as they are at ground level. */
   559 					 * as they are at ground level. */
   569 				}
   571 				}
   570 
   572 
   571 				return (altitude << 8) | airporttype;
   573 				return (altitude << 8) | airporttype;
   572 			}
   574 			}
   573 
   575 
   574 		case 0x46: /* Motion counter */
   576 		case 0x46: // Motion counter
   575 			return v->motion_counter;
   577 			return v->motion_counter;
   576 
   578 
   577 		case 0x47: { /* Vehicle cargo info */
   579 		case 0x47: { // Vehicle cargo info
   578 			/* Format: ccccwwtt
   580 			/* Format: ccccwwtt
   579 			 * tt - the cargo type transported by the vehicle,
   581 			 * tt - the cargo type transported by the vehicle,
   580 			 *     translated if a translation table has been installed.
   582 			 *     translated if a translation table has been installed.
   581 			 * ww - cargo unit weight in 1/16 tons, same as cargo prop. 0F.
   583 			 * ww - cargo unit weight in 1/16 tons, same as cargo prop. 0F.
   582 			 * cccc - the cargo class value of the cargo transported by the vehicle.
   584 			 * cccc - the cargo class value of the cargo transported by the vehicle.
   584 			const CargoSpec *cs = GetCargo(v->cargo_type);
   586 			const CargoSpec *cs = GetCargo(v->cargo_type);
   585 
   587 
   586 			return (cs->classes << 16) | (cs->weight << 8) | GetEngineGRF(v->engine_type)->cargo_map[v->cargo_type];
   588 			return (cs->classes << 16) | (cs->weight << 8) | GetEngineGRF(v->engine_type)->cargo_map[v->cargo_type];
   587 		}
   589 		}
   588 
   590 
   589 		case 0x48: return GetEngine(v->engine_type)->flags; /* Vehicle Type Info */
   591 		case 0x48: return GetEngine(v->engine_type)->flags; // Vehicle Type Info
   590 
   592 
   591 		/* Variables which use the parameter */
   593 		/* Variables which use the parameter */
   592 		case 0x60: /* Count consist's engine ID occurance */
   594 		case 0x60: // Count consist's engine ID occurance
   593 			if (v->type != VEH_TRAIN) return v->engine_type == parameter;
   595 			if (v->type != VEH_TRAIN) return v->engine_type == parameter;
   594 
   596 
   595 			{
   597 			{
   596 				uint count = 0;
   598 				uint count = 0;
   597 				for (; v != NULL; v = v->next) {
   599 				for (; v != NULL; v = v->next) {
   598 					if (v->engine_type == parameter) count++;
   600 					if (v->engine_type == parameter) count++;
   599 				}
   601 				}
   600 				return count;
   602 				return count;
   601 			}
   603 			}
   602 
   604 
   603 		case 0x7F: return GetGRFParameter(v->engine_type, parameter); /* Read GRF parameter */
   605 		case 0x7F: return GetGRFParameter(v->engine_type, parameter); // Read GRF parameter
   604 
   606 
   605 		case 0xFE:
   607 		case 0xFE:
   606 		case 0xFF: {
   608 		case 0xFF: {
   607 			uint16 modflags = 0;
   609 			uint16 modflags = 0;
   608 
   610 
   609 			/* TODO: There are some other bits that should be implemented:
   611 			/* @todo: There are some other bits that should be implemented:
   610 			 *   bit 5: Whether the rail vehicle is powered or not (mostly useful for wagons).
   612 			 *   bit 5: Whether the rail vehicle is powered or not (mostly useful for wagons).
   611 			 *   bit 6: This is an electrically powered rail vehicle which is running on normal rail.
   613 			 *   bit 6: This is an electrically powered rail vehicle which is running on normal rail.
   612 			 *   bit 8: (Maybe?) Toggled whenever the train reverses.
   614 			 *   bit 8: (Maybe?) Toggled whenever the train reverses.
   613 			 */
   615 			 */
   614 
   616 
   990 }
   992 }
   991 
   993 
   992 void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
   994 void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
   993 {
   995 {
   994 	if (trigger == VEHICLE_TRIGGER_DEPOT) {
   996 	if (trigger == VEHICLE_TRIGGER_DEPOT) {
   995 		// store that the vehicle entered a depot this tick
   997 		/* store that the vehicle entered a depot this tick */
   996 		VehicleEnteredDepotThisTick(v);
   998 		VehicleEnteredDepotThisTick(v);
   997 	}
   999 	}
   998 
  1000 
   999 	DoTriggerVehicle(v, trigger, 0, true);
  1001 	DoTriggerVehicle(v, trigger, 0, true);
  1000 }
  1002 }
  1018 StringID GetCustomEngineName(EngineID engine)
  1020 StringID GetCustomEngineName(EngineID engine)
  1019 {
  1021 {
  1020 	return _engine_custom_names[engine] == 0 ? _engine_name_strings[engine] : _engine_custom_names[engine];
  1022 	return _engine_custom_names[engine] == 0 ? _engine_name_strings[engine] : _engine_custom_names[engine];
  1021 }
  1023 }
  1022 
  1024 
  1023 // Functions for changing the order of vehicle purchase lists
  1025 /* Functions for changing the order of vehicle purchase lists
  1024 // This is currently only implemented for rail vehicles.
  1026  * This is currently only implemented for rail vehicles. */
  1025 static EngineID _engine_list_order[NUM_TRAIN_ENGINES];
  1027 static EngineID _engine_list_order[NUM_TRAIN_ENGINES];
  1026 static byte _engine_list_position[NUM_TRAIN_ENGINES];
  1028 static byte _engine_list_position[NUM_TRAIN_ENGINES];
  1027 
  1029 
  1028 void ResetEngineListOrder()
  1030 void ResetEngineListOrder()
  1029 {
  1031 {
  1064 	EngineID i;
  1066 	EngineID i;
  1065 	bool moving = false;
  1067 	bool moving = false;
  1066 
  1068 
  1067 	if (engine == target) return;
  1069 	if (engine == target) return;
  1068 
  1070 
  1069 	// First, remove our ID from the list.
  1071 	/* First, remove our ID from the list. */
  1070 	for (i = 0; i < NUM_TRAIN_ENGINES - 1; i++) {
  1072 	for (i = 0; i < NUM_TRAIN_ENGINES - 1; i++) {
  1071 		if (_engine_list_order[i] == engine) moving = true;
  1073 		if (_engine_list_order[i] == engine) moving = true;
  1072 		if (moving) _engine_list_order[i] = _engine_list_order[i + 1];
  1074 		if (moving) _engine_list_order[i] = _engine_list_order[i + 1];
  1073 	}
  1075 	}
  1074 
  1076 
  1075 	// Now, insert it again, before the target engine.
  1077 	/* Now, insert it again, before the target engine. */
  1076 	for (i = NUM_TRAIN_ENGINES - 1; i > 0; i--) {
  1078 	for (i = NUM_TRAIN_ENGINES - 1; i > 0; i--) {
  1077 		_engine_list_order[i] = _engine_list_order[i - 1];
  1079 		_engine_list_order[i] = _engine_list_order[i - 1];
  1078 		if (_engine_list_order[i] == target) {
  1080 		if (_engine_list_order[i] == target) {
  1079 			_engine_list_order[i - 1] = engine;
  1081 			_engine_list_order[i - 1] = engine;
  1080 			break;
  1082 			break;
  1081 		}
  1083 		}
  1082 	}
  1084 	}
  1083 
  1085 
  1084 	// Update the engine list position (a reverse of engine list order)
  1086 	/* Update the engine list position (a reverse of engine list order) */
  1085 	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
  1087 	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
  1086 		_engine_list_position[_engine_list_order[i]] = i;
  1088 		_engine_list_position[_engine_list_order[i]] = i;
  1087 	}
  1089 	}
  1088 }
  1090 }