Don't decay when connected to connected allied territory, and also allow the decay script to determine which parts of the territory should blink
This was SVN commit r16692.
This commit is contained in:
parent
f4432330e1
commit
e68ef21334
@ -20,14 +20,14 @@ TerritoryDecay.prototype.IsConnected = function()
|
||||
if (!cmpPosition || !cmpPosition.IsInWorld())
|
||||
return false;
|
||||
|
||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
if (!cmpOwnership)
|
||||
return true; // something without ownership can't decay
|
||||
|
||||
var cmpPlayer = QueryOwnerInterface(this.entity);
|
||||
if (!cmpPlayer)
|
||||
return true;// something without ownership can't decay
|
||||
|
||||
var cmpTerritoryManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager);
|
||||
var pos = cmpPosition.GetPosition2D();
|
||||
var tileOwner = cmpTerritoryManager.GetOwner(pos.x, pos.y);
|
||||
if (tileOwner != cmpOwnership.GetOwner())
|
||||
if (tileOwner != cmpPlayer.GetPlayerID())
|
||||
{
|
||||
this.connectedNeighbours[tileOwner] = 1;
|
||||
return false;
|
||||
@ -40,6 +40,16 @@ TerritoryDecay.prototype.IsConnected = function()
|
||||
return true;
|
||||
|
||||
this.connectedNeighbours = cmpTerritoryManager.GetNeighbours(pos.x, pos.y, true);
|
||||
|
||||
for (var i = 1; i < numPlayers; ++i)
|
||||
if (this.connectedNeighbours[i] > 0 && cmpPlayer.IsAlly(i))
|
||||
return true; // don't decay if connected to a connected ally
|
||||
|
||||
// decay to gaia when there all neighbours are unconnected
|
||||
if (this.connectedNeighbours.reduce((a, b) => a + b) == 0)
|
||||
this.connectedNeighbours[0] = 1;
|
||||
|
||||
cmpTerritoryManager.SetTerritoryBlinking(pos.x, pos.y);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -82,7 +82,7 @@ std::vector<STerritoryBoundary> CTerritoryBoundaryCalculator::ComputeBoundaries(
|
||||
// do this by looking at a curvature value which we define to start at 0, and which is incremented by 1 for every CCW turn and
|
||||
// decremented by 1 for every CW turn. Hence, a negative multiple of 4 means a CW winding order, and a positive one means CCW.
|
||||
|
||||
const int TERRITORY_DISCR_MASK = (ICmpTerritoryManager::TERRITORY_CONNECTED_MASK | ICmpTerritoryManager::TERRITORY_PLAYER_MASK);
|
||||
const int TERRITORY_DISCR_MASK = (ICmpTerritoryManager::TERRITORY_BLINKING_MASK | ICmpTerritoryManager::TERRITORY_PLAYER_MASK);
|
||||
|
||||
// Try to find an assigned tile
|
||||
for (u16 j = 0; j < grid.m_H; ++j)
|
||||
@ -90,11 +90,11 @@ std::vector<STerritoryBoundary> CTerritoryBoundaryCalculator::ComputeBoundaries(
|
||||
for (u16 i = 0; i < grid.m_W; ++i)
|
||||
{
|
||||
// saved tile state; from MSB to LSB:
|
||||
// processed bit, connected bit, player ID
|
||||
// processed bit, blinking bit, player ID
|
||||
u8 tileState = grid.get(i, j);
|
||||
u8 tileDiscr = (tileState & TERRITORY_DISCR_MASK);
|
||||
|
||||
// ignore neutral tiles (note that tiles without an owner should never have the connected bit set)
|
||||
// ignore neutral tiles (note that tiles without an owner should never have the blinking bit set)
|
||||
if (!tileDiscr)
|
||||
continue;
|
||||
|
||||
@ -112,7 +112,7 @@ std::vector<STerritoryBoundary> CTerritoryBoundaryCalculator::ComputeBoundaries(
|
||||
|
||||
boundaries.push_back(STerritoryBoundary());
|
||||
boundaries.back().owner = (tileState & ICmpTerritoryManager::TERRITORY_PLAYER_MASK);
|
||||
boundaries.back().connected = (tileState & ICmpTerritoryManager::TERRITORY_CONNECTED_MASK) != 0;
|
||||
boundaries.back().blinking = (tileState & ICmpTerritoryManager::TERRITORY_BLINKING_MASK) != 0;
|
||||
std::vector<CVector2D>& points = boundaries.back().points;
|
||||
|
||||
u8 dir = TILE_BOTTOM;
|
||||
|
@ -36,8 +36,8 @@
|
||||
*/
|
||||
struct STerritoryBoundary
|
||||
{
|
||||
/// Is the territory enclosed by this boundary mathematically connected to (i.e. reachable from) a root influence entity?
|
||||
bool connected;
|
||||
/// Set if this boundary should blink
|
||||
bool blinking;
|
||||
player_id_t owner;
|
||||
/// The boundary points, in clockwise order for inner boundaries and counter-clockwise order for outer boundaries.
|
||||
/// Note: if you need a way to explicitly find out which winding order these are in, you can have
|
||||
|
@ -81,8 +81,9 @@ public:
|
||||
float m_BorderThickness;
|
||||
float m_BorderSeparation;
|
||||
|
||||
// Player ID in bits 0-5 (TERRITORY_PLAYER_MASK);
|
||||
// connected flag in bit 6 (TERRITORY_CONNECTED_MASK);
|
||||
// Player ID in bits 0-4 (TERRITORY_PLAYER_MASK)
|
||||
// connected flag in bit 4 (TERRITORY_CONNECTED_MASK)
|
||||
// blinking flag in bit 5 (TERRITORY_BLINKING_MASK)
|
||||
// processed flag in bit 7 (TERRITORY_PROCESSED_MASK)
|
||||
Grid<u8>* m_Territories;
|
||||
|
||||
@ -92,7 +93,7 @@ public:
|
||||
|
||||
struct SBoundaryLine
|
||||
{
|
||||
bool connected;
|
||||
bool blinking;
|
||||
CColor color;
|
||||
SOverlayTexturedLine overlay;
|
||||
};
|
||||
@ -220,6 +221,8 @@ public:
|
||||
virtual std::vector<u32> GetNeighbours(entity_pos_t x, entity_pos_t z, bool filterConnected);
|
||||
virtual bool IsConnected(entity_pos_t x, entity_pos_t z);
|
||||
|
||||
virtual void SetTerritoryBlinking(entity_pos_t x, entity_pos_t z);
|
||||
|
||||
// To support lazy updates of territory render data,
|
||||
// we maintain a DirtyID here and increment it whenever territories change;
|
||||
// if a caller has a lower DirtyID then it needs to be updated.
|
||||
@ -509,7 +512,7 @@ void CCmpTerritoryManager::UpdateBoundaryLines()
|
||||
color = cmpPlayer->GetColor();
|
||||
|
||||
m_BoundaryLines.push_back(SBoundaryLine());
|
||||
m_BoundaryLines.back().connected = boundaries[i].connected;
|
||||
m_BoundaryLines.back().blinking = boundaries[i].blinking;
|
||||
m_BoundaryLines.back().color = color;
|
||||
m_BoundaryLines.back().overlay.m_SimContext = &GetSimContext();
|
||||
m_BoundaryLines.back().overlay.m_TextureBase = textureBase;
|
||||
@ -559,7 +562,7 @@ void CCmpTerritoryManager::Interpolate(float frameTime, float UNUSED(frameOffset
|
||||
|
||||
for (size_t i = 0; i < m_BoundaryLines.size(); ++i)
|
||||
{
|
||||
if (!m_BoundaryLines[i].connected)
|
||||
if (m_BoundaryLines[i].blinking)
|
||||
{
|
||||
CColor c = m_BoundaryLines[i].color;
|
||||
c.a *= 0.2f + 0.8f * fabsf((float)cos(m_AnimTime * M_PI)); // TODO: should let artists tweak this
|
||||
@ -641,6 +644,29 @@ bool CCmpTerritoryManager::IsConnected(entity_pos_t x, entity_pos_t z)
|
||||
return (m_Territories->get(i, j) & TERRITORY_CONNECTED_MASK) != 0;
|
||||
}
|
||||
|
||||
void CCmpTerritoryManager::SetTerritoryBlinking(entity_pos_t x, entity_pos_t z)
|
||||
{
|
||||
CalculateTerritories();
|
||||
if (!m_Territories)
|
||||
return;
|
||||
|
||||
u16 i, j;
|
||||
NearestTile(x, z, i, j, m_Territories->m_W, m_Territories->m_H);
|
||||
|
||||
u16 tilesW = m_Territories->m_W;
|
||||
u16 tilesH = m_Territories->m_H;
|
||||
|
||||
player_id_t thisOwner = m_Territories->get(i, j) & TERRITORY_PLAYER_MASK;
|
||||
|
||||
FLOODFILL(i, j,
|
||||
u8 bitmask = m_Territories->get(nx, nz);
|
||||
if ((bitmask & TERRITORY_PLAYER_MASK) != thisOwner || (bitmask & TERRITORY_BLINKING_MASK))
|
||||
continue;
|
||||
m_Territories->set(nx, nz, bitmask | TERRITORY_BLINKING_MASK);
|
||||
);
|
||||
m_BoundaryLinesDirty = true;
|
||||
}
|
||||
|
||||
TerritoryOverlay::TerritoryOverlay(CCmpTerritoryManager& manager)
|
||||
: TerrainOverlay(manager.GetSimContext()), m_TerritoryManager(manager)
|
||||
{ }
|
||||
|
@ -25,4 +25,5 @@ BEGIN_INTERFACE_WRAPPER(TerritoryManager)
|
||||
DEFINE_INTERFACE_METHOD_2("GetOwner", player_id_t, ICmpTerritoryManager, GetOwner, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_3("GetNeighbours", std::vector<u32>, ICmpTerritoryManager, GetNeighbours, entity_pos_t, entity_pos_t, bool)
|
||||
DEFINE_INTERFACE_METHOD_2("IsConnected", bool, ICmpTerritoryManager, IsConnected, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_2("SetTerritoryBlinking", void, ICmpTerritoryManager, SetTerritoryBlinking, entity_pos_t, entity_pos_t)
|
||||
END_INTERFACE_WRAPPER(TerritoryManager)
|
||||
|
@ -29,8 +29,9 @@ class ICmpTerritoryManager : public IComponent
|
||||
public:
|
||||
virtual bool NeedUpdate(size_t* dirtyID) = 0;
|
||||
|
||||
static const int TERRITORY_PLAYER_MASK = 0x3F;
|
||||
static const int TERRITORY_CONNECTED_MASK = 0x40;
|
||||
static const int TERRITORY_PLAYER_MASK = 0x1F;
|
||||
static const int TERRITORY_CONNECTED_MASK = 0x20;
|
||||
static const int TERRITORY_BLINKING_MASK = 0x40;
|
||||
static const int TERRITORY_PROCESSED_MASK = 0x80; //< For internal use; marks a tile as processed.
|
||||
|
||||
/**
|
||||
@ -58,6 +59,11 @@ public:
|
||||
*/
|
||||
virtual bool IsConnected(entity_pos_t x, entity_pos_t z) = 0;
|
||||
|
||||
/**
|
||||
* Set a piece of territory to blinking. Must be updated on every territory calculation
|
||||
*/
|
||||
virtual void SetTerritoryBlinking(entity_pos_t x, entity_pos_t z) = 0;
|
||||
|
||||
DECLARE_INTERFACE_TYPE(TerritoryManager)
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
TS_ASSERT_EQUALS(1U, boundaries.size());
|
||||
TS_ASSERT_EQUALS(18U, boundaries[0].points.size()); // 2x6 + 2x3
|
||||
TS_ASSERT_EQUALS((player_id_t)7, boundaries[0].owner);
|
||||
TS_ASSERT_EQUALS(false, boundaries[0].connected); // high bits aren't set by GetGrid
|
||||
TS_ASSERT_EQUALS(false, boundaries[0].blinking); // high bits aren't set by GetGrid
|
||||
|
||||
// assumes CELL_SIZE is 4; dealt with in TestBoundaryPointsEqual
|
||||
int expectedPoints[][2] = {{ 2, 4}, { 6, 4}, {10, 4}, {14, 4}, {18, 4}, {22, 4},
|
||||
|
Loading…
Reference in New Issue
Block a user