From 76abf2d6b298c21687f6e3c4bb2c43b2f99cee7e Mon Sep 17 00:00:00 2001
From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com>
Date: Tue, 10 Apr 2018 18:21:54 +0000
Subject: [PATCH] Faction System (Good vs Evil).
---
.../dist/db_installer/sql/game/characters.sql | 1 +
.../dist/game/config/Custom/FactionSystem.ini | 76 +++++++
.../dist/game/data/html/guard/501.htm | 4 +
.../dist/game/data/html/guard/502.htm | 3 +
.../custom/FactionSystem/FactionSystem.java | 186 ++++++++++++++++++
.../scripts/custom/FactionSystem/manager.html | 6 +
.../custom/FactionSystem/onlinelimit.html | 5 +
.../handlers/chathandlers/ChatGeneral.java | 24 ++-
.../handlers/chathandlers/ChatHeroVoice.java | 19 +-
.../chathandlers/ChatPartyMatchRoom.java | 19 +-
.../handlers/chathandlers/ChatRandomizer.java | 50 +++++
.../handlers/chathandlers/ChatShout.java | 40 +++-
.../handlers/chathandlers/ChatTrade.java | 38 +++-
.../handlers/chathandlers/ChatWhisper.java | 5 +
.../data/stats/npcs/custom/gve_factions.xml | 107 ++++++++++
.../java/com/l2jmobius/Config.java | 47 ++++-
.../com/l2jmobius/gameserver/GameServer.java | 6 +
.../gameserver/data/xml/impl/NpcData.java | 6 +-
.../instancemanager/FactionManager.java | 115 +++++++++++
.../instancemanager/MapRegionManager.java | 19 +-
.../model/CharSelectInfoPackage.java | 24 +++
.../l2jmobius/gameserver/model/L2World.java | 43 ++++
.../gameserver/model/actor/L2Attackable.java | 2 +-
.../model/actor/instance/L2GuardInstance.java | 40 +++-
.../model/actor/instance/L2PcInstance.java | 77 +++++++-
.../clientpackets/CharacterCreate.java | 4 +
.../clientpackets/CharacterSelect.java | 23 +++
.../network/clientpackets/EnterWorld.java | 21 ++
.../serverpackets/CharSelectionInfo.java | 12 +-
.../network/serverpackets/NpcSay.java | 5 +-
L2J_Mobius_CT_2.6_HighFive/readme.txt | 1 +
31 files changed, 997 insertions(+), 31 deletions(-)
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/config/Custom/FactionSystem.ini
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/501.htm
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/502.htm
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/manager.html
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatRandomizer.java
create mode 100644 L2J_Mobius_CT_2.6_HighFive/dist/game/data/stats/npcs/custom/gve_factions.xml
create mode 100644 L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/FactionManager.java
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/db_installer/sql/game/characters.sql b/L2J_Mobius_CT_2.6_HighFive/dist/db_installer/sql/game/characters.sql
index 5ff9916e82..56b80c6f13 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/db_installer/sql/game/characters.sql
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/db_installer/sql/game/characters.sql
@@ -55,6 +55,7 @@ CREATE TABLE IF NOT EXISTS `characters` (
`vitality_points` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
`createDate` date NOT NULL DEFAULT '2015-01-01',
`language` VARCHAR(2) DEFAULT NULL,
+ `faction` TINYINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`charId`),
KEY `account_name` (`account_name`),
KEY `char_name` (`char_name`),
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/config/Custom/FactionSystem.ini b/L2J_Mobius_CT_2.6_HighFive/dist/game/config/Custom/FactionSystem.ini
new file mode 100644
index 0000000000..9539f2ce24
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/config/Custom/FactionSystem.ini
@@ -0,0 +1,76 @@
+# ---------------------------------------------------------------------------
+# Faction System (Good vs Evil)
+# ---------------------------------------------------------------------------
+
+# Enable faction system.
+# Default: False
+EnableFactionSystem = True
+
+# Starting location for all players.
+# Default: 85332,16199,-1252
+StartingLocation = 85332,16199,-1252
+
+# Faction manager NPC ID.
+# Default: 500
+FactionManagerNpcId = 500
+
+# Spawn location for faction manager NPC.
+# Default: 85712,15974,-1260,26808
+ManagerSpawnLocation = 85712,15974,-1260,26808
+
+# Good base location.
+# Default: 45306,48878,-3058
+GoodBaseLocation = 45306,48878,-3058
+
+# Evil base location.
+# Default: -44037,-113283,-237
+EvilBaseLocation = -44037,-113283,-237
+
+# Good team name.
+# Default: Good
+GoodTeamName = Good
+
+# Evil team name.
+# Default: Evil
+EvilTeamName = Evil
+
+# Good name color.
+# Default: 00FF00
+GoodNameColor = 00FF00
+
+# Evil name color.
+# Default: 0000FF
+EvilNameColor = 0000FF
+
+# Enable faction guards.
+# The NPC template must have faction as clan.
+# Default: True
+EnableFactionGuards = True
+
+# Good Guard NPC ID.
+# Default: 501
+GoodGuardNpcId = 501
+
+# Evil Guard NPC ID.
+# Default: 502
+EvilGuardNpcId = 502
+
+# Upon death, respawn at faction base.
+# Default: True
+RespawnAtFactionBase = True
+
+# Upon selecting faction, players become nobless.
+# Default: False
+FactionAutoNobless = False
+
+# Disallow chat between factions.
+# Default: True
+EnableFactionChat = True
+
+# Prohibit login when faction has more online players.
+# Default: True
+BalanceOnlinePlayers = True
+
+# Online player exceed limit (used by setting above).
+# Default: 20
+BalancePlayerExceedLimit = 20
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/501.htm b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/501.htm
new file mode 100644
index 0000000000..ae4b343c3e
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/501.htm
@@ -0,0 +1,4 @@
+
Sentinel:
+You must use extreme caution, sir! There have been reports of roaming thugs in this area, who think nothing of killing for the sheer pleasure of it. Please let me know if you see any of them. My bow will protect you from these murderers.
+May the divine protection of Eva be with you always.
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/502.htm b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/502.htm
new file mode 100644
index 0000000000..8910ad01a0
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/guard/502.htm
@@ -0,0 +1,3 @@
+Centurion:
+I am sworn by the will of Paagrio to destroy all evildoers! If you see any of them, tell me. My bow will put an end to their treachery!
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java
new file mode 100644
index 0000000000..47c97583dc
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java
@@ -0,0 +1,186 @@
+/*
+ * 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 custom.FactionSystem;
+
+import com.l2jmobius.Config;
+import com.l2jmobius.gameserver.enums.ChatType;
+import com.l2jmobius.gameserver.model.L2World;
+import com.l2jmobius.gameserver.model.actor.L2Character;
+import com.l2jmobius.gameserver.model.actor.L2Npc;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Mobius
+ */
+public final class FactionSystem extends AbstractNpcAI
+{
+ // NPCs
+ private static final int MANAGER = Config.FACTION_MANAGER_NPCID;
+ private static final int GOOD_GUARD = Config.FACTION_GOOD_GUARD_NPCID;
+ private static final int EVIL_GUARD = Config.FACTION_EVIL_GUARD_NPCID;
+ // Other
+ private static final String[] TEXTS =
+ {
+ Config.FACTION_GOOD_TEAM_NAME + " or " + Config.FACTION_EVIL_TEAM_NAME + "?",
+ "Select your faction!",
+ "The choice is yours!"
+ };
+
+ private FactionSystem()
+ {
+ addSpawnId(MANAGER);
+ addStartNpc(MANAGER);
+ addTalkId(MANAGER);
+ addFirstTalkId(MANAGER);
+ addSeeCreatureId(EVIL_GUARD, GOOD_GUARD);
+
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ addSpawn(MANAGER, Config.FACTION_MANAGER_LOCATION, false, 0);
+ }
+ }
+
+ @Override
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
+ {
+ switch (event)
+ {
+ case "selectGoodFaction":
+ {
+ if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (L2World.getInstance().getAllGoodPlayers().size() >= (L2World.getInstance().getAllEvilPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT)))
+ {
+ final String htmltext = null;
+ final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
+ packet.setHtml(getHtm(player.getHtmlPrefix(), "onlinelimit.html"));
+ packet.replace("%name%", player.getName());
+ packet.replace("%more%", Config.FACTION_GOOD_TEAM_NAME);
+ packet.replace("%less%", Config.FACTION_EVIL_TEAM_NAME);
+ player.sendPacket(packet);
+ return htmltext;
+ }
+ if (Config.FACTION_AUTO_NOBLESS)
+ {
+ player.setNoble(true);
+ }
+ player.setGood();
+ player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR);
+ player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR);
+ player.setTitle(Config.FACTION_GOOD_TEAM_NAME);
+ player.sendMessage("You are now fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.");
+ player.teleToLocation(Config.FACTION_GOOD_BASE_LOCATION);
+ broadcastMessageToFaction(Config.FACTION_GOOD_TEAM_NAME, Config.FACTION_GOOD_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + ".");
+ L2World.addFactionPlayerToWorld(player);
+ break;
+ }
+ case "selectEvilFaction":
+ {
+ if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (L2World.getInstance().getAllEvilPlayers().size() >= (L2World.getInstance().getAllGoodPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT)))
+ {
+ final String htmltext = null;
+ final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
+ packet.setHtml(getHtm(player.getHtmlPrefix(), "onlinelimit.html"));
+ packet.replace("%name%", player.getName());
+ packet.replace("%more%", Config.FACTION_EVIL_TEAM_NAME);
+ packet.replace("%less%", Config.FACTION_GOOD_TEAM_NAME);
+ player.sendPacket(packet);
+ return htmltext;
+ }
+ if (Config.FACTION_AUTO_NOBLESS)
+ {
+ player.setNoble(true);
+ }
+ player.setEvil();
+ player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR);
+ player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR);
+ player.setTitle(Config.FACTION_EVIL_TEAM_NAME);
+ player.sendMessage("You are now fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.");
+ player.teleToLocation(Config.FACTION_EVIL_BASE_LOCATION);
+ broadcastMessageToFaction(Config.FACTION_EVIL_TEAM_NAME, Config.FACTION_EVIL_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + ".");
+ L2World.addFactionPlayerToWorld(player);
+ break;
+ }
+ case "SPEAK":
+ {
+ if (npc != null)
+ {
+ npc.broadcastSay(ChatType.NPC_GENERAL, TEXTS[getRandom(TEXTS.length)], 1500);
+ }
+ break;
+ }
+ }
+ return super.onAdvEvent(event, npc, player);
+ }
+
+ @Override
+ public String onFirstTalk(L2Npc npc, L2PcInstance player)
+ {
+ final String htmltext = null;
+ final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
+ packet.setHtml(getHtm(player.getHtmlPrefix(), "manager.html"));
+ packet.replace("%name%", player.getName());
+ packet.replace("%good%", Config.FACTION_GOOD_TEAM_NAME);
+ packet.replace("%evil%", Config.FACTION_EVIL_TEAM_NAME);
+ player.sendPacket(packet);
+ return htmltext;
+ }
+
+ @Override
+ public String onSpawn(L2Npc npc)
+ {
+ if (npc.getId() == MANAGER)
+ {
+ startQuestTimer("SPEAK", 10000, npc, null, true);
+ }
+ return super.onSpawn(npc);
+ }
+
+ private void broadcastMessageToFaction(String factionName, String message)
+ {
+ if (factionName.equals(Config.FACTION_GOOD_TEAM_NAME))
+ {
+ for (L2PcInstance player : L2World.getInstance().getAllGoodPlayers())
+ {
+ player.sendMessage(message);
+ }
+ }
+ else
+ {
+ for (L2PcInstance player : L2World.getInstance().getAllEvilPlayers())
+ {
+ player.sendMessage(message);
+ }
+ }
+ }
+
+ @Override
+ public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
+ {
+ if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && creature.isPlayer() && ((creature.getActingPlayer().isGood() && (npc.getId() == EVIL_GUARD)) || (creature.getActingPlayer().isEvil() && (npc.getId() == GOOD_GUARD))))
+ {
+ addAttackDesire(npc, creature);
+ }
+ return super.onSeeCreature(npc, creature, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new FactionSystem();
+ }
+}
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/manager.html b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/manager.html
new file mode 100644
index 0000000000..2b95871ec8
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/manager.html
@@ -0,0 +1,6 @@
+Faction Manager:
+What will your destiny be %name%?
+Will you choose to be %good%? ...or maybe %evil%?
+"I choose %good%!"
+"I choose %evil%!"
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html
new file mode 100644
index 0000000000..0f9fa95cc6
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html
@@ -0,0 +1,5 @@
+Faction Manager:
+I am sorry %name%.
+It seems that there are currently more %more% than %less% players online.
+Try selecting the opposing faction or wait for some %more% players to logout.
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatGeneral.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatGeneral.java
index 92f649271c..088cf9fe5a 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatGeneral.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatGeneral.java
@@ -87,11 +87,33 @@ public final class ChatGeneral implements IChatHandler
}
final CreatureSay cs = new CreatureSay(activeChar.getObjectId(), type, activeChar.getAppearance().getVisibleName(), text);
+ final CreatureSay csRandom = new CreatureSay(activeChar.getObjectId(), type, activeChar.getAppearance().getVisibleName(), ChatRandomizer.randomize(text));
L2World.getInstance().forEachVisibleObjectInRange(activeChar, L2PcInstance.class, 1250, player ->
{
if ((player != null) && !BlockList.isBlocked(player, activeChar))
{
- player.sendPacket(cs);
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (Config.FACTION_SPECIFIC_CHAT)
+ {
+ if ((activeChar.isGood() && player.isEvil()) || (activeChar.isEvil() && player.isGood()))
+ {
+ player.sendPacket(csRandom);
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
}
});
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatHeroVoice.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatHeroVoice.java
index 2ee3839b31..a8759805cd 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatHeroVoice.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatHeroVoice.java
@@ -67,7 +67,24 @@ public final class ChatHeroVoice implements IChatHandler
{
if ((player != null) && !BlockList.isBlocked(player, activeChar))
{
- player.sendPacket(cs);
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (Config.FACTION_SPECIFIC_CHAT)
+ {
+ if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
}
}
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatPartyMatchRoom.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatPartyMatchRoom.java
index 01f561a320..30650f6676 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatPartyMatchRoom.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatPartyMatchRoom.java
@@ -63,7 +63,24 @@ public class ChatPartyMatchRoom implements IChatHandler
final CreatureSay cs = new CreatureSay(activeChar.getObjectId(), type, activeChar.getName(), text);
for (L2PcInstance _member : _room.getPartyMembers())
{
- _member.sendPacket(cs);
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (Config.FACTION_SPECIFIC_CHAT)
+ {
+ if ((activeChar.isGood() && _member.isGood()) || (activeChar.isEvil() && _member.isEvil()))
+ {
+ _member.sendPacket(cs);
+ }
+ }
+ else
+ {
+ _member.sendPacket(cs);
+ }
+ }
+ else
+ {
+ _member.sendPacket(cs);
+ }
}
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatRandomizer.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatRandomizer.java
new file mode 100644
index 0000000000..24ef1222ad
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatRandomizer.java
@@ -0,0 +1,50 @@
+/*
+ * 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 handlers.chathandlers;
+
+import com.l2jmobius.commons.util.Rnd;
+
+/**
+ * @author Mobius
+ */
+class ChatRandomizer
+{
+ static String randomize(String text)
+ {
+ final StringBuilder textOut = new StringBuilder();
+ for (char c : text.toCharArray())
+ {
+ if ((c > 96) && (c < 123))
+ {
+ textOut.append(Character.toString((char) Rnd.get(96, 123)));
+ }
+ else if ((c > 64) && (c < 91))
+ {
+ textOut.append(Character.toString((char) Rnd.get(64, 91)));
+ }
+ else if ((c == 32) || (c == 44) || (c == 46))
+ {
+ textOut.append(c);
+ }
+ else
+ {
+ textOut.append(Character.toString((char) Rnd.get(47, 64)));
+ }
+ }
+ return textOut.toString();
+ }
+}
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatShout.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatShout.java
index cbd3987b30..b5846dc8f2 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatShout.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatShout.java
@@ -63,9 +63,26 @@ public final class ChatShout implements IChatHandler
final int region = MapRegionManager.getInstance().getMapRegionLocId(activeChar);
for (L2PcInstance player : L2World.getInstance().getPlayers())
{
- if ((region == MapRegionManager.getInstance().getMapRegionLocId(player)) && !BlockList.isBlocked(player, activeChar) && (player.getInstanceId() == activeChar.getInstanceId()))
+ if ((region == MapRegionManager.getInstance().getMapRegionLocId(player)) && !BlockList.isBlocked(player, activeChar) && (player.getInstanceId() == activeChar.getInstanceId()) && !BlockList.isBlocked(player, activeChar))
{
- player.sendPacket(cs);
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (Config.FACTION_SPECIFIC_CHAT)
+ {
+ if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
}
}
}
@@ -81,7 +98,24 @@ public final class ChatShout implements IChatHandler
{
if (!BlockList.isBlocked(player, activeChar))
{
- player.sendPacket(cs);
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (Config.FACTION_SPECIFIC_CHAT)
+ {
+ if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
}
}
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatTrade.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatTrade.java
index f2ade47c1b..79420497e2 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatTrade.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatTrade.java
@@ -65,7 +65,24 @@ public final class ChatTrade implements IChatHandler
{
if ((region == MapRegionManager.getInstance().getMapRegionLocId(player)) && !BlockList.isBlocked(player, activeChar) && (player.getInstanceId() == activeChar.getInstanceId()))
{
- player.sendPacket(cs);
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (Config.FACTION_SPECIFIC_CHAT)
+ {
+ if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
}
}
}
@@ -81,7 +98,24 @@ public final class ChatTrade implements IChatHandler
{
if (!BlockList.isBlocked(player, activeChar))
{
- player.sendPacket(cs);
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (Config.FACTION_SPECIFIC_CHAT)
+ {
+ if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
+ }
+ else
+ {
+ player.sendPacket(cs);
+ }
}
}
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatWhisper.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatWhisper.java
index da9ac7fbef..12a4e008a7 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatWhisper.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/handlers/chathandlers/ChatWhisper.java
@@ -77,6 +77,11 @@ public final class ChatWhisper implements IChatHandler
activeChar.sendMessage("Player is in offline mode.");
return;
}
+ if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_SPECIFIC_CHAT && ((activeChar.isGood() && receiver.isEvil()) || (activeChar.isEvil() && receiver.isGood())))
+ {
+ activeChar.sendMessage("Player belongs to the opposing faction.");
+ return;
+ }
if (!BlockList.isBlocked(receiver, activeChar))
{
// Allow reciever to send PMs to this char, which is in silence mode.
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/stats/npcs/custom/gve_factions.xml b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/stats/npcs/custom/gve_factions.xml
new file mode 100644
index 0000000000..6214bfc71c
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/stats/npcs/custom/gve_factions.xml
@@ -0,0 +1,107 @@
+
+
+
+ ELF
+ FEMALE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ELF
+ MALE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ Good
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ORC
+ MALE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ Evil
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java
index 5beb37a810..e59d77eb9e 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java
@@ -105,13 +105,13 @@ public final class Config
// Custom Config File Definitions
// --------------------------------------------------
public static final String CUSTOM_ALLOWED_PLAYER_RACES_CONFIG_FILE = "./config/Custom/AllowedPlayerRaces.ini";
- public static final String CUSTOM_ANTIFEED_CONFIG_FILE = "./config/Custom/AntiFeed.ini";
public static final String CUSTOM_AUTO_POTIONS_CONFIG_FILE = "./config/Custom/AutoPotions.ini";
public static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini";
public static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini";
public static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini";
public static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini";
public static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini";
+ public static final String CUSTOM_FACTION_SYSTEM_CONFIG_FILE = "./config/Custom/FactionSystem.ini";
public static final String CUSTOM_FIND_PVP_CONFIG_FILE = "./config/Custom/FindPvP.ini";
public static final String CUSTOM_HELLBOUND_STATUS_CONFIG_FILE = "./config/Custom/HellboundStatus.ini";
public static final String CUSTOM_OFFLINE_TRADE_CONFIG_FILE = "./config/Custom/OfflineTrade.ini";
@@ -1200,6 +1200,24 @@ public final class Config
public static int COMMUNITY_PREMIUM_PRICE_PER_DAY;
public static List COMMUNITY_AVAILABLE_BUFFS;
public static Map COMMUNITY_AVAILABLE_TELEPORTS;
+ public static boolean FACTION_SYSTEM_ENABLED;
+ public static Location FACTION_STARTING_LOCATION;
+ public static int FACTION_MANAGER_NPCID;
+ public static Location FACTION_MANAGER_LOCATION;
+ public static Location FACTION_GOOD_BASE_LOCATION;
+ public static Location FACTION_EVIL_BASE_LOCATION;
+ public static String FACTION_GOOD_TEAM_NAME;
+ public static String FACTION_EVIL_TEAM_NAME;
+ public static int FACTION_GOOD_NAME_COLOR;
+ public static int FACTION_EVIL_NAME_COLOR;
+ public static boolean FACTION_GUARDS_ENABLED;
+ public static int FACTION_GOOD_GUARD_NPCID;
+ public static int FACTION_EVIL_GUARD_NPCID;
+ public static boolean FACTION_RESPAWN_AT_BASE;
+ public static boolean FACTION_AUTO_NOBLESS;
+ public static boolean FACTION_SPECIFIC_CHAT;
+ public static boolean FACTION_BALANCE_ONLINE_PLAYERS;
+ public static int FACTION_BALANCE_PLAYER_EXCEED_LIMIT;
public static boolean ENABLE_FIND_PVP;
public static boolean PREMIUM_SYSTEM_ENABLED;
public static float PREMIUM_RATE_XP;
@@ -2602,6 +2620,33 @@ public final class Config
}
}
+ // Load FactionSystem config file (if exists)
+ final PropertiesParser FactionSystem = new PropertiesParser(CUSTOM_FACTION_SYSTEM_CONFIG_FILE);
+
+ String[] tempString;
+ FACTION_SYSTEM_ENABLED = Boolean.valueOf(FactionSystem.getBoolean("EnableFactionSystem", false));
+ tempString = FactionSystem.getString("StartingLocation", "85332,16199,-1252").split(",");
+ FACTION_STARTING_LOCATION = new Location(Integer.parseInt(tempString[0]), Integer.parseInt(tempString[1]), Integer.parseInt(tempString[2]));
+ FACTION_MANAGER_NPCID = FactionSystem.getInt("FactionManagerNpcId", 500);
+ tempString = FactionSystem.getString("ManagerSpawnLocation", "85712,15974,-1260,26808").split(",");
+ FACTION_MANAGER_LOCATION = new Location(Integer.parseInt(tempString[0]), Integer.parseInt(tempString[1]), Integer.parseInt(tempString[2]), tempString[3] != null ? Integer.parseInt(tempString[3]) : 0);
+ tempString = FactionSystem.getString("GoodBaseLocation", "45306,48878,-3058").split(",");
+ FACTION_GOOD_BASE_LOCATION = new Location(Integer.parseInt(tempString[0]), Integer.parseInt(tempString[1]), Integer.parseInt(tempString[2]));
+ tempString = FactionSystem.getString("EvilBaseLocation", "-44037,-113283,-237").split(",");
+ FACTION_EVIL_BASE_LOCATION = new Location(Integer.parseInt(tempString[0]), Integer.parseInt(tempString[1]), Integer.parseInt(tempString[2]));
+ FACTION_GOOD_TEAM_NAME = FactionSystem.getString("GoodTeamName", "Good");
+ FACTION_EVIL_TEAM_NAME = FactionSystem.getString("EvilTeamName", "Evil");
+ FACTION_GOOD_NAME_COLOR = Integer.decode("0x" + FactionSystem.getString("GoodNameColor", "00FF00"));
+ FACTION_EVIL_NAME_COLOR = Integer.decode("0x" + FactionSystem.getString("EvilNameColor", "0000FF"));
+ FACTION_GUARDS_ENABLED = FactionSystem.getBoolean("EnableFactionGuards", true);
+ FACTION_GOOD_GUARD_NPCID = FactionSystem.getInt("GoodGuardNpcId", 501);
+ FACTION_EVIL_GUARD_NPCID = FactionSystem.getInt("EvilGuardNpcId", 502);
+ FACTION_RESPAWN_AT_BASE = FactionSystem.getBoolean("RespawnAtFactionBase", true);
+ FACTION_AUTO_NOBLESS = FactionSystem.getBoolean("FactionAutoNobless", false);
+ FACTION_SPECIFIC_CHAT = FactionSystem.getBoolean("EnableFactionChat", true);
+ FACTION_BALANCE_ONLINE_PLAYERS = FactionSystem.getBoolean("BalanceOnlinePlayers", true);
+ FACTION_BALANCE_PLAYER_EXCEED_LIMIT = FactionSystem.getInt("BalancePlayerExceedLimit", 20);
+
// Load FindPvP config file (if exists)
final PropertiesParser FindPvP = new PropertiesParser(CUSTOM_FIND_PVP_CONFIG_FILE);
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java
index a5d912fe0e..75d4a5d897 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java
@@ -98,6 +98,7 @@ import com.l2jmobius.gameserver.instancemanager.CoupleManager;
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
import com.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
import com.l2jmobius.gameserver.instancemanager.DimensionalRiftManager;
+import com.l2jmobius.gameserver.instancemanager.FactionManager;
import com.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
import com.l2jmobius.gameserver.instancemanager.FortManager;
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
@@ -237,6 +238,11 @@ public final class GameServer
PetDataTable.getInstance();
CharSummonTable.getInstance().init();
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ FactionManager.getInstance();
+ }
+
if (Config.PREMIUM_SYSTEM_ENABLED)
{
LOGGER.info("PremiumManager: Premium system is enabled.");
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/xml/impl/NpcData.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/xml/impl/NpcData.java
index 15f32773be..9bc44dd28f 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/xml/impl/NpcData.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/xml/impl/NpcData.java
@@ -672,11 +672,11 @@ public class NpcData implements IGameXmlReader
*/
private int getOrCreateClanId(String clanName)
{
- Integer id = _clans.get(clanName.toUpperCase());
+ Integer id = _clans.get(clanName);
if (id == null)
{
id = _clans.size();
- _clans.put(clanName.toUpperCase(), id);
+ _clans.put(clanName, id);
}
return id;
}
@@ -688,7 +688,7 @@ public class NpcData implements IGameXmlReader
*/
public int getClanId(String clanName)
{
- final Integer id = _clans.get(clanName.toUpperCase());
+ final Integer id = _clans.get(clanName);
return id != null ? id : -1;
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/FactionManager.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/FactionManager.java
new file mode 100644
index 0000000000..7f4c6abd61
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/FactionManager.java
@@ -0,0 +1,115 @@
+/*
+ * 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 com.l2jmobius.gameserver.instancemanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.l2jmobius.commons.database.DatabaseFactory;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * Contains objectId and factionId for all players.
+ * @author Mobius
+ */
+public class FactionManager
+{
+ private static Logger _log = Logger.getLogger(FactionManager.class.getName());
+ private final Map _playerFactions = new ConcurrentHashMap<>();
+
+ protected FactionManager()
+ {
+ loadAll();
+ }
+
+ private void loadAll()
+ {
+ _playerFactions.clear();
+ try (Connection con = DatabaseFactory.getInstance().getConnection();
+ Statement s = con.createStatement();
+ ResultSet rs = s.executeQuery("SELECT charId, faction FROM characters"))
+ {
+ while (rs.next())
+ {
+ _playerFactions.put(rs.getInt(1), rs.getInt(2));
+ }
+ }
+ catch (SQLException e)
+ {
+ _log.log(Level.WARNING, getClass().getSimpleName() + ": Could not load character faction information: " + e.getMessage(), e);
+ }
+ _log.info(getClass().getSimpleName() + ": Loaded " + _playerFactions.size() + " character faction values.");
+ }
+
+ public final int getFactionByCharId(int id)
+ {
+ if (id <= 0)
+ {
+ return 0;
+ }
+
+ Integer factionId = _playerFactions.get(id);
+ if (factionId != null)
+ {
+ return factionId;
+ }
+
+ try (Connection con = DatabaseFactory.getInstance().getConnection();
+ PreparedStatement ps = con.prepareStatement("SELECT faction FROM characters WHERE charId=?"))
+ {
+ ps.setInt(1, id);
+ try (ResultSet rset = ps.executeQuery())
+ {
+ if (rset.next())
+ {
+ factionId = rset.getInt(1);
+ _playerFactions.put(id, factionId);
+ return factionId;
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ _log.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing char id: " + e.getMessage(), e);
+ }
+
+ return 0; // not found
+ }
+
+ public final boolean isSameFaction(L2PcInstance player1, L2PcInstance player2)
+ {
+ // TODO: Maybe add support for multiple factions?
+ return (player1.isGood() && player2.isGood()) || (player1.isEvil() && player2.isEvil());
+ }
+
+ public static FactionManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final FactionManager _instance = new FactionManager();
+ }
+}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/MapRegionManager.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/MapRegionManager.java
index 80050adfbf..60d6688941 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/MapRegionManager.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/MapRegionManager.java
@@ -25,6 +25,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
+import com.l2jmobius.Config;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.SevenSigns;
import com.l2jmobius.gameserver.model.L2MapRegion;
@@ -158,7 +159,11 @@ public final class MapRegionManager implements IGameXmlReader
public final int getMapRegionLocId(int locX, int locY)
{
final L2MapRegion region = getMapRegion(locX, locY);
- return region != null ? region.getLocId() : 0;
+ if (region != null)
+ {
+ return region.getLocId();
+ }
+ return 0;
}
/**
@@ -405,6 +410,18 @@ public final class MapRegionManager implements IGameXmlReader
}
}
+ if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_RESPAWN_AT_BASE)
+ {
+ if (activeChar.getActingPlayer().isGood())
+ {
+ return Config.FACTION_GOOD_BASE_LOCATION;
+ }
+ if (activeChar.getActingPlayer().isEvil())
+ {
+ return Config.FACTION_EVIL_BASE_LOCATION;
+ }
+ }
+
// Get the nearest town
try
{
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/CharSelectInfoPackage.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/CharSelectInfoPackage.java
index 6e4b5a59ba..26072c8a99 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/CharSelectInfoPackage.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/CharSelectInfoPackage.java
@@ -54,6 +54,8 @@ public class CharSelectInfoPackage
private int _y = 0;
private int _z = 0;
private String _htmlPrefix = null;
+ private boolean _isGood = false;
+ private boolean _isEvil = false;
private int _vitalityPoints = 0;
private int _accessLevel = 0;
@@ -98,6 +100,28 @@ public class CharSelectInfoPackage
_accessLevel = level;
}
+ public boolean isGood()
+ {
+ return _isGood;
+ }
+
+ public void setGood()
+ {
+ _isGood = true;
+ _isEvil = false;
+ }
+
+ public boolean isEvil()
+ {
+ return _isEvil;
+ }
+
+ public void setEvil()
+ {
+ _isGood = false;
+ _isEvil = true;
+ }
+
public int getClanId()
{
return _clanId;
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/L2World.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/L2World.java
index bad5cbead9..0cb5921bfc 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/L2World.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/L2World.java
@@ -25,6 +25,7 @@ import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.logging.Logger;
+import com.l2jmobius.Config;
import com.l2jmobius.commons.util.CommonUtil;
import com.l2jmobius.gameserver.ai.CtrlEvent;
import com.l2jmobius.gameserver.ai.CtrlIntention;
@@ -84,6 +85,10 @@ public final class L2World
/** Map containing all the players in game. */
private final Map _allPlayers = new ConcurrentHashMap<>();
+ /** Map containing all the Good players in game. */
+ private static final Map _allGoodPlayers = new ConcurrentHashMap<>();
+ /** Map containing all the Evil players in game. */
+ private static final Map _allEvilPlayers = new ConcurrentHashMap<>();
/** Map containing all visible objects. */
private final Map _allObjects = new ConcurrentHashMap<>();
/** Map with the pets instances and their owner ID. */
@@ -139,6 +144,10 @@ public final class L2World
Disconnection.of(newPlayer).defaultSequence(false);
LOGGER.warning(getClass().getSimpleName() + ": Duplicate character!? Disconnected both characters (" + newPlayer.getName() + ")");
}
+ else if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ addFactionPlayerToWorld(newPlayer);
+ }
}
}
@@ -163,6 +172,18 @@ public final class L2World
return;
}
_allPlayers.remove(object.getObjectId());
+
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (player.isGood())
+ {
+ _allGoodPlayers.remove(player.getObjectId());
+ }
+ else if (player.isEvil())
+ {
+ _allEvilPlayers.remove(player.getObjectId());
+ }
+ }
}
}
@@ -198,6 +219,16 @@ public final class L2World
return _allPlayers.values();
}
+ public Collection getAllGoodPlayers()
+ {
+ return _allGoodPlayers.values();
+ }
+
+ public Collection getAllEvilPlayers()
+ {
+ return _allEvilPlayers.values();
+ }
+
/**
* If you have access to player objectId use {@link #getPlayer(int playerObjId)}
* @param name Name of the player to get Instance
@@ -323,6 +354,18 @@ public final class L2World
});
}
+ public static void addFactionPlayerToWorld(L2PcInstance player)
+ {
+ if (player.isGood())
+ {
+ _allGoodPlayers.put(player.getObjectId(), player);
+ }
+ else if (player.isEvil())
+ {
+ _allEvilPlayers.put(player.getObjectId(), player);
+ }
+ }
+
/**
* Remove a L2Object from the world. Concept : L2Object (including L2PcInstance) are identified in _visibleObjects of his current L2WorldRegion and in _knownObjects of other surrounding L2Characters
* L2PcInstance are identified in _allPlayers of L2World, in _allPlayers of his current L2WorldRegion and in _knownPlayer of other surrounding L2Characters Actions :
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Attackable.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Attackable.java
index b8e4457520..b3e0849158 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Attackable.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Attackable.java
@@ -653,7 +653,7 @@ public class L2Attackable extends L2Npc
*/
public void addDamageHate(L2Character attacker, int damage, int aggro)
{
- if (attacker == null)
+ if ((attacker == null) || (attacker == this))
{
return;
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2GuardInstance.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2GuardInstance.java
index fbcf4ba6c1..8ab1f3e991 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2GuardInstance.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2GuardInstance.java
@@ -16,16 +16,17 @@
*/
package com.l2jmobius.gameserver.model.actor.instance;
+import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.model.L2World;
-import com.l2jmobius.gameserver.model.L2WorldRegion;
import com.l2jmobius.gameserver.model.actor.L2Attackable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
import com.l2jmobius.gameserver.model.events.EventType;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
+import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
/**
@@ -49,11 +50,24 @@ public class L2GuardInstance extends L2Attackable
@Override
public boolean isAutoAttackable(L2Character attacker)
{
- if (attacker.isPlayer())
+ if (attacker.isMonster())
{
- return ((L2PcInstance) attacker).getKarma() > 0;
+ return true;
}
- return attacker instanceof L2MonsterInstance;
+ return super.isAutoAttackable(attacker);
+ }
+
+ @Override
+ public void addDamage(L2Character attacker, int damage, Skill skill)
+ {
+ super.addDamage(attacker, damage, skill);
+ getAI().startFollow(attacker);
+ addDamageHate(attacker, 0, 10);
+ L2World.getInstance().forEachVisibleObjectInRange(this, L2GuardInstance.class, 500, guard ->
+ {
+ guard.getAI().startFollow(attacker);
+ guard.addDamageHate(attacker, 0, 10);
+ });
}
/**
@@ -65,12 +79,13 @@ public class L2GuardInstance extends L2Attackable
setIsNoRndWalk(true);
super.onSpawn();
+ getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
// check the region where this mob is, do not activate the AI if region is inactive.
- final L2WorldRegion region = L2World.getInstance().getRegion(this);
- if ((region != null) && (!region.isActive()))
- {
- getAI().stopAITask();
- }
+ // final L2WorldRegion region = L2World.getInstance().getRegion(this);
+ // if ((region != null) && (!region.isActive()))
+ // {
+ // getAI().stopAITask();
+ // }
}
/**
@@ -126,6 +141,13 @@ public class L2GuardInstance extends L2Attackable
return;
}
+ if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((player.isGood() && getTemplate().isClan(Config.FACTION_EVIL_TEAM_NAME)) || (player.isEvil() && getTemplate().isClan(Config.FACTION_GOOD_TEAM_NAME))))
+ {
+ interact = false;
+ // TODO: Fix normal targeting
+ player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
+ }
+
// Check if the L2PcInstance already target the L2GuardInstance
if (getObjectId() != player.getTargetId())
{
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java
index b79c819b85..833aa6f517 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java
@@ -349,7 +349,7 @@ public final class L2PcInstance extends L2Playable
// Character Character SQL String Definitions:
private static final String INSERT_CHARACTER = "INSERT INTO characters (account_name,charId,char_name,level,maxHp,curHp,maxCp,curCp,maxMp,curMp,face,hairStyle,hairColor,sex,exp,sp,karma,fame,pvpkills,pkkills,clanid,race,classid,deletetime,cancraft,title,title_color,accesslevel,online,isin7sdungeon,clan_privs,wantspeace,base_class,newbie,nobless,power_grade,createDate) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
- private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,face=?,hairStyle=?,hairColor=?,sex=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,fame=?,pvpkills=?,pkkills=?,clanid=?,race=?,classid=?,deletetime=?,title=?,title_color=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,newbie=?,nobless=?,power_grade=?,subpledge=?,lvl_joined_academy=?,apprentice=?,sponsor=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,bookmarkslot=?,vitality_points=?,language=? WHERE charId=?";
+ private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,face=?,hairStyle=?,hairColor=?,sex=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,fame=?,pvpkills=?,pkkills=?,clanid=?,race=?,classid=?,deletetime=?,title=?,title_color=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,newbie=?,nobless=?,power_grade=?,subpledge=?,lvl_joined_academy=?,apprentice=?,sponsor=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,bookmarkslot=?,vitality_points=?,language=?,faction=? WHERE charId=?";
private static final String RESTORE_CHARACTER = "SELECT * FROM characters WHERE charId=?";
// Character Teleport Bookmark:
@@ -575,6 +575,10 @@ public final class L2PcInstance extends L2Playable
/** Premium System */
private boolean _premiumStatus = false;
+ /** Faction System */
+ private boolean _isGood = false;
+ private boolean _isEvil = false;
+
/** The L2FolkInstance corresponding to the last Folk which one the player talked. */
private L2Npc _lastFolkNpc = null;
@@ -593,7 +597,7 @@ public final class L2PcInstance extends L2Playable
private final Set _snoopListener = ConcurrentHashMap.newKeySet(1);
private final Set _snoopedPlayer = ConcurrentHashMap.newKeySet(1);
- // hennas
+ /** Hennas */
private final L2Henna[] _henna = new L2Henna[3];
private int _hennaSTR;
private int _hennaINT;
@@ -5436,6 +5440,16 @@ public final class L2PcInstance extends L2Playable
return;
}
+ if (this == player_target)
+ {
+ return;
+ }
+
+ if (Config.FACTION_SYSTEM_ENABLED && target.isPlayer() && ((isGood() && player_target.isEvil()) || (isEvil() && player_target.isGood())))
+ {
+ return;
+ }
+
if (isInDuel() && (player_target.getDuelId() == getDuelId()))
{
return;
@@ -6715,6 +6729,16 @@ public final class L2PcInstance extends L2Playable
player.setNewbie(rset.getInt("newbie"));
player.setNoble(rset.getInt("nobless") == 1);
+ final int factionId = rset.getInt("faction");
+ if (factionId == 1)
+ {
+ player.setGood();
+ }
+ if (factionId == 2)
+ {
+ player.setEvil();
+ }
+
player.setClanJoinExpiryTime(rset.getLong("clan_join_expiry_time"));
if (player.getClanJoinExpiryTime() < System.currentTimeMillis())
{
@@ -7282,7 +7306,18 @@ public final class L2PcInstance extends L2Playable
ps.setInt(47, getBookMarkSlot());
ps.setInt(48, getVitalityPoints());
ps.setString(49, getLang());
- ps.setInt(50, getObjectId());
+
+ int factionId = 0;
+ if (isGood())
+ {
+ factionId = 1;
+ }
+ if (isEvil())
+ {
+ factionId = 2;
+ }
+ ps.setInt(50, factionId);
+ ps.setInt(51, getObjectId());
ps.execute();
}
@@ -8226,7 +8261,11 @@ public final class L2PcInstance extends L2Playable
// Check if the attacker is in olympia and olympia start
if (attacker.isPlayer() && attacker.getActingPlayer().isInOlympiadMode())
{
- return isInOlympiadMode() && isOlympiadStart() && (((L2PcInstance) attacker).getOlympiadGameId() == getOlympiadGameId());
+ if (isInOlympiadMode() && isOlympiadStart() && (((L2PcInstance) attacker).getOlympiadGameId() == getOlympiadGameId()))
+ {
+ return true;
+ }
+ return false;
}
// Check if the attacker is in TvT and TvT is started
@@ -8295,8 +8334,14 @@ public final class L2PcInstance extends L2Playable
{
return true;
}
+
+ if (Config.FACTION_SYSTEM_ENABLED && ((isGood() && attackerPlayer.isEvil()) || (isEvil() && attackerPlayer.isGood())))
+ {
+ return true;
+ }
}
- else if (attacker instanceof L2DefenderInstance)
+
+ if (attacker instanceof L2DefenderInstance)
{
if (getClan() != null)
{
@@ -14301,6 +14346,28 @@ public final class L2PcInstance extends L2Playable
return _hasCharmOfCourage;
}
+ public boolean isGood()
+ {
+ return _isGood;
+ }
+
+ public boolean isEvil()
+ {
+ return _isEvil;
+ }
+
+ public void setGood()
+ {
+ _isGood = true;
+ _isEvil = false;
+ }
+
+ public void setEvil()
+ {
+ _isGood = false;
+ _isEvil = true;
+ }
+
/**
* @param target the target
* @return {@code true} if this player got war with the target, {@code false} otherwise.
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java
index 816b56bdc3..b68af7e434 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java
@@ -285,6 +285,10 @@ public final class CharacterCreate implements IClientIncomingPacket
final Location createLoc = new Location(Config.CUSTOM_STARTING_LOC_X, Config.CUSTOM_STARTING_LOC_Y, Config.CUSTOM_STARTING_LOC_Z);
newChar.setXYZInvisible(createLoc.getX(), createLoc.getY(), createLoc.getZ());
}
+ else if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ newChar.setXYZInvisible(Config.FACTION_STARTING_LOCATION.getX(), Config.FACTION_STARTING_LOCATION.getY(), Config.FACTION_STARTING_LOCATION.getZ());
+ }
else
{
final Location createLoc = template.getCreationPoint();
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterSelect.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterSelect.java
index 905e385928..40ae455c2f 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterSelect.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/CharacterSelect.java
@@ -27,6 +27,7 @@ import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
import com.l2jmobius.gameserver.instancemanager.PunishmentManager;
import com.l2jmobius.gameserver.model.CharSelectInfoPackage;
+import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.events.Containers;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
@@ -126,6 +127,28 @@ public class CharacterSelect implements IClientIncomingPacket
return;
}
+ if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_BALANCE_ONLINE_PLAYERS)
+ {
+ if (info.isGood() && (L2World.getInstance().getAllGoodPlayers().size() >= (L2World.getInstance().getAllEvilPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT)))
+ {
+ final NpcHtmlMessage msg = new NpcHtmlMessage();
+ msg.setFile(info.getHtmlPrefix(), "data/html/mods/Faction/ExceededOnlineLimit.htm");
+ msg.replace("%more%", Config.FACTION_GOOD_TEAM_NAME);
+ msg.replace("%less%", Config.FACTION_EVIL_TEAM_NAME);
+ client.sendPacket(msg);
+ return;
+ }
+ if (info.isEvil() && (L2World.getInstance().getAllEvilPlayers().size() >= (L2World.getInstance().getAllGoodPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT)))
+ {
+ final NpcHtmlMessage msg = new NpcHtmlMessage();
+ msg.setFile(info.getHtmlPrefix(), "data/html/mods/Faction/ExceededOnlineLimit.htm");
+ msg.replace("%more%", Config.FACTION_EVIL_TEAM_NAME);
+ msg.replace("%less%", Config.FACTION_GOOD_TEAM_NAME);
+ client.sendPacket(msg);
+ return;
+ }
+ }
+
// load up character from disk
final L2PcInstance cha = client.load(_charSlot);
if (cha == null)
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index ae97243c7d..a5a36d2506 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -376,6 +376,27 @@ public class EnterWorld implements IClientIncomingPacket
Quest.playerEnter(activeChar);
+ // Faction System
+ if (Config.FACTION_SYSTEM_ENABLED)
+ {
+ if (activeChar.isGood())
+ {
+ activeChar.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR);
+ activeChar.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR);
+ activeChar.sendMessage("Welcome " + activeChar.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.");
+ activeChar.sendPacket(new ExShowScreenMessage("Welcome " + activeChar.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.", 10000));
+ activeChar.broadcastUserInfo(); // for seeing self name color
+ }
+ else if (activeChar.isEvil())
+ {
+ activeChar.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR);
+ activeChar.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR);
+ activeChar.sendMessage("Welcome " + activeChar.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.");
+ activeChar.sendPacket(new ExShowScreenMessage("Welcome " + activeChar.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.", 10000));
+ activeChar.broadcastUserInfo(); // for seeing self name color
+ }
+ }
+
if (!Config.DISABLE_TUTORIAL)
{
loadTutorial(activeChar);
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/CharSelectionInfo.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/CharSelectionInfo.java
index 8ea628748d..cb39a05e0a 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/CharSelectionInfo.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/CharSelectionInfo.java
@@ -201,7 +201,7 @@ public class CharSelectionInfo implements IClientOutgoingPacket
private static void loadCharacterSubclassInfo(CharSelectInfoPackage charInfopackage, int ObjectId, int activeClassId)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
- PreparedStatement statement = con.prepareStatement("SELECT exp, sp, level FROM character_subclasses WHERE charId=? && class_id=? ORDER BY charId"))
+ PreparedStatement statement = con.prepareStatement("SELECT exp, sp, level FROM character_subclasses WHERE charId=? AND class_id=? ORDER BY charId"))
{
statement.setInt(1, ObjectId);
statement.setInt(2, activeClassId);
@@ -272,6 +272,16 @@ public class CharSelectionInfo implements IClientOutgoingPacket
charInfopackage.setY(chardata.getInt("y"));
charInfopackage.setZ(chardata.getInt("z"));
+ final int faction = chardata.getInt("faction");
+ if (faction == 1)
+ {
+ charInfopackage.setGood();
+ }
+ if (faction == 2)
+ {
+ charInfopackage.setEvil();
+ }
+
if (Config.MULTILANG_ENABLE)
{
String lang = chardata.getString("language");
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/NpcSay.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/NpcSay.java
index 8c10a0bc6e..5f4c4035f6 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/NpcSay.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/serverpackets/NpcSay.java
@@ -56,7 +56,7 @@ public final class NpcSay implements IClientOutgoingPacket
{
_objectId = npc.getObjectId();
_textType = messageType;
- _npcId = 1000000 + npc.getId();
+ _npcId = 1000000 + npc.getTemplate().getDisplayId();
_npcString = -1;
_text = text;
}
@@ -73,7 +73,7 @@ public final class NpcSay implements IClientOutgoingPacket
{
_objectId = npc.getObjectId();
_textType = messageType;
- _npcId = 1000000 + npc.getId();
+ _npcId = 1000000 + npc.getTemplate().getDisplayId();
_npcString = npcString.getId();
}
@@ -119,6 +119,7 @@ public final class NpcSay implements IClientOutgoingPacket
public boolean write(PacketWriter packet)
{
OutgoingPackets.NPC_SAY.writeId(packet);
+
packet.writeD(_objectId);
packet.writeD(_textType.getClientId());
packet.writeD(_npcId);
diff --git a/L2J_Mobius_CT_2.6_HighFive/readme.txt b/L2J_Mobius_CT_2.6_HighFive/readme.txt
index 0d6892b991..044732e46e 100644
--- a/L2J_Mobius_CT_2.6_HighFive/readme.txt
+++ b/L2J_Mobius_CT_2.6_HighFive/readme.txt
@@ -33,3 +33,4 @@ What is done
-Dropped SQL spawnlist
-Sell buffs command
-Dropped knownlists
+-Faction System (Good vs Evil)