mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r16376) -Codechange: Vehicle::Tick() now returns false if the vehicle was deleted
This commit is contained in:
parent
561d97880d
commit
b687ac51ee
|
@ -106,7 +106,7 @@ struct Aircraft : public Vehicle {
|
|||
int GetDisplayMaxSpeed() const { return this->max_speed; }
|
||||
Money GetRunningCost() const;
|
||||
bool IsInDepot() const { return (this->vehstatus & VS_HIDDEN) != 0 && IsHangarTile(this->tile); }
|
||||
void Tick();
|
||||
bool Tick();
|
||||
void OnNewDay();
|
||||
TileIndex GetOrderStationLocation(StationID station);
|
||||
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
|
||||
|
|
|
@ -1137,7 +1137,7 @@ static bool AircraftController(Vehicle *v)
|
|||
}
|
||||
|
||||
|
||||
static void HandleCrashedAircraft(Vehicle *v)
|
||||
static bool HandleCrashedAircraft(Vehicle *v)
|
||||
{
|
||||
v->u.air.crashed_counter += 3;
|
||||
|
||||
|
@ -1182,7 +1182,11 @@ static void HandleCrashedAircraft(Vehicle *v)
|
|||
}
|
||||
|
||||
delete v;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void HandleBrokenAircraft(Vehicle *v)
|
||||
|
@ -1988,16 +1992,15 @@ static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *apc)
|
|||
return false; // it shouldn't get here anytime, but just to be sure
|
||||
}
|
||||
|
||||
static void AircraftEventHandler(Vehicle *v, int loop)
|
||||
static bool AircraftEventHandler(Vehicle *v, int loop)
|
||||
{
|
||||
v->tick_counter++;
|
||||
|
||||
if (v->vehstatus & VS_CRASHED) {
|
||||
HandleCrashedAircraft(v);
|
||||
return;
|
||||
return HandleCrashedAircraft(v);
|
||||
}
|
||||
|
||||
if (v->vehstatus & VS_STOPPED) return;
|
||||
if (v->vehstatus & VS_STOPPED) return true;
|
||||
|
||||
/* aircraft is broken down? */
|
||||
if (v->breakdown_ctr != 0) {
|
||||
|
@ -2012,14 +2015,16 @@ static void AircraftEventHandler(Vehicle *v, int loop)
|
|||
ProcessOrders(v);
|
||||
v->HandleLoading(loop != 0);
|
||||
|
||||
if (v->current_order.IsType(OT_LOADING) || v->current_order.IsType(OT_LEAVESTATION)) return;
|
||||
if (v->current_order.IsType(OT_LOADING) || v->current_order.IsType(OT_LEAVESTATION)) return true;
|
||||
|
||||
AirportGoToNextPosition(v);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Aircraft::Tick()
|
||||
bool Aircraft::Tick()
|
||||
{
|
||||
if (!IsNormalAircraft(this)) return;
|
||||
if (!IsNormalAircraft(this)) return true;
|
||||
|
||||
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
|
||||
|
||||
|
@ -2030,10 +2035,13 @@ void Aircraft::Tick()
|
|||
this->current_order_time++;
|
||||
|
||||
for (uint i = 0; i != 2; i++) {
|
||||
AircraftEventHandler(this, i);
|
||||
if (this->type != VEH_AIRCRAFT) // In case it was deleted
|
||||
break;
|
||||
/* stop if the aircraft was deleted */
|
||||
if (!AircraftEventHandler(this, i)) return false;
|
||||
assert(this->IsValid());
|
||||
assert(IsNormalAircraft(this));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -180,12 +180,12 @@ static void SetDisasterVehiclePos(Vehicle *v, int x, int y, byte z)
|
|||
* 2: Clear the runway after some time and remove crashed zeppeliner
|
||||
* If not airport was found, only state 0 is reached until zeppeliner leaves map
|
||||
*/
|
||||
static void DisasterTick_Zeppeliner(Vehicle *v)
|
||||
static bool DisasterTick_Zeppeliner(Vehicle *v)
|
||||
{
|
||||
v->tick_counter++;
|
||||
|
||||
if (v->current_order.GetDestination() < 2) {
|
||||
if (HasBit(v->tick_counter, 0)) return;
|
||||
if (HasBit(v->tick_counter, 0)) return true;
|
||||
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
|
||||
|
@ -215,12 +215,16 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
|||
}
|
||||
}
|
||||
|
||||
if (v->y_pos >= ((int)MapSizeY() + 9) * TILE_SIZE - 1) delete v;
|
||||
return;
|
||||
if (v->y_pos >= ((int)MapSizeY() + 9) * TILE_SIZE - 1) {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (v->current_order.GetDestination() > 2) {
|
||||
if (++v->age <= 13320) return;
|
||||
if (++v->age <= 13320) return true;
|
||||
|
||||
if (IsValidTile(v->tile) &&
|
||||
IsTileType(v->tile, MP_STATION) &&
|
||||
|
@ -232,7 +236,7 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
|||
|
||||
SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos);
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
int x = v->x_pos;
|
||||
|
@ -267,6 +271,8 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
|||
IsAirport(v->tile)) {
|
||||
SETBITS(GetStationByTile(v->tile)->airport_flags, RUNWAY_IN_block);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,7 +281,7 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
|||
* 1: Home in on a road vehicle and crash it >:)
|
||||
* If not road vehicle was found, only state 0 is used and Ufo disappears after a while
|
||||
*/
|
||||
static void DisasterTick_Ufo(Vehicle *v)
|
||||
static bool DisasterTick_Ufo(Vehicle *v)
|
||||
{
|
||||
v->u.disaster.image_override = (HasBit(++v->tick_counter, 3)) ? SPR_UFO_SMALL_SCOUT_DARKER : SPR_UFO_SMALL_SCOUT;
|
||||
|
||||
|
@ -287,11 +293,11 @@ static void DisasterTick_Ufo(Vehicle *v)
|
|||
v->direction = GetDirectionTowards(v, x, y);
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (++v->age < 6) {
|
||||
v->dest_tile = RandomTile();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
v->current_order.SetDestination(1);
|
||||
|
||||
|
@ -300,17 +306,18 @@ static void DisasterTick_Ufo(Vehicle *v)
|
|||
if (u->type == VEH_ROAD && IsRoadVehFront(u)) {
|
||||
v->dest_tile = u->index;
|
||||
v->age = 0;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
delete v;
|
||||
return false;
|
||||
} else {
|
||||
/* Target a vehicle */
|
||||
Vehicle *u = Vehicle::Get(v->dest_tile);
|
||||
if (u->type != VEH_ROAD || !IsRoadVehFront(u)) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos);
|
||||
|
@ -351,8 +358,11 @@ static void DisasterTick_Ufo(Vehicle *v)
|
|||
CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
|
||||
SndPlayVehicleFx(SND_12_EXPLOSION, v);
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DestructIndustry(Industry *i)
|
||||
|
@ -378,7 +388,7 @@ static void DestructIndustry(Industry *i)
|
|||
* @param news_message The string that's used as news message.
|
||||
* @param industry_flag Only attack industries that have this flag set.
|
||||
*/
|
||||
static void DisasterTick_Aircraft(Vehicle *v, uint16 image_override, bool leave_at_top, StringID news_message, IndustryBehaviour industry_flag)
|
||||
static bool DisasterTick_Aircraft(Vehicle *v, uint16 image_override, bool leave_at_top, StringID news_message, IndustryBehaviour industry_flag)
|
||||
{
|
||||
v->tick_counter++;
|
||||
v->u.disaster.image_override = (v->current_order.GetDestination() == 1 && HasBit(v->tick_counter, 2)) ? image_override : 0;
|
||||
|
@ -388,7 +398,7 @@ static void DisasterTick_Aircraft(Vehicle *v, uint16 image_override, bool leave_
|
|||
|
||||
if ((leave_at_top && gp.x < (-10 * TILE_SIZE)) || (!leave_at_top && gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1)) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v->current_order.GetDestination() == 2) {
|
||||
|
@ -422,10 +432,10 @@ static void DisasterTick_Aircraft(Vehicle *v, uint16 image_override, bool leave_
|
|||
int x = v->x_pos - (15 * TILE_SIZE);
|
||||
int y = v->y_pos;
|
||||
|
||||
if ((uint)x > MapMaxX() * TILE_SIZE - 1) return;
|
||||
if ((uint)x > MapMaxX() * TILE_SIZE - 1) return true;
|
||||
|
||||
TileIndex tile = TileVirtXY(x, y);
|
||||
if (!IsTileType(tile, MP_INDUSTRY)) return;
|
||||
if (!IsTileType(tile, MP_INDUSTRY)) return true;
|
||||
|
||||
IndustryID ind = GetIndustryIndex(tile);
|
||||
v->dest_tile = ind;
|
||||
|
@ -435,29 +445,33 @@ static void DisasterTick_Aircraft(Vehicle *v, uint16 image_override, bool leave_
|
|||
v->age = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Airplane handling. */
|
||||
static void DisasterTick_Airplane(Vehicle *v)
|
||||
static bool DisasterTick_Airplane(Vehicle *v)
|
||||
{
|
||||
DisasterTick_Aircraft(v, SPR_F_15_FIRING, true, STR_NEWS_DISASTER_AIRPLANE_OIL_REFINERY, INDUSTRYBEH_AIRPLANE_ATTACKS);
|
||||
return DisasterTick_Aircraft(v, SPR_F_15_FIRING, true, STR_NEWS_DISASTER_AIRPLANE_OIL_REFINERY, INDUSTRYBEH_AIRPLANE_ATTACKS);
|
||||
}
|
||||
|
||||
/** Helicopter handling. */
|
||||
static void DisasterTick_Helicopter(Vehicle *v)
|
||||
static bool DisasterTick_Helicopter(Vehicle *v)
|
||||
{
|
||||
DisasterTick_Aircraft(v, SPR_AH_64A_FIRING, false, STR_NEWS_DISASTER_HELICOPTER_FACTORY, INDUSTRYBEH_CHOPPER_ATTACKS);
|
||||
return DisasterTick_Aircraft(v, SPR_AH_64A_FIRING, false, STR_NEWS_DISASTER_HELICOPTER_FACTORY, INDUSTRYBEH_CHOPPER_ATTACKS);
|
||||
}
|
||||
|
||||
/** Helicopter rotor blades; keep these spinning */
|
||||
static void DisasterTick_Helicopter_Rotors(Vehicle *v)
|
||||
static bool DisasterTick_Helicopter_Rotors(Vehicle *v)
|
||||
{
|
||||
v->tick_counter++;
|
||||
if (HasBit(v->tick_counter, 0)) return;
|
||||
if (HasBit(v->tick_counter, 0)) return true;
|
||||
|
||||
if (++v->cur_image > SPR_ROTOR_MOVING_3) v->cur_image = SPR_ROTOR_MOVING_1;
|
||||
|
||||
VehicleMove(v, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -466,7 +480,7 @@ static void DisasterTick_Helicopter_Rotors(Vehicle *v)
|
|||
* 1: Land there and breakdown all trains in a radius of 12 tiles; and now we wait...
|
||||
* because as soon as the Ufo lands, a fighter jet, a Skyranger, is called to clear up the mess
|
||||
*/
|
||||
static void DisasterTick_Big_Ufo(Vehicle *v)
|
||||
static bool DisasterTick_Big_Ufo(Vehicle *v)
|
||||
{
|
||||
v->tick_counter++;
|
||||
|
||||
|
@ -478,19 +492,19 @@ static void DisasterTick_Big_Ufo(Vehicle *v)
|
|||
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!IsValidTile(v->dest_tile)) {
|
||||
/* Make sure we don't land outside the map. */
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
byte z = GetSlopeZ(v->x_pos, v->y_pos);
|
||||
if (z < v->z_pos) {
|
||||
SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
v->current_order.SetDestination(2);
|
||||
|
@ -514,7 +528,7 @@ static void DisasterTick_Big_Ufo(Vehicle *v)
|
|||
|
||||
if (!Vehicle::CanAllocateItem(2)) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
u = new DisasterVehicle();
|
||||
|
||||
|
@ -533,12 +547,12 @@ static void DisasterTick_Big_Ufo(Vehicle *v)
|
|||
v->direction = GetDirectionTowards(v, x, y);
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (++v->age < 6) {
|
||||
v->dest_tile = RandomTile();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
v->current_order.SetDestination(1);
|
||||
|
||||
|
@ -554,13 +568,15 @@ static void DisasterTick_Big_Ufo(Vehicle *v)
|
|||
v->dest_tile = tile;
|
||||
v->age = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skyranger destroying (Big) Ufo handling, v->current_order.dest states:
|
||||
* 0: Home in on landed Ufo and shoot it down
|
||||
*/
|
||||
static void DisasterTick_Big_Ufo_Destroyer(Vehicle *v)
|
||||
static bool DisasterTick_Big_Ufo_Destroyer(Vehicle *v)
|
||||
{
|
||||
v->tick_counter++;
|
||||
|
||||
|
@ -569,12 +585,12 @@ static void DisasterTick_Big_Ufo_Destroyer(Vehicle *v)
|
|||
|
||||
if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v->current_order.GetDestination() == 0) {
|
||||
Vehicle *u = Vehicle::Get(v->u.disaster.big_ufo_destroyer_target);
|
||||
if (Delta(v->x_pos, u->x_pos) > TILE_SIZE) return;
|
||||
if (Delta(v->x_pos, u->x_pos) > TILE_SIZE) return true;
|
||||
v->current_order.SetDestination(1);
|
||||
|
||||
CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE);
|
||||
|
@ -598,22 +614,24 @@ static void DisasterTick_Big_Ufo_Destroyer(Vehicle *v)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submarine, v->current_order.dest states:
|
||||
* Unused, just float around aimlessly and pop up at different places, turning around
|
||||
*/
|
||||
static void DisasterTick_Submarine(Vehicle *v)
|
||||
static bool DisasterTick_Submarine(Vehicle *v)
|
||||
{
|
||||
v->tick_counter++;
|
||||
|
||||
if (++v->age > 8880) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasBit(v->tick_counter, 0)) return;
|
||||
if (!HasBit(v->tick_counter, 0)) return true;
|
||||
|
||||
TileIndex tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
|
||||
if (IsValidTile(tile)) {
|
||||
|
@ -621,16 +639,22 @@ static void DisasterTick_Submarine(Vehicle *v)
|
|||
if (trackbits == TRACK_BIT_ALL && !Chance16(1, 90)) {
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
v->direction = ChangeDir(v->direction, GB(Random(), 0, 1) ? DIRDIFF_90RIGHT : DIRDIFF_90LEFT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void DisasterTick_NULL(Vehicle *v) {}
|
||||
typedef void DisasterVehicleTickProc(Vehicle *v);
|
||||
static bool DisasterTick_NULL(Vehicle *v)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool DisasterVehicleTickProc(Vehicle *v);
|
||||
|
||||
static DisasterVehicleTickProc * const _disastervehicle_tick_procs[] = {
|
||||
DisasterTick_Zeppeliner, DisasterTick_NULL,
|
||||
|
@ -644,9 +668,9 @@ static DisasterVehicleTickProc * const _disastervehicle_tick_procs[] = {
|
|||
};
|
||||
|
||||
|
||||
void DisasterVehicle::Tick()
|
||||
bool DisasterVehicle::Tick()
|
||||
{
|
||||
_disastervehicle_tick_procs[this->subtype](this);
|
||||
return _disastervehicle_tick_procs[this->subtype](this);
|
||||
}
|
||||
|
||||
typedef void DisasterInitProc();
|
||||
|
|
|
@ -20,7 +20,7 @@ static void ChimneySmokeInit(Vehicle *v)
|
|||
v->progress = GB(r, 16, 3);
|
||||
}
|
||||
|
||||
static void ChimneySmokeTick(Vehicle *v)
|
||||
static bool ChimneySmokeTick(Vehicle *v)
|
||||
{
|
||||
if (v->progress > 0) {
|
||||
v->progress--;
|
||||
|
@ -28,7 +28,7 @@ static void ChimneySmokeTick(Vehicle *v)
|
|||
TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
|
||||
if (!IsTileType(tile, MP_INDUSTRY)) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v->cur_image != SPR_CHIMNEY_SMOKE_7) {
|
||||
|
@ -39,6 +39,8 @@ static void ChimneySmokeTick(Vehicle *v)
|
|||
v->progress = 7;
|
||||
VehicleMove(v, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SteamSmokeInit(Vehicle *v)
|
||||
|
@ -47,7 +49,7 @@ static void SteamSmokeInit(Vehicle *v)
|
|||
v->progress = 12;
|
||||
}
|
||||
|
||||
static void SteamSmokeTick(Vehicle *v)
|
||||
static bool SteamSmokeTick(Vehicle *v)
|
||||
{
|
||||
bool moved = false;
|
||||
|
||||
|
@ -63,12 +65,14 @@ static void SteamSmokeTick(Vehicle *v)
|
|||
v->cur_image++;
|
||||
} else {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
moved = true;
|
||||
}
|
||||
|
||||
if (moved) VehicleMove(v, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DieselSmokeInit(Vehicle *v)
|
||||
|
@ -77,7 +81,7 @@ static void DieselSmokeInit(Vehicle *v)
|
|||
v->progress = 0;
|
||||
}
|
||||
|
||||
static void DieselSmokeTick(Vehicle *v)
|
||||
static bool DieselSmokeTick(Vehicle *v)
|
||||
{
|
||||
v->progress++;
|
||||
|
||||
|
@ -90,8 +94,11 @@ static void DieselSmokeTick(Vehicle *v)
|
|||
VehicleMove(v, true);
|
||||
} else {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ElectricSparkInit(Vehicle *v)
|
||||
|
@ -100,7 +107,7 @@ static void ElectricSparkInit(Vehicle *v)
|
|||
v->progress = 1;
|
||||
}
|
||||
|
||||
static void ElectricSparkTick(Vehicle *v)
|
||||
static bool ElectricSparkTick(Vehicle *v)
|
||||
{
|
||||
if (v->progress < 2) {
|
||||
v->progress++;
|
||||
|
@ -111,8 +118,11 @@ static void ElectricSparkTick(Vehicle *v)
|
|||
VehicleMove(v, true);
|
||||
} else {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SmokeInit(Vehicle *v)
|
||||
|
@ -121,7 +131,7 @@ static void SmokeInit(Vehicle *v)
|
|||
v->progress = 12;
|
||||
}
|
||||
|
||||
static void SmokeTick(Vehicle *v)
|
||||
static bool SmokeTick(Vehicle *v)
|
||||
{
|
||||
bool moved = false;
|
||||
|
||||
|
@ -137,12 +147,14 @@ static void SmokeTick(Vehicle *v)
|
|||
v->cur_image++;
|
||||
} else {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
moved = true;
|
||||
}
|
||||
|
||||
if (moved) VehicleMove(v, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ExplosionLargeInit(Vehicle *v)
|
||||
|
@ -151,7 +163,7 @@ static void ExplosionLargeInit(Vehicle *v)
|
|||
v->progress = 0;
|
||||
}
|
||||
|
||||
static void ExplosionLargeTick(Vehicle *v)
|
||||
static bool ExplosionLargeTick(Vehicle *v)
|
||||
{
|
||||
v->progress++;
|
||||
if ((v->progress & 3) == 0) {
|
||||
|
@ -160,8 +172,11 @@ static void ExplosionLargeTick(Vehicle *v)
|
|||
VehicleMove(v, true);
|
||||
} else {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void BreakdownSmokeInit(Vehicle *v)
|
||||
|
@ -170,7 +185,7 @@ static void BreakdownSmokeInit(Vehicle *v)
|
|||
v->progress = 0;
|
||||
}
|
||||
|
||||
static void BreakdownSmokeTick(Vehicle *v)
|
||||
static bool BreakdownSmokeTick(Vehicle *v)
|
||||
{
|
||||
v->progress++;
|
||||
if ((v->progress & 7) == 0) {
|
||||
|
@ -185,7 +200,10 @@ static void BreakdownSmokeTick(Vehicle *v)
|
|||
v->u.effect.animation_state--;
|
||||
if (v->u.effect.animation_state == 0) {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ExplosionSmallInit(Vehicle *v)
|
||||
|
@ -194,7 +212,7 @@ static void ExplosionSmallInit(Vehicle *v)
|
|||
v->progress = 0;
|
||||
}
|
||||
|
||||
static void ExplosionSmallTick(Vehicle *v)
|
||||
static bool ExplosionSmallTick(Vehicle *v)
|
||||
{
|
||||
v->progress++;
|
||||
if ((v->progress & 3) == 0) {
|
||||
|
@ -203,8 +221,11 @@ static void ExplosionSmallTick(Vehicle *v)
|
|||
VehicleMove(v, true);
|
||||
} else {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void BulldozerInit(Vehicle *v)
|
||||
|
@ -254,7 +275,7 @@ static const struct {
|
|||
{ 0, -1 }
|
||||
};
|
||||
|
||||
static void BulldozerTick(Vehicle *v)
|
||||
static bool BulldozerTick(Vehicle *v)
|
||||
{
|
||||
v->progress++;
|
||||
if ((v->progress & 7) == 0) {
|
||||
|
@ -271,11 +292,13 @@ static void BulldozerTick(Vehicle *v)
|
|||
v->u.effect.animation_state++;
|
||||
if (v->u.effect.animation_state == lengthof(_bulldozer_movement)) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
VehicleMove(v, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void BubbleInit(Vehicle *v)
|
||||
|
@ -435,18 +458,18 @@ static const BubbleMovement * const _bubble_movement[] = {
|
|||
_bubble_absorb,
|
||||
};
|
||||
|
||||
static void BubbleTick(Vehicle *v)
|
||||
static bool BubbleTick(Vehicle *v)
|
||||
{
|
||||
uint anim_state;
|
||||
|
||||
v->progress++;
|
||||
if ((v->progress & 3) != 0) return;
|
||||
if ((v->progress & 3) != 0) return true;
|
||||
|
||||
if (v->spritenum == 0) {
|
||||
v->cur_image++;
|
||||
if (v->cur_image < SPR_BUBBLE_GENERATE_3) {
|
||||
VehicleMove(v, true);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (v->u.effect.animation_substate != 0) {
|
||||
v->spritenum = GB(Random(), 0, 2) + 1;
|
||||
|
@ -462,7 +485,7 @@ static void BubbleTick(Vehicle *v)
|
|||
|
||||
if (b->y == 4 && b->x == 0) {
|
||||
delete v;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (b->y == 4 && b->x == 1) {
|
||||
|
@ -492,11 +515,13 @@ static void BubbleTick(Vehicle *v)
|
|||
v->cur_image = SPR_BUBBLE_0 + b->image;
|
||||
|
||||
VehicleMove(v, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
typedef void EffectInitProc(Vehicle *v);
|
||||
typedef void EffectTickProc(Vehicle *v);
|
||||
typedef bool EffectTickProc(Vehicle *v);
|
||||
|
||||
static EffectInitProc * const _effect_init_procs[] = {
|
||||
ChimneySmokeInit,
|
||||
|
@ -558,9 +583,9 @@ Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVeh
|
|||
return CreateEffectVehicle(v->x_pos + x, v->y_pos + y, v->z_pos + z, type);
|
||||
}
|
||||
|
||||
void EffectVehicle::Tick()
|
||||
bool EffectVehicle::Tick()
|
||||
{
|
||||
_effect_tick_procs[this->subtype](this);
|
||||
return _effect_tick_procs[this->subtype](this);
|
||||
}
|
||||
|
||||
void EffectVehicle::UpdateDeltaXY(Direction direction)
|
||||
|
|
|
@ -31,7 +31,7 @@ struct EffectVehicle : public Vehicle {
|
|||
|
||||
const char *GetTypeString() const { return "special vehicle"; }
|
||||
void UpdateDeltaXY(Direction direction);
|
||||
void Tick();
|
||||
bool Tick();
|
||||
};
|
||||
|
||||
#endif /* EFFECTVEHICLE_BASE_H */
|
||||
|
|
|
@ -99,7 +99,7 @@ struct RoadVehicle : public Vehicle {
|
|||
Money GetRunningCost() const { return RoadVehInfo(this->engine_type)->running_cost * GetPriceByIndex(RoadVehInfo(this->engine_type)->running_cost_class); }
|
||||
bool IsInDepot() const { return this->u.road.state == RVSB_IN_DEPOT; }
|
||||
bool IsStoppedInDepot() const;
|
||||
void Tick();
|
||||
bool Tick();
|
||||
void OnNewDay();
|
||||
TileIndex GetOrderStationLocation(StationID station);
|
||||
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
|
||||
|
|
|
@ -540,7 +540,7 @@ static void RoadVehSetRandomDirection(Vehicle *v)
|
|||
} while ((v = v->Next()) != NULL);
|
||||
}
|
||||
|
||||
static void RoadVehIsCrashed(Vehicle *v)
|
||||
static bool RoadVehIsCrashed(Vehicle *v)
|
||||
{
|
||||
v->u.road.crashed_ctr++;
|
||||
if (v->u.road.crashed_ctr == 2) {
|
||||
|
@ -548,8 +548,12 @@ static void RoadVehIsCrashed(Vehicle *v)
|
|||
} else if (v->u.road.crashed_ctr <= 45) {
|
||||
if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v);
|
||||
} else if (v->u.road.crashed_ctr >= 2220 && !(v->tick_counter & 0x1F)) {
|
||||
bool ret = v->Next() != NULL;
|
||||
DeleteLastRoadVeh(v);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Vehicle *EnumCheckRoadVehCrashTrain(Vehicle *v, void *data)
|
||||
|
@ -1735,7 +1739,7 @@ again:
|
|||
return true;
|
||||
}
|
||||
|
||||
static void RoadVehController(Vehicle *v)
|
||||
static bool RoadVehController(Vehicle *v)
|
||||
{
|
||||
/* decrease counters */
|
||||
v->tick_counter++;
|
||||
|
@ -1744,8 +1748,7 @@ static void RoadVehController(Vehicle *v)
|
|||
|
||||
/* handle crashed */
|
||||
if (v->vehstatus & VS_CRASHED) {
|
||||
RoadVehIsCrashed(v);
|
||||
return;
|
||||
return RoadVehIsCrashed(v);
|
||||
}
|
||||
|
||||
RoadVehCheckTrainCrash(v);
|
||||
|
@ -1754,19 +1757,19 @@ static void RoadVehController(Vehicle *v)
|
|||
if (v->breakdown_ctr != 0) {
|
||||
if (v->breakdown_ctr <= 2) {
|
||||
HandleBrokenRoadVeh(v);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
|
||||
}
|
||||
|
||||
if (v->vehstatus & VS_STOPPED) return;
|
||||
if (v->vehstatus & VS_STOPPED) return true;
|
||||
|
||||
ProcessOrders(v);
|
||||
v->HandleLoading();
|
||||
|
||||
if (v->current_order.IsType(OT_LOADING)) return;
|
||||
if (v->current_order.IsType(OT_LOADING)) return true;
|
||||
|
||||
if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return;
|
||||
if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return true;
|
||||
|
||||
/* Check how far the vehicle needs to proceed */
|
||||
int j = RoadVehAccelerate(v);
|
||||
|
@ -1796,6 +1799,8 @@ static void RoadVehController(Vehicle *v)
|
|||
}
|
||||
|
||||
if (v->progress == 0) v->progress = j;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void AgeRoadVehCargo(Vehicle *v)
|
||||
|
@ -1804,14 +1809,16 @@ static void AgeRoadVehCargo(Vehicle *v)
|
|||
v->cargo.AgeCargo();
|
||||
}
|
||||
|
||||
void RoadVehicle::Tick()
|
||||
bool RoadVehicle::Tick()
|
||||
{
|
||||
AgeRoadVehCargo(this);
|
||||
|
||||
if (IsRoadVehFront(this)) {
|
||||
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
|
||||
RoadVehController(this);
|
||||
return RoadVehController(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CheckIfRoadVehNeedsService(Vehicle *v)
|
||||
|
|
|
@ -40,7 +40,7 @@ struct Ship: public Vehicle {
|
|||
int GetDisplayMaxSpeed() const { return this->max_speed / 2; }
|
||||
Money GetRunningCost() const;
|
||||
bool IsInDepot() const { return this->u.ship.state == TRACK_BIT_DEPOT; }
|
||||
void Tick();
|
||||
bool Tick();
|
||||
void OnNewDay();
|
||||
TileIndex GetOrderStationLocation(StationID station);
|
||||
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
|
||||
|
|
|
@ -708,12 +708,14 @@ static void AgeShipCargo(Vehicle *v)
|
|||
v->cargo.AgeCargo();
|
||||
}
|
||||
|
||||
void Ship::Tick()
|
||||
bool Ship::Tick()
|
||||
{
|
||||
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
|
||||
|
||||
AgeShipCargo(this);
|
||||
ShipController(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Build a ship.
|
||||
|
|
|
@ -329,7 +329,7 @@ struct Train : public Vehicle {
|
|||
Money GetRunningCost() const;
|
||||
bool IsInDepot() const { return CheckTrainInDepot(this, false) != -1; }
|
||||
bool IsStoppedInDepot() const { return CheckTrainStoppedInDepot(this) >= 0; }
|
||||
void Tick();
|
||||
bool Tick();
|
||||
void OnNewDay();
|
||||
TileIndex GetOrderStationLocation(StationID station);
|
||||
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
|
||||
|
|
|
@ -4022,7 +4022,7 @@ static void ChangeTrainDirRandomly(Vehicle *v)
|
|||
} while ((v = v->Next()) != NULL);
|
||||
}
|
||||
|
||||
static void HandleCrashedTrain(Vehicle *v)
|
||||
static bool HandleCrashedTrain(Vehicle *v)
|
||||
{
|
||||
int state = ++v->u.rail.crash_anim_pos;
|
||||
|
||||
|
@ -4052,9 +4052,13 @@ static void HandleCrashedTrain(Vehicle *v)
|
|||
if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
|
||||
|
||||
if (state >= 4440 && !(v->tick_counter & 0x1F)) {
|
||||
bool ret = v->Next() != NULL;
|
||||
DeleteLastWagon(v);
|
||||
InvalidateWindow(WC_REPLACE_VEHICLE, (v->group_id << 16) | VEH_TRAIN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void HandleBrokenTrain(Vehicle *v)
|
||||
|
@ -4249,12 +4253,11 @@ static bool TrainCheckIfLineEnds(Vehicle *v)
|
|||
}
|
||||
|
||||
|
||||
static void TrainLocoHandler(Vehicle *v, bool mode)
|
||||
static bool TrainLocoHandler(Vehicle *v, bool mode)
|
||||
{
|
||||
/* train has crashed? */
|
||||
if (v->vehstatus & VS_CRASHED) {
|
||||
if (!mode) HandleCrashedTrain(v);
|
||||
return;
|
||||
return mode ? true : HandleCrashedTrain(v); // 'this' can be deleted here
|
||||
}
|
||||
|
||||
if (v->u.rail.force_proceed != 0) {
|
||||
|
@ -4267,7 +4270,7 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
|||
if (v->breakdown_ctr != 0) {
|
||||
if (v->breakdown_ctr <= 2) {
|
||||
HandleBrokenTrain(v);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
|
||||
}
|
||||
|
@ -4277,7 +4280,7 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
|||
}
|
||||
|
||||
/* exit if train is stopped */
|
||||
if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return;
|
||||
if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return true;
|
||||
|
||||
bool valid_order = v->current_order.IsValid() && v->current_order.GetType() != OT_CONDITIONAL;
|
||||
if (ProcessOrders(v) && CheckReverseTrain(v)) {
|
||||
|
@ -4285,14 +4288,14 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
|||
v->cur_speed = 0;
|
||||
v->subspeed = 0;
|
||||
ReverseTrainDirection(v);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
v->HandleLoading(mode);
|
||||
|
||||
if (v->current_order.IsType(OT_LOADING)) return;
|
||||
if (v->current_order.IsType(OT_LOADING)) return true;
|
||||
|
||||
if (CheckTrainStayInDepot(v)) return;
|
||||
if (CheckTrainStayInDepot(v)) return true;
|
||||
|
||||
if (!mode) HandleLocomotiveSmokeCloud(v);
|
||||
|
||||
|
@ -4308,7 +4311,7 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
|||
/* Should we try reversing this tick if still stuck? */
|
||||
bool turn_around = v->load_unload_time_rem % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.wait_for_pbs_path < 255;
|
||||
|
||||
if (!turn_around && v->load_unload_time_rem % _settings_game.pf.path_backoff_interval != 0 && v->u.rail.force_proceed == 0) return;
|
||||
if (!turn_around && v->load_unload_time_rem % _settings_game.pf.path_backoff_interval != 0 && v->u.rail.force_proceed == 0) return true;
|
||||
if (!TryPathReserve(v)) {
|
||||
/* Still stuck. */
|
||||
if (turn_around) ReverseTrainDirection(v);
|
||||
|
@ -4326,7 +4329,7 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
|||
v->load_unload_time_rem = 0;
|
||||
}
|
||||
/* Exit if force proceed not pressed, else reset stuck flag anyway. */
|
||||
if (v->u.rail.force_proceed == 0) return;
|
||||
if (v->u.rail.force_proceed == 0) return true;
|
||||
ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
|
||||
v->load_unload_time_rem = 0;
|
||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
||||
|
@ -4336,7 +4339,7 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
|||
if (v->current_order.IsType(OT_LEAVESTATION)) {
|
||||
v->current_order.Free();
|
||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
int j = UpdateTrainSpeed(v);
|
||||
|
@ -4387,6 +4390,8 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
|||
}
|
||||
|
||||
if (v->progress == 0) v->progress = j; // Save unused spd for next time, if TrainController didn't set progress
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4412,7 +4417,7 @@ Money Train::GetRunningCost() const
|
|||
}
|
||||
|
||||
|
||||
void Train::Tick()
|
||||
bool Train::Tick()
|
||||
{
|
||||
if (_age_cargo_skip_counter == 0) this->cargo.AgeCargo();
|
||||
|
||||
|
@ -4420,17 +4425,25 @@ void Train::Tick()
|
|||
|
||||
if (IsFrontEngine(this)) {
|
||||
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
|
||||
|
||||
this->current_order_time++;
|
||||
|
||||
TrainLocoHandler(this, false);
|
||||
if (!TrainLocoHandler(this, false)) return false;
|
||||
|
||||
/* make sure vehicle wasn't deleted. */
|
||||
if (this->type == VEH_TRAIN && IsFrontEngine(this))
|
||||
TrainLocoHandler(this, true);
|
||||
assert(this->IsValid());
|
||||
assert(IsFrontEngine(this));
|
||||
|
||||
return TrainLocoHandler(this, true);
|
||||
} else if (IsFreeWagon(this) && HASBITS(this->vehstatus, VS_CRASHED)) {
|
||||
/* Delete flooded standalone wagon chain */
|
||||
if (++this->u.rail.crash_anim_pos >= 4400) delete this;
|
||||
if (++this->u.rail.crash_anim_pos >= 4400) {
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CheckIfTrainNeedsService(Vehicle *v)
|
||||
|
|
|
@ -604,7 +604,10 @@ void CallVehicleTicks()
|
|||
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
v->Tick();
|
||||
/* Vehicle could be deleted in this tick */
|
||||
if (!v->Tick()) continue;
|
||||
|
||||
assert(v->IsValid());
|
||||
|
||||
switch (v->type) {
|
||||
default: break;
|
||||
|
|
|
@ -423,8 +423,9 @@ public:
|
|||
|
||||
/**
|
||||
* Calls the tick handler of the vehicle
|
||||
* @return is this vehicle still valid?
|
||||
*/
|
||||
virtual void Tick() {};
|
||||
virtual bool Tick() { return true; };
|
||||
|
||||
/**
|
||||
* Calls the new day handler of the vehicle
|
||||
|
@ -620,7 +621,7 @@ struct DisasterVehicle : public Vehicle {
|
|||
|
||||
const char *GetTypeString() const { return "disaster vehicle"; }
|
||||
void UpdateDeltaXY(Direction direction);
|
||||
void Tick();
|
||||
bool Tick();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -639,7 +640,6 @@ struct InvalidVehicle : public Vehicle {
|
|||
virtual ~InvalidVehicle() {}
|
||||
|
||||
const char *GetTypeString() const { return "invalid vehicle"; }
|
||||
void Tick() {}
|
||||
};
|
||||
|
||||
#define FOR_ALL_VEHICLES_FROM(v, start) for (v = Vehicle::Get(start); v != NULL; v = (v->index + 1U < Vehicle::GetPoolSize()) ? Vehicle::Get(v->index + 1) : NULL) if (v->IsValid())
|
||||
|
|
Loading…
Reference in New Issue