Update to 14.0-beta1
This commit is contained in:
+93
-74
@@ -17,7 +17,7 @@
|
||||
* that handles the vehicle's ticks.
|
||||
* <li>Run the disaster vehicles each tick until their target has been reached,
|
||||
* this happens in the DisasterTick_XXX() functions. In here, a vehicle's
|
||||
* state is kept by v->current_order.dest variable. Each achieved sub-target
|
||||
* state is kept by v->state variable. Each achieved sub-target
|
||||
* will increase this value, and the last one will remove the disaster itself
|
||||
* </ol>
|
||||
*/
|
||||
@@ -34,25 +34,27 @@
|
||||
#include "town.h"
|
||||
#include "company_func.h"
|
||||
#include "strings_func.h"
|
||||
#include "date_func.h"
|
||||
#include "viewport_func.h"
|
||||
#include "vehicle_func.h"
|
||||
#include "sound_func.h"
|
||||
#include "effectvehicle_func.h"
|
||||
#include "roadveh.h"
|
||||
#include "train.h"
|
||||
#include "ai/ai.hpp"
|
||||
#include "game/game.hpp"
|
||||
#include "company_base.h"
|
||||
#include "core/random_func.hpp"
|
||||
#include "core/backup_type.hpp"
|
||||
#include "landscape_cmd.h"
|
||||
#include "timer/timer.h"
|
||||
#include "timer/timer_game_economy.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
/** Delay counter for considering the next disaster. */
|
||||
uint16 _disaster_delay;
|
||||
uint16_t _disaster_delay;
|
||||
|
||||
static void DisasterClearSquare(TileIndex tile)
|
||||
{
|
||||
@@ -166,7 +168,7 @@ DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubT
|
||||
this->UpdateDeltaXY();
|
||||
this->owner = OWNER_NONE;
|
||||
this->image_override = 0;
|
||||
this->current_order.Free();
|
||||
this->state = 0;
|
||||
|
||||
this->UpdateImage();
|
||||
this->UpdatePositionAndViewport();
|
||||
@@ -190,12 +192,12 @@ void DisasterVehicle::UpdatePosition(int x, int y, int z)
|
||||
|
||||
DisasterVehicle *u = this->Next();
|
||||
if (u != nullptr) {
|
||||
int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE);
|
||||
int safe_y = Clamp(y - 1, 0, MapMaxY() * TILE_SIZE);
|
||||
int safe_x = Clamp(x, 0, Map::MaxX() * TILE_SIZE);
|
||||
int safe_y = Clamp(y - 1, 0, Map::MaxY() * TILE_SIZE);
|
||||
|
||||
u->x_pos = x;
|
||||
u->y_pos = y - 1 - (std::max(z - GetSlopePixelZ(safe_x, safe_y), 0) >> 3);
|
||||
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
|
||||
safe_y = Clamp(u->y_pos, 0, Map::MaxY() * TILE_SIZE);
|
||||
u->z_pos = GetSlopePixelZ(safe_x, safe_y);
|
||||
u->direction = this->direction;
|
||||
|
||||
@@ -212,7 +214,7 @@ void DisasterVehicle::UpdatePosition(int x, int y, int z)
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeppeliner handling, v->current_order.dest states:
|
||||
* Zeppeliner handling, v->state states:
|
||||
* 0: Zeppeliner initialization has found a small airport, go there and crash
|
||||
* 1: Create crash and animate falling down for extra dramatic effect
|
||||
* 2: Create more smoke and leave debris on ground
|
||||
@@ -223,24 +225,24 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||
{
|
||||
v->tick_counter++;
|
||||
|
||||
if (v->current_order.GetDestination() < 2) {
|
||||
if (v->state < 2) {
|
||||
if (HasBit(v->tick_counter, 0)) return true;
|
||||
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
|
||||
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
|
||||
|
||||
if (v->current_order.GetDestination() == 1) {
|
||||
if (v->state == 1) {
|
||||
if (++v->age == 38) {
|
||||
v->current_order.SetDestination(2);
|
||||
v->state = 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) {
|
||||
} else if (v->state == 0) {
|
||||
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
|
||||
v->current_order.SetDestination(1);
|
||||
v->state = 1;
|
||||
v->age = 0;
|
||||
|
||||
SetDParam(0, GetStationIndex(v->tile));
|
||||
@@ -249,7 +251,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||
}
|
||||
}
|
||||
|
||||
if (v->y_pos >= (int)((MapSizeY() + 9) * TILE_SIZE - 1)) {
|
||||
if (v->y_pos >= (int)((Map::SizeY() + 9) * TILE_SIZE - 1)) {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
@@ -257,7 +259,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (v->current_order.GetDestination() > 2) {
|
||||
if (v->state > 2) {
|
||||
if (++v->age <= 13320) return true;
|
||||
|
||||
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
|
||||
@@ -285,7 +287,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||
v->image_override = SPR_BLIMP_CRASHED;
|
||||
} else if (v->age <= 300) {
|
||||
if (GB(v->tick_counter, 0, 3) == 0) {
|
||||
uint32 r = Random();
|
||||
uint32_t r = Random();
|
||||
|
||||
CreateEffectVehicleRel(v,
|
||||
GB(r, 0, 4) - 7,
|
||||
@@ -294,7 +296,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||
EV_EXPLOSION_SMALL);
|
||||
}
|
||||
} else if (v->age == 350) {
|
||||
v->current_order.SetDestination(3);
|
||||
v->state = 3;
|
||||
v->age = 0;
|
||||
}
|
||||
|
||||
@@ -306,7 +308,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||
}
|
||||
|
||||
/**
|
||||
* (Small) Ufo handling, v->current_order.dest states:
|
||||
* (Small) Ufo handling, v->state states:
|
||||
* 0: Fly around to the middle of the map, then randomly, after a while target a road vehicle
|
||||
* 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
|
||||
@@ -315,7 +317,7 @@ 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) {
|
||||
if (v->state == 0) {
|
||||
/* Fly around randomly */
|
||||
int x = TileX(v->dest_tile) * TILE_SIZE;
|
||||
int y = TileY(v->dest_tile) * TILE_SIZE;
|
||||
@@ -329,11 +331,11 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
|
||||
v->dest_tile = RandomTile();
|
||||
return true;
|
||||
}
|
||||
v->current_order.SetDestination(1);
|
||||
v->state = 1;
|
||||
|
||||
uint n = 0; // Total number of targetable road vehicles.
|
||||
for (const RoadVehicle *u : RoadVehicle::Iterate()) {
|
||||
if (u->IsFrontEngine()) n++;
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
n += c->group_all[VEH_ROAD].num_vehicle;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
@@ -356,7 +358,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
|
||||
return true;
|
||||
} else {
|
||||
/* Target a vehicle */
|
||||
RoadVehicle *u = RoadVehicle::Get(v->dest_tile);
|
||||
RoadVehicle *u = RoadVehicle::Get(v->dest_tile.base());
|
||||
assert(u != nullptr && u->type == VEH_ROAD && u->IsFrontEngine());
|
||||
|
||||
uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos);
|
||||
@@ -399,7 +401,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
|
||||
|
||||
static void DestructIndustry(Industry *i)
|
||||
{
|
||||
for (TileIndex tile = 0; tile != MapSize(); tile++) {
|
||||
for (TileIndex tile = 0; tile != Map::Size(); tile++) {
|
||||
if (i->TileBelongsToIndustry(tile)) {
|
||||
ResetIndustryConstructionStage(tile);
|
||||
MarkTileDirtyByTile(tile);
|
||||
@@ -408,7 +410,7 @@ static void DestructIndustry(Industry *i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Aircraft handling, v->current_order.dest states:
|
||||
* Aircraft handling, v->state states:
|
||||
* 0: Fly towards the targeted industry
|
||||
* 1: If within 15 tiles, fire away rockets and destroy industry
|
||||
* 2: Industry explosions
|
||||
@@ -420,25 +422,25 @@ 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 bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, bool leave_at_top, StringID news_message, IndustryBehaviour industry_flag)
|
||||
static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16_t 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;
|
||||
v->image_override = (v->state == 1 && HasBit(v->tick_counter, 2)) ? image_override : 0;
|
||||
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
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)) {
|
||||
if ((leave_at_top && gp.x < (-10 * (int)TILE_SIZE)) || (!leave_at_top && gp.x > (int)(Map::SizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1)) {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v->current_order.GetDestination() == 2) {
|
||||
if (v->state == 2) {
|
||||
if (GB(v->tick_counter, 0, 2) == 0) {
|
||||
Industry *i = Industry::Get(v->dest_tile); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid
|
||||
Industry *i = Industry::Get(v->dest_tile.base()); // 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();
|
||||
uint32_t r = Random();
|
||||
|
||||
CreateEffectVehicleAbove(
|
||||
GB(r, 0, 6) + x,
|
||||
@@ -446,25 +448,25 @@ static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, boo
|
||||
GB(r, 12, 4),
|
||||
EV_EXPLOSION_SMALL);
|
||||
|
||||
if (++v->age >= 55) v->current_order.SetDestination(3);
|
||||
if (++v->age >= 55) v->state = 3;
|
||||
}
|
||||
} else if (v->current_order.GetDestination() == 1) {
|
||||
} else if (v->state == 1) {
|
||||
if (++v->age == 112) {
|
||||
v->current_order.SetDestination(2);
|
||||
v->state = 2;
|
||||
v->age = 0;
|
||||
|
||||
Industry *i = Industry::Get(v->dest_tile); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid
|
||||
Industry *i = Industry::Get(v->dest_tile.base()); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid
|
||||
DestructIndustry(i);
|
||||
|
||||
SetDParam(0, i->town->index);
|
||||
AddIndustryNewsItem(news_message, NT_ACCIDENT, i->index);
|
||||
if (_settings_client.sound.disaster) SndPlayTileFx(SND_12_EXPLOSION, i->location.tile);
|
||||
}
|
||||
} else if (v->current_order.GetDestination() == 0) {
|
||||
} else if (v->state == 0) {
|
||||
int x = v->x_pos + ((leave_at_top ? -15 : 15) * TILE_SIZE);
|
||||
int y = v->y_pos;
|
||||
|
||||
if ((uint)x > MapMaxX() * TILE_SIZE - 1) return true;
|
||||
if ((uint)x > Map::MaxX() * TILE_SIZE - 1) return true;
|
||||
|
||||
TileIndex tile = TileVirtXY(x, y);
|
||||
if (!IsTileType(tile, MP_INDUSTRY)) return true;
|
||||
@@ -473,7 +475,7 @@ static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, boo
|
||||
v->dest_tile = ind;
|
||||
|
||||
if (GetIndustrySpec(Industry::Get(ind)->type)->behaviour & industry_flag) {
|
||||
v->current_order.SetDestination(1);
|
||||
v->state = 1;
|
||||
v->age = 0;
|
||||
}
|
||||
}
|
||||
@@ -508,7 +510,7 @@ static bool DisasterTick_Helicopter_Rotors(DisasterVehicle *v)
|
||||
}
|
||||
|
||||
/**
|
||||
* (Big) Ufo handling, v->current_order.dest states:
|
||||
* (Big) Ufo handling, v->state states:
|
||||
* 0: Fly around to the middle of the map, then randomly for a while and home in on a piece of rail
|
||||
* 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
|
||||
@@ -517,7 +519,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
|
||||
{
|
||||
v->tick_counter++;
|
||||
|
||||
if (v->current_order.GetDestination() == 1) {
|
||||
if (v->state == 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) {
|
||||
@@ -540,7 +542,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
|
||||
return true;
|
||||
}
|
||||
|
||||
v->current_order.SetDestination(2);
|
||||
v->state = 2;
|
||||
|
||||
for (Vehicle *target : Vehicle::Iterate()) {
|
||||
if (target->IsGroundVehicle()) {
|
||||
@@ -562,7 +564,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
|
||||
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) {
|
||||
} else if (v->state == 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) {
|
||||
@@ -576,26 +578,43 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
|
||||
v->dest_tile = RandomTile();
|
||||
return true;
|
||||
}
|
||||
v->current_order.SetDestination(1);
|
||||
v->state = 1;
|
||||
|
||||
TileIndex tile_org = RandomTile();
|
||||
TileIndex tile = tile_org;
|
||||
do {
|
||||
if (IsPlainRailTile(tile) &&
|
||||
Company::IsHumanID(GetTileOwner(tile))) {
|
||||
const auto is_valid_target = [](const Train *t) {
|
||||
return t->IsFrontEngine() // Only the engines
|
||||
&& Company::IsHumanID(t->owner) // Don't break AIs
|
||||
&& IsPlainRailTile(t->tile) // No tunnels
|
||||
&& (t->vehstatus & VS_CRASHED) == 0; // Not crashed
|
||||
};
|
||||
|
||||
uint n = 0; // Total number of targetable trains.
|
||||
for (const Train *t : Train::Iterate()) {
|
||||
if (is_valid_target(t)) n++;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
/* If there are no targetable trains, destroy the UFO. */
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
n = RandomRange(n); // Choose one of them.
|
||||
for (const Train *t : Train::Iterate()) {
|
||||
/* Find (n+1)-th train. */
|
||||
if (is_valid_target(t) && (n-- == 0)) {
|
||||
/* Target it. */
|
||||
v->dest_tile = t->tile;
|
||||
v->age = 0;
|
||||
break;
|
||||
}
|
||||
tile = TILE_MASK(tile + 1);
|
||||
} while (tile != tile_org);
|
||||
v->dest_tile = tile;
|
||||
v->age = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skyranger destroying (Big) Ufo handling, v->current_order.dest states:
|
||||
* Skyranger destroying (Big) Ufo handling, v->state states:
|
||||
* 0: Home in on landed Ufo and shoot it down
|
||||
*/
|
||||
static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v)
|
||||
@@ -605,15 +624,15 @@ static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v)
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
|
||||
|
||||
if (gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1) {
|
||||
if (gp.x > (int)(Map::SizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1) {
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v->current_order.GetDestination() == 0) {
|
||||
if (v->state == 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);
|
||||
v->state = 1;
|
||||
|
||||
CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE);
|
||||
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, u);
|
||||
@@ -621,7 +640,7 @@ static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v)
|
||||
delete u;
|
||||
|
||||
for (int i = 0; i != 80; i++) {
|
||||
uint32 r = Random();
|
||||
uint32_t r = Random();
|
||||
CreateEffectVehicleAbove(
|
||||
GB(r, 0, 6) + v->x_pos - 32,
|
||||
GB(r, 5, 6) + v->y_pos - 32,
|
||||
@@ -641,7 +660,7 @@ static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Submarine, v->current_order.dest states:
|
||||
* Submarine, v->state states:
|
||||
* Unused, just float around aimlessly and pop up at different places, turning around
|
||||
*/
|
||||
static bool DisasterTick_Submarine(DisasterVehicle *v)
|
||||
@@ -671,7 +690,7 @@ static bool DisasterTick_Submarine(DisasterVehicle *v)
|
||||
}
|
||||
|
||||
|
||||
static bool DisasterTick_NULL(DisasterVehicle *v)
|
||||
static bool DisasterTick_NULL(DisasterVehicle *)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -733,7 +752,7 @@ static void Disaster_Small_Ufo_Init()
|
||||
|
||||
int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
|
||||
DisasterVehicle *v = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO);
|
||||
v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
|
||||
v->dest_tile = TileXY(Map::SizeX() / 2, Map::SizeY() / 2);
|
||||
|
||||
/* Allocate shadow */
|
||||
DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO_SHADOW);
|
||||
@@ -758,7 +777,7 @@ static void Disaster_Airplane_Init()
|
||||
if (found == nullptr) return;
|
||||
|
||||
/* Start from the bottom (south side) of the map */
|
||||
int x = (MapSizeX() + 9) * TILE_SIZE - 1;
|
||||
int x = (Map::SizeX() + 9) * TILE_SIZE - 1;
|
||||
int y = TileY(found->location.tile) * TILE_SIZE + 37;
|
||||
|
||||
DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE);
|
||||
@@ -802,10 +821,10 @@ static void Disaster_Big_Ufo_Init()
|
||||
if (!Vehicle::CanAllocateItem(2)) return;
|
||||
|
||||
int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
|
||||
int y = MapMaxX() * TILE_SIZE - 1;
|
||||
int y = Map::MaxX() * TILE_SIZE - 1;
|
||||
|
||||
DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO);
|
||||
v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
|
||||
v->dest_tile = TileXY(Map::SizeX() / 2, Map::SizeY() / 2);
|
||||
|
||||
/* Allocate shadow */
|
||||
DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO_SHADOW);
|
||||
@@ -819,11 +838,11 @@ static void Disaster_Submarine_Init(DisasterSubType subtype)
|
||||
|
||||
int y;
|
||||
Direction dir;
|
||||
uint32 r = Random();
|
||||
uint32_t r = Random();
|
||||
int x = TileX(r) * TILE_SIZE + TILE_SIZE / 2;
|
||||
|
||||
if (HasBit(r, 31)) {
|
||||
y = MapMaxY() * TILE_SIZE - TILE_SIZE / 2 - 1;
|
||||
y = Map::MaxY() * TILE_SIZE - TILE_SIZE / 2 - 1;
|
||||
dir = DIR_NW;
|
||||
} else {
|
||||
y = TILE_SIZE / 2;
|
||||
@@ -881,9 +900,9 @@ static void Disaster_CoalMine_Init()
|
||||
}
|
||||
|
||||
struct Disaster {
|
||||
DisasterInitProc *init_proc; ///< The init function for this disaster.
|
||||
Year min_year; ///< The first year this disaster will occur.
|
||||
Year max_year; ///< The last year this disaster will occur.
|
||||
DisasterInitProc *init_proc; ///< The init function for this disaster.
|
||||
TimerGameCalendar::Year min_year; ///< The first year this disaster will occur.
|
||||
TimerGameCalendar::Year max_year; ///< The last year this disaster will occur.
|
||||
};
|
||||
|
||||
static const Disaster _disasters[] = {
|
||||
@@ -903,7 +922,7 @@ static void DoDisaster()
|
||||
|
||||
byte j = 0;
|
||||
for (size_t i = 0; i != lengthof(_disasters); i++) {
|
||||
if (_cur_year >= _disasters[i].min_year && _cur_year < _disasters[i].max_year) buf[j++] = (byte)i;
|
||||
if (TimerGameCalendar::year >= _disasters[i].min_year && TimerGameCalendar::year < _disasters[i].max_year) buf[j++] = (byte)i;
|
||||
}
|
||||
|
||||
if (j == 0) return;
|
||||
@@ -917,14 +936,14 @@ static void ResetDisasterDelay()
|
||||
_disaster_delay = GB(Random(), 0, 9) + 730;
|
||||
}
|
||||
|
||||
void DisasterDailyLoop()
|
||||
static IntervalTimer<TimerGameEconomy> _economy_disaster_daily({TimerGameEconomy::DAY, TimerGameEconomy::Priority::DISASTER}, [](auto)
|
||||
{
|
||||
if (--_disaster_delay != 0) return;
|
||||
|
||||
ResetDisasterDelay();
|
||||
|
||||
if (_settings_game.difficulty.disasters != 0) DoDisaster();
|
||||
}
|
||||
});
|
||||
|
||||
void StartupDisasters()
|
||||
{
|
||||
@@ -942,7 +961,7 @@ void ReleaseDisastersTargetingIndustry(IndustryID i)
|
||||
/* primary disaster vehicles that have chosen target */
|
||||
if (v->subtype == ST_AIRPLANE || v->subtype == ST_HELICOPTER) {
|
||||
/* if it has chosen target, and it is this industry (yes, dest_tile is IndustryID here), set order to "leaving map peacefully" */
|
||||
if (v->current_order.GetDestination() > 0 && v->dest_tile == (uint32)i) v->current_order.SetDestination(3);
|
||||
if (v->state > 0 && v->dest_tile == (uint32_t)i) v->state = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -956,9 +975,9 @@ void ReleaseDisastersTargetingVehicle(VehicleID vehicle)
|
||||
for (DisasterVehicle *v : DisasterVehicle::Iterate()) {
|
||||
/* primary disaster vehicles that have chosen target */
|
||||
if (v->subtype == ST_SMALL_UFO) {
|
||||
if (v->current_order.GetDestination() != 0 && v->dest_tile == vehicle) {
|
||||
if (v->state != 0 && v->dest_tile == vehicle) {
|
||||
/* Revert to target-searching */
|
||||
v->current_order.SetDestination(0);
|
||||
v->state = 0;
|
||||
v->dest_tile = RandomTile();
|
||||
GetAircraftFlightLevelBounds(v, &v->z_pos, nullptr);
|
||||
v->age = 0;
|
||||
|
||||
Reference in New Issue
Block a user