1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-25 12:14:46 +02:00

7 days without castle loss condition. Minor fixes.

This commit is contained in:
Michał W. Urbańczyk 2010-02-01 23:30:03 +00:00
parent 172b3b0158
commit 49e56e3749
6 changed files with 81 additions and 13 deletions

View File

@ -152,7 +152,7 @@ void RemoveObject::applyFirstCl( CClient *cl )
void RemoveObject::applyCl( CClient *cl ) void RemoveObject::applyCl( CClient *cl )
{ {
if(cl->pathInfo->hero) if(cl->pathInfo->hero && cl->pathInfo->hero->id != id)
GS(cl)->calculatePaths(cl->pathInfo->hero, *cl->pathInfo); GS(cl)->calculatePaths(cl->pathInfo->hero, *cl->pathInfo);
} }

View File

@ -217,6 +217,9 @@ void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst
case SEC_SKILL_NAME: case SEC_SKILL_NAME:
vec = &VLC->generaltexth->skillName; vec = &VLC->generaltexth->skillName;
break; break;
case COLOR:
vec = &VLC->generaltexth->capColors;
break;
} }
dst = (*vec)[ser]; dst = (*vec)[ser];
} }
@ -3224,6 +3227,9 @@ int CGameState::lossCheck( ui8 player ) const
} }
} }
if(!p->towns.size() && p->daysWithoutCastle >= 7)
return 2;
return false; return false;
} }

View File

@ -73,7 +73,7 @@ private:
enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER}; enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER};
public: public:
enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES, enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES,
MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES, CREGENS4}; MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES, CREGENS4, COLOR};
std::vector<ui8> message; //vector of EMessage std::vector<ui8> message; //vector of EMessage
@ -631,7 +631,7 @@ struct NewTurn : public CPackForClient //101
struct Component : public CPack //2002 helper for object scrips informations struct Component : public CPack //2002 helper for object scrips informations
{ {
enum {PRIM_SKILL, SEC_SKILL, RESOURCE, CREATURE, ARTIFACT, EXPERIENCE, SPELL, MORALE=8, LUCK, HERO}; enum {PRIM_SKILL, SEC_SKILL, RESOURCE, CREATURE, ARTIFACT, EXPERIENCE, SPELL, MORALE=8, LUCK, HERO, FLAG};
ui16 id, subtype; //id uses ^^^ enums, when id==EXPPERIENCE subtype==0 means exp points and subtype==1 levels) ui16 id, subtype; //id uses ^^^ enums, when id==EXPPERIENCE subtype==0 means exp points and subtype==1 levels)
si32 val; // + give; - take si32 val; // + give; - take
si16 when; // 0 - now; +x - within x days; -x - per x days si16 when; // 0 - now; +x - within x days; -x - per x days

View File

@ -575,6 +575,15 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
if(gs->getDate(1) == 7) //new week if(gs->getDate(1) == 7) //new week
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes) BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
h->bonuses.remove_if(HeroBonus::OneWeek); h->bonuses.remove_if(HeroBonus::OneWeek);
//count days without town
for( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
{
if(i->second.towns.size() || gs->day == 1)
i->second.daysWithoutCastle = 0;
else
i->second.daysWithoutCastle++;
}
} }
DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs ) DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs )

View File

@ -912,6 +912,38 @@ void CGameHandler::newTurn()
gs->map->objects[i]->newTurn(); gs->map->objects[i]->newTurn();
winLoseHandle(0xff); winLoseHandle(0xff);
//warn players without town
if(gs->day)
{
for (std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
{
if(i->second.status || i->second.towns.size() || i->second.color >= PLAYER_LIMIT)
continue;
InfoWindow iw;
iw.player = i->first;
iw.components.push_back(Component(Component::FLAG,i->first,0,0));
if(!i->second.daysWithoutCastle)
{
iw.text.addTxt(MetaString::GENERAL_TXT,6); //%s, you have lost your last town. If you do not conquer another town in the next week, you will be eliminated.
iw.text.addReplacement(MetaString::COLOR, i->first);
}
else if(i->second.daysWithoutCastle == 6)
{
iw.text.addTxt(MetaString::ARRAY_TXT,129); //%s, this is your last day to capture a town or you will be banished from this land.
iw.text.addReplacement(MetaString::COLOR, i->first);
}
else
{
iw.text.addTxt(MetaString::ARRAY_TXT,128); //%s, you only have %d days left to capture a town or you will be banished from this land.
iw.text.addReplacement(MetaString::COLOR, i->first);
iw.text.addReplacement(7 - i->second.daysWithoutCastle);
}
sendAndApply(&iw);
}
}
} }
void CGameHandler::run(bool resume) void CGameHandler::run(bool resume)
{ {
@ -1583,10 +1615,18 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
} }
void CGameHandler::setOwner(int objid, ui8 owner) void CGameHandler::setOwner(int objid, ui8 owner)
{ {
ui8 oldOwner = getOwner(objid);
SetObjectProperty sop(objid,1,owner); SetObjectProperty sop(objid,1,owner);
sendAndApply(&sop); sendAndApply(&sop);
winLoseHandle(1<<owner); winLoseHandle(1<<owner | 1<<oldOwner);
if(owner < PLAYER_LIMIT && getTown(objid) && !gs->getPlayer(owner)->towns.size()) //player lost last town
{
InfoWindow iw;
iw.player = oldOwner;
iw.text.addTxt(MetaString::GENERAL_TXT, 6); //%s, you have lost your last town. If you do not conquer another town in the next week, you will be eliminated.
sendAndApply(&iw);
}
} }
void CGameHandler::setHoverName(int objid, MetaString* name) void CGameHandler::setHoverName(int objid, MetaString* name)
{ {
@ -2877,7 +2917,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
break; break;
} }
} }
if(ba.stackNumber == gs->curB->activeStack) if(ba.stackNumber == gs->curB->activeStack || battleResult.get()) //active stack has moved or battle has finished
battleMadeAction.setn(true); battleMadeAction.setn(true);
return ok; return ok;
} }
@ -3522,7 +3562,7 @@ void CGameHandler::checkLossVictory( ui8 player )
return; return;
InfoWindow iw; InfoWindow iw;
getLossVicMessage(player, vic ? vic < 0 : loss < 0, vic, iw); getLossVicMessage(player, vic ? vic : loss , vic, iw);
sendAndApply(&iw); sendAndApply(&iw);
PlayerEndsGame peg; PlayerEndsGame peg;
@ -3530,7 +3570,7 @@ void CGameHandler::checkLossVictory( ui8 player )
peg.victory = vic; peg.victory = vic;
sendAndApply(&peg); sendAndApply(&peg);
if(vic) //one player won -> all enemies lost //TODO: allies if(vic > 0) //one player won -> all enemies lost //TODO: allies
{ {
iw.text.localStrings.front().second++; //message about losing because enemy won first is just after victory message iw.text.localStrings.front().second++; //message about losing because enemy won first is just after victory message
@ -3549,18 +3589,25 @@ void CGameHandler::checkLossVictory( ui8 player )
} }
else //player lost -> all his objects become unflagged (neutral) else //player lost -> all his objects become unflagged (neutral)
{ {
for (std::vector<CGObjectInstance*>::const_iterator i = gs->map->objects.begin(); i != gs->map->objects.end(); i++) std::vector<CGHeroInstance*> hlp = p->heroes;
for (std::vector<CGHeroInstance*>::const_iterator i = hlp.begin(); i != hlp.end(); i++) //eliminate heroes
removeObject((*i)->id);
for (std::vector<CGObjectInstance*>::const_iterator i = gs->map->objects.begin(); i != gs->map->objects.end(); i++) //unflag objs
{ {
if(*i && (*i)->tempOwner == player) if(*i && (*i)->tempOwner == player)
setOwner((**i).id,NEUTRAL_PLAYER); setOwner((**i).id,NEUTRAL_PLAYER);
} }
//eliminating one player may cause victory of anoother:
winLoseHandle(ALL_PLAYERS & ~(1<<player));
} }
if(vic) if(vic)
end2 = true; end2 = true;
} }
void CGameHandler::getLossVicMessage( ui8 player, bool standard, bool victory, InfoWindow &out ) const void CGameHandler::getLossVicMessage( ui8 player, ui8 standard, bool victory, InfoWindow &out ) const
{ {
const PlayerState *p = gs->getPlayer(player); const PlayerState *p = gs->getPlayer(player);
// if(!p->human) // if(!p->human)
@ -3570,7 +3617,7 @@ void CGameHandler::getLossVicMessage( ui8 player, bool standard, bool victory, I
if(victory) if(victory)
{ {
if(!standard) //not std loss if(standard < 0) //not std loss
{ {
switch(gs->map->victoryCondition.condition) switch(gs->map->victoryCondition.condition)
{ {
@ -3626,12 +3673,12 @@ void CGameHandler::getLossVicMessage( ui8 player, bool standard, bool victory, I
} }
else else
{ {
out.text.addTxt(MetaString::GENERAL_TXT, 659); //Congratulations! You have reached your destination, precious cargo intact, and can claim victory!
} }
} }
else else
{ {
if(!standard) //not std loss if(standard < 0) //not std loss
{ {
switch(gs->map->lossCondition.typeOfLossCon) switch(gs->map->lossCondition.typeOfLossCon)
{ {
@ -3656,6 +3703,12 @@ void CGameHandler::getLossVicMessage( ui8 player, bool standard, bool victory, I
break; break;
} }
} }
else if(standard == 2)
{
out.text.addTxt(MetaString::GENERAL_TXT, 7);//%s, your heroes abandon you, and you are banished from this land.
out.text.addReplacement(MetaString::COLOR, player);
out.components.push_back(Component(Component::FLAG,player,0,0));
}
else //lost all towns and heroes else //lost all towns and heroes
{ {
out.text.addTxt(MetaString::GENERAL_TXT, 660); //All your forces have been defeated, and you are banished from this land! out.text.addTxt(MetaString::GENERAL_TXT, 660); //All your forces have been defeated, and you are banished from this land!

View File

@ -91,7 +91,7 @@ public:
void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
void checkLossVictory(ui8 player); void checkLossVictory(ui8 player);
void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all
void getLossVicMessage(ui8 player, bool standard, bool victory, InfoWindow &out) const; void getLossVicMessage(ui8 player, ui8 standard, bool victory, InfoWindow &out) const;
////used only in endBattle - don't touch elsewhere ////used only in endBattle - don't touch elsewhere
boost::function<void(BattleResult*)> * battleEndCallback; boost::function<void(BattleResult*)> * battleEndCallback;