diff --git a/src/game_battlealgorithm.cpp b/src/game_battlealgorithm.cpp index b278652a56..e5b6c7805c 100644 --- a/src/game_battlealgorithm.cpp +++ b/src/game_battlealgorithm.cpp @@ -1781,7 +1781,7 @@ std::string Game_BattleAlgorithm::SelfDestruct::GetStartMessage() const { } int Game_BattleAlgorithm::SelfDestruct::GetSourceAnimationState() const { - return Sprite_Battler::AnimationState_Dead; + return Sprite_Battler::AnimationState_SelfDestruct; } const RPG::Sound* Game_BattleAlgorithm::SelfDestruct::GetStartSe() const { diff --git a/src/game_enemy.cpp b/src/game_enemy.cpp index f14f5a459f..732b425744 100644 --- a/src/game_enemy.cpp +++ b/src/game_enemy.cpp @@ -338,3 +338,7 @@ const RPG::EnemyAction* Game_Enemy::ChooseRandomAction() { return nullptr; } + +bool Game_Enemy::IsTransparent() const { + return enemy->transparent; +} diff --git a/src/game_enemy.h b/src/game_enemy.h index 4e31aae230..a1d38fbcc0 100644 --- a/src/game_enemy.h +++ b/src/game_enemy.h @@ -169,6 +169,8 @@ class Game_Enemy : public Game_Battler void UpdateBattle() override; + bool IsTransparent() const; + /** * Get's the ID of the item the enemy drops when defeated. * diff --git a/src/scene_battle_rpg2k.cpp b/src/scene_battle_rpg2k.cpp index 5541f5683a..dd106f649a 100644 --- a/src/scene_battle_rpg2k.cpp +++ b/src/scene_battle_rpg2k.cpp @@ -435,9 +435,6 @@ bool Scene_Battle_Rpg2k::ProcessBattleAction(Game_BattleAlgorithm::AlgorithmBase source_sprite = Game_Battle::GetSpriteset().FindBattler(action->GetSource()); if (source_sprite) { source_sprite->Flash(Color(255, 255, 255, 100), 15); - source_sprite->SetAnimationState( - action->GetSourceAnimationState(), - Sprite_Battler::LoopState_DefaultAnimationAfterFinish); } auto* src = action->GetSource(); @@ -542,6 +539,22 @@ bool Scene_Battle_Rpg2k::ProcessBattleAction(Game_BattleAlgorithm::AlgorithmBase action->Apply(); battle_action_state = BattleActionState_ResultPop; + if (action->GetSource()->GetType() == Game_Battler::Type_Enemy) { + if (action->GetType() == Game_BattleAlgorithm::Type::Escape) { + source_sprite = Game_Battle::GetSpriteset().FindBattler(action->GetSource()); + source_sprite->SetAnimationState( + Sprite_Battler::AnimationState_Dead, + Sprite_Battler::LoopState_DefaultAnimationAfterFinish); + } + + if (action->GetType() == Game_BattleAlgorithm::Type::SelfDestruct) { + source_sprite = Game_Battle::GetSpriteset().FindBattler(action->GetSource()); + source_sprite->SetAnimationState( + Sprite_Battler::AnimationState_SelfDestruct, + Sprite_Battler::LoopState_DefaultAnimationAfterFinish); + } + } + if (!action->IsFirstAttack()) { battle_action_wait = 0; return ProcessBattleAction(action); diff --git a/src/sprite_battler.cpp b/src/sprite_battler.cpp index 73d628a951..37ab2e3038 100644 --- a/src/sprite_battler.cpp +++ b/src/sprite_battler.cpp @@ -17,6 +17,7 @@ // Headers #include "battle_animation.h" +#include "game_enemy.h" #include "sprite_battler.h" #include "bitmap.h" #include "cache.h" @@ -49,7 +50,9 @@ void Sprite_Battler::Update() { } if (!battler->IsHidden() && old_hidden != battler->IsHidden()) { - SetOpacity(255); + SetZoomX(1.0); + SetZoomY(1.0); + SetOpacity(GetMaxOpacity()); SetVisible(true); DoIdleAnimation(); } @@ -62,25 +65,39 @@ void Sprite_Battler::Update() { if (battler->GetBattleAnimationId() <= 0) { // Animations for monster - if (anim_state != AnimationState_Dead) { - fade_out = 255; + if (anim_state != AnimationState_Dead && anim_state != AnimationState_SelfDestruct) { + fade_out = GetMaxOpacity(); + fade_out_incr = GetMaxOpacity() * (Player::IsRPG2k() ? 6 : 15) / 255; + zoom = 1.0; } if (anim_state == AnimationState_Idle) { - SetOpacity(255); + SetOpacity(GetMaxOpacity()); idling = true; } else if (anim_state == AnimationState_Dead) { if (fade_out > 0) { - fade_out -= 15; + fade_out -= fade_out_incr; SetOpacity(std::max(0, fade_out)); } else { idling = true; } } + else if (anim_state == AnimationState_SelfDestruct) { + if (fade_out > 0) { + fade_out -= fade_out_incr; + zoom += 0.07; + SetOpacity(std::max(0, fade_out)); + SetZoomX(zoom); + SetZoomY(zoom); + } + else { + idling = true; + } + } else if (anim_state == AnimationState_Damage) { flash_counter = (flash_counter + 1) % 10; - SetOpacity(flash_counter > 5 ? 50 : 255); + SetOpacity(flash_counter > 5 ? 50 : GetMaxOpacity()); if (cycle == 30) { DoIdleAnimation(); cycle = 0; @@ -363,3 +380,10 @@ void Sprite_Battler::OnBattlercharsetReady(FileRequestResult* result, int32_t ba SetBitmap(Cache::Battlecharset(result->file)); SetSrcRect(Rect(0, battler_index * 48, 48, 48)); } + +int Sprite_Battler::GetMaxOpacity() const { + if (battler->GetType() == Game_Battler::Type_Enemy) { + return static_cast(battler)->IsTransparent()? 255 - 96 : 255; + } + return 255; +} diff --git a/src/sprite_battler.h b/src/sprite_battler.h index f4030c0336..f73b13c574 100644 --- a/src/sprite_battler.h +++ b/src/sprite_battler.h @@ -31,7 +31,8 @@ class BattleAnimation; class Sprite_Battler : public Sprite { public: enum AnimationState { - AnimationState_Idle = 1, + AnimationState_Null, + AnimationState_Idle, AnimationState_RightHand, AnimationState_LeftHand, AnimationState_SkillUse, @@ -42,7 +43,8 @@ class Sprite_Battler : public Sprite { AnimationState_WalkingLeft, AnimationState_WalkingRight, AnimationState_Victory, - AnimationState_Item + AnimationState_Item, + AnimationState_SelfDestruct = 255 }; enum LoopState { @@ -99,6 +101,7 @@ class Sprite_Battler : public Sprite { void DoIdleAnimation(); void OnMonsterSpriteReady(FileRequestResult* result); void OnBattlercharsetReady(FileRequestResult* result, int32_t battler_index); + int GetMaxOpacity() const; std::string sprite_name; int hue = 0; @@ -109,12 +112,14 @@ class Sprite_Battler : public Sprite { std::string sprite_file; int sprite_frame = -1; int fade_out = 255; + int fade_out_incr = 15; int flash_counter = 0; LoopState loop_state = LoopState_DefaultAnimationAfterFinish; bool old_hidden = false; std::unique_ptr animation; // false when a newly set animation didn't loop once bool idling = true; + float zoom = 1.0; FileRequestBinding request_id; };