mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
* corrected per-stack spell immunity handling
* support for new artifacts: * of Legion, shackles of war
This commit is contained in:
parent
2b44cd35b6
commit
4fc25c7b98
@ -577,6 +577,11 @@ bool CCallback::battleCanCastSpell()
|
||||
return gs->curB->castSpells[1] == 0 && gs->getHero(gs->curB->hero2)->getArt(17);
|
||||
}
|
||||
|
||||
bool CCallback:: battleCanFlee()
|
||||
{
|
||||
return gs->battleCanFlee(player);
|
||||
}
|
||||
|
||||
void CCallback::swapGarrisonHero( const CGTownInstance *town )
|
||||
{
|
||||
if(town->tempOwner != player) return;
|
||||
|
@ -172,6 +172,7 @@ public:
|
||||
virtual bool battleIsStackMine(int ID)=0; //returns true if stack with id ID belongs to caller
|
||||
virtual bool battleCanShoot(int ID, int dest)=0; //returns true if unit with id ID can shoot to dest
|
||||
virtual bool battleCanCastSpell()=0; //returns true, if caller can cast a spell
|
||||
virtual bool battleCanFlee()=0; //returns true if caller can flee from the battle
|
||||
};
|
||||
|
||||
struct HeroMoveDetails
|
||||
@ -270,6 +271,7 @@ public:
|
||||
bool battleIsStackMine(int ID); //returns true if stack with id ID belongs to caller
|
||||
bool battleCanShoot(int ID, int dest); //returns true if unit with id ID can shoot to dest
|
||||
bool battleCanCastSpell(); //returns true, if caller can cast a spell
|
||||
bool battleCanFlee(); //returns true if caller can flee from the battle
|
||||
|
||||
//XXX hmmm _tmain on _GNUC_ wtf?
|
||||
//friends
|
||||
|
@ -985,8 +985,29 @@ void CBattleInterface::bSurrenderf()
|
||||
|
||||
void CBattleInterface::bFleef()
|
||||
{
|
||||
CFunctionList<void()> ony = boost::bind(&CBattleInterface::reallyFlee,this);
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[28],std::vector<SComponent*>(), ony, 0, false);
|
||||
if( LOCPLINT->cb->battleCanFlee() )
|
||||
{
|
||||
CFunctionList<void()> ony = boost::bind(&CBattleInterface::reallyFlee,this);
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[28],std::vector<SComponent*>(), ony, 0, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<SComponent*> comps;
|
||||
std::string heroName;
|
||||
//calculating fleeing hero's name
|
||||
if(attackingHeroInstance)
|
||||
if(attackingHeroInstance->tempOwner == LOCPLINT->cb->getMyColor())
|
||||
heroName = attackingHeroInstance->name;
|
||||
if(defendingHeroInstance)
|
||||
if(defendingHeroInstance->tempOwner == LOCPLINT->cb->getMyColor())
|
||||
heroName = defendingHeroInstance->name;
|
||||
//calculating text
|
||||
char buffer[1000];
|
||||
sprintf(buffer, CGI->generaltexth->allTexts[340].c_str(), heroName.c_str());
|
||||
|
||||
//printing message
|
||||
LOCPLINT->showInfoDialog(std::string(buffer), comps);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::reallyFlee()
|
||||
|
@ -314,11 +314,11 @@ void CArtHandler::addBonuses()
|
||||
giveArtBonus(116,HeroBonus::GENERATE_RESOURCE,+750,6); //Endless Bag of Gold
|
||||
giveArtBonus(117,HeroBonus::GENERATE_RESOURCE,+500,6); //Endless Purse of Gold
|
||||
|
||||
giveArtBonus(118,HeroBonus::CREATURE_GROWTH,+5,2); //Legs of Legion
|
||||
giveArtBonus(119,HeroBonus::CREATURE_GROWTH,+4,3); //Loins of Legion
|
||||
giveArtBonus(120,HeroBonus::CREATURE_GROWTH,+3,4); //Torso of Legion
|
||||
giveArtBonus(121,HeroBonus::CREATURE_GROWTH,+2,5); //Arms of Legion
|
||||
giveArtBonus(122,HeroBonus::CREATURE_GROWTH,+1,6); //Head of Legion
|
||||
giveArtBonus(118,HeroBonus::CREATURE_GROWTH,+5,1); //Legs of Legion
|
||||
giveArtBonus(119,HeroBonus::CREATURE_GROWTH,+4,2); //Loins of Legion
|
||||
giveArtBonus(120,HeroBonus::CREATURE_GROWTH,+3,3); //Torso of Legion
|
||||
giveArtBonus(121,HeroBonus::CREATURE_GROWTH,+2,4); //Arms of Legion
|
||||
giveArtBonus(122,HeroBonus::CREATURE_GROWTH,+1,5); //Head of Legion
|
||||
|
||||
//Sea Captain's Hat
|
||||
giveArtBonus(123,HeroBonus::WHIRLPOOL_PROTECTION,0);
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
ui32 price;
|
||||
std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
|
||||
EartClass aClass;
|
||||
int id;
|
||||
ui32 id;
|
||||
std::list<HeroBonus> bonuses; //bonuses given by artifact
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
|
@ -1173,7 +1173,7 @@ void CGDwelling::fightOver(const CGHeroInstance *h, BattleResult *result) const
|
||||
|
||||
int CGTownInstance::getSightRadious() const //returns sight distance
|
||||
{
|
||||
if (subID == 2 && (builtBuildings.find(21))!=builtBuildings.end())
|
||||
if (subID == 2 && (builtBuildings.find(21))!=builtBuildings.end()) //town has lookout tower
|
||||
return 20;
|
||||
return 5;
|
||||
}
|
||||
@ -1241,6 +1241,13 @@ int CGTownInstance::creatureGrowth(const int & level) const
|
||||
if(getHordeLevel(1)==level)
|
||||
if((builtBuildings.find(24)!=builtBuildings.end()) || (builtBuildings.find(25)!=builtBuildings.end()))
|
||||
ret+=VLC->creh->creatures[town->basicCreatures[level]].hordeGrowth;
|
||||
|
||||
//support for legs of legion etc.
|
||||
if(garrisonHero)
|
||||
ret += garrisonHero->valOfBonuses(HeroBonus::CREATURE_GROWTH, level);
|
||||
if(visitingHero)
|
||||
ret += visitingHero->valOfBonuses(HeroBonus::CREATURE_GROWTH, level);
|
||||
|
||||
return ret;
|
||||
}
|
||||
int CGTownInstance::dailyIncome() const
|
||||
|
@ -1373,6 +1373,21 @@ bool CGameState::battleShootCreatureStack(int ID, int dest)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameState::battleCanFlee(int player)
|
||||
{
|
||||
if(!curB) //there is no battle
|
||||
return false;
|
||||
|
||||
const CGHeroInstance *h1 = getHero(curB->hero1);
|
||||
const CGHeroInstance *h2 = getHero(curB->hero2);
|
||||
|
||||
if(h1->hasBonusOfType(HeroBonus::ENEMY_CANT_ESCAPE) //eg. one of heroes is wearing shakles of war
|
||||
|| h2->hasBonusOfType(HeroBonus::ENEMY_CANT_ESCAPE))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CGameState::battleGetStack(int pos, bool onlyAlive)
|
||||
{
|
||||
if(!curB)
|
||||
|
@ -275,6 +275,7 @@ public:
|
||||
bool battleMoveCreatureStack(int ID, int dest);
|
||||
bool battleAttackCreatureStack(int ID, int dest);
|
||||
bool battleShootCreatureStack(int ID, int dest);
|
||||
bool battleCanFlee(int player); //returns true if player can flee from the battle
|
||||
int battleGetStack(int pos, bool onlyAlive); //returns ID of stack at given tile
|
||||
int battleGetBattlefieldType(int3 tile = int3());// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
||||
si8 battleMaxSpellLevel(); //calculates maximum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, SPELL_LEVELS is returned
|
||||
|
@ -2287,8 +2287,8 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
}
|
||||
case 4: //retreat/flee
|
||||
{
|
||||
//TODO: check if fleeing is possible (e.g. enemy may have Shackles of War)
|
||||
//TODO: calculate casualties
|
||||
if( !gs->battleCanFlee(ba.side ? gs->curB->side2 : gs->curB->side1) )
|
||||
break;
|
||||
//TODO: remove retreating hero from map and place it in recruitment list
|
||||
BattleResult *br = new BattleResult;
|
||||
br->result = 1;
|
||||
@ -2681,7 +2681,8 @@ static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHero
|
||||
|
||||
if(prob > 100) prob = 100;
|
||||
|
||||
if(rand()%100 < prob)
|
||||
if( (*it)->hasFeatureOfType(StackFeature::SPELL_IMMUNITY, sp->id) //100% sure spell immunity
|
||||
|| rand()%100 < prob) //immunity from resistance
|
||||
ret.push_back((*it)->ID);
|
||||
|
||||
}
|
||||
@ -2690,7 +2691,8 @@ static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHero
|
||||
{
|
||||
for(std::set<CStack*>::const_iterator it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
|
||||
{
|
||||
if( (*it)->amount * (*it)->MaxHealth() + (*it)->firstHPleft
|
||||
if( (*it)->hasFeatureOfType(StackFeature::SPELL_IMMUNITY, sp->id) //100% sure spell immunity
|
||||
|| (*it)->amount * (*it)->MaxHealth() + (*it)->firstHPleft
|
||||
>
|
||||
caster->getPrimSkillLevel(2) * 25 + sp->powers[caster->getSpellSchoolLevel(sp)]
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user