1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-21 17:17:06 +02:00

Implemented semi-transparent spell effects

This commit is contained in:
Ivan Savenko 2024-11-17 19:48:16 +00:00
parent fd1a31253b
commit dfe6e04464
13 changed files with 41 additions and 28 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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);
});

View File

@ -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);

View File

@ -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));
}
}
}

View File

@ -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);
});
}

View File

@ -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
}

View File

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

View File

@ -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"

View File

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

View File

@ -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"

View File

@ -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);

View File

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