mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Surrendering and related artifacts (Statesman's Medal,
Diplomat's Ring, Ambassador's Sash).
This commit is contained in:
parent
7908a1a61d
commit
7dbf105f6e
@ -1135,3 +1135,14 @@ bool CBattleCallback::battleMakeTacticAction( BattleAction * action )
|
||||
sendRequest(&ma);
|
||||
return true;
|
||||
}
|
||||
|
||||
int CBattleCallback::battleGetSurrenderCost()
|
||||
{
|
||||
if (!gs->curB)
|
||||
{
|
||||
tlog1 << "battleGetSurrenderCost called when no battle!\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return gs->curB->getSurrenderingCost(player);
|
||||
}
|
@ -99,6 +99,7 @@ public:
|
||||
virtual bool battleCanCastSpell()=0; //returns true, if caller can cast a spell
|
||||
virtual SpellCasting::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell)=0; //determines if given spell can be casted (and returns problem description)
|
||||
virtual bool battleCanFlee()=0; //returns true if caller can flee from the battle
|
||||
virtual int battleGetSurrenderCost()=0; //returns cost of surrendering battle, -1 if surrendering is not possible
|
||||
virtual const CGTownInstance * battleGetDefendedTown()=0; //returns defended town if current battle is a siege, NULL instead
|
||||
virtual ui8 battleGetWallState(int partOfWall)=0; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle
|
||||
virtual int battleGetWallUnderHex(THex hex)=0; //returns part of destructible wall / gate / keep under given hex or -1 if not found
|
||||
@ -237,6 +238,7 @@ public:
|
||||
bool battleCanCastSpell() OVERRIDE; //returns true, if caller can cast a spell
|
||||
SpellCasting::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell) OVERRIDE; //determines if given spell can be casted (and returns problem description)
|
||||
bool battleCanFlee() OVERRIDE; //returns true if caller can flee from the battle
|
||||
int battleGetSurrenderCost() OVERRIDE; //returns cost of surrendering battle, -1 if surrendering is not possible
|
||||
const CGTownInstance * battleGetDefendedTown() OVERRIDE; //returns defended town if current battle is a siege, NULL instead
|
||||
ui8 battleGetWallState(int partOfWall) OVERRIDE; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle
|
||||
int battleGetWallUnderHex(THex hex) OVERRIDE; //returns part of destructible wall / gate / keep under given hex or -1 if not found
|
||||
|
@ -1,3 +1,11 @@
|
||||
0.84 -> 0.85
|
||||
GENERAL:
|
||||
* New artifacts supported:
|
||||
- Statesman's Medal
|
||||
- Diplomat's Ring
|
||||
- Ambassador's Sash
|
||||
|
||||
|
||||
0.83 -> 0.84 (Mar 01 2011)
|
||||
GENERAL:
|
||||
* Bonus system has been rewritten
|
||||
|
@ -37,6 +37,7 @@ const double M_PI = 3.14159265358979323846;
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#endif
|
||||
#include <boost/format.hpp>
|
||||
|
||||
/*
|
||||
* CBattleInterface.cpp, part of VCMI engine
|
||||
@ -1198,8 +1199,8 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
||||
bOptions = new AdventureMapButton (CGI->generaltexth->zelp[381].first, CGI->generaltexth->zelp[381].second, boost::bind(&CBattleInterface::bOptionsf,this), 3 + pos.x, 561 + pos.y, "icm003.def", SDLK_o);
|
||||
bSurrender = new AdventureMapButton (CGI->generaltexth->zelp[379].first, CGI->generaltexth->zelp[379].second, boost::bind(&CBattleInterface::bSurrenderf,this), 54 + pos.x, 561 + pos.y, "icm001.def", SDLK_s);
|
||||
bFlee = new AdventureMapButton (CGI->generaltexth->zelp[380].first, CGI->generaltexth->zelp[380].second, boost::bind(&CBattleInterface::bFleef,this), 105 + pos.x, 561 + pos.y, "icm002.def", SDLK_r);
|
||||
bSurrender->block(!curInt->cb->battleCanFlee());
|
||||
bFlee->block(!curInt->cb->battleCanFlee());
|
||||
bSurrender->block(curInt->cb->battleGetSurrenderCost() < 0);
|
||||
bAutofight = new AdventureMapButton (CGI->generaltexth->zelp[382].first, CGI->generaltexth->zelp[382].second, boost::bind(&CBattleInterface::bAutofightf,this), 157 + pos.x, 561 + pos.y, "icm004.def", SDLK_a);
|
||||
bSpell = new AdventureMapButton (CGI->generaltexth->zelp[385].first, CGI->generaltexth->zelp[385].second, boost::bind(&CBattleInterface::bSpellf,this), 645 + pos.x, 561 + pos.y, "icm005.def", SDLK_c);
|
||||
bSpell->block(true);
|
||||
@ -2160,6 +2161,15 @@ void CBattleInterface::bSurrenderf()
|
||||
{
|
||||
if(spellDestSelectMode) //we are casting a spell
|
||||
return;
|
||||
|
||||
int cost = curInt->cb->battleGetSurrenderCost();
|
||||
if(cost >= 0)
|
||||
{
|
||||
const CGHeroInstance *opponent = curInt->cb->battleGetFightingHero(1);
|
||||
std::string enemyHeroName = opponent ? opponent->name : "#ENEMY#"; //TODO: should surrendering without enemy hero be enabled?
|
||||
std::string surrenderMessage = boost::str(boost::format(CGI->generaltexth->allTexts[32]) % enemyHeroName % cost); //%s states: "I will accept your surrender and grant you and your troops safe passage for the price of %d gold."
|
||||
curInt->showYesNoDialog(surrenderMessage, std::vector<SComponent*>(), boost::bind(&CBattleInterface::reallySurrender,this), 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::bFleef()
|
||||
@ -2170,7 +2180,7 @@ void CBattleInterface::bFleef()
|
||||
if( curInt->cb->battleCanFlee() )
|
||||
{
|
||||
CFunctionList<void()> ony = boost::bind(&CBattleInterface::reallyFlee,this);
|
||||
curInt->showYesNoDialog(CGI->generaltexth->allTexts[28],std::vector<SComponent*>(), ony, 0, false);
|
||||
curInt->showYesNoDialog(CGI->generaltexth->allTexts[28],std::vector<SComponent*>(), ony, 0, false); //Are you sure you want to retreat?
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2185,7 +2195,7 @@ void CBattleInterface::bFleef()
|
||||
heroName = defendingHeroInstance->name;
|
||||
//calculating text
|
||||
char buffer[1000];
|
||||
sprintf(buffer, CGI->generaltexth->allTexts[340].c_str(), heroName.c_str());
|
||||
sprintf(buffer, CGI->generaltexth->allTexts[340].c_str(), heroName.c_str()); //The Shackles of War are present. %s can not retreat!
|
||||
|
||||
//printing message
|
||||
curInt->showInfoDialog(std::string(buffer), comps);
|
||||
@ -2194,10 +2204,23 @@ void CBattleInterface::bFleef()
|
||||
|
||||
void CBattleInterface::reallyFlee()
|
||||
{
|
||||
giveCommand(4,0,0);
|
||||
giveCommand(BattleAction::RETREAT,0,0);
|
||||
CCS->curh->changeGraphic(0, 0);
|
||||
}
|
||||
|
||||
void CBattleInterface::reallySurrender()
|
||||
{
|
||||
if(curInt->cb->getResourceAmount(Res::GOLD) < curInt->cb->battleGetSurrenderCost())
|
||||
{
|
||||
curInt->showInfoDialog(CGI->generaltexth->allTexts[29]); //You don't have enough gold!
|
||||
}
|
||||
else
|
||||
{
|
||||
giveCommand(BattleAction::SURRENDER,0,0);
|
||||
CCS->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::bAutofightf()
|
||||
{
|
||||
if(spellDestSelectMode) //we are casting a spell
|
||||
@ -3013,6 +3036,7 @@ void CBattleInterface::activateStack()
|
||||
bSpell->block(!curInt->cb->battleCanCastSpell());
|
||||
bSurrender->block((curInt == attackerInt ? defendingHeroInstance : attackingHeroInstance) == NULL);
|
||||
bFlee->block(!curInt->cb->battleCanFlee());
|
||||
bSurrender->block(curInt->cb->battleGetSurrenderCost() < 0);
|
||||
|
||||
GH.fakeMouseMove();
|
||||
|
||||
|
@ -496,6 +496,7 @@ public:
|
||||
void bSurrenderf();
|
||||
void bFleef();
|
||||
void reallyFlee(); //performs fleeing without asking player
|
||||
void reallySurrender(); //performs surrendering without asking player
|
||||
void bAutofightf();
|
||||
void bSpellf();
|
||||
void bWaitf();
|
||||
|
@ -1883,6 +1883,42 @@ std::vector<ui32> BattleInfo::calculateResistedStacks( const CSpell * sp, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BattleInfo::getSurrenderingCost(int player) const
|
||||
{
|
||||
if(!battleCanFlee(player)) //to surrender, conditions of fleeing must be fulfilled
|
||||
return -1;
|
||||
if(!getHero(theOtherPlayer(player))) //additionally, there must be an enemy hero
|
||||
return -2;
|
||||
|
||||
int ret = 0;
|
||||
double discount = 0;
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
if(s->owner == player && s->base) //we pay for our stack that comes from our army (the last condition eliminates summoned cres and war machines)
|
||||
ret += s->getCreature()->cost[Res::GOLD] * s->count;
|
||||
|
||||
if(const CGHeroInstance *h = getHero(player))
|
||||
discount += h->valOfBonuses(Bonus::SURRENDER_DISCOUNT);
|
||||
|
||||
ret *= (100.0 - discount) / 100.0;
|
||||
amax(ret, 0); //no negative costs for >100% discounts (impossible in original H3 mechanics, but some day...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BattleInfo::theOtherPlayer(int player) const
|
||||
{
|
||||
return sides[!whatSide(player)];
|
||||
}
|
||||
|
||||
ui8 BattleInfo::whatSide(int player) const
|
||||
{
|
||||
for(int i = 0; i < ARRAY_COUNT(sides); i++)
|
||||
if(sides[i] == player)
|
||||
return i;
|
||||
|
||||
tlog1 << "BattleInfo::whatSide: Player " << player << " is not in battle!\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)
|
||||
: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
|
||||
counterAttacks(1)
|
||||
|
@ -131,6 +131,10 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
|
||||
void localInit();
|
||||
static BattleInfo * setupBattle( int3 tile, int terrain, int terType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town );
|
||||
bool isInTacticRange( THex dest ) const;
|
||||
int getSurrenderingCost(int player) const;
|
||||
|
||||
int theOtherPlayer(int player) const;
|
||||
ui8 whatSide(int player) const;
|
||||
};
|
||||
|
||||
class DLL_EXPORT CStack : public CBonusSystemNode, public CStackBasicDescriptor
|
||||
|
@ -1177,6 +1177,14 @@ void CGHeroInstance::updateSkill(int which, int val)
|
||||
else
|
||||
b->val = +val;
|
||||
}
|
||||
else if(which == DIPLOMACY) //surrender discount: 20% per level
|
||||
{
|
||||
|
||||
if(Bonus *b = getBonus(Selector::type(Bonus::SURRENDER_DISCOUNT) && Selector::sourceType(Bonus::SECONDARY_SKILL)))
|
||||
b->val = +val;
|
||||
else
|
||||
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::SURRENDER_DISCOUNT, Bonus::SECONDARY_SKILL, val * 20, which));
|
||||
}
|
||||
|
||||
int skillVal = 0;
|
||||
switch (which)
|
||||
|
@ -1254,11 +1254,7 @@ void CGameHandler::checkForBattleEnd( std::vector<CStack*> &stacks )
|
||||
}
|
||||
if(!hasStack[0] || !hasStack[1]) //somebody has won
|
||||
{
|
||||
BattleResult *br = new BattleResult; //will be deleted at the end of startBattle(...)
|
||||
br->result = 0;
|
||||
br->winner = hasStack[1]; //fleeing side loses
|
||||
gs->curB->calculateCasualties(br->casualties);
|
||||
battleResult.set(br);
|
||||
setBattleResult(0, hasStack[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1665,40 +1661,6 @@ void CGameHandler::stopHeroVisitCastle(int obj, int heroID)
|
||||
sendAndApply(&vc);
|
||||
}
|
||||
|
||||
// bool CGameHandler::removeArtifact(const CArtifact* art, int hid)
|
||||
// {
|
||||
// const CGHeroInstance* h = getHero(hid);
|
||||
//
|
||||
// SetHeroArtifacts sha;
|
||||
// sha.hid = hid;
|
||||
// sha.artifacts = h->artifacts;
|
||||
// sha.artifWorn = h->artifWorn;
|
||||
//
|
||||
// std::vector<const CArtifact*>::iterator it;
|
||||
// if ((it = std::find(sha.artifacts.begin(), sha.artifacts.end(), art)) != sha.artifacts.end()) //it is in backpack
|
||||
// sha.artifacts.erase(it);
|
||||
// else //worn
|
||||
// {
|
||||
// std::map<ui16, const CArtifact*>::iterator itr;
|
||||
// for (itr = sha.artifWorn.begin(); itr != sha.artifWorn.end(); ++itr)
|
||||
// {
|
||||
// if (itr->second == art)
|
||||
// {
|
||||
// VLC->arth->unequipArtifact(sha.artifWorn, itr->first);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(itr == sha.artifWorn.end())
|
||||
// {
|
||||
// tlog2 << "Cannot find artifact to remove!\n";
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// sendAndApply(&sha);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
void CGameHandler::removeArtifact(const ArtifactLocation &al)
|
||||
{
|
||||
assert(al.getArt());
|
||||
@ -1737,13 +1699,6 @@ void CGameHandler::startBattleI( const CArmedInstance *army1, const CArmedInstan
|
||||
startBattleI(army1, army2, army2->visitablePos(), cb, creatureBank);
|
||||
}
|
||||
|
||||
//void CGameHandler::startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb) //for hero<=>neutral army
|
||||
//{
|
||||
// CGHeroInstance* h = const_cast<CGHeroInstance*>(getHero(heroID));
|
||||
// startBattleI(&h->army,&army,tile,h,NULL,cb);
|
||||
// //battle(&h->army,army,tile,h,NULL);
|
||||
//}
|
||||
|
||||
void CGameHandler::changeSpells( int hid, bool give, const std::set<ui32> &spells )
|
||||
{
|
||||
ChangeSpells cs;
|
||||
@ -2534,17 +2489,7 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u
|
||||
COMPLAIN_RET("No artifact to move!");
|
||||
if (destArtifact && srcHero->tempOwner != destHero->tempOwner)
|
||||
COMPLAIN_RET("Can't touch artifact on hero of another player!");
|
||||
|
||||
|
||||
|
||||
// // Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks.
|
||||
// if (srcHeroID == destHeroID && srcSlot < 19 && destSlot < 19)
|
||||
// {
|
||||
// sha.setArtAtPos(srcSlot, NULL);
|
||||
// if (!vstd::contains(sha.artifWorn, destSlot))
|
||||
// destArtifact = NULL;
|
||||
// }
|
||||
|
||||
|
||||
// Check if src/dest slots are appropriate for the artifacts exchanged.
|
||||
// Moving to the backpack is always allowed.
|
||||
if ((!srcArtifact || destSlot < Arts::BACKPACK_START)
|
||||
@ -2562,10 +2507,6 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u
|
||||
if(dst.slot >= Arts::BACKPACK_START)
|
||||
amin(dst.slot, Arts::BACKPACK_START + dst.hero->artifactsInBackpack.size());
|
||||
|
||||
// // Correction for destination from removing source artifact in backpack.
|
||||
// if (src.slot >= 19 && dst.slot >= 19 && src.slot < dst.slot)
|
||||
// dst.slot--;
|
||||
|
||||
if (src.slot == dst.slot && src.hero == dst.hero)
|
||||
COMPLAIN_RET("Won't move artifact: Dest same as source!");
|
||||
|
||||
@ -2583,37 +2524,6 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u
|
||||
moveArtifact(src, dst);
|
||||
}
|
||||
|
||||
//
|
||||
// // If dest does not fit in src, put it in dest's backpack instead.
|
||||
// if (srcHeroID == destHeroID) // To avoid stumbling on own locks, remove artifact first.
|
||||
// sha.setArtAtPos(destSlot, NULL);
|
||||
// const bool destFits = !destArtifact || srcSlot >= 19 || destSlot >= 19 || destArtifact->fitsAt(sha.artifWorn, srcSlot);
|
||||
// if (srcHeroID == destHeroID && destArtifact)
|
||||
// sha.setArtAtPos(destSlot, destArtifact);
|
||||
//
|
||||
// sha.setArtAtPos(srcSlot, NULL);
|
||||
// if (destSlot < 19 && (destArtifact || srcSlot < 19) && destFits)
|
||||
// sha.setArtAtPos(srcSlot, destArtifact ? destArtifact : NULL);
|
||||
//
|
||||
// // Internal hero artifact arrangement.
|
||||
// if(srcHero == destHero)
|
||||
// {
|
||||
//
|
||||
// sha.setArtAtPos(destSlot, srcHero->getArtAtPos(srcSlot));
|
||||
// }
|
||||
// if (srcHeroID != destHeroID)
|
||||
// {
|
||||
// // Exchange between two different heroes.
|
||||
// SetHeroArtifacts sha2;
|
||||
// sha2.hid = destHeroID;
|
||||
// sha2.artifacts = destHero->artifacts;
|
||||
// sha2.artifWorn = destHero->artifWorn;
|
||||
// sha2.setArtAtPos(destSlot, srcArtifact ? srcArtifact : NULL);
|
||||
// if (!destFits)
|
||||
// sha2.setArtAtPos(sha2.artifacts.size() + 19, destHero->getArtAtPos(destSlot));
|
||||
// sendAndApply(&sha2);
|
||||
// }
|
||||
// sendAndApply(&sha);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2656,118 +2566,7 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
|
||||
da.al = ArtifactLocation(hero, artifactSlot);
|
||||
sendAndApply(&da);
|
||||
}
|
||||
/*
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = heroID;
|
||||
sha.artifacts = hero->artifacts;
|
||||
sha.artifWorn = hero->artifWorn;
|
||||
|
||||
if (assemble)
|
||||
{
|
||||
if (VLC->arth->artifacts.size() < assembleTo)
|
||||
{
|
||||
complain("Illegal artifact to assemble to.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!destArtifact->canBeAssembledTo(hero->artifWorn, assembleTo))
|
||||
{
|
||||
complain("Artifact cannot be assembled.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const CArtifact &artifact = *VLC->arth->artifacts[assembleTo];
|
||||
|
||||
if (artifact.constituents == NULL)
|
||||
{
|
||||
complain("Not a combinational artifact.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform assembly.
|
||||
bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
|
||||
const bool destSpecific = vstd::contains(artifact.possibleSlots, artifactSlot); // Prefer the chosen slot as the location for the assembled artifact.
|
||||
|
||||
BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
|
||||
{
|
||||
if (destSpecific && constituentID == destArtifact->id)
|
||||
{
|
||||
sha.artifWorn[artifactSlot] = VLC->arth->artifacts[assembleTo];
|
||||
destConsumed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (std::map<ui16, const CArtifact*>::iterator it = sha.artifWorn.begin(); it != sha.artifWorn.end(); ++it)
|
||||
{
|
||||
if (it->second->id == constituentID)
|
||||
{ // Found possible constituent to substitute.
|
||||
if (destSpecific && !destConsumed && it->second->id == destArtifact->id)
|
||||
{
|
||||
// Find the specified destination for assembled artifact.
|
||||
if (it->first == artifactSlot)
|
||||
{
|
||||
it->second = VLC->arth->artifacts[assembleTo];
|
||||
destConsumed = true;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Either put the assembled artifact in a fitting spot, or put a lock.
|
||||
if (!destSpecific && !destConsumed && vstd::contains(artifact.possibleSlots, it->first))
|
||||
{
|
||||
it->second = VLC->arth->artifacts[assembleTo];
|
||||
destConsumed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second = VLC->arth->artifacts[145];
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
complain("Constituent missing.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Perform disassembly.
|
||||
bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
|
||||
BOOST_FOREACH(ui32 constituentID, *destArtifact->constituents)
|
||||
{
|
||||
const CArtifact &constituent = *VLC->arth->artifacts[constituentID];
|
||||
|
||||
if (!destConsumed && vstd::contains(constituent.possibleSlots, artifactSlot))
|
||||
{
|
||||
sha.artifWorn[artifactSlot] = VLC->arth->artifacts[constituentID];
|
||||
destConsumed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_REVERSE_FOREACH(ui16 slotID, constituent.possibleSlots)
|
||||
{
|
||||
if (vstd::contains(sha.artifWorn, slotID) && sha.artifWorn[slotID]->id == 145)
|
||||
{
|
||||
const_cast<CArtifact*>(sha.artifWorn[slotID])->id = constituentID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendAndApply(&sha);
|
||||
|
||||
return true;*/
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3142,17 +2941,28 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
}
|
||||
case BattleAction::RETREAT: //retreat/flee
|
||||
{
|
||||
if( !gs->curB->battleCanFlee(ba.side ? gs->curB->sides[1] : gs->curB->sides[0]) )
|
||||
break;
|
||||
//TODO: remove retreating hero from map and place it in recruitment list
|
||||
BattleResult *br = new BattleResult;
|
||||
br->result = 1;
|
||||
br->winner = !ba.side; //fleeing side loses
|
||||
gs->curB->calculateCasualties(br->casualties);
|
||||
giveExp(*br);
|
||||
battleResult.set(br);
|
||||
if(!gs->curB->battleCanFlee(gs->curB->sides[ba.side]))
|
||||
complain("Cannot retreat!");
|
||||
else
|
||||
setBattleResult(1, !ba.side); //surrendering side loses
|
||||
break;
|
||||
}
|
||||
case BattleAction::SURRENDER:
|
||||
{
|
||||
int player = gs->curB->sides[ba.side];
|
||||
int cost = gs->curB->getSurrenderingCost(player);
|
||||
if(cost < 0)
|
||||
complain("Cannot surrender!");
|
||||
else if(getResource(player, Res::GOLD) < cost)
|
||||
complain("Not enough gold to surrender!");
|
||||
else
|
||||
{
|
||||
giveResource(player, Res::GOLD, -cost);
|
||||
setBattleResult(2, !ba.side); //surrendering side loses
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BattleAction::WALK_AND_ATTACK: //walk or attack
|
||||
{
|
||||
sendAndApply(&StartAction(ba)); //start movement and attack
|
||||
@ -3538,17 +3348,6 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
if(!hero) return;
|
||||
for (int g=7; g<=140; ++g)
|
||||
giveHeroNewArtifact(hero, VLC->arth->artifacts[g], -1);
|
||||
|
||||
// SetHeroArtifacts sha;
|
||||
// sha.hid = hero->id;
|
||||
// sha.artifacts = hero->artifacts;
|
||||
// sha.artifWorn = hero->artifWorn;
|
||||
// sha.artifacts.push_back(VLC->arth->artifacts[2]); //grail
|
||||
// for (int g=7; g<=140; ++g)
|
||||
// {
|
||||
// sha.artifacts.push_back(VLC->arth->artifacts[g]);
|
||||
// }
|
||||
// sendAndApply(&sha);
|
||||
}
|
||||
else
|
||||
cheated = false;
|
||||
@ -3730,7 +3529,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
{
|
||||
switch(ba.actionType)
|
||||
{
|
||||
case 1: //hero casts spell
|
||||
case BattleAction::HERO_SPELL: //hero casts spell
|
||||
{
|
||||
const CGHeroInstance *h = gs->curB->heroes[ba.side];
|
||||
const CGHeroInstance *secondHero = gs->curB->heroes[!ba.side];
|
||||
@ -5062,6 +4861,15 @@ void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact
|
||||
giveHeroArtifact(h, a, pos);
|
||||
}
|
||||
|
||||
void CGameHandler::setBattleResult(int resultType, int victoriusSide)
|
||||
{
|
||||
BattleResult *br = new BattleResult;
|
||||
br->result = resultType;
|
||||
br->winner = victoriusSide; //surrendering side loses
|
||||
gs->curB->calculateCasualties(br->casualties);
|
||||
battleResult.set(br);
|
||||
}
|
||||
|
||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
|
||||
{
|
||||
int color = army->tempOwner;
|
||||
|
@ -120,6 +120,7 @@ public:
|
||||
void prepareAttack(BattleAttack &bat, const CStack *att, const CStack *def, int distance); //distance - number of hexes travelled before attacking
|
||||
void checkForBattleEnd( std::vector<CStack*> &stacks );
|
||||
void setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance *heroes[2], bool creatureBank, const CGTownInstance *town);
|
||||
void setBattleResult(int resultType, int victoriusSide);
|
||||
|
||||
CGameHandler(void);
|
||||
~CGameHandler(void);
|
||||
|
Loading…
Reference in New Issue
Block a user