src/train_cmd.cpp
branchnoai
changeset 10294 7798ae816af8
parent 10249 58810805030e
child 10355 ee4b5f7a5bf2
equal deleted inserted replaced
10292:7856e972f8aa 10294:7798ae816af8
    47 #include "autoreplace_gui.h"
    47 #include "autoreplace_gui.h"
    48 #include "gfx_func.h"
    48 #include "gfx_func.h"
    49 #include "ai/ai.h"
    49 #include "ai/ai.h"
    50 #include "settings_type.h"
    50 #include "settings_type.h"
    51 #include "order_func.h"
    51 #include "order_func.h"
       
    52 #include "newgrf_station.h"
       
    53 #include "effectvehicle_func.h"
    52 
    54 
    53 #include "table/strings.h"
    55 #include "table/strings.h"
    54 #include "table/train_cmd.h"
    56 #include "table/train_cmd.h"
    55 
    57 
    56 static bool TrainCheckIfLineEnds(Vehicle *v);
    58 static bool TrainCheckIfLineEnds(Vehicle *v);
   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);
  2217 		SND_0A_TRAIN_HORN,
  2221 		SND_0A_TRAIN_HORN,
  2218 		SND_47_MAGLEV_2,
  2222 		SND_47_MAGLEV_2,
  2219 		SND_41_MAGLEV
  2223 		SND_41_MAGLEV
  2220 	};
  2224 	};
  2221 
  2225 
       
  2226 	if (IsTileType(this->tile, MP_STATION)) StationAnimationTrigger(NULL, this->tile, STAT_ANIM_TRAIN_DEPARTS);
       
  2227 
  2222 	if (PlayVehicleSound(this, VSE_START)) return;
  2228 	if (PlayVehicleSound(this, VSE_START)) return;
  2223 
  2229 
  2224 	EngineID engtype = this->engine_type;
  2230 	EngineID engtype = this->engine_type;
  2225 	SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], this);
  2231 	SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], this);
  2226 }
  2232 }
  2637 			0
  2643 			0
  2638 		);
  2644 		);
  2639 	}
  2645 	}
  2640 
  2646 
  2641 	v->BeginLoading();
  2647 	v->BeginLoading();
       
  2648 
       
  2649 	StationAnimationTrigger(st, v->tile, STAT_ANIM_TRAIN_ARRIVES);
  2642 }
  2650 }
  2643 
  2651 
  2644 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2652 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2645 {
  2653 {
  2646 	byte old_z = v->z_pos;
  2654 	byte old_z = v->z_pos;
  3232 				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
  3240 				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
  3233 		}
  3241 		}
  3234 
  3242 
  3235 		if (!(v->vehstatus & VS_HIDDEN)) {
  3243 		if (!(v->vehstatus & VS_HIDDEN)) {
  3236 			Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
  3244 			Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
  3237 			if (u != NULL) u->u.special.animation_state = v->breakdown_delay * 2;
  3245 			if (u != NULL) u->u.effect.animation_state = v->breakdown_delay * 2;
  3238 		}
  3246 		}
  3239 	}
  3247 	}
  3240 
  3248 
  3241 	if (!(v->tick_counter & 3)) {
  3249 	if (!(v->tick_counter & 3)) {
  3242 		if (!--v->breakdown_delay) {
  3250 		if (!--v->breakdown_delay) {
  3421 	if (v->breakdown_ctr != 0) {
  3429 	if (v->breakdown_ctr != 0) {
  3422 		if (v->breakdown_ctr <= 2) {
  3430 		if (v->breakdown_ctr <= 2) {
  3423 			HandleBrokenTrain(v);
  3431 			HandleBrokenTrain(v);
  3424 			return;
  3432 			return;
  3425 		}
  3433 		}
  3426 		v->breakdown_ctr--;
  3434 		if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
  3427 	}
  3435 	}
  3428 
  3436 
  3429 	if (HasBit(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) {
  3437 	if (HasBit(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) {
  3430 		ReverseTrainDirection(v);
  3438 		ReverseTrainDirection(v);
  3431 	}
  3439 	}