1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-13 11:40:38 +02:00

- linux fix for BuildingHandler

- #584 should be fixed

- first part of ally support:
-- shared FoW
-- function Callback::getPlayerRelations for team checking
This commit is contained in:
Ivan Savenko 2010-08-03 12:34:06 +00:00
parent 54496ddee1
commit 3c868146a6
11 changed files with 112 additions and 41 deletions

View File

@ -315,7 +315,7 @@ bool CCallback::verifyPath(CPath * path, bool blockSea) const
std::vector< std::vector< std::vector<unsigned char> > > & CCallback::getVisibilityMap() const
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return gs->players[player].fogOfWarMap;
return gs->getPlayerTeam(player)->fogOfWarMap;
}

View File

@ -157,13 +157,13 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSi
else
{
/* TODO: boost should have a nice method to do that. */
while(pos > 0 &&
text[pos] != ' ' &&
while(pos > 0 && text[pos]>' ')
/* text[pos] != ' ' &&
text[pos] != ',' &&
text[pos] != '.' &&
text[pos] != ';' &&
text[pos] != '!' &&
text[pos] != '?')
text[pos] != '?')*/
pos --;
}
if (pos > 0)

View File

@ -194,7 +194,7 @@ void RemoveObject::applyFirstCl( CClient *cl )
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
{
if(i->first >= PLAYER_LIMIT) continue;
if(GS(cl)->players[i->first].fogOfWarMap[pos.x][pos.y][pos.z])
if(GS(cl)->getPlayerTeam(i->first)->fogOfWarMap[pos.x][pos.y][pos.z])
{
i->second->objectRemoved(o);
}
@ -216,8 +216,9 @@ void TryMoveHero::applyFirstCl( CClient *cl )
{
if(i->first >= PLAYER_LIMIT)
continue;
PlayerState &p = GS(cl)->players[i->first];
if((p.fogOfWarMap[start.x-1][start.y][start.z] || p.fogOfWarMap[end.x-1][end.y][end.z]) && p.human)
TeamState *t = GS(cl)->getPlayerTeam(i->first);
if((t->fogOfWarMap[start.x-1][start.y][start.z] || t->fogOfWarMap[end.x-1][end.y][end.z])
&& GS(cl)->getPlayer(i->first)->human)
humanKnows = true;
}
@ -250,8 +251,8 @@ void TryMoveHero::applyCl( CClient *cl )
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
{
if(i->first >= PLAYER_LIMIT) continue;
PlayerState &p = GS(cl)->players[i->first];
if(p.fogOfWarMap[start.x-1][start.y][start.z] || p.fogOfWarMap[end.x-1][end.y][end.z])
TeamState *t = GS(cl)->getPlayerTeam(i->first);
if(t->fogOfWarMap[start.x-1][start.y][start.z] || t->fogOfWarMap[end.x-1][end.y][end.z])
{
i->second->heroMoved(*this);
}
@ -786,7 +787,7 @@ void NewObject::applyCl(CClient *cl)
{
//TODO: check if any covered tile is visible
if(i->first >= PLAYER_LIMIT) continue;
if(GS(cl)->players[i->first].fogOfWarMap[obj->pos.x][obj->pos.y][obj->pos.z])
if(GS(cl)->getPlayerTeam(i->first)->fogOfWarMap[obj->pos.x][obj->pos.y][obj->pos.z])
{
i->second->newObject(obj);
}

View File

@ -145,7 +145,7 @@ void CBuildingHandler::loadBuildings()
}
//loading ERMU to picture
std::ifstream etp("config/ERMU_to_picture.txt");
std::ifstream etp(DATA_DIR "/config/ERMU_to_picture.txt");
assert(etp.is_open());

View File

@ -435,9 +435,9 @@ void CGObjectInstance::getSightTiles(std::set<int3> &tiles) const //returns refe
}
void CGObjectInstance::hideTiles(int ourplayer, int radius) const
{
for (std::map<ui8, PlayerState>::iterator i = cb->gameState()->players.begin(); i != cb->gameState()->players.end(); i++)
for (std::map<ui8, TeamState>::iterator i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++)
{
if (ourplayer != i->first && i->second.status == PlayerState::INGAME) //TODO: team support
if ( !vstd::contains(i->second.players, ourplayer )/* && i->second.status == PlayerState::INGAME*/)
{
FoWChange fw;
fw.mode = 0;
@ -923,8 +923,7 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
if (ID == HEROI_TYPE) //hero
{
//TODO: check for allies
if(tempOwner == h->tempOwner) //our hero
if( cb->getPlayerRelations(tempOwner, h->tempOwner)) //our or ally hero
{
//exchange
cb->heroExchange(id, h->id);

View File

@ -1394,6 +1394,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
std::pair<int,PlayerState> ins(it->first,PlayerState());
ins.second.color=ins.first;
ins.second.human = it->second.human;
ins.second.team = map->players[ins.first].team;
teams[ins.second.team].players.insert(ins.first);
players.insert(ins);
}
@ -1608,8 +1610,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
}
}
/*************************FOG**OF**WAR******************************************/
for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
/*************************FOG**OF**WAR******************************************/
for(std::map<ui8, TeamState>::iterator k=teams.begin(); k!=teams.end(); ++k)
{
k->second.fogOfWarMap.resize(map->width);
for(int g=0; g<map->width; ++g)
@ -1626,7 +1628,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
BOOST_FOREACH(CGObjectInstance *obj, map->objects)
{
if(obj->tempOwner != k->first) continue; //not a flagged object
if( !vstd::contains(k->second.players, obj->tempOwner)) continue; //not a flagged object
std::set<int3> tiles;
obj->getSightTiles(tiles);
@ -1635,7 +1637,10 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
k->second.fogOfWarMap[tile.x][tile.y][tile.z] = 1;
}
}
}
for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
{
//starting bonus
if(si->playerInfos[k->first].bonus==PlayerSettings::brandom)
si->playerInfos[k->first].bonus = ran()%3;
@ -2225,6 +2230,28 @@ void CGameState::apply(CPack *pack)
applierGs->apps[typ]->applyOnGS(this,pack);
}
TeamState *CGameState::getTeam(ui8 teamID)
{
if(vstd::contains(teams,teamID))
{
return &teams[teamID];
}
else
{
tlog2 << "Warning: Cannot find info for team " << int(teamID) << std::endl;
return NULL;
}
}
TeamState *CGameState::getPlayerTeam(ui8 color)
{
PlayerState * ps = getPlayer(color);
if (ps)
return getTeam(ps->team);
return NULL;
}
PlayerState * CGameState::getPlayer( ui8 color, bool verbose )
{
if(vstd::contains(players,color))
@ -2244,6 +2271,17 @@ const PlayerState * CGameState::getPlayer( ui8 color, bool verbose ) const
return (const_cast<CGameState *>(this))->getPlayer(color, verbose);
}
const TeamState * CGameState::getTeam( ui8 teamID ) const
{
return (const_cast<CGameState *>(this))->getTeam(teamID);
}
const TeamState * CGameState::getPlayerTeam( ui8 teamID ) const
{
return (const_cast<CGameState *>(this))->getPlayerTeam(teamID);
}
bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)
{
if(!map->isInTheMap(src) || !map->isInTheMap(dest)) //check input
@ -2261,7 +2299,7 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
// else
// blockLandSea = boost::logic::indeterminate;
const std::vector<std::vector<std::vector<ui8> > > &FoW = getPlayer(hero->tempOwner)->fogOfWarMap;
const std::vector<std::vector<std::vector<ui8> > > &FoW = getPlayerTeam(hero->tempOwner)->fogOfWarMap;
//graph initialization
std::vector< std::vector<CPathNode> > graph;
@ -2407,7 +2445,7 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
else
onLand = boost::logic::indeterminate;
const std::vector<std::vector<std::vector<ui8> > > &FoW = getPlayer(hero->tempOwner)->fogOfWarMap;
const std::vector<std::vector<std::vector<ui8> > > &FoW = getPlayerTeam(hero->tempOwner)->fogOfWarMap;
bool flying = hero->hasBonusOfType(Bonus::FLYING_MOVEMENT);
bool waterWalk = hero->hasBonusOfType(Bonus::WATER_WALKING);
@ -2654,7 +2692,7 @@ bool CGameState::isVisible(int3 pos, int player)
{
if(player == 255) //neutral player
return false;
return players[player].fogOfWarMap[pos.x][pos.y][pos.z];
return getPlayerTeam(player)->fogOfWarMap[pos.x][pos.y][pos.z];
}
bool CGameState::isVisible( const CGObjectInstance *obj, int player )
@ -3434,9 +3472,9 @@ ui8 CGameState::checkForStandardWin() const
{
//first player remaining ingame - candidate for victory
supposedWinner = i->second.color;
winnerTeam = map->players[supposedWinner].team;
winnerTeam = i->second.team;
}
else if(winnerTeam != map->players[i->second.color].team)
else if(winnerTeam != i->second.team)
{
//current candidate has enemy remaining in game -> no vicotry
return 255;

View File

@ -120,7 +120,8 @@ public:
ui8 color;
ui8 human; //true if human controlled player, false for AI
ui32 currentSelection; //id of hero/town, 0xffffffff if none
std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden
ui8 team;
//std::vector<std::vector<std::vector<ui8> > > * fogOfWarMap; //pointer to team's fog of war
std::vector<si32> resources;
std::vector<CGHeroInstance *> heroes;
std::vector<CGTownInstance *> towns;
@ -139,13 +140,29 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & color & human & currentSelection & fogOfWarMap & resources & status;
h & color & human & currentSelection & team & resources & status;
h & heroes & towns & availableHeroes & dwellings & bonuses & status & daysWithoutCastle;
h & enteredLosingCheatCode & enteredWinningCheatCode;
h & static_cast<CBonusSystemNode&>(*this);
}
};
struct DLL_EXPORT TeamState : public CBonusSystemNode
{
public:
std::set<ui8> players; // members of this team
std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden
//TeamState();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & players & fogOfWarMap;
h & static_cast<CBonusSystemNode&>(*this);
}
};
struct DLL_EXPORT CObstacleInstance
{
int uniqueID;
@ -384,6 +401,7 @@ public:
ui32 day; //total number of days in game
Mapa * map;
std::map<ui8, PlayerState> players; //ID <-> player state
std::map<ui8, TeamState> teams; //ID <-> team state
std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
CBonusSystemNode globalEffects;
@ -402,7 +420,11 @@ public:
boost::shared_mutex *mx;
PlayerState *getPlayer(ui8 color, bool verbose = true);
TeamState *getTeam(ui8 teamID);//get team by team ID
TeamState *getPlayerTeam(ui8 color);// get team by player color
const PlayerState *getPlayer(ui8 color, bool verbose = true) const;
const TeamState *getTeam(ui8 teamID) const;
const TeamState *getPlayerTeam(ui8 color) const;
void init(StartInfo * si, ui32 checksum, int Seed);
void loadTownDInfos();
void randomizeObject(CGObjectInstance *cur);

View File

@ -107,7 +107,7 @@ void IGameCallback::getTilesInRange( std::set<int3> &tiles, int3 pos, int radiou
getAllTiles (tiles, player, -1, 0);
else
{
PlayerState * plr = &gs->players.find(player)->second;
const TeamState * team = gs->getPlayerTeam(player);
for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, gs->map->width - 1); xd++)
{
for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>(pos.y + radious, gs->map->height - 1); yd++)
@ -116,8 +116,8 @@ void IGameCallback::getTilesInRange( std::set<int3> &tiles, int3 pos, int radiou
if(distance <= radious)
{
if(player < 0
|| (mode == 1 && plr->fogOfWarMap[xd][yd][pos.z]==0)
|| (mode == -1 && plr->fogOfWarMap[xd][yd][pos.z]==1)
|| (mode == 1 && team->fogOfWarMap[xd][yd][pos.z]==0)
|| (mode == -1 && team->fogOfWarMap[xd][yd][pos.z]==1)
)
tiles.insert(int3(xd,yd,pos.z));
}
@ -239,6 +239,18 @@ const PlayerState * IGameCallback::getPlayerState( int color )
return gs->getPlayer(color, false);
}
int IGameCallback::getPlayerRelations( ui8 color1, ui8 color2 )
{
if ( color1 == color2 )
return 2;
if ( color1 == 255 || color2 == 255)
return 0;
const TeamState * ts = gs->getPlayerTeam(color1);
if (ts && vstd::contains(ts->players, color2))
return 1;
return 0;
}
const CTown * IGameCallback::getNativeTown(int color)
{
return &VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(color).castle];

View File

@ -68,6 +68,7 @@ public:
virtual int3 getMapSize(); //returns size of the map
virtual TerrainTile * getTile(int3 pos);
virtual const PlayerState * getPlayerState(int color);
virtual int getPlayerRelations(ui8 color1, ui8 color2);// -1 = enemy, 0 = neutral, 1 = ally, 2 = same player
virtual const CTown *getNativeTown(int color);
//do sth

View File

@ -143,14 +143,15 @@ DLL_EXPORT void SetMovePoints::applyGs( CGameState *gs )
DLL_EXPORT void FoWChange::applyGs( CGameState *gs )
{
BOOST_FOREACH(int3 t, tiles)
gs->getPlayer(player)->fogOfWarMap[t.x][t.y][t.z] = mode;
TeamState * team = gs->getPlayerTeam(player);
BOOST_FOREACH(int3 t, tiles)
team->fogOfWarMap[t.x][t.y][t.z] = mode;
if (mode == 0) //do not hide too much
{
std::set<int3> tilesRevealed;
for (size_t i = 0; i < gs->map->objects.size(); i++)
{
if(gs->map->objects[i] && gs->map->objects[i]->tempOwner == player) //check owned observators
if (gs->map->objects[i])
{
switch(gs->map->objects[i]->ID)
{
@ -158,13 +159,14 @@ DLL_EXPORT void FoWChange::applyGs( CGameState *gs )
case 53://mine
case 98://town
case 220:
gs->map->objects[i]->getSightTiles(tilesRevealed);
if(vstd::contains(team->players, player)) //check owned observators
gs->map->objects[i]->getSightTiles(tilesRevealed);
break;
}
}
}
BOOST_FOREACH(int3 t, tilesRevealed) //probably not the most optimal solution ever
gs->getPlayer(player)->fogOfWarMap[t.x][t.y][t.z] = 1;
team->fogOfWarMap[t.x][t.y][t.z] = 1;
}
}
DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
@ -377,7 +379,7 @@ void TryMoveHero::applyGs( CGameState *gs )
}
BOOST_FOREACH(int3 t, fowRevealed)
gs->getPlayer(h->getOwner())->fogOfWarMap[t.x][t.y][t.z] = 1;
gs->getPlayerTeam(h->getOwner())->fogOfWarMap[t.x][t.y][t.z] = 1;
}
DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )

View File

@ -1888,12 +1888,11 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
{
CGHeroInstance *dh = static_cast<CGHeroInstance *>(obj);
if(obj->tempOwner==h->tempOwner)
if( getPlayerRelations(dh->tempOwner, h->tempOwner))
{
heroExchange(dh->id, h->id);
return true;
}
//TODO: check for ally
startBattleI(h, dh);
return true;
}
@ -3357,10 +3356,8 @@ bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance
}
if (!army)
COMPLAIN_RET("Incorrect call to transform in undead!");
tlog1<<"test2\n";
if(!vstd::contains(army->Slots(), slot))
COMPLAIN_RET("Army doesn't have any creature in that slot!");
tlog1<<"test3\n";
const CStackInstance &s = army->getStack(slot);
int resCreature;//resulting creature - bone dragons or skeletons
@ -3368,7 +3365,6 @@ bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance
resCreature = 68;
else
resCreature = 56;
tlog1<<"test4\n";
SetGarrisons sg;
sg.garrs[army->id] = army->getArmy();
sg.garrs[army->id].setCreature(slot, resCreature, s.count);
@ -3913,7 +3909,7 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
for(int i=0;i<gs->map->width;i++)
for(int j=0;j<gs->map->height;j++)
for(int k=0;k<gs->map->twoLevel+1;k++)
if(!gs->getPlayer(fc.player)->fogOfWarMap[i][j][k])
if(!gs->getPlayerTeam(fc.player)->fogOfWarMap[i][j][k])
fc.tiles.insert(int3(i,j,k));
sendAndApply(&fc);
}