mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
parent
b36be10e30
commit
5f310aa20f
@ -1750,16 +1750,6 @@ void CBattleInterface::getPossibleActionsForStack(const CStack * stack)
|
||||
for (Bonus * spellBonus : spellBonuses)
|
||||
{
|
||||
spell = CGI->spellh->spells[spellBonus->subtype];
|
||||
if (spell->isRisingSpell())
|
||||
{
|
||||
possibleActions.push_back (RISING_SPELL);
|
||||
}
|
||||
//possibleActions.push_back (NO_LOCATION);
|
||||
//possibleActions.push_back (ANY_LOCATION);
|
||||
//TODO: allow stacks cast aimed spells
|
||||
//possibleActions.push_back (OTHER_SPELL);
|
||||
else
|
||||
{
|
||||
switch (spellBonus->subtype)
|
||||
{
|
||||
case SpellID::REMOVE_OBSTACLE:
|
||||
@ -1769,7 +1759,6 @@ void CBattleInterface::getPossibleActionsForStack(const CStack * stack)
|
||||
possibleActions.push_back (selectionTypeByPositiveness (*spell));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
std::sort(possibleActions.begin(), possibleActions.end());
|
||||
@ -2194,13 +2183,18 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
legalAction = true;
|
||||
break;
|
||||
case FRIENDLY_CREATURE_SPELL:
|
||||
if (shere && shere->alive() && ourStack && isCastingPossibleHere (sactive, shere, myNumber))
|
||||
legalAction = true;
|
||||
break;
|
||||
case RISING_SPELL:
|
||||
if (shere && shere->canBeHealed() && ourStack && isCastingPossibleHere (sactive, shere, myNumber)) //TODO: at least one stack has to be raised by resurrection / animate dead
|
||||
{
|
||||
if (isCastingPossibleHere (sactive, shere, myNumber)); //need to be called before sp is determined
|
||||
{
|
||||
bool rise = false; //TODO: can you imagine rising hostile creatures?
|
||||
sp = CGI->spellh->spells[creatureCasting ? creatureSpellToCast : spellToCast->additionalInfo];
|
||||
if (sp && sp->isRisingSpell())
|
||||
rise = true;
|
||||
if (shere && (shere->alive() || rise) && ourStack)
|
||||
legalAction = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RANDOM_GENIE_SPELL:
|
||||
{
|
||||
if (shere && ourStack && shere != sactive) //only positive spells for other allied creatures
|
||||
@ -2379,7 +2373,6 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
break;
|
||||
case HOSTILE_CREATURE_SPELL:
|
||||
case FRIENDLY_CREATURE_SPELL:
|
||||
case RISING_SPELL:
|
||||
sp = CGI->spellh->spells[creatureCasting ? creatureSpellToCast : spellToCast->additionalInfo]; //necessary if creature has random Genie spell at same time
|
||||
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % sp->name % shere->getName()); //Cast %s on %s
|
||||
switch (sp->id)
|
||||
@ -2452,7 +2445,6 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
{
|
||||
case HOSTILE_CREATURE_SPELL:
|
||||
case FRIENDLY_CREATURE_SPELL:
|
||||
case RISING_SPELL:
|
||||
case RANDOM_GENIE_SPELL:
|
||||
cursorFrame = ECursor::COMBAT_BLOCKED;
|
||||
consoleMsg = CGI->generaltexth->allTexts[23];
|
||||
|
@ -112,7 +112,7 @@ void BattleInfo::calculateCasualties( std::map<ui32,si32> *casualties ) const
|
||||
for(auto & elem : stacks)//setting casualties
|
||||
{
|
||||
const CStack * const st = elem;
|
||||
si32 killed = (st->alive() ? st->baseAmount - st->count : st->baseAmount);
|
||||
si32 killed = (st->alive() ? (st->baseAmount - st->count + st->resurrected) : st->baseAmount);
|
||||
vstd::amax(killed, 0);
|
||||
if(killed)
|
||||
casualties[!st->attackerOwned][st->getCreature()->idNumber] += killed;
|
||||
@ -161,9 +161,9 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
|
||||
}
|
||||
|
||||
//All spells casted by hero 9resurrection, cure, sacrifice)
|
||||
ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack) const
|
||||
ui32 CBattleInfoCallback::calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack) const
|
||||
{
|
||||
bool resurrect = resurrects(spell->id);
|
||||
bool resurrect = spell->isRisingSpell();
|
||||
int healedHealth;
|
||||
if (spell->id == SpellID::SACRIFICE && sacrificedStack)
|
||||
healedHealth = (caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) + sacrificedStack->MaxHealth() + spell->powers[caster->getSpellSchoolLevel(spell)]) * sacrificedStack->count;
|
||||
@ -173,15 +173,15 @@ ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell *
|
||||
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
|
||||
}
|
||||
//Archangel
|
||||
ui32 BattleInfo::calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const
|
||||
ui32 CBattleInfoCallback::calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const
|
||||
{
|
||||
bool resurrect = resurrects(spell->id);
|
||||
bool resurrect = spell->isRisingSpell();
|
||||
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
|
||||
}
|
||||
//Casted by stack, no hero bonus applied
|
||||
ui32 BattleInfo::calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const
|
||||
ui32 CBattleInfoCallback::calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const
|
||||
{
|
||||
bool resurrect = resurrects(spell->id);
|
||||
bool resurrect = spell->isRisingSpell();
|
||||
int healedHealth = usedSpellPower * spell->power + spell->powers[spellSchoolLevel];
|
||||
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
|
||||
}
|
||||
@ -893,6 +893,7 @@ void CStack::postInit()
|
||||
shots = getCreature()->valOfBonuses(Bonus::SHOTS);
|
||||
counterAttacks = 1 + valOfBonuses(Bonus::ADDITIONAL_RETALIATION);
|
||||
casts = valOfBonuses(Bonus::CASTS);
|
||||
resurrected = 0;
|
||||
}
|
||||
|
||||
ui32 CStack::level() const
|
||||
|
@ -125,14 +125,10 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
|
||||
CStack * generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, SlotID slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
|
||||
int getIdForNewStack() const; //suggest a currently unused ID that'd suitable for generating a new stack
|
||||
//std::pair<const CStack *, BattleHex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex)
|
||||
ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack = nullptr) const; //Sacrifice
|
||||
ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel
|
||||
ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //healing spells casted by stacks
|
||||
bool resurrects(SpellID spellid) const; //TODO: move it to spellHandler?
|
||||
|
||||
const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
|
||||
|
||||
|
||||
std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::vector<const CStack*> affectedCreatures, PlayerColor casterSideOwner, ECastingMode::ECastingMode mode, int usedSpellPower, int spellLevel) const;
|
||||
|
||||
const CStack * battleGetStack(BattleHex pos, bool onlyAlive); //returns stack at given tile
|
||||
@ -165,6 +161,7 @@ public:
|
||||
ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
|
||||
si16 shots; //how many shots left
|
||||
ui8 casts; //how many casts left
|
||||
TQuantity resurrected; // these units will be taken back after battle is over
|
||||
|
||||
std::set<EBattleStackState::EBattleStackState> state;
|
||||
//overrides
|
||||
@ -218,7 +215,7 @@ public:
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & static_cast<CStackBasicDescriptor&>(*this);
|
||||
h & ID & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
|
||||
& shots & casts & count;
|
||||
& shots & casts & count & resurrected;
|
||||
|
||||
const CArmedInstance *army = (base ? base->armyObj : nullptr);
|
||||
SlotID slot = (base ? base->armyObj->findStack(base) : SlotID());
|
||||
|
@ -1562,7 +1562,8 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
|
||||
|
||||
if (spell->isRisingSpell())
|
||||
{
|
||||
if (subject->count >= subject->baseAmount) //TODO: calculate potential hp raised
|
||||
auto maxHealth = calculateHealedHP (caster, spell, subject);
|
||||
if (subject->count >= subject->baseAmount || maxHealth < subject->MaxHealth()) //must be able to rise at least one full creature
|
||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||
}
|
||||
|
||||
@ -1663,7 +1664,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
|
||||
{
|
||||
const CGHeroInstance * caster = battleGetFightingHero(side);
|
||||
bool targetExists = false;
|
||||
for(const CStack * stack : battleAliveStacks())
|
||||
for(const CStack * stack : battleGetAllStacks()) //dead stacks will be immune anyway
|
||||
{
|
||||
switch (spell->positiveness)
|
||||
{
|
||||
@ -1941,8 +1942,9 @@ std::set<const CStack*> CBattleInfoCallback::getAffectedCreatures(const CSpell *
|
||||
|
||||
const ui8 attackerSide = playerToSide(attackerOwner) == 1;
|
||||
const auto attackedHexes = spell->rangeInHexes(destinationTile, skillLevel, attackerSide);
|
||||
const bool onlyAlive = spell->id != SpellID::RESURRECTION && spell->id != SpellID::ANIMATE_DEAD; //when casting resurrection or animate dead we should be allow to select dead stack
|
||||
//fixme: what about other rising spells (Sacrifice) ?
|
||||
const bool onlyAlive = !spell->isRisingSpell(); //when casting resurrection or animate dead we should be allow to select dead stack
|
||||
|
||||
//TODO: more generic solution for mass spells
|
||||
if(spell->id == SpellID::DEATH_RIPPLE || spell->id == SpellID::DESTROY_UNDEAD || spell->id == SpellID::ARMAGEDDON)
|
||||
{
|
||||
for(const CStack *stack : battleGetAllStacks())
|
||||
|
@ -260,6 +260,9 @@ public:
|
||||
std::vector<BattleHex> battleGetPossibleTargets(PlayerColor player, const CSpell *spell) const;
|
||||
ui32 calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const;
|
||||
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
|
||||
ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack = nullptr) const; //Sacrifice
|
||||
ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel
|
||||
ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //healing spells casted by stacks
|
||||
std::set<const CStack*> getAffectedCreatures(const CSpell * s, int skillLevel, PlayerColor attackerOwner, BattleHex destinationTile); //calculates stack affected by given spell
|
||||
|
||||
SpellID battleGetRandomStackSpell(const CStack * stack, ERandomSpell mode) const;
|
||||
|
@ -1403,12 +1403,12 @@ DLL_LINKAGE void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
if(resurrected)
|
||||
{
|
||||
changedStack->state.insert(EBattleStackState::ALIVE);
|
||||
if(elem.lowLevelResurrection)
|
||||
changedStack->state.insert(EBattleStackState::SUMMONED); //TODO: different counter for rised units
|
||||
}
|
||||
//int missingHPfirst = changedStack->MaxHealth() - changedStack->firstHPleft;
|
||||
int res = std::min( elem.healedHP / changedStack->MaxHealth() , changedStack->baseAmount - changedStack->count );
|
||||
changedStack->count += res;
|
||||
if(elem.lowLevelResurrection)
|
||||
changedStack->resurrected += res;
|
||||
changedStack->firstHPleft += elem.healedHP - res * changedStack->MaxHealth();
|
||||
if(changedStack->firstHPleft > changedStack->MaxHealth())
|
||||
{
|
||||
|
@ -6266,6 +6266,9 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
||||
if(vstd::contains(st->state, EBattleStackState::SUMMONED)) //don't take into account summoned stacks
|
||||
continue;
|
||||
|
||||
//FIXME: this info is also used in BattleInfo::calculateCasualties, refactor
|
||||
st->count = std::max (0, st->count - st->resurrected);
|
||||
|
||||
if(st->owner==color && !army->slotEmpty(st->slot) && st->count < army->getStackCount(st->slot))
|
||||
{
|
||||
StackLocation sl(army, st->slot);
|
||||
|
Loading…
Reference in New Issue
Block a user