mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
initial implementation.
This commit is contained in:
parent
323c4e1637
commit
69c458e881
@ -1188,19 +1188,22 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
|
||||
void CBattleInterface::stackIsCatapulting(const CatapultAttack & ca)
|
||||
{
|
||||
for(auto it = ca.attackedParts.begin(); it != ca.attackedParts.end(); ++it)
|
||||
if(ca.attacker != -1) //no shooting animation for spells like earthquake
|
||||
{
|
||||
const CStack * stack = curInt->cb->battleGetStackByID(ca.attacker);
|
||||
addNewAnim(new CShootingAnimation(this, stack, it->destinationTile, nullptr, true, it->damageDealt));
|
||||
for(auto attackInfo : ca.attackedParts)
|
||||
{
|
||||
addNewAnim(new CShootingAnimation(this, stack, attackInfo.destinationTile, nullptr, true, attackInfo.damageDealt));
|
||||
}
|
||||
}
|
||||
|
||||
waitForAnims();
|
||||
|
||||
for(auto it = ca.attackedParts.begin(); it != ca.attackedParts.end(); ++it)
|
||||
for(auto attackInfo : ca.attackedParts)
|
||||
{
|
||||
SDL_FreeSurface(siegeH->walls[it->attackedPart + 2]);
|
||||
siegeH->walls[it->attackedPart + 2] = BitmapHandler::loadBitmap(
|
||||
siegeH->getSiegeName(it->attackedPart + 2, curInt->cb->battleGetWallState(it->attackedPart)) );
|
||||
SDL_FreeSurface(siegeH->walls[attackInfo.attackedPart + 2]);
|
||||
siegeH->walls[attackInfo.attackedPart + 2] = BitmapHandler::loadBitmap(
|
||||
siegeH->getSiegeName(attackInfo.attackedPart + 2, curInt->cb->battleGetWallState(attackInfo.attackedPart)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1555,7 +1555,6 @@ struct ObstaclesRemoved : public CPackForClient //3014
|
||||
};
|
||||
|
||||
struct ELF_VISIBILITY CatapultAttack : public CPackForClient //3015
|
||||
|
||||
{
|
||||
struct AttackInfo
|
||||
{
|
||||
|
@ -152,6 +152,83 @@ 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 damagable 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);
|
||||
|
||||
vstd::erase_if(possibleTargets, [parameters](EWallPart::EWallPart part)
|
||||
{
|
||||
return (parameters.cb->si.wallState[part] == EWallState::DESTROYED) || (parameters.cb->si.wallState[part] == EWallState::NONE);
|
||||
});
|
||||
|
||||
if(0 == possibleTargets.size())
|
||||
{
|
||||
env->complain("EarthquakeMechanics: no target to attack");
|
||||
return;
|
||||
}
|
||||
|
||||
int targetsToAttack = 2;
|
||||
|
||||
switch(parameters.spellLvl)
|
||||
{
|
||||
case 2:
|
||||
targetsToAttack = 3;
|
||||
break;
|
||||
case 3:
|
||||
targetsToAttack = 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CatapultAttack ca;
|
||||
ca.attacker = -1;
|
||||
|
||||
do
|
||||
{
|
||||
EWallPart::EWallPart target = *RandomGeneratorUtil::nextItem(possibleTargets, env->getRandomGenerator());
|
||||
|
||||
CatapultAttack::AttackInfo attackInfo;
|
||||
|
||||
attackInfo.damageDealt = 1;
|
||||
attackInfo.attackedPart = target;
|
||||
attackInfo.destinationTile = BattleHex::INVALID;
|
||||
|
||||
ca.attackedParts.push_back(attackInfo);
|
||||
|
||||
possibleTargets.erase(target);
|
||||
targetsToAttack--;
|
||||
}
|
||||
while(targetsToAttack > 0 && possibleTargets.size() > 0);
|
||||
|
||||
env->sendAndApply(&ca);
|
||||
}
|
||||
|
||||
///HypnotizeMechanics
|
||||
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
||||
|
@ -44,6 +44,14 @@ public:
|
||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE EarthquakeMechanics : public DefaultSpellMechanics
|
||||
{
|
||||
public:
|
||||
EarthquakeMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||
protected:
|
||||
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE HypnotizeMechanics : public DefaultSpellMechanics
|
||||
{
|
||||
public:
|
||||
|
@ -42,6 +42,8 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
|
||||
return new DispellMechanics(s);
|
||||
case SpellID::DISPEL_HELPFUL_SPELLS:
|
||||
return new DispellHelpfulMechanics(s);
|
||||
case SpellID::EARTHQUAKE:
|
||||
return new EarthquakeMechanics(s);
|
||||
case SpellID::FIRE_WALL:
|
||||
case SpellID::FORCE_FIELD:
|
||||
return new WallMechanics(s);
|
||||
|
Loading…
Reference in New Issue
Block a user