mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-07 13:08:09 +02:00
New pack - BattleEffectTrigger for various one-shot effects with animation
This commit is contained in:
parent
f4fc77ccb8
commit
0903d6037c
@ -24,6 +24,7 @@ public:
|
|||||||
void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) OVERRIDE;
|
void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) OVERRIDE;
|
||||||
void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
|
void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
|
||||||
void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE;//called when a specific effect is set to stacks
|
void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE;//called when a specific effect is set to stacks
|
||||||
|
//void battleTriggerEffect(const BattleTriggerEffect & bte) OVERRIDE;
|
||||||
void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right
|
void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right
|
||||||
void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp
|
void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp
|
||||||
void battleNewStackAppeared(const CStack * stack) OVERRIDE; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
void battleNewStackAppeared(const CStack * stack) OVERRIDE; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
||||||
|
2
AUTHORS
2
AUTHORS
@ -29,7 +29,7 @@ Xiaomin Ding, <dingding303@gmail.com>
|
|||||||
* smack videos player
|
* smack videos player
|
||||||
|
|
||||||
Tom Zielinski aka Warmonger, <Warmonger@vp.pl>
|
Tom Zielinski aka Warmonger, <Warmonger@vp.pl>
|
||||||
* support for some of map objects and other items
|
* game objects, mechanics
|
||||||
|
|
||||||
Frank Zago aka ubuntux, <>
|
Frank Zago aka ubuntux, <>
|
||||||
* GCC/Linux compatibility changes, sound/music support, video support on Linux
|
* GCC/Linux compatibility changes, sound/music support, video support on Linux
|
||||||
|
@ -2631,47 +2631,6 @@ void CBattleInterface::stackRemoved(int stackID)
|
|||||||
|
|
||||||
void CBattleInterface::stackActivated(const CStack * stack) //TODO: check it all before game state is changed due to abilities
|
void CBattleInterface::stackActivated(const CStack * stack) //TODO: check it all before game state is changed due to abilities
|
||||||
{
|
{
|
||||||
//don't show animation when no HP is regenerated
|
|
||||||
if (stack->firstHPleft != stack->MaxHealth())
|
|
||||||
{
|
|
||||||
if( stack->hasBonusOfType(Bonus::HP_REGENERATION) || stack->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 1))
|
|
||||||
{
|
|
||||||
displayEffect(74, stack->position);
|
|
||||||
CCS->soundh->playSound(soundBase::REGENER);
|
|
||||||
}
|
|
||||||
if( stack->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 0))
|
|
||||||
{
|
|
||||||
displayEffect(74, stack->position);
|
|
||||||
CCS->soundh->playSound(soundBase::REGENER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stack->hasBonusOfType(Bonus::MANA_DRAIN))
|
|
||||||
{
|
|
||||||
CGHeroInstance * enemy = NULL; //probably could be smarter and not duplicated
|
|
||||||
if (defendingHero)
|
|
||||||
if (defendingHero->myHero->tempOwner != stack->owner)
|
|
||||||
enemy = const_cast<CGHeroInstance *>(defendingHero->myHero);
|
|
||||||
if (attackingHero)
|
|
||||||
if (attackingHero->myHero->tempOwner != stack->owner)
|
|
||||||
enemy = const_cast<CGHeroInstance *>(attackingHero->myHero);
|
|
||||||
if (enemy)
|
|
||||||
{
|
|
||||||
ui32 manaDrained = stack->valOfBonuses(Bonus::MANA_DRAIN);
|
|
||||||
amin (manaDrained, enemy->mana);
|
|
||||||
if (manaDrained)
|
|
||||||
{
|
|
||||||
displayEffect(77, stack->position);
|
|
||||||
CCS->soundh->playSound(soundBase::MANADRAI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(stack->hasBonusOfType(Bonus::POISON))
|
|
||||||
{
|
|
||||||
displayEffect(67, stack->position);
|
|
||||||
CCS->soundh->playSound(soundBase::POISON);
|
|
||||||
}
|
|
||||||
|
|
||||||
//givenCommand = NULL;
|
//givenCommand = NULL;
|
||||||
stackToActivate = stack;
|
stackToActivate = stack;
|
||||||
if(pendingAnims.size() == 0)
|
if(pendingAnims.size() == 0)
|
||||||
@ -3546,6 +3505,38 @@ void CBattleInterface::displayEffect(ui32 effect, int destTile)
|
|||||||
addNewAnim(new CSpellEffectAnim(this, effect, destTile));
|
addNewAnim(new CSpellEffectAnim(this, effect, destTile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBattleInterface::battleTriggerEffect(const BattleTriggerEffect & bte)
|
||||||
|
{
|
||||||
|
const CStack * stack = curInt->cb->battleGetStackByID(bte.stackID);
|
||||||
|
//don't show animation when no HP is regenerated
|
||||||
|
switch (bte.effect)
|
||||||
|
{
|
||||||
|
case Bonus::HP_REGENERATION:
|
||||||
|
if( stack->hasBonusOfType(Bonus::HP_REGENERATION) || stack->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 1))
|
||||||
|
{
|
||||||
|
displayEffect(74, stack->position);
|
||||||
|
CCS->soundh->playSound(soundBase::REGENER);
|
||||||
|
}
|
||||||
|
if( stack->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 0))
|
||||||
|
{
|
||||||
|
displayEffect(74, stack->position);
|
||||||
|
CCS->soundh->playSound(soundBase::REGENER);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Bonus::MANA_DRAIN:
|
||||||
|
displayEffect(77, stack->position);
|
||||||
|
CCS->soundh->playSound(soundBase::MANADRAI);
|
||||||
|
break;
|
||||||
|
case Bonus::POISON:
|
||||||
|
displayEffect(67, stack->position);
|
||||||
|
CCS->soundh->playSound(soundBase::POISON);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//waitForAnims(); //fixme: freezes game :?
|
||||||
|
}
|
||||||
|
|
||||||
void CBattleInterface::setAnimSpeed(int set)
|
void CBattleInterface::setAnimSpeed(int set)
|
||||||
{
|
{
|
||||||
curInt->sysOpts.animSpeed = set;
|
curInt->sysOpts.animSpeed = set;
|
||||||
|
@ -37,6 +37,7 @@ class CGTownInstance;
|
|||||||
struct CatapultAttack;
|
struct CatapultAttack;
|
||||||
class CBattleInterface;
|
class CBattleInterface;
|
||||||
struct CatapultProjectileInfo;
|
struct CatapultProjectileInfo;
|
||||||
|
struct BattleTriggerEffect;
|
||||||
|
|
||||||
/// Small struct which contains information about the id of the attacked stack, the damage dealt,...
|
/// Small struct which contains information about the id of the attacked stack, the damage dealt,...
|
||||||
struct SStackAttackedInfo
|
struct SStackAttackedInfo
|
||||||
@ -569,6 +570,7 @@ public:
|
|||||||
void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
|
void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
|
||||||
void castThisSpell(int spellID); //called when player has chosen a spell from spellbook
|
void castThisSpell(int spellID); //called when player has chosen a spell from spellbook
|
||||||
void displayEffect(ui32 effect, int destTile); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
|
void displayEffect(ui32 effect, int destTile); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
|
||||||
|
void battleTriggerEffect(const BattleTriggerEffect & bte);
|
||||||
void setBattleCursor(const int myNumber); //really complex and messy
|
void setBattleCursor(const int myNumber); //really complex and messy
|
||||||
void endAction(const BattleAction* action);
|
void endAction(const BattleAction* action);
|
||||||
void hideQueue();
|
void hideQueue();
|
||||||
|
@ -801,6 +801,10 @@ void CPlayerInterface::battleStacksEffectsSet( const SetStackEffect & sse )
|
|||||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
battleInt->battleStacksEffectsSet(sse);
|
battleInt->battleStacksEffectsSet(sse);
|
||||||
}
|
}
|
||||||
|
void CPlayerInterface::battleTriggerEffect (const BattleTriggerEffect & bte)
|
||||||
|
{
|
||||||
|
battleInt->battleTriggerEffect(bte);
|
||||||
|
}
|
||||||
void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa)
|
void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa)
|
||||||
{
|
{
|
||||||
if(LOCPLINT != this)
|
if(LOCPLINT != this)
|
||||||
|
@ -224,6 +224,7 @@ public:
|
|||||||
void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) OVERRIDE;
|
void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) OVERRIDE;
|
||||||
void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
|
void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
|
||||||
void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks
|
void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks
|
||||||
|
void battleTriggerEffect(const BattleTriggerEffect & bte) OVERRIDE; //various one-shot effect
|
||||||
void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE;
|
void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE;
|
||||||
void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right
|
void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right
|
||||||
void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected
|
void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected
|
||||||
|
@ -587,6 +587,11 @@ void BattleSetActiveStack::applyCl( CClient *cl )
|
|||||||
boost::thread( boost::bind(&CClient::waitForMoveAndSend, cl, playerToCall) );
|
boost::thread( boost::bind(&CClient::waitForMoveAndSend, cl, playerToCall) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleTriggerEffect::applyCl(CClient * cl)
|
||||||
|
{
|
||||||
|
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleTriggerEffect, *this);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleResult::applyFirstCl( CClient *cl )
|
void BattleResult::applyFirstCl( CClient *cl )
|
||||||
{
|
{
|
||||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleEnd,this);
|
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleEnd,this);
|
||||||
|
@ -126,6 +126,7 @@ public:
|
|||||||
virtual void battleNewRoundFirst(int round);
|
virtual void battleNewRoundFirst(int round);
|
||||||
virtual void actionFinished(const BattleAction *action);
|
virtual void actionFinished(const BattleAction *action);
|
||||||
virtual void battleStacksEffectsSet(const SetStackEffect & sse);
|
virtual void battleStacksEffectsSet(const SetStackEffect & sse);
|
||||||
|
//virtual void battleTriggerEffect(const BattleTriggerEffect & bte);
|
||||||
virtual void battleStacksRemoved(const BattleStacksRemoved & bsr);
|
virtual void battleStacksRemoved(const BattleStacksRemoved & bsr);
|
||||||
virtual void battleObstaclesRemoved(const std::set<si32> & removedObstacles);
|
virtual void battleObstaclesRemoved(const std::set<si32> & removedObstacles);
|
||||||
virtual void battleNewStackAppeared(const CStack * stack);
|
virtual void battleNewStackAppeared(const CStack * stack);
|
||||||
|
@ -30,6 +30,7 @@ class CStack;
|
|||||||
class CCreatureSet;
|
class CCreatureSet;
|
||||||
struct BattleAttack;
|
struct BattleAttack;
|
||||||
struct SetStackEffect;
|
struct SetStackEffect;
|
||||||
|
struct BattleTriggerEffect;
|
||||||
|
|
||||||
|
|
||||||
class DLL_EXPORT IBattleEventsReceiver
|
class DLL_EXPORT IBattleEventsReceiver
|
||||||
@ -45,6 +46,7 @@ public:
|
|||||||
virtual void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance){};
|
virtual void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance){};
|
||||||
virtual void battleSpellCast(const BattleSpellCast *sc){};
|
virtual void battleSpellCast(const BattleSpellCast *sc){};
|
||||||
virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks
|
virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks
|
||||||
|
virtual void battleTriggerEffect(const BattleTriggerEffect & bte){}; //called for various one-shot effects
|
||||||
virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right
|
virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right
|
||||||
virtual void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom){}; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp
|
virtual void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom){}; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp
|
||||||
virtual void battleNewStackAppeared(const CStack * stack){}; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
virtual void battleNewStackAppeared(const CStack * stack){}; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
||||||
|
@ -1522,6 +1522,26 @@ struct BattleSetStackProperty : public CPackForClient //3018
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BattleTriggerEffect : public CPackForClient //3019
|
||||||
|
{ //activated at the beginning of turn
|
||||||
|
BattleTriggerEffect(){type = 3019;};
|
||||||
|
|
||||||
|
DLL_EXPORT void applyGs(CGameState *gs); //effect
|
||||||
|
void applyCl(CClient *cl); //play animations & stuff
|
||||||
|
|
||||||
|
//enum BattleEffect {REGENERATION, MANA_DRAIN, FEAR, MANA_CHANNELING, ENCHANTER, UNBIND, POISON, ENCHANTED, SUMMONER};
|
||||||
|
|
||||||
|
int stackID;
|
||||||
|
int effect; //use enumBattleEffect or corresponding Bonus type for sanity?
|
||||||
|
int val;
|
||||||
|
int additionalInfo;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & stackID & effect & val & additionalInfo;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ShowInInfobox : public CPackForClient //107
|
struct ShowInInfobox : public CPackForClient //107
|
||||||
{
|
{
|
||||||
ShowInInfobox(){type = 107;};
|
ShowInInfobox(){type = 107;};
|
||||||
|
@ -858,34 +858,6 @@ DLL_EXPORT void BattleSetActiveStack::applyGs( CGameState *gs )
|
|||||||
gs->curB->activeStack = stack;
|
gs->curB->activeStack = stack;
|
||||||
CStack *st = gs->curB->getStack(stack);
|
CStack *st = gs->curB->getStack(stack);
|
||||||
|
|
||||||
if (st->alive())
|
|
||||||
{
|
|
||||||
//regeneration
|
|
||||||
if(st->hasBonusOfType(Bonus::HP_REGENERATION))
|
|
||||||
st->firstHPleft = std::min<ui32>( st->MaxHealth(), st->valOfBonuses(Bonus::HP_REGENERATION) );
|
|
||||||
if(st->hasBonusOfType(Bonus::FULL_HP_REGENERATION))
|
|
||||||
st->firstHPleft = st->MaxHealth();
|
|
||||||
if(st->hasBonusOfType(Bonus::POISON))
|
|
||||||
{
|
|
||||||
Bonus * b = st->getBonus(Selector::source(Bonus::SPELL_EFFECT, 71) && Selector::type(Bonus::STACK_HEALTH));
|
|
||||||
if (b) //TODO: what if not?...
|
|
||||||
{
|
|
||||||
b->val -= 10;
|
|
||||||
amax (b->val, -(st->valOfBonuses(Bonus::POISON)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(st->hasBonusOfType(Bonus::MANA_DRAIN))
|
|
||||||
{
|
|
||||||
const CGHeroInstance * enemy = gs->curB->getHero(gs->curB->theOtherPlayer(st->owner));
|
|
||||||
if (enemy)
|
|
||||||
{
|
|
||||||
ui32 manaDrained = st->valOfBonuses(Bonus::MANA_DRAIN);
|
|
||||||
amin (manaDrained, gs->curB->heroes[0]->mana);
|
|
||||||
gs->getHero(enemy->id)->mana -= manaDrained; //jeez, it's overcomplicate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove bonuses that last until when stack gets new turn
|
//remove bonuses that last until when stack gets new turn
|
||||||
st->getBonusList().remove_if(Bonus::UntilGetsTurn);
|
st->getBonusList().remove_if(Bonus::UntilGetsTurn);
|
||||||
|
|
||||||
@ -893,6 +865,36 @@ DLL_EXPORT void BattleSetActiveStack::applyGs( CGameState *gs )
|
|||||||
st->state.insert(HAD_MORALE);
|
st->state.insert(HAD_MORALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DLL_EXPORT void BattleTriggerEffect::applyGs( CGameState *gs )
|
||||||
|
{
|
||||||
|
CStack *st = gs->curB->getStack(stackID);
|
||||||
|
switch (effect)
|
||||||
|
{
|
||||||
|
case Bonus::HP_REGENERATION:
|
||||||
|
st->firstHPleft += val;
|
||||||
|
amin (st->firstHPleft, (ui32)st->MaxHealth());
|
||||||
|
break;
|
||||||
|
case Bonus::MANA_DRAIN:
|
||||||
|
{
|
||||||
|
CGHeroInstance * h = gs->getHero(additionalInfo);
|
||||||
|
h->mana -= val;
|
||||||
|
amax(h->mana, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Bonus::POISON:
|
||||||
|
{
|
||||||
|
Bonus * b = st->getBonus(Selector::source(Bonus::SPELL_EFFECT, 71) && Selector::type(Bonus::STACK_HEALTH));
|
||||||
|
if (b)
|
||||||
|
b->val = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Bonus::ENCHANTER:
|
||||||
|
case Bonus::FEAR:
|
||||||
|
default:
|
||||||
|
tlog2 << "Unrecognized trigger effect type "<< type <<"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BattleResult::applyGs( CGameState *gs )
|
void BattleResult::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
//stack with SUMMONED flag but coming from garrison -> most likely resurrected, needs to be removed
|
//stack with SUMMONED flag but coming from garrison -> most likely resurrected, needs to be removed
|
||||||
|
@ -150,6 +150,7 @@ void registerTypes2(Serializer &s)
|
|||||||
s.template registerType<EndAction>();
|
s.template registerType<EndAction>();
|
||||||
s.template registerType<BattleSpellCast>();
|
s.template registerType<BattleSpellCast>();
|
||||||
s.template registerType<SetStackEffect>();
|
s.template registerType<SetStackEffect>();
|
||||||
|
s.template registerType<BattleTriggerEffect>();
|
||||||
s.template registerType<BattleSetStackProperty>();
|
s.template registerType<BattleSetStackProperty>();
|
||||||
s.template registerType<StacksInjured>();
|
s.template registerType<StacksInjured>();
|
||||||
s.template registerType<BattleResultsApplied>();
|
s.template registerType<BattleResultsApplied>();
|
||||||
|
@ -3935,6 +3935,70 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||||
|
{
|
||||||
|
BattleTriggerEffect bte;
|
||||||
|
bte.stackID = st->ID;
|
||||||
|
bte.effect = -1;
|
||||||
|
bte.val = 0;
|
||||||
|
bte.additionalInfo = 0;
|
||||||
|
if (st->alive())
|
||||||
|
{
|
||||||
|
//regeneration
|
||||||
|
if(st->hasBonusOfType(Bonus::HP_REGENERATION))
|
||||||
|
{
|
||||||
|
bte.effect = Bonus::HP_REGENERATION;
|
||||||
|
bte.val = std::min((int)(st->MaxHealth() - st->firstHPleft), st->valOfBonuses(Bonus::HP_REGENERATION));
|
||||||
|
}
|
||||||
|
if(st->hasBonusOfType(Bonus::FULL_HP_REGENERATION))
|
||||||
|
{
|
||||||
|
bte.effect = Bonus::HP_REGENERATION;
|
||||||
|
bte.val = st->MaxHealth() - st->firstHPleft;
|
||||||
|
}
|
||||||
|
if (bte.val) //anything to heal
|
||||||
|
sendAndApply(&bte);
|
||||||
|
|
||||||
|
if(st->hasBonusOfType(Bonus::POISON))
|
||||||
|
{
|
||||||
|
const Bonus * b = st->getBonus(Selector::source(Bonus::SPELL_EFFECT, 71) && Selector::type(Bonus::STACK_HEALTH));
|
||||||
|
if (b) //TODO: what if not?...
|
||||||
|
{
|
||||||
|
bte.val = std::max (b->val - 10, -(st->valOfBonuses(Bonus::POISON)));
|
||||||
|
if (bte.val < b->val) //(negative) poison effect increases - update it
|
||||||
|
{
|
||||||
|
bte.effect = Bonus::POISON;
|
||||||
|
sendAndApply(&bte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(st->hasBonusOfType(Bonus::MANA_DRAIN))
|
||||||
|
{
|
||||||
|
const CGHeroInstance * enemy = gs->curB->getHero(gs->curB->theOtherPlayer(st->owner));
|
||||||
|
if (enemy)
|
||||||
|
{
|
||||||
|
ui32 manaDrained = st->valOfBonuses(Bonus::MANA_DRAIN);
|
||||||
|
amin (manaDrained, gs->curB->heroes[0]->mana);
|
||||||
|
if (manaDrained)
|
||||||
|
{
|
||||||
|
bte.effect = Bonus::MANA_DRAIN;
|
||||||
|
bte.val = manaDrained;
|
||||||
|
bte.additionalInfo = enemy->id; //for sanity
|
||||||
|
sendAndApply(&bte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BonusList * bl = st->getBonuses(Selector::type(Bonus::ENCHANTER)).get();
|
||||||
|
if (bl->size())
|
||||||
|
{
|
||||||
|
bte.effect = Bonus::ENCHANTER;
|
||||||
|
int index = rand() % bl->size();
|
||||||
|
bte.val = (*bl)[index]->subtype; //spell ID
|
||||||
|
bte.additionalInfo = (*bl)[index]->val; //spell level
|
||||||
|
sendAndApply(&bte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CGameHandler::handleTimeEvents()
|
void CGameHandler::handleTimeEvents()
|
||||||
{
|
{
|
||||||
gs->map->events.sort(evntCmp);
|
gs->map->events.sort(evntCmp);
|
||||||
@ -5207,6 +5271,8 @@ void CGameHandler::runBattle()
|
|||||||
{//ask interface and wait for answer
|
{//ask interface and wait for answer
|
||||||
if(!battleResult.get())
|
if(!battleResult.get())
|
||||||
{
|
{
|
||||||
|
stackTurnTrigger(next); //various effects
|
||||||
|
|
||||||
BattleSetActiveStack sas;
|
BattleSetActiveStack sas;
|
||||||
sas.stack = next->ID;
|
sas.stack = next->ID;
|
||||||
sendAndApply(&sas);
|
sendAndApply(&sas);
|
||||||
|
@ -199,6 +199,7 @@ public:
|
|||||||
bool makeBattleAction(BattleAction &ba);
|
bool makeBattleAction(BattleAction &ba);
|
||||||
void handleSpellCasting(int spellID, int spellLvl, THex destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero, int usedSpellPower, SpellCasting::ECastingMode mode, const CStack * stack);
|
void handleSpellCasting(int spellID, int spellLvl, THex destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero, int usedSpellPower, SpellCasting::ECastingMode mode, const CStack * stack);
|
||||||
bool makeCustomAction(BattleAction &ba);
|
bool makeCustomAction(BattleAction &ba);
|
||||||
|
void stackTurnTrigger(const CStack * stack);
|
||||||
bool queryReply( ui32 qid, ui32 answer, ui8 player );
|
bool queryReply( ui32 qid, ui32 answer, ui8 player );
|
||||||
bool hireHero( const CGObjectInstance *obj, ui8 hid, ui8 player );
|
bool hireHero( const CGObjectInstance *obj, ui8 hid, ui8 player );
|
||||||
bool buildBoat( ui32 objid );
|
bool buildBoat( ui32 objid );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user