Allow building walls along the shore. Patch by sanderd17. Fix #1610.

This was SVN commit r13542.
This commit is contained in:
alpha123
2013-07-07 22:44:47 +00:00
parent d479f373aa
commit 041855e547
9 changed files with 100 additions and 16 deletions
@@ -17,6 +17,7 @@ BuildRestrictions.prototype.Schema =
"<choice>" +
"<value>land</value>" +
"<value>shore</value>" +
"<value>land-shore</value>"+
"</choice>" +
"</element>" +
"<element name='Territory' a:help='Specifies territory type restrictions for this building.'>" +
@@ -130,7 +131,13 @@ BuildRestrictions.prototype.CheckPlacement = function()
case "shore":
passClassName = "building-shore";
break;
case "land-shore":
// 'default' is everywhere a normal unit can go
// So on passable land, and not too deep in the water
passClassName = "default";
break;
case "land":
default:
passClassName = "building-land";
@@ -139,8 +146,18 @@ BuildRestrictions.prototype.CheckPlacement = function()
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
if (!cmpObstruction)
return result; // Fail
if (this.template.Category == "Wall")
{
// for walls, only test the center point
var ret = cmpObstruction.CheckFoundation(passClassName, true);
}
else
{
var ret = cmpObstruction.CheckFoundation(passClassName, false);
}
var ret = cmpObstruction.CheckFoundation(passClassName);
if (ret != "success")
{
switch (ret)
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="template_structure_defense">
<BuildRestrictions>
<PlacementType>land-shore</PlacementType>
<Category>Wall</Category>
</BuildRestrictions>
<Cost>
@@ -15,12 +15,13 @@
</Attack>
<BuildingAI>
<DefaultArrowCount>1</DefaultArrowCount>
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
</BuildingAI>
<BuildRestrictions>
<Category>Wall</Category>
</BuildRestrictions>
<Cost>
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
</BuildingAI>
<BuildRestrictions>
<PlacementType>land-shore</PlacementType>
<Category>Wall</Category>
</BuildRestrictions>
<Cost>
<BuildTime>20</BuildTime>
<Resources>
<stone>100</stone>
@@ -477,8 +477,13 @@ public:
{
return m_ControlPersist;
}
virtual EFoundationCheck CheckFoundation(std::string className)
{
return CheckFoundation(className, false);
}
virtual EFoundationCheck CheckFoundation(std::string className, bool onlyCenterPoint)
{
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
if (!cmpPosition)
@@ -510,9 +515,9 @@ public:
ICmpObstructionManager::FLAG_BLOCK_FOUNDATION);
if (m_Type == UNIT)
return cmpPathfinder->CheckUnitPlacement(filter, pos.X, pos.Y, m_Size0, passClass);
return cmpPathfinder->CheckUnitPlacement(filter, pos.X, pos.Y, m_Size0, passClass, onlyCenterPoint);
else
return cmpPathfinder->CheckBuildingPlacement(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, GetEntityId(), passClass);
return cmpPathfinder->CheckBuildingPlacement(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, GetEntityId(), passClass, onlyCenterPoint);
}
virtual bool CheckDuplicateFoundation()
@@ -544,7 +549,7 @@ public:
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);
return !cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, NULL );
}
virtual std::vector<entity_id_t> GetEntityCollisions(bool checkStructures, bool checkUnits)
@@ -658,6 +658,12 @@ void CCmpPathfinder::ProcessSameTurnMoves()
ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckUnitPlacement(const IObstructionTestFilter& filter,
entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass)
{
return CCmpPathfinder::CheckUnitPlacement(filter, x, z, r, passClass, false);
}
ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckUnitPlacement(const IObstructionTestFilter& filter,
entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint)
{
// Check unit obstruction
CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
@@ -670,6 +676,17 @@ ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckUnitPlacement(const IObst
// Test against terrain:
UpdateGrid();
if (onlyCenterPoint)
{
u16 i, j;
NearestTile(x , z, i, j);
if (IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;
return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
}
u16 i0, j0, i1, j1;
NearestTile(x - r, z - r, i0, j0);
@@ -690,6 +707,14 @@ ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckUnitPlacement(const IObst
ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const IObstructionTestFilter& filter,
entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w,
entity_pos_t h, entity_id_t id, pass_class_t passClass)
{
return CCmpPathfinder::CheckBuildingPlacement(filter, x, z, a, w, h, id, passClass, false);
}
ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const IObstructionTestFilter& filter,
entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w,
entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint)
{
// Check unit obstruction
CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
@@ -708,6 +733,17 @@ ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const I
if (!cmpObstruction || !cmpObstruction->GetObstructionSquare(square))
return ICmpObstruction::FOUNDATION_CHECK_FAIL_NO_OBSTRUCTION;
if (onlyCenterPoint)
{
u16 i, j;
NearestTile(x, z, i, j);
if (IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;
return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
}
// Expand bounds by 1/sqrt(2) tile (multiply by TERRAIN_TILE_SIZE since we want world coordinates)
entity_pos_t expand = entity_pos_t::FromInt(2).Sqrt().Multiply(entity_pos_t::FromInt(TERRAIN_TILE_SIZE / 2));
CFixedVector2D halfSize(square.hw + expand, square.hh + expand);
@@ -262,8 +262,12 @@ public:
virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass);
virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint);
virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass);
virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint);
virtual void FinishAsyncRequests();
void ProcessLongRequests(const std::vector<AsyncLongPathRequest>& longRequests);
@@ -23,9 +23,9 @@
#include "simulation2/system/SimContext.h"
std::string ICmpObstruction::CheckFoundation_wrapper(std::string className)
std::string ICmpObstruction::CheckFoundation_wrapper(std::string className, bool onlyCenterPoint)
{
EFoundationCheck check = CheckFoundation(className);
EFoundationCheck check = CheckFoundation(className, onlyCenterPoint);
switch (check)
{
@@ -47,7 +47,7 @@ std::string ICmpObstruction::CheckFoundation_wrapper(std::string className)
BEGIN_INTERFACE_WRAPPER(Obstruction)
DEFINE_INTERFACE_METHOD_0("GetUnitRadius", entity_pos_t, ICmpObstruction, GetUnitRadius)
DEFINE_INTERFACE_METHOD_1("CheckFoundation", std::string, ICmpObstruction, CheckFoundation_wrapper, std::string)
DEFINE_INTERFACE_METHOD_2("CheckFoundation", std::string, ICmpObstruction, CheckFoundation_wrapper, std::string, bool)
DEFINE_INTERFACE_METHOD_0("CheckDuplicateFoundation", bool, ICmpObstruction, CheckDuplicateFoundation)
DEFINE_INTERFACE_METHOD_2("GetEntityCollisions", std::vector<entity_id_t>, ICmpObstruction, GetEntityCollisions, bool, bool)
DEFINE_INTERFACE_METHOD_1("SetActive", void, ICmpObstruction, SetActive, bool)
@@ -59,12 +59,13 @@ public:
* value describing the type of failure.
*/
virtual EFoundationCheck CheckFoundation(std::string className) = 0;
virtual EFoundationCheck CheckFoundation(std::string className, bool onlyCenterPoint) = 0;
/**
* CheckFoundation wrapper for script calls, to return friendly strings instead of an EFoundationCheck.
* @return "success" if check passes, else a string describing the type of failure.
*/
virtual std::string CheckFoundation_wrapper(std::string className);
virtual std::string CheckFoundation_wrapper(std::string className, bool onlyCenterPoint);
/**
* Test whether this entity is colliding with any obstructions that share its
@@ -158,6 +158,15 @@ public:
*/
virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass) = 0;
/**
* Check whether a unit placed here is valid and doesn't hit any obstructions
* or impassable terrain.
* When onlyCenterPoint = true, only check the center tile of the unit
* @return ICmpObstruction::FOUNDATION_CHECK_SUCCESS if the placement is okay, else
* a value describing the type of failure.
*/
virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint) = 0;
/**
* Check whether a building placed here is valid and doesn't hit any obstructions
* or impassable terrain.
@@ -166,6 +175,16 @@ public:
*/
virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass) = 0;
/**
* Check whether a building placed here is valid and doesn't hit any obstructions
* or impassable terrain.
* when onlyCenterPoint = true, only check the center tile of the building
* @return ICmpObstruction::FOUNDATION_CHECK_SUCCESS if the placement is okay, else
* a value describing the type of failure.
*/
virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint) = 0;
/**
* Toggle the storage and rendering of debug info.
*/