JavaScript:
package services;
import l2.commons.listener.EventListener;
import l2.gameserver.GameServer;
import l2.gameserver.model.Player;
import l2.gameserver.model.Skill;
import l2.gameserver.scripts.Functions;
import l2.gameserver.scripts.ScriptFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings("unused")
public class SkillRemove extends Functions implements ScriptFile, EventListener {
private static final Logger _log = LoggerFactory.getLogger(SkillRemove.class);
private static final String EVENT_LEARN_SKILL = "onSkillLearned";
private static final Map<Integer, List<Integer>> REMOVAL_DATA = new HashMap<>();
@Override
public String[] listeningEventTypes() {
return new String[]{EVENT_LEARN_SKILL};
}
@Override
public void onEvent(String eventType, Object... args) {
if (EVENT_LEARN_SKILL.equals(eventType) && args.length >= 2) {
if (args[0] instanceof Player && args[1] instanceof Skill) {
checkAndRemove((Player) args[0], (Skill) args[1]);
}
}
}
private void checkAndRemove(Player player, Skill learnedSkill) {
if (player == null || learnedSkill == null) return;
List<Integer> toRemove = REMOVAL_DATA.get(learnedSkill.getId());
if (toRemove != null && !toRemove.isEmpty()) {
boolean updated = false;
for (Integer id : toRemove) {
Skill old = player.getKnownSkill(id);
if (old != null) {
player.removeSkill(old, false);
player.sendMessage("При изучении " + learnedSkill.getName() + ", магические потоки вытеснили умение " + old.getName() + ".");
updated = true;
}
}
if (updated) {
player.sendSkillList();
player.updateStats();
player.store(true);
}
}
}
@Override
public void onLoad() {
loadXmlData();
if (!REMOVAL_DATA.isEmpty()) {
GameServer.getInstance().getListeners().addEventListener(this);
_log.info("SkillRemove: Loaded {} skill removal rules.", REMOVAL_DATA.size());
} else {
_log.warn("SkillRemove: No data loaded! Check SkillRemove.xml");
}
}
private void loadXmlData() {
REMOVAL_DATA.clear();
File file = new File("data/SkillRemove.xml");
if (!file.exists()) {
_log.error("SkillRemove: File not found: {}", file.getAbsolutePath());
return;
}
try {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
Node listNode = doc.getElementsByTagName("list").item(0);
if (listNode != null) {
for (Node d = listNode.getFirstChild(); d != null; d = d.getNextSibling()) {
if ("skill".equalsIgnoreCase(d.getNodeName())) {
NamedNodeMap attrs = d.getAttributes();
if (attrs == null) continue;
Node idAttr = attrs.getNamedItem("id");
Node removeAttr = attrs.getNamedItem("remove");
if (idAttr != null && removeAttr != null) {
try {
int id = Integer.parseInt(idAttr.getNodeValue());
String[] removeIds = removeAttr.getNodeValue().split(",");
List<Integer> list = new ArrayList<>();
for (String s : removeIds) {
list.add(Integer.parseInt(s.trim()));
}
REMOVAL_DATA.put(id, list);
} catch (NumberFormatException e) {
_log.error("SkillRemove: Error parsing ID in XML: {}", idAttr.getNodeValue());
}
}
}
}
}
} catch (Exception e) {
_log.error("SkillRemove: Error while reading XML:", e);
}
}
@Override
public void onReload() {
}
@Override
public void onShutdown() {
}
}
Удаляем способность если изучили другую, кому нужно придумает что с этим делать.
Compile for Lucera 2 Legacy (525)