237 if (!IsArticulatedPart(u)) { |
239 if (!IsArticulatedPart(u)) { |
238 /* Check powered wagon / visual effect callback */ |
240 /* Check powered wagon / visual effect callback */ |
239 if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) { |
241 if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) { |
240 uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u); |
242 uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u); |
241 |
243 |
242 if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback; |
244 if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = GB(callback, 0, 8); |
243 } |
245 } |
244 |
246 |
245 if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON && |
247 if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON && |
246 UsesWagonOverride(u) && !HasBit(u->u.rail.cached_vis_effect, 7)) { |
248 UsesWagonOverride(u) && !HasBit(u->u.rail.cached_vis_effect, 7)) { |
247 /* wagon is powered */ |
249 /* wagon is powered */ |
464 uint weight = v->u.rail.cached_weight; |
466 uint weight = v->u.rail.cached_weight; |
465 assert(weight != 0); |
467 assert(weight != 0); |
466 v->acceleration = Clamp(power / weight * 4, 1, 255); |
468 v->acceleration = Clamp(power / weight * 4, 1, 255); |
467 } |
469 } |
468 |
470 |
469 int Train::GetImage(Direction direction) const |
471 SpriteID Train::GetImage(Direction direction) const |
470 { |
472 { |
471 int img = this->spritenum; |
473 uint8 spritenum = this->spritenum; |
472 int base; |
474 SpriteID sprite; |
473 |
475 |
474 if (HasBit(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction); |
476 if (HasBit(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction); |
475 |
477 |
476 if (is_custom_sprite(img)) { |
478 if (is_custom_sprite(spritenum)) { |
477 base = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img))); |
479 sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum))); |
478 if (base != 0) return base; |
480 if (sprite != 0) return sprite; |
479 img = _orig_rail_vehicle_info[this->engine_type].image_index; |
481 |
480 } |
482 spritenum = _orig_rail_vehicle_info[this->engine_type].image_index; |
481 |
483 } |
482 base = _engine_sprite_base[img] + ((direction + _engine_sprite_add[img]) & _engine_sprite_and[img]); |
484 |
483 |
485 sprite = _engine_sprite_base[spritenum] + ((direction + _engine_sprite_add[spritenum]) & _engine_sprite_and[spritenum]); |
484 if (this->cargo.Count() >= this->cargo_cap / 2U) base += _wagon_full_adder[img]; |
486 |
485 return base; |
487 if (this->cargo.Count() >= this->cargo_cap / 2U) sprite += _wagon_full_adder[spritenum]; |
|
488 |
|
489 return sprite; |
|
490 } |
|
491 |
|
492 static SpriteID GetRailIcon(EngineID engine, bool rear_head, int &y) |
|
493 { |
|
494 Direction dir = rear_head ? DIR_E : DIR_W; |
|
495 uint8 spritenum = RailVehInfo(engine)->image_index; |
|
496 |
|
497 if (is_custom_sprite(spritenum)) { |
|
498 SpriteID sprite = GetCustomVehicleIcon(engine, dir); |
|
499 if (sprite != 0) { |
|
500 y += _traininfo_vehicle_pitch; // TODO Make this per-GRF |
|
501 return sprite; |
|
502 } |
|
503 |
|
504 spritenum = _orig_rail_vehicle_info[engine].image_index; |
|
505 } |
|
506 |
|
507 if (rear_head) spritenum++; |
|
508 |
|
509 return ((6 + _engine_sprite_add[spritenum]) & _engine_sprite_and[spritenum]) + _engine_sprite_base[spritenum]; |
486 } |
510 } |
487 |
511 |
488 void DrawTrainEngine(int x, int y, EngineID engine, SpriteID pal) |
512 void DrawTrainEngine(int x, int y, EngineID engine, SpriteID pal) |
489 { |
513 { |
490 const RailVehicleInfo *rvi = RailVehInfo(engine); |
514 if (RailVehInfo(engine)->railveh_type == RAILVEH_MULTIHEAD) { |
491 |
515 int yf = y; |
492 int img = rvi->image_index; |
516 int yr = y; |
493 SpriteID image = 0; |
517 |
494 |
518 SpriteID spritef = GetRailIcon(engine, false, yf); |
495 if (is_custom_sprite(img)) { |
519 SpriteID spriter = GetRailIcon(engine, true, yr); |
496 image = GetCustomVehicleIcon(engine, DIR_W); |
520 DrawSprite(spritef, pal, x - 14, yf); |
497 if (image == 0) { |
521 DrawSprite(spriter, pal, x + 15, yr); |
498 img = _orig_rail_vehicle_info[engine].image_index; |
522 } else { |
499 } else { |
523 SpriteID sprite = GetRailIcon(engine, false, y); |
500 y += _traininfo_vehicle_pitch; |
524 DrawSprite(sprite, pal, x, y); |
501 } |
525 } |
502 } |
|
503 if (image == 0) { |
|
504 image = (6 & _engine_sprite_and[img]) + _engine_sprite_base[img]; |
|
505 } |
|
506 |
|
507 if (rvi->railveh_type == RAILVEH_MULTIHEAD) { |
|
508 DrawSprite(image, pal, x - 14, y); |
|
509 x += 15; |
|
510 image = 0; |
|
511 if (is_custom_sprite(img)) { |
|
512 image = GetCustomVehicleIcon(engine, DIR_E); |
|
513 if (image == 0) img = _orig_rail_vehicle_info[engine].image_index; |
|
514 } |
|
515 if (image == 0) { |
|
516 image = |
|
517 ((6 + _engine_sprite_add[img + 1]) & _engine_sprite_and[img + 1]) + |
|
518 _engine_sprite_base[img + 1]; |
|
519 } |
|
520 } |
|
521 DrawSprite(image, pal, x, y); |
|
522 } |
526 } |
523 |
527 |
524 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags) |
528 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags) |
525 { |
529 { |
526 const RailVehicleInfo *rvi = RailVehInfo(engine); |
530 const RailVehicleInfo *rvi = RailVehInfo(engine); |
1277 if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; |
1281 if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; |
1278 |
1282 |
1279 /* Check if this train can be started/stopped. The callback will fail or |
1283 /* Check if this train can be started/stopped. The callback will fail or |
1280 * return 0xFF if it can. */ |
1284 * return 0xFF if it can. */ |
1281 uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v); |
1285 uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v); |
1282 if (callback != CALLBACK_FAILED && callback != 0xFF) { |
1286 if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) { |
1283 StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback); |
1287 StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback); |
1284 return_cmd_error(error); |
1288 return_cmd_error(error); |
1285 } |
1289 } |
1286 |
1290 |
1287 if (v->vehstatus & VS_STOPPED && v->u.rail.cached_power == 0) return_cmd_error(STR_TRAIN_START_NO_CATENARY); |
1291 if (v->vehstatus & VS_STOPPED && v->u.rail.cached_power == 0) return_cmd_error(STR_TRAIN_START_NO_CATENARY); |