mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Delete sheep corpses when starting to build a foundation,
so that units don't try to gather forever while not being able to reach it and so that the sheep corpse can't be selected and seen anymore. Differential Revision: https://code.wildfiregames.com/D21 Fixes #4268 Based On Patch By: wraitii Reviewed By: temple Previously Reviewed By: Itms This was SVN commit r21597.
This commit is contained in:
parent
adfd2cfae1
commit
29492badb7
8 changed files with 78 additions and 12 deletions
|
|
@ -196,7 +196,9 @@ Foundation.prototype.Build = function(builderEnt, work)
|
|||
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
|
||||
if (cmpObstruction && cmpObstruction.GetBlockMovementFlag())
|
||||
{
|
||||
var collisions = cmpObstruction.GetUnitCollisions();
|
||||
// Remove all obstructions at the new entity, especially animal corpses
|
||||
let collisions = cmpObstruction.GetEntityCollisions();
|
||||
|
||||
if (collisions.length)
|
||||
{
|
||||
var cmpFoundationOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ function testFoundation(...mocks)
|
|||
|
||||
AddMock(foundationEnt, IID_Obstruction, {
|
||||
"GetBlockMovementFlag": () => true,
|
||||
"GetUnitCollisions": () => [],
|
||||
"GetEntityCollisions": () => [],
|
||||
"SetDisableBlockMovementPathfinding": () => {},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -190,8 +190,7 @@ function ObstructionsBlockingTemplateChange(ent, templateArg)
|
|||
var cmpNewObstruction = Engine.QueryInterface(previewEntity, IID_Obstruction);
|
||||
if (cmpNewObstruction && cmpNewObstruction.GetBlockMovementFlag())
|
||||
{
|
||||
// Check for units
|
||||
var collisions = cmpNewObstruction.GetUnitCollisions();
|
||||
let collisions = cmpNewObstruction.GetEntityCollisions();
|
||||
if (collisions.length)
|
||||
return DeleteEntityAndReturn(previewEntity, cmpPosition, pos, angle, cmpNewPosition, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ public:
|
|||
return ret; // error
|
||||
|
||||
// There are four 'block' flags: construction, foundation, movement,
|
||||
// and pathfinding. Structures have all of these flags, while units
|
||||
// and pathfinding. Structures have all of these flags, while most units
|
||||
// block only movement and construction.
|
||||
flags_t flags = ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION;
|
||||
|
||||
|
|
@ -642,6 +642,27 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
virtual std::vector<entity_id_t> GetEntityCollisions() const
|
||||
{
|
||||
std::vector<entity_id_t> ret;
|
||||
|
||||
CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSystemEntity());
|
||||
if (!cmpObstructionManager)
|
||||
return ret; // error
|
||||
|
||||
// Ignore collisions within the same control group.
|
||||
SkipControlGroupsRequireFlagObstructionFilter filter(true, m_ControlGroup, m_ControlGroup2, 0);
|
||||
|
||||
ICmpObstructionManager::ObstructionSquare square;
|
||||
if (!GetObstructionSquare(square))
|
||||
return ret; // error
|
||||
|
||||
cmpObstructionManager->GetUnitsOnObstruction(square, ret, filter, false);
|
||||
cmpObstructionManager->GetStaticObstructionsOnObstruction(square, ret, filter);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void SetMovingFlag(bool enabled)
|
||||
{
|
||||
m_Moving = enabled;
|
||||
|
|
|
|||
|
|
@ -476,6 +476,7 @@ public:
|
|||
virtual void GetUnitObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares) const;
|
||||
virtual void GetStaticObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares) const;
|
||||
virtual void GetUnitsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter, bool strict = false) const;
|
||||
virtual void GetStaticObstructionsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter) const;
|
||||
|
||||
virtual void SetPassabilityCircular(bool enabled)
|
||||
{
|
||||
|
|
@ -890,7 +891,7 @@ void CCmpObstructionManager::Rasterize(Grid<NavcellData>& grid, const std::vecto
|
|||
{
|
||||
case PathfinderPassability::PATHFINDING:
|
||||
{
|
||||
auto it = pathfindingMasks.find(passability.m_Clearance);
|
||||
std::map<entity_pos_t, u16>::iterator it = pathfindingMasks.find(passability.m_Clearance);
|
||||
if (it == pathfindingMasks.end())
|
||||
pathfindingMasks[passability.m_Clearance] = passability.m_Mask;
|
||||
else
|
||||
|
|
@ -979,7 +980,7 @@ void CCmpObstructionManager::GetUnitObstructionsInRange(const IObstructionTestFi
|
|||
m_UnitSubdivision.GetInRange(unitShapes, CFixedVector2D(x0, z0), CFixedVector2D(x1, z1));
|
||||
for (entity_id_t& unitShape : unitShapes)
|
||||
{
|
||||
auto it = m_UnitShapes.find(unitShape);
|
||||
std::map<u32, UnitShape>::const_iterator it = m_UnitShapes.find(unitShape);
|
||||
ENSURE(it != m_UnitShapes.end());
|
||||
|
||||
if (!filter.TestShape(UNIT_INDEX_TO_TAG(it->first), it->second.flags, it->second.group, INVALID_ENTITY))
|
||||
|
|
@ -1007,7 +1008,7 @@ void CCmpObstructionManager::GetStaticObstructionsInRange(const IObstructionTest
|
|||
m_StaticSubdivision.GetInRange(staticShapes, CFixedVector2D(x0, z0), CFixedVector2D(x1, z1));
|
||||
for (entity_id_t& staticShape : staticShapes)
|
||||
{
|
||||
auto it = m_StaticShapes.find(staticShape);
|
||||
std::map<u32, StaticShape>::const_iterator it = m_StaticShapes.find(staticShape);
|
||||
ENSURE(it != m_StaticShapes.end());
|
||||
|
||||
if (!filter.TestShape(STATIC_INDEX_TO_TAG(it->first), it->second.flags, it->second.group, it->second.group2))
|
||||
|
|
@ -1030,7 +1031,7 @@ void CCmpObstructionManager::GetUnitsOnObstruction(const ObstructionSquare& squa
|
|||
PROFILE("GetUnitsOnObstruction");
|
||||
|
||||
// In order to avoid getting units on impassable cells, we want to find all
|
||||
// units s.t. the RasterizeRectWithClearance of the building's shape with the
|
||||
// units subject to the RasterizeRectWithClearance of the building's shape with the
|
||||
// unit's clearance covers the navcell the unit is on.
|
||||
|
||||
std::vector<entity_id_t> unitShapes;
|
||||
|
|
@ -1044,7 +1045,7 @@ void CCmpObstructionManager::GetUnitsOnObstruction(const ObstructionSquare& squa
|
|||
|
||||
for (const u32& unitShape : unitShapes)
|
||||
{
|
||||
auto it = m_UnitShapes.find(unitShape);
|
||||
std::map<u32, UnitShape>::const_iterator it = m_UnitShapes.find(unitShape);
|
||||
ENSURE(it != m_UnitShapes.end());
|
||||
|
||||
const UnitShape& shape = it->second;
|
||||
|
|
@ -1086,6 +1087,40 @@ void CCmpObstructionManager::GetUnitsOnObstruction(const ObstructionSquare& squa
|
|||
}
|
||||
}
|
||||
|
||||
void CCmpObstructionManager::GetStaticObstructionsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter) const
|
||||
{
|
||||
PROFILE("GetStaticObstructionsOnObstruction");
|
||||
|
||||
std::vector<entity_id_t> staticShapes;
|
||||
CFixedVector2D center(square.x, square.z);
|
||||
CFixedVector2D expandedBox = Geometry::GetHalfBoundingBox(square.u, square.v, CFixedVector2D(square.hw, square.hh));
|
||||
m_StaticSubdivision.GetInRange(staticShapes, center - expandedBox, center + expandedBox);
|
||||
|
||||
for (const u32& staticShape : staticShapes)
|
||||
{
|
||||
std::map<u32, StaticShape>::const_iterator it = m_StaticShapes.find(staticShape);
|
||||
ENSURE(it != m_StaticShapes.end());
|
||||
|
||||
const StaticShape& shape = it->second;
|
||||
|
||||
if (!filter.TestShape(STATIC_INDEX_TO_TAG(staticShape), shape.flags, shape.group, shape.group2))
|
||||
continue;
|
||||
|
||||
if (Geometry::TestSquareSquare(
|
||||
center,
|
||||
square.u,
|
||||
square.v,
|
||||
CFixedVector2D(square.hw, square.hh),
|
||||
CFixedVector2D(shape.x, shape.z),
|
||||
shape.u,
|
||||
shape.v,
|
||||
CFixedVector2D(shape.hw, shape.hh)))
|
||||
{
|
||||
out.push_back(shape.entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCmpObstructionManager::RenderSubmit(SceneCollector& collector)
|
||||
{
|
||||
if (!m_DebugOverlayEnabled)
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ DEFINE_INTERFACE_METHOD_CONST_0("CheckShorePlacement", bool, ICmpObstruction, Ch
|
|||
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("GetUnitCollisions", std::vector<entity_id_t>, ICmpObstruction, GetUnitCollisions)
|
||||
DEFINE_INTERFACE_METHOD_CONST_0("GetEntityCollisions", std::vector<entity_id_t>, ICmpObstruction, GetEntityCollisions)
|
||||
DEFINE_INTERFACE_METHOD_1("SetActive", void, ICmpObstruction, SetActive, bool)
|
||||
DEFINE_INTERFACE_METHOD_3("SetDisableBlockMovementPathfinding", void, ICmpObstruction, SetDisableBlockMovementPathfinding, bool, bool, int32_t)
|
||||
DEFINE_INTERFACE_METHOD_CONST_0("GetBlockMovementFlag", bool, ICmpObstruction, GetBlockMovementFlag)
|
||||
|
|
|
|||
|
|
@ -89,11 +89,18 @@ public:
|
|||
virtual bool CheckDuplicateFoundation() const = 0;
|
||||
|
||||
/**
|
||||
* Returns a list of units that are colliding with this entity,
|
||||
* Returns a list of units that are colliding with this entity.
|
||||
* @return vector of blocking units
|
||||
*/
|
||||
virtual std::vector<entity_id_t> GetUnitCollisions() const = 0;
|
||||
|
||||
/**
|
||||
* Returns a list of entities that are colliding with this entity (excluding self).
|
||||
* This can be used to retrieve units with static obstructions, such as animal corpses.
|
||||
* @return vector of blocking units
|
||||
*/
|
||||
virtual std::vector<entity_id_t> GetEntityCollisions() const = 0;
|
||||
|
||||
/**
|
||||
* Detects collisions between foundation-blocking entities and
|
||||
* tries to fix them by setting control groups, if appropriate.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -245,6 +245,7 @@ public:
|
|||
virtual void GetObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares) const = 0;
|
||||
virtual void GetStaticObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares) const = 0;
|
||||
virtual void GetUnitObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares) const = 0;
|
||||
virtual void GetStaticObstructionsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter) const = 0;
|
||||
|
||||
/**
|
||||
* Returns the entity IDs of all unit shapes that intersect the given
|
||||
|
|
|
|||
Loading…
Reference in a new issue