Split CMapField into CMapFieldPlayerInfo with stuff related to player "knowledge".

This commit is contained in:
Joris 2012-09-06 16:06:39 +02:00
parent 6e64f99ecc
commit 1bfedc3116
9 changed files with 98 additions and 94 deletions

View file

@ -854,16 +854,16 @@ void CommandSharedVision(int player, bool state, int opponent)
Vec2i pos;
for (pos.x = 0; pos.x < Map.Info.MapWidth; ++pos.x) {
for (pos.y = 0; pos.y < Map.Info.MapHeight; ++pos.y) {
CMapField &mf = *Map.Field(pos);
CMapFieldPlayerInfo &mfp = Map.Field(pos)->playerInfo;
if (mf.Visible[player] && !mf.Visible[opponent]) {
mf.Visible[opponent] = 1;
if (mfp.Visible[player] && !mfp.Visible[opponent]) {
mfp.Visible[opponent] = 1;
if (opponent == ThisPlayer->Index) {
Map.MarkSeenTile(pos);
}
}
if (mf.Visible[opponent] && !mf.Visible[player]) {
mf.Visible[player] = 1;
if (mfp.Visible[opponent] && !mfp.Visible[player]) {
mfp.Visible[player] = 1;
if (player == ThisPlayer->Index) {
Map.MarkSeenTile(pos);
}

View file

@ -37,6 +37,30 @@
-- Documentation
----------------------------------------------------------------------------*/
/**
** @class CMapField tile.h
**
** \#include "tile.h"
*
** CMapFieldPlayerInfo::Visible[]
**
** Counter how many units of the player can see this field. 0 the
** field is not explored, 1 explored, n-1 unit see it. Currently
** no more than 253 units can see a field.
**
** CMapFieldPlayerInfo::VisCloak[]
**
** Visiblity for cloaking.
**
** CMapFieldPlayerInfo::Radar[]
**
** Visiblity for radar.
**
** CMapFieldPlayerInfo::RadarJammer[]
**
** Jamming capabilities.
*/
/**
** @class CMapField tile.h
**
@ -68,11 +92,9 @@
**
** ::MapFieldVisible field is visible.
** ::MapFieldExplored field is explored.
** ::MapFieldHuman human player is the owner of the field used for
** walls.
** ::MapFieldHuman human player is the owner of the field used for walls.
** ::MapFieldLandAllowed land units are allowed.
** ::MapFieldCoastAllowed coast units (transporter) and coast
** buildings (shipyard) are allowed.
** ::MapFieldCoastAllowed coast units (transporter) and coast buildings (shipyard) are allowed.
** ::MapFieldWaterAllowed water units allowed.
** ::MapFieldNoBuilding no buildings allowed.
** ::MapFieldUnpassable field is movement blocked.
@ -97,24 +119,6 @@
** walls, contains the remaining hit points of the wall and
** for forest, contains the frames until they grow.
**
** CMapField::Visible[]
**
** Counter how many units of the player can see this field. 0 the
** field is not explored, 1 explored, n-1 unit see it. Currently
** no more than 253 units can see a field.
**
** CMapField::VisCloak[]
**
** Visiblity for cloaking.
**
** CMapField::Radar[]
**
** Visiblity for radar.
**
** CMapField::RadarJammer[]
**
** Jamming capabilities.
**
** CMapField::UnitCache
**
** Contains a vector of all units currently on this field.
@ -137,15 +141,10 @@
-- Map - field
----------------------------------------------------------------------------*/
/// Describes a field of the map
class CMapField
class CMapFieldPlayerInfo
{
public:
CMapField() : Tile(0), SeenTile(0), Flags(0), Cost(0), Value(0), UnitCache()
#ifdef DEBUG
, TilesetTile(0)
#endif
CMapFieldPlayerInfo()
{
memset(Visible, 0, sizeof(Visible));
memset(VisCloak, 0, sizeof(VisCloak));
@ -153,30 +152,43 @@ public:
memset(RadarJammer, 0, sizeof(RadarJammer));
}
unsigned short Tile; /// graphic tile number
unsigned short SeenTile; /// last seen tile (FOW)
unsigned short Flags; /// field flags
unsigned char Cost; /// unit cost to move in this tile
// FIXME: Value can be removed, walls and regeneration can be handled
// different.
unsigned char Value; /// HP for walls/ Wood Regeneration
/// Check if a field for the user is explored.
bool IsExplored(unsigned int player_index) const {
return Visible[player_index] != 0;
}
public:
unsigned short Visible[PlayerMax]; /// Seen counter 0 unexplored
unsigned char VisCloak[PlayerMax]; /// Visiblity for cloaking.
unsigned char Radar[PlayerMax]; /// Visiblity for radar.
unsigned char RadarJammer[PlayerMax]; /// Jamming capabilities.
CUnitCache UnitCache; /// A unit on the map field.
#ifdef DEBUG
unsigned int TilesetTile; /// tileset tile number
#endif
/// Check if a field for the user is explored.
bool IsExplored(const unsigned int player_index) const {
return !!Visible[player_index];
};
};
/// Describes a field of the map
class CMapField
{
public:
CMapField() : Tile(0), SeenTile(0), Flags(0), Cost(0), Value(0), UnitCache()
#ifdef DEBUG
, TilesetTile(0)
#endif
{}
unsigned short Tile; /// graphic tile number
unsigned short SeenTile; /// last seen tile (FOW)
unsigned short Flags; /// field flags
unsigned char Cost; /// unit cost to move in this tile
// FIXME: Value should be removed, walls and regeneration can be handled differently.
unsigned char Value; /// HP for walls/ Wood Regeneration
CUnitCache UnitCache; /// A unit on the map field.
#ifdef DEBUG
unsigned int TilesetTile; /// tileset tile number
#endif
CMapFieldPlayerInfo playerInfo; /// stuff related to player
};
//@}
#endif // !__MAP_TILE_H__

View file

@ -135,10 +135,9 @@ void CMap::Reveal()
Vec2i pos;
for (pos.x = 0; pos.x < this->Info.MapWidth; ++pos.x) {
for (pos.y = 0; pos.y < this->Info.MapHeight; ++pos.y) {
CMapFieldPlayerInfo& playerInfo = this->Field(pos)->playerInfo;
for (int p = 0; p < PlayerMax; ++p) {
if (!this->Field(pos)->Visible[p]) {
this->Field(pos)->Visible[p] = 1;
}
playerInfo.Visible[p] = std::max<unsigned short>(1, playerInfo.Visible[p]);
}
MarkSeenTile(pos);
}
@ -203,8 +202,8 @@ bool CMap::IsTerrainResourceOnMap(const Vec2i &pos) const
unsigned short CMap::IsTileVisible(const CPlayer &player, const unsigned int index) const
{
const CMapField &mf = this->Fields[index];
unsigned short visiontype = mf.Visible[player.Index];
const CMapFieldPlayerInfo &mfp = this->Fields[index].playerInfo;
unsigned short visiontype = mfp.Visible[player.Index];
if (visiontype > 1) {
return visiontype;
@ -212,10 +211,10 @@ unsigned short CMap::IsTileVisible(const CPlayer &player, const unsigned int ind
if (player.IsVisionSharing()) {
for (int i = 0; i < PlayerMax ; ++i) {
if (player.IsBothSharedVision(Players[i])) {
if (mf.Visible[i] > 1) {
if (mfp.Visible[i] > 1) {
return 2;
}
visiontype |= mf.Visible[i];
visiontype |= mfp.Visible[i];
}
}
}
@ -227,7 +226,7 @@ unsigned short CMap::IsTileVisible(const CPlayer &player, const unsigned int ind
bool CMap::IsFieldExplored(const CPlayer &player, const unsigned int index) const
{
return this->Fields[index].IsExplored(player.Index);
return this->Fields[index].playerInfo.IsExplored(player.Index);
}

View file

@ -133,7 +133,7 @@ int MapFogFilterFlags(CPlayer &player, const Vec2i &pos, int mask)
void MapMarkTileSight(const CPlayer &player, const unsigned int index)
{
//v = &Map.Field(x, y)->Visible[player.Index];
unsigned short *v = &(Map.Field(index)->Visible[player.Index]);
unsigned short *v = &(Map.Field(index)->playerInfo.Visible[player.Index]);
if (*v == 0 || *v == 1) { // Unexplored or unseen
// When there is no fog only unexplored tiles are marked.
if (!Map.NoFogOfWar || *v == 0) {
@ -165,7 +165,7 @@ void MapMarkTileSight(const CPlayer &player, const Vec2i &pos)
*/
void MapUnmarkTileSight(const CPlayer &player, const unsigned int index)
{
unsigned short *v = &(Map.Field(index)->Visible[player.Index]);
unsigned short *v = &(Map.Field(index)->playerInfo.Visible[player.Index]);
switch (*v) {
case 0: // Unexplored
case 1:
@ -202,7 +202,7 @@ void MapUnmarkTileSight(const CPlayer &player, const Vec2i &pos)
*/
void MapMarkTileDetectCloak(const CPlayer &player, const unsigned int index)
{
unsigned char *v = &(Map.Field(index)->VisCloak[player.Index]);
unsigned char *v = &(Map.Field(index)->playerInfo.VisCloak[player.Index]);
if (*v == 0) {
UnitsOnTileMarkSeen(player, index, 1);
}
@ -226,7 +226,7 @@ void MapMarkTileDetectCloak(const CPlayer &player, const Vec2i &pos)
void
MapUnmarkTileDetectCloak(const CPlayer &player, const unsigned int index)
{
unsigned char *v = &(Map.Field(index)->VisCloak[player.Index]);
unsigned char *v = &(Map.Field(index)->playerInfo.VisCloak[player.Index]);
Assert(*v != 0);
if (*v == 1) {
UnitsOnTileUnmarkSeen(player, index, 1);

View file

@ -47,16 +47,16 @@
----------------------------------------------------------------------------*/
static inline unsigned char
IsTileRadarVisible(const CPlayer &pradar, const CPlayer &punit, const CMapField &mf)
IsTileRadarVisible(const CPlayer &pradar, const CPlayer &punit, const CMapFieldPlayerInfo &mfp)
{
if (mf.RadarJammer[punit.Index]) {
if (mfp.RadarJammer[punit.Index]) {
return 0;
}
int p = pradar.Index;
if (pradar.IsVisionSharing()) {
const unsigned char *const radar = mf.Radar;
const unsigned char *const jamming = mf.RadarJammer;
const unsigned char *const radar = mfp.Radar;
const unsigned char *const jamming = mfp.RadarJammer;
unsigned char radarvision = 0;
// Check jamming first, if we are jammed, exit
for (int i = 0; i < PlayerMax; ++i) {
@ -71,9 +71,9 @@ IsTileRadarVisible(const CPlayer &pradar, const CPlayer &punit, const CMapField
}
}
// Can't exit until the end, as we might be jammed
return (radarvision | mf.Radar[p]);
return (radarvision | mfp.Radar[p]);
}
return mf.Radar[p];
return mfp.Radar[p];
}
@ -86,7 +86,7 @@ bool CUnit::IsVisibleOnRadar(const CPlayer &pradar) const
const CMapField *mf = Map.Field(index);
int i = x_max;
do {
if (IsTileRadarVisible(pradar, *Player, *mf) != 0) {
if (IsTileRadarVisible(pradar, *Player, mf->playerInfo) != 0) {
return true;
}
++mf;
@ -108,8 +108,8 @@ bool CUnit::IsVisibleOnRadar(const CPlayer &pradar) const
*/
void MapMarkTileRadar(const CPlayer &player, const unsigned int index)
{
Assert(Map.Field(index)->Radar[player.Index] != 255);
Map.Field(index)->Radar[player.Index]++;
Assert(Map.Field(index)->playerInfo.Radar[player.Index] != 255);
Map.Field(index)->playerInfo.Radar[player.Index]++;
}
void MapMarkTileRadar(const CPlayer &player, int x, int y)
@ -129,7 +129,7 @@ void MapMarkTileRadar(const CPlayer &player, int x, int y)
void MapUnmarkTileRadar(const CPlayer &player, const unsigned int index)
{
// Reduce radar coverage if it exists.
unsigned char *v = &(Map.Field(index)->Radar[player.Index]);
unsigned char *v = &(Map.Field(index)->playerInfo.Radar[player.Index]);
if (*v) {
--*v;
}
@ -151,8 +151,8 @@ void MapUnmarkTileRadar(const CPlayer &player, int x, int y)
*/
void MapMarkTileRadarJammer(const CPlayer &player, const unsigned int index)
{
Assert(Map.Field(index)->RadarJammer[player.Index] != 255);
Map.Field(index)->RadarJammer[player.Index]++;
Assert(Map.Field(index)->playerInfo.RadarJammer[player.Index] != 255);
Map.Field(index)->playerInfo.RadarJammer[player.Index]++;
}
void MapMarkTileRadarJammer(const CPlayer &player, int x, int y)
@ -171,7 +171,7 @@ void MapMarkTileRadarJammer(const CPlayer &player, int x, int y)
void MapUnmarkTileRadarJammer(const CPlayer &player, const unsigned int index)
{
// Reduce radar coverage if it exists.
unsigned char *v = &(Map.Field(index)->RadarJammer[player.Index]);
unsigned char *v = &(Map.Field(index)->playerInfo.RadarJammer[player.Index]);
if (*v) {
--*v;
}

View file

@ -79,7 +79,7 @@ void CMap::Save(CFile &file) const
file.printf(" {%3d, %3d, %2d, %2d,", mf.Tile, mf.SeenTile, mf.Value, mf.Cost);
for (int i = 0; i < PlayerMax; ++i) {
if (mf.Visible[i] == 1) {
if (mf.playerInfo.Visible[i] == 1) {
file.printf(" \"explored\", %d,", i);
}
}

View file

@ -110,30 +110,23 @@ static int CclStratagusMap(lua_State *l)
Map.Info.Filename = LuaToString(l, -1);
lua_pop(l, 1);
} else if (!strcmp(value, "map-fields")) {
int i;
int subsubargs;
int subk;
lua_rawgeti(l, j + 1, k + 1);
if (!lua_istable(l, -1)) {
LuaError(l, "incorrect argument");
}
subsubargs = lua_rawlen(l, -1);
const int subsubargs = lua_rawlen(l, -1);
if (subsubargs != Map.Info.MapWidth * Map.Info.MapHeight) {
fprintf(stderr, "Wrong tile table length: %d\n", subsubargs);
}
i = 0;
for (subk = 0; subk < subsubargs; ++subk) {
int args2;
int j2;
int i = 0;
for (int subk = 0; subk < subsubargs; ++subk) {
lua_rawgeti(l, -1, subk + 1);
if (!lua_istable(l, -1)) {
LuaError(l, "incorrect argument");
}
args2 = lua_rawlen(l, -1);
j2 = 0;
int args2 = lua_rawlen(l, -1);
int j2 = 0;
lua_rawgeti(l, -1, j2 + 1);
Map.Fields[i].Tile = LuaToNumber(l, -1);
@ -158,7 +151,7 @@ static int CclStratagusMap(lua_State *l)
if (!strcmp(value, "explored")) {
++j2;
lua_rawgeti(l, -1, j2 + 1);
Map.Fields[i].Visible[(int)LuaToNumber(l, -1)] = 1;
Map.Fields[i].playerInfo.Visible[LuaToNumber(l, -1)] = 1;
lua_pop(l, 1);
} else if (!strcmp(value, "human")) {
Map.Fields[i].Flags |= MapFieldHuman;

View file

@ -525,7 +525,7 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
int i = w;
do {
const int flag = mf->Flags & mask;
if (flag && (AStarKnowUnseenTerrain || mf->IsExplored(player_index))) {
if (flag && (AStarKnowUnseenTerrain || mf->playerInfo.IsExplored(player_index))) {
if (flag & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit)) {
// we can't cross fixed units and other unpassable things
return -1;
@ -549,7 +549,7 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
}
}
// Add cost of crossing unknown tiles if required
if (!AStarKnowUnseenTerrain && !mf->IsExplored(player_index)) {
if (!AStarKnowUnseenTerrain && !mf->playerInfo.IsExplored(player_index)) {
// Tend against unknown tiles.
cost += AStarUnknownTerrainCost;
}

View file

@ -1617,12 +1617,12 @@ void UnitCountSeen(CUnit &unit)
int x = width;
do {
if (unit.Type->PermanentCloak && unit.Player != &Players[p]) {
if (mf->VisCloak[p]) {
if (mf->playerInfo.VisCloak[p]) {
newv++;
}
} else {
// Icky ugly code trick. With NoFogOfWar we haveto be > 0;
if (mf->Visible[p] > 1 - (Map.NoFogOfWar ? 1 : 0)) {
if (mf->playerInfo.Visible[p] > 1 - (Map.NoFogOfWar ? 1 : 0)) {
newv++;
}
}