src/newgrf_engine.cpp
branchcustombridgeheads
changeset 5649 55c8267c933f
parent 5643 3778051e8095
child 5650 aefc131bf5ce
equal deleted inserted replaced
5648:1608018c5ff2 5649:55c8267c933f
       
     1 /* $Id$ */
       
     2 
       
     3 #include "stdafx.h"
       
     4 #include "openttd.h"
       
     5 #include "variables.h"
       
     6 #include "debug.h"
       
     7 #include "functions.h"
       
     8 #include "engine.h"
       
     9 #include "train.h"
       
    10 #include "player.h"
       
    11 #include "station.h"
       
    12 #include "airport.h"
       
    13 #include "newgrf.h"
       
    14 #include "newgrf_callbacks.h"
       
    15 #include "newgrf_engine.h"
       
    16 #include "newgrf_station.h"
       
    17 #include "newgrf_spritegroup.h"
       
    18 #include "newgrf_cargo.h"
       
    19 #include "date.h"
       
    20 
       
    21 
       
    22 
       
    23 /* Default cargo classes */
       
    24 static const uint16 _cargo_classes[NUM_GLOBAL_CID] = {
       
    25 	CC_PASSENGERS,
       
    26 	CC_BULK,
       
    27 	CC_MAIL,
       
    28 	CC_LIQUID,
       
    29 	CC_PIECE_GOODS,
       
    30 	CC_EXPRESS,
       
    31 	CC_BULK,
       
    32 	CC_PIECE_GOODS,
       
    33 	CC_BULK,
       
    34 	CC_PIECE_GOODS,
       
    35 	CC_ARMOURED,
       
    36 	CC_PIECE_GOODS,
       
    37 	CC_REFRIGERATED | CC_EXPRESS,
       
    38 	CC_REFRIGERATED | CC_EXPRESS,
       
    39 	CC_BULK,
       
    40 	CC_LIQUID,
       
    41 	CC_LIQUID,
       
    42 	CC_BULK,
       
    43 	CC_PIECE_GOODS,
       
    44 	CC_PIECE_GOODS,
       
    45 	CC_EXPRESS,
       
    46 	CC_BULK,
       
    47 	CC_LIQUID,
       
    48 	CC_BULK,
       
    49 	CC_PIECE_GOODS,
       
    50 	CC_LIQUID,
       
    51 	CC_PIECE_GOODS,
       
    52 	CC_PIECE_GOODS,
       
    53 	CC_NOAVAILABLE,
       
    54 	CC_NOAVAILABLE,
       
    55 	CC_NOAVAILABLE,
       
    56 };
       
    57 
       
    58 int _traininfo_vehicle_pitch = 0;
       
    59 int _traininfo_vehicle_width = 29;
       
    60 
       
    61 typedef struct WagonOverride {
       
    62 	byte *train_id;
       
    63 	int trains;
       
    64 	CargoID cargo;
       
    65 	const SpriteGroup *group;
       
    66 } WagonOverride;
       
    67 
       
    68 typedef struct WagonOverrides {
       
    69 	int overrides_count;
       
    70 	WagonOverride *overrides;
       
    71 } WagonOverrides;
       
    72 
       
    73 static WagonOverrides _engine_wagon_overrides[TOTAL_NUM_ENGINES];
       
    74 
       
    75 void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const SpriteGroup *group, byte *train_id, int trains)
       
    76 {
       
    77 	WagonOverrides *wos;
       
    78 	WagonOverride *wo;
       
    79 
       
    80 	assert(engine < TOTAL_NUM_ENGINES);
       
    81 	assert(cargo < NUM_GLOBAL_CID);
       
    82 
       
    83 	wos = &_engine_wagon_overrides[engine];
       
    84 	wos->overrides_count++;
       
    85 	wos->overrides = realloc(wos->overrides,
       
    86 		wos->overrides_count * sizeof(*wos->overrides));
       
    87 
       
    88 	wo = &wos->overrides[wos->overrides_count - 1];
       
    89 	/* FIXME: If we are replacing an override, release original SpriteGroup
       
    90 	 * to prevent leaks. But first we need to refcount the SpriteGroup.
       
    91 	 * --pasky */
       
    92 	wo->group = group;
       
    93 	wo->cargo = cargo;
       
    94 	wo->trains = trains;
       
    95 	wo->train_id = malloc(trains);
       
    96 	memcpy(wo->train_id, train_id, trains);
       
    97 }
       
    98 
       
    99 static const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine)
       
   100 {
       
   101 	const WagonOverrides *wos = &_engine_wagon_overrides[engine];
       
   102 	int i;
       
   103 
       
   104 	// XXX: This could turn out to be a timesink on profiles. We could
       
   105 	// always just dedicate 65535 bytes for an [engine][train] trampoline
       
   106 	// for O(1). Or O(logMlogN) and searching binary tree or smt. like
       
   107 	// that. --pasky
       
   108 
       
   109 	for (i = 0; i < wos->overrides_count; i++) {
       
   110 		const WagonOverride *wo = &wos->overrides[i];
       
   111 		int j;
       
   112 
       
   113 		for (j = 0; j < wo->trains; j++) {
       
   114 			if (wo->train_id[j] == overriding_engine && (wo->cargo == cargo || wo->cargo == GC_DEFAULT)) return wo->group;
       
   115 		}
       
   116 	}
       
   117 	return NULL;
       
   118 }
       
   119 
       
   120 /**
       
   121  * Unload all wagon override sprite groups.
       
   122  */
       
   123 void UnloadWagonOverrides(void)
       
   124 {
       
   125 	WagonOverrides *wos;
       
   126 	WagonOverride *wo;
       
   127 	EngineID engine;
       
   128 	int i;
       
   129 
       
   130 	for (engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
       
   131 		wos = &_engine_wagon_overrides[engine];
       
   132 		for (i = 0; i < wos->overrides_count; i++) {
       
   133 			wo = &wos->overrides[i];
       
   134 			wo->group = NULL;
       
   135 			free(wo->train_id);
       
   136 		}
       
   137 		free(wos->overrides);
       
   138 		wos->overrides_count = 0;
       
   139 		wos->overrides = NULL;
       
   140 	}
       
   141 }
       
   142 
       
   143 // 0 - 28 are cargos, 29 is default, 30 is the advert (purchase list)
       
   144 // (It isn't and shouldn't be like this in the GRF files since new cargo types
       
   145 // may appear in future - however it's more convenient to store it like this in
       
   146 // memory. --pasky)
       
   147 static const SpriteGroup *engine_custom_sprites[TOTAL_NUM_ENGINES][NUM_GLOBAL_CID];
       
   148 static const GRFFile *_engine_grf[TOTAL_NUM_ENGINES];
       
   149 
       
   150 void SetCustomEngineSprites(EngineID engine, byte cargo, const SpriteGroup *group)
       
   151 {
       
   152 	assert(engine < TOTAL_NUM_ENGINES);
       
   153 	assert(cargo < NUM_GLOBAL_CID);
       
   154 
       
   155 	if (engine_custom_sprites[engine][cargo] != NULL) {
       
   156 		grfmsg(6, "SetCustomEngineSprites: engine %d cargo %d already has group -- replacing", engine, cargo);
       
   157 	}
       
   158 	engine_custom_sprites[engine][cargo] = group;
       
   159 }
       
   160 
       
   161 /**
       
   162  * Unload all engine sprite groups.
       
   163  */
       
   164 void UnloadCustomEngineSprites(void)
       
   165 {
       
   166 	EngineID engine;
       
   167 	CargoID cargo;
       
   168 
       
   169 	for (engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
       
   170 		for (cargo = 0; cargo < NUM_GLOBAL_CID; cargo++) {
       
   171 			engine_custom_sprites[engine][cargo] = NULL;
       
   172 		}
       
   173 		_engine_grf[engine] = 0;
       
   174 	}
       
   175 }
       
   176 
       
   177 static const SpriteGroup *heli_rotor_custom_sprites[NUM_AIRCRAFT_ENGINES];
       
   178 
       
   179 /** Load a rotor override sprite group for an aircraft */
       
   180 void SetRotorOverrideSprites(EngineID engine, const SpriteGroup *group)
       
   181 {
       
   182 	assert(engine >= AIRCRAFT_ENGINES_INDEX);
       
   183 	assert(engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES);
       
   184 
       
   185 	if (heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] != NULL) {
       
   186 		grfmsg(6, "SetRotorOverrideSprites: engine %d already has group -- replacing.", engine);
       
   187 	}
       
   188 	heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] = group;
       
   189 }
       
   190 
       
   191 /** Unload all rotor override sprite groups */
       
   192 void UnloadRotorOverrideSprites(void)
       
   193 {
       
   194 	EngineID engine;
       
   195 
       
   196 	/* Starting at AIRCRAFT_ENGINES_INDEX may seem pointless, but it means
       
   197 	 * the context of EngineID is correct */
       
   198 	for (engine = AIRCRAFT_ENGINES_INDEX; engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; engine++) {
       
   199 		heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] = NULL;
       
   200 	}
       
   201 }
       
   202 
       
   203 
       
   204 /**
       
   205  * Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters
       
   206  * etc during a game.
       
   207  * @param engine Engine ID to tie the GRFFile to.
       
   208  * @param file   Pointer of GRFFile to tie.
       
   209  */
       
   210 void SetEngineGRF(EngineID engine, const GRFFile *file)
       
   211 {
       
   212 	assert(engine < TOTAL_NUM_ENGINES);
       
   213 	_engine_grf[engine] = file;
       
   214 }
       
   215 
       
   216 
       
   217 /**
       
   218  * Retrieve the GRFFile tied to an engine
       
   219  * @param engine Engine ID to retrieve.
       
   220  * @return Pointer to GRFFile.
       
   221  */
       
   222 const GRFFile *GetEngineGRF(EngineID engine)
       
   223 {
       
   224 	assert(engine < TOTAL_NUM_ENGINES);
       
   225 	return _engine_grf[engine];
       
   226 }
       
   227 
       
   228 
       
   229 /**
       
   230  * Retrieve the GRF ID of the GRFFile tied to an engine
       
   231  * @param engine Engine ID to retrieve.
       
   232  * @return 32 bit GRFID value.
       
   233  */
       
   234 uint32 GetEngineGRFID(EngineID engine)
       
   235 {
       
   236 	assert(engine < TOTAL_NUM_ENGINES);
       
   237 	return _engine_grf[engine]->grfid;
       
   238 }
       
   239 
       
   240 
       
   241 static int MapOldSubType(const Vehicle *v)
       
   242 {
       
   243 	if (v->type != VEH_Train) return v->subtype;
       
   244 	if (IsTrainEngine(v)) return 0;
       
   245 	if (IsFreeWagon(v)) return 4;
       
   246 	return 2;
       
   247 }
       
   248 
       
   249 
       
   250 /* TTDP style aircraft movement states for GRF Action 2 Var 0xE2 */
       
   251 enum {
       
   252 	AMS_TTDP_HANGAR,
       
   253 	AMS_TTDP_TO_HANGAR,
       
   254 	AMS_TTDP_TO_PAD1,
       
   255 	AMS_TTDP_TO_PAD2,
       
   256 	AMS_TTDP_TO_PAD3,
       
   257 	AMS_TTDP_TO_ENTRY_2_AND_3,
       
   258 	AMS_TTDP_TO_ENTRY_2_AND_3_AND_H,
       
   259 	AMS_TTDP_TO_JUNCTION,
       
   260 	AMS_TTDP_LEAVE_RUNWAY,
       
   261 	AMS_TTDP_TO_INWAY,
       
   262 	AMS_TTDP_TO_RUNWAY,
       
   263 	AMS_TTDP_TO_OUTWAY,
       
   264 	AMS_TTDP_WAITING,
       
   265 	AMS_TTDP_TAKEOFF,
       
   266 	AMS_TTDP_TO_TAKEOFF,
       
   267 	AMS_TTDP_CLIMBING,
       
   268 	AMS_TTDP_FLIGHT_APPROACH,
       
   269 	AMS_TTDP_UNUSED_0x11,
       
   270 	AMS_TTDP_FLIGHT_TO_TOWER,
       
   271 	AMS_TTDP_UNUSED_0x13,
       
   272 	AMS_TTDP_FLIGHT_FINAL,
       
   273 	AMS_TTDP_FLIGHT_DESCENT,
       
   274 	AMS_TTDP_BRAKING,
       
   275 	AMS_TTDP_HELI_TAKEOFF_AIRPORT,
       
   276 	AMS_TTDP_HELI_TO_TAKEOFF_AIRPORT,
       
   277 	AMS_TTDP_HELI_LAND_AIRPORT,
       
   278 	AMS_TTDP_HELI_TAKEOFF_HELIPORT,
       
   279 	AMS_TTDP_HELI_TO_TAKEOFF_HELIPORT,
       
   280 	AMS_TTDP_HELI_LAND_HELIPORT,
       
   281 };
       
   282 
       
   283 
       
   284 /**
       
   285  * Map OTTD aircraft movement states to TTDPatch style movement states
       
   286  * (VarAction 2 Variable 0xE2)
       
   287  */
       
   288 static byte MapAircraftMovementState(const Vehicle *v)
       
   289 {
       
   290 	const Station *st = GetStation(v->u.air.targetairport);
       
   291 	byte amdflag = GetAirportMovingData(st->airport_type, v->u.air.pos)->flag;
       
   292 
       
   293 	switch (v->u.air.state) {
       
   294 		case HANGAR:
       
   295 			/* The international airport is a special case as helicopters can land in
       
   296 			 * front of the hanger. Helicopters also change their air.state to
       
   297 			 * AMED_HELI_LOWER some time before actually descending. */
       
   298 
       
   299 			/* This condition only occurs for helicopters, during descent,
       
   300 			 * to a landing by the hanger of an international airport. */
       
   301 			if (amdflag & AMED_HELI_LOWER) return AMS_TTDP_HELI_LAND_AIRPORT;
       
   302 
       
   303 			/* This condition only occurs for helicopters, before starting descent,
       
   304 			 * to a landing by the hanger of an international airport. */
       
   305 			if (amdflag & AMED_SLOWTURN) return AMS_TTDP_FLIGHT_TO_TOWER;
       
   306 
       
   307 			// The final two conditions apply to helicopters or aircraft.
       
   308 			/* Has reached hanger? */
       
   309 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_HANGAR;
       
   310 
       
   311 			// Still moving towards hanger.
       
   312 			return AMS_TTDP_TO_HANGAR;
       
   313 
       
   314 		case TERM1:
       
   315 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD1;
       
   316 			return AMS_TTDP_TO_JUNCTION;
       
   317 
       
   318 		case TERM2:
       
   319 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD2;
       
   320 			return AMS_TTDP_TO_ENTRY_2_AND_3_AND_H;
       
   321 
       
   322 		case TERM3:
       
   323 		case TERM4:
       
   324 		case TERM5:
       
   325 		case TERM6:
       
   326 		case TERM7:
       
   327 		case TERM8:
       
   328 			/* TTDPatch only has 3 terminals, so treat these states the same */
       
   329 			if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD3;
       
   330 			return AMS_TTDP_TO_ENTRY_2_AND_3_AND_H;
       
   331 
       
   332 		case HELIPAD1:
       
   333 		case HELIPAD2:
       
   334 		case HELIPAD3:
       
   335 		case HELIPAD4: // Will only occur for helicopters.
       
   336 			if (amdflag & AMED_HELI_LOWER) return AMS_TTDP_HELI_LAND_AIRPORT; // Descending.
       
   337 			if (amdflag & AMED_SLOWTURN)   return AMS_TTDP_FLIGHT_TO_TOWER;   // Still hasn't started descent.
       
   338 			return AMS_TTDP_TO_JUNCTION; // On the ground.
       
   339 
       
   340 		case TAKEOFF: // Moving to takeoff position.
       
   341 			return AMS_TTDP_TO_OUTWAY;
       
   342 
       
   343 		case STARTTAKEOFF: // Accelerating down runway.
       
   344 			return AMS_TTDP_TAKEOFF;
       
   345 
       
   346 		case ENDTAKEOFF: // Ascent
       
   347 			return AMS_TTDP_CLIMBING;
       
   348 
       
   349 		case HELITAKEOFF: // Helicopter is moving to take off position.
       
   350 			switch (st->airport_type) {
       
   351 				case AT_SMALL:
       
   352 				case AT_LARGE:
       
   353 				case AT_METROPOLITAN:
       
   354 				case AT_INTERNATIONAL:
       
   355 				case AT_COMMUTER:
       
   356 				case AT_INTERCON:
       
   357 				/* Note, Helidepot and Helistation are treated as airports as
       
   358 				 * helicopters are taking off from ground level. */
       
   359 				case AT_HELIDEPOT:
       
   360 				case AT_HELISTATION:
       
   361 					if (amdflag & AMED_HELI_RAISE) return AMS_TTDP_HELI_TAKEOFF_AIRPORT;
       
   362 					return AMS_TTDP_TO_JUNCTION;
       
   363 
       
   364 				case AT_HELIPORT:
       
   365 				case AT_OILRIG:
       
   366 					return AMS_TTDP_HELI_TAKEOFF_HELIPORT;
       
   367 
       
   368 				default:
       
   369 					return AMS_TTDP_HELI_TAKEOFF_AIRPORT;
       
   370 			}
       
   371 
       
   372 		case FLYING:
       
   373 			return AMS_TTDP_FLIGHT_TO_TOWER;
       
   374 
       
   375 		case LANDING: // Descent
       
   376 			return AMS_TTDP_FLIGHT_DESCENT;
       
   377 
       
   378 		case ENDLANDING: // On the runway braking
       
   379 			if (amdflag & AMED_BRAKE) return AMS_TTDP_BRAKING;
       
   380 			// Landed - moving off runway
       
   381 			return AMS_TTDP_TO_INWAY;
       
   382 
       
   383 		case HELILANDING:
       
   384 		case HELIENDLANDING: // Helicoptor is decending.
       
   385 			if (amdflag & AMED_HELI_LOWER) {
       
   386 				switch (st->airport_type) {
       
   387 					case AT_HELIPORT:
       
   388 					case AT_OILRIG:
       
   389 						return AMS_TTDP_HELI_LAND_HELIPORT;
       
   390 
       
   391 					default:
       
   392 						/* Note, Helidepot and Helistation are treated as airports as
       
   393 						 * helicopters are landing at ground level. */
       
   394 						return AMS_TTDP_HELI_LAND_AIRPORT;
       
   395 				}
       
   396 			}
       
   397 			return AMS_TTDP_FLIGHT_TO_TOWER;
       
   398 
       
   399 		default:
       
   400 			return AMS_TTDP_HANGAR;
       
   401 	}
       
   402 }
       
   403 
       
   404 
       
   405 /* TTDP style aircraft movement action for GRF Action 2 Var 0xE6 */
       
   406 enum {
       
   407 	AMA_TTDP_IN_HANGAR,
       
   408 	AMA_TTDP_ON_PAD1,
       
   409 	AMA_TTDP_ON_PAD2,
       
   410 	AMA_TTDP_ON_PAD3,
       
   411 	AMA_TTDP_HANGAR_TO_PAD1,
       
   412 	AMA_TTDP_HANGAR_TO_PAD2,
       
   413 	AMA_TTDP_HANGAR_TO_PAD3,
       
   414 	AMA_TTDP_LANDING_TO_PAD1,
       
   415 	AMA_TTDP_LANDING_TO_PAD2,
       
   416 	AMA_TTDP_LANDING_TO_PAD3,
       
   417 	AMA_TTDP_PAD1_TO_HANGAR,
       
   418 	AMA_TTDP_PAD2_TO_HANGAR,
       
   419 	AMA_TTDP_PAD3_TO_HANGAR,
       
   420 	AMA_TTDP_PAD1_TO_TAKEOFF,
       
   421 	AMA_TTDP_PAD2_TO_TAKEOFF,
       
   422 	AMA_TTDP_PAD3_TO_TAKEOFF,
       
   423 	AMA_TTDP_HANGAR_TO_TAKOFF,
       
   424 	AMA_TTDP_LANDING_TO_HANGAR,
       
   425 	AMA_TTDP_IN_FLIGHT,
       
   426 };
       
   427 
       
   428 
       
   429 /**
       
   430  * Map OTTD aircraft movement states to TTDPatch style movement actions
       
   431  * (VarAction 2 Variable 0xE6)
       
   432  * This is not fully supported yet but it's enough for Planeset.
       
   433  */
       
   434 static byte MapAircraftMovementAction(const Vehicle *v)
       
   435 {
       
   436 	switch (v->u.air.state) {
       
   437 		case HANGAR:
       
   438 			return (v->cur_speed > 0) ? AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_IN_HANGAR;
       
   439 
       
   440 		case TERM1:
       
   441 		case HELIPAD1:
       
   442 			return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD1 : AMA_TTDP_LANDING_TO_PAD1;
       
   443 
       
   444 		case TERM2:
       
   445 		case HELIPAD2:
       
   446 			return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD2 : AMA_TTDP_LANDING_TO_PAD2;
       
   447 
       
   448 		case TERM3:
       
   449 		case TERM4:
       
   450 		case TERM5:
       
   451 		case TERM6:
       
   452 		case TERM7:
       
   453 		case TERM8:
       
   454 		case HELIPAD3:
       
   455 		case HELIPAD4:
       
   456 			return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD3 : AMA_TTDP_LANDING_TO_PAD3;
       
   457 
       
   458 		case TAKEOFF:      // Moving to takeoff position
       
   459 		case STARTTAKEOFF: // Accelerating down runway
       
   460 		case ENDTAKEOFF:   // Ascent
       
   461 		case HELITAKEOFF:
       
   462 			// TODO Need to find which terminal (or hanger) we've come from. How?
       
   463 			return AMA_TTDP_PAD1_TO_TAKEOFF;
       
   464 
       
   465 		case FLYING:
       
   466 			return AMA_TTDP_IN_FLIGHT;
       
   467 
       
   468 		case LANDING:    // Descent
       
   469 		case ENDLANDING: // On the runway braking
       
   470 		case HELILANDING:
       
   471 		case HELIENDLANDING:
       
   472 			// TODO Need to check terminal we're landing to. Is it known yet?
       
   473 			return (v->current_order.type == OT_GOTO_DEPOT) ?
       
   474 				AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_LANDING_TO_PAD1;
       
   475 
       
   476 		default:
       
   477 			return AMA_TTDP_IN_HANGAR;
       
   478 	}
       
   479 }
       
   480 
       
   481 
       
   482 /* TTDP airport types. Used to map our types to TTDPatch's */
       
   483 enum {
       
   484 	ATP_TTDP_SMALL,
       
   485 	ATP_TTDP_LARGE,
       
   486 	ATP_TTDP_HELIPORT,
       
   487 	ATP_TTDP_OILRIG,
       
   488 };
       
   489 
       
   490 
       
   491 /* Vehicle Resolver Functions */
       
   492 static inline const Vehicle *GRV(const ResolverObject *object)
       
   493 {
       
   494 	return object->scope == VSG_SCOPE_SELF ? object->u.vehicle.self : object->u.vehicle.parent;
       
   495 }
       
   496 
       
   497 
       
   498 static uint32 VehicleGetRandomBits(const ResolverObject *object)
       
   499 {
       
   500 	return GRV(object) == NULL ? 0 : GRV(object)->random_bits;
       
   501 }
       
   502 
       
   503 
       
   504 static uint32 VehicleGetTriggers(const ResolverObject *object)
       
   505 {
       
   506 	return GRV(object) == NULL ? 0 : GRV(object)->waiting_triggers;
       
   507 }
       
   508 
       
   509 
       
   510 static void VehicleSetTriggers(const ResolverObject *object, int triggers)
       
   511 {
       
   512 	/* Evil cast to get around const-ness. This used to be achieved by an
       
   513 	 * innocent looking function pointer cast... Currently I cannot see a
       
   514 	 * way of avoiding this without removing consts deep within gui code.
       
   515 	 */
       
   516 	Vehicle *v = (Vehicle*)GRV(object);
       
   517 
       
   518 	/* This function must only be called when processing triggers -- any
       
   519 	 * other time is an error. */
       
   520 	assert(object->trigger != 0);
       
   521 
       
   522 	if (v != NULL) v->waiting_triggers = triggers;
       
   523 }
       
   524 
       
   525 
       
   526 static uint32 GetVehicleTypeInfo(EngineID engine_type)
       
   527 {
       
   528 	/* Bit 0  Vehicle type is available on the market
       
   529 	 * Bit 1  Vehicle type is in the testing phase
       
   530 	 * Bit 2  Exclusive testing offer for a human player active */
       
   531 	const Engine *e = GetEngine(engine_type);
       
   532 	uint32 var = 0;
       
   533 
       
   534 	if (e->player_avail == 0xFF) SETBIT(var, 0);
       
   535 	if (e->age < e->duration_phase_1) SETBIT(var, 1);
       
   536 	if (e->player_avail > 0 && e->player_avail != 0xFF) SETBIT(var, 2);
       
   537 	return var;
       
   538 }
       
   539 
       
   540 
       
   541 static uint32 GetGRFParameter(EngineID engine_type, byte parameter)
       
   542 {
       
   543 	const GRFFile *file = GetEngineGRF(engine_type);
       
   544 
       
   545 	if (parameter >= file->param_end) return 0;
       
   546 	return file->param[parameter];
       
   547 }
       
   548 
       
   549 
       
   550 static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
       
   551 {
       
   552 	const Vehicle *v = GRV(object);
       
   553 
       
   554 	if (v == NULL) {
       
   555 		/* Vehicle does not exist, so we're in a purchase list */
       
   556 		switch (variable) {
       
   557 			case 0x43: return _current_player; /* Owner information */
       
   558 			case 0x46: return 0;               /* Motion counter */
       
   559 			case 0x48: return GetVehicleTypeInfo(object->u.vehicle.self_type); /* Vehicle Type Info */
       
   560 			case 0xC4: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; /* Build year */
       
   561 			case 0xDA: return INVALID_VEHICLE; /* Next vehicle */
       
   562 			case 0x7F: return GetGRFParameter(object->u.vehicle.self_type, parameter); /* Read GRF parameter */
       
   563 		}
       
   564 
       
   565 		*available = false;
       
   566 		return -1;
       
   567 	}
       
   568 
       
   569 	/* Calculated vehicle parameters */
       
   570 	switch (variable) {
       
   571 		case 0x40: /* Get length of consist */
       
   572 		case 0x41: /* Get length of same consecutive wagons */
       
   573 			if (v->type != VEH_Train) return 1;
       
   574 
       
   575 			{
       
   576 				const Vehicle* u;
       
   577 				byte chain_before = 0;
       
   578 				byte chain_after  = 0;
       
   579 
       
   580 				for (u = GetFirstVehicleInChain(v); u != v; u = u->next) {
       
   581 					chain_before++;
       
   582 					if (variable == 0x41 && u->engine_type != v->engine_type) chain_before = 0;
       
   583 				}
       
   584 
       
   585 				while (u->next != NULL && (variable == 0x40 || u->next->engine_type == v->engine_type)) {
       
   586 					chain_after++;
       
   587 					u = u->next;
       
   588 				}
       
   589 
       
   590 				return chain_before | chain_after << 8 | (chain_before + chain_after + (variable == 0x41)) << 16;
       
   591 			}
       
   592 
       
   593 		case 0x42: { /* Consist cargo information */
       
   594 			/* XXX Missing support for common refit cycle and property 25 */
       
   595 			const Vehicle *u;
       
   596 			byte cargo_classes = 0;
       
   597 			uint common_cargo_best = 0;
       
   598 			uint common_cargos[NUM_GLOBAL_CID];
       
   599 			byte user_def_data = 0;
       
   600 			CargoID cargo;
       
   601 			CargoID common_cargo_type = GC_PASSENGERS;
       
   602 
       
   603 			/* Reset our arrays */
       
   604 			memset(common_cargos, 0, sizeof(common_cargos));
       
   605 
       
   606 			for (u = v; u != NULL; u = u->next) {
       
   607 				/* Skip empty engines */
       
   608 				if (u->cargo_cap == 0) continue;
       
   609 				/* Map from climate to global cargo ID */
       
   610 				cargo = _global_cargo_id[_opt.landscape][u->cargo_type];
       
   611 				cargo_classes |= _cargo_classes[cargo];
       
   612 				common_cargos[cargo]++;
       
   613 				user_def_data |= RailVehInfo(u->engine_type)->user_def_data;
       
   614 			}
       
   615 
       
   616 			/* Pick the most common cargo type */
       
   617 			for (cargo = 0; cargo < NUM_GLOBAL_CID; cargo++) {
       
   618 				if (common_cargos[cargo] > common_cargo_best) {
       
   619 					common_cargo_best = common_cargos[cargo];
       
   620 					common_cargo_type = cargo;
       
   621 				}
       
   622 			}
       
   623 
       
   624 			return cargo_classes | (common_cargo_type << 8) | (user_def_data << 24);
       
   625 		}
       
   626 
       
   627 		case 0x43: /* Player information */
       
   628 			return v->owner;
       
   629 
       
   630 		case 0x44: /* Aircraft information */
       
   631 			if (v->type != VEH_Aircraft) return -1;
       
   632 
       
   633 			{
       
   634 				const Vehicle *w = v->next;
       
   635 				uint16 altitude = v->z_pos - w->z_pos; /* Aircraft height - shadow height */
       
   636 				byte airporttype;
       
   637 
       
   638 				switch (GetStation(v->u.air.targetairport)->airport_type) {
       
   639 					/* Note, Helidepot and Helistation are treated as small airports
       
   640 					 * as they are at ground level. */
       
   641 					case AT_HELIDEPOT:
       
   642 					case AT_HELISTATION:
       
   643 					case AT_COMMUTER:
       
   644 					case AT_SMALL:         airporttype = ATP_TTDP_SMALL; break;
       
   645 					case AT_METROPOLITAN:
       
   646 					case AT_INTERNATIONAL:
       
   647 					case AT_INTERCON:
       
   648 					case AT_LARGE:         airporttype = ATP_TTDP_LARGE; break;
       
   649 					case AT_HELIPORT:      airporttype = ATP_TTDP_HELIPORT; break;
       
   650 					case AT_OILRIG:        airporttype = ATP_TTDP_OILRIG; break;
       
   651 					default:               airporttype = ATP_TTDP_LARGE; break;
       
   652 				}
       
   653 
       
   654 				return (altitude << 8) | airporttype;
       
   655 			}
       
   656 
       
   657 		case 0x46: /* Motion counter */
       
   658 			return v->motion_counter;
       
   659 
       
   660 		case 0x47: { /* Vehicle cargo info */
       
   661 			/* Format: ccccwwtt
       
   662 			 * tt - the cargo type transported by the vehicle,
       
   663 			 *     translated if a translation table has been installed.
       
   664 			 * ww - cargo unit weight in 1/16 tons, same as cargo prop. 0F.
       
   665 			 * cccc - the cargo class value of the cargo transported by the vehicle.
       
   666 			 */
       
   667 			CargoID cid = _global_cargo_id[_opt.landscape][v->cargo_type];
       
   668 
       
   669 			return (_cargo_classes[cid] << 16) | (_cargoc.weights[v->cargo_type] << 8) | cid;
       
   670 		}
       
   671 
       
   672 		case 0x48: return GetVehicleTypeInfo(v->engine_type); /* Vehicle Type Info */
       
   673 
       
   674 		/* Variables which use the parameter */
       
   675 		case 0x60: /* Count consist's engine ID occurance */
       
   676 			if (v->type != VEH_Train) return v->engine_type == parameter;
       
   677 
       
   678 			{
       
   679 				uint count = 0;
       
   680 				for (; v != NULL; v = v->next) {
       
   681 					if (v->engine_type == parameter) count++;
       
   682 				}
       
   683 				return count;
       
   684 			}
       
   685 
       
   686 		case 0x7F: return GetGRFParameter(v->engine_type, parameter); /* Read GRF parameter */
       
   687 	}
       
   688 
       
   689 	/* General vehicle properties */
       
   690 	switch (variable - 0x80) {
       
   691 		case 0x00: return v->type;
       
   692 		case 0x01: return MapOldSubType(v);
       
   693 		case 0x04: return v->index;
       
   694 		case 0x05: return GB(v->index, 8, 8);
       
   695 		case 0x0A: return PackOrder(&v->current_order);
       
   696 		case 0x0B: return GB(PackOrder(&v->current_order), 8, 8);
       
   697 		case 0x0C: return v->num_orders;
       
   698 		case 0x0D: return v->cur_order_index;
       
   699 		case 0x10: return v->load_unload_time_rem;
       
   700 		case 0x11: return GB(v->load_unload_time_rem, 8, 8);
       
   701 		case 0x12: return max(v->date_of_last_service - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
       
   702 		case 0x13: return GB(max(v->date_of_last_service - DAYS_TILL_ORIGINAL_BASE_YEAR, 0), 8, 8);
       
   703 		case 0x14: return v->service_interval;
       
   704 		case 0x15: return GB(v->service_interval, 8, 8);
       
   705 		case 0x16: return v->last_station_visited;
       
   706 		case 0x17: return v->tick_counter;
       
   707 		case 0x18: return v->max_speed;
       
   708 		case 0x19: return GB(v->max_speed, 8, 8);
       
   709 		case 0x1A: return v->x_pos;
       
   710 		case 0x1B: return GB(v->x_pos, 8, 8);
       
   711 		case 0x1C: return v->y_pos;
       
   712 		case 0x1D: return GB(v->y_pos, 8, 8);
       
   713 		case 0x1E: return v->z_pos;
       
   714 		case 0x1F: return object->info_view ? DIR_W : v->direction;
       
   715 		case 0x28: return v->cur_image;
       
   716 		case 0x29: return GB(v->cur_image, 8, 8);
       
   717 		case 0x32: return v->vehstatus;
       
   718 		case 0x33: return 0; // non-existent high byte of vehstatus
       
   719 		case 0x34: return v->cur_speed;
       
   720 		case 0x35: return GB(v->cur_speed, 8, 8);
       
   721 		case 0x36: return v->subspeed;
       
   722 		case 0x37: return v->acceleration;
       
   723 		case 0x39: return v->cargo_type;
       
   724 		case 0x3A: return v->cargo_cap;
       
   725 		case 0x3B: return GB(v->cargo_cap, 8, 8);
       
   726 		case 0x3C: return v->cargo_count;
       
   727 		case 0x3D: return GB(v->cargo_count, 8, 8);
       
   728 		case 0x3E: return v->cargo_source;
       
   729 		case 0x3F: return v->cargo_days;
       
   730 		case 0x40: return v->age;
       
   731 		case 0x41: return GB(v->age, 8, 8);
       
   732 		case 0x42: return v->max_age;
       
   733 		case 0x43: return GB(v->max_age, 8, 8);
       
   734 		case 0x44: return clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
       
   735 		case 0x45: return v->unitnumber;
       
   736 		case 0x46: return v->engine_type;
       
   737 		case 0x47: return GB(v->engine_type, 8, 8);
       
   738 		case 0x48: return v->spritenum;
       
   739 		case 0x49: return v->day_counter;
       
   740 		case 0x4A: return v->breakdowns_since_last_service;
       
   741 		case 0x4B: return v->breakdown_ctr;
       
   742 		case 0x4C: return v->breakdown_delay;
       
   743 		case 0x4D: return v->breakdown_chance;
       
   744 		case 0x4E: return v->reliability;
       
   745 		case 0x4F: return GB(v->reliability, 8, 8);
       
   746 		case 0x50: return v->reliability_spd_dec;
       
   747 		case 0x51: return GB(v->reliability_spd_dec, 8, 8);
       
   748 		case 0x52: return v->profit_this_year;
       
   749 		case 0x53: return GB(v->profit_this_year,  8, 24);
       
   750 		case 0x54: return GB(v->profit_this_year, 16, 16);
       
   751 		case 0x55: return GB(v->profit_this_year, 24,  8);
       
   752 		case 0x56: return v->profit_last_year;
       
   753 		case 0x57: return GB(v->profit_last_year,  8, 24);
       
   754 		case 0x58: return GB(v->profit_last_year, 16, 16);
       
   755 		case 0x59: return GB(v->profit_last_year, 24,  8);
       
   756 		case 0x5A: return v->next == NULL ? INVALID_VEHICLE : v->next->index;
       
   757 		case 0x5C: return v->value;
       
   758 		case 0x5D: return GB(v->value,  8, 24);
       
   759 		case 0x5E: return GB(v->value, 16, 16);
       
   760 		case 0x5F: return GB(v->value, 24,  8);
       
   761 		case 0x60: return v->string_id;
       
   762 		case 0x61: return GB(v->string_id, 8, 8);
       
   763 		case 0x72: return v->cargo_subtype;
       
   764 		case 0x7A: return v->random_bits;
       
   765 		case 0x7B: return v->waiting_triggers;
       
   766 	}
       
   767 
       
   768 	/* Vehicle specific properties */
       
   769 	switch (v->type) {
       
   770 		case VEH_Train:
       
   771 			switch (variable - 0x80) {
       
   772 				case 0x62: return v->u.rail.track;
       
   773 				case 0x66: return v->u.rail.railtype;
       
   774 				case 0x73: return v->u.rail.cached_veh_length;
       
   775 				case 0x74: return v->u.rail.cached_power;
       
   776 				case 0x75: return GB(v->u.rail.cached_power,  8, 24);
       
   777 				case 0x76: return GB(v->u.rail.cached_power, 16, 16);
       
   778 				case 0x77: return GB(v->u.rail.cached_power, 24,  8);
       
   779 				case 0x7C: return v->first->index;
       
   780 				case 0x7D: return GB(v->first->index, 8, 8);
       
   781 				case 0x7F: return 0; // Used for vehicle reversing hack in TTDP
       
   782 			}
       
   783 			break;
       
   784 
       
   785 		case VEH_Road:
       
   786 			switch (variable - 0x80) {
       
   787 				case 0x62: return v->u.road.state;
       
   788 				case 0x64: return v->u.road.blocked_ctr;
       
   789 				case 0x65: return GB(v->u.road.blocked_ctr, 8, 8);
       
   790 				case 0x66: return v->u.road.overtaking;
       
   791 				case 0x67: return v->u.road.overtaking_ctr;
       
   792 				case 0x68: return v->u.road.crashed_ctr;
       
   793 				case 0x69: return GB(v->u.road.crashed_ctr, 8, 8);
       
   794 			}
       
   795 			break;
       
   796 
       
   797 		case VEH_Aircraft:
       
   798 			switch (variable - 0x80) {
       
   799 				case 0x62: return MapAircraftMovementState(v);  // Current movement state
       
   800 				case 0x63: return v->u.air.targetairport;       // Airport to which the action refers
       
   801 				case 0x66: return MapAircraftMovementAction(v); // Current movement action
       
   802 			}
       
   803 			break;
       
   804 	}
       
   805 
       
   806 	DEBUG(grf, 1, "Unhandled vehicle property 0x%X, type 0x%X", variable, v->type);
       
   807 
       
   808 	*available = false;
       
   809 	return -1;
       
   810 }
       
   811 
       
   812 
       
   813 static const SpriteGroup *VehicleResolveReal(const ResolverObject *object, const SpriteGroup *group)
       
   814 {
       
   815 	const Vehicle *v = object->u.vehicle.self;
       
   816 	uint totalsets;
       
   817 	uint set;
       
   818 	bool in_motion;
       
   819 
       
   820 	if (v == NULL) return group->g.real.loading[0];
       
   821 
       
   822 	if (v->type == VEH_Train) {
       
   823 		in_motion = GetFirstVehicleInChain(v)->current_order.type != OT_LOADING;
       
   824 	} else {
       
   825 		in_motion = v->current_order.type != OT_LOADING;
       
   826 	}
       
   827 
       
   828 	totalsets = in_motion ? group->g.real.num_loaded : group->g.real.num_loading;
       
   829 
       
   830 	if (v->cargo_count == v->cargo_cap || totalsets == 1) {
       
   831 		set = totalsets - 1;
       
   832 	} else if (v->cargo_count == 0 || totalsets == 2) {
       
   833 		set = 0;
       
   834 	} else {
       
   835 		set = v->cargo_count * (totalsets - 2) / max(1, v->cargo_cap) + 1;
       
   836 	}
       
   837 
       
   838 	return in_motion ? group->g.real.loaded[set] : group->g.real.loading[set];
       
   839 }
       
   840 
       
   841 
       
   842 static inline void NewVehicleResolver(ResolverObject *res, EngineID engine_type, const Vehicle *v)
       
   843 {
       
   844 	res->GetRandomBits = &VehicleGetRandomBits;
       
   845 	res->GetTriggers   = &VehicleGetTriggers;
       
   846 	res->SetTriggers   = &VehicleSetTriggers;
       
   847 	res->GetVariable   = &VehicleGetVariable;
       
   848 	res->ResolveReal   = &VehicleResolveReal;
       
   849 
       
   850 	res->u.vehicle.self   = v;
       
   851 	res->u.vehicle.parent = (v != NULL && v->type == VEH_Train) ? GetFirstVehicleInChain(v) : v;
       
   852 
       
   853 	res->u.vehicle.self_type = engine_type;
       
   854 
       
   855 	res->info_view = false;
       
   856 
       
   857 	res->callback        = 0;
       
   858 	res->callback_param1 = 0;
       
   859 	res->callback_param2 = 0;
       
   860 	res->last_value      = 0;
       
   861 	res->trigger         = 0;
       
   862 	res->reseed          = 0;
       
   863 }
       
   864 
       
   865 
       
   866 /** Retrieve the SpriteGroup for the specified vehicle.
       
   867  * If the vehicle is not specified, the purchase list group for the engine is
       
   868  * chosen. For trains, an additional engine override lookup is performed.
       
   869  * @param engine Engine type of the vehicle.
       
   870  * @param v      The vehicle itself.
       
   871  * @returns      The selected SpriteGroup for the vehicle.
       
   872  */
       
   873 static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle *v)
       
   874 {
       
   875 	const SpriteGroup *group;
       
   876 	CargoID cargo;
       
   877 
       
   878 	if (v == NULL) {
       
   879 		cargo = GC_PURCHASE;
       
   880 	} else {
       
   881 		cargo = _global_cargo_id[_opt.landscape][v->cargo_type];
       
   882 		assert(cargo != GC_INVALID);
       
   883 
       
   884 		if (v->type == VEH_Train) {
       
   885 			group = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine);
       
   886 
       
   887 			if (group != NULL) return group;
       
   888 		}
       
   889 	}
       
   890 
       
   891 	group = engine_custom_sprites[engine][cargo];
       
   892 	if (group != NULL) return group;
       
   893 
       
   894 	/* Fall back to the default set if the selected cargo type is not defined */
       
   895 	return engine_custom_sprites[engine][GC_DEFAULT];
       
   896 }
       
   897 
       
   898 
       
   899 SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction)
       
   900 {
       
   901 	const SpriteGroup *group;
       
   902 	ResolverObject object;
       
   903 
       
   904 	NewVehicleResolver(&object, engine, v);
       
   905 
       
   906 	group = Resolve(GetVehicleSpriteGroup(engine, v), &object);
       
   907 	if (group == NULL || group->type != SGT_RESULT) return 0;
       
   908 
       
   909 	return group->g.result.sprite + (direction % group->g.result.num_sprites);
       
   910 }
       
   911 
       
   912 
       
   913 SpriteID GetRotorOverrideSprite(EngineID engine, const Vehicle *v, bool info_view)
       
   914 {
       
   915 	const SpriteGroup *group;
       
   916 	ResolverObject object;
       
   917 
       
   918 	assert(engine >= AIRCRAFT_ENGINES_INDEX);
       
   919 	assert(engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES);
       
   920 
       
   921 	/* Only valid for helicopters */
       
   922 	assert(!(AircraftVehInfo(engine)->subtype & AIR_CTOL));
       
   923 
       
   924 	NewVehicleResolver(&object, engine, v);
       
   925 
       
   926 	object.info_view = info_view;
       
   927 
       
   928 	group = heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX];
       
   929 	group = Resolve(group, &object);
       
   930 
       
   931 	if (group == NULL || group->type != SGT_RESULT) return 0;
       
   932 
       
   933 	if (v == NULL) return group->g.result.sprite;
       
   934 
       
   935 	return group->g.result.sprite + (info_view ? 0 : (v->next->next->u.air.state % group->g.result.num_sprites));
       
   936 }
       
   937 
       
   938 
       
   939 /**
       
   940  * Check if a wagon is currently using a wagon override
       
   941  * @param v The wagon to check
       
   942  * @return true if it is using an override, false otherwise
       
   943  */
       
   944 bool UsesWagonOverride(const Vehicle* v)
       
   945 {
       
   946 	assert(v->type == VEH_Train);
       
   947 	return GetWagonOverrideSpriteSet(v->engine_type, _global_cargo_id[_opt.landscape][v->cargo_type], v->u.rail.first_engine) != NULL;
       
   948 }
       
   949 
       
   950 /**
       
   951  * Evaluate a newgrf callback for vehicles
       
   952  * @param callback The callback to evalute
       
   953  * @param param1   First parameter of the callback
       
   954  * @param param2   Second parameter of the callback
       
   955  * @param engine   Engine type of the vehicle to evaluate the callback for
       
   956  * @param vehicle  The vehicle to evaluate the callback for, or NULL if it doesnt exist yet
       
   957  * @return The value the callback returned, or CALLBACK_FAILED if it failed
       
   958  */
       
   959 uint16 GetVehicleCallback(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
       
   960 {
       
   961 	const SpriteGroup *group;
       
   962 	ResolverObject object;
       
   963 
       
   964 	NewVehicleResolver(&object, engine, v);
       
   965 
       
   966 	object.callback        = callback;
       
   967 	object.callback_param1 = param1;
       
   968 	object.callback_param2 = param2;
       
   969 
       
   970 	group = Resolve(GetVehicleSpriteGroup(engine, v), &object);
       
   971 	if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED;
       
   972 
       
   973 	return group->g.callback.result;
       
   974 }
       
   975 
       
   976 /**
       
   977  * Evaluate a newgrf callback for vehicles with a different vehicle for parent scope.
       
   978  * @param callback The callback to evalute
       
   979  * @param param1   First parameter of the callback
       
   980  * @param param2   Second parameter of the callback
       
   981  * @param engine   Engine type of the vehicle to evaluate the callback for
       
   982  * @param v        The vehicle to evaluate the callback for, or NULL if it doesnt exist yet
       
   983  * @param parent   The vehicle to use for parent scope
       
   984  * @return The value the callback returned, or CALLBACK_FAILED if it failed
       
   985  */
       
   986 uint16 GetVehicleCallbackParent(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent)
       
   987 {
       
   988 	const SpriteGroup *group;
       
   989 	ResolverObject object;
       
   990 
       
   991 	NewVehicleResolver(&object, engine, v);
       
   992 
       
   993 	object.callback        = callback;
       
   994 	object.callback_param1 = param1;
       
   995 	object.callback_param2 = param2;
       
   996 
       
   997 	object.u.vehicle.parent = parent;
       
   998 
       
   999 	group = Resolve(GetVehicleSpriteGroup(engine, v), &object);
       
  1000 	if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED;
       
  1001 
       
  1002 	return group->g.callback.result;
       
  1003 }
       
  1004 
       
  1005 static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first)
       
  1006 {
       
  1007 	const SpriteGroup *group;
       
  1008 	ResolverObject object;
       
  1009 	byte new_random_bits;
       
  1010 
       
  1011 	/* We can't trigger a non-existent vehicle... */
       
  1012 	assert(v != NULL);
       
  1013 
       
  1014 	NewVehicleResolver(&object, v->engine_type, v);
       
  1015 
       
  1016 	object.trigger = trigger;
       
  1017 
       
  1018 	group = Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object);
       
  1019 
       
  1020 	new_random_bits = Random();
       
  1021 	v->random_bits &= ~object.reseed;
       
  1022 	v->random_bits |= (first ? new_random_bits : base_random_bits) & object.reseed;
       
  1023 
       
  1024 	switch (trigger) {
       
  1025 		case VEHICLE_TRIGGER_NEW_CARGO:
       
  1026 			/* All vehicles in chain get ANY_NEW_CARGO trigger now.
       
  1027 			 * So we call it for the first one and they will recurse. */
       
  1028 			/* Indexing part of vehicle random bits needs to be
       
  1029 			 * same for all triggered vehicles in the chain (to get
       
  1030 			 * all the random-cargo wagons carry the same cargo,
       
  1031 			 * i.e.), so we give them all the NEW_CARGO triggered
       
  1032 			 * vehicle's portion of random bits. */
       
  1033 			assert(first);
       
  1034 			DoTriggerVehicle(GetFirstVehicleInChain(v), VEHICLE_TRIGGER_ANY_NEW_CARGO, new_random_bits, false);
       
  1035 			break;
       
  1036 
       
  1037 		case VEHICLE_TRIGGER_DEPOT:
       
  1038 			/* We now trigger the next vehicle in chain recursively.
       
  1039 			 * The random bits portions may be different for each
       
  1040 			 * vehicle in chain. */
       
  1041 			if (v->next != NULL) DoTriggerVehicle(v->next, trigger, 0, true);
       
  1042 			break;
       
  1043 
       
  1044 		case VEHICLE_TRIGGER_EMPTY:
       
  1045 			/* We now trigger the next vehicle in chain
       
  1046 			 * recursively.  The random bits portions must be same
       
  1047 			 * for each vehicle in chain, so we give them all
       
  1048 			 * first chained vehicle's portion of random bits. */
       
  1049 			if (v->next != NULL) DoTriggerVehicle(v->next, trigger, first ? new_random_bits : base_random_bits, false);
       
  1050 			break;
       
  1051 
       
  1052 		case VEHICLE_TRIGGER_ANY_NEW_CARGO:
       
  1053 			/* Now pass the trigger recursively to the next vehicle
       
  1054 			 * in chain. */
       
  1055 			assert(!first);
       
  1056 			if (v->next != NULL) DoTriggerVehicle(v->next, VEHICLE_TRIGGER_ANY_NEW_CARGO, base_random_bits, false);
       
  1057 			break;
       
  1058 	}
       
  1059 }
       
  1060 
       
  1061 void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
       
  1062 {
       
  1063 	if (trigger == VEHICLE_TRIGGER_DEPOT) {
       
  1064 		// store that the vehicle entered a depot this tick
       
  1065 		VehicleEnteredDepotThisTick(v);
       
  1066 	}
       
  1067 
       
  1068 	DoTriggerVehicle(v, trigger, 0, true);
       
  1069 }
       
  1070 
       
  1071 StringID _engine_custom_names[TOTAL_NUM_ENGINES];
       
  1072 
       
  1073 void SetCustomEngineName(EngineID engine, StringID name)
       
  1074 {
       
  1075 	assert(engine < lengthof(_engine_custom_names));
       
  1076 	_engine_custom_names[engine] = name;
       
  1077 }
       
  1078 
       
  1079 void UnloadCustomEngineNames(void)
       
  1080 {
       
  1081 	EngineID i;
       
  1082 	for (i = 0; i < TOTAL_NUM_ENGINES; i++) {
       
  1083 		_engine_custom_names[i] = 0;
       
  1084 	}
       
  1085 }
       
  1086 
       
  1087 StringID GetCustomEngineName(EngineID engine)
       
  1088 {
       
  1089 	return _engine_custom_names[engine] == 0 ? _engine_name_strings[engine] : _engine_custom_names[engine];
       
  1090 }
       
  1091 
       
  1092 // Functions for changing the order of vehicle purchase lists
       
  1093 // This is currently only implemented for rail vehicles.
       
  1094 static EngineID _engine_list_order[NUM_TRAIN_ENGINES];
       
  1095 static byte _engine_list_position[NUM_TRAIN_ENGINES];
       
  1096 
       
  1097 void ResetEngineListOrder(void)
       
  1098 {
       
  1099 	EngineID i;
       
  1100 
       
  1101 	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
       
  1102 		_engine_list_order[i] = i;
       
  1103 		_engine_list_position[i] = i;
       
  1104 	}
       
  1105 }
       
  1106 
       
  1107 /**
       
  1108  * Get the EngineID at position pos.
       
  1109  * Used when drawing a(n unsorted) list of engines.
       
  1110  * @param pos List position/
       
  1111  * @return The EngineID at the requested position.
       
  1112  */
       
  1113 EngineID GetRailVehAtPosition(EngineID pos)
       
  1114 {
       
  1115 	if (pos < NUM_TRAIN_ENGINES) return _engine_list_order[pos];
       
  1116 	return pos;
       
  1117 }
       
  1118 
       
  1119 /**
       
  1120  * Get the list position of an engine.
       
  1121  * Used when sorting a list of engines.
       
  1122  * @param engine ID of the engine.
       
  1123  * @return The list position of the engine.
       
  1124  */
       
  1125 uint16 ListPositionOfEngine(EngineID engine)
       
  1126 {
       
  1127 	if (engine < NUM_TRAIN_ENGINES) return _engine_list_position[engine];
       
  1128 	return engine;
       
  1129 }
       
  1130 
       
  1131 void AlterRailVehListOrder(EngineID engine, EngineID target)
       
  1132 {
       
  1133 	EngineID i;
       
  1134 	bool moving = false;
       
  1135 
       
  1136 	if (engine == target) return;
       
  1137 
       
  1138 	// First, remove our ID from the list.
       
  1139 	for (i = 0; i < NUM_TRAIN_ENGINES - 1; i++) {
       
  1140 		if (_engine_list_order[i] == engine) moving = true;
       
  1141 		if (moving) _engine_list_order[i] = _engine_list_order[i + 1];
       
  1142 	}
       
  1143 
       
  1144 	// Now, insert it again, before the target engine.
       
  1145 	for (i = NUM_TRAIN_ENGINES - 1; i > 0; i--) {
       
  1146 		_engine_list_order[i] = _engine_list_order[i - 1];
       
  1147 		if (_engine_list_order[i] == target) {
       
  1148 			_engine_list_order[i - 1] = engine;
       
  1149 			break;
       
  1150 		}
       
  1151 	}
       
  1152 
       
  1153 	// Update the engine list position (a reverse of engine list order)
       
  1154 	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
       
  1155 		_engine_list_position[_engine_list_order[i]] = i;
       
  1156 	}
       
  1157 }