Add per-player LOS-reveal flag.

Reveal LOS for Gaia and AI players (fixes #879).
Use player_id_t slightly more consistently in interfaces.

This was SVN commit r9720.
This commit is contained in:
Ykkrosh 2011-06-28 23:24:42 +00:00
parent d9c944c975
commit 996a32125c
10 changed files with 90 additions and 40 deletions

View file

@ -122,9 +122,10 @@ EndGameManager.prototype.UpdatePlayerStates = function()
var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
cmpPlayer.SetState("won");
}
// Reveal the map to all players
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
cmpRangeManager.SetLosRevealAll(true);
cmpRangeManager.SetLosRevealAll(-1, true);
}
break;

View file

@ -17,8 +17,10 @@ function ProcessCommand(player, cmd)
break;
case "reveal-map":
// Reveal the map for all players, not just the current player,
// primarily to make it obvious to everyone that the player is cheating
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
cmpRangeManager.SetLosRevealAll(cmd.enable);
cmpRangeManager.SetLosRevealAll(-1, cmd.enable);
break;
case "walk":

View file

@ -22,7 +22,7 @@ function LoadMapSettings(settings)
{
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (cmpRangeManager)
cmpRangeManager.SetLosRevealAll(true);
cmpRangeManager.SetLosRevealAll(-1, true);
}
if (settings.CircularMap)

View file

@ -32,6 +32,7 @@
#include "simulation2/components/ICmpAIInterface.h"
#include "simulation2/components/ICmpCommandQueue.h"
#include "simulation2/components/ICmpObstructionManager.h"
#include "simulation2/components/ICmpRangeManager.h"
#include "simulation2/components/ICmpTemplateManager.h"
#include "simulation2/helpers/Grid.h"
#include "simulation2/serialization/DebugSerializer.h"
@ -537,9 +538,17 @@ public:
}
}
}
virtual void AddPlayer(std::wstring id, player_id_t player)
{
m_Worker.AddPlayer(id, player, true);
// AI players can cheat and see through FoW/SoD, since that greatly simplifies
// their implementation.
// (TODO: maybe cleverer AIs should be able to optionally retain FoW/SoD)
CmpPtr<ICmpRangeManager> cmpRangeManager(GetSimContext(), SYSTEM_ENTITY);
if (!cmpRangeManager.null())
cmpRangeManager->SetLosRevealAll(player, true);
}
virtual void StartComputation()

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2010 Wildfire Games.
/* Copyright (C) 2011 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -185,7 +185,7 @@ public:
// LOS state:
bool m_LosRevealAll;
std::map<player_id_t, bool> m_LosRevealAll;
bool m_LosCircular;
i32 m_TerrainVerticesPerSide;
@ -222,7 +222,10 @@ public:
// SetBounds is called)
ResetSubdivisions(entity_pos_t::FromInt(1), entity_pos_t::FromInt(1));
m_LosRevealAll = false;
// The whole map should be visible to Gaia by default, else e.g. animals
// will get confused when trying to run from enemies
m_LosRevealAll[0] = true;
m_LosCircular = false;
m_TerrainVerticesPerSide = 0;
}
@ -243,7 +246,7 @@ public:
SerializeMap<SerializeU32_Unbounded, SerializeQuery>()(serialize, "queries", m_Queries);
SerializeMap<SerializeU32_Unbounded, SerializeEntityData>()(serialize, "entity data", m_EntityData);
serialize.Bool("los reveal all", m_LosRevealAll);
SerializeMap<SerializeI32_Unbounded, SerializeBool>()(serialize, "los reveal all", m_LosRevealAll);
serialize.Bool("los circular", m_LosCircular);
serialize.NumberI32_Unbounded("terrain verts per side", m_TerrainVerticesPerSide);
@ -557,11 +560,11 @@ public:
return r;
}
virtual std::vector<entity_id_t> GetEntitiesByPlayer(int playerId)
virtual std::vector<entity_id_t> GetEntitiesByPlayer(player_id_t player)
{
std::vector<entity_id_t> entities;
u32 ownerMask = CalcOwnerMask(playerId);
u32 ownerMask = CalcOwnerMask(player);
for (std::map<entity_id_t, EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it)
{
@ -800,15 +803,15 @@ public:
// LOS implementation:
virtual CLosQuerier GetLosQuerier(int player)
virtual CLosQuerier GetLosQuerier(player_id_t player)
{
if (m_LosRevealAll)
if (GetLosRevealAll(player))
return CLosQuerier(player, m_LosStateRevealed, m_TerrainVerticesPerSide);
else
return CLosQuerier(player, m_LosState, m_TerrainVerticesPerSide);
}
virtual ELosVisibility GetLosVisibility(entity_id_t ent, int player)
virtual ELosVisibility GetLosVisibility(entity_id_t ent, player_id_t player)
{
// (We can't use m_EntityData since this needs to handle LOCAL entities too)
@ -822,8 +825,8 @@ public:
int i = (pos.X / (int)CELL_SIZE).ToInt_RoundToNearest();
int j = (pos.Y / (int)CELL_SIZE).ToInt_RoundToNearest();
// Global flag makes all positioned entities visible
if (m_LosRevealAll)
// Reveal flag makes all positioned entities visible
if (GetLosRevealAll(player))
{
if (LosIsOffWorld(i, j))
return VIS_HIDDEN;
@ -850,18 +853,26 @@ public:
return VIS_HIDDEN;
}
virtual void SetLosRevealAll(bool enabled)
virtual void SetLosRevealAll(player_id_t player, bool enabled)
{
// Eventually we might want this to be a per-player flag (which is why
// GetLosRevealAll takes a player argument), but currently it's just a
// global setting since I can't quite work out where per-player would be useful
m_LosRevealAll = enabled;
m_LosRevealAll[player] = enabled;
}
virtual bool GetLosRevealAll(int UNUSED(player))
virtual bool GetLosRevealAll(player_id_t player)
{
return m_LosRevealAll;
std::map<player_id_t, bool>::const_iterator it;
// Special player value can force reveal-all for every player
it = m_LosRevealAll.find(-1);
if (it != m_LosRevealAll.end() && it->second)
return true;
// Otherwise check the player-specific flag
it = m_LosRevealAll.find(player);
if (it != m_LosRevealAll.end() && it->second)
return true;
return false;
}
virtual void SetLosCircular(bool enabled)
@ -1181,11 +1192,11 @@ public:
}
}
virtual i32 GetPercentMapExplored(player_id_t playerId)
virtual i32 GetPercentMapExplored(player_id_t player)
{
i32 exploredVertices = 0;
i32 overallVisibleVertices = 0;
CLosQuerier los(playerId, m_LosState, m_TerrainVerticesPerSide);
CLosQuerier los(player, m_LosState, m_TerrainVerticesPerSide);
for (i32 j = 0; j < m_TerrainVerticesPerSide; j++)
{

View file

@ -40,10 +40,10 @@ DEFINE_INTERFACE_METHOD_1("DestroyActiveQuery", void, ICmpRangeManager, DestroyA
DEFINE_INTERFACE_METHOD_1("EnableActiveQuery", void, ICmpRangeManager, EnableActiveQuery, ICmpRangeManager::tag_t)
DEFINE_INTERFACE_METHOD_1("DisableActiveQuery", void, ICmpRangeManager, DisableActiveQuery, ICmpRangeManager::tag_t)
DEFINE_INTERFACE_METHOD_1("ResetActiveQuery", std::vector<entity_id_t>, ICmpRangeManager, ResetActiveQuery, ICmpRangeManager::tag_t)
DEFINE_INTERFACE_METHOD_1("GetEntitiesByPlayer", std::vector<entity_id_t>, ICmpRangeManager, GetEntitiesByPlayer, int)
DEFINE_INTERFACE_METHOD_1("GetEntitiesByPlayer", std::vector<entity_id_t>, ICmpRangeManager, GetEntitiesByPlayer, player_id_t)
DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpRangeManager, SetDebugOverlay, bool)
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_2("SetLosRevealAll", void, ICmpRangeManager, SetLosRevealAll, player_id_t, bool)
DEFINE_INTERFACE_METHOD_2("GetLosVisibility", std::string, ICmpRangeManager, GetLosVisibility_wrapper, entity_id_t, player_id_t)
DEFINE_INTERFACE_METHOD_1("SetLosCircular", void, ICmpRangeManager, SetLosCircular, bool)
DEFINE_INTERFACE_METHOD_0("GetLosCircular", bool, ICmpRangeManager, GetLosCircular)
DEFINE_INTERFACE_METHOD_1("GetPercentMapExplored", i32, ICmpRangeManager, GetPercentMapExplored, player_id_t)

View file

@ -135,7 +135,7 @@ public:
* Maybe it should be extended to be more like ExecuteQuery without
* the range parameter.)
*/
virtual std::vector<entity_id_t> GetEntitiesByPlayer(int playerId) = 0;
virtual std::vector<entity_id_t> GetEntitiesByPlayer(player_id_t player) = 0;
/**
* Toggle the rendering of debug info.
@ -171,7 +171,7 @@ public:
friend class CCmpRangeManager;
friend class TestLOSTexture;
CLosQuerier(int player, const std::vector<u32>& data, ssize_t verticesPerSide) :
CLosQuerier(player_id_t player, const std::vector<u32>& data, ssize_t verticesPerSide) :
m_Data(&data[0]), m_VerticesPerSide(verticesPerSide)
{
if (player > 0 && player <= 16)
@ -254,30 +254,31 @@ public:
/**
* Returns a CLosQuerier for checking whether vertex positions are visible to the given player.
*/
virtual CLosQuerier GetLosQuerier(int player) = 0;
virtual CLosQuerier GetLosQuerier(player_id_t player) = 0;
/**
* Returns the visibility status of the given entity, with respect to the given player.
* Returns VIS_HIDDEN if the entity doesn't exist or is not in the world.
* This respects the GetLosRevealAll flag.
*/
virtual ELosVisibility GetLosVisibility(entity_id_t ent, int player) = 0;
virtual ELosVisibility GetLosVisibility(entity_id_t ent, player_id_t player) = 0;
/**
* GetLosVisibility wrapped for script calls.
* Returns "hidden", "fogged" or "visible".
*/
std::string GetLosVisibility_wrapper(entity_id_t ent, int player);
std::string GetLosVisibility_wrapper(entity_id_t ent, player_id_t player);
/**
* Set globally whether the whole map should be made visible.
* Set whether the whole map should be made visible to the given player.
* If player is -1, the map will be made visible to all players.
*/
virtual void SetLosRevealAll(bool enabled) = 0;
virtual void SetLosRevealAll(player_id_t player, bool enabled) = 0;
/**
* Returns whether the whole map has been made visible to the given player.
*/
virtual bool GetLosRevealAll(int player) = 0;
virtual bool GetLosRevealAll(player_id_t player) = 0;
/**
* Set the LOS to be restricted to a circular map.
@ -290,9 +291,9 @@ public:
virtual bool GetLosCircular() = 0;
/**
* Get percent map explored statistics for specified player
* Get percent map explored statistics for specified player.
*/
virtual i32 GetPercentMapExplored(player_id_t playerId) = 0;
virtual i32 GetPercentMapExplored(player_id_t player) = 0;
DECLARE_INTERFACE_TYPE(RangeManager)
};

View file

@ -114,6 +114,32 @@ struct SerializeU32_Unbounded
}
};
struct SerializeI32_Unbounded
{
void operator()(ISerializer& serialize, const char* name, i32 value)
{
serialize.NumberI32_Unbounded(name, value);
}
void operator()(IDeserializer& deserialize, const char* name, i32& value)
{
deserialize.NumberI32_Unbounded(name, value);
}
};
struct SerializeBool
{
void operator()(ISerializer& serialize, const char* name, bool value)
{
serialize.Bool(name, value);
}
void operator()(IDeserializer& deserialize, const char* name, bool& value)
{
deserialize.Bool(name, value);
}
};
struct SerializeScriptVal
{
void operator()(ISerializer& serialize, const char* name, CScriptValRooted value)

View file

@ -152,7 +152,7 @@ ActorViewer::ActorViewer()
CmpPtr<ICmpRangeManager> cmpRangeManager(m.Simulation2, SYSTEM_ENTITY);
if (!cmpRangeManager.null())
cmpRangeManager->SetLosRevealAll(true);
cmpRangeManager->SetLosRevealAll(-1, true);
}
ActorViewer::~ActorViewer()

View file

@ -69,7 +69,7 @@ namespace
// Disable fog-of-war
CmpPtr<ICmpRangeManager> cmpRangeManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
if (!cmpRangeManager.null())
cmpRangeManager->SetLosRevealAll(true);
cmpRangeManager->SetLosRevealAll(-1, true);
}
}