浏览代码

Handle HYPNOTIZE effect in case of mana drain

AlexVinS 9 年之前
父节点
当前提交
83b3c700dd
共有 5 个文件被更改,包括 25 次插入14 次删除
  1. 1 6
      lib/BattleState.cpp
  2. 1 2
      lib/BattleState.h
  3. 17 2
      lib/CBattleCallback.cpp
  4. 3 0
      lib/CBattleCallback.h
  5. 3 4
      server/CGameHandler.cpp

+ 1 - 6
lib/BattleState.cpp

@@ -95,7 +95,7 @@ std::pair< std::vector<BattleHex>, int > BattleInfo::getPath(BattleHex start, Ba
 	return std::make_pair(path, reachability.distances[dest]);
 }
 
-ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero,
+ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender,
 	bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg, CRandomGenerator & rand )
 {
 	TDmgRange range = calculateDmgRange(attacker, defender, shooting, charge, lucky, unlucky, deathBlow, ballistaDoubleDmg);
@@ -150,11 +150,6 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
 	return ret;
 }
 
-const CGHeroInstance * BattleInfo::battleGetOwner(const CStack * stack) const
-{
-	return sides[!stack->attackerOwned].hero;
-}
-
 void BattleInfo::localInit()
 {
 	for(int i = 0; i < 2; i++)

+ 1 - 2
lib/BattleState.h

@@ -129,7 +129,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 	std::shared_ptr<CObstacleInstance> getObstacleOnTile(BattleHex tile) const;
 	std::set<BattleHex> getStoppers(bool whichSidePerspective) const;
 
-	ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg, CRandomGenerator & rand); //charge - number of hexes travelled before attack (for champion's jousting)
+	ui32 calculateDmg(const CStack * attacker, const CStack * defender, bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg, CRandomGenerator & rand); //charge - number of hexes travelled before attack (for champion's jousting)
 	void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount)
 
 	//void getPotentiallyAttackableHexes(AttackableTiles &at, const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos); //hexes around target that could be attacked in melee
@@ -142,7 +142,6 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 
 	const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
 
-	const CGHeroInstance * battleGetOwner(const CStack * stack) const; //returns hero that owns given stack; nullptr if none
 	void localInit();
 
 	void localInitStack(CStack * s);

+ 17 - 2
lib/CBattleCallback.cpp

@@ -429,7 +429,7 @@ bool CBattleInfoEssentials::playerHasAccessToHeroInfo(PlayerColor player, const
 {
 	RETURN_IF_NOT_BATTLE(false);
 	ui8 playerSide = playerToSide(player);
-	if (playerSide >= 0)
+	if (playerSide != (ui8)-1)
 	{
 		if (getBattle()->sides[!playerSide].hero == h)
 			return true;
@@ -478,6 +478,22 @@ EGateState CBattleInfoEssentials::battleGetGateState() const
 	return getBattle()->si.gateState;
 }
 
+
+PlayerColor CBattleInfoEssentials::battleGetOwner(const CStack * stack) const
+{
+	RETURN_IF_NOT_BATTLE(PlayerColor::CANNOT_DETERMINE);
+	if(stack->hasBonusOfType(Bonus::HYPNOTIZED))
+		return getBattle()->theOtherPlayer(stack->owner);
+	else
+		return stack->owner;
+}
+
+const CGHeroInstance * CBattleInfoEssentials::battleGetOwnerHero(const CStack * stack) const
+{
+	RETURN_IF_NOT_BATTLE(nullptr);
+	return getBattle()->sides.at(playerToSide(battleGetOwner(stack))).hero;
+}
+
 si8 CBattleInfoCallback::battleHasWallPenalty( const CStack * stack, BattleHex destHex ) const
 {
 	return battleHasWallPenalty(stack, stack->position, destHex);
@@ -862,7 +878,6 @@ bool CBattleInfoCallback::battleCanShoot(const CStack * stack, BattleHex dest) c
 	if(stack->getCreature()->idNumber == CreatureID::CATAPULT && dst) //catapult cannot attack creatures
 		return false;
 
-	//const CGHeroInstance * stackHero = battleGetOwner(stack);
 	if(stack->hasBonusOfType(Bonus::SHOOTER)//it's shooter
 		&& stack->owner != dst->owner
 		&& dst->alive()

+ 3 - 0
lib/CBattleCallback.h

@@ -213,6 +213,9 @@ public:
 	TStacks battleAliveStacks(ui8 side) const;
 	const CStack * battleGetStackByID(int ID, bool onlyAlive = true) const; //returns stack info by given ID
 	bool battleIsObstacleVisibleForSide(const CObstacleInstance & coi, BattlePerspective::BattlePerspective side) const;
+
+	PlayerColor battleGetOwner(const CStack * stack) const; //returns player that controls given stack; mind control included
+	const CGHeroInstance * battleGetOwnerHero(const CStack * stack) const; //returns hero that controls given stack; nullptr if none; mind control included
 };
 
 struct DLL_LINKAGE BattleAttackInfo

+ 3 - 4
server/CGameHandler.cpp

@@ -875,8 +875,7 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
 		bsa.flags |= BattleStackAttacked::SECONDARY; //all other targets do not suffer from spells & spell-like abilities
 	bsa.attackerID = att->ID;
 	bsa.stackAttacked = def->ID;
-	bsa.damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def),
-		bat.shot(), distance, bat.lucky(), bat.unlucky(), bat.deathBlow(), bat.ballistaDoubleDmg(), getRandomGenerator());
+	bsa.damageAmount = gs->curB->calculateDmg(att, def, bat.shot(), distance, bat.lucky(), bat.unlucky(), bat.deathBlow(), bat.ballistaDoubleDmg(), getRandomGenerator());
 	def->prepareAttacked(bsa, getRandomGenerator()); //calculate casualties
 
 	//life drain handling
@@ -4537,7 +4536,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
 		}
 		if (st->hasBonusOfType(Bonus::MANA_DRAIN) && !vstd::contains(st->state, EBattleStackState::DRAINED_MANA))
 		{
-			const PlayerColor opponent = gs->curB->theOtherPlayer(st->owner);
+			const PlayerColor opponent = gs->curB->theOtherPlayer(gs->curB->battleGetOwner(st));
 			const CGHeroInstance * opponentHero = gs->curB->getHero(opponent);
 			if (opponentHero)
 			{
@@ -5727,7 +5726,7 @@ void CGameHandler::runBattle()
 				continue;
 			}
 
-			const CGHeroInstance * curOwner = gs->curB->battleGetOwner(next);
+			const CGHeroInstance * curOwner = gs->curB->battleGetOwnerHero(next);
 
 			if( (next->position < 0 || next->getCreature()->idNumber == CreatureID::BALLISTA)	//arrow turret or ballista
 				&& (!curOwner || curOwner->getSecSkillLevel(SecondarySkill::ARTILLERY) == 0)) //hero has no artillery