Changeset - r21729:37178ad3391a
[Not reviewed]
master
0 4 0
rubidium - 10 years ago 2014-09-21 11:12:42
rubidium@openttd.org
(svn r26872) -Change: give the disaster vehicles the same treatment as aircraft in r26866; make the ascend and descend if needed to cross high mountains (based on patch by ic111)
4 files changed with 16 insertions and 12 deletions:
0 comments (0 inline, 0 general)
src/aircraft_cmd.cpp
Show inline comments
 
@@ -27,24 +27,25 @@
 
#include "sound_func.h"
 
#include "cheat_type.h"
 
#include "company_base.h"
 
#include "ai/ai.hpp"
 
#include "game/game.hpp"
 
#include "company_func.h"
 
#include "effectvehicle_func.h"
 
#include "station_base.h"
 
#include "engine_base.h"
 
#include "core/random_func.hpp"
 
#include "core/backup_type.hpp"
 
#include "zoom_func.h"
 
#include "disaster_vehicle.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 

	
 
void Aircraft::UpdateDeltaXY(Direction direction)
 
{
 
	this->x_offs = -1;
 
	this->y_offs = -1;
 
	this->x_extent = 2;
 
	this->y_extent = 2;
 

	
 
@@ -754,24 +755,26 @@ int GetAircraftFlightLevel(T *v, bool ta
 
		z--;
 
	} else if (HasBit(v->flags, VAF_IN_MIN_HEIGHT_CORRECTION) && z >= aircraft_middle_altitude) {
 
		/* Now, we have corrected altitude enough. */
 
		ClrBit(v->flags, VAF_IN_MIN_HEIGHT_CORRECTION);
 
	} else if (HasBit(v->flags, VAF_IN_MAX_HEIGHT_CORRECTION) && z <= aircraft_middle_altitude) {
 
		/* Now, we have corrected altitude enough. */
 
		ClrBit(v->flags, VAF_IN_MAX_HEIGHT_CORRECTION);
 
	}
 

	
 
	return z;
 
}
 

	
 
template int GetAircraftFlightLevel(DisasterVehicle *v, bool takeoff = false);
 

	
 
/**
 
 * Find the entry point to an airport depending on direction which
 
 * the airport is being approached from. Each airport can have up to
 
 * four entry points for its approach system so that approaching
 
 * aircraft do not fly through each other or are forced to do 180
 
 * degree turns during the approach. The arrivals are grouped into
 
 * four sectors dependent on the DiagDirection from which the airport
 
 * is approached.
 
 *
 
 * @param v   The vehicle that is approaching the airport
 
 * @param apc The Airport Class being approached.
 
 * @param rotation The rotation of the airport.
src/disaster_vehicle.cpp
Show inline comments
 
@@ -46,26 +46,24 @@
 
#include "game/game.hpp"
 
#include "company_base.h"
 
#include "core/random_func.hpp"
 
#include "core/backup_type.hpp"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 

	
 
/** Delay counter for considering the next disaster. */
 
uint16 _disaster_delay;
 

	
 
static const uint INITIAL_DISASTER_VEHICLE_ZPOS = 135; ///< Initial Z position of flying disaster vehicles.
 

	
 
static void DisasterClearSquare(TileIndex tile)
 
{
 
	if (EnsureNoVehicleOnGround(tile).Failed()) return;
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_RAILWAY:
 
			if (Company::IsHumanID(GetTileOwner(tile)) && !IsRailDepot(tile)) {
 
				Backup<CompanyByte> cur_company(_current_company, OWNER_WATER, FILE_LINE);
 
				DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
				cur_company.Restore();
 

	
 
				/* update signals in buffer */
 
@@ -128,29 +126,30 @@ void DisasterVehicle::UpdateImage()
 
DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubType subtype, VehicleID big_ufo_destroyer_target) :
 
		SpecializedVehicleBase(), big_ufo_destroyer_target(big_ufo_destroyer_target)
 
{
 
	this->x_pos = x;
 
	this->y_pos = y;
 
	switch (subtype) {
 
		case ST_ZEPPELINER:
 
		case ST_SMALL_UFO:
 
		case ST_AIRPLANE:
 
		case ST_HELICOPTER:
 
		case ST_BIG_UFO:
 
		case ST_BIG_UFO_DESTROYER:
 
			this->z_pos = INITIAL_DISASTER_VEHICLE_ZPOS;
 
			GetAircraftFlightLevelBounds(this, &this->z_pos, NULL);
 
			break;
 

	
 
		case ST_HELICOPTER_ROTORS:
 
			this->z_pos = INITIAL_DISASTER_VEHICLE_ZPOS + ROTOR_Z_OFFSET;
 
			GetAircraftFlightLevelBounds(this, &this->z_pos, NULL);
 
			this->z_pos += ROTOR_Z_OFFSET;
 
			break;
 

	
 
		case ST_SMALL_SUBMARINE:
 
		case ST_BIG_SUBMARINE:
 
			this->z_pos = 0;
 
			break;
 

	
 
		case ST_ZEPPELINER_SHADOW:
 
		case ST_SMALL_UFO_SHADOW:
 
		case ST_AIRPLANE_SHADOW:
 
		case ST_HELICOPTER_SHADOW:
 
		case ST_BIG_UFO_SHADOW:
 
@@ -220,25 +219,25 @@ void DisasterVehicle::UpdatePosition(int
 
 * 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 bool DisasterTick_Zeppeliner(DisasterVehicle *v)
 
{
 
	v->tick_counter++;
 

	
 
	if (v->current_order.GetDestination() < 2) {
 
		if (HasBit(v->tick_counter, 0)) return true;
 

	
 
		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 

	
 
		v->UpdatePosition(gp.x, gp.y, v->z_pos);
 
		v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
 

	
 
		if (v->current_order.GetDestination() == 1) {
 
			if (++v->age == 38) {
 
				v->current_order.SetDestination(2);
 
				v->age = 0;
 
			}
 

	
 
			if (GB(v->tick_counter, 0, 3) == 0) CreateEffectVehicleRel(v, 0, -17, 2, EV_CRASH_SMOKE);
 

	
 
		} else if (v->current_order.GetDestination() == 0) {
 
			if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
 
				v->current_order.SetDestination(1);
 
@@ -258,25 +257,25 @@ static bool DisasterTick_Zeppeliner(Disa
 
		return true;
 
	}
 

	
 
	if (v->current_order.GetDestination() > 2) {
 
		if (++v->age <= 13320) return true;
 

	
 
		if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
 
			Station *st = Station::GetByTile(v->tile);
 
			CLRBITS(st->airport.flags, RUNWAY_IN_block);
 
			AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCleared(st->index));
 
		}
 

	
 
		v->UpdatePosition(v->x_pos, v->y_pos, v->z_pos);
 
		v->UpdatePosition(v->x_pos, v->y_pos, GetAircraftFlightLevel(v));
 
		delete v;
 
		return false;
 
	}
 

	
 
	int x = v->x_pos;
 
	int y = v->y_pos;
 
	int z = GetSlopePixelZ(x, y);
 
	if (z < v->z_pos) z = v->z_pos - 1;
 
	v->UpdatePosition(x, y, z);
 

	
 
	if (++v->age == 1) {
 
		CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
 
@@ -314,25 +313,25 @@ static bool DisasterTick_Zeppeliner(Disa
 
 */
 
static bool DisasterTick_Ufo(DisasterVehicle *v)
 
{
 
	v->image_override = (HasBit(++v->tick_counter, 3)) ? SPR_UFO_SMALL_SCOUT_DARKER : SPR_UFO_SMALL_SCOUT;
 

	
 
	if (v->current_order.GetDestination() == 0) {
 
		/* Fly around randomly */
 
		int x = TileX(v->dest_tile) * TILE_SIZE;
 
		int y = TileY(v->dest_tile) * TILE_SIZE;
 
		if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= (int)TILE_SIZE) {
 
			v->direction = GetDirectionTowards(v, x, y);
 
			GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 
			v->UpdatePosition(gp.x, gp.y, v->z_pos);
 
			v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
 
			return true;
 
		}
 
		if (++v->age < 6) {
 
			v->dest_tile = RandomTile();
 
			return true;
 
		}
 
		v->current_order.SetDestination(1);
 

	
 
		uint n = 0; // Total number of targetable road vehicles.
 
		RoadVehicle *u;
 
		FOR_ALL_ROADVEHICLES(u) {
 
			if (u->IsFrontEngine()) n++;
 
@@ -417,25 +416,25 @@ static void DestructIndustry(Industry *i
 
 * @param v The disaster vehicle.
 
 * @param image_override The image at the time the aircraft is firing.
 
 * @param leave_at_top True iff the vehicle leaves the map at the north side.
 
 * @param news_message The string that's used as news message.
 
 * @param industry_flag Only attack industries that have this flag set.
 
 */
 
static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, bool leave_at_top, StringID news_message, IndustryBehaviour industry_flag)
 
{
 
	v->tick_counter++;
 
	v->image_override = (v->current_order.GetDestination() == 1 && HasBit(v->tick_counter, 2)) ? image_override : 0;
 

	
 
	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 
	v->UpdatePosition(gp.x, gp.y, v->z_pos);
 
	v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
 

	
 
	if ((leave_at_top && gp.x < (-10 * (int)TILE_SIZE)) || (!leave_at_top && gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1)) {
 
		delete v;
 
		return false;
 
	}
 

	
 
	if (v->current_order.GetDestination() == 2) {
 
		if (GB(v->tick_counter, 0, 2) == 0) {
 
			Industry *i = Industry::Get(v->dest_tile); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid
 
			int x = TileX(i->location.tile) * TILE_SIZE;
 
			int y = TileY(i->location.tile) * TILE_SIZE;
 
			uint32 r = Random();
 
@@ -514,25 +513,25 @@ static bool DisasterTick_Helicopter_Roto
 
 */
 
static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
 
{
 
	v->tick_counter++;
 

	
 
	if (v->current_order.GetDestination() == 1) {
 
		int x = TileX(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
 
		int y = TileY(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
 
		if (Delta(v->x_pos, x) + Delta(v->y_pos, y) >= 8) {
 
			v->direction = GetDirectionTowards(v, x, y);
 

	
 
			GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 
			v->UpdatePosition(gp.x, gp.y, v->z_pos);
 
			v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
 
			return true;
 
		}
 

	
 
		if (!IsValidTile(v->dest_tile)) {
 
			/* Make sure we don't land outside the map. */
 
			delete v;
 
			return false;
 
		}
 

	
 
		int z = GetSlopePixelZ(v->x_pos, v->y_pos);
 
		if (z < v->z_pos) {
 
			v->UpdatePosition(v->x_pos, v->y_pos, v->z_pos - 1);
 
@@ -559,25 +558,25 @@ static bool DisasterTick_Big_Ufo(Disaste
 
			delete v;
 
			return false;
 
		}
 
		DisasterVehicle *u = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER, v->index);
 
		DisasterVehicle *w = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER_SHADOW);
 
		u->SetNext(w);
 
	} else if (v->current_order.GetDestination() == 0) {
 
		int x = TileX(v->dest_tile) * TILE_SIZE;
 
		int y = TileY(v->dest_tile) * TILE_SIZE;
 
		if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= (int)TILE_SIZE) {
 
			v->direction = GetDirectionTowards(v, x, y);
 
			GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 
			v->UpdatePosition(gp.x, gp.y, v->z_pos);
 
			v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
 
			return true;
 
		}
 

	
 
		if (++v->age < 6) {
 
			v->dest_tile = RandomTile();
 
			return true;
 
		}
 
		v->current_order.SetDestination(1);
 

	
 
		TileIndex tile_org = RandomTile();
 
		TileIndex tile = tile_org;
 
		do {
 
@@ -594,25 +593,25 @@ static bool DisasterTick_Big_Ufo(Disaste
 
	return true;
 
}
 

	
 
/**
 
 * Skyranger destroying (Big) Ufo handling, v->current_order.dest states:
 
 * 0: Home in on landed Ufo and shoot it down
 
 */
 
static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v)
 
{
 
	v->tick_counter++;
 

	
 
	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 
	v->UpdatePosition(gp.x, gp.y, v->z_pos);
 
	v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
 

	
 
	if (gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1) {
 
		delete v;
 
		return false;
 
	}
 

	
 
	if (v->current_order.GetDestination() == 0) {
 
		Vehicle *u = Vehicle::Get(v->big_ufo_destroyer_target);
 
		if (Delta(v->x_pos, u->x_pos) > (int)TILE_SIZE) return true;
 
		v->current_order.SetDestination(1);
 

	
 
		CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE);
 
@@ -956,25 +955,25 @@ void ReleaseDisastersTargetingIndustry(I
 
 * @param vehicle deleted vehicle
 
 */
 
void ReleaseDisastersTargetingVehicle(VehicleID vehicle)
 
{
 
	DisasterVehicle *v;
 
	FOR_ALL_DISASTERVEHICLES(v) {
 
		/* primary disaster vehicles that have chosen target */
 
		if (v->subtype == ST_SMALL_UFO) {
 
			if (v->current_order.GetDestination() != 0 && v->dest_tile == vehicle) {
 
				/* Revert to target-searching */
 
				v->current_order.SetDestination(0);
 
				v->dest_tile = RandomTile();
 
				v->z_pos = INITIAL_DISASTER_VEHICLE_ZPOS;
 
				GetAircraftFlightLevelBounds(v, &v->z_pos, NULL);
 
				v->age = 0;
 
			}
 
		}
 
	}
 
}
 

	
 
void DisasterVehicle::UpdateDeltaXY(Direction direction)
 
{
 
	this->x_offs        = -1;
 
	this->y_offs        = -1;
 
	this->x_extent      =  2;
 
	this->y_extent      =  2;
src/disaster_vehicle.h
Show inline comments
 
@@ -30,24 +30,25 @@ enum DisasterSubType {
 
	ST_BIG_UFO_DESTROYER,        ///< Aircraft the will bomb the big UFO
 
	ST_BIG_UFO_DESTROYER_SHADOW, ///< Shadow of the aircraft.
 
	ST_SMALL_SUBMARINE,          ///< Small submarine, pops up in the oceans but doesn't do anything
 
	ST_BIG_SUBMARINE,            ///< Big submarine, pops up in the oceans but doesn't do anything
 
};
 

	
 
/**
 
 * Disasters, like submarines, skyrangers and their shadows, belong to this class.
 
 */
 
struct DisasterVehicle FINAL : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
 
	SpriteID image_override;            ///< Override for the default disaster vehicle sprite.
 
	VehicleID big_ufo_destroyer_target; ///< The big UFO that this destroyer is supposed to bomb.
 
	byte flags;                         ///< Flags about the state of the vehicle, @see AirVehicleFlags
 

	
 
	/** For use by saveload. */
 
	DisasterVehicle() : SpecializedVehicleBase() {}
 
	DisasterVehicle(int x, int y, Direction direction, DisasterSubType subtype, VehicleID big_ufo_destroyer_target = VEH_INVALID);
 
	/** We want to 'destruct' the right class. */
 
	virtual ~DisasterVehicle() {}
 

	
 
	void UpdatePosition(int x, int y, int z);
 
	void UpdateDeltaXY(Direction direction);
 
	void UpdateImage();
 
	bool Tick();
 
};
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -836,24 +836,25 @@ const SaveLoad *GetVehicleDescription(Ve
 
		 SLE_CONDVAR(Vehicle, current_order.dest,    SLE_FILE_U8 | SLE_VAR_U16,    0,   4),
 
		 SLE_CONDVAR(Vehicle, current_order.dest,    SLE_UINT16,                   5, SL_MAX_VERSION),
 

	
 
		     SLE_VAR(Vehicle, cur_image,             SLE_FILE_U16 | SLE_VAR_U32),
 
		 SLE_CONDVAR(Vehicle, age,                   SLE_FILE_U16 | SLE_VAR_I32,   0,  30),
 
		 SLE_CONDVAR(Vehicle, age,                   SLE_INT32,                   31, SL_MAX_VERSION),
 
		     SLE_VAR(Vehicle, tick_counter,          SLE_UINT8),
 

	
 
		 SLE_CONDVAR(DisasterVehicle, image_override,            SLE_FILE_U16 | SLE_VAR_U32,   0, 190),
 
		 SLE_CONDVAR(DisasterVehicle, image_override,            SLE_UINT32,                 191, SL_MAX_VERSION),
 
		 SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target,  SLE_FILE_U16 | SLE_VAR_U32,   0, 190),
 
		 SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target,  SLE_UINT32,                 191, SL_MAX_VERSION),
 
		 SLE_CONDVAR(DisasterVehicle, flags,                     SLE_UINT8,                  194, SL_MAX_VERSION),
 

	
 
		SLE_CONDNULL(16,                                                           2, 143), // old reserved space
 

	
 
		     SLE_END()
 
	};
 

	
 

	
 
	static const SaveLoad * const _veh_descs[] = {
 
		_train_desc,
 
		_roadveh_desc,
 
		_ship_desc,
 
		_aircraft_desc,
0 comments (0 inline, 0 general)