mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-08-15 14:43:32 -07:00
Attempt minor improvements to stances code (see #865).
Don't chase units that are no longer visible, beyond where they were last seen (fixes #595). This was SVN commit r9657.
This commit is contained in:
parent
4e809a02e8
commit
92fcb737cd
7 changed files with 163 additions and 127 deletions
|
|
@ -274,7 +274,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
|
|||
}
|
||||
else if (guiName == "Stance")
|
||||
{
|
||||
var stanceSelected = Engine.GuiInterfaceCall("StanceSelected", {
|
||||
var stanceSelected = Engine.GuiInterfaceCall("IsStanceSelected", {
|
||||
"ents": g_Selection.toList(),
|
||||
"stance": item
|
||||
});
|
||||
|
|
@ -385,13 +385,19 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
|
|||
|
||||
var formations = getEntityFormationsList(entState);
|
||||
if (isUnit(entState) && !isAnimal(entState) && !entState.garrisonHolder && formations.length)
|
||||
{
|
||||
setupUnitPanel("Formation", usedPanels, entState, formations,
|
||||
function (item) { performFormation(entState.id, item); } );
|
||||
}
|
||||
|
||||
var stances = ["violent","aggressive","passive","defensive","stand"];
|
||||
// TODO: probably should load the stance list from a data file,
|
||||
// and/or vary depending on what units are selected
|
||||
var stances = ["violent", "aggressive", "passive", "defensive", "stand"];
|
||||
if (isUnit(entState) && !isAnimal(entState) && !entState.garrisonHolder && stances.length)
|
||||
{
|
||||
setupUnitPanel("Stance", usedPanels, entState, stances,
|
||||
function (item) { performStance(entState.id, item); } );
|
||||
}
|
||||
|
||||
if (entState.buildEntities && entState.buildEntities.length)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ GuiInterface.prototype.CanMoveEntsIntoFormation = function(player, data)
|
|||
return CanMoveEntsIntoFormation(data.ents, data.formationName);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.StanceSelected = function(player, data)
|
||||
GuiInterface.prototype.IsStanceSelected = function(player, data)
|
||||
{
|
||||
for each (var ent in data.ents)
|
||||
{
|
||||
|
|
@ -567,7 +567,7 @@ var exposedFunctions = {
|
|||
"GetNextNotification": 1,
|
||||
|
||||
"CanMoveEntsIntoFormation": 1,
|
||||
"StanceSelected": 1,
|
||||
"IsStanceSelected": 1,
|
||||
|
||||
"SetSelectionHighlight": 1,
|
||||
"SetStatusBars": 1,
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ UnitAI.prototype.Schema =
|
|||
"<a:example/>" +
|
||||
"<element name='DefaultStance'>" +
|
||||
"<choice>" +
|
||||
"<value>violent</value>" +
|
||||
"<value>aggressive</value>" +
|
||||
"<value>defensive</value>" +
|
||||
"<value>passive</value>" +
|
||||
"<value>stand</value>" +
|
||||
"</choice>" +
|
||||
"</element>" +
|
||||
"<element name='FormationController'>" +
|
||||
|
|
@ -45,60 +47,64 @@ UnitAI.prototype.Schema =
|
|||
"</interleave>" +
|
||||
"</optional>";
|
||||
|
||||
// Very basic stance support (currently just for test maps where we don't want
|
||||
// everyone killing each other immediately after loading, and for female citizens)
|
||||
// Unit stances.
|
||||
// There some targeting options:
|
||||
// targetVisibleEnemies: anything in vision range is a viable target
|
||||
// targetAttackers: anything that hurts us is a viable target
|
||||
// There are some response options, triggered when targets are detected:
|
||||
// respondFlee: run away
|
||||
// respondChase: start chasing after the enemy
|
||||
// TODO: maybe add respondStandGround, respondHoldGround (allow chasing a short distance then return),
|
||||
// targetAggressiveEnemies (don't worry about lone scouts, do worry around armies slaughtering
|
||||
// the guy standing next to you), etc.
|
||||
// TODO: even this limited version isn't implemented properly yet (e.g. it can't handle
|
||||
// dynamic stance changes).
|
||||
// respondChaseBeyondVision: start chasing, and don't stop even if it's out
|
||||
// of this unit's vision range (though still visible to the player)
|
||||
// respondStandGround: attack enemy but don't move at all
|
||||
// respondHoldGround: attack enemy but don't move far from current position
|
||||
// TODO: maybe add targetAggressiveEnemies (don't worry about lone scouts,
|
||||
// do worry around armies slaughtering the guy standing next to you), etc.
|
||||
var g_Stances = {
|
||||
"violent": {
|
||||
targetVisibleEnemies: true,
|
||||
targetAttackers: true,
|
||||
respondFlee: false,
|
||||
respondChase: true,
|
||||
respondStandGround : false,
|
||||
respondHoldGround : false,
|
||||
respondChaseToHell : true,
|
||||
respondChaseBeyondVision: true,
|
||||
respondStandGround: false,
|
||||
respondHoldGround: false,
|
||||
},
|
||||
"aggressive": {
|
||||
targetVisibleEnemies: true,
|
||||
targetAttackers: true,
|
||||
respondFlee: false,
|
||||
respondChase: true,
|
||||
respondStandGround : false,
|
||||
respondHoldGround : false,
|
||||
respondChaseBeyondVision: false,
|
||||
respondStandGround: false,
|
||||
respondHoldGround: false,
|
||||
},
|
||||
"defensive": {
|
||||
targetVisibleEnemies: true,
|
||||
targetAttackers: true,
|
||||
respondFlee: false,
|
||||
respondChase: false,
|
||||
respondStandGround : false,
|
||||
respondHoldGround : true,
|
||||
respondChaseBeyondVision: false,
|
||||
respondStandGround: false,
|
||||
respondHoldGround: true,
|
||||
},
|
||||
"passive": {
|
||||
targetVisibleEnemies: false,
|
||||
targetAttackers: true,
|
||||
respondFlee: true,
|
||||
respondChase: false,
|
||||
respondStandGround : false,
|
||||
respondHoldGround : false,
|
||||
respondChaseBeyondVision: false,
|
||||
respondStandGround: false,
|
||||
respondHoldGround: false,
|
||||
},
|
||||
"stand": {
|
||||
targetVisibleEnemies: true,
|
||||
targetAttackers: true,
|
||||
respondFlee: false,
|
||||
respondChase: false,
|
||||
respondStandGround : true,
|
||||
respondHoldGround : false,
|
||||
respondChaseBeyondVision: false,
|
||||
respondStandGround: true,
|
||||
respondHoldGround: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -137,11 +143,6 @@ var UnitFsmSpec = {
|
|||
// ignore
|
||||
},
|
||||
|
||||
"StanceChanged": function(msg) {
|
||||
if (this.StanceSpecificQuery(this.stance,true))
|
||||
return;
|
||||
},
|
||||
|
||||
// Formation handlers:
|
||||
|
||||
"FormationLeave": function(msg) {
|
||||
|
|
@ -246,27 +247,39 @@ var UnitFsmSpec = {
|
|||
}
|
||||
this.attackType = type;
|
||||
|
||||
// If we are already at the target, try attacking it from here
|
||||
if (this.CheckTargetRange(this.order.data.target, IID_Attack, this.attackType))
|
||||
{
|
||||
// We are already at the target
|
||||
// so try attacking it from here.
|
||||
this.StopMoving();
|
||||
if (this.IsAnimal())
|
||||
this.SetNextState("ANIMAL.COMBAT.ATTACKING");
|
||||
else
|
||||
this.SetNextState("INDIVIDUAL.COMBAT.ATTACKING");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we can't reach the target, but are standing ground,
|
||||
// then abandon this attack order
|
||||
if (this.GetStance().respondStandGround && !this.order.data.force)
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to move within attack range
|
||||
else if ((!this.GetStance().respondStandGround || this.order.data.force) && this.MoveToTargetRange(this.order.data.target, IID_Attack, this.attackType))
|
||||
if (this.MoveToTargetRange(this.order.data.target, IID_Attack, this.attackType))
|
||||
{
|
||||
// We've started walking to the given point
|
||||
if (this.IsAnimal())
|
||||
this.SetNextState("ANIMAL.COMBAT.APPROACHING");
|
||||
else
|
||||
this.SetNextState("INDIVIDUAL.COMBAT.APPROACHING");
|
||||
return;
|
||||
}
|
||||
else
|
||||
this.FinishOrder();
|
||||
|
||||
// We can't reach the target, and can't move towards it,
|
||||
// so abandon this attack order
|
||||
this.FinishOrder();
|
||||
},
|
||||
|
||||
"Order.Gather": function(msg) {
|
||||
|
|
@ -514,8 +527,8 @@ var UnitFsmSpec = {
|
|||
// If we entered the idle state we must have nothing better to do,
|
||||
// so immediately check whether there's anybody nearby to attack.
|
||||
// (If anyone approaches later, it'll be handled via LosRangeUpdate.)
|
||||
if (this.StanceSpecificQuery(this.stance))
|
||||
return true;
|
||||
if (this.FindNewTargets())
|
||||
return true; // (abort the FSM transition since we may have already switched state)
|
||||
|
||||
// Nobody to attack - stay in idle
|
||||
return false;
|
||||
|
|
@ -572,11 +585,6 @@ var UnitFsmSpec = {
|
|||
this.FinishOrder();
|
||||
}
|
||||
},
|
||||
|
||||
"StanceChanged": function(msg) {
|
||||
if (this.StanceSpecificQuery(this.stance))
|
||||
return;
|
||||
},
|
||||
},
|
||||
|
||||
"WALKING": {
|
||||
|
|
@ -634,12 +642,12 @@ var UnitFsmSpec = {
|
|||
},
|
||||
|
||||
"Timer": function(msg) {
|
||||
if (!this.ChaseTargetedEntity(this.order.data.target, this.order.data.force))
|
||||
if (this.ShouldAbandonChase(this.order.data.target, this.order.data.force))
|
||||
{
|
||||
this.StopMoving();
|
||||
this.FinishOrder();
|
||||
|
||||
// we return to our position
|
||||
// Return to our original position
|
||||
if (this.GetStance().respondHoldGround)
|
||||
this.WalkToHeldPosition();
|
||||
}
|
||||
|
|
@ -691,7 +699,8 @@ var UnitFsmSpec = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.ChaseTargetedEntity(this.order.data.target))
|
||||
// Can't reach it - try to chase after it
|
||||
if (this.ShouldChaseTargetedEntity(this.order.data.target, this.order.data.force))
|
||||
{
|
||||
if (this.MoveToTargetRange(this.order.data.target, IID_Attack, this.attackType))
|
||||
{
|
||||
|
|
@ -706,16 +715,13 @@ var UnitFsmSpec = {
|
|||
if (this.FinishOrder())
|
||||
return;
|
||||
|
||||
// see if we can switch to a new nearby enemy
|
||||
if (this.StanceSpecificQuery(this.stance, true))
|
||||
// See if we can switch to a new nearby enemy
|
||||
if (this.FindNewTargets())
|
||||
return;
|
||||
|
||||
// we return to our position
|
||||
// Return to our original position
|
||||
if (this.GetStance().respondHoldGround)
|
||||
{
|
||||
if (this.WalkToHeldPosition())
|
||||
return;
|
||||
}
|
||||
this.WalkToHeldPosition();
|
||||
},
|
||||
|
||||
// TODO: respond to target deaths immediately, rather than waiting
|
||||
|
|
@ -733,12 +739,12 @@ var UnitFsmSpec = {
|
|||
},
|
||||
|
||||
"Timer": function(msg) {
|
||||
if (!this.ChaseTargetedEntity(this.order.data.target))
|
||||
if (this.ShouldAbandonChase(this.order.data.target, this.order.data.force))
|
||||
{
|
||||
this.StopMoving();
|
||||
this.FinishOrder();
|
||||
|
||||
// we return to our position
|
||||
// Return to our original position
|
||||
if (this.GetStance().respondHoldGround)
|
||||
this.WalkToHeldPosition();
|
||||
}
|
||||
|
|
@ -1365,7 +1371,7 @@ UnitAI.prototype.OnCreate = function()
|
|||
|
||||
UnitAI.prototype.OnOwnershipChanged = function(msg)
|
||||
{
|
||||
this.SetupRangeQuery(msg.to);
|
||||
this.SetupRangeQuery();
|
||||
};
|
||||
|
||||
UnitAI.prototype.OnDestroy = function()
|
||||
|
|
@ -1382,8 +1388,11 @@ UnitAI.prototype.OnDestroy = function()
|
|||
// Set up a range query for all enemy units within LOS range
|
||||
// which can be attacked.
|
||||
// This should be called whenever our ownership changes.
|
||||
UnitAI.prototype.SetupRangeQuery = function(owner)
|
||||
UnitAI.prototype.SetupRangeQuery = function()
|
||||
{
|
||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
var owner = cmpOwnership.GetOwner();
|
||||
|
||||
var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||
var playerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
||||
|
||||
|
|
@ -1410,11 +1419,11 @@ UnitAI.prototype.SetupRangeQuery = function(owner)
|
|||
}
|
||||
}
|
||||
|
||||
var range = this.StanceSpecificRange();
|
||||
var range = this.GetQueryRange();
|
||||
|
||||
this.losRangeQuery = rangeMan.CreateActiveQuery(this.entity, 0, range.max, players, IID_DamageReceiver);
|
||||
this.losRangeQuery = rangeMan.CreateActiveQuery(this.entity, range.min, range.max, players, IID_DamageReceiver);
|
||||
rangeMan.EnableActiveQuery(this.losRangeQuery);
|
||||
}
|
||||
};
|
||||
|
||||
//// FSM linkage functions ////
|
||||
|
||||
|
|
@ -1861,12 +1870,18 @@ UnitAI.prototype.MoveToPointRange = function(x, z, rangeMin, rangeMax)
|
|||
|
||||
UnitAI.prototype.MoveToTarget = function(target)
|
||||
{
|
||||
if (!this.CheckTargetVisible(target))
|
||||
return false;
|
||||
|
||||
var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
|
||||
return cmpUnitMotion.MoveToTargetRange(target, 0, 0);
|
||||
};
|
||||
|
||||
UnitAI.prototype.MoveToTargetRange = function(target, iid, type)
|
||||
{
|
||||
if (!this.CheckTargetVisible(target))
|
||||
return false;
|
||||
|
||||
var cmpRanged = Engine.QueryInterface(this.entity, iid);
|
||||
var range = cmpRanged.GetRange(type);
|
||||
|
||||
|
|
@ -1876,6 +1891,9 @@ UnitAI.prototype.MoveToTargetRange = function(target, iid, type)
|
|||
|
||||
UnitAI.prototype.MoveToTargetRangeExplicit = function(target, min, max)
|
||||
{
|
||||
if (!this.CheckTargetVisible(target))
|
||||
return false;
|
||||
|
||||
var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
|
||||
return cmpUnitMotion.MoveToTargetRange(target, min, max);
|
||||
};
|
||||
|
|
@ -1889,6 +1907,26 @@ UnitAI.prototype.CheckTargetRange = function(target, iid, type)
|
|||
return cmpUnitMotion.IsInTargetRange(target, range.min, range.max);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the target entity is visible through the FoW/SoD.
|
||||
*/
|
||||
UnitAI.prototype.CheckTargetVisible = function(target)
|
||||
{
|
||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
if (!cmpOwnership)
|
||||
return false;
|
||||
|
||||
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||
if (!cmpRangeManager)
|
||||
return false;
|
||||
|
||||
if (cmpRangeManager.GetLosVisibility(target, cmpOwnership.GetOwner()) == "hidden")
|
||||
return false;
|
||||
|
||||
// Either visible directly, or visible in fog
|
||||
return true;
|
||||
};
|
||||
|
||||
UnitAI.prototype.FaceTowardsTarget = function(target)
|
||||
{
|
||||
var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
|
||||
|
|
@ -1942,7 +1980,7 @@ UnitAI.prototype.CheckTargetIsInVisionRange = function(target)
|
|||
var distance = DistanceBetweenEntities(this.entity,target);
|
||||
|
||||
return distance < range;
|
||||
}
|
||||
};
|
||||
|
||||
UnitAI.prototype.GetBestAttack = function()
|
||||
{
|
||||
|
|
@ -1971,8 +2009,8 @@ UnitAI.prototype.AttackVisibleEntity = function(ents)
|
|||
};
|
||||
|
||||
/**
|
||||
* Try to find one of the given entities which can be attacked,
|
||||
* within zone.
|
||||
* Try to find one of the given entities which can be attacked
|
||||
* and which is close to the hold position, and start attacking it.
|
||||
* Returns true if it found something to attack.
|
||||
*/
|
||||
UnitAI.prototype.AttackEntityInZone = function(ents)
|
||||
|
|
@ -2017,38 +2055,45 @@ UnitAI.prototype.RespondToTargetedEntities = function(ents)
|
|||
return false;
|
||||
};
|
||||
|
||||
/*
|
||||
* Try to chase targeted entity given our current stance
|
||||
/**
|
||||
* Returns true if we should stop following the target entity.
|
||||
*/
|
||||
UnitAI.prototype.ChaseTargetedEntity = function(ent, force)
|
||||
UnitAI.prototype.ShouldAbandonChase = function(target, force)
|
||||
{
|
||||
if (this.GetStance().respondChase)
|
||||
{
|
||||
if (this.CheckTargetIsInVisionRange(ent))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Stop if we're in hold-ground mode and it's too far from the holding point
|
||||
if (this.GetStance().respondHoldGround)
|
||||
{
|
||||
if (!this.CheckTargetDistanceFromHeldPosition(target, this.attackType))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.GetStance().respondChaseToHell || force)
|
||||
{
|
||||
//if ( TODO : Check ent is not in Shroud of Darkness)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Stop if it's left our vision range, unless we're especially persistent
|
||||
if (!force && !this.GetStance().respondChaseBeyondVision)
|
||||
{
|
||||
if (!this.CheckTargetIsInVisionRange(target))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.GetStance().respondHoldGround)
|
||||
{
|
||||
if (this.CheckTargetDistanceFromHeldPosition(ent, this.attackType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// (Note that CCmpUnitMotion will detect if the target is lost in FoW,
|
||||
// and will continue moving to its last seen position and then stop)
|
||||
|
||||
return false;
|
||||
return false;
|
||||
};
|
||||
|
||||
}
|
||||
/*
|
||||
* Returns whether we should chase the targeted entity,
|
||||
* given our current stance.
|
||||
*/
|
||||
UnitAI.prototype.ShouldChaseTargetedEntity = function(target, force)
|
||||
{
|
||||
if (this.GetStance().respondChase)
|
||||
return true;
|
||||
|
||||
if (force)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
//// External interface functions ////
|
||||
|
||||
|
|
@ -2289,32 +2334,29 @@ UnitAI.prototype.SwitchToStance = function(stance)
|
|||
if (stance == "stand" || stance == "defensive" || stance == "passive")
|
||||
this.StopMoving();
|
||||
|
||||
UnitFsm.ProcessMessage(this, {"type": "StanceChanged", "stance": stance});
|
||||
// Reset the range query, since the range depends on stance
|
||||
this.SetupRangeQuery();
|
||||
}
|
||||
|
||||
UnitAI.prototype.StanceSpecificQuery = function(stance, disable)
|
||||
/**
|
||||
* Resets losRangeQuery, and if there are some targets in range that we can
|
||||
* attack then we start attacking and this returns true; otherwise, returns false.
|
||||
*/
|
||||
UnitAI.prototype.FindNewTargets = function()
|
||||
{
|
||||
if (!g_Stances[stance])
|
||||
{
|
||||
error("UnitAI: Setting to invalid stance '"+stance+"'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.losRangeQuery)
|
||||
return false;
|
||||
|
||||
var range = this.StanceSpecificRange();
|
||||
|
||||
var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||
var ents = rangeMan.ModifyRangeActiveQuery(this.losRangeQuery, range.min, range.max);
|
||||
var ents = rangeMan.ResetActiveQuery(this.losRangeQuery);
|
||||
|
||||
if (disable && !this.IsAnimal())
|
||||
rangeMan.DisableActiveQuery(this.losRangeQuery);
|
||||
if (!this.GetStance().targetVisibleEnemies)
|
||||
return false;
|
||||
|
||||
return this.RespondToTargetedEntities(ents);
|
||||
};
|
||||
|
||||
UnitAI.prototype.StanceSpecificRange = function()
|
||||
UnitAI.prototype.GetQueryRange = function()
|
||||
{
|
||||
var ret = { "min": 0, "max": 0 };
|
||||
if (this.GetStance().respondStandGround)
|
||||
|
|
|
|||
|
|
@ -459,23 +459,6 @@ public:
|
|||
return (tag_t)id;
|
||||
}
|
||||
|
||||
virtual std::vector<entity_id_t> ModifyRangeActiveQuery(tag_t tag,
|
||||
entity_pos_t minRange, entity_pos_t maxRange)
|
||||
{
|
||||
std::map<tag_t, Query>::iterator it = m_Queries.find(tag);
|
||||
if (it == m_Queries.end())
|
||||
{
|
||||
LOGERROR(L"CCmpRangeManager: ModifyRangeActiveQuery called with invalid tag %d", tag);
|
||||
std::vector<entity_id_t> r;
|
||||
return r;
|
||||
}
|
||||
|
||||
Query& q = it->second;
|
||||
q.minRange = minRange;
|
||||
q.maxRange = maxRange;
|
||||
return ResetActiveQuery(tag);
|
||||
}
|
||||
|
||||
virtual void DestroyActiveQuery(tag_t tag)
|
||||
{
|
||||
if (m_Queries.find(tag) == m_Queries.end())
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@
|
|||
|
||||
#include "ICmpObstruction.h"
|
||||
#include "ICmpObstructionManager.h"
|
||||
#include "ICmpOwnership.h"
|
||||
#include "ICmpPosition.h"
|
||||
#include "ICmpPathfinder.h"
|
||||
#include "ICmpRangeManager.h"
|
||||
#include "simulation2/MessageTypes.h"
|
||||
#include "simulation2/helpers/Geometry.h"
|
||||
#include "simulation2/helpers/Render.h"
|
||||
|
|
@ -1003,6 +1005,20 @@ bool CCmpUnitMotion::CheckTargetMovement(CFixedVector2D from, entity_pos_t minDe
|
|||
if (!PathIsShort(m_LongPath, from, CHECK_TARGET_MOVEMENT_AT_MAX_DIST))
|
||||
return false;
|
||||
|
||||
// Fail if the target is no longer visible to this entity's owner
|
||||
// (in which case we'll continue moving to its last known location,
|
||||
// unless it comes back into view before we reach that location)
|
||||
CmpPtr<ICmpOwnership> cmpOwnership(GetSimContext(), GetEntityId());
|
||||
if (!cmpOwnership.null())
|
||||
{
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(GetSimContext(), SYSTEM_ENTITY);
|
||||
if (!cmpRangeManager.null())
|
||||
{
|
||||
if (cmpRangeManager->GetLosVisibility(m_TargetEntity, cmpOwnership->GetOwner()) == ICmpRangeManager::VIS_HIDDEN)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The target moved and we need to update our current path;
|
||||
// change the goal here and expect our caller to start the path request
|
||||
m_FinalGoal.x = targetPos.X;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ std::string ICmpRangeManager::GetLosVisibility_wrapper(entity_id_t ent, int play
|
|||
BEGIN_INTERFACE_WRAPPER(RangeManager)
|
||||
DEFINE_INTERFACE_METHOD_5("ExecuteQuery", std::vector<entity_id_t>, ICmpRangeManager, ExecuteQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector<int>, int)
|
||||
DEFINE_INTERFACE_METHOD_5("CreateActiveQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector<int>, int)
|
||||
DEFINE_INTERFACE_METHOD_3("ModifyRangeActiveQuery", std::vector<entity_id_t>, ICmpRangeManager, ModifyRangeActiveQuery, ICmpRangeManager::tag_t, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_1("DestroyActiveQuery", void, ICmpRangeManager, DestroyActiveQuery, ICmpRangeManager::tag_t)
|
||||
DEFINE_INTERFACE_METHOD_1("EnableActiveQuery", void, ICmpRangeManager, EnableActiveQuery, ICmpRangeManager::tag_t)
|
||||
DEFINE_INTERFACE_METHOD_1("DisableActiveQuery", void, ICmpRangeManager, DisableActiveQuery, ICmpRangeManager::tag_t)
|
||||
|
|
|
|||
|
|
@ -101,16 +101,6 @@ public:
|
|||
virtual tag_t CreateActiveQuery(entity_id_t source,
|
||||
entity_pos_t minRange, entity_pos_t maxRange, std::vector<int> owners, int requiredInterface) = 0;
|
||||
|
||||
/**
|
||||
* Modify an active query's range parameters and execute a ResetActiveQuery.
|
||||
* @param tag identifier of query.
|
||||
* @param minRange non-negative minimum distance in metres (inclusive).
|
||||
* @param maxRange non-negative maximum distance in metres (inclusive); or -1.0 to ignore distance.
|
||||
* @return list of entities matching the query, ordered by increasing distance from the source entity.
|
||||
*/
|
||||
virtual std::vector<entity_id_t> ModifyRangeActiveQuery(tag_t tag,
|
||||
entity_pos_t minRange, entity_pos_t maxRange) = 0;
|
||||
|
||||
/**
|
||||
* Destroy a query and clean up resources. This must be called when an entity no longer needs its
|
||||
* query (e.g. when the entity is destroyed).
|
||||
|
|
|
|||
Loading…
Reference in a new issue