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 } |