1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-29 21:56:54 +02:00

- University fix for #594

- Ally support:
- - fix for non-continuous players (notes to rev 1736)
- - objects visiting and shared puzzle map
This commit is contained in:
Ivan Savenko 2010-08-06 13:14:10 +00:00
parent ec5fa1dc22
commit bdcdc89991
8 changed files with 76 additions and 39 deletions

View File

@ -923,7 +923,7 @@ int3 CCallback::getGrailPos( float &outKnownRatio )
} }
else else
{ {
outKnownRatio = (float)CGObelisk::visited[player] / CGObelisk::obeliskCount; outKnownRatio = (float)CGObelisk::visited[gs->getPlayerTeam(player)->id] / CGObelisk::obeliskCount;
} }
return gs->map->grailPos; return gs->map->grailPos;
} }

View File

@ -5978,7 +5978,7 @@ int CUniversityWindow::CItem::state()
void CUniversityWindow::CItem::showAll(SDL_Surface * to) void CUniversityWindow::CItem::showAll(SDL_Surface * to)
{ {
SDL_Surface * bar; CPicture * bar;
switch (state()) switch (state())
{ {
case 0: bar = parent->red; case 0: bar = parent->red;
@ -5989,8 +5989,8 @@ void CUniversityWindow::CItem::showAll(SDL_Surface * to)
break; break;
} }
blitAtLoc(bar, -28, -22, to); blitAtLoc(bar->bg, -28, -22, to);
blitAtLoc(bar, -28, 48, to); blitAtLoc(bar->bg, -28, 48, to);
printAtMiddleLoc (CGI->generaltexth->skillName[ID], 22, -13, FONT_SMALL, zwykly,to);//Name printAtMiddleLoc (CGI->generaltexth->skillName[ID], 22, -13, FONT_SMALL, zwykly,to);//Name
printAtMiddleLoc (CGI->generaltexth->levels[0], 22, 57, FONT_SMALL, zwykly,to);//Level(always basic) printAtMiddleLoc (CGI->generaltexth->levels[0], 22, 57, FONT_SMALL, zwykly,to);//Level(always basic)
@ -6009,9 +6009,13 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
bg = new CPicture("UNIVERS1.PCX"); bg = new CPicture("UNIVERS1.PCX");
bg->colorizeAndConvert(LOCPLINT->playerID); bg->colorizeAndConvert(LOCPLINT->playerID);
yellow = BitmapHandler::loadBitmap("UNIVGOLD.PCX"); green = new CPicture("UNIVGREN.PCX");
green = BitmapHandler::loadBitmap("UNIVGREN.PCX");//bars yellow = new CPicture("UNIVGOLD.PCX");//bars
red = BitmapHandler::loadBitmap("UNIVRED.PCX"); red = new CPicture("UNIVRED.PCX");
green->recActions =
yellow->recActions =
red->recActions = DISPOSE;
if ( market->o->ID == 104 ) // this is adventure map university if ( market->o->ID == 104 ) // this is adventure map university
{ {
@ -6045,9 +6049,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
CUniversityWindow::~CUniversityWindow() CUniversityWindow::~CUniversityWindow()
{ {
delete red;
delete yellow;
delete green;
} }
CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available ):parent(PARENT) CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available ):parent(PARENT)

View File

@ -1103,9 +1103,7 @@ public:
const CGHeroInstance *hero; const CGHeroInstance *hero;
const IMarket * market; const IMarket * market;
SDL_Surface * red, CPicture * green, * yellow, * red;//colored bars near skills
* green,//colored bars near skills
* yellow;
CPicture *bg; //background CPicture *bg; //background
std::vector<CItem*> items; std::vector<CItem*> items;

View File

@ -437,13 +437,18 @@ void CGObjectInstance::hideTiles(int ourplayer, int radius) const
{ {
for (std::map<ui8, TeamState>::iterator i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++) for (std::map<ui8, TeamState>::iterator i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++)
{ {
if ( !vstd::contains(i->second.players, ourplayer )/* && i->second.status == PlayerState::INGAME*/) if ( !vstd::contains(i->second.players, ourplayer ))//another team
{ {
FoWChange fw; for (std::set<ui8>::iterator j = i->second.players.begin(); j != i->second.players.end(); j++)
fw.mode = 0; if ( cb->getPlayerState(*j)->status == PlayerState::INGAME )//seek for living player (if any)
fw.player = i->first; {
cb->getTilesInRange (fw.tiles, pos, radius, i->first, -1); FoWChange fw;
cb->sendAndApply (&fw); fw.mode = 0;
fw.player = i->first;
cb->getTilesInRange (fw.tiles, pos, radius, (*j), -1);
cb->sendAndApply (&fw);
break;
}
} }
} }
} }
@ -1659,7 +1664,12 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
return; return;
} }
if(h->tempOwner != tempOwner && stacksCount() > 0) //object is guarded int relations = cb->getPlayerRelations( h->tempOwner, tempOwner );
if ( relations == 1 )//ally
return;//do not allow recruiting or capturing
if( !relations && stacksCount() > 0) //object is guarded, owned by enemy
{ {
BlockingDialog bd; BlockingDialog bd;
bd.player = h->tempOwner; bd.player = h->tempOwner;
@ -1672,7 +1682,7 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
return; return;
} }
if(h->tempOwner != tempOwner && ID != 106) if(!relations && ID != 106)
{ {
cb->setOwner(id, h->tempOwner); cb->setOwner(id, h->tempOwner);
} }
@ -2037,9 +2047,8 @@ bool CGTownInstance::needsLastStack() const
void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
{ {
if(getOwner() != h->getOwner()) if( !cb->getPlayerRelations( getOwner(), h->getOwner() ))//if this is enemy
{ {
//TODO ally check
if(stacksCount() > 0 || visitingHero) if(stacksCount() > 0 || visitingHero)
{ {
const CGHeroInstance *defendingHero = NULL; const CGHeroInstance *defendingHero = NULL;
@ -2188,7 +2197,17 @@ int3 CGTownInstance::getSightCenter() const
ui8 CGTownInstance::getPassableness() const ui8 CGTownInstance::getPassableness() const
{ {
return stacksCount() ? 1<<tempOwner : ALL_PLAYERS; //if there is garrison army, castle be entered only by owner //TODO: allies if ( !stacksCount() )//empty castle - anyone can visit
return ALL_PLAYERS;
if ( tempOwner == 255 )//neutral guarded - noone can visit
return 0;
ui8 mask;
TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
BOOST_FOREACH(ui8 it, ts->players)
mask |= 1<<it;//allies - add to possible visitors
return mask;
} }
void CGTownInstance::getOutOffsets( std::vector<int3> &offsets ) const void CGTownInstance::getOutOffsets( std::vector<int3> &offsets ) const
@ -3099,23 +3118,25 @@ void CGCreature::flee( const CGHeroInstance * h ) const
void CGMine::onHeroVisit( const CGHeroInstance * h ) const void CGMine::onHeroVisit( const CGHeroInstance * h ) const
{ {
if(h->tempOwner == tempOwner) //we're visiting our mine int relations = cb->getPlayerRelations(h->tempOwner, tempOwner);
if(relations == 2) //we're visiting our mine
{ {
cb->showGarrisonDialog(id,h->id,true,0); cb->showGarrisonDialog(id,h->id,true,0);
return; return;
} }
else if (relations == 1)//ally
return;
if(subID >= 7) //Abandoned mine if(stacksCount()) //Mine is guarded
{ {
BlockingDialog ynd(true,false); BlockingDialog ynd(true,false);
ynd.player = h->tempOwner; ynd.player = h->tempOwner;
ynd.text << std::pair<ui8,ui32>(MetaString::ADVOB_TXT, 84); ynd.text << std::pair<ui8,ui32>(MetaString::ADVOB_TXT, subID == 7 ? 84 : 187);
cb->showBlockingDialog(&ynd,boost::bind(&CGMine::fight, this, _1, h)); cb->showBlockingDialog(&ynd,boost::bind(&CGMine::fight, this, _1, h));
return; return;
} }
//TODO: check if mine is guarded
flagMine(h->tempOwner); flagMine(h->tempOwner);
} }
@ -5239,14 +5260,15 @@ void CGScholar::initObj()
void CGGarrison::onHeroVisit (const CGHeroInstance *h) const void CGGarrison::onHeroVisit (const CGHeroInstance *h) const
{ {
if (h->tempOwner != tempOwner && stacksCount() > 0) { int ally = cb->getPlayerRelations(h->tempOwner, tempOwner);
if (!ally && stacksCount() > 0) {
//TODO: Find a way to apply magic garrison effects in battle. //TODO: Find a way to apply magic garrison effects in battle.
cb->startBattleI(h, this, boost::bind(&CGGarrison::fightOver, this, h, _1)); cb->startBattleI(h, this, boost::bind(&CGGarrison::fightOver, this, h, _1));
return; return;
} }
//New owner. //New owner.
if (h->tempOwner != tempOwner) if (!ally)
cb->setOwner(id, h->tempOwner); cb->setOwner(id, h->tempOwner);
cb->showGarrisonDialog(id, h->id, removableUnits, 0); cb->showGarrisonDialog(id, h->id, removableUnits, 0);
@ -5260,7 +5282,17 @@ void CGGarrison::fightOver (const CGHeroInstance *h, BattleResult *result) const
ui8 CGGarrison::getPassableness() const ui8 CGGarrison::getPassableness() const
{ {
return 1<<tempOwner; if ( !stacksCount() )//empty - anyone can visit
return ALL_PLAYERS;
if ( tempOwner == 255 )//neutral guarded - noone can visit
return 0;
ui8 mask;
TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
BOOST_FOREACH(ui8 it, ts->players)
mask |= 1<<it;//allies - add to possible visitors
return mask;
} }
void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
@ -6247,7 +6279,7 @@ void CGShipyard::getOutOffsets( std::vector<int3> &offsets ) const
void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const
{ {
if(tempOwner != h->tempOwner) if(!cb->getPlayerRelations(tempOwner, h->tempOwner))
cb->setOwner(id, h->tempOwner); cb->setOwner(id, h->tempOwner);
int s = state(); int s = state();
@ -6341,20 +6373,23 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
{ {
InfoWindow iw; InfoWindow iw;
iw.player = h->tempOwner; iw.player = h->tempOwner;
TeamState *ts = cb->gameState()->getPlayerTeam(h->tempOwner);
assert(ts);
int team = ts->id;
if(!hasVisited(h->tempOwner)) if(!hasVisited(team))
{ {
iw.text.addTxt(MetaString::ADVOB_TXT, 96); iw.text.addTxt(MetaString::ADVOB_TXT, 96);
cb->sendAndApply(&iw); cb->sendAndApply(&iw);
cb->setObjProperty(id,20,h->tempOwner); //increment general visited obelisks counter cb->setObjProperty(id,20,team); //increment general visited obelisks counter
OpenWindow ow; OpenWindow ow;
ow.id1 = h->tempOwner; ow.id1 = h->tempOwner;
ow.window = OpenWindow::PUZZLE_MAP; ow.window = OpenWindow::PUZZLE_MAP;
cb->sendAndApply(&ow); cb->sendAndApply(&ow);
cb->setObjProperty(id,10,h->tempOwner); //mark that particular obelisk as visited cb->setObjProperty(id,10,team); //mark that particular obelisk as visited
} }
else else
{ {

View File

@ -1112,7 +1112,7 @@ class DLL_EXPORT CGObelisk : public CPlayersVisited
{ {
public: public:
static ui8 obeliskCount; //how many obelisks are on map static ui8 obeliskCount; //how many obelisks are on map
static std::map<ui8, ui8> visited; //map: color_id => how many obelisks has been visited static std::map<ui8, ui8> visited; //map: team_id => how many obelisks has been visited
void setPropertyDer (ui8 what, ui32 val); void setPropertyDer (ui8 what, ui32 val);
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;

View File

@ -1395,7 +1395,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
ins.second.color=ins.first; ins.second.color=ins.first;
ins.second.human = it->second.human; ins.second.human = it->second.human;
ins.second.team = map->players[ins.first].team; ins.second.team = map->players[ins.first].team;
teams[ins.second.team].players.insert(ins.first); teams[ins.second.team].id = ins.second.team;//init team
teams[ins.second.team].players.insert(ins.first);//add player to team
players.insert(ins); players.insert(ins);
} }

View File

@ -151,6 +151,7 @@ public:
struct DLL_EXPORT TeamState : public CBonusSystemNode struct DLL_EXPORT TeamState : public CBonusSystemNode
{ {
public: public:
ui8 id; //position in gameState::teams
std::set<ui8> players; // members of this team std::set<ui8> players; // members of this team
std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden

View File

@ -3361,7 +3361,7 @@ bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance
const CStackInstance &s = army->getStack(slot); const CStackInstance &s = army->getStack(slot);
int resCreature;//resulting creature - bone dragons or skeletons int resCreature;//resulting creature - bone dragons or skeletons
if (s.hasBonusOfType(Bonus::KING1)) if (s.hasBonusOfType(Bonus::DRAGON_NATURE))
resCreature = 68; resCreature = 68;
else else
resCreature = 56; resCreature = 56;