Index: binaries/data/mods/public/gui/manual/intro.txt
===================================================================
--- binaries/data/mods/public/gui/manual/intro.txt (revision 194114)
+++ binaries/data/mods/public/gui/manual/intro.txt (working copy)
@@ -106,6 +106,7 @@
Alt + W: Toggle wireframe mode (press once to get wireframes overlaid over the textured models, twice to get just the wireframes colored by the textures, thrice to get back to normal textured mode)
Alt + S: Toggle unit silhouettes (might give a small performance boost)
Alt + Z: Toggle sky
+Alt + V: Toggle aura range visualizations
[font="sans-bold-14"]Camera manipulation
[font="sans-14"]W or \[up]: Pan screen up
Index: binaries/data/mods/public/gui/session/inputsession.js
===================================================================
--- binaries/data/mods/public/gui/session/inputsession.js (revision 194114)
+++ binaries/data/mods/public/gui/session/inputsession.js (working copy)
@@ -839323,6 +839,15 @@323,10 @@
g_ShowGuarded = (ev.type == "hotkeydown"); onSimulationUpdate();
updateAdditionalHighlight();setTimeout(displayGamestateNotifications, 1000);
+ Engine.GuiInterfaceCall("SetVisualRangeOverlayTypes", {
+ "Aura": Engine.ConfigDB_GetValue("user", "renderer.aurarange") == "true"
+ });
+
// Report the performance after 5 seconds (when we're still near
// the initial camera view) and a minute (when the profiler will
// have settled down if framerates as very low), to give some
@@ -1232,6 +1236,26 @@
});
}
+ else if (ev.hotkey == "session.toggleaura
+/**
+ * Toggles the display of range overlays" && ev.type == "hotkeydown") for a player's entities.
+ {+ */
+function recalculateRangeOverlays(remove = false)
+{
+ let selected = g_Selection.toList();
+ + for (let enabled = Engine.ConfigDB_GetValue("user", "renderer.aurarange");t in g_Selection.highlighted)
+ selected.push(g_Selection.highlighted[ent]);
+
+ Engine.Renderer_SetAuraRangeEnabled(enabled != "true");+ let entities = Engine.GuiInterfaceCall(
+ enabled = String(enabled != "true");+ g_ViewedPlayer == -1 ? "GetNonGaiaEntities" : "GetPlayerEntities", {
+ Engine.ConfigDB_CreateValue("user", "renderer.aurarange", enabled);+ "viewedPlayer": g_ViewedPlayer
+ Engine.ConfigDB_WriteValueToFile("user", "renderer.aurarange", enabled, "config/user.cfg");+ }).filter(idx => selected.indexOf(idx) == -1);
+ }
+ Engine.GuiInterfaceCall("SetRangeOverlays", {
+ "entities": entities,
+ "enabled": remove
+ });
+}
+
// Update the additional list of entities to be highlighted.
function updateAdditionalHighlight()
{
Index: binaries/data/mods/public/gui/session/input.js
===================================================================
--- binaries/data/mods/public/gui/session/input.js (revision 19414)
+++ binaries/data/mods/public/gui/session/input.js (working copy)
@@ -1841,3 +1841,17 @@
// State-machine processing:preSelectedAction = ACTION_NONE;
}
+function toggleRangeOverlay(type)
+{
+ let configString = "renderer." + type + "range";
+ let enabled = Engine.ConfigDB_GetValue("user", configString);
+
+ Engine.GuiInterfaceCall("EnableVisualRangeOverlayType", {
+ "type": type.charAt(0).toUpperCase() + type.slice(1), "enabled": enabled != "true"
+ });
+
+ enabled = String(enabled != "true");
+ Engine.ConfigDB_CreateValue("user", configString, enabled);
+ Engine.ConfigDB_WriteValueToFile("user", configString, enabled, "config/user.cfg");
+ recalculateRangeOverlays();
+}
Index: binaries/data/mods/public/simulation/components/RangeVisualization.js
===================================================================
--- binaries/data/mods/public/simulation/components/RangeVisualization.js (revision 0)
+++ binaries/data/mods/public/simulation/components/RangeVisualization.js (working copy)
@@ -0,0 +1,74 @@76 @@
+function RangeVisualization() {}
+
+RangeVisualization.prototype.Schema = "<empty/>";
+
+// TODO: Implement other range visualizations
+RangeVisualization.prototype.VisualizationTypes = [ "Aura" ];
+
+RangeVisualization.prototype.Init = function()
+{
+ this.enabled = false;
+ // Keep track of the config options that toggle different visualization types
+ this.enabledRangeTypes = {};
+
+ this.rangeVisualizations = new Map();
+ for (let type of this.VisualizationTypes)
+ this["GetVisual" + type + "Ranges"](type);
+};
+
+RangeVisualization.prototype.Serialize = null;
+
+RangeVisualization.prototype.Deserialize = function(data)
+{
+ this.Init();
+};
+
+RangeVisualization.prototype.GetVisualAuraRanges = function(type)
+{
+ let cmpAuras = Engine.QueryInterface(this.entity, IID_Auras);
+ if (!cmpAuras)
+ return;
+
+ this.rangeVisualizations.set(type, []);
+
+ for (let auraName of cmpAuras.GetVisualAuraRangeNames())
+ this.rangeVisualizations.get(type).push({
+ "radius": cmpAuras.GetRange(auraName),
+ "texture": cmpAuras.GetLineTexture(auraName),
+ "textureMask": cmpAuras.GetLineTextureMask(auraName),
+ "thickness": cmpAuras.GetLineThickness(auraName),
+ });
+};
+
+RangeVisualization.prototype.SetEnabled = function(enabled, enabledRangeTypes)
+{
+ if (enabled == this.enabled)
+ return;
+
+ this.enabled = enabled;
+ this.enabledRangeTypes = enabledRangeTypes;
+
+ this.RegenerateRangeVisualizations();
+};
+
+RangeVisualization.prototype.RegenerateRangeVisualizations = function()
+{
+ let cmpSelectable = Engine.QueryInterface(this.entity, IID_Selectable);
+ if (!cmpSelectable)
+ return;
+
+ cmpSelectable.ResetRangeOverlays();
+
+ if (!this.enabled)
+ return;
+
+ // Only render individual range types that have been enabled
+ for (let rangeOverlayType of this.rangeVisualizations.keys())
+ for (let rangeOverlay of + if (this.rangeVisualizations.get(enabledRangeTypes[rangeOverlayType)])
+ cmpSelectable.SetRfor (let rangeOverlay( of this.rangeOverlay.radius, Visualizations.get(rangeOverlay.texture,Type))
+ cmpSelectable.SetRangeOverlay(rangeOverlay.radius, rangeOverlay.texture,
+ rangeOverlay.textureMask, rangeOverlay.thickness);
+};
+
+RangeVisualization.prototype.OnOwnershipChanged = function(msg)
+{
+ if (this.enabled && msg.to != -1)
+ this.RegenerateRangeVisualizations();
+};
+
+Engine.RegisterComponentType(IID_RangeVisualization, "RangeVisualization", RangeVisualization);
Index: binaries/data/mods/public/gui/session/hotkeys/misc.xml
===================================================================
--- binaries/data/mods/public/gui/session/hotkeys/misc.xml (revision 19414)
+++ binaries/data/mods/public/gui/session/hotkeys/misc.xml (working copy)
@@ -96,4 +96,8 @@
<action on="Press">clearSelection();</action>
</object>
+ <object hotkey="session.toggleauraoverlays">
+ <action on="Press">toggleRangeOverlay("aura");</action>
+ </object>
+
</object>
Index: binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/GuiInterface.js (revision 194114)
+++ binaries/data/mods/public/simulation/components/GuiInterface.js (working copy)
@@ -33,6 +33,7 @@
this.timeNotifications = [];
this.entsRallyPointsDisplayed = [];
this.entsWithAuraAndStatusBars = new Set();
+ this.enabledVisualRangeOverlayTypes = {};
};
/*
@@ -894,69 +894,12 @@5,25 @@
}
cmpSelectable.SetSelectionHighlight({ "r": color.r, "g": color.g, "b": color.b, "a": cmd.alpha }, cmd.selected);
+
+ let cmpRangeVisualization = Engine.QueryInterface(ent, IID_RangeVisualization);
+ if (!cmpRangeVisualization || player != owner && player != -1)
+ continue;
+
+ cmpRangeVisualization.SetEnabled(cmd.selected);, this.enabledVisualRangeOverlayTypes);
}
};
+GuiInterface.prototype.SetVisualRangeOverlayTypes = function(player, overlayTypes)
+{
+ this.enabledVisualRangeOverlayTypes = overlayTypes;
+};
+
+GuiInterface.prototype.EnableVisualRangeOverlayType = function(player, data)
+{
+ this.enabledVisualRangeOverlayTypes[data.type] = data.enabled;
+};
+
GuiInterface.prototype.GetEntitiesWithStatusBars = function()
{
return [...this.entsWithAuraAndStatusBars];
@@ -937,6 +954,17 @@
}
};
+GuiInterface.prototype.SetRangeOverlays = function(player, cmd)
+{
+ for (let ent of cmd.entities)
+ {
+ let cmpRangeVisualization = Engine.QueryInterface(ent, IID_RangeVisualization);
+ if (!cmpRangeVisualization)
+ continue;
+ cmpRangeVisualization.SetEnabled(cmd.enabled, this.enabledVisualRangeOverlayTypes);
+ }
+};
+
GuiInterface.prototype.GetPlayerEntities = function(player)
{
return Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetEntitiesByPlayer(player);
@@ -2016,6 +2044,9 @@
"SetObstructionDebugOverlay": 1,
"SetMotionDebugOverlay": 1,
"SetRangeDebugOverlay": 1,
+ "EnableVisualRangeOverlayType": 1,
+ "SetVisualRangeOverlayTypes": 1,
+ "SetRangeOverlays": 1,
"GetTraderNumber": 1,
"GetTradingGoods": 1,
Index: binaries/data/mods/public/simulation/components/interfaces/RangeVisualization.js
===================================================================
--- binaries/data/mods/public/simulation/components/interfaces/RangeVisualization.js (revision 0)
+++ binaries/data/mods/public/simulation/components/interfaces/RangeVisualization.js (working copy)
@@ -0,0 +1 @@
+Engine.RegisterInterface("RangeVisualization");
Index: binaries/data/mods/public/simulation/templates/template_structure.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure.xml (revision 194114)
+++ binaries/data/mods/public/simulation/templates/template_structure.xml (working copy)
@@ -101,6 +101,7 @@
<LineEndCap>round</LineEndCap>
<LinePassabilityClass>default</LinePassabilityClass>
</RallyPointRenderer>
+ <RangeVisualization/>
<Repairable>
<RepairTimeRatio>2.0</RepairTimeRatio>
</Repairable>
Index: binaries/data/mods/public/simulation/templates/template_unit.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit.xml (revision 194114)
+++ binaries/data/mods/public/simulation/templates/template_unit.xml (working copy)
@@ -65,6 +65,7 @@
<DisableBlockPathfinding>false</DisableBlockPathfinding>
</Obstruction>
<OverlayRenderer/>
+ <RangeVisualization/>
<ResourceGatherer>
<MaxDistance>2.0</MaxDistance>
<BaseSpeed>1.0</BaseSpeed>
Index: binaries/data/config/default.cfg
===================================================================
--- binaries/data/config/default.cfg (revision 194114)
+++ binaries/data/config/default.cfg (working copy)
@@ -75,6 +75,9 @@
silhouettes = true
showsky = true
+[renderer]
+aurarange = true
+
nos3tc = false
noautomipmap = true
novbo = false
@@ -161,6 +164,7 @@
session.showstatusbars = Tab ; Toggle display of status bars
session.highlightguarding = PgDn ; Toggle highlight of guarding units
session.highlightguarded = PgUp ; Toggle highlight of guarded units
+session.toggleauraoverlays = "Alt+V" ; Toggle rendering of aura range overlays
; > HOTKEYS ONLY
chat = Return ; Toggle chat window
Index: binaries/data/mods/public/gui/options/options.json
===================================================================
--- binaries/data/mods/public/gui/options/options.json (revision 194114)
+++ binaries/data/mods/public/gui/options/options.json (working copy)
@@ -209,6 +209,12 @@
"label": "Limit FPS in Menus",
"tooltip": "Limit FPS to 50 in all menus, to save power.",
"parameters": { "config": "gui.menu.limitfps" }
+ },
+ {
+ "type": "boolean",
+ "label": "Aura Range Visualization",
+ "tooltip": "Display the range of auras (can also be toggled in-game with the hotkey).",
+ "parameters": { "config": "renderer.aurarange", "renderer": "AuraRange" }
}
],
"soundSetting":
Index: source/ps/GameSetup/Config.cpp
===================================================================
--- source/ps/GameSetup/Config.cpp (revision 19411)
+++ source/ps/GameSetup/Config.cpp (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -49,6 +49,8 @@
bool g_WaterReflection = false;
bool g_WaterShadows = false;
+bool g_AuraRange = false;
+
bool g_Particles = false;
bool g_Silhouettes = false;
bool g_ShowSky = false;
@@ -103,6 +105,8 @@
CFG_GET_VAL("waterreflection", g_WaterReflection);
CFG_GET_VAL("watershadows", g_WaterShadows);
+ CFG_GET_VAL("renderer.aurarange", g_AuraRange);
+
CFG_GET_VAL("renderpath", g_RenderPath);
CFG_GET_VAL("particles", g_Particles);
CFG_GET_VAL("silhouettes", g_Silhouettes);
Index: source/ps/GameSetup/Config.h
===================================================================
--- source/ps/GameSetup/Config.h (revision 19411)
+++ source/ps/GameSetup/Config.h (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -62,6 +62,8 @@
extern bool g_WaterReflection;
// Enable on-water shadows.
extern bool g_WaterShadows;
+// Render aura ranges.
+extern bool g_AuraRange;
// flag to switch on shadow PCF
extern bool g_ShadowPCF;
Index: source/ps/GameSetup/GameSetup.cpp
===================================================================
--- source/ps/GameSetup/GameSetup.cpp (revision 19411)
+++ source/ps/GameSetup/GameSetup.cpp (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -625,6 +625,8 @@
g_ConfigDB.SetValueBool(CFG_SYSTEM, "waterrefraction", g_WaterRefraction);
g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWSONWATER, g_WaterShadows);
g_ConfigDB.SetValueBool(CFG_SYSTEM, "watershadows", g_WaterShadows);
+ g_Renderer.SetOptionBool(CRenderer::OPT_AURARANGE, g_AuraRange);
+ g_ConfigDB.SetValueBool(CFG_SYSTEM, "renderer.aurarange", g_AuraRange);
g_Renderer.SetRenderPath(CRenderer::GetRenderPathByName(g_RenderPath));
g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWPCF, g_ShadowPCF);
Index: source/renderer/Renderer.cpp
===================================================================
--- source/renderer/Renderer.cpp (revision 19411)
+++ source/renderer/Renderer.cpp (working copy)
@@ -730,6 +730,9 @@
case OPT_DISPLAYFRUSTUM:
m_Options.m_DisplayFrustum = value;
break;
+ case OPT_AURARANGE:
+ m_Options.m_AuraRange = value;
+ break;
default:
debug_warn(L"CRenderer::SetOptionBool: unknown option");
break;
@@ -773,6 +776,8 @@
return m_Options.m_Postproc;
case OPT_DISPLAYFRUSTUM:
return m_Options.m_DisplayFrustum;
+ case OPT_AURARANGE:
+ return m_Options.m_AuraRange;
default:
debug_warn(L"CRenderer::GetOptionBool: unknown option");
break;
Index: source/renderer/Renderer.h
===================================================================
--- source/renderer/Renderer.h (revision 19411)
+++ source/renderer/Renderer.h (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -89,6 +89,7 @@
OPT_SMOOTHLOS,
OPT_POSTPROC,
OPT_DISPLAYFRUSTUM,
+ OPT_AURARANGE
};
enum CullGroup {
@@ -158,6 +159,7 @@
bool m_ShowSky;
bool m_Postproc;
bool m_DisplayFrustum;
+ bool m_AuraRange;
} m_Options;
struct Caps {
Index: source/renderer/scripting/JSInterface_Renderer.cpp
===================================================================
--- source/renderer/scripting/JSInterface_Renderer.cpp (revision 19411)
+++ source/renderer/scripting/JSInterface_Renderer.cpp (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -47,6 +47,7 @@
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(SMOOTHLOS, SmoothLOS);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(POSTPROC, Postproc);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(DISPLAYFRUSTUM, DisplayFrustum);
+IMPLEMENT_BOOLEAN_SCRIPT_SETTING(AURARANGE, AuraRange);
#undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING
@@ -84,6 +85,7 @@
REGISTER_BOOLEAN_SCRIPT_SETTING(SmoothLOS);
REGISTER_BOOLEAN_SCRIPT_SETTING(Postproc);
REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayFrustum);
+ REGISTER_BOOLEAN_SCRIPT_SETTING(AuraRange);
}
#undef REGISTER_BOOLEAN_SCRIPT_SETTING
Index: source/renderer/scripting/JSInterface_Renderer.h
===================================================================
--- source/renderer/scripting/JSInterface_Renderer.h (revision 19411)
+++ source/renderer/scripting/JSInterface_Renderer.h (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -45,6 +45,7 @@
DECLARE_BOOLEAN_SCRIPT_SETTING(SmoothLOS);
DECLARE_BOOLEAN_SCRIPT_SETTING(Postproc);
DECLARE_BOOLEAN_SCRIPT_SETTING(DisplayFrustum);
+ DECLARE_BOOLEAN_SCRIPT_SETTING(AuraRange);
void RegisterScriptFunctions(ScriptInterface& scriptInterface);
}
Index: source/simulation2/components/CCmpSelectable.cpp
===================================================================
--- source/simulation2/components/CCmpSelectable.cpp (revision 194114)
+++ source/simulation2/components/CCmpSelectable.cpp (working copy)
@@ -27,6 +27,7 @@
#include "maths/Matrix3D.h"
#include "maths/Vector3D.h"
#include "maths/Vector2D.h"
+#include "ps/ConfigDB.h"
#include "ps/Profile.h"
#include "renderer/Scene.h"
#include "renderer/Renderer.h"
@@ -58,6 +59,7 @@
componentManager.SubscribeToMessageType(MT_PositionChanged);
componentManager.SubscribeToMessageType(MT_TerrainChanged);
componentManager.SubscribeToMessageType(MT_WaterChanged);
+ componentManager.SubscribeToMessageType(MT_Update);
}
DEFAULT_COMPONENT_ALLOCATOR(Selectable)
@@ -66,7 +686,7 @@
: m_DebugBoundingBoxOverlay(NULL), m_DebugSelectionBoxOverlay(NULL),
m_BuildingOverlay(NULL), m_UnitOverlay(NULL),
m_FadeBaselineAlpha(0.f), m_FadeDeltaAlpha(0.f), m_FadeProgress(0.f),
- m_Selected(false), m_Cached(false), m_Visible(false)
+ m_Selected(false), m_Cached(false), m_Visible(false), m_RangeOverlayData()
{
m_Color = CColor(0, 0, 0, m_FadeBaselineAlpha);
}
@@ -77,6 +797,8 @@
delete m_DebugSelectionBoxOverlay;
delete m_BuildingOverlay;
delete m_UnitOverlay;
+ for (RangeOverlayData& rangeOverlay : m_RangeOverlayData)
+ delete rangeOverlay.second;
}
static std::string GetSchema()
@@ -126,23 +13028,21 @@
const CParamNode& textureNode = paramNode.GetChild("Overlay").GetChild("Texture");
const CParamNode& outlineNode = paramNode.GetChild("Overlay").GetChild("Outline");
- const char* textureBasePath = "art/textures/selection/";
-
// Save some memory by using interned file paths in these descriptors (almost all actors and
// entities have this component, and many use the same textures).
if (textureNode.IsOk())
{
// textured quad mode (dynamic, for units)
m_OverlayDescriptor.m_Type = ICmpSelectable::DYNAMIC_QUAD;
- m_OverlayDescriptor.m_QuadTexture = CStrIntern(textureBasePath + textureNode.GetChild("MainTexture").ToUTF8());
- m_OverlayDescriptor.m_QuadTextureMask = CStrIntern(textureBasePath + textureNode.GetChild("MainTextureMask").ToUTF8());
+ m_OverlayDescriptor.m_QuadTexture = CStrIntern(TEXTUREBASEPATH + textureNode.GetChild("MainTexture").ToUTF8());
+ m_OverlayDescriptor.m_QuadTextureMask = CStrIntern(TEXTUREBASEPATH + textureNode.GetChild("MainTextureMask").ToUTF8());
}
else if (outlineNode.IsOk())
{
// textured outline mode (static, for buildings)
m_OverlayDescriptor.m_Type = ICmpSelectable::STATIC_OUTLINE;
- m_OverlayDescriptor.m_LineTexture = CStrIntern(textureBasePath + outlineNode.GetChild("LineTexture").ToUTF8());
- m_OverlayDescriptor.m_LineTextureMask = CStrIntern(textureBasePath + outlineNode.GetChild("LineTextureMask").ToUTF8());
+ m_OverlayDescriptor.m_LineTexture = CStrIntern(TEXTUREBASEPATH + outlineNode.GetChild("LineTexture").ToUTF8());
+ m_OverlayDescriptor.m_LineTextureMask = CStrIntern(TEXTUREBASEPATH + outlineNode.GetChild("LineTextureMask").ToUTF8());
m_OverlayDescriptor.m_LineThickness = outlineNode.GetChild("LineThickness").ToFloat();
}
@@ -193,6 +195,24 @@3,22 @@
SetSelectionHighlightAlpha(color.a);
}
+ virtual void SetRangeOverlay(float radius, const std::string& texture, const std::string& textureMask, float thickness)
+ {
+ if (!CRenderer::IsInitialised())
+ return;
+
+ CFG_GET_VAL("renderer.aura+ SOverlayDescriptor range", m_VisualAuraRangeOption);OverlayDescriptor;
+
+ SOverlayDescriptor auraOverlayDescriptor;
++ SOverlayTexturedLine* aurarangeOverlay = nullptr;
+
+ aura+ rangeOverlayDescriptor.m_Radius = radius;
+ aura+ rangeOverlayDescriptor.m_LineTexture = CStrIntern(TEXTUREBASEPATH + texture);
+ aura+ rangeOverlayDescriptor.m_LineTextureMask = CStrIntern(TEXTUREBASEPATH + textureMask);
+ aura+ rangeOverlayDescriptor.m_LineThickness = thickness;
+
+ m_RangeOverlayData.emplace_back(std::make_pair(aurarangeOverlayDescriptor, aurarangeOverlay));
+ }
+
virtual void SetSelectionHighlightAlpha(float alpha)
{
alpha = std::max(m_AlphaMin, alpha);
@@ -219,11 +2395,9 @@
void RenderSubmit(SceneCollector& collector);
/**
- * Called from RenderSubmit if using a static outline; responsible for ensuring that the static overlay
- * is up-to-date before it is rendered. Has no effect unless the static overlay is explicitly marked as
- * invalid first (see InvalidateStaticOverlay).
- */
- void UpdateStaticOverlay();
+ * Draw a textured overlay. The selection overlays for structures are based solely on footprint shape.
+ */
+ void UpdateTexturedOverlay(const SOverlayDescriptor* overlayDescriptor, SOverlayTexturedLine& overlay, float frameOffset, bool buildingOverlay);
/**
* Called from the interpolation handler; responsible for ensuring the dynamic overlay (provided we're
@@ -244,11 +26258,20 @@
*/
void UpdateMessageSubscriptions();
+ /**
+ * Delete range overlays
+ */
+ void ResetRangeOverlays();
+
private:
SOverlayDescriptor m_OverlayDescriptor;
SOverlayTexturedLine* m_BuildingOverlay;
SOverlayQuad* m_UnitOverlay;
+ // Holds the data for any range overlays
+ typedef std::pair<SOverlayDescriptor, SOverlayTexturedLine*> RangeOverlayData;
+ std::vector<RangeOverlayData> m_RangeOverlayData;
+
SOverlayLine* m_DebugBoundingBoxOverlay;
SOverlayLine* m_DebugSelectionBoxOverlay;
@@ -275,139,9 +302,17 @@1 @@
float m_FadeDeltaAlpha;
/// Linear time progress of the fade, between 0 and m_FadeDuration.
float m_FadeProgress;
+ /// If the config option to show aura ranges has been selected.
+ bool m_VisualAuraRangeOption;
/// Total duration of a single fade, in seconds. Assumed constant for now; feel free to change this into
/// a member variable if you need to adjust it per component.
static const double FADE_DURATION;
+ static const char* TEXTUREBASEPATH;
};
const double CCmpSelectable::FADE_DURATION = 0.3;
+const char* CCmpSelectable::TEXTUREBASEPATH = "art/textures/selection/";
void CCmpSelectable::HandleMessage(const CMessage& msg, bool UNUSED(global))
{
@@ -314,8 +345,19 @@39,18 @@
// update dynamic overlay only when visible
if (m_Color.a > 0)
+ {
UpdateDynamicOverlay(msgData.offset);
+ // Update any range overlays
+ if (m_VisualAuraRangeOption)
+ for (RangeOverlayData& rangeOverlay : m_RangeOverlayData)
+ {
+ delete rangeOverlay.second;
+ rangeOverlay.second = new SOverlayTexturedLine;
+ UpdateTexturedOverlay(&rangeOverlay.first, *rangeOverlay.second, msgData.offset, false);
+ }
+ }
+
UpdateMessageSubscriptions();
break;
@@ -370,9 +412,26 @@
break;
}
+ case MT_Update:
+ {
+ if (!CRenderer::IsInitialised())
+ break;
+
+ m_VisualAuraRangeOption = g_Renderer.GetOptionBool(CRenderer::OPT_AURARANGE);
+ break;
+ }3,6 +408,15 @@
}
}
+void CCmpSelectable::ResetRangeOverlays()
+{
+ for (RangeOverlayData& rangeOverlay : m_RangeOverlayData)
+ delete rangeOverlay.second;
+ m_RangeOverlayData.clear();
+
+ UpdateMessageSubscriptions();
+}
+
void CCmpSelectable::UpdateMessageSubscriptions()
{
bool needInterpolate = false;
@@ -402,15 +46146,8 @@
SAFE_DELETE(m_BuildingOverlay);
}
-void CCmpSelectable::UpdateStaticOverlay()
+void CCmpSelectable::UpdateTexturedOverlay(const SOverlayDescriptor* overlayDescriptor, SOverlayTexturedLine& overlay, float frameOffset, bool buildingOverlay)
{
- // Static overlays are allocated once and not updated until they are explicitly deleted again
- // (see InvalidateStaticOverlay). Since they are expected to change rarely (if ever) during
- // normal gameplay, this saves us doing all the work below on each frame.
-
- if (m_BuildingOverlay || m_OverlayDescriptor.m_Type != STATIC_OUTLINE)
- return;
-
if (!CRenderer::IsInitialised())
return;
@@ -419,84 +47156,69 @@
if (!cmpFootprint || !cmpPosition || !cmpPosition->IsInWorld())
return;
- CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity());
- if (!cmpTerrain)
- return; // should never happen
-
- // grab position/footprint data
- CFixedVector2D position = cmpPosition->GetPosition2D();
- CFixedVector3D rotation = cmpPosition->GetRotation();
-
ICmpFootprint::EShape fpShape;
entity_pos_t fpSize0_fixed, fpSize1_fixed, fpHeight_fixed;
cmpFootprint->GetShape(fpShape, fpSize0_fixed, fpSize1_fixed, fpHeight_fixed);
- CTextureProperties texturePropsBase(m_OverlayDescriptor.m_LineTexture.c_str());
+ float rotY;
+ CVector2D origin;
+ cmpPosition->GetInterpolatedPosition2D(frameOffset, origin.X, origin.Y, rotY);
+ CFixedVector3D rotation = cmpPosition->GetRotation();
+
+ CTextureProperties texturePropsBase(overlayDescriptor->m_LineTexture.c_str());
texturePropsBase.SetWrap(GL_CLAMP_TO_BORDER, GL_CLAMP_TO_EDGE);
texturePropsBase.SetMaxAnisotropy(4.f);
- CTextureProperties texturePropsMask(m_OverlayDescriptor.m_LineTextureMask.c_str());
+ CTextureProperties texturePropsMask(overlayDescriptor->m_LineTextureMask.c_str());
texturePropsMask.SetWrap(GL_CLAMP_TO_BORDER, GL_CLAMP_TO_EDGE);
texturePropsMask.SetMaxAnisotropy(4.f);
- // -------------------------------------------------------------------------------------
-
- m_BuildingOverlay = new SOverlayTexturedLine;
- m_BuildingOverlay->m_AlwaysVisible = false;
- m_BuildingOverlay->m_Closed = true;
- m_BuildingOverlay->m_SimContext = &GetSimContext();
- m_BuildingOverlay->m_Thickness = m_OverlayDescriptor.m_LineThickness;
- m_BuildingOverlay->m_TextureBase = g_Renderer.GetTextureManager().CreateTexture(texturePropsBase);
- m_BuildingOverlay->m_TextureMask = g_Renderer.GetTextureManager().CreateTexture(texturePropsMask);
-
- CVector2D origin(position.X.ToFloat(), position.Y.ToFloat());
-
- switch (fpShape)
- {
- case ICmpFootprint::SQUARE:
- {
- float s = sinf(-rotation.Y.ToFloat());
- float c = cosf(-rotation.Y.ToFloat());
- CVector2D unitX(c, s);
- CVector2D unitZ(-s, c);
-
- // add half the line thickness to the radius so that we get an 'outside' stroke of the footprint shape
- const float halfSizeX = fpSize0_fixed.ToFloat()/2.f + m_BuildingOverlay->m_Thickness/2.f;
- const float halfSizeZ = fpSize1_fixed.ToFloat()/2.f + m_BuildingOverlay->m_Thickness/2.f;
-
- std::vector<CVector2D> points;
- points.push_back(CVector2D(origin + unitX * halfSizeX + unitZ *(-halfSizeZ)));
- points.push_back(CVector2D(origin + unitX *(-halfSizeX) + unitZ *(-halfSizeZ)));
- points.push_back(CVector2D(origin + unitX *(-halfSizeX) + unitZ * halfSizeZ));
- points.push_back(CVector2D(origin + unitX * halfSizeX + unitZ * halfSizeZ));
+ overlay.m_AlwaysVisible = false;
+ overlay.m_Closed = true;
+ overlay.m_SimContext = &GetSimContext();
+ overlay.m_Thickness = overlayDescriptor->m_LineThickness;
+ overlay.m_TextureBase = g_Renderer.GetTextureManager().CreateTexture(texturePropsBase);
+ overlay.m_TextureMask = g_Renderer.GetTextureManager().CreateTexture(texturePropsMask);
+ overlay.m_Color = m_Color;
+
+ if (buildingOverlay && fpShape == ICmpFootprint::SQUARE)
+ {
+ float s = sinf(-rotation.Y.ToFloat());
+ float c = cosf(-rotation.Y.ToFloat());
+ CVector2D unitX(c, s);
+ CVector2D unitZ(-s, c);
+
+ // Add half the line thickness to the radius so that we get an 'outside' stroke of the footprint shape
+ const float halfSizeX = fpSize0_fixed.ToFloat() / 2.f + overlay.m_Thickness / 2.f;
+ const float halfSizeZ = fpSize1_fixed.ToFloat() / 2.f + overlay.m_Thickness / 2.f;
+
+ std::vector<CVector2D> points;
+ points.push_back(CVector2D(origin + unitX * halfSizeX + unitZ *(-halfSizeZ)));
+ points.push_back(CVector2D(origin + unitX *(-halfSizeX) + unitZ *(-halfSizeZ)));
+ points.push_back(CVector2D(origin + unitX *(-halfSizeX) + unitZ * halfSizeZ));
+ points.push_back(CVector2D(origin + unitX * halfSizeX + unitZ * halfSizeZ));
+
+ SimRender::SubdividePoints(points, TERRAIN_TILE_SIZE / 3.f, overlay.m_Closed);
+ overlay.PushCoords(points);
+ }
+ else
+ {
+ const float radius = (buildingOverlay ? fpSize0_fixed.ToFloat() : overlayDescriptor->m_Radius) + overlay.m_Thickness / 3.f;
+ float stepAngle;
+ unsigned numSteps;
+ SimRender::AngularStepFromChordLen(TERRAIN_TILE_SIZE / 3.f, radius, stepAngle, numSteps);
- m_BuildingOverlay = new SOverlayTexturedLine;
- m_BuildingOverlay->m_AlwaysVisible = false;
- m_BuildingOverlay->m_Closed = true;
- m_BuildingOverlay->m_SimContext = &GetSimContext();
- m_BuildingOverlay->m_Thickness = m_OverlayDescriptor.m_LineThickness;
- m_BuildingOverlay->m_TextureBase = g_Renderer.GetTextureManager().CreateTexture(texturePropsBase);
- m_BuildingOverlay->m_TextureMask = g_Renderer.GetTextureManager().CreateTexture(texturePropsMask);
-
- CVector2D origin(position.X.ToFloat(), position.Y.ToFloat());
-
- switch (fpShape)
- {
- case ICmpFootprint::SQUARE:
+ for (unsigned i = 0; i < numSteps; ++i)
{
- float s = sinf(-rotation.Y.ToFloat());
- float c = cosf(-rotation.Y.ToFloat());
- CVector2D unitX(c, s);
- CVector2D unitZ(-s, c);
-
- // add half the line thickness to the radius so that we get an 'outside' stroke of the footprint shape
- const float halfSizeX = fpSize0_fixed.ToFloat()/2.f + m_BuildingOverlay->m_Thickness/2.f;
- const float halfSizeZ = fpSize1_fixed.ToFloat()/2.f + m_BuildingOverlay->m_Thickness/2.f;
-
- std::vector<CVector2D> points;
- points.push_back(CVector2D(origin + unitX * halfSizeX + unitZ *(-halfSizeZ)));
- points.push_back(CVector2D(origin + unitX *(-halfSizeX) + unitZ *(-halfSizeZ)));
- points.push_back(CVector2D(origin + unitX *(-halfSizeX) + unitZ * halfSizeZ));
- points.push_back(CVector2D(origin + unitX * halfSizeX + unitZ * halfSizeZ));
+ float angle = i * stepAngle;
+ float px = origin.X + radius * sinf(angle);
+ float pz = origin.Y + radius * cosf(angle);
- SimRender::SubdividePoints(points, TERRAIN_TILE_SIZE/3.f, m_BuildingOverlay->m_Closed);
- m_BuildingOverlay->PushCoords(points);
+ overlay.PushCoords(px, pz);
}- }
- break;
- case ICmpFootprint::CIRCLE:
- {+ for (unsigned i = 0; i < numSteps; ++i)
{
- const float radius = fpSize0_fixed.ToFloat() + m_BuildingOverlay->m_Thickness/3.f;
- if (radius > 0) // prevent catastrophic failure
- {
- float stepAngle;
- unsigned numSteps;
- SimRender::AngularStepFromChordLen(TERRAIN_TILE_SIZE/3.f, radius, stepAngle, numSteps);
-
- for (unsigned i = 0; i < numSteps; i++) // '<' is sufficient because the line is closed automatically
- {
- float angle = i * stepAngle;
- float px = origin.X + radius * sinf(angle);
- float pz = origin.Y + radius * cosf(angle);
-+ float angle = i * stepAngle;
+ float px = origin.X + radius * sinf(angle);
+ float pz = origin.Y + radius * cosf(angle);
- m_BuildingOverlay->PushCoords(px, pz);
- }
- }
- }+ overlay.PushCoords(px, pz);
}
- break;
}
- ENSURE(m_BuildingOverlay);
+ ENSURE(overlay.m_TextureBase);
}
void CCmpSelectable::UpdateDynamicOverlay(float frameOffset)
@@ -625,7 +66247,10 @@
{
case STATIC_OUTLINE:
{
- UpdateStaticOverlay();
+ if (!m_BuildingOverlay)
+ m_BuildingOverlay = new SOverlayTexturedLine;
+
+ UpdateTexturedOverlay(&m_OverlayDescriptor, *m_BuildingOverlay, 1.f, true);
m_BuildingOverlay->m_Color = m_Color; // done separately so alpha changes don't require a full update call
collector.Submit(m_BuildingOverlay);
}
@@ -639,6 +679,10 @@64,9 @@
default:
break;
}
+
+ if (m_VisualAura+ for (const RangeOverlayData& rangeOverlay : m_RangeOptionverlayData)
+ for (const RangeOverlayData& rangeOverlay : m_RangeOverlayData)
+ collector.Submit(rangeOverlay.second);
}
// Render bounding box debug overlays if we have a positive target alpha value. This ensures
Index: source/simulation2/components/ICmpSelectable.h
===================================================================
--- source/simulation2/components/ICmpSelectable.h (revision 194114)
+++ source/simulation2/components/ICmpSelectable.h (working copy)
@@ -43,6 +43,7 @@
CStrIntern m_LineTexture;
CStrIntern m_LineTextureMask;
float m_LineThickness;
+ int m_Radius;
SOverlayDescriptor() : m_LineThickness(0) { }
};
@@ -61,6 +62,16 @@
virtual void SetSelectionHighlight(const CColor& color, bool selected) = 0;
/**
+ * Set a range overlays.
+ */
+ virtual void SetRangeOverlay(float radius, const std::string& texture, const std::string& textureMask, float thickness) = 0;
+
+ /**
+ * Reset any range overlays.
+ */
+ virtual void ResetRangeOverlays() = 0;
+
+ /**
* Enables or disables rendering of an entity's selectable.
* @param visible Whether the selectable should be visible.
*/
Index: source/simulation2/components/ICmpSelectable.cpp
===================================================================
--- source/simulation2/components/ICmpSelectable.cpp (revision 194114)
+++ source/simulation2/components/ICmpSelectable.cpp (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -25,6 +25,8 @@
BEGIN_INTERFACE_WRAPPER(Selectable)
DEFINE_INTERFACE_METHOD_2("SetSelectionHighlight", void, ICmpSelectable, SetSelectionHighlight, CColor, bool)
+DEFINE_INTERFACE_METHOD_4("SetRangeOverlay", void, ICmpSelectable, SetRangeOverlay, float, std::string, std::string, float)
+DEFINE_INTERFACE_METHOD_0("ResetRangeOverlays", void, ICmpSelectable, ResetRangeOverlays)
END_INTERFACE_WRAPPER(Selectable)
bool ICmpSelectable::ms_EnableDebugOverlays = false;