[SHARE] script for announce when player hits a RB and when have 50/20/10%

fa1thDEV

Heir
Customer
it only shows the RB (+75 LVL) that was attacked and his remaining life, if another player hits him, he doesn't announce it because he has a condition not to generate SPAM, the only problem is that it doesn't show in which zone he is being attacked... if someone wants to add that line, he is more than welcome!

JavaScript:
package services;

import l2.gameserver.Announcements;
import l2.gameserver.listener.actor.OnAttackListener;
import l2.gameserver.listener.actor.OnDeathListener;
import l2.gameserver.model.Creature;
import l2.gameserver.model.Player;
import l2.gameserver.model.instances.RaidBossInstance;
import l2.gameserver.model.actor.listener.CharListenerList;
import l2.gameserver.network.l2.components.ChatType;
import l2.gameserver.network.l2.s2c.Say2;
import l2.gameserver.scripts.ScriptFile;

import java.util.HashMap;
import java.util.Map;

public class RaidBossNotifier implements OnAttackListener, OnDeathListener, ScriptFile {
    private static final RaidBossNotifier INSTANCE = new RaidBossNotifier();

    // Mapa para rastrear los porcentajes ya anunciados por cada Raid Boss
    private final Map<Integer, Boolean> notifiedPercentages = new HashMap<>();
    private boolean isBeingAttacked = false; // Estado para saber si el Raid Boss está siendo atacado

    @Override
    public void onAttack(Creature attacker, Creature target) {
        if (attacker instanceof Player && target instanceof RaidBossInstance raidBoss) {
            if (raidBoss.getLevel() < 75) {
                return; // Ignorar Raid Bosses de nivel menor a 75
            }

            double currentHp = raidBoss.getCurrentHp();
            double maxHp = raidBoss.getMaxHp();
            int hpPercentage = (int) ((currentHp / maxHp) * 100);

            // Si el Raid Boss no está siendo atacado actualmente, marcarlo como atacado y anunciarlo
            if (!isBeingAttacked) {
                isBeingAttacked = true;

                String message = "¡El Raid Boss -" + raidBoss.getName() + "- está siendo atacado!";

                announceToAll(message);
            }

            // Verifica si el porcentaje ya ha sido anunciado
            if (!notifiedPercentages.containsKey(hpPercentage)) {
                notifiedPercentages.put(hpPercentage, true);

                String message = switch (hpPercentage) {
                    case 50, 25, 10 -> "¡Atención! El Raid Boss -" + raidBoss.getName() + "- tiene " + hpPercentage + "% de vida restante!";
                    default -> null;
                };

                if (message != null) {
                    announceToAll(message);
                }
            }
        }
    }

    @Override
    public void onDeath(Creature actor, Creature killer) {
        if (actor instanceof RaidBossInstance raidBoss) {
            if (raidBoss.getLevel() < 75) {
                return; // Ignorar Raid Bosses de nivel menor a 75
            }

            // Anuncio global cuando el Raid Boss es derrotado
            String message = "¡El Raid Boss -" + raidBoss.getName() + "- ha sido derrotado!";
            announceToAll(message);

            // Limpia los porcentajes notificados y el estado de ataque
            notifiedPercentages.clear();
            isBeingAttacked = false;
        }
    }

    private void announceToAll(String message) {
        // Crear y enviar un anuncio global usando Say2
        Say2 announcement = new Say2(0, ChatType.ANNOUNCEMENT, "", message);
        Announcements.getInstance().announceToAll(announcement);
    }

    @Override
    public void onLoad() {
        // Registrar la clase como un listener global
        CharListenerList.addGlobal(INSTANCE);
    }

    @Override
    public void onReload() {
        // Reiniciar el listener al recargar
        onShutdown();
        onLoad();
    }

    @Override
    public void onShutdown() {
        // Eliminar el listener global al apagar
        CharListenerList.removeGlobal(INSTANCE);
    }
}
 
I've identified several bugs.

1️⃣ Problem: Notifications can be inaccurate in certain scenarios
Since notifiedPercentages is a single map for all bosses, it may not clear correctly when starting a new fight with another Raid Boss.
Solution: Use a separate map for each Raid Boss, ensuring that notifications are independent.
2️⃣ Problem: The mod does not detect multiple Raid Bosses simultaneously
The mod only has a single isBeingAttacked variable, so if multiple RBs are attacked at the same time, the logic may fail.
Solution: Create a state map per Raid Boss, ensuring that multiple RBs can be announced correctly.
3️⃣ Problem: Message spam may occur when a Raid Boss dies
notifiedPercentages.clear() clears all notifications, but if two different Raid Bosses are active at the same time, notifications may reset for both when killing just one. Solution: Clear notifications only for the Raid Boss that died.
4️⃣ Problem: No control over who receives the announcements
Currently, all players receive the messages, but there could be a system to restrict announcements to nearby players only.
 
Back
Top