forked from 0ad/0ad
Adds shared LOS for allied players, based on patch by Deiz/F00. Fixes #1334.
This was SVN commit r11949.
This commit is contained in:
parent
659049eb1c
commit
962da61f12
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -178,7 +178,7 @@ void CLOSTexture::RecomputeTexture(int unit)
|
||||
if (!cmpRangeManager)
|
||||
return;
|
||||
|
||||
ICmpRangeManager::CLosQuerier los (cmpRangeManager->GetLosQuerier(g_Game->GetPlayerID()));
|
||||
ICmpRangeManager::CLosQuerier los(cmpRangeManager->GetLosQuerier(g_Game->GetPlayerID()));
|
||||
|
||||
GenerateBitmap(los, &losData[0], m_MapSize, m_MapSize);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user