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:
sanderd17 2015-05-29 07:02:16 +00:00
parent f4432330e1
commit e68ef21334
7 changed files with 62 additions and 19 deletions

View File

@ -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;
};

View File

@ -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;

View File

@ -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

View File

@ -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)
{ }

View File

@ -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)

View File

@ -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)
};

View File

@ -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},