From aa201e6caea9601cc3788878535c245b40610151 Mon Sep 17 00:00:00 2001
From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com>
Date: Sun, 14 Jul 2019 13:03:02 +0000
Subject: [PATCH] Addition of localisations for NPC name and titles.
---
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 18 ++-
.../gameserver/network/GameClient.java | 5 +
.../serverpackets/AbstractNpcInfo.java | 32 +++--
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
.../game/data/lang/el/NpcNameLocalisation.xml | 5 +
.../admincommandhandlers/AdminReload.java | 2 +
.../handlers/voicedcommandhandlers/Lang.java | 19 +++
.../game/data/xsd/NpcNameLocalisation.xsd | 19 +++
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../xml/impl/NpcNameLocalisationData.java | 126 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 15 ++-
.../model/actor/status/PlayerStatus.java | 15 ++-
.../gameserver/network/GameClient.java | 5 +
.../network/serverpackets/NpcInfo.java | 57 +++++++-
130 files changed, 3351 insertions(+), 72 deletions(-)
create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_6.0_Fafurion/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_Classic_2.1_Zaken/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_Classic_2.2_Antharas/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
create mode 100644 L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/lang/el/NpcNameLocalisation.xml
create mode 100644 L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/NpcNameLocalisation.xsd
create mode 100644 L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_1.0_Ertheia/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 505e6d91db..9939d6ddcf 100644
--- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -333,6 +334,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java
index 090f88c0ec..37693c723a 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java
@@ -75,6 +75,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -341,6 +342,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index cbe6566430..4fce9f5617 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -67,6 +67,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11658,7 +11659,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_2.5_Underground/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_2.5_Underground/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 445212da84..54988607c0 100644
--- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -38,6 +38,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -340,6 +341,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_2.5_Underground/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_2.5_Underground/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java
index bdb634c8e0..717772e98d 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java
@@ -78,6 +78,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -349,6 +350,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 3748450659..bf4090be70 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -68,6 +68,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11665,7 +11666,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_3.0_Helios/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_3.0_Helios/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 445212da84..54988607c0 100644
--- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -38,6 +38,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -340,6 +341,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_3.0_Helios/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_3.0_Helios/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java
index bdb634c8e0..717772e98d 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java
@@ -78,6 +78,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -349,6 +350,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index edb5e800af..1e73eb707c 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -68,6 +68,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11667,7 +11668,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 7bee2f3d02..3c26c6f57b 100644
--- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -333,6 +334,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java
index aa09c9be7c..9e7d7cec03 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java
@@ -78,6 +78,7 @@ import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -349,6 +350,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 5313606b55..a3485ff31f 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -69,6 +69,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11647,7 +11648,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_5.0_Salvation/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_5.0_Salvation/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index fc8f01eb2b..328d863377 100644
--- a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -38,6 +38,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -340,6 +341,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_5.0_Salvation/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_5.0_Salvation/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java
index 206cd7ee61..eb71b8ff1e 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java
@@ -80,6 +80,7 @@ import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -353,6 +354,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 3280b75116..ddda92dff2 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -69,6 +69,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11637,7 +11638,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_5.5_EtinasFate/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index fc8f01eb2b..328d863377 100644
--- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -38,6 +38,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -340,6 +341,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java
index 206cd7ee61..eb71b8ff1e 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java
@@ -80,6 +80,7 @@ import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -353,6 +354,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index a2c7b7f649..5f1676d987 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -69,6 +69,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11643,7 +11644,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 0e9db17a8c..f521339fb1 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_6.0_Fafurion/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index fc8f01eb2b..328d863377 100644
--- a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -38,6 +38,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -340,6 +341,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java
index e43ea524d5..b5c635c4c8 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java
@@ -81,6 +81,7 @@ import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -355,6 +356,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 75d4ebebc1..5d0158ed21 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -69,6 +69,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.MonsterBookData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11649,7 +11650,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 0e9db17a8c..f521339fb1 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 4bb4693b02..823bf3e16b 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -33,6 +33,7 @@ import org.l2jmobius.gameserver.data.xml.impl.EnchantItemGroupsData;
import org.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SendMessageLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
@@ -285,6 +286,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 4aca2e64c7..2367fbe022 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,8 +19,15 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.AbstractNpcInfo.NpcInfo;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
public class Lang implements IVoicedCommandHandler
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj, activeChar));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java
index 00c3f41784..92c2cd1b4e 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java
@@ -65,6 +65,7 @@ import org.l2jmobius.gameserver.data.xml.impl.InitialShortcutData;
import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -331,6 +332,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 7b95c15b88..5da180d3f5 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -71,6 +71,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.FishData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -12592,7 +12593,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_DONE_S3_POINTS_OF_DAMAGE_TO_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 4aff039a8f..5d18236814 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -19,6 +19,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -226,11 +227,22 @@ public class PlayerStatus extends PlayableStatus
if ((fullValue > 0) && !isDOT)
{
- SystemMessage smsg;
// Send a System Message to the PlayerInstance
- smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
+ SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/GameClient.java
index f2b0d40f22..c5bf66e8b0 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -40,6 +40,7 @@ import org.l2jmobius.gameserver.model.CharSelectInfoPackage;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.clan.Clan;
+import org.l2jmobius.gameserver.network.serverpackets.AbstractNpcInfo.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
@@ -263,6 +264,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/AbstractNpcInfo.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/AbstractNpcInfo.java
index 31d27bc273..d13c40effe 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/AbstractNpcInfo.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/AbstractNpcInfo.java
@@ -19,6 +19,7 @@ package org.l2jmobius.gameserver.network.serverpackets;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.instancemanager.TownManager;
import org.l2jmobius.gameserver.model.PlayerCondOverride;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -90,6 +91,17 @@ public abstract class AbstractNpcInfo implements IClientOutgoingPacket
private int _allyId = 0;
private int _clanId = 0;
private int _displayEffect = 0;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ _name = _localisation[0];
+ _title = _localisation[1];
+ }
+ }
public NpcInfo(Npc cha, Creature attacker)
{
@@ -102,9 +114,10 @@ public abstract class AbstractNpcInfo implements IClientOutgoingPacket
_collisionHeight = cha.getCollisionHeight();// On every subclass
_collisionRadius = cha.getCollisionRadius();// On every subclass
_isAttackable = cha.isAutoAttackable(attacker);
- if (cha.getTemplate().isUsingServerSideName())
+
+ if (_name.equals("") && cha.getTemplate().isUsingServerSideName())
{
- _name = cha.getName();// On every subclass
+ _name = cha.getName(); // On every subclass
}
if (_npc.isInvisible())
@@ -115,13 +128,16 @@ public abstract class AbstractNpcInfo implements IClientOutgoingPacket
{
_title = (Config.CHAMP_TITLE); // On every subclass
}
- else if (cha.getTemplate().isUsingServerSideTitle())
+ else if (_title.equals(""))
{
- _title = cha.getTemplate().getTitle(); // On every subclass
- }
- else
- {
- _title = cha.getTitle(); // On every subclass
+ if (cha.getTemplate().isUsingServerSideTitle())
+ {
+ _title = cha.getTemplate().getTitle(); // On every subclass
+ }
+ else
+ {
+ _title = cha.getTitle(); // On every subclass
+ }
}
if (Config.SHOW_NPC_LVL && _npc.isMonster())
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 7bee2f3d02..3c26c6f57b 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -333,6 +334,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java
index ccb8c7d068..b0ed8693fe 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java
@@ -76,6 +76,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -345,6 +346,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index b8901a4db0..220f355070 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -68,6 +68,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11500,7 +11501,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 7bee2f3d02..3c26c6f57b 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -333,6 +334,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java
index ccb8c7d068..b0ed8693fe 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java
@@ -76,6 +76,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -345,6 +346,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 0bbe86ec44..b44610d91c 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -68,6 +68,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11507,7 +11508,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 7bee2f3d02..3c26c6f57b 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -333,6 +334,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java
index ccb8c7d068..b0ed8693fe 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java
@@ -76,6 +76,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -345,6 +346,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 89a3c6e729..a3ed51b30f 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -68,6 +68,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11492,7 +11493,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 7bee2f3d02..3c26c6f57b 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -333,6 +334,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java
index ccb8c7d068..b0ed8693fe 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java
@@ -76,6 +76,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -345,6 +346,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index f481a56160..8275a59c00 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -68,6 +68,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11498,7 +11499,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/lang/el/NpcNameLocalisation.xml b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/lang/el/NpcNameLocalisation.xml
new file mode 100644
index 0000000000..e260fd7156
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/lang/el/NpcNameLocalisation.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
index 7bee2f3d02..3c26c6f57b 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/admincommandhandlers/AdminReload.java
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.data.xml.impl.FishingData;
import org.l2jmobius.gameserver.data.xml.impl.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import org.l2jmobius.gameserver.data.xml.impl.SayuneData;
@@ -333,6 +334,7 @@ public class AdminReload implements IAdminCommandHandler
SystemMessageId.loadLocalisations();
NpcStringId.loadLocalisations();
SendMessageLocalisationData.getInstance().load();
+ NpcNameLocalisationData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Localisation data.");
break;
}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
index 559eaaea12..26f24c4e52 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/handlers/voicedcommandhandlers/Lang.java
@@ -19,9 +19,16 @@ package handlers.voicedcommandhandlers;
import java.util.StringTokenizer;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
public class Lang implements IVoicedCommandHandler
{
@@ -61,6 +68,18 @@ public class Lang implements IVoicedCommandHandler
{
msg.setFile(activeChar, "data/html/mods/Lang/Ok.htm");
activeChar.sendPacket(msg);
+ for (WorldObject obj : World.getInstance().getVisibleObjects())
+ {
+ if (obj.isNpc() && NpcNameLocalisationData.getInstance().hasLocalisation(obj.getId()))
+ {
+ activeChar.sendPacket(new DeleteObject(obj));
+ ThreadPool.schedule(() ->
+ {
+ activeChar.sendPacket(new NpcInfo((Npc) obj));
+ }, 1000);
+ }
+ }
+ activeChar.setTarget(null);
return true;
}
msg.setFile(activeChar, "data/html/mods/Lang/Error.htm");
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/NpcNameLocalisation.xsd b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/NpcNameLocalisation.xsd
new file mode 100644
index 0000000000..b8b185243e
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/NpcNameLocalisation.xsd
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java
index ee8bca4041..960a31fcb3 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java
@@ -77,6 +77,7 @@ import org.l2jmobius.gameserver.data.xml.impl.KarmaData;
import org.l2jmobius.gameserver.data.xml.impl.LuckyGameData;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.OptionData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PetSkillData;
@@ -347,6 +348,7 @@ public class GameServer
if (Config.MULTILANG_ENABLE)
{
SendMessageLocalisationData.getInstance();
+ NpcNameLocalisationData.getInstance();
}
printSection("Scripts");
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
new file mode 100644
index 0000000000..e374cd78a5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/impl/NpcNameLocalisationData.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatsSet;
+
+/**
+ * @author Mobius
+ */
+public class NpcNameLocalisationData implements IXmlReader
+{
+ private final static Logger LOGGER = Logger.getLogger(NpcNameLocalisationData.class.getName());
+
+ private final static Map> NPC_NAME_LOCALISATIONS = new ConcurrentHashMap<>();
+ private static String _lang;
+
+ protected NpcNameLocalisationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ NPC_NAME_LOCALISATIONS.clear();
+
+ if (Config.MULTILANG_ENABLE)
+ {
+ for (String lang : Config.MULTILANG_ALLOWED)
+ {
+ final File file = new File("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ if (!file.isFile())
+ {
+ continue;
+ }
+
+ NPC_NAME_LOCALISATIONS.put(lang, new ConcurrentHashMap());
+ _lang = lang;
+ parseDatapackFile("data/lang/" + lang + "/NpcNameLocalisation.xml");
+ final int count = NPC_NAME_LOCALISATIONS.get(lang).values().size();
+ if (count == 0)
+ {
+ NPC_NAME_LOCALISATIONS.remove(lang);
+ }
+ else
+ {
+ LOGGER.info(getClass().getSimpleName() + ": Loaded localisations for '" + lang + "'");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "localisation", localisationNode ->
+ {
+ final StatsSet set = new StatsSet(parseAttributes(localisationNode));
+ NPC_NAME_LOCALISATIONS.get(_lang).put(set.getInt("id"), new String[]
+ {
+ set.getString("name"),
+ set.getString("title")
+ });
+ }));
+ }
+
+ /**
+ * @param lang
+ * @param id
+ * @return a String Array[] that contains NPC name and title or Null if is does not exist.
+ */
+ public String[] getLocalisation(String lang, int id)
+ {
+ final Map localisations = NPC_NAME_LOCALISATIONS.get(lang);
+ if (localisations != null)
+ {
+ return localisations.get(id);
+ }
+ return null;
+ }
+
+ public boolean hasLocalisation(int id)
+ {
+ for (Map data : NPC_NAME_LOCALISATIONS.values())
+ {
+ if (data.containsKey(id))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static NpcNameLocalisationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final NpcNameLocalisationData INSTANCE = new NpcNameLocalisationData();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 09d06b698d..9372c85feb 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -68,6 +68,7 @@ import org.l2jmobius.gameserver.data.xml.impl.ClassListData;
import org.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import org.l2jmobius.gameserver.data.xml.impl.HennaData;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import org.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
@@ -11498,7 +11499,19 @@ public final class PlayerInstance extends Playable
{
sm = new SystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2);
sm.addPcName(this);
- sm.addString(target.getName());
+
+ // Localisation related.
+ String targetName = target.getName();
+ if (Config.MULTILANG_ENABLE && target.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(_lang, target.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ sm.addString(targetName);
sm.addInt(damage);
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
index 64d1bdbd1c..df33eb168e 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/status/PlayerStatus.java
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.model.actor.status;
import org.l2jmobius.Config;
import org.l2jmobius.gameserver.ai.CtrlIntention;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.PrivateStoreType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -253,7 +254,19 @@ public class PlayerStatus extends PlayableStatus
// Send a System Message to the PlayerInstance
SystemMessage smsg = new SystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getName());
- smsg.addString(attacker.getName());
+
+ // Localisation related.
+ String targetName = attacker.getName();
+ if (Config.MULTILANG_ENABLE && attacker.isNpc())
+ {
+ final String[] localisation = NpcNameLocalisationData.getInstance().getLocalisation(getActiveChar().getLang(), attacker.getId());
+ if (localisation != null)
+ {
+ targetName = localisation[0];
+ }
+ }
+
+ smsg.addString(targetName);
smsg.addInt(fullValue);
smsg.addPopup(getActiveChar().getObjectId(), attacker.getObjectId(), -fullValue);
getActiveChar().sendPacket(smsg);
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/GameClient.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/GameClient.java
index 4ed506b02a..ed0f223551 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/GameClient.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/GameClient.java
@@ -49,6 +49,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
+import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -268,6 +269,10 @@ public final class GameClient extends ChannelInboundHandler
{
((ExShowScreenMessage) packet).setLang(lang);
}
+ else if (packet instanceof NpcInfo)
+ {
+ ((NpcInfo) packet).setLang(lang);
+ }
}
}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
index b9aed30eb3..eb77b0fd17 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/NpcInfo.java
@@ -21,6 +21,8 @@ import java.util.Set;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.sql.impl.ClanTable;
+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
+import org.l2jmobius.gameserver.data.xml.impl.NpcNameLocalisationData;
import org.l2jmobius.gameserver.enums.NpcInfoType;
import org.l2jmobius.gameserver.enums.Team;
import org.l2jmobius.gameserver.model.actor.Npc;
@@ -57,6 +59,40 @@ public class NpcInfo extends AbstractMaskPacket
private int _statusMask = 0;
private final Set _abnormalVisualEffects;
+ private String[] _localisation;
+
+ public void setLang(String lang)
+ {
+ _localisation = NpcNameLocalisationData.getInstance().getLocalisation(lang, _npc.getId());
+ if (_localisation != null)
+ {
+ if (!containsMask(NpcInfoType.NAME))
+ {
+ addComponentType(NpcInfoType.NAME);
+ }
+ _blockSize -= _npc.getName().length() * 2;
+ _blockSize += _localisation[0].length() * 2;
+
+ if (!_localisation[1].equals(""))
+ {
+ if (!containsMask(NpcInfoType.TITLE))
+ {
+ addComponentType(NpcInfoType.TITLE);
+ }
+ final String title = _npc.getTitle();
+ _initSize -= title.length() * 2;
+ if (title.equals(""))
+ {
+ _initSize += _localisation[1].length() * 2;
+ }
+ else
+ {
+ _initSize += title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]).length() * 2;
+ }
+ }
+ }
+ }
+
public NpcInfo(Npc npc)
{
_npc = npc;
@@ -283,7 +319,22 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.TITLE))
{
- packet.writeS(_npc.getTitle());
+ String title = _npc.getTitle();
+
+ // Localisation related.
+ if ((_localisation != null) && !_localisation[1].equals(""))
+ {
+ if (title.equals(""))
+ {
+ title = _localisation[1];
+ }
+ else
+ {
+ title = title.replace(NpcData.getInstance().getTemplate(_npc.getId()).getTitle(), _localisation[1]);
+ }
+ }
+
+ packet.writeS(title);
}
// Block 2
@@ -344,7 +395,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.FLYING))
{
- packet.writeD(_npc.isFlying() ? 0x01 : 00);
+ packet.writeD(_npc.isFlying() ? 0x01 : 0x00);
}
if (containsMask(NpcInfoType.CLONE))
{
@@ -389,7 +440,7 @@ public class NpcInfo extends AbstractMaskPacket
}
if (containsMask(NpcInfoType.NAME))
{
- packet.writeS(_npc.getName());
+ packet.writeS(_localisation != null ? _localisation[0] : _npc.getName());
}
if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
{