Split CMapField into CMapFieldPlayerInfo with stuff related to player "knowledge".
This commit is contained in:
parent
6e64f99ecc
commit
1bfedc3116
9 changed files with 98 additions and 94 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue