Added a function for finding colliding entities with identical control groups. Refs #1529.

This was SVN commit r12269.
This commit is contained in:
Deiz 2012-08-03 16:36:40 +00:00
parent 2ee61750b4
commit be31d3a9e7
4 changed files with 76 additions and 0 deletions

View File

@ -517,6 +517,38 @@ public:
return cmpPathfinder->CheckBuildingPlacement(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, GetEntityId(), passClass);
}
virtual bool CheckDuplicateFoundation()
{
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
if (!cmpPosition)
return false; // error
if (!cmpPosition->IsInWorld())
return false; // no obstruction
CFixedVector2D pos = cmpPosition->GetPosition2D();
CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
if (!cmpObstructionManager)
return false; // error
// required precondition to use SkipControlGroupsRequireFlagObstructionFilter
if (m_ControlGroup == INVALID_ENTITY)
{
LOGERROR(L"[CmpObstruction] Cannot test for foundation obstructions; primary control group must be valid");
return false;
}
// Ignore collisions with entities unless they block foundations and match both control groups.
SkipTagRequireControlGroupsAndFlagObstructionFilter filter(m_Tag, m_ControlGroup, m_ControlGroup2,
ICmpObstructionManager::FLAG_BLOCK_FOUNDATION);
if (m_Type == UNIT)
return !cmpObstructionManager->TestUnitShape(filter, pos.X, pos.Y, m_Size0, NULL);
else
return !cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, NULL);
}
virtual std::vector<entity_id_t> GetConstructionCollisions()
{
std::vector<entity_id_t> ret;

View File

@ -24,6 +24,7 @@
BEGIN_INTERFACE_WRAPPER(Obstruction)
DEFINE_INTERFACE_METHOD_0("GetUnitRadius", entity_pos_t, ICmpObstruction, GetUnitRadius)
DEFINE_INTERFACE_METHOD_1("CheckFoundation", bool, ICmpObstruction, CheckFoundation, std::string)
DEFINE_INTERFACE_METHOD_0("CheckDuplicateFoundation", bool, ICmpObstruction, CheckDuplicateFoundation)
DEFINE_INTERFACE_METHOD_0("GetConstructionCollisions", std::vector<entity_id_t>, ICmpObstruction, GetConstructionCollisions)
DEFINE_INTERFACE_METHOD_1("SetActive", void, ICmpObstruction, SetActive, bool)
DEFINE_INTERFACE_METHOD_3("SetDisableBlockMovementPathfinding", void, ICmpObstruction, SetDisableBlockMovementPathfinding, bool, bool, int32_t)

View File

@ -51,6 +51,13 @@ public:
*/
virtual bool CheckFoundation(std::string className) = 0;
/**
* Test whether this entity is colliding with any obstructions that share its
* control groups and block the creation of foundations.
* @return true if foundation is valid (not obstructed)
*/
virtual bool CheckDuplicateFoundation() = 0;
/**
* Returns a list of entities that are colliding with this entity, and that
* are set to block construction.

View File

@ -397,6 +397,42 @@ public:
}
};
/**
* Obstruction test filter that will test only against shapes that:
* - are part of both of the specified control groups
* - AND have at least one of the specified flags set.
*
* The first (primary) control group to include shapes from must be specified and valid.
*
* This filter is useful for preventing entities with identical control groups
* from colliding e.g. building a new wall segment on top of an existing wall)
*
* @todo This filter needs test cases.
*/
class SkipTagRequireControlGroupsAndFlagObstructionFilter : public IObstructionTestFilter
{
bool m_Exclude;
tag_t m_Tag;
entity_id_t m_Group;
entity_id_t m_Group2;
flags_t m_Mask;
public:
SkipTagRequireControlGroupsAndFlagObstructionFilter(tag_t tag, entity_id_t group1, entity_id_t group2, flags_t mask) :
m_Tag(tag), m_Group(group1), m_Group2(group2), m_Mask(mask)
{
ENSURE(m_Group != INVALID_ENTITY);
}
virtual bool TestShape(tag_t tag, flags_t flags, entity_id_t group, entity_id_t group2) const
{
// To be included in testing, a shape must not have the specified tag, and must
// match at least one of the flags in m_Mask, as well as both control groups.
return (tag.n != m_Tag.n && (flags & m_Mask) != 0 && ((group == m_Group
&& group2 == m_Group2) || (group2 == m_Group && group == m_Group2)));
}
};
/**
* Obstruction test filter that will test only against shapes that do not have the specified tag set.
*/