1
0
forked from 0ad/0ad

Improve navigation for ship formations by setting the formation controller to the right passability class

This was SVN commit r15149.
This commit is contained in:
sanderd17 2014-05-18 07:59:43 +00:00
parent 96c806841d
commit 86196212e2
4 changed files with 63 additions and 1 deletions

View File

@ -289,9 +289,26 @@ Formation.prototype.SetMembers = function(ents)
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var templateName = cmpTemplateManager.GetCurrentTemplateName(this.entity);
// keep the number of entities per pass class to find the most used
// For land units, this will be "default", for ship units, it should be "ship"
var passClasses = {};
var bestPassClassNumber = 0;
var bestPassClass = "default";
for each (var ent in this.members)
{
var cmpUnitMotion = Engine.QueryInterface(ent,IID_UnitMotion);
var passClass = cmpUnitMotion.GetPassabilityClassName();
if (passClasses[passClass])
var number = passClasses[passClass]++;
else
var number = passClasses[passClass] = 1;
if (number > bestPassClassNumber)
{
bestPassClass = passClass;
bestPassClassNumber = number;
}
var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
cmpUnitAI.SetFormationController(this.entity);
cmpUnitAI.SetLastFormationTemplate(templateName);
@ -303,6 +320,8 @@ Formation.prototype.SetMembers = function(ents)
cmpAuras.ApplyFormationBonus(ents);
}
}
var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
cmpUnitMotion.SetPassabilityClassName(bestPassClass);
this.offsets = undefined;
// Locate this formation controller in the middle of its members

View File

@ -133,6 +133,7 @@ public:
fixed m_WalkSpeed, m_OriginalWalkSpeed; // in metres per second
fixed m_RunSpeed, m_OriginalRunSpeed;
ICmpPathfinder::pass_class_t m_PassClass;
std::string m_PassClassName;
ICmpPathfinder::cost_class_t m_CostClass;
// Dynamic state:
@ -306,7 +307,8 @@ public:
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
if (cmpPathfinder)
{
m_PassClass = cmpPathfinder->GetPassabilityClass(paramNode.GetChild("PassabilityClass").ToUTF8());
m_PassClassName = paramNode.GetChild("PassabilityClass").ToUTF8();
m_PassClass = cmpPathfinder->GetPassabilityClass(m_PassClassName);
m_CostClass = cmpPathfinder->GetCostClass(paramNode.GetChild("CostClass").ToUTF8());
}
@ -338,6 +340,8 @@ public:
serialize.NumberU8("state", m_State, 0, STATE_MAX-1);
serialize.NumberU8("path state", m_PathState, 0, PATHSTATE_MAX-1);
serialize.StringASCII("pass class", m_PassClassName, 0, 64);
serialize.NumberU32_Unbounded("ticket", m_ExpectedPathTicket);
serialize.NumberU32_Unbounded("target entity", m_TargetEntity);
@ -369,6 +373,10 @@ public:
Init(paramNode);
SerializeCommon(deserialize);
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
if (cmpPathfinder)
m_PassClass = cmpPathfinder->GetPassabilityClass(m_PassClassName);
}
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
@ -448,6 +456,19 @@ public:
return m_PassClass;
}
virtual std::string GetPassabilityClassName()
{
return m_PassClassName;
}
virtual void SetPassabilityClassName(std::string passClassName)
{
m_PassClassName = passClassName;
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
if (cmpPathfinder)
m_PassClass = cmpPathfinder->GetPassabilityClass(passClassName);
}
virtual fixed GetCurrentSpeed()
{
return m_CurSpeed;

View File

@ -35,6 +35,8 @@ DEFINE_INTERFACE_METHOD_1("SetSpeed", void, ICmpUnitMotion, SetSpeed, fixed)
DEFINE_INTERFACE_METHOD_0("IsMoving", bool, ICmpUnitMotion, IsMoving)
DEFINE_INTERFACE_METHOD_0("GetWalkSpeed", fixed, ICmpUnitMotion, GetWalkSpeed)
DEFINE_INTERFACE_METHOD_0("GetRunSpeed", fixed, ICmpUnitMotion, GetRunSpeed)
DEFINE_INTERFACE_METHOD_0("GetPassabilityClassName", std::string, ICmpUnitMotion, GetPassabilityClassName)
DEFINE_INTERFACE_METHOD_1("SetPassabilityClassName", void, ICmpUnitMotion, SetPassabilityClassName, std::string)
DEFINE_INTERFACE_METHOD_1("SetFacePointAfterMove", void, ICmpUnitMotion, SetFacePointAfterMove, bool)
DEFINE_INTERFACE_METHOD_1("SetUnitRadius", void, ICmpUnitMotion, SetUnitRadius, fixed)
DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitMotion, SetDebugOverlay, bool)
@ -115,6 +117,16 @@ public:
return m_Script.Call<ICmpPathfinder::pass_class_t>("GetPassabilityClass");
}
virtual std::string GetPassabilityClassName()
{
return m_Script.Call<std::string>("GetPassabilityClassName");
}
virtual void SetPassabilityClassName(std::string passClassName)
{
m_Script.CallVoid("SetPassabilityClassName", passClassName);
}
virtual void SetUnitRadius(fixed radius)
{
m_Script.CallVoid("SetUnitRadius", radius);

View File

@ -119,6 +119,16 @@ public:
*/
virtual ICmpPathfinder::pass_class_t GetPassabilityClass() = 0;
/**
* Get the passability class name (as defined in pathfinder.xml)
*/
virtual std::string GetPassabilityClassName() = 0;
/**
* Set the passability class
*/
virtual void SetPassabilityClassName(std::string passClassName) = 0;
/**
* Override the default obstruction radius, used for planning paths and checking for collisions.
* Bad things may happen if this entity has an active Obstruction component with a larger