mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-10-31 15:20:10 +00:00
Maintain map of targeted road vehicles to small UFO disaster vehicle
This commit is contained in:
parent
1e2834a422
commit
903adceab5
@ -48,6 +48,7 @@
|
||||
#include "core/backup_type.hpp"
|
||||
#include "core/checksum_func.hpp"
|
||||
#include "event_logs.h"
|
||||
#include "3rdparty/cpp-btree/btree_map.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
@ -57,6 +58,7 @@
|
||||
uint16_t _disaster_delay;
|
||||
|
||||
static uint32_t _disaster_vehicle_count = 0;
|
||||
static btree::btree_map<VehicleID, VehicleID> _disaster_ufo_target_map;
|
||||
|
||||
static void DisasterClearSquare(TileIndex tile)
|
||||
{
|
||||
@ -369,6 +371,11 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
|
||||
for (const RoadVehicle *u : RoadVehicle::Iterate()) {
|
||||
/* Find (n+1)-th road vehicle. */
|
||||
if (u->IsFrontEngine() && (n-- == 0)) {
|
||||
if (u->crashed_ctr != 0 || !SetDisasterVehicleTargetingVehicle(u->index, v->index)) {
|
||||
/* Targetted vehicle is crashed or already a target, destroy the UFO. */
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
/* Target it. */
|
||||
v->dest_tile = u->index;
|
||||
v->age = 0;
|
||||
@ -1010,22 +1017,43 @@ void ReleaseDisastersTargetingIndustry(IndustryID i)
|
||||
* Notify disasters that we are about to delete a vehicle. So make them head elsewhere.
|
||||
* @param vehicle deleted vehicle
|
||||
*/
|
||||
void ReleaseDisastersTargetingVehicle(VehicleID vehicle)
|
||||
void ReleaseDisasterVehicleTargetingVehicle(VehicleID vehicle)
|
||||
{
|
||||
if (!_disaster_vehicle_count) return;
|
||||
|
||||
for (DisasterVehicle *v : DisasterVehicle::Iterate()) {
|
||||
/* primary disaster vehicles that have chosen target */
|
||||
if (v->subtype == ST_SMALL_UFO) {
|
||||
if (v->state != 0 && v->dest_tile == vehicle) {
|
||||
/* Revert to target-searching */
|
||||
v->state = 0;
|
||||
v->dest_tile = RandomTile();
|
||||
GetAircraftFlightLevelBounds(v, &v->z_pos, nullptr);
|
||||
v->age = 0;
|
||||
}
|
||||
}
|
||||
auto iter = _disaster_ufo_target_map.find(vehicle);
|
||||
if (iter == _disaster_ufo_target_map.end()) return;
|
||||
|
||||
DisasterVehicle *v = DisasterVehicle::GetIfValid(iter->second);
|
||||
_disaster_ufo_target_map.erase(iter);
|
||||
|
||||
if (v == nullptr) return;
|
||||
|
||||
/* primary disaster vehicles that have chosen target */
|
||||
assert(v->subtype == ST_SMALL_UFO);
|
||||
assert(v->state != 0);
|
||||
|
||||
/* Revert to target-searching */
|
||||
v->state = 0;
|
||||
v->dest_tile = RandomTile();
|
||||
GetAircraftFlightLevelBounds(v, &v->z_pos, nullptr);
|
||||
v->age = 0;
|
||||
}
|
||||
|
||||
void ResetDisasterVehicleTargeting()
|
||||
{
|
||||
_disaster_ufo_target_map.clear();
|
||||
}
|
||||
|
||||
bool SetDisasterVehicleTargetingVehicle(VehicleID vehicle, VehicleID disaster_vehicle)
|
||||
{
|
||||
auto insert_result = _disaster_ufo_target_map.insert(std::make_pair(vehicle, disaster_vehicle));
|
||||
if (!insert_result.second) {
|
||||
/* Vehicle already has an associated disaster vehicle, return failure if that isn't this disaster vehicle */
|
||||
if (insert_result.first->second != disaster_vehicle) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisasterVehicle::UpdateDeltaXY()
|
||||
|
@ -120,6 +120,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
||||
AllocateMap(size_x, size_y);
|
||||
|
||||
ViewportMapClearTunnelCache();
|
||||
ResetDisasterVehicleTargeting();
|
||||
ClearCommandLog();
|
||||
ClearCommandQueue();
|
||||
ClearSpecialEventsLog();
|
||||
|
@ -520,6 +520,7 @@ static void ShutdownGame()
|
||||
InvalidateVehicleTickCaches();
|
||||
ClearVehicleTickCaches();
|
||||
InvalidateTemplateReplacementImages();
|
||||
ResetDisasterVehicleTargeting();
|
||||
ClearCommandLog();
|
||||
ClearCommandQueue();
|
||||
ClearSpecialEventsLog();
|
||||
|
@ -507,6 +507,8 @@ void AfterLoadVehicles(bool part_of_load)
|
||||
}
|
||||
}
|
||||
|
||||
ResetDisasterVehicleTargeting();
|
||||
|
||||
for (Vehicle *v : Vehicle::Iterate()) {
|
||||
si_v = v;
|
||||
switch (v->type) {
|
||||
@ -539,6 +541,22 @@ void AfterLoadVehicles(bool part_of_load)
|
||||
UpdateAircraftCache(Aircraft::From(v), true);
|
||||
}
|
||||
break;
|
||||
|
||||
case VEH_DISASTER: {
|
||||
auto *dv = DisasterVehicle::From(v);
|
||||
if (dv->subtype == ST_SMALL_UFO && dv->state != 0) {
|
||||
RoadVehicle *u = RoadVehicle::GetIfValid(v->dest_tile);
|
||||
if (u != nullptr && u->IsFrontEngine()) {
|
||||
/* Delete UFO targeting a vehicle which is already a target. */
|
||||
if (!SetDisasterVehicleTargetingVehicle(u->index, dv->index)) {
|
||||
delete v;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -1030,6 +1030,7 @@ void InitializeVehicles()
|
||||
{
|
||||
_vehicles_to_autoreplace.clear();
|
||||
ResetVehicleHash();
|
||||
ResetDisasterVehicleTargeting();
|
||||
}
|
||||
|
||||
uint CountVehiclesInChain(const Vehicle *v)
|
||||
@ -1202,6 +1203,8 @@ void Vehicle::PreDestructor()
|
||||
/* Leave the drive through roadstop, when you have not already left it. */
|
||||
RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
|
||||
}
|
||||
|
||||
ReleaseDisasterVehicleTargetingVehicle(this->index);
|
||||
}
|
||||
|
||||
if (HasBit(this->vehicle_flags, VF_HAVE_SLOT)) {
|
||||
@ -1238,8 +1241,6 @@ void Vehicle::PreDestructor()
|
||||
|
||||
StopGlobalFollowVehicle(this);
|
||||
|
||||
ReleaseDisastersTargetingVehicle(this->index);
|
||||
|
||||
/* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles,
|
||||
* it may happen that vehicle chain is deleted when visible */
|
||||
if (this->IsDrawn()) this->MarkAllViewportsDirty();
|
||||
|
@ -258,7 +258,9 @@ bool CanVehicleUseStation(EngineID engine_type, const struct Station *st);
|
||||
bool CanVehicleUseStation(const Vehicle *v, const struct Station *st);
|
||||
StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st);
|
||||
|
||||
void ReleaseDisastersTargetingVehicle(VehicleID vehicle);
|
||||
void ResetDisasterVehicleTargeting();
|
||||
void ReleaseDisasterVehicleTargetingVehicle(VehicleID vehicle);
|
||||
bool SetDisasterVehicleTargetingVehicle(VehicleID vehicle, VehicleID disaster_vehicle);
|
||||
|
||||
typedef std::vector<VehicleID> VehicleSet;
|
||||
void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8_t num_vehicles);
|
||||
|
Loading…
Reference in New Issue
Block a user