* Add method to rangemanager to query around a position instead of an entity

* Use that method in the splash damage calculation
Fixes #2285

This was SVN commit r14283.
This commit is contained in:
sanderd17 2013-12-04 15:30:01 +00:00
parent 367614343b
commit 60c986c135
4 changed files with 37 additions and 21 deletions

View File

@ -99,14 +99,6 @@ Damage.EntitiesNearPoint = function(origin, radius, players)
// If there is insufficient data return an empty array.
if (!origin || !radius)
return [];
// Create/recycle the dummy entity used for range calculations.
if (!Damage.dummyTargetEntity || dummyPath != Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager).GetCurrentTemplateName(Damage.dummyTargetEntity))
Damage.dummyTargetEntity = Engine.AddEntity(dummyPath);
// Move the dummy entity to the origin of the query.
var cmpDummyPosition = Engine.QueryInterface(Damage.dummyTargetEntity, IID_Position);
if (!cmpDummyPosition)
return [];
cmpDummyPosition.JumpTo(origin.x, origin.z);
// If the players parameter is not specified use all players.
if (!players)
@ -119,7 +111,7 @@ Damage.EntitiesNearPoint = function(origin, radius, players)
// Call RangeManager with dummy entity and return the result.
var rangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
var rangeQuery = rangeManager.ExecuteQuery(Damage.dummyTargetEntity, 0, radius, players, IID_DamageReceiver);
var rangeQuery = rangeManager.ExecuteQueryAroundPos({"x": origin.x, "y": origin.z}, 0, radius, players, IID_DamageReceiver);
return rangeQuery;
};

View File

@ -33,7 +33,6 @@
#include "graphics/Overlay.h"
#include "graphics/Terrain.h"
#include "lib/timer.h"
#include "maths/FixedVector2D.h"
#include "ps/CLogger.h"
#include "ps/Overlay.h"
#include "ps/Profile.h"
@ -729,6 +728,20 @@ public:
q.enabled = false;
}
virtual std::vector<entity_id_t> ExecuteQueryAroundPos(CFixedVector2D pos,
entity_pos_t minRange, entity_pos_t maxRange,
std::vector<int> owners, int requiredInterface)
{
Query q = ConstructQuery(INVALID_ENTITY, minRange, maxRange, owners, requiredInterface, GetEntityFlagMask("normal"));
std::vector<entity_id_t> r;
PerformQuery(q, r, pos);
// Return the list sorted by distance from the entity
std::stable_sort(r.begin(), r.end(), EntityDistanceOrdering(m_EntityData, pos));
return r;
}
virtual std::vector<entity_id_t> ExecuteQuery(entity_id_t source,
entity_pos_t minRange, entity_pos_t maxRange,
std::vector<int> owners, int requiredInterface)
@ -746,10 +759,10 @@ public:
return r;
}
PerformQuery(q, r);
CFixedVector2D pos = cmpSourcePosition->GetPosition2D();
PerformQuery(q, r, pos);
// Return the list sorted by distance from the entity
CFixedVector2D pos = cmpSourcePosition->GetPosition2D();
std::stable_sort(r.begin(), r.end(), EntityDistanceOrdering(m_EntityData, pos));
return r;
@ -779,12 +792,12 @@ public:
return r;
}
PerformQuery(q, r);
CFixedVector2D pos = cmpSourcePosition->GetPosition2D();
PerformQuery(q, r, pos);
q.lastMatch = r;
// Return the list sorted by distance from the entity
CFixedVector2D pos = cmpSourcePosition->GetPosition2D();
std::stable_sort(r.begin(), r.end(), EntityDistanceOrdering(m_EntityData, pos));
return r;
@ -841,7 +854,8 @@ public:
results.clear();
results.reserve(query.lastMatch.size());
PerformQuery(query, results);
CFixedVector2D pos = cmpSourcePosition->GetPosition2D();
PerformQuery(query, results, pos);
// Compute the changes vs the last match
added.clear();
@ -902,12 +916,8 @@ public:
/**
* Returns a list of distinct entity IDs that match the given query, sorted by ID.
*/
void PerformQuery(const Query& q, std::vector<entity_id_t>& r)
void PerformQuery(const Query& q, std::vector<entity_id_t>& r, CFixedVector2D pos)
{
CmpPtr<ICmpPosition> cmpSourcePosition(q.source);
if (!cmpSourcePosition || !cmpSourcePosition->IsInWorld())
return;
CFixedVector2D pos = cmpSourcePosition->GetPosition2D();
// Special case: range -1.0 means check all entities ignoring distance
if (q.maxRange == entity_pos_t::FromInt(-1))
@ -924,6 +934,7 @@ public:
else if (q.parabolic)
{
// elevationBonus is part of the 3D position, as the source is really that much heigher
CmpPtr<ICmpPosition> cmpSourcePosition(q.source);
CFixedVector3D pos3d = cmpSourcePosition->GetPosition()+
CFixedVector3D(entity_pos_t::Zero(), q.elevationBonus, entity_pos_t::Zero()) ;
// Get a quick list of entities that are potentially in range, with a cutoff of 2*maxRange
@ -992,7 +1003,6 @@ public:
}
}
virtual entity_pos_t GetElevationAdaptedRange(CFixedVector3D pos, CFixedVector3D rot, entity_pos_t range, entity_pos_t elevationBonus, entity_pos_t angle)
{
entity_pos_t r = entity_pos_t::Zero() ;

View File

@ -35,6 +35,7 @@ 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("ExecuteQueryAroundPos", std::vector<entity_id_t>, ICmpRangeManager, ExecuteQueryAroundPos, CFixedVector2D, entity_pos_t, entity_pos_t, std::vector<int>, int)
DEFINE_INTERFACE_METHOD_6("CreateActiveQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector<int>, int, u8)
DEFINE_INTERFACE_METHOD_7("CreateActiveParabolicQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveParabolicQuery, entity_id_t, entity_pos_t, entity_pos_t, entity_pos_t, std::vector<int>, int, u8)
DEFINE_INTERFACE_METHOD_1("DestroyActiveQuery", void, ICmpRangeManager, DestroyActiveQuery, ICmpRangeManager::tag_t)

View File

@ -19,6 +19,7 @@
#define INCLUDED_ICMPRANGEMANAGER
#include "maths/FixedVector3D.h"
#include "maths/FixedVector2D.h"
#include "simulation2/system/Interface.h"
#include "simulation2/helpers/Position.h"
@ -91,6 +92,18 @@ public:
virtual std::vector<entity_id_t> ExecuteQuery(entity_id_t source,
entity_pos_t minRange, entity_pos_t maxRange, std::vector<int> owners, int requiredInterface) = 0;
/**
* Execute a passive query.
* @param pos the position around which the range will be computed.
* @param minRange non-negative minimum distance in metres (inclusive).
* @param maxRange non-negative maximum distance in metres (inclusive); or -1.0 to ignore distance.
* @param owners list of player IDs that matching entities may have; -1 matches entities with no owner.
* @param requiredInterface if non-zero, an interface ID that matching entities must implement.
* @return list of entities matching the query, ordered by increasing distance from the source entity.
*/
virtual std::vector<entity_id_t> ExecuteQueryAroundPos(CFixedVector2D pos,
entity_pos_t minRange, entity_pos_t maxRange, std::vector<int> owners, int requiredInterface) = 0;
/**
* Construct an active query. The query will be disabled by default.
* @param source the entity around which the range will be computed.