Adds shared LOS for allied players, based on patch by Deiz/F00. Fixes #1334.

This was SVN commit r11949.
This commit is contained in:
historic_bruno 2012-06-08 04:41:39 +00:00
parent 659049eb1c
commit 962da61f12
5 changed files with 86 additions and 15 deletions

View File

@ -221,6 +221,30 @@ Player.prototype.GetDiplomacy = function()
Player.prototype.SetDiplomacy = function(dipl)
{
this.diplomacy = dipl;
this.UpdateSharedLos();
};
Player.prototype.SetDiplomacyIndex = function(idx, value)
{
// TODO: send a message too?
this.diplomacy[idx] = value;
this.UpdateSharedLos();
};
Player.prototype.UpdateSharedLos = function()
{
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (!cmpRangeManager)
return;
// TODO: only check our alliances currently, more advanced checks
// will be needed when we have full diplomacy
var sharedLos = [];
for (var i = 0; i < this.diplomacy.length; ++i)
if (this.IsAlly(i))
sharedLos.push(i);
cmpRangeManager.SetSharedLos(this.playerID, sharedLos);
};
Player.prototype.GetFormations = function()
@ -275,7 +299,7 @@ Player.prototype.IsAI = function()
Player.prototype.SetAlly = function(id)
{
this.diplomacy[id] = 1;
this.SetDiplomacyIndex(id, 1);
};
/**
@ -288,7 +312,7 @@ Player.prototype.IsAlly = function(id)
Player.prototype.SetEnemy = function(id)
{
this.diplomacy[id] = -1;
this.SetDiplomacyIndex(id, -1);
};
/**
@ -301,7 +325,7 @@ Player.prototype.IsEnemy = function(id)
Player.prototype.SetNeutral = function(id)
{
this.diplomacy[id] = 0;
this.SetDiplomacyIndex(id, 0);
};
/**

View File

@ -57,7 +57,7 @@ struct Query
* Convert an owner ID (-1 = unowned, 0 = gaia, 1..30 = players)
* into a 32-bit mask for quick set-membership tests.
*/
static u32 CalcOwnerMask(i32 owner)
static u32 CalcOwnerMask(player_id_t owner)
{
if (owner >= -1 && owner < 31)
return 1 << (1+owner);
@ -65,6 +65,23 @@ static u32 CalcOwnerMask(i32 owner)
return 0; // owner was invalid
}
/**
* Returns shared LOS mask for given list of players.
*/
static u32 CalcSharedLosMask(std::vector<player_id_t> players)
{
u32 playerMask = 0;
player_id_t player;
for (size_t i = 0; i < players.size(); i++)
{
player = players[i];
if (player > 0 && player <= 16)
playerMask |= ICmpRangeManager::LOS_MASK << (2*(player-1));
}
return playerMask;
}
/**
* Representation of an entity, with the data needed for queries.
*/
@ -212,6 +229,9 @@ public:
// (TODO: this is usually a waste of memory)
std::vector<u32> m_LosStateRevealed;
// Shared LOS masks, one per player.
std::map<player_id_t, u32> m_SharedLosMasks;
static std::string GetSchema()
{
return "<a:component type='system'/><empty/>";
@ -234,6 +254,10 @@ public:
// will get confused when trying to run from enemies
m_LosRevealAll[0] = true;
// This is not really an error condition, an entity recently created or destroyed
// might have an owner of INVALID_PLAYER
m_SharedLosMasks[INVALID_PLAYER] = 0;
m_LosCircular = false;
m_TerrainVerticesPerSide = 0;
@ -265,6 +289,8 @@ public:
// m_LosState must be serialized since it depends on the history of exploration
SerializeVector<SerializeU32_Unbounded>()(serialize, "los state", m_LosState);
SerializeMap<SerializeI32_Unbounded, SerializeU32_Unbounded>()(serialize, "shared los masks", m_SharedLosMasks);
}
virtual void Serialize(ISerializer& serialize)
@ -910,9 +936,9 @@ public:
virtual CLosQuerier GetLosQuerier(player_id_t player)
{
if (GetLosRevealAll(player))
return CLosQuerier(player, m_LosStateRevealed, m_TerrainVerticesPerSide);
return CLosQuerier(GetSharedLosMask(player), m_LosStateRevealed, m_TerrainVerticesPerSide);
else
return CLosQuerier(player, m_LosState, m_TerrainVerticesPerSide);
return CLosQuerier(GetSharedLosMask(player), m_LosState, m_TerrainVerticesPerSide);
}
virtual ELosVisibility GetLosVisibility(entity_id_t ent, player_id_t player, bool forceRetainInFog)
@ -939,8 +965,7 @@ public:
}
// Visible if within a visible region
CLosQuerier los(player, m_LosState, m_TerrainVerticesPerSide);
CLosQuerier los(GetSharedLosMask(player), m_LosState, m_TerrainVerticesPerSide);
if (los.IsVisible(i, j))
return VIS_VISIBLE;
@ -991,6 +1016,19 @@ public:
return m_LosCircular;
}
virtual void SetSharedLos(player_id_t player, std::vector<player_id_t> players)
{
m_SharedLosMasks[player] = CalcSharedLosMask(players);
}
virtual u32 GetSharedLosMask(player_id_t player)
{
std::map<player_id_t, u32>::const_iterator it = m_SharedLosMasks.find(player);
ENSURE(it != m_SharedLosMasks.end());
return m_SharedLosMasks[player];
}
void UpdateTerritoriesLos()
{
CmpPtr<ICmpTerritoryManager> cmpTerritoryManager(GetSimContext(), SYSTEM_ENTITY);

View File

@ -48,5 +48,6 @@ DEFINE_INTERFACE_METHOD_2("SetLosRevealAll", void, ICmpRangeManager, SetLosRevea
DEFINE_INTERFACE_METHOD_3("GetLosVisibility", std::string, ICmpRangeManager, GetLosVisibility_wrapper, entity_id_t, player_id_t, bool)
DEFINE_INTERFACE_METHOD_1("SetLosCircular", void, ICmpRangeManager, SetLosCircular, bool)
DEFINE_INTERFACE_METHOD_0("GetLosCircular", bool, ICmpRangeManager, GetLosCircular)
DEFINE_INTERFACE_METHOD_2("SetSharedLos", void, ICmpRangeManager, SetSharedLos, player_id_t, std::vector<player_id_t>)
DEFINE_INTERFACE_METHOD_1("GetPercentMapExplored", i32, ICmpRangeManager, GetPercentMapExplored, player_id_t)
END_INTERFACE_WRAPPER(RangeManager)

View File

@ -185,13 +185,10 @@ public:
friend class CCmpRangeManager;
friend class TestLOSTexture;
CLosQuerier(player_id_t player, const std::vector<u32>& data, ssize_t verticesPerSide) :
CLosQuerier(u32 playerMask, const std::vector<u32>& data, ssize_t verticesPerSide) :
m_Data(&data[0]), m_VerticesPerSide(verticesPerSide)
{
if (player > 0 && player <= 16)
m_PlayerMask = LOS_MASK << (2*(player-1));
else
m_PlayerMask = 0;
m_PlayerMask = playerMask;
}
const CLosQuerier& operator=(const CLosQuerier&); // not implemented
@ -266,7 +263,8 @@ public:
};
/**
* Returns a CLosQuerier for checking whether vertex positions are visible to the given player.
* Returns a CLosQuerier for checking whether vertex positions are visible to the given player
* (or other players it shares LOS with).
*/
virtual CLosQuerier GetLosQuerier(player_id_t player) = 0;
@ -307,6 +305,16 @@ public:
*/
virtual bool GetLosCircular() = 0;
/**
* Sets shared LOS data for player to the given list of players.
*/
virtual void SetSharedLos(player_id_t player, std::vector<player_id_t> players) = 0;
/**
* Returns shared LOS mask for player.
*/
virtual u32 GetSharedLosMask(player_id_t player) = 0;
/**
* Get percent map explored statistics for specified player.
*/