[MV] Heal After Taking Damage

Hello everyone!

I’d like to share another small RPG Maker MV plugin that I created while working on my own project.

This plugin allows a State to restore HP automatically after the battler receives HP damage.

I originally created it for boss battles, especially for bosses that become more difficult to defeat when they’re close to death. However, it can also be used for enemies, actors, or any custom mechanics that require automatic healing after taking damage.

I thought this mechanic might be useful for other developers, so I decided to share it.

The plugin is free for both commercial and non-commercial use. Feel free to modify it however you’d like—no permission is required.

If you decide to use it, I’d really appreciate it if you could credit “Melphilium” in your project.

I hope you find it useful. Thank you!

/*:
 * @plugindesc [MV] State Heal After Taking Damage v1.0
 * @author Melphilium
 *
 * @help
 * ============================================================================
 * Overview
 * ============================================================================
 *
 * Add the following notetag to a State:
 *
 *   <AfterDamageHeal:50>
 *   <AfterDamageHeal:25%>
 *
 * While a battler is affected by this state:
 *
 * - Restores HP after receiving HP damage.
 * - Flat and percentage healing are both supported.
 * - Multiple states with this notetag will stack.
 * - Healing only occurs if the battler survives the damage.
 *
 * ============================================================================
 * Notetag
 * ============================================================================
 *
 * <AfterDamageHeal:50>
 * Restores 50 HP after taking HP damage.
 *
 * <AfterDamageHeal:25%>
 * Restores 25% of the battler's Max HP after taking HP damage.
 *
 * ============================================================================
 * Example
 * ============================================================================
 *
 * State:
 * <AfterDamageHeal:100>
 *
 * Battler receives 300 HP damage.
 *
 * Result:
 * HP is restored by 100 immediately after the damage is applied.
 *
 * --------------------------------------------------------------------------
 *
 * State:
 * <AfterDamageHeal:10%>
 *
 * Battler receives HP damage.
 *
 * Result:
 * HP is restored by 10% of the battler's Max HP immediately after the damage
 * is applied.
 *
 * ============================================================================
 * Notes
 * ============================================================================
 *
 * - Only triggers when receiving HP damage.
 * - Does not trigger if damage is 0.
 * - Does not trigger if the battler is defeated by the damage.
 * - Healing from multiple states will stack.
 *
 * ============================================================================
 * Compatibility
 * ============================================================================
 *
 * RPG Maker MV
 *
 * ============================================================================
 * Terms of Use
 * ============================================================================
 *
 * Free for commercial and non-commercial use.
 *
 * Feel free to modify this plugin however you'd like.
 *
 * No permission is required.
 *
 * Credit: Melphilium
 *
 * ============================================================================
 * Version History
 * ============================================================================
 *
 * v1.0
 * - Initial release.
 */

(function() {

    const _Game_Action_executeHpDamage =
        Game_Action.prototype.executeHpDamage;

    Game_Action.prototype.executeHpDamage = function(target, value) {

        // Jalankan damage asli dulu
        _Game_Action_executeHpDamage.call(this, target, value);

        // Hanya trigger jika benar-benar menerima damage HP
        if (value <= 0) return;

        // Tidak trigger jika target mati
        if (target.isDead()) return;

        let totalHeal = 0;

        target.states().forEach(state => {

            if (!state || !state.note) return;

            const match = state.note.match(
                /<AfterDamageHeal\s*:\s*(\d+)(%)?>/i
            );

            if (match) {

                const amount = Number(match[1]);
                const isPercent = !!match[2];

                if (isPercent) {
                    totalHeal += Math.floor(target.mhp * amount / 100);
                } else {
                    totalHeal += amount;
                }
            }
        });

        if (totalHeal > 0) {
            
            // Gunakan setTimeout untuk memberikan jeda (delay)
            // 600 di bawah berarti 600 milidetik (0.6 detik).
            setTimeout(function() {
                
                // Pengecekan ulang
                if (!target.isDead()) {
                    
                    // Membersihkan result agar popup heal tidak bentrok
                    target.clearResult();
                    
                    // Eksekusi Heal
                    target.gainHp(totalHeal);
                    target.startDamagePopup();
                    target.refresh();

                    // Update battle log untuk menampilkan efek pemulihan HP
                    if (BattleManager._logWindow) {
                        BattleManager._logWindow.displayHpDamage(target);
                    }
                }
                
            }, 600); // <- Jeda waktu (delay)
        }
    };

})();
2 Likes

This looks nice, but I think you should figure out a way to do it without setTimeout, as that seems like it’ll make it happen out of sequence. The battle log window handles timing already, so it can probably take care of this for you – instead of calling BattleManager._logWindow.displayHpDamage, you can likely get something working with BattleManager._logWindow.push. In the worst case your custom function could be added as a new method on the log window which you push after pushing a delay.

1 Like

Thanks for the suggestion! I originally used setTimeout to prevent the damage popup from being overwritten by the heal popup, but I agree that using the battle log queue would be a cleaner solution. I’ll experiment with it later and see if I can make it work while keeping compatibility with the SRPG plugin. :pink_heart: