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 cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var templateName = cmpTemplateManager.GetCurrentTemplateName(this.entity); 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) 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); var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
cmpUnitAI.SetFormationController(this.entity); cmpUnitAI.SetFormationController(this.entity);
cmpUnitAI.SetLastFormationTemplate(templateName); cmpUnitAI.SetLastFormationTemplate(templateName);
@ -303,6 +320,8 @@ Formation.prototype.SetMembers = function(ents)
cmpAuras.ApplyFormationBonus(ents); cmpAuras.ApplyFormationBonus(ents);
} }
} }
var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
cmpUnitMotion.SetPassabilityClassName(bestPassClass);
this.offsets = undefined; this.offsets = undefined;
// Locate this formation controller in the middle of its members // 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_WalkSpeed, m_OriginalWalkSpeed; // in metres per second
fixed m_RunSpeed, m_OriginalRunSpeed; fixed m_RunSpeed, m_OriginalRunSpeed;
ICmpPathfinder::pass_class_t m_PassClass; ICmpPathfinder::pass_class_t m_PassClass;
std::string m_PassClassName;
ICmpPathfinder::cost_class_t m_CostClass; ICmpPathfinder::cost_class_t m_CostClass;
// Dynamic state: // Dynamic state:
@ -306,7 +307,8 @@ public:
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity()); CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
if (cmpPathfinder) 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()); m_CostClass = cmpPathfinder->GetCostClass(paramNode.GetChild("CostClass").ToUTF8());
} }
@ -338,6 +340,8 @@ public:
serialize.NumberU8("state", m_State, 0, STATE_MAX-1); serialize.NumberU8("state", m_State, 0, STATE_MAX-1);
serialize.NumberU8("path state", m_PathState, 0, PATHSTATE_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("ticket", m_ExpectedPathTicket);
serialize.NumberU32_Unbounded("target entity", m_TargetEntity); serialize.NumberU32_Unbounded("target entity", m_TargetEntity);
@ -369,6 +373,10 @@ public:
Init(paramNode); Init(paramNode);
SerializeCommon(deserialize); SerializeCommon(deserialize);
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
if (cmpPathfinder)
m_PassClass = cmpPathfinder->GetPassabilityClass(m_PassClassName);
} }
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
@ -448,6 +456,19 @@ public:
return m_PassClass; 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() virtual fixed GetCurrentSpeed()
{ {
return m_CurSpeed; 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("IsMoving", bool, ICmpUnitMotion, IsMoving)
DEFINE_INTERFACE_METHOD_0("GetWalkSpeed", fixed, ICmpUnitMotion, GetWalkSpeed) DEFINE_INTERFACE_METHOD_0("GetWalkSpeed", fixed, ICmpUnitMotion, GetWalkSpeed)
DEFINE_INTERFACE_METHOD_0("GetRunSpeed", fixed, ICmpUnitMotion, GetRunSpeed) 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("SetFacePointAfterMove", void, ICmpUnitMotion, SetFacePointAfterMove, bool)
DEFINE_INTERFACE_METHOD_1("SetUnitRadius", void, ICmpUnitMotion, SetUnitRadius, fixed) DEFINE_INTERFACE_METHOD_1("SetUnitRadius", void, ICmpUnitMotion, SetUnitRadius, fixed)
DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitMotion, SetDebugOverlay, bool) DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitMotion, SetDebugOverlay, bool)
@ -115,6 +117,16 @@ public:
return m_Script.Call<ICmpPathfinder::pass_class_t>("GetPassabilityClass"); 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) virtual void SetUnitRadius(fixed radius)
{ {
m_Script.CallVoid("SetUnitRadius", radius); m_Script.CallVoid("SetUnitRadius", radius);

View File

@ -119,6 +119,16 @@ public:
*/ */
virtual ICmpPathfinder::pass_class_t GetPassabilityClass() = 0; 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. * 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 * Bad things may happen if this entity has an active Obstruction component with a larger