|
@@ -152,6 +152,115 @@ void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast *
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+///EarthquakeMechanics
|
|
|
|
+void EarthquakeMechanics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
|
|
|
+{
|
|
|
|
+ if(nullptr == parameters.cb->town)
|
|
|
|
+ {
|
|
|
|
+ env->complain("EarthquakeMechanics: not town siege");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(CGTownInstance::NONE == parameters.cb->town->fortLevel())
|
|
|
|
+ {
|
|
|
|
+ env->complain("EarthquakeMechanics: town has no fort");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //start with all destructible parts
|
|
|
|
+ std::set<EWallPart::EWallPart> possibleTargets =
|
|
|
|
+ {
|
|
|
|
+ EWallPart::KEEP,
|
|
|
|
+ EWallPart::BOTTOM_TOWER,
|
|
|
|
+ EWallPart::BOTTOM_WALL,
|
|
|
|
+ EWallPart::BELOW_GATE,
|
|
|
|
+ EWallPart::OVER_GATE,
|
|
|
|
+ EWallPart::UPPER_WALL,
|
|
|
|
+ EWallPart::UPPER_TOWER,
|
|
|
|
+ EWallPart::GATE
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ assert(possibleTargets.size() == EWallPart::PARTS_COUNT);
|
|
|
|
+
|
|
|
|
+ const int targetsToAttack = 2 + std::max<int>(parameters.spellLvl - 1, 0);
|
|
|
|
+
|
|
|
|
+ CatapultAttack ca;
|
|
|
|
+ ca.attacker = -1;
|
|
|
|
+
|
|
|
|
+ for(int i = 0; i < targetsToAttack; i++)
|
|
|
|
+ {
|
|
|
|
+ //Any destructible part can be hit regardless of its HP. Multiple hit on same target is allowed.
|
|
|
|
+ EWallPart::EWallPart target = *RandomGeneratorUtil::nextItem(possibleTargets, env->getRandomGenerator());
|
|
|
|
+
|
|
|
|
+ auto & currentHP = parameters.cb->si.wallState;
|
|
|
|
+
|
|
|
|
+ if(currentHP.at(target) == EWallState::DESTROYED || currentHP.at(target) == EWallState::NONE)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ CatapultAttack::AttackInfo attackInfo;
|
|
|
|
+
|
|
|
|
+ attackInfo.damageDealt = 1;
|
|
|
|
+ attackInfo.attackedPart = target;
|
|
|
|
+ attackInfo.destinationTile = parameters.cb->wallPartToBattleHex(target);
|
|
|
|
+
|
|
|
|
+ ca.attackedParts.push_back(attackInfo);
|
|
|
|
+
|
|
|
|
+ //removing creatures in turrets / keep if one is destroyed
|
|
|
|
+ BattleHex posRemove;
|
|
|
|
+
|
|
|
|
+ switch(target)
|
|
|
|
+ {
|
|
|
|
+ case EWallPart::KEEP:
|
|
|
|
+ posRemove = -2;
|
|
|
|
+ break;
|
|
|
|
+ case EWallPart::BOTTOM_TOWER:
|
|
|
|
+ posRemove = -3;
|
|
|
|
+ break;
|
|
|
|
+ case EWallPart::UPPER_TOWER:
|
|
|
|
+ posRemove = -4;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(posRemove != BattleHex::INVALID)
|
|
|
|
+ {
|
|
|
|
+ BattleStacksRemoved bsr;
|
|
|
|
+ for(auto & elem : parameters.cb->stacks)
|
|
|
|
+ {
|
|
|
|
+ if(elem->position == posRemove)
|
|
|
|
+ {
|
|
|
|
+ bsr.stackIDs.insert(elem->ID);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(bsr.stackIDs.size() > 0)
|
|
|
|
+ env->sendAndApply(&bsr);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ env->sendAndApply(&ca);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+ESpellCastProblem::ESpellCastProblem EarthquakeMechanics::canBeCasted(const CBattleInfoCallback * cb, PlayerColor player) const
|
|
|
|
+{
|
|
|
|
+ if(nullptr == cb->battleGetDefendedTown())
|
|
|
|
+ {
|
|
|
|
+ return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(CGTownInstance::NONE == cb->battleGetDefendedTown()->fortLevel())
|
|
|
|
+ {
|
|
|
|
+ return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(owner->getTargetInfo(0).smart) //TODO: use real spell level
|
|
|
|
+ {
|
|
|
|
+ //if spell targeting is smart, then only attacker can use it
|
|
|
|
+ if(cb->playerToSide(player) != 0)
|
|
|
|
+ return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ESpellCastProblem::OK;
|
|
|
|
+}
|
|
|
|
|
|
///HypnotizeMechanics
|
|
///HypnotizeMechanics
|
|
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
|
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|