1
0
forked from 0ad/0ad

Stop units walking outside the edges of circular maps.

Switch the GUI between square/circular minimap automatically.

This was SVN commit r8500.
This commit is contained in:
Ykkrosh 2010-10-30 18:25:34 +00:00
parent 21b0504ca5
commit 1840bb3507
10 changed files with 84 additions and 7 deletions

View File

@ -192,18 +192,35 @@ function onSimulationUpdate()
g_TemplateData = {};
var simState = Engine.GuiInterfaceCall("GetSimulationState");
// If we're called during init when the game is first loading, there will be no simulation yet, so do nothing
if (!simState)
return;
handleNotifications();
updateMinimap(simState);
updateDebug(simState);
updatePlayerDisplay(simState);
updateSelectionDetails();
}
function updateMinimap(simState)
{
if (simState.circularMap)
{
getGUIObjectByName("minimap").circular = true;
getGUIObjectByName("minimapSquareOverlay").hidden = true;
getGUIObjectByName("minimapCircleOverlay").hidden = false;
}
else
{
getGUIObjectByName("minimap").circular = false;
getGUIObjectByName("minimapSquareOverlay").hidden = false;
getGUIObjectByName("minimapCircleOverlay").hidden = true;
}
}
function updateDebug(simState)
{
var debug = getGUIObjectByName("debug");

View File

@ -409,9 +409,9 @@
>
<action on="WorldClick">handleMinimapEvent(arguments[0]);</action>
</object>
<!-- <object size="10 10 100%-10 100%-10" type="image" sprite="glassSquareMap" ghost="true"/>-->
<object size="10 10 100%-10 100%-10" type="image" sprite="stretched:session/minimap_circle.png" ghost="true"/>
<object name="minimapSquareOverlay" size="10 10 100%-10 100%-10" type="image" sprite="glassSquareMap" ghost="true"/>
<object name="minimapCircleOverlay" size="10 10 100%-10 100%-10" type="image" sprite="stretched:session/minimap_circle.png" ghost="true" hidden="true"/>
</object>
<!-- ================================ ================================ -->

View File

@ -45,6 +45,12 @@ GuiInterface.prototype.GetSimulationState = function(player)
ret.players.push(playerData);
}
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (cmpRangeManager)
{
ret.circularMap = cmpRangeManager.GetLosCircular();
}
return ret;
};

View File

@ -31,6 +31,10 @@ function LoadMapSettings(settings)
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (cmpRangeManager)
cmpRangeManager.SetLosCircular(true);
var cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager);
if (cmpObstructionManager)
cmpObstructionManager.SetPassabilityCircular(true);
}
var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
@ -41,4 +45,4 @@ function LoadMapSettings(settings)
cmpEndGameManager.Start();
}
Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);
Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);

View File

@ -122,6 +122,8 @@ public:
u32 m_UnitShapeNext; // next allocated id
u32 m_StaticShapeNext;
bool m_PassabilityCircular;
entity_pos_t m_WorldX0;
entity_pos_t m_WorldZ0;
entity_pos_t m_WorldX1;
@ -142,6 +144,8 @@ public:
m_DirtyID = 1; // init to 1 so default-initialised grids are considered dirty
m_PassabilityCircular = false;
m_WorldX0 = m_WorldZ0 = m_WorldX1 = m_WorldZ1 = entity_pos_t::Zero();
// Initialise with bogus values (these will get replaced when
@ -164,6 +168,8 @@ public:
serialize.NumberU32_Unbounded("unit shape next", m_UnitShapeNext);
serialize.NumberU32_Unbounded("static shape next", m_StaticShapeNext);
serialize.Bool("circular", m_PassabilityCircular);
serialize.NumberFixed_Unbounded("world x0", m_WorldX0);
serialize.NumberFixed_Unbounded("world z0", m_WorldZ0);
serialize.NumberFixed_Unbounded("world x1", m_WorldX1);
@ -388,6 +394,12 @@ public:
virtual void GetObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares);
virtual bool FindMostImportantObstruction(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, ObstructionSquare& square);
virtual void SetPassabilityCircular(bool enabled)
{
m_PassabilityCircular = enabled;
MakeDirty();
}
virtual void SetDebugOverlay(bool enabled)
{
m_DebugOverlayEnabled = enabled;
@ -660,6 +672,27 @@ bool CCmpObstructionManager::Rasterise(Grid<u8>& grid)
grid.set(i, j, TILE_OBSTRUCTED | TILE_OUTOFBOUNDS);
}
if (m_PassabilityCircular)
{
for (u16 j = 0; j < grid.m_H; ++j)
{
for (u16 i = 0; i < grid.m_W; ++i)
{
// Based on CCmpRangeManager::LosIsOffWorld
// but tweaked since it's tile-based instead.
// This needs to be slightly tighter than the LOS circle,
// else units might get themselves lost in the SoD around the edge.
ssize_t dist2 = (i*2 + 1 - grid.m_W)*(i*2 + 1 - grid.m_W)
+ (j*2 + 1 - grid.m_H)*(j*2 + 1 - grid.m_H);
if (dist2 >= (grid.m_W-2)*(grid.m_H-2))
grid.set(i, j, TILE_OBSTRUCTED | TILE_OUTOFBOUNDS);
}
}
}
return true;
}

View File

@ -816,6 +816,11 @@ private:
ResetDerivedData();
}
virtual bool GetLosCircular()
{
return m_LosCircular;
}
/**
* Returns whether the given vertex is outside the normal bounds of the world
* (i.e. outside the range of a circular map)
@ -824,12 +829,12 @@ private:
{
if (m_LosCircular)
{
// With a circular map, vertex is off-world if hypot(i - size/2, j - size/2) > size/2:
// With a circular map, vertex is off-world if hypot(i - size/2, j - size/2) >= size/2:
ssize_t dist2 = (i - m_TerrainVerticesPerSide/2)*(i - m_TerrainVerticesPerSide/2)
+ (j - m_TerrainVerticesPerSide/2)*(j - m_TerrainVerticesPerSide/2);
if (dist2 >= m_TerrainVerticesPerSide*m_TerrainVerticesPerSide/4)
if (dist2 >= (m_TerrainVerticesPerSide/2)*(m_TerrainVerticesPerSide/2))
return true;
}

View File

@ -22,5 +22,6 @@
#include "simulation2/system/InterfaceScripted.h"
BEGIN_INTERFACE_WRAPPER(ObstructionManager)
DEFINE_INTERFACE_METHOD_1("SetPassabilityCircular", void, ICmpObstructionManager, SetPassabilityCircular, bool)
DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpObstructionManager, SetDebugOverlay, bool)
END_INTERFACE_WRAPPER(ObstructionManager)

View File

@ -215,6 +215,11 @@ public:
*/
virtual ObstructionSquare GetObstruction(tag_t tag) = 0;
/**
* Set the passability to be restricted to a circular map.
*/
virtual void SetPassabilityCircular(bool enabled) = 0;
/**
* Toggle the rendering of debug info.
*/

View File

@ -45,4 +45,5 @@ DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpRangeManager, SetDebugOve
DEFINE_INTERFACE_METHOD_1("SetLosRevealAll", void, ICmpRangeManager, SetLosRevealAll, bool)
DEFINE_INTERFACE_METHOD_2("GetLosVisibility", std::string, ICmpRangeManager, GetLosVisibility_wrapper, entity_id_t, int)
DEFINE_INTERFACE_METHOD_1("SetLosCircular", void, ICmpRangeManager, SetLosCircular, bool)
DEFINE_INTERFACE_METHOD_0("GetLosCircular", bool, ICmpRangeManager, GetLosCircular)
END_INTERFACE_WRAPPER(RangeManager)

View File

@ -249,6 +249,11 @@ public:
*/
virtual void SetLosCircular(bool enabled) = 0;
/**
* Returns whether the LOS is restricted to a circular map.
*/
virtual bool GetLosCircular() = 0;
DECLARE_INTERFACE_TYPE(RangeManager)
};