Browse Source

Implemented semi-transparent spell effects

Ivan Savenko 1 year ago
parent
commit
dfe6e04464

+ 9 - 7
client/battle/BattleAnimationClasses.cpp

@@ -881,9 +881,10 @@ uint32_t CastAnimation::getAttackClimaxFrame() const
 	return maxFrames / 2;
 }
 
-EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects, bool reversed):
+EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects, float transparencyFactor, bool reversed):
 	BattleAnimation(owner),
 	animation(GH.renderHandler().loadAnimation(animationName, EImageBlitMode::SIMPLE)),
+	transparencyFactor(transparencyFactor),
 	effectFlags(effects),
 	effectFinished(false),
 	reversed(reversed)
@@ -892,32 +893,32 @@ EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath &
 }
 
 EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector<BattleHex> hex, int effects, bool reversed):
-	EffectAnimation(owner, animationName, effects, reversed)
+	EffectAnimation(owner, animationName, effects, 1.0f, reversed)
 {
 	battlehexes = hex;
 }
 
-EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, BattleHex hex, int effects, bool reversed):
-	EffectAnimation(owner, animationName, effects, reversed)
+EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, BattleHex hex, int effects, float transparencyFactor, bool reversed):
+	EffectAnimation(owner, animationName, effects, transparencyFactor, reversed)
 {
 	assert(hex.isValid());
 	battlehexes.push_back(hex);
 }
 
 EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector<Point> pos, int effects, bool reversed):
-	EffectAnimation(owner, animationName, effects, reversed)
+	EffectAnimation(owner, animationName, effects, 1.0f, reversed)
 {
 	positions = pos;
 }
 
 EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos, int effects, bool reversed):
-	EffectAnimation(owner, animationName, effects, reversed)
+	EffectAnimation(owner, animationName, effects, 1.0f, reversed)
 {
 	positions.push_back(pos);
 }
 
 EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos, BattleHex hex, int effects, bool reversed):
-	EffectAnimation(owner, animationName, effects, reversed)
+	EffectAnimation(owner, animationName, effects, 1.0f, reversed)
 {
 	assert(hex.isValid());
 	battlehexes.push_back(hex);
@@ -951,6 +952,7 @@ bool EffectAnimation::init()
 	be.effectID = ID;
 	be.animation = animation;
 	be.currentFrame = 0;
+	be.transparencyFactor = transparencyFactor;
 	be.type = reversed ? BattleEffect::AnimType::REVERSE : BattleEffect::AnimType::DEFAULT;
 
 	for (size_t i = 0; i < std::max(battlehexes.size(), positions.size()); ++i)

+ 4 - 3
client/battle/BattleAnimationClasses.h

@@ -309,9 +309,10 @@ public:
 class EffectAnimation : public BattleAnimation
 {
 	std::string soundName;
+	int effectFlags;
+	float transparencyFactor;
 	bool effectFinished;
 	bool reversed;
-	int effectFlags;
 
 	std::shared_ptr<CAnimation>	animation;
 	std::vector<Point> positions;
@@ -335,14 +336,14 @@ public:
 	};
 
 	/// Create animation with screen-wide effect
-	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects = 0, bool reversed = false);
+	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects = 0, float transparencyFactor = 1.f, bool reversed = false);
 
 	/// Create animation positioned at point(s). Note that positions must be are absolute, including battleint position offset
 	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos                 , int effects = 0, bool reversed = false);
 	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector<Point> pos    , int effects = 0, bool reversed = false);
 
 	/// Create animation positioned at certain hex(es)
-	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, BattleHex hex             , int effects = 0, bool reversed = false);
+	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, BattleHex hex             , int effects = 0, float transparencyFactor = 1.0f, bool reversed = false);
 	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector<BattleHex> hex, int effects = 0, bool reversed = false);
 
 	EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos, BattleHex hex,   int effects = 0, bool reversed = false);

+ 5 - 4
client/battle/BattleEffectsController.cpp

@@ -44,7 +44,7 @@ void BattleEffectsController::displayEffect(EBattleEffect effect, const BattleHe
 	displayEffect(effect, AudioPath(), destTile);
 }
 
-void BattleEffectsController::displayEffect(EBattleEffect effect, const AudioPath & soundFile, const BattleHex & destTile)
+void BattleEffectsController::displayEffect(EBattleEffect effect, const AudioPath & soundFile, const BattleHex & destTile, float transparencyFactor)
 {
 	size_t effectID = static_cast<size_t>(effect);
 
@@ -52,7 +52,7 @@ void BattleEffectsController::displayEffect(EBattleEffect effect, const AudioPat
 
 	CCS->soundh->playSound( soundFile );
 
-	owner.stacksController->addNewAnim(new EffectAnimation(owner, customAnim, destTile));
+	owner.stacksController->addNewAnim(new EffectAnimation(owner, customAnim, destTile, 0, transparencyFactor));
 }
 
 void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bte)
@@ -69,7 +69,7 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt
 	switch(static_cast<BonusType>(bte.effect))
 	{
 		case BonusType::HP_REGENERATION:
-			displayEffect(EBattleEffect::REGENERATION, AudioPath::builtin("REGENER"), stack->getPosition());
+			displayEffect(EBattleEffect::REGENERATION, AudioPath::builtin("REGENER"), stack->getPosition(), 0.5);
 			break;
 		case BonusType::MANA_DRAIN:
 			displayEffect(EBattleEffect::MANA_DRAIN, AudioPath::builtin("MANADRAI"), stack->getPosition());
@@ -78,7 +78,7 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt
 			displayEffect(EBattleEffect::POISON, AudioPath::builtin("POISON"), stack->getPosition());
 			break;
 		case BonusType::FEAR:
-			displayEffect(EBattleEffect::FEAR, AudioPath::builtin("FEAR"), stack->getPosition());
+			displayEffect(EBattleEffect::FEAR, AudioPath::builtin("FEAR"), stack->getPosition(), 0.5);
 			break;
 		case BonusType::MORALE:
 		{
@@ -124,6 +124,7 @@ void BattleEffectsController::collectRenderableObjects(BattleRenderer & renderer
 			currentFrame %= elem.animation->size();
 
 			auto img = elem.animation->getImage(currentFrame, static_cast<size_t>(elem.type));
+			img->setAlpha(255 * elem.transparencyFactor);
 
 			canvas.draw(img, elem.pos);
 		});

+ 3 - 2
client/battle/BattleEffectsController.h

@@ -39,7 +39,8 @@ struct BattleEffect
 
 	AnimType type;
 	Point pos; //position on the screen
-	float currentFrame;
+	float currentFrame = 0.0;
+	float transparencyFactor = 1.0;
 	std::shared_ptr<CAnimation> animation;
 	int effectID; //uniqueID equal ot ID of appropriate CSpellEffectAnim
 	BattleHex tile; //Indicates if effect which hex the effect is drawn on
@@ -65,7 +66,7 @@ public:
 
 	//displays custom effect on the battlefield
 	void displayEffect(EBattleEffect effect, const BattleHex & destTile);
-	void displayEffect(EBattleEffect effect, const AudioPath & soundFile, const BattleHex & destTile);
+	void displayEffect(EBattleEffect effect, const AudioPath & soundFile, const BattleHex & destTile, float transparencyFactor = 1.f);
 
 	void battleTriggerEffect(const BattleTriggerEffect & bte);
 

+ 2 - 2
client/battle/BattleInterface.cpp

@@ -535,9 +535,9 @@ void BattleInterface::displaySpellAnimationQueue(const CSpell * spell, const CSp
 				flags |= EffectAnimation::SCREEN_FILL;
 
 			if (!destinationTile.isValid())
-				stacksController->addNewAnim(new EffectAnimation(*this, animation.resourceName, flags));
+				stacksController->addNewAnim(new EffectAnimation(*this, animation.resourceName, flags, animation.transparency));
 			else
-				stacksController->addNewAnim(new EffectAnimation(*this, animation.resourceName, destinationTile, flags));
+				stacksController->addNewAnim(new EffectAnimation(*this, animation.resourceName, destinationTile, flags, animation.transparency));
 		}
 	}
 }

+ 1 - 1
client/battle/BattleStacksController.cpp

@@ -636,7 +636,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
 	{
 		owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=]()
 		{
-			owner.effectsController->displayEffect(EBattleEffect::DRAIN_LIFE, AudioPath::builtin("DRAINLIF"), attacker->getPosition());
+			owner.effectsController->displayEffect(EBattleEffect::DRAIN_LIFE, AudioPath::builtin("DRAINLIF"), attacker->getPosition(), 0.5);
 		});
 	}
 

+ 2 - 1
config/schemas/spell.json

@@ -22,7 +22,8 @@
 						"properties" : {
 							"verticalPosition" : {"type" : "string", "enum" :["top","bottom"]},
 							"defName" : {"type" : "string", "format" : "animationFile"},
-							"effectName" : { "type" : "string" }
+							"effectName" : { "type" : "string" },
+							"transparency" : {"type" : "number", "minimum" : 0, "maximum" : 1}
 						},
 						"additionalProperties" : false
 					}

+ 1 - 1
config/spells/ability.json

@@ -252,7 +252,7 @@
 		"targetType": "NO_TARGET",
 
 		"animation":{
-			"hit":["SP04_"]
+			"hit":[{ "defName" : "SP04_", "transparency" : 0.5}]
 		},
 		"sounds": {
 			"cast": "DEATHCLD"

+ 2 - 2
config/spells/offensive.json

@@ -44,7 +44,7 @@
 				{"minimumAngle": 1.20 ,"defName":"C08SPW1"},
 				{"minimumAngle": 1.50 ,"defName":"C08SPW0"}
 			],
-			"hit":["C08SPW5"]
+			"hit":[ {"defName" : "C08SPW5", "transparency" : 0.5 }]
 		},
 		"sounds": {
 			"cast": "ICERAY"
@@ -309,7 +309,7 @@
 		"targetType" : "CREATURE",
 
 		"animation":{
-			"affect":["C14SPA0"]
+			"affect":[{"defName" : "C14SPA0", "transparency" : 0.5}]
 		},
 		"sounds": {
 			"cast": "SACBRETH"

+ 1 - 1
config/spells/other.json

@@ -483,7 +483,7 @@
 		"targetType" : "CREATURE",
 
 		"animation":{
-			"affect":["C01SPE0"]
+			"affect":[{ "defName" : "C01SPE0", "transparency" : 0.5}]
 		},
 		"sounds": {
 			"cast": "RESURECT"

+ 2 - 2
config/spells/timed.json

@@ -652,7 +652,7 @@
 		"targetType" : "CREATURE",
 
 		"animation":{
-			"affect":["C07SPA1"],
+			"affect":[{"defName" : "C07SPA1", "transparency" : 0.5}],
 			"projectile":[{"defName":"C07SPA0"}]//???
 		},
 		"sounds": {
@@ -696,7 +696,7 @@
 		"targetType" : "CREATURE",
 
 		"animation":{
-			"affect":[{"defName":"C10SPW", "verticalPosition":"bottom"}]
+			"affect":[{"defName":"C10SPW", "verticalPosition":"bottom", "transparency" : 0.5}]
 		},
 		"sounds": {
 			"cast": "PRAYER"

+ 8 - 2
lib/spells/CSpellHandler.cpp

@@ -544,7 +544,8 @@ void CSpell::serializeJson(JsonSerializeFormat & handler)
 ///CSpell::AnimationInfo
 CSpell::AnimationItem::AnimationItem() :
 	verticalPosition(VerticalPosition::TOP),
-	pause(0)
+	pause(0),
+	transparency(1)
 {
 
 }
@@ -965,10 +966,15 @@ std::shared_ptr<CSpell> CSpellHandler::loadFromJson(const std::string & scope, c
 				auto vPosStr = item["verticalPosition"].String();
 				if("bottom" == vPosStr)
 					newItem.verticalPosition = VerticalPosition::BOTTOM;
+
+				if (item["transparency"].isNumber())
+					newItem.transparency = item["transparency"].Float();
+				else
+					newItem.transparency = 1.0;
 			}
 			else if(item.isNumber())
 			{
-				newItem.pause = static_cast<int>(item.Float());
+				newItem.pause = item.Integer();
 			}
 
 			q.push_back(newItem);

+ 1 - 0
lib/spells/CSpellHandler.h

@@ -74,6 +74,7 @@ public:
 		AnimationPath resourceName;
 		std::string effectName;
 		VerticalPosition verticalPosition;
+		float transparency;
 		int pause;
 
 		AnimationItem();