mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Add formations paths to UnitMotionDebugOverlay
Formation controllers now display their movement paths when enabling UnitMotion debug overlay. Key changes: - Formation controllers show long paths in blue and short paths in green - Formation controllers path are rendered if selecting some of the formation's members - Prevent the gui from making redundant calls to SetMotionDebugOverlay Existing limitations (not regressions): - Paths are often cleared before entities complete them - Formation members have short paths that rarely get rendered
This commit is contained in:
parent
2e450f0f52
commit
f856565de9
4 changed files with 54 additions and 27 deletions
|
|
@ -24,10 +24,28 @@ function _setStatusBars(ents, enabled)
|
|||
});
|
||||
}
|
||||
|
||||
function _setMotionOverlay(ents, enabled)
|
||||
function _setMotionOverlay(ents, enabled, motionDebugOverlay, force = false)
|
||||
{
|
||||
if (ents.length)
|
||||
Engine.GuiInterfaceCall("SetMotionDebugOverlay", { "entities": ents, "enabled": enabled });
|
||||
if (!force && !motionDebugOverlay)
|
||||
return;
|
||||
|
||||
// Get entities plus their formation controllers (if any)
|
||||
const resultSet = new Set();
|
||||
for (const ent of ents)
|
||||
{
|
||||
resultSet.add(ent);
|
||||
const entState = GetEntityState(ent);
|
||||
if (entState?.unitAI?.formation)
|
||||
{
|
||||
resultSet.add(entState.unitAI.formation);
|
||||
}
|
||||
}
|
||||
|
||||
if (resultSet.size)
|
||||
Engine.GuiInterfaceCall("SetMotionDebugOverlay", {
|
||||
"entities": resultSet,
|
||||
"enabled": enabled
|
||||
});
|
||||
}
|
||||
|
||||
function _playSound(ent)
|
||||
|
|
@ -255,7 +273,7 @@ EntitySelection.prototype.update = function()
|
|||
// Disable any highlighting of the disappeared unit
|
||||
_setHighlight([ent], 0, false);
|
||||
_setStatusBars([ent], false);
|
||||
_setMotionOverlay([ent], false);
|
||||
_setMotionOverlay([ent], false, this.motionDebugOverlay);
|
||||
|
||||
this.selected.delete(ent);
|
||||
this.groups.removeEnt(ent);
|
||||
|
|
@ -263,6 +281,10 @@ EntitySelection.prototype.update = function()
|
|||
continue;
|
||||
}
|
||||
}
|
||||
// Refresh the motion overlay
|
||||
if (this.motionDebugOverlay)
|
||||
_setMotionOverlay([...this.selected], true, this.motionDebugOverlay);
|
||||
|
||||
if (changed)
|
||||
this.onChange();
|
||||
};
|
||||
|
|
@ -327,7 +349,7 @@ EntitySelection.prototype.addList = function(ents, quiet, force = false, addForm
|
|||
|
||||
_setHighlight(added, 1, true);
|
||||
_setStatusBars(added, true);
|
||||
_setMotionOverlay(added, this.motionDebugOverlay);
|
||||
_setMotionOverlay(added, this.motionDebugOverlay, this.motionDebugOverlay);
|
||||
if (added.length)
|
||||
{
|
||||
// Play the sound if the entity is controllable by us or Gaia-owned.
|
||||
|
|
@ -358,7 +380,7 @@ EntitySelection.prototype.removeList = function(ents, addFormationMembers = true
|
|||
|
||||
_setHighlight(removed, 0, false);
|
||||
_setStatusBars(removed, false);
|
||||
_setMotionOverlay(removed, false);
|
||||
_setMotionOverlay(removed, false, this.motionDebugOverlay);
|
||||
|
||||
this.onChange();
|
||||
};
|
||||
|
|
@ -367,7 +389,7 @@ EntitySelection.prototype.reset = function()
|
|||
{
|
||||
_setHighlight(this.toList(), 0, false);
|
||||
_setStatusBars(this.toList(), false);
|
||||
_setMotionOverlay(this.toList(), false);
|
||||
_setMotionOverlay(this.toList(), false, this.motionDebugOverlay);
|
||||
this.selected.clear();
|
||||
this.groups.reset();
|
||||
this.onChange();
|
||||
|
|
@ -460,7 +482,7 @@ EntitySelection.prototype.setHighlightList = function(entities)
|
|||
EntitySelection.prototype.SetMotionDebugOverlay = function(enabled)
|
||||
{
|
||||
this.motionDebugOverlay = enabled;
|
||||
_setMotionOverlay(this.toList(), enabled);
|
||||
_setMotionOverlay(this.toList(), enabled, this.motionDebugOverlay, true);
|
||||
};
|
||||
|
||||
EntitySelection.prototype.onChange = function()
|
||||
|
|
|
|||
|
|
@ -1986,12 +1986,9 @@ GuiInterface.prototype.SetObstructionDebugOverlay = function(player, enabled)
|
|||
|
||||
GuiInterface.prototype.SetMotionDebugOverlay = function(player, data)
|
||||
{
|
||||
for (const ent of data.entities)
|
||||
{
|
||||
const cmpUnitMotion = Engine.QueryInterface(ent, IID_UnitMotion);
|
||||
if (cmpUnitMotion)
|
||||
cmpUnitMotion.SetDebugOverlay(data.enabled);
|
||||
}
|
||||
data.entities.forEach(ent => {
|
||||
Engine.QueryInterface(ent, IID_UnitMotion)?.SetDebugOverlay(data.enabled);
|
||||
});
|
||||
};
|
||||
|
||||
GuiInterface.prototype.SetRangeDebugOverlay = function(player, enabled)
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ extern void ColorActivateFastImpl();
|
|||
|
||||
struct CColor
|
||||
{
|
||||
CColor() : r(-1.f), g(-1.f), b(-1.f), a(1.f) {}
|
||||
CColor(float cr, float cg, float cb, float ca) : r(cr), g(cg), b(cb), a(ca) {}
|
||||
constexpr CColor() : r(-1.f), g(-1.f), b(-1.f), a(1.f) {}
|
||||
constexpr CColor(float cr, float cg, float cb, float ca) : r(cr), g(cg), b(cb), a(ca) {}
|
||||
|
||||
/**
|
||||
* Returns whether this has been set to a valid color.
|
||||
|
|
|
|||
|
|
@ -138,8 +138,14 @@ constexpr u8 BACKUP_HACK_DELAY = 10;
|
|||
*/
|
||||
constexpr u8 VERY_OBSTRUCTED_THRESHOLD = 10;
|
||||
|
||||
const CColor OVERLAY_COLOR_LONG_PATH(1, 1, 1, 1);
|
||||
const CColor OVERLAY_COLOR_SHORT_PATH(1, 0, 0, 1);
|
||||
struct PathColorPalette
|
||||
{
|
||||
CColor longPath;
|
||||
CColor shortPath;
|
||||
};
|
||||
|
||||
constexpr PathColorPalette REGULAR_UNIT_PALETTE{{1, 1, 1, 1}, {1, 0, 0, 1}};
|
||||
constexpr PathColorPalette FORMATION_CONTROLLER_PALETTE{{0, 0, 1, 1}, {0, 1, 0, 1}};
|
||||
} // anonymous namespace
|
||||
|
||||
class CCmpUnitMotion final : public ICmpUnitMotion
|
||||
|
|
@ -1902,7 +1908,6 @@ bool CCmpUnitMotion::IsTargetRangeReachable(entity_id_t target, entity_pos_t min
|
|||
return cmpPathfinder->IsGoalReachable(pos.X, pos.Y, goal, m_PassClass);
|
||||
}
|
||||
|
||||
|
||||
void CCmpUnitMotion::RenderPath(const WaypointPath& path, std::vector<SOverlayLine>& lines, CColor color)
|
||||
{
|
||||
bool floating = false;
|
||||
|
|
@ -1934,17 +1939,20 @@ void CCmpUnitMotion::RenderPath(const WaypointPath& path, std::vector<SOverlayLi
|
|||
|
||||
void CCmpUnitMotion::RenderSubmit(SceneCollector& collector)
|
||||
{
|
||||
if (!m_DebugOverlayEnabled)
|
||||
return;
|
||||
if (!m_DebugOverlayEnabled)
|
||||
return;
|
||||
|
||||
RenderPath(m_LongPath, m_DebugOverlayLongPathLines, OVERLAY_COLOR_LONG_PATH);
|
||||
RenderPath(m_ShortPath, m_DebugOverlayShortPathLines, OVERLAY_COLOR_SHORT_PATH);
|
||||
const auto& palette{m_IsFormationController ?
|
||||
FORMATION_CONTROLLER_PALETTE : REGULAR_UNIT_PALETTE};
|
||||
|
||||
for (size_t i = 0; i < m_DebugOverlayLongPathLines.size(); ++i)
|
||||
collector.Submit(&m_DebugOverlayLongPathLines[i]);
|
||||
RenderPath(m_LongPath, m_DebugOverlayLongPathLines, palette.longPath);
|
||||
RenderPath(m_ShortPath, m_DebugOverlayShortPathLines, palette.shortPath);
|
||||
|
||||
for (size_t i = 0; i < m_DebugOverlayShortPathLines.size(); ++i)
|
||||
collector.Submit(&m_DebugOverlayShortPathLines[i]);
|
||||
for (SOverlayLine& line : m_DebugOverlayLongPathLines)
|
||||
collector.Submit(&line);
|
||||
|
||||
for (SOverlayLine& line : m_DebugOverlayShortPathLines)
|
||||
collector.Submit(&line);
|
||||
}
|
||||
|
||||
#endif // INCLUDED_CCMPUNITMOTION
|
||||
|
|
|
|||
Loading…
Reference in a new issue