mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	initial implementation.
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user