diff --git a/lib/NetPacks.h b/lib/NetPacks.h index a931983a1..b82e6188a 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -274,17 +274,18 @@ struct ChangeSpells : public CPackForClient //109 struct SetMana : public CPackForClient //110 { - SetMana(){type = 110;}; + SetMana(){type = 110;absolute=true;}; void applyCl(CClient *cl); DLL_LINKAGE void applyGs(CGameState *gs); ObjectInstanceID hid; si32 val; + bool absolute; template void serialize(Handler &h, const int version) { - h & val & hid; + h & val & hid & absolute; } }; @@ -1447,7 +1448,6 @@ struct BattleSpellCast : public CPackForClient//3009 ui8 side; //which hero did cast spell: 0 - attacker, 1 - defender ui32 id; //id of spell ui8 skill; //caster's skill level - ui8 spellCost; ui8 manaGained; //mana channeling ability BattleHex tile; //destination tile (may not be set in some global/mass spells std::vector resisted; //ids of creatures that resisted this spell @@ -1456,7 +1456,7 @@ struct BattleSpellCast : public CPackForClient//3009 bool castedByHero; //if true - spell has been casted by hero, otherwise by a creature template void serialize(Handler &h, const int version) { - h & dmgToDisplay & side & id & skill & spellCost & manaGained & tile & resisted & affectedCres & attackerType & castedByHero; + h & dmgToDisplay & side & id & skill & tile & resisted & affectedCres & attackerType & castedByHero; } }; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 60538d031..c6c6a992c 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -184,9 +184,16 @@ DLL_LINKAGE void ChangeSpells::applyGs( CGameState *gs ) DLL_LINKAGE void SetMana::applyGs( CGameState *gs ) { - CGHeroInstance *hero = gs->getHero(hid); - vstd::amax(val, 0); //not less than 0 - hero->mana = val; + CGHeroInstance * hero = gs->getHero(hid); + + assert(hero); + + if(absolute) + hero->mana = val; + else + hero->mana += val; + + vstd::amax(hero->mana, 0); //not less than 0 } DLL_LINKAGE void SetMovePoints::applyGs( CGameState *gs ) @@ -1330,13 +1337,6 @@ DLL_LINKAGE void BattleSpellCast::applyGs( CGameState *gs ) assert(gs->curB); if (castedByHero) { - CGHeroInstance * h = gs->curB->battleGetFightingHero(side); - CGHeroInstance * enemy = gs->curB->battleGetFightingHero(!side); - - h->mana -= spellCost; - vstd::amax(h->mana, 0); - if (enemy && manaGained) - enemy->mana += manaGained; if (side < 2) { gs->curB->sides[side].castSpellsCount++; diff --git a/lib/SpellMechanics.cpp b/lib/SpellMechanics.cpp index 66dd9700a..01ba77432 100644 --- a/lib/SpellMechanics.cpp +++ b/lib/SpellMechanics.cpp @@ -368,12 +368,13 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS sc.castedByHero = nullptr != parameters.caster; sc.attackerType = (parameters.casterStack ? parameters.casterStack->type->idNumber : CreatureID(CreatureID::NONE)); sc.manaGained = 0; - sc.spellCost = 0; + + int spellCost = 0; //calculate spell cost if(parameters.caster) { - sc.spellCost = parameters.cb->battleGetSpellCost(owner, parameters.caster); + spellCost = parameters.cb->battleGetSpellCost(owner, parameters.caster); if(parameters.secHero && parameters.mode == ECastingMode::HERO_CASTING) //handle mana channel { @@ -385,7 +386,7 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS vstd::amax(manaChannel, stack->valOfBonuses(Bonus::MANA_CHANNELING)); } } - sc.manaGained = (manaChannel * sc.spellCost) / 100; + sc.manaGained = (manaChannel * spellCost) / 100; } } @@ -423,6 +424,29 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS applyBattleEffects(env, parameters, ctx); env->sendAndApply(&sc); + + + //spend mana + if(parameters.caster) + { + SetMana sm; + sm.absolute = false; + + sm.hid = parameters.caster->id; + sm.val = -spellCost; + + env->sendAndApply(&sm); + + if(sc.manaGained > 0) + { + assert(parameters.secHero); + + sm.hid = parameters.secHero->id; + sm.val = sc.manaGained; + env->sendAndApply(&sm); + } + } + if(!si.stacks.empty()) //after spellcast info shows env->sendAndApply(&si); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index b731ae897..7363af610 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2045,6 +2045,7 @@ void CGameHandler::setManaPoints( ObjectInstanceID hid, int val ) SetMana sm; sm.hid = hid; sm.val = val; + sm.absolute = true; sendAndApply(&sm); } @@ -3830,6 +3831,7 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message //give mana sm.val = 999; + sm.absolute = true; if(!h->hasSpellbook()) //hero doesn't have spellbook giveHeroNewArtifact(h, VLC->arth->artifacts.at(0), ArtifactPosition::SPELLBOOK); //give spellbook @@ -5146,7 +5148,8 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, SpellID spellID, const int SetMana sm; sm.hid = h->id; - sm.val = h->mana - cost; + sm.absolute = false; + sm.val = -cost; sendAndApply(&sm); return true;