Index: binaries/data/mods/public/maps/random/rmgen-common/player.js
===================================================================
--- binaries/data/mods/public/maps/random/rmgen-common/player.js
+++ binaries/data/mods/public/maps/random/rmgen-common/player.js
@@ -122,6 +122,9 @@
if (civ != "iber" || g_Map.getSize() <= 128)
return;
+ // TODO: should prevent trees inside forests
+ // When fixing, remove the DeleteUponConstruction flag from template_gaia_flora.xml
+
if (wallType == "towers")
placePolygonalWall(position, 15, ["entry"], "tower", civ, playerID, orientation, 7);
else if (wallType)
Index: binaries/data/mods/public/simulation/components/Foundation.js
===================================================================
--- binaries/data/mods/public/simulation/components/Foundation.js
+++ binaries/data/mods/public/simulation/components/Foundation.js
@@ -191,31 +191,22 @@
if (this.GetBuildProgress() == 1.0)
return;
- // If there's any units in the way, ask them to move away
- // and return early from this method.
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
+ // If there are any units in the way, ask them to move away and return early from this method.
if (cmpObstruction && cmpObstruction.GetBlockMovementFlag())
{
- // Remove all obstructions at the new entity, especially animal corpses
- let collisions = cmpObstruction.GetEntityCollisions();
+ // Remove animal corpses
+ for (let ent of cmpObstruction.GetEntitiesDeletedUponConstruction())
+ Engine.DestroyEntity(ent);
+ let collisions = cmpObstruction.GetEntitiesBlockingConstruction();
if (collisions.length)
{
- var cmpFoundationOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
for (var ent of collisions)
{
var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
if (cmpUnitAI)
cmpUnitAI.LeaveFoundation(this.entity);
- else
- {
- // If obstructing fauna is gaia or our own but doesn't have UnitAI, just destroy it
- var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
- var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
- if (cmpOwnership && cmpIdentity && cmpIdentity.HasClass("Animal")
- && (cmpOwnership.GetOwner() == 0 || cmpFoundationOwnership && cmpOwnership.GetOwner() == cmpFoundationOwnership.GetOwner()))
- Engine.DestroyEntity(ent);
- }
// TODO: What if an obstruction has no UnitAI?
}
Index: binaries/data/mods/public/simulation/components/Gate.js
===================================================================
--- binaries/data/mods/public/simulation/components/Gate.js
+++ binaries/data/mods/public/simulation/components/Gate.js
@@ -140,14 +140,19 @@
Gate.prototype.LockGate = function()
{
this.locked = true;
+
+ // Delete animal corpses to prevent units trying to gather the unreachable entity
+ let cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
+ if (cmpObstruction && cmpObstruction.GetBlockMovementFlag())
+ for (let ent of cmpObstruction.GetEntitiesDeletedUponConstruction())
+ Engine.DestroyEntity(ent);
+
// If the door is closed, enable 'block pathfinding'
// Else 'block pathfinding' will be enabled the next time the gate close
if (!this.opened)
{
- var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
- if (!cmpObstruction)
- return;
- cmpObstruction.SetDisableBlockMovementPathfinding(false, false, 0);
+ if (cmpObstruction)
+ cmpObstruction.SetDisableBlockMovementPathfinding(false, false, 0);
}
else
this.OperateGate();
@@ -215,7 +220,7 @@
return;
// The gate can't be closed if there are entities colliding with it.
- var collisions = cmpObstruction.GetUnitCollisions();
+ var collisions = cmpObstruction.GetEntitiesBlockingConstruction();
if (collisions.length)
{
if (!this.timer)
Index: binaries/data/mods/public/simulation/components/tests/test_Foundation.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_Foundation.js
+++ binaries/data/mods/public/simulation/components/tests/test_Foundation.js
@@ -62,7 +62,8 @@
AddMock(foundationEnt, IID_Obstruction, {
"GetBlockMovementFlag": () => true,
- "GetEntityCollisions": () => [],
+ "GetEntitiesBlockingConstruction": () => [],
+ "GetEntitiesDeletedUponConstruction": () => [],
"SetDisableBlockMovementPathfinding": () => {},
});
Index: binaries/data/mods/public/simulation/helpers/Transform.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Transform.js
+++ binaries/data/mods/public/simulation/helpers/Transform.js
@@ -190,7 +190,11 @@
var cmpNewObstruction = Engine.QueryInterface(previewEntity, IID_Obstruction);
if (cmpNewObstruction && cmpNewObstruction.GetBlockMovementFlag())
{
- let collisions = cmpNewObstruction.GetEntityCollisions();
+ // Remove all obstructions at the new entity, especially animal corpses
+ for (let ent of cmpNewObstruction.GetEntitiesDeletedUponConstruction())
+ Engine.DestroyEntity(ent);
+
+ let collisions = cmpNewObstruction.GetEntitiesBlockingConstruction();
if (collisions.length)
return DeleteEntityAndReturn(previewEntity, cmpPosition, pos, angle, cmpNewPosition, true);
}
Index: binaries/data/mods/public/simulation/templates/special/filter/mirage.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/special/filter/mirage.xml
+++ binaries/data/mods/public/simulation/templates/special/filter/mirage.xml
@@ -17,6 +17,7 @@
false
false
false
+ false
Index: binaries/data/mods/public/simulation/templates/special/filter/resource.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/special/filter/resource.xml
+++ binaries/data/mods/public/simulation/templates/special/filter/resource.xml
@@ -14,7 +14,8 @@
false
false
false
- false
+ true
+ true
false
false
Index: binaries/data/mods/public/simulation/templates/template_gaia.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_gaia.xml
+++ binaries/data/mods/public/simulation/templates/template_gaia.xml
@@ -14,6 +14,7 @@
true
false
false
+ false
Index: binaries/data/mods/public/simulation/templates/template_gaia_flora.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_gaia_flora.xml
+++ binaries/data/mods/public/simulation/templates/template_gaia_flora.xml
@@ -10,6 +10,8 @@
+
+ true
false
Index: binaries/data/mods/public/simulation/templates/template_structure.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure.xml
+++ binaries/data/mods/public/simulation/templates/template_structure.xml
@@ -78,6 +78,7 @@
true
false
false
+ false
Index: binaries/data/mods/public/simulation/templates/template_unit.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit.xml
+++ binaries/data/mods/public/simulation/templates/template_unit.xml
@@ -63,6 +63,7 @@
true
false
false
+ false
Index: source/simulation2/components/CCmpObstruction.cpp
===================================================================
--- source/simulation2/components/CCmpObstruction.cpp
+++ source/simulation2/components/CCmpObstruction.cpp
@@ -168,6 +168,9 @@
""
""
""
+ ""
+ ""
+ ""
""
""
""
@@ -195,6 +198,8 @@
m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_FOUNDATION;
if (paramNode.GetChild("BlockConstruction").ToBool())
m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION;
+ if (paramNode.GetChild("DeleteUponConstruction").ToBool())
+ m_TemplateFlags |= ICmpObstructionManager::FLAG_DELETE_UPON_CONSTRUCTION;
m_Flags = m_TemplateFlags;
if (paramNode.GetChild("DisableBlockMovement").ToBool())
@@ -615,7 +620,7 @@
return !cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, NULL );
}
- virtual std::vector GetUnitCollisions() const
+ virtual std::vector GetEntitiesByFlags(flags_t flags) const
{
std::vector ret;
@@ -623,11 +628,6 @@
if (!cmpObstructionManager)
return ret; // error
- // There are four 'block' flags: construction, foundation, movement,
- // and pathfinding. Structures have all of these flags, while most units
- // block only movement and construction.
- flags_t flags = ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION;
-
// Ignore collisions within the same control group, or with other shapes that don't match the filter.
// Note that, since the control group for each entity defaults to the entity's ID, this is typically
// equivalent to only ignoring the entity's own shape and other shapes that don't match the filter.
@@ -637,30 +637,20 @@
if (!GetObstructionSquare(square))
return ret; // error
- cmpObstructionManager->GetUnitsOnObstruction(square, ret, filter);
+ cmpObstructionManager->GetUnitsOnObstruction(square, ret, filter, false);
+ cmpObstructionManager->GetStaticObstructionsOnObstruction(square, ret, filter);
return ret;
}
- virtual std::vector GetEntityCollisions() const
+ virtual std::vector GetEntitiesBlockingConstruction() const
{
- std::vector ret;
-
- CmpPtr 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 GetEntitiesByFlags(ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION);
+ }
- return ret;
+ virtual std::vector GetEntitiesDeletedUponConstruction() const
+ {
+ return GetEntitiesByFlags(ICmpObstructionManager::FLAG_DELETE_UPON_CONSTRUCTION);
}
virtual void SetMovingFlag(bool enabled)
Index: source/simulation2/components/ICmpObstruction.h
===================================================================
--- source/simulation2/components/ICmpObstruction.h
+++ source/simulation2/components/ICmpObstruction.h
@@ -89,17 +89,22 @@
virtual bool CheckDuplicateFoundation() const = 0;
/**
- * Returns a list of units that are colliding with this entity.
- * @return vector of blocking units
+ * Returns a list of entities that have an obstruction matching the given flag and intersect the current obstruction.
+ * @return vector of blocking entities
*/
- virtual std::vector GetUnitCollisions() const = 0;
+ virtual std::vector GetEntitiesByFlags(ICmpObstructionManager::flags_t flags) 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
+ * Returns a list of entities that are blocking construction of a foundation.
+ * @return vector of blocking entities
*/
- virtual std::vector GetEntityCollisions() const = 0;
+ virtual std::vector GetEntitiesBlockingConstruction() const = 0;
+
+ /**
+ * Returns a list of entities that shall be deleted when a construction on this obstruction starts,
+ * for example sheep carcasses.
+ */
+ virtual std::vector GetEntitiesDeletedUponConstruction() const = 0;
/**
* Detects collisions between foundation-blocking entities and
Index: source/simulation2/components/ICmpObstruction.cpp
===================================================================
--- source/simulation2/components/ICmpObstruction.cpp
+++ source/simulation2/components/ICmpObstruction.cpp
@@ -50,8 +50,8 @@
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("GetUnitCollisions", std::vector, ICmpObstruction, GetUnitCollisions)
-DEFINE_INTERFACE_METHOD_CONST_0("GetEntityCollisions", std::vector, ICmpObstruction, GetEntityCollisions)
+DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesBlockingConstruction", std::vector, ICmpObstruction, GetEntitiesBlockingConstruction)
+DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesDeletedUponConstruction", std::vector, ICmpObstruction, GetEntitiesDeletedUponConstruction)
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)
Index: source/simulation2/components/ICmpObstructionManager.h
===================================================================
--- source/simulation2/components/ICmpObstructionManager.h
+++ source/simulation2/components/ICmpObstructionManager.h
@@ -71,11 +71,12 @@
*/
enum EFlags
{
- FLAG_BLOCK_MOVEMENT = (1 << 0), // prevents units moving through this shape
- FLAG_BLOCK_FOUNDATION = (1 << 1), // prevents foundations being placed on this shape
- FLAG_BLOCK_CONSTRUCTION = (1 << 2), // prevents buildings being constructed on this shape
- FLAG_BLOCK_PATHFINDING = (1 << 3), // prevents the tile pathfinder choosing paths through this shape
- FLAG_MOVING = (1 << 4) // indicates this unit is currently moving
+ FLAG_BLOCK_MOVEMENT = (1 << 0), // prevents units moving through this shape
+ FLAG_BLOCK_FOUNDATION = (1 << 1), // prevents foundations being placed on this shape
+ FLAG_BLOCK_CONSTRUCTION = (1 << 2), // prevents buildings being constructed on this shape
+ FLAG_BLOCK_PATHFINDING = (1 << 3), // prevents the tile pathfinder choosing paths through this shape
+ FLAG_MOVING = (1 << 4), // indicates this unit is currently moving
+ FLAG_DELETE_UPON_CONSTRUCTION = (1 << 5) // this entity is deleted when construction of a building placed on top of this entity starts
};
/**