Move visibility stuff from CMap into CMapFieldPlayerInfo.

This commit is contained in:
Joris 2012-09-07 18:16:07 +02:00
parent 649701b5ef
commit 61c60d580f
11 changed files with 86 additions and 88 deletions

View file

@ -182,7 +182,7 @@ int DoActionMove(CUnit &unit)
unit.MoveToXY(pos);
// Remove unit from the current selection
if (unit.Selected && !Map.IsFieldVisible(*ThisPlayer, pos)) {
if (unit.Selected && !Map.Field(pos)->playerInfo.IsTeamVisible(*ThisPlayer)) {
if (NumSelected == 1) { // Remove building cursor
CancelBuildingMode();
}

View file

@ -179,31 +179,6 @@ public:
/// convert tilepos coordonates into map pixel pos (take the center of the tile)
PixelPos TilePosToMapPixelPos_Center(const Vec2i &tilePos) const;
/**
** Find out if a field is seen (By player, or by shared vision)
** This function will return > 1 with no fog of war.
**
** @param player Player to check for.
** @param index flat tile index adress.
**
** @return 0 unexplored, 1 explored, > 1 visible.
*/
unsigned short IsTileVisible(const CPlayer &player, const unsigned int index) const;
/// Check if a field for the user is visible.
bool IsFieldVisible(const CPlayer &player, const unsigned int index) const {
return IsTileVisible(player, index) > 1;
}
unsigned short IsTileVisible(const CPlayer &player, const Vec2i &pos) const {
return IsTileVisible(player, getIndex(pos));
}
/// Check if a field for the user is visible.
bool IsFieldVisible(const CPlayer &player, const Vec2i &pos) {
return IsTileVisible(player, getIndex(pos)) > 1;
}
/// Mark a tile as seen by the player.
void MarkSeenTile(const unsigned int index);

View file

@ -176,6 +176,19 @@ public:
/// Check if a field for the user is explored.
bool IsExplored(const CPlayer &player) const;
/// @note Manage Map.NoFogOfWar
bool IsVisible(const CPlayer &player) const;
bool IsTeamVisible(const CPlayer &player) const;
/**
** Find out how a field is seen (By player, or by shared vision)
**
** @param player Player to check for.
** @note manage fogOfWar (using Map.NoFogOfWar)
**
** @return 0 unexplored, 1 explored, 2 visible.
*/
unsigned char TeamVisibilityState(const CPlayer &player) const;
public:
unsigned short SeenTile; /// last seen tile (FOW)
unsigned short Visible[PlayerMax]; /// Seen counter 0 unexplored

View file

@ -200,28 +200,27 @@ bool CMapField::IsTerrainResourceOnMap() const
return false;
}
unsigned short CMap::IsTileVisible(const CPlayer &player, const unsigned int index) const
unsigned char CMapFieldPlayerInfo::TeamVisibilityState(const CPlayer &player) const
{
const CMapFieldPlayerInfo &mfp = this->Fields[index].playerInfo;
unsigned short visiontype = mfp.Visible[player.Index];
const bool fogOfWar = !Map.NoFogOfWar;
if (visiontype > 1) {
return visiontype;
if (IsVisible(player)) {
return 2;
}
if (player.IsVisionSharing()) {
for (int i = 0; i < PlayerMax ; ++i) {
if (player.IsBothSharedVision(Players[i])) {
if (mfp.Visible[i] > 1) {
return 2;
}
visiontype |= mfp.Visible[i];
}
if (IsExplored(player) == false) {
return 0;
}
if (player.IsVisionSharing() == false) {
return 1;
}
const int minValueRequired = fogOfWar ? 2 : 1;
for (int i = 0; i != PlayerMax ; ++i) {
if (Visible[i] >= minValueRequired && player.IsBothSharedVision(Players[i])) {
return 2;
}
}
if (visiontype) {
return visiontype + (NoFogOfWar ? 1 : 0);
}
return 0;
return 1;
}
bool CMapFieldPlayerInfo::IsExplored(const CPlayer &player) const
@ -229,6 +228,17 @@ bool CMapFieldPlayerInfo::IsExplored(const CPlayer &player) const
return Visible[player.Index] != 0;
}
bool CMapFieldPlayerInfo::IsVisible(const CPlayer &player) const
{
const bool fogOfWar = !Map.NoFogOfWar;
return Visible[player.Index] >= 2 || (!fogOfWar && IsExplored(player));
}
bool CMapFieldPlayerInfo::IsTeamVisible(const CPlayer &player) const
{
return TeamVisibilityState(player) == 2;
}
/**
** Wall on map tile.
**
@ -555,7 +565,7 @@ void CMap::FixTile(unsigned short type, int seen, const Vec2i &pos)
}
//maybe isExplored
if (IsTileVisible(*ThisPlayer, index) > 0) {
if (mf->playerInfo.IsExplored(*ThisPlayer)) {
UI.Minimap.UpdateSeenXY(pos);
if (!seen) {
MarkSeenTile(pos);
@ -592,8 +602,7 @@ void CMap::ClearTile(unsigned short type, const Vec2i &pos)
int removedtile;
int flags;
unsigned int index = getIndex(pos);
CMapField &mf = *this->Field(index);
CMapField &mf = *this->Field(pos);
// Select Table to lookup
switch (type) {
@ -616,7 +625,7 @@ void CMap::ClearTile(unsigned short type, const Vec2i &pos)
FixNeighbors(type, 0, pos);
//maybe isExplored
if (IsTileVisible(*ThisPlayer, index) > 0) {
if (mf.playerInfo.IsExplored(*ThisPlayer)) {
UI.Minimap.UpdateSeenXY(pos);
MarkSeenTile(pos);
}
@ -662,11 +671,11 @@ void CMap::RegenerateForestTile(const Vec2i &pos)
mf.Tile = this->Tileset.BotOneTree;
mf.Value = 0;
mf.Flags |= MapFieldForest | MapFieldUnpassable;
if (Map.IsFieldVisible(*ThisPlayer, pos)) {
if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) {
MarkSeenTile(pos);
}
const Vec2i offset(0, -1);
if (Map.IsFieldVisible(*ThisPlayer, pos + offset)) {
if (Map.Field(pos + offset)->playerInfo.IsTeamVisible(*ThisPlayer)) {
MarkSeenTile(pos);
}
}

View file

@ -426,10 +426,12 @@ void CViewport::Draw() const
//
if (CursorOn == CursorOnMap && Preference.ShowNameDelay && (ShowNameDelay < GameCycle) && (GameCycle < ShowNameTime)) {
const Vec2i tilePos = this->ScreenToTilePos(CursorScreenPos);
const bool isMapFieldVisile = Map.Field(tilePos)->playerInfo.IsTeamVisible(*ThisPlayer);
if (UI.MouseViewport->IsInsideMapArea(CursorScreenPos)
&& (Map.IsFieldVisible(*ThisPlayer, tilePos) || ReplayRevealMap)) {
&& (isMapFieldVisile || ReplayRevealMap)) {
ShowUnitName(*this, CursorScreenPos, UnitUnderCursor);
} else if (!Map.IsFieldVisible(*ThisPlayer, tilePos)) {
} else if (!isMapFieldVisile) {
ShowUnitName(*this, CursorScreenPos, NULL, true);
}
}

View file

@ -140,7 +140,7 @@ void MapMarkTileSight(const CPlayer &player, const unsigned int index)
UnitsOnTileMarkSeen(player, index, 0);
}
*v = 2;
if (Map.IsTileVisible(*ThisPlayer, index) > 1) {
if (Map.Field(index)->playerInfo.IsTeamVisible(*ThisPlayer)) {
Map.MarkSeenTile(index);
}
return;
@ -177,7 +177,7 @@ void MapUnmarkTileSight(const CPlayer &player, const unsigned int index)
UnitsOnTileUnmarkSeen(player, index, 0);
}
// Check visible Tile, then deduct...
if (Map.IsTileVisible(*ThisPlayer, index) > 1) {
if (Map.Field(index)->playerInfo.IsTeamVisible(*ThisPlayer)) {
Map.MarkSeenTile(index);
}
default: // seen -> seen
@ -546,7 +546,7 @@ void CViewport::DrawMapFogOfWar() const
unsigned int my_index = my * Map.Info.MapWidth;
for (; my < ey; ++my) {
for (int mx = sx; mx < ex; ++mx) {
VisibleTable[my_index + mx] = Map.IsTileVisible(*ThisPlayer, mx + my_index);
VisibleTable[my_index + mx] = Map.Field(mx + my_index)->playerInfo.TeamVisibilityState(*ThisPlayer);
}
my_index += Map.Info.MapWidth;
}

View file

@ -96,8 +96,8 @@ void MapFixSeenWallTile(const Vec2i &pos)
if (!Map.Info.IsPointOnMap(pos)) {
return;
}
CMapField *mf = Map.Field(pos);
int t = Map.Tileset.TileTypeTable[mf->playerInfo.SeenTile];
CMapField &mf = *Map.Field(pos);
int t = Map.Tileset.TileTypeTable[mf.playerInfo.SeenTile];
if (t != TileTypeHumanWall && t != TileTypeOrcWall) {
return;
}
@ -121,7 +121,7 @@ void MapFixSeenWallTile(const Vec2i &pos)
if (t == TileTypeHumanWall) {
tile = Map.Tileset.HumanWallTable[tile];
if (UnitTypeHumanWall && mf->Value <= UnitTypeHumanWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
if (UnitTypeHumanWall && mf.Value <= UnitTypeHumanWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
while (Map.Tileset.Table[tile]) { // Skip good tiles
++tile;
}
@ -131,7 +131,7 @@ void MapFixSeenWallTile(const Vec2i &pos)
}
} else {
tile = Map.Tileset.OrcWallTable[tile];
if (UnitTypeOrcWall && mf->Value <= UnitTypeOrcWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
if (UnitTypeOrcWall && mf.Value <= UnitTypeOrcWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
while (Map.Tileset.Table[tile]) { // Skip good tiles
++tile;
}
@ -140,7 +140,7 @@ void MapFixSeenWallTile(const Vec2i &pos)
}
}
}
if (mf->Value == 0) {
if (mf.Value == 0) {
while (Map.Tileset.Table[tile]) { // Skip good tiles
++tile;
}
@ -150,11 +150,11 @@ void MapFixSeenWallTile(const Vec2i &pos)
}
tile = Map.Tileset.Table[tile];
if (mf->playerInfo.SeenTile != tile) { // Already there!
mf->playerInfo.SeenTile = tile;
if (mf.playerInfo.SeenTile != tile) { // Already there!
mf.playerInfo.SeenTile = tile;
// FIXME: can this only happen if seen?
if (Map.IsFieldVisible(*ThisPlayer, pos)) {
if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) {
UI.Minimap.UpdateSeenXY(pos);
}
}
@ -185,12 +185,12 @@ void MapFixWallTile(const Vec2i &pos)
if (!Map.Info.IsPointOnMap(pos)) {
return;
}
CMapField *mf = Map.Field(pos);
if (!(mf->Flags & MapFieldWall)) {
CMapField &mf = *Map.Field(pos);
if (!(mf.Flags & MapFieldWall)) {
return;
}
int t = mf->Flags & (MapFieldHuman | MapFieldWall);
int t = mf.Flags & (MapFieldHuman | MapFieldWall);
//
// Calculate the correct tile. Depends on the surrounding.
//
@ -214,7 +214,7 @@ void MapFixWallTile(const Vec2i &pos)
if (t & MapFieldHuman) {
tile = Map.Tileset.HumanWallTable[tile];
if (UnitTypeHumanWall && mf->Value <= UnitTypeHumanWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
if (UnitTypeHumanWall && mf.Value <= UnitTypeHumanWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
while (Map.Tileset.Table[tile]) { // Skip good tiles
++tile;
}
@ -224,7 +224,7 @@ void MapFixWallTile(const Vec2i &pos)
}
} else {
tile = Map.Tileset.OrcWallTable[tile];
if (UnitTypeOrcWall && mf->Value <= UnitTypeOrcWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
if (UnitTypeOrcWall && mf.Value <= UnitTypeOrcWall->DefaultStat.Variables[HP_INDEX].Max / 2) {
while (Map.Tileset.Table[tile]) { // Skip good tiles
++tile;
}
@ -233,7 +233,7 @@ void MapFixWallTile(const Vec2i &pos)
}
}
}
if (mf->Value == 0) {
if (mf.Value == 0) {
while (Map.Tileset.Table[tile]) { // Skip good tiles
++tile;
}
@ -243,11 +243,11 @@ void MapFixWallTile(const Vec2i &pos)
}
tile = Map.Tileset.Table[tile];
if (mf->Tile != tile) {
mf->Tile = tile;
if (mf.Tile != tile) {
mf.Tile = tile;
UI.Minimap.UpdateXY(pos);
if (Map.IsFieldVisible(*ThisPlayer, pos)) {
if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) {
UI.Minimap.UpdateSeenXY(pos);
Map.MarkSeenTile(pos);
}
@ -275,17 +275,17 @@ static void MapFixWallNeighbors(const Vec2i &pos)
*/
void CMap::RemoveWall(const Vec2i &pos)
{
CMapField *mf = Field(pos);
CMapField &mf = *Field(pos);
mf->Value = 0;
mf.Value = 0;
// FIXME: support more walls of different races.
mf->Flags &= ~(MapFieldHuman | MapFieldWall | MapFieldUnpassable);
mf.Flags &= ~(MapFieldHuman | MapFieldWall | MapFieldUnpassable);
UI.Minimap.UpdateXY(pos);
MapFixWallTile(pos);
MapFixWallNeighbors(pos);
if (Map.IsFieldVisible(*ThisPlayer, pos)) {
if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) {
UI.Minimap.UpdateSeenXY(pos);
this->MarkSeenTile(pos);
}
@ -301,26 +301,26 @@ void CMap::RemoveWall(const Vec2i &pos)
*/
void CMap::SetWall(const Vec2i &pos, int humanwall)
{
CMapField *mf = Field(pos);
CMapField &mf = *Field(pos);
// FIXME: support more walls of different races.
if (humanwall) {
// FIXME: Set random walls
mf->Tile = this->Tileset.Table[this->Tileset.HumanWallTable[0]];
mf->Flags |= MapFieldWall | MapFieldUnpassable | MapFieldHuman;
mf->Value = UnitTypeHumanWall->DefaultStat.Variables[HP_INDEX].Max;
mf.Tile = this->Tileset.Table[this->Tileset.HumanWallTable[0]];
mf.Flags |= MapFieldWall | MapFieldUnpassable | MapFieldHuman;
mf.Value = UnitTypeHumanWall->DefaultStat.Variables[HP_INDEX].Max;
} else {
// FIXME: Set random walls
mf->Tile = this->Tileset.Table[this->Tileset.OrcWallTable[0]];
mf->Flags |= MapFieldWall | MapFieldUnpassable;
mf->Value = UnitTypeOrcWall->DefaultStat.Variables[HP_INDEX].Max;
mf.Tile = this->Tileset.Table[this->Tileset.OrcWallTable[0]];
mf.Flags |= MapFieldWall | MapFieldUnpassable;
mf.Value = UnitTypeOrcWall->DefaultStat.Variables[HP_INDEX].Max;
}
UI.Minimap.UpdateXY(pos);
MapFixWallTile(pos);
MapFixWallNeighbors(pos);
if (Map.IsFieldVisible(*ThisPlayer, pos)) {
if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) {
UI.Minimap.UpdateSeenXY(pos);
this->MarkSeenTile(pos);
}

View file

@ -508,7 +508,7 @@ void CMinimap::Update()
visiontype = 2;
} else {
const Vec2i tilePos(Minimap2MapX[mx], Minimap2MapY[my] / Map.Info.MapWidth);
visiontype = Map.IsTileVisible(*ThisPlayer, tilePos);
visiontype = Map.Field(tilePos)->playerInfo.TeamVisibilityState(*ThisPlayer);
}
if (visiontype == 0 || (visiontype == 1 && ((mx & 1) != (my & 1)))) {

View file

@ -462,7 +462,7 @@ static int MissileVisibleInViewport(const CViewport &vp, const Missile &missile)
Vec2i pos;
for (pos.x = boxmin.x; pos.x <= boxmax.x; ++pos.x) {
for (pos.y = boxmin.y; pos.y <= boxmax.y; ++pos.y) {
if (ReplayRevealMap || Map.IsFieldVisible(*ThisPlayer, pos)) {
if (ReplayRevealMap || Map.Field(pos)->playerInfo.IsTeamVisible(*ThisPlayer)) {
return 1;
}
}

View file

@ -1877,7 +1877,7 @@ void UIHandleButtonUp(unsigned button)
// FIXME: johns: only complete invisibile units
const Vec2i cursorTilePos = UI.MouseViewport->ScreenToTilePos(CursorScreenPos);
CUnit *unit = NULL;
if (Map.IsFieldVisible(*ThisPlayer, cursorTilePos) || ReplayRevealMap) {
if (ReplayRevealMap || Map.Field(cursorTilePos)->playerInfo.IsTeamVisible(*ThisPlayer)) {
const PixelPos cursorMapPos = UI.MouseViewport->ScreenToMapPixelPos(CursorScreenPos);
unit = UnitOnScreen(cursorMapPos.x, cursorMapPos.y);

View file

@ -1621,8 +1621,7 @@ void UnitCountSeen(CUnit &unit)
newv++;
}
} else {
// Icky ugly code trick. With NoFogOfWar we haveto be > 0;
if (mf->playerInfo.Visible[p] > 1 - (Map.NoFogOfWar ? 1 : 0)) {
if (mf->playerInfo.IsVisible(Players[p])) {
newv++;
}
}