Player-testing has revealed QA issues, so reverting these for now.

Differential Revision: https://code.wildfiregames.com/D2773
This was SVN commit r23714.
This commit is contained in:
wraitii
2020-05-31 10:06:39 +00:00
parent 0cde295654
commit 531dcf40c3
9 changed files with 39 additions and 235 deletions
@@ -249,11 +249,6 @@ GarrisonHolder.prototype.Garrison = function(entity, vgpEntity)
if (cmpUnitAI)
cmpUnitAI.SetTurretStance();
// Remove the unit's obstruction to avoid interfering with pathing.
let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
if (cmpObstruction)
cmpObstruction.SetDisableBlockMovementPathfinding(true, true, -1);
isVisiblyGarrisoned = true;
}
else
@@ -371,11 +366,6 @@ GarrisonHolder.prototype.Eject = function(entity, forced)
break;
}
// Reset the obstruction flags to template defaults.
let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
if (cmpObstruction)
cmpObstruction.SetDisableBlockMovementPathfinding(false, false, -1);
if (cmpEntUnitAI)
cmpEntUnitAI.Ungarrison();
@@ -15,7 +15,6 @@ Gate.prototype.Schema =
Gate.prototype.Init = function()
{
this.allies = [];
this.ignoreList = [];
this.opened = false;
this.locked = false;
};
@@ -33,11 +32,10 @@ Gate.prototype.OnOwnershipChanged = function(msg)
Gate.prototype.OnDiplomacyChanged = function(msg)
{
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (cmpOwnership && cmpOwnership.GetOwner() == msg.player)
{
this.allies = [];
this.ignoreList = [];
this.SetupRangeQuery(msg.player);
}
};
@@ -93,36 +91,11 @@ Gate.prototype.OnRangeUpdate = function(msg)
if (msg.added.length > 0)
for (let entity of msg.added)
{
// Ignore entities that cannot move as those won't be able to go through the gate.
let unitAI = Engine.QueryInterface(entity, IID_UnitAI);
if (!unitAI.AbleToMove())
this.ignoreList.push(entity);
this.allies.push(entity);
}
if (msg.removed.length > 0)
for (let entity of msg.removed)
{
let index = this.ignoreList.indexOf(entity);
if (index !== -1)
this.ignoreList.splice(index, 1);
this.allies.splice(this.allies.indexOf(entity), 1);
}
this.OperateGate();
};
Gate.prototype.OnGlobalUnitAbleToMoveChanged = function(msg)
{
if (this.allies.indexOf(msg.entity) === -1)
return;
let index = this.ignoreList.indexOf(msg.entity);
if (msg.ableToMove && index !== -1)
this.ignoreList.splice(index, 1);
else if (!msg.ableToMove && index === -1)
this.ignoreList.push(msg.entity);
this.OperateGate();
};
@@ -135,11 +108,6 @@ Gate.prototype.GetPassRange = function()
return +this.template.PassRange;
};
Gate.prototype.ShouldOpen = function()
{
return this.allies.some(ent => this.ignoreList.indexOf(ent) === -1);
};
/**
* Attempt to open or close the gate.
* An ally must be in range to open the gate, but an unlocked gate will only close
@@ -154,9 +122,10 @@ Gate.prototype.OperateGate = function()
cmpTimer.CancelTimer(this.timer);
this.timer = undefined;
}
if (this.opened && (this.locked || !this.ShouldOpen()))
if (this.opened && (this.allies.length == 0 || this.locked))
this.CloseGate();
else if (!this.opened && this.ShouldOpen())
else if (!this.opened && this.allies.length)
this.OpenGate();
};
@@ -246,19 +215,19 @@ Gate.prototype.OpenGate = function()
*/
Gate.prototype.CloseGate = function()
{
let cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
if (!cmpObstruction)
return;
// The gate can't be closed if there are entities colliding with it.
let collisions = cmpObstruction.GetEntitiesBlockingMovement();
var collisions = cmpObstruction.GetEntitiesBlockingConstruction();
if (collisions.length)
{
if (!this.timer)
{
// Set an "instant" timer which will run on the next simulation turn.
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
this.timer = cmpTimer.SetTimeout(this.entity, IID_Gate, "OperateGate", 0);
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
this.timer = cmpTimer.SetTimeout(this.entity, IID_Gate, "OperateGate", 0, {});
}
return;
}
@@ -272,7 +241,7 @@ Gate.prototype.CloseGate = function()
this.opened = false;
PlaySound("gate_closing", this.entity);
let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
if (cmpVisual)
cmpVisual.SelectAnimation("gate_closing", true, 1.0);
};
@@ -193,13 +193,6 @@ UnitAI.prototype.UnitFsmSpec = {
// ignore
},
"OrderTargetRenamed": function() {
// By default, trigger an exit-reenter
// so that state preconditions are checked against the new entity
// (there is no reason to assume the target is still valid).
this.SetNextState(this.GetCurrentState());
},
// Formation handlers:
"FormationLeave": function(msg) {
@@ -209,7 +202,7 @@ UnitAI.prototype.UnitFsmSpec = {
// Called when being told to walk as part of a formation
"Order.FormationWalk": function(msg) {
// Let players move captured domestic animals around
if (this.IsAnimal() && !this.IsDomestic() || !this.AbleToMove())
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
{
this.FinishOrder();
return;
@@ -269,7 +262,7 @@ UnitAI.prototype.UnitFsmSpec = {
"Order.Walk": function(msg) {
// Let players move captured domestic animals around
if (this.IsAnimal() && !this.IsDomestic() || !this.AbleToMove())
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
{
this.FinishOrder();
return;
@@ -295,7 +288,7 @@ UnitAI.prototype.UnitFsmSpec = {
"Order.WalkAndFight": function(msg) {
// Let players move captured domestic animals around
if (this.IsAnimal() && !this.IsDomestic() || !this.AbleToMove())
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
{
this.FinishOrder();
return;
@@ -322,7 +315,7 @@ UnitAI.prototype.UnitFsmSpec = {
"Order.WalkToTarget": function(msg) {
// Let players move captured domestic animals around
if (this.IsAnimal() && !this.IsDomestic() || !this.AbleToMove())
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
{
this.FinishOrder();
return;
@@ -451,7 +444,7 @@ UnitAI.prototype.UnitFsmSpec = {
// If we can't reach the target, but are standing ground, then abandon this attack order.
// Unless we're hunting, that's a special case where we should continue attacking our target.
if (this.GetStance().respondStandGround && !this.order.data.force && !this.order.data.hunting || !this.AbleToMove())
if (this.GetStance().respondStandGround && !this.order.data.force && !this.order.data.hunting || this.IsTurret())
{
this.FinishOrder();
return;
@@ -477,7 +470,7 @@ UnitAI.prototype.UnitFsmSpec = {
},
"Order.Patrol": function(msg) {
if (this.IsAnimal() || !this.AbleToMove())
if (this.IsAnimal() || this.IsTurret())
{
this.FinishOrder();
return;
@@ -630,7 +623,7 @@ UnitAI.prototype.UnitFsmSpec = {
},
"Order.Garrison": function(msg) {
if (!this.AbleToMove())
if (this.IsTurret())
{
this.SetNextState("IDLE");
return;
@@ -1985,7 +1978,6 @@ UnitAI.prototype.UnitFsmSpec = {
"Timer": function(msg) {
let target = this.order.data.target;
let attackType = this.order.data.attackType;
// Check the target is still alive and attackable
if (!this.CanAttack(target))
@@ -2008,16 +2000,11 @@ UnitAI.prototype.UnitFsmSpec = {
if (!cmpBuildingAI)
{
let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
cmpAttack.PerformAttack(attackType, target);
cmpAttack.PerformAttack(this.order.data.attackType, target);
}
// PerformAttack might have triggered messages that moved us to another state.
if (this.GetCurrentState() != "INDIVIDUAL.COMBAT.ATTACKING")
return;
// Check we can still reach the target for the next attack
if (this.CheckTargetAttackRange(target, attackType))
if (this.CheckTargetAttackRange(target, this.order.data.attackType))
{
if (this.resyncAnimation)
{
@@ -3055,7 +3042,6 @@ UnitAI.prototype.UnitFsmSpec = {
if (cmpGarrisonHolder.Garrison(this.entity))
{
this.isGarrisoned = true;
this.SetImmobile(true);
if (this.formationController)
{
@@ -3387,7 +3373,6 @@ UnitAI.prototype.Init = function()
this.formationController = INVALID_ENTITY; // entity with IID_Formation that we belong to
this.isGarrisoned = false;
this.isIdle = false;
this.isImmobile = false; // True if the unit is currently unable to move (garrisoned,...)
this.finishedOrder = false; // used to find if all formation members finished the order
this.heldPosition = undefined;
@@ -3487,30 +3472,6 @@ UnitAI.prototype.ShouldRespondToEndOfAlert = function()
return !this.orderQueue.length || this.orderQueue[0].type == "Garrison";
};
UnitAI.prototype.SetImmobile = function(immobile)
{
this.isImmobile = immobile;
Engine.PostMessage(this.entity, MT_UnitAbleToMoveChanged, {
"entity": this.entity,
"ableToMove": this.AbleToMove()
});
};
/**
* @param cmpUnitMotion - optionally pass unitMotion to avoid querying it here
* @returns true if the entity can move, i.e. has UnitMotion and isn't immobile.
*/
UnitAI.prototype.AbleToMove = function(cmpUnitMotion)
{
if (this.isImmobile || this.IsTurret())
return false;
if (!cmpUnitMotion)
cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return !!cmpUnitMotion;
};
UnitAI.prototype.IsFleeing = function()
{
var state = this.GetCurrentState().split(".").pop();
@@ -3947,8 +3908,9 @@ UnitAI.prototype.WillMoveFromFoundation = function(target, checkPacking = true)
// If foundation is not ally of entity, or if entity is unpacked siege,
// ignore the order.
if (!IsOwnedByAllyOfEntity(this.entity, target) &&
!Engine.QueryInterface(SYSTEM_ENTITY, IID_CeasefireManager).IsCeasefireActive() ||
checkPacking && this.IsPacking() || this.CanPack() || !this.AbleToMove())
!Engine.QueryInterface(SYSTEM_ENTITY, IID_CeasefireManager).IsCeasefireActive() ||
checkPacking && this.IsPacking() ||
this.CanPack() || this.IsTurret())
return false;
// Move a tile outside the building.
@@ -4182,32 +4144,24 @@ UnitAI.prototype.OnGlobalConstructionFinished = function(msg)
UnitAI.prototype.OnGlobalEntityRenamed = function(msg)
{
let changed = false;
let currentOrderChanged = false;
for (let i = 0; i < this.orderQueue.length; ++i)
for (let order of this.orderQueue)
{
let order = this.orderQueue[i];
if (order.data && order.data.target && order.data.target == msg.entity)
{
changed = true;
if (i == 0)
currentOrderChanged = true;
order.data.target = msg.newentity;
}
if (order.data && order.data.formationTarget && order.data.formationTarget == msg.entity)
{
changed = true;
if (i == 0)
currentOrderChanged = true;
order.data.formationTarget = msg.newentity;
}
}
if (!changed)
return;
if (this.repairTarget && this.repairTarget == msg.entity)
this.repairTarget = msg.newentity;
if (currentOrderChanged)
this.UnitFsm.ProcessMessage(this, { "type": "OrderTargetRenamed", "data": msg });
Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
if (changed)
Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
};
UnitAI.prototype.OnAttacked = function(msg)
@@ -4538,13 +4492,13 @@ UnitAI.prototype.MoveTo = function(data, iid, type)
UnitAI.prototype.MoveToPoint = function(x, z)
{
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return this.AbleToMove(cmpUnitMotion) && cmpUnitMotion.MoveToPointRange(x, z, 0, 0); // For point goals, allow a max range of 0.
return cmpUnitMotion && cmpUnitMotion.MoveToPointRange(x, z, 0, 0); // For point goals, allow a max range of 0.
};
UnitAI.prototype.MoveToPointRange = function(x, z, rangeMin, rangeMax)
{
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return this.AbleToMove(cmpUnitMotion) && cmpUnitMotion.MoveToPointRange(x, z, rangeMin, rangeMax);
return cmpUnitMotion && cmpUnitMotion.MoveToPointRange(x, z, rangeMin, rangeMax);
};
UnitAI.prototype.MoveToTarget = function(target)
@@ -4553,12 +4507,12 @@ UnitAI.prototype.MoveToTarget = function(target)
return false;
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return this.AbleToMove(cmpUnitMotion) && cmpUnitMotion.MoveToTargetRange(target, 0, 1);
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, 0, 1);
};
UnitAI.prototype.MoveToTargetRange = function(target, iid, type)
{
if (!this.CheckTargetVisible(target))
if (!this.CheckTargetVisible(target) || this.IsTurret())
return false;
let range = this.GetRange(iid, type);
@@ -4566,7 +4520,7 @@ UnitAI.prototype.MoveToTargetRange = function(target, iid, type)
return false;
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return this.AbleToMove(cmpUnitMotion) && cmpUnitMotion.MoveToTargetRange(target, range.min, range.max);
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, range.min, range.max);
};
/**
@@ -4584,10 +4538,6 @@ UnitAI.prototype.MoveToTargetAttackRange = function(target, type)
return false;
}
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
if (!this.AbleToMove(cmpUnitMotion))
return false;
let cmpFormation = Engine.QueryInterface(target, IID_Formation);
if (cmpFormation)
target = cmpFormation.GetClosestMember(this.entity);
@@ -4624,6 +4574,7 @@ UnitAI.prototype.MoveToTargetAttackRange = function(target, type)
// The parabole changes while walking so be cautious:
let guessedMaxRange = parabolicMaxRange > range.max ? (range.max + parabolicMaxRange) / 2 : parabolicMaxRange;
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, range.min, guessedMaxRange);
};
@@ -4633,7 +4584,7 @@ UnitAI.prototype.MoveToTargetRangeExplicit = function(target, min, max)
return false;
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return this.AbleToMove(cmpUnitMotion) && cmpUnitMotion.MoveToTargetRange(target, min, max);
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, min, max);
};
/**
@@ -4648,7 +4599,7 @@ UnitAI.prototype.MoveFormationToTargetAttackRange = function(target)
if (cmpTargetFormation)
target = cmpTargetFormation.GetClosestMember(this.entity);
if (!this.CheckTargetVisible(target))
if (!this.CheckTargetVisible(target) || this.IsTurret())
return false;
let cmpFormationAttack = Engine.QueryInterface(this.entity, IID_Attack);
@@ -4657,7 +4608,7 @@ UnitAI.prototype.MoveFormationToTargetAttackRange = function(target)
let range = cmpFormationAttack.GetRange(target);
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return this.AbleToMove(cmpUnitMotion) && cmpUnitMotion.MoveToTargetRange(target, range.min, range.max);
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, range.min, range.max);
};
UnitAI.prototype.MoveToGarrisonRange = function(target)
@@ -4671,7 +4622,7 @@ UnitAI.prototype.MoveToGarrisonRange = function(target)
var range = cmpGarrisonHolder.GetLoadingRange();
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return this.AbleToMove(cmpUnitMotion) && cmpUnitMotion.MoveToTargetRange(target, range.min, range.max);
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, range.min, range.max);
};
/**
@@ -5056,7 +5007,7 @@ UnitAI.prototype.ShouldAbandonChase = function(target, force, iid, type)
*/
UnitAI.prototype.ShouldChaseTargetedEntity = function(target, force)
{
if (!this.AbleToMove())
if (this.IsTurret())
return false;
if (this.GetStance().respondChase)
@@ -5382,11 +5333,11 @@ UnitAI.prototype.LeaveFoundation = function(target)
{
// If we're already being told to leave a foundation, then
// ignore this new request so we don't end up being too indecisive
// to ever actually move anywhere.
// to ever actually move anywhere
// Ignore also the request if we are packing
if (this.order && (this.order.type == "LeaveFoundation" || (this.order.type == "Flee" && this.order.data.target == target)))
return;
// Ignore also the request if we are packing.
if (this.orderQueue.length && this.orderQueue[0].type == "Unpack" && this.WillMoveFromFoundation(target, false))
{
let cmpPack = Engine.QueryInterface(this.entity, IID_Pack);
@@ -5448,10 +5399,7 @@ UnitAI.prototype.Garrison = function(target, queued)
UnitAI.prototype.Ungarrison = function()
{
if (this.IsGarrisoned())
{
this.SetImmobile(false);
this.AddOrder("Ungarrison", null, false);
}
};
/**
@@ -6,13 +6,6 @@ Engine.RegisterInterface("UnitAI");
*/
Engine.RegisterMessageType("UnitIdleChanged");
/**
* Message of the form { "ableToMove": boolean }
* sent from UnitAI whenever the unit's ability to move changes.
*/
Engine.RegisterMessageType("UnitAbleToMoveChanged");
/**
* Message of the form { "to": string }
* where "to" value is a UnitAI stance,
@@ -1,10 +1,8 @@
Engine.LoadHelperScript("FSM.js");
Engine.LoadHelperScript("Entity.js");
Engine.LoadHelperScript("Player.js");
Engine.LoadHelperScript("Sound.js");
Engine.LoadComponentScript("interfaces/Attack.js");
Engine.LoadComponentScript("interfaces/Auras.js");
Engine.LoadComponentScript("interfaces/Builder.js");
Engine.LoadComponentScript("interfaces/BuildingAI.js");
Engine.LoadComponentScript("interfaces/Capturable.js");
Engine.LoadComponentScript("interfaces/Resistance.js");
@@ -19,87 +17,6 @@ Engine.LoadComponentScript("interfaces/UnitAI.js");
Engine.LoadComponentScript("Formation.js");
Engine.LoadComponentScript("UnitAI.js");
/**
* Fairly straightforward test that entity renaming is handled
* by unitAI states. These ought to be augmented with integration tests, ideally.
*/
function TestTargetEntityRenaming(init_state, post_state, setup)
{
ResetState();
const player_ent = 5;
const target_ent = 6;
AddMock(SYSTEM_ENTITY, IID_Timer, {
"SetInterval": () => {},
"SetTimeout": () => {}
});
AddMock(SYSTEM_ENTITY, IID_ObstructionManager, {
"IsInTargetRange": () => false
});
let unitAI = ConstructComponent(player_ent, "UnitAI", {
"FormationController": "false",
"DefaultStance": "aggressive",
"FleeDistance": 10
});
unitAI.OnCreate();
setup(unitAI, player_ent, target_ent);
TS_ASSERT_EQUALS(unitAI.GetCurrentState(), init_state);
unitAI.OnGlobalEntityRenamed({
"entity": target_ent,
"newentity": target_ent + 1
});
TS_ASSERT_EQUALS(unitAI.GetCurrentState(), post_state);
}
TestTargetEntityRenaming(
"INDIVIDUAL.GARRISON.APPROACHING", "INDIVIDUAL.IDLE",
(unitAI, player_ent, target_ent) => {
unitAI.CanGarrison = (target) => target == target_ent;
unitAI.MoveToGarrisonRange = (target) => target == target_ent;
unitAI.AbleToMove = () => true;
AddMock(target_ent, IID_GarrisonHolder, {
"CanPickup": () => false
});
unitAI.Garrison(target_ent, false);
}
);
TestTargetEntityRenaming(
"INDIVIDUAL.REPAIR.REPAIRING", "INDIVIDUAL.IDLE",
(unitAI, player_ent, target_ent) => {
QueryBuilderListInterface = () => {};
unitAI.CheckTargetRange = () => true;
unitAI.CanRepair = (target) => target == target_ent;
unitAI.Repair(target_ent, false, false);
}
);
TestTargetEntityRenaming(
"INDIVIDUAL.FLEEING", "INDIVIDUAL.FLEEING",
(unitAI, player_ent, target_ent) => {
DistanceBetweenEntities = () => 10;
unitAI.CheckTargetRangeExplicit = () => false;
AddMock(player_ent, IID_UnitMotion, {
"MoveToTargetRange": () => true,
"GetRunMultiplier": () => 1,
"SetSpeedMultiplier": () => {},
"StopMoving": () => {}
});
unitAI.Flee(target_ent, false);
}
);
/* Regression test.
* Tests the FSM behaviour of a unit when walking as part of a formation,
* then exiting the formation.
@@ -651,11 +651,6 @@ public:
return ret;
}
virtual std::vector<entity_id_t> GetEntitiesBlockingMovement() const
{
return GetEntitiesByFlags(ICmpObstructionManager::FLAG_BLOCK_MOVEMENT);
}
virtual std::vector<entity_id_t> GetEntitiesBlockingConstruction() const
{
return GetEntitiesByFlags(ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION);
@@ -50,7 +50,6 @@ DEFINE_INTERFACE_METHOD_CONST_0("GetUnitRadius", entity_pos_t, ICmpObstruction,
DEFINE_INTERFACE_METHOD_CONST_0("CheckShorePlacement", bool, ICmpObstruction, CheckShorePlacement)
DEFINE_INTERFACE_METHOD_CONST_2("CheckFoundation", std::string, ICmpObstruction, CheckFoundation_wrapper, std::string, bool)
DEFINE_INTERFACE_METHOD_CONST_0("CheckDuplicateFoundation", bool, ICmpObstruction, CheckDuplicateFoundation)
DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesBlockingMovement", std::vector<entity_id_t>, ICmpObstruction, GetEntitiesBlockingMovement)
DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesBlockingConstruction", std::vector<entity_id_t>, ICmpObstruction, GetEntitiesBlockingConstruction)
DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesDeletedUponConstruction", std::vector<entity_id_t>, ICmpObstruction, GetEntitiesDeletedUponConstruction)
DEFINE_INTERFACE_METHOD_1("SetActive", void, ICmpObstruction, SetActive, bool)
@@ -104,12 +104,6 @@ public:
*/
virtual std::vector<entity_id_t> GetEntitiesByFlags(ICmpObstructionManager::flags_t flags) const = 0;
/**
* Returns a list of entities that are blocking movement.
* @return vector of blocking entities
*/
virtual std::vector<entity_id_t> GetEntitiesBlockingMovement() const = 0;
/**
* Returns a list of entities that are blocking construction of a foundation.
* @return vector of blocking entities
@@ -41,7 +41,6 @@ public:
virtual std::string CheckFoundation_wrapper(const std::string& UNUSED(className), bool UNUSED(onlyCenterPoint)) const { return std::string(); }
virtual bool CheckDuplicateFoundation() const { return true; }
virtual std::vector<entity_id_t> GetEntitiesByFlags(ICmpObstructionManager::flags_t UNUSED(flags)) const { return std::vector<entity_id_t>(); }
virtual std::vector<entity_id_t> GetEntitiesBlockingMovement() const { return std::vector<entity_id_t>(); }
virtual std::vector<entity_id_t> GetEntitiesBlockingConstruction() const { return std::vector<entity_id_t>(); }
virtual std::vector<entity_id_t> GetEntitiesDeletedUponConstruction() const { return std::vector<entity_id_t>(); }
virtual void ResolveFoundationCollisions() const { }