From 29374416111dbf014bfe87fdae35ce1e734a4a5c Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Sat, 19 Mar 2022 22:06:45 +0000 Subject: [PATCH] Addition of faction system (Good vs Evil). --- .../dist/db_installer/sql/game/characters.sql | 1 + .../dist/db_installer/sql/game/custom_npc.sql | 11 +- .../dist/game/config/custom/FactionSystem.ini | 64 +++++++ .../dist/game/data/html/guard/501.htm | 4 + .../dist/game/data/html/guard/502.htm | 3 + .../html/mods/Faction/ExceededOnlineLimit.htm | 3 + .../custom/FactionSystem/FactionSystem.java | 164 ++++++++++++++++++ .../scripts/custom/FactionSystem/manager.html | 6 + .../custom/FactionSystem/onlinelimit.html | 5 + .../java/org/l2jmobius/Config.java | 45 +++++ .../l2jmobius/gameserver/ai/AttackableAI.java | 19 +- .../gameserver/data/xml/MapRegionData.java | 13 ++ .../handler/itemhandlers/ScrollOfEscape.java | 6 + .../handler/usercommandhandlers/Escape.java | 6 + .../l2jmobius/gameserver/model/BlockList.java | 5 + .../org/l2jmobius/gameserver/model/World.java | 45 ++++- .../gameserver/model/actor/Playable.java | 12 ++ .../gameserver/model/actor/Player.java | 142 +++++++++++---- .../model/actor/instance/Guard.java | 3 +- .../model/actor/knownlist/GuardKnownList.java | 22 ++- .../l2jmobius/gameserver/model/clan/Clan.java | 28 +++ .../clientpackets/CharacterCreate.java | 4 + .../clientpackets/CharacterSelected.java | 25 +++ .../network/clientpackets/EnterWorld.java | 21 +++ .../dist/db_installer/sql/game/characters.sql | 1 + .../dist/db_installer/sql/game/custom_npc.sql | 3 + .../dist/game/config/custom/FactionSystem.ini | 64 +++++++ .../dist/game/data/html/guard/501.htm | 4 + .../dist/game/data/html/guard/502.htm | 3 + .../html/mods/Faction/ExceededOnlineLimit.htm | 3 + .../custom/FactionSystem/FactionSystem.java | 164 ++++++++++++++++++ .../scripts/custom/FactionSystem/manager.html | 6 + .../custom/FactionSystem/onlinelimit.html | 5 + .../java/org/l2jmobius/Config.java | 45 +++++ .../l2jmobius/gameserver/ai/AttackableAI.java | 19 +- .../gameserver/data/xml/MapRegionData.java | 13 ++ .../handler/itemhandlers/ScrollOfEscape.java | 6 + .../handler/usercommandhandlers/Escape.java | 6 + .../l2jmobius/gameserver/model/BlockList.java | 5 + .../org/l2jmobius/gameserver/model/World.java | 45 ++++- .../gameserver/model/actor/Playable.java | 12 ++ .../gameserver/model/actor/Player.java | 143 +++++++++++---- .../model/actor/instance/Guard.java | 3 +- .../model/actor/knownlist/GuardKnownList.java | 22 ++- .../l2jmobius/gameserver/model/clan/Clan.java | 28 +++ .../clientpackets/CharacterCreate.java | 4 + .../clientpackets/CharacterSelected.java | 25 +++ .../network/clientpackets/EnterWorld.java | 21 +++ 48 files changed, 1193 insertions(+), 114 deletions(-) create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/custom/FactionSystem.ini create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/html/guard/501.htm create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/html/guard/502.htm create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/manager.html create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html create mode 100644 L2J_Mobius_C6_Interlude/dist/game/config/custom/FactionSystem.ini create mode 100644 L2J_Mobius_C6_Interlude/dist/game/data/html/guard/501.htm create mode 100644 L2J_Mobius_C6_Interlude/dist/game/data/html/guard/502.htm create mode 100644 L2J_Mobius_C6_Interlude/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm create mode 100644 L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java create mode 100644 L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/manager.html create mode 100644 L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/characters.sql b/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/characters.sql index 9a357de631..34817f15e2 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/characters.sql +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/characters.sql @@ -71,6 +71,7 @@ CREATE TABLE IF NOT EXISTS characters ( power_grade decimal(11,0) DEFAULT NULL, nobless decimal(1,0) NOT NULL DEFAULT 0, subpledge int(1) NOT NULL DEFAULT 0, + faction int(1) NOT NULL DEFAULT 0, last_recom_date decimal(20,0) NOT NULL DEFAULT 0, lvl_joined_academy int(1) NOT NULL DEFAULT 0, apprentice int(1) NOT NULL DEFAULT 0, diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/custom_npc.sql b/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/custom_npc.sql index 54a354432b..1354f12c67 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/custom_npc.sql +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/custom_npc.sql @@ -49,8 +49,11 @@ CREATE TABLE `custom_npc`( ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; INSERT ignore INTO custom_npc values -('31288', '31228', 'Roy the Cat', '1', 'Class Master', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'ClassMaster', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), -('50000', '31228', 'Dom the Cat', '1', 'Merchant', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'Merchant', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), -('50007', '31324', 'Andromeda', '1', 'Wedding Manager', '1', 'NPC.a_casino_FDarkElf', '8.00', '23.00', '70', 'female', 'WeddingManager', '40', '3862', '1493', '500', '500', '40', '43', '30', '21', '20', '10', '0', '0', '9999', '9999', '999', '999', '278', '0', '333', '316', '0', '0', '55', '132', null, '0', '1', '0', 'LAST_HIT'), -('50008', '31228', 'Rex the Cat', '1', 'Buffer', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'SchemeBuffer', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), +('500', '7115', 'Jurek', '1', 'Faction Manager', '1', 'NPC.a_mageguild_master_MHuman', '8.00', '24.00', '70', 'male', 'Folk', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '0', '0', '1314', '470', '780', '382', '278', '0', '333', '0', '0', '0', '55', '132', null, '0', '1', '0', 'LAST_HIT'), +('501', '8033', 'Sentinel', '1', ' ', '1', 'NPC.a_guard_MElf', '8.00', '23.50', '80', 'male', 'Guard', '1100', '4551', '1859', '13.43', '3.09', '40', '43', '30', '21', '20', '10', '0', '0', '4031', '576', '1144', '468', '249', '1000', '333', '276', '0', '0', '55', '176', 'Good', '500', '1', '0', 'LAST_HIT'), +('502', '8036', 'Centurion', '1', ' ', '1', 'NPC.e_guard_MOrc', '8.00', '27.00', '80', 'male', 'Guard', '1100', '4551', '1859', '13.43', '3.09', '40', '43', '30', '21', '20', '10', '0', '0', '4031', '576', '1144', '468', '249', '1000', '333', '273', '0', '0', '55', '176', 'Evil', '500', '1', '0', 'LAST_HIT'), +('31288', '8228', 'Roy the Cat', '1', 'Class Master', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'ClassMaster', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), +('50000', '8228', 'Dom the Cat', '1', 'Merchant', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'Merchant', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), +('50007', '8324', 'Andromeda', '1', 'Wedding Manager', '1', 'NPC.a_casino_FDarkElf', '8.00', '23.00', '70', 'female', 'WeddingManager', '40', '3862', '1493', '500', '500', '40', '43', '30', '21', '20', '10', '0', '0', '9999', '9999', '999', '999', '278', '0', '333', '316', '0', '0', '55', '132', null, '0', '1', '0', 'LAST_HIT'), +('50008', '8228', 'Rex the Cat', '1', 'Buffer', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'SchemeBuffer', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), ('55555', '22124', 'Totor', '1', 'Rebirth Manager', '1', 'NPC.a_fighterguild_master_FHuman', '11.00', '27.00', '83', 'male', 'Merchant', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '0', '0', '1314', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/custom/FactionSystem.ini b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/custom/FactionSystem.ini new file mode 100644 index 0000000000..ca1de8904b --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/custom/FactionSystem.ini @@ -0,0 +1,64 @@ +# --------------------------------------------------------------------------- +# Faction System (Good vs Evil) +# --------------------------------------------------------------------------- + +# Enable faction system. +# Default: False +EnableFactionSystem = False + +# Starting location for all players. +# Default: 85332,16199,-1252 +StartingLocation = 85332,16199,-1252 + +# 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 + +# 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_C4_ScionsOfDestiny/dist/game/data/html/guard/501.htm b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/html/guard/501.htm new file mode 100644 index 0000000000..ae4b343c3e --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/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_C4_ScionsOfDestiny/dist/game/data/html/guard/502.htm b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/html/guard/502.htm new file mode 100644 index 0000000000..8910ad01a0 --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/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_C4_ScionsOfDestiny/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm new file mode 100644 index 0000000000..858aa73517 --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm @@ -0,0 +1,3 @@ +RestrictionIt seems that there are currently more %more% than %less% players online.
+Try selecting an opposing faction character or wait for some %more% players to logout. + \ No newline at end of file diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java new file mode 100644 index 0000000000..c4aee45fef --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java @@ -0,0 +1,164 @@ +/* + * 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 org.l2jmobius.Config; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.Player; +import org.l2jmobius.gameserver.model.quest.Quest; +import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; + +/** + * @author Mobius + */ +public class FactionSystem extends Quest +{ + // NPC + private static final int MANAGER = 500; + // 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() + { + super(-1, "custom"); + + addSpawnId(MANAGER); + addStartNpc(MANAGER); + addTalkId(MANAGER); + addFirstTalkId(MANAGER); + + if (Config.FACTION_SYSTEM_ENABLED) + { + addSpawn(MANAGER, Config.FACTION_MANAGER_LOCATION, false, 0); + } + } + + @Override + public String onAdvEvent(String event, Npc npc, Player player) + { + switch (event) + { + case "selectGoodFaction": + { + if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (World.getInstance().getAllGoodPlayers().size() >= (World.getInstance().getAllEvilPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + String htmltext = getHtmlText("onlinelimit.html"); + htmltext = htmltext.replace("%name%", player.getName()); + htmltext = htmltext.replace("%more%", Config.FACTION_GOOD_TEAM_NAME); + htmltext = htmltext.replace("%less%", Config.FACTION_EVIL_TEAM_NAME); + 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, true); + broadcastMessageToFaction(Config.FACTION_GOOD_TEAM_NAME, Config.FACTION_GOOD_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + "."); + World.addFactionPlayerToWorld(player); + break; + } + case "selectEvilFaction": + { + if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (World.getInstance().getAllEvilPlayers().size() >= (World.getInstance().getAllGoodPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + String htmltext = getHtmlText("onlinelimit.html"); + htmltext = htmltext.replace("%name%", player.getName()); + htmltext = htmltext.replace("%more%", Config.FACTION_EVIL_TEAM_NAME); + htmltext = htmltext.replace("%less%", Config.FACTION_GOOD_TEAM_NAME); + 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, true); + broadcastMessageToFaction(Config.FACTION_EVIL_TEAM_NAME, Config.FACTION_EVIL_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + "."); + World.addFactionPlayerToWorld(player); + break; + } + case "SPEAK": + { + if (npc != null) + { + npc.broadcastPacket(new CreatureSay(npc.getObjectId(), ChatType.GENERAL, npc.getName(), getRandomEntry(TEXTS))); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onFirstTalk(Npc npc, Player player) + { + String htmltext = getHtmlText("manager.html"); + htmltext = htmltext.replace("%name%", player.getName()); + htmltext = htmltext.replace("%good%", Config.FACTION_GOOD_TEAM_NAME); + htmltext = htmltext.replace("%evil%", Config.FACTION_EVIL_TEAM_NAME); + return htmltext; + } + + @Override + public String onSpawn(Npc npc) + { + if (npc.getNpcId() == 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 (Player player : World.getInstance().getAllGoodPlayers()) + { + player.sendMessage(message); + } + } + else + { + for (Player player : World.getInstance().getAllEvilPlayers()) + { + player.sendMessage(message); + } + } + } + + public static void main(String[] args) + { + new FactionSystem(); + } +} diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/manager.html b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/manager.html new file mode 100644 index 0000000000..2b95871ec8 --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/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_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html new file mode 100644 index 0000000000..0f9fa95cc6 --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/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_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java index 6ae1fb39fb..88f21d65cc 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java @@ -41,6 +41,7 @@ import org.l2jmobius.commons.util.ClassMasterSettings; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.commons.util.StringUtil; import org.l2jmobius.gameserver.enums.GeoType; +import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.olympiad.OlympiadPeriod; import org.l2jmobius.gameserver.util.FloodProtectorConfig; @@ -87,6 +88,7 @@ public class Config public static final String CLASS_DAMAGE_CONFIG_FILE = "./config/custom/ClassDamage.ini"; private static final String CUSTOM_AUTO_POTIONS_CONFIG_FILE = "./config/custom/AutoPotions.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/custom/CustomMailManager.ini"; + private static final String CUSTOM_FACTION_SYSTEM_CONFIG_FILE = "./config/Custom/FactionSystem.ini"; private static final String MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE = "./config/custom/MerchantZeroSellPrice.ini"; private static final String CUSTOM_RANDOM_SPAWNS_CONFIG_FILE = "./config/custom/RandomSpawns.ini"; private static final String OFFLINE_CONFIG_FILE = "./config/custom/Offline.ini"; @@ -466,6 +468,22 @@ public class Config public static boolean CUSTOM_MAIL_MANAGER_ENABLED; public static int CUSTOM_MAIL_MANAGER_DELAY; + public static boolean FACTION_SYSTEM_ENABLED; + public static Location FACTION_STARTING_LOCATION; + 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 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 MERCHANT_ZERO_SELL_PRICE; public static boolean ENABLE_RANDOM_MONSTER_SPAWNS; @@ -1631,6 +1649,32 @@ public class Config CUSTOM_MAIL_MANAGER_DELAY = customMailManagerConfig.getInt("DatabaseQueryDelay", 30) * 1000; } + public static void loadFactionSystemConfig() + { + // Load FactionSystem config file (if exists) + final PropertiesParser factionSystemConfig = new PropertiesParser(CUSTOM_FACTION_SYSTEM_CONFIG_FILE); + String[] tempString; + FACTION_SYSTEM_ENABLED = factionSystemConfig.getBoolean("EnableFactionSystem", false); + tempString = factionSystemConfig.getString("StartingLocation", "85332,16199,-1252").split(","); + FACTION_STARTING_LOCATION = new Location(Integer.parseInt(tempString[0]), Integer.parseInt(tempString[1]), Integer.parseInt(tempString[2])); + tempString = factionSystemConfig.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 = factionSystemConfig.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 = factionSystemConfig.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 = factionSystemConfig.getString("GoodTeamName", "Good"); + FACTION_EVIL_TEAM_NAME = factionSystemConfig.getString("EvilTeamName", "Evil"); + FACTION_GOOD_NAME_COLOR = Integer.decode("0x" + factionSystemConfig.getString("GoodNameColor", "00FF00")); + FACTION_EVIL_NAME_COLOR = Integer.decode("0x" + factionSystemConfig.getString("EvilNameColor", "0000FF")); + FACTION_GUARDS_ENABLED = factionSystemConfig.getBoolean("EnableFactionGuards", true); + FACTION_RESPAWN_AT_BASE = factionSystemConfig.getBoolean("RespawnAtFactionBase", true); + FACTION_AUTO_NOBLESS = factionSystemConfig.getBoolean("FactionAutoNobless", false); + FACTION_SPECIFIC_CHAT = factionSystemConfig.getBoolean("EnableFactionChat", true); + FACTION_BALANCE_ONLINE_PLAYERS = factionSystemConfig.getBoolean("BalanceOnlinePlayers", true); + FACTION_BALANCE_PLAYER_EXCEED_LIMIT = factionSystemConfig.getInt("BalancePlayerExceedLimit", 20); + } + public static void loadMerchantZeroPriceConfig() { final PropertiesParser merchantZeroSellPriceConfig = new PropertiesParser(MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE); @@ -2871,6 +2915,7 @@ public class Config loadChampionConfig(); loadAutoPotionsConfig(); loadCustomMailManagerConfig(); + loadFactionSystemConfig(); loadMerchantZeroPriceConfig(); loadRandomSpawnsConfig(); loadWeddingConfig(); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/ai/AttackableAI.java index e5034dcf6f..24482d8f62 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -89,7 +89,7 @@ public class AttackableAI extends CreatureAI } /** - * Actor is a GuardInstance: + * Actor is a Guard: *
    *
  • The target isn't a Folk or a Door
  • *
  • The target isn't dead, isn't invulnerable, isn't in silent moving mode AND too far (>100)
  • @@ -233,18 +233,15 @@ public class AttackableAI extends CreatureAI } } - // Check if the actor is a GuardInstance + // Check if the actor is a Guard if (_actor instanceof Guard) { - // Check if the Player target has karma (=PK) - if ((target instanceof Player) && (((Player) target).getKarma() > 0)) + if ((target instanceof Playable) && ((target.getActingPlayer().getKarma() > 0) // Check if the Player target has karma (=PK) + || (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((target.getActingPlayer().isGood() && Config.FACTION_EVIL_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId())) || (target.getActingPlayer().isEvil() && Config.FACTION_GOOD_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId())))))) { - // Los Check return GeoEngine.getInstance().canSeeTarget(me, target); } - // if (target instanceof Summon) - // return ((Summon)target).getKarma() > 0; // Check if the Monster target is aggressive if (target instanceof Monster) { @@ -375,7 +372,7 @@ public class AttackableAI extends CreatureAI *
      *
    • Update every 1s the _globalAggro counter to come close to 0
    • *
    • If the actor is Aggressive and can attack, add all autoAttackable Creature in its Aggro Range to its _aggroList, chose a target and order to attack it
    • - *
    • If the actor is a GuardInstance that can't attack, order to it to return to its home location
    • + *
    • If the actor is a Guard that can't attack, order to it to return to its home location
    • *
    • If the actor is a Monster that can't attack, order to it to random walk (1/100)
    • *
    */ @@ -481,10 +478,10 @@ public class AttackableAI extends CreatureAI } } - // Check if the actor is a GuardInstance + // Check if the actor is a Guard if (_actor instanceof Guard) { - // Order to the GuardInstance to return to its home location because there's no target to attack + // Order to the Guard to return to its home location because there's no target to attack ((Guard) _actor).returnHome(); } @@ -1073,7 +1070,7 @@ public class AttackableAI extends CreatureAI * Actions: *
      *
    • Add the target to the actor _aggroList or update hate if already present
    • - *
    • Set the actor Intention to AI_INTENTION_ATTACK (if actor is GuardInstance check if it isn't too far from its home location)
    • + *
    • Set the actor Intention to AI_INTENTION_ATTACK (if actor is Guard check if it isn't too far from its home location)
    • *
    * @param target the Creature that attacks * @param aggro The value of hate to add to the actor against the target diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java index 7c4c8164ba..3db28ea021 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java @@ -24,6 +24,7 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import org.l2jmobius.Config; import org.l2jmobius.commons.util.IXmlReader; import org.l2jmobius.gameserver.data.sql.ClanHallTable; import org.l2jmobius.gameserver.enums.Race; @@ -235,6 +236,18 @@ public class MapRegionData implements IXmlReader return arena.getSpawnLoc(); } + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_RESPAWN_AT_BASE) + { + if (creature.getActingPlayer().isGood()) + { + return Config.FACTION_GOOD_BASE_LOCATION; + } + if (creature.getActingPlayer().isEvil()) + { + return Config.FACTION_EVIL_BASE_LOCATION; + } + } + // Retrieve a random spawn location of the nearest town. return getClosestTown(player).getSpawnLoc(); } diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java index 20b37f347e..9ecb7dd297 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java @@ -142,6 +142,12 @@ public class ScrollOfEscape implements IItemHandler return; } + if (Config.FACTION_SYSTEM_ENABLED && !player.isGood() && !player.isEvil()) + { + player.sendMessage("You cannot use this item while you are neutral."); + return; + } + // Check if this is a blessed scroll, if it is then shorten the cast time. final int itemId = item.getItemId(); final SystemMessage sm3 = new SystemMessage(SystemMessageId.USE_S1); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java index 1b3e54254d..9a3232c46d 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java @@ -82,6 +82,12 @@ public class Escape implements IUserCommandHandler return false; } + if (Config.FACTION_SYSTEM_ENABLED && !player.isGood() && !player.isEvil()) + { + player.sendMessage("You cannot use this function while you are neutral."); + return false; + } + // Check player status. if (player.isCastingNow() || player.isMovementDisabled() || player.isMuted() || player.isAlikeDead() || player.isInOlympiadMode()) { diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/BlockList.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/BlockList.java index 39f01e9b42..ac2d0ec1a5 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/BlockList.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/BlockList.java @@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import org.l2jmobius.Config; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.gameserver.data.sql.CharNameTable; import org.l2jmobius.gameserver.model.actor.Player; @@ -128,6 +129,10 @@ public class BlockList public boolean isInBlockList(Player target) { + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_SPECIFIC_CHAT && ((_owner.isGood() && target.isEvil()) || (_owner.isEvil() && target.isGood()))) + { + return true; + } return _blockList.contains(target.getObjectId()); } diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/World.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/World.java index 34f13ded04..3ff4827232 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/World.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/World.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; +import org.l2jmobius.Config; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.instance.Pet; @@ -64,6 +65,10 @@ public class World /** HashMap(String Player name, Player) containing all the players in game. */ private static 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<>(); /** WorldObjectHashMap(WorldObject) containing all visible objects. */ private static final Map _allObjects = new ConcurrentHashMap<>(); @@ -159,6 +164,28 @@ public class World return _allPlayers.values(); } + public Collection getAllGoodPlayers() + { + return _allGoodPlayers.values(); + } + + public Collection getAllEvilPlayers() + { + return _allEvilPlayers.values(); + } + + public static void addFactionPlayerToWorld(Player player) + { + if (player.isGood()) + { + _allGoodPlayers.put(player.getObjectId(), player); + } + else if (player.isEvil()) + { + _allEvilPlayers.put(player.getObjectId(), player); + } + } + /** * Return how many players are online. * @return number of online players. @@ -323,9 +350,11 @@ public class World return; } - synchronized (_allPlayers) + _allPlayers.put(player.getName().toLowerCase(), player); + + if (Config.FACTION_SYSTEM_ENABLED) { - _allPlayers.put(player.getName().toLowerCase(), player); + addFactionPlayerToWorld(player); } } @@ -373,6 +402,18 @@ public class World if ((player != null) && !player.isTeleporting()) { _allPlayers.remove(player.getName().toLowerCase()); + + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood()) + { + _allGoodPlayers.remove(player.getObjectId()); + } + else if (player.isEvil()) + { + _allEvilPlayers.remove(player.getObjectId()); + } + } } } diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Playable.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Playable.java index 6ad302c9ff..9ae00a7944 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Playable.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Playable.java @@ -16,6 +16,7 @@ */ package org.l2jmobius.gameserver.model.actor; +import org.l2jmobius.Config; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.knownlist.PlayableKnownList; import org.l2jmobius.gameserver.model.actor.stat.PlayableStat; @@ -124,10 +125,12 @@ public abstract class Playable extends Creature { return false; // Target is null } + if (target == this) { return false; // Target is self } + if (!(target instanceof Playable)) { return false; // Target is not a PlayableInstance @@ -147,6 +150,7 @@ public abstract class Playable extends Creature { return false; // Active player is null } + if (player.getKarma() != 0) { return false; // Active player has karma @@ -166,19 +170,27 @@ public abstract class Playable extends Creature { return false; // Target player is null } + if (targetPlayer == this) { return false; // Target player is self } + if (targetPlayer.getKarma() != 0) { return false; // Target player has karma } + if (targetPlayer.getPvpFlag() == 0) { return false; } + if (Config.FACTION_SYSTEM_ENABLED && ((player.isGood() && targetPlayer.isEvil()) || (player.isEvil() && targetPlayer.isGood()))) + { + return false; + } + return true; } diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Player.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Player.java index 8b20ebb22f..bbe2d1963e 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Player.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/Player.java @@ -238,8 +238,8 @@ import org.l2jmobius.gameserver.util.Util; public class Player extends Playable { /** SQL queries */ - private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,str=?,con=?,dex=?,_int=?,men=?,wit=?,face=?,hairStyle=?,hairColor=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,maxload=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_timer=?,newbie=?,nobless=?,power_grade=?,subpledge=?,last_recom_date=?,lvl_joined_academy=?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,pc_point=?,name_color=?,title_color=?,aio=?,aio_end=? WHERE charId=?"; - private static final String RESTORE_CHARACTER = "SELECT account_name, charId, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon,punish_level,punish_timer,newbie, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,pc_point,name_color,title_color,first_log,aio,aio_end FROM characters WHERE charId=?"; + private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,str=?,con=?,dex=?,_int=?,men=?,wit=?,face=?,hairStyle=?,hairColor=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,maxload=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_timer=?,newbie=?,nobless=?,power_grade=?,subpledge=?,faction=?,last_recom_date=?,lvl_joined_academy=?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,pc_point=?,name_color=?,title_color=?,aio=?,aio_end=? WHERE charId=?"; + private static final String RESTORE_CHARACTER = "SELECT account_name, charId, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon,punish_level,punish_timer,newbie, nobless, power_grade, subpledge, faction, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,pc_point,name_color,title_color,first_log,aio,aio_end FROM characters WHERE charId=?"; private static final String RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? ORDER BY (skill_level+0)"; private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE char_obj_id=? ORDER BY class_index ASC"; private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (char_obj_id,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)"; @@ -350,6 +350,8 @@ public class Player extends Playable private boolean _noble = false; private boolean _hero = false; private boolean _donator = false; + private boolean _isGood = false; + private boolean _isEvil = false; private Folk _lastFolkNpc = null; private int _questNpcObject = 0; private int _partyFind = 0; @@ -4629,7 +4631,7 @@ public class Player extends Playable */ public void updatePvPColor(int pvpKillAmount) { - if (Config.PVP_COLOR_SYSTEM_ENABLED) + if (Config.PVP_COLOR_SYSTEM_ENABLED && !Config.FACTION_SYSTEM_ENABLED) // Faction system uses title colors. { // Check if the character has GM access and if so, let them be. if (isGM()) @@ -5835,7 +5837,18 @@ public class Player extends Playable } else if (targetPlayer.getPvpFlag() == 0) // Target player doesn't have karma { - increasePkKillsAndKarma(targetPlayer.getLevel()); + if (Config.FACTION_SYSTEM_ENABLED) + { + if ((_isGood && targetPlayer.isGood()) || (_isEvil && targetPlayer.isEvil())) + { + increasePkKillsAndKarma(targetPlayer.getLevel()); + } + } + else + { + increasePkKillsAndKarma(targetPlayer.getLevel()); + } + if ((target instanceof Player) && Config.ANNOUNCE_PK_KILL) { AnnouncementsTable.getInstance().announceToAll("Player " + getName() + " has assassinated Player " + target.getName()); @@ -6209,6 +6222,11 @@ public class Player extends Playable return; } + if (Config.FACTION_SYSTEM_ENABLED && target.isPlayer() && ((isGood() && targetPlayer.isEvil()) || (isEvil() && targetPlayer.isGood()))) + { + return; + } + if ((!isInsideZone(ZoneId.PVP) || !targetPlayer.isInsideZone(ZoneId.PVP)) && (targetPlayer.getKarma() == 0)) { if (checkIfPvP(targetPlayer)) @@ -7460,6 +7478,17 @@ public class Player extends Playable player.setOnlineTime(rset.getLong("onlinetime")); player.setNewbie(rset.getInt("newbie") == 1); 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")); player.setFirstLog(rset.getInt("first_log")); player._pcBangPoints = rset.getInt("pc_point"); @@ -8017,21 +8046,31 @@ public class Player extends Playable statement.setInt(45, isNoble() ? 1 : 0); statement.setLong(46, getPowerGrade()); statement.setInt(47, getPledgeType()); - statement.setLong(48, getLastRecomUpdate()); - statement.setInt(49, getLvlJoinedAcademy()); - statement.setLong(50, getApprentice()); - statement.setLong(51, getSponsor()); - statement.setInt(52, getAllianceWithVarkaKetra()); - statement.setLong(53, getClanJoinExpiryTime()); - statement.setLong(54, getClanCreateExpiryTime()); - statement.setString(55, getName()); - statement.setLong(56, getDeathPenaltyBuffLevel()); - statement.setInt(57, getPcBangScore()); - statement.setString(58, StringToHex(Integer.toHexString(_originalNameColorOffline).toUpperCase())); - statement.setString(59, StringToHex(Integer.toHexString(getAppearance().getTitleColor()).toUpperCase())); - statement.setInt(60, isAio() ? 1 : 0); - statement.setLong(61, getAioEndTime()); - statement.setInt(62, getObjectId()); + int factionId = 0; + if (_isGood) + { + factionId = 1; + } + if (_isEvil) + { + factionId = 2; + } + statement.setInt(48, factionId); + statement.setLong(49, getLastRecomUpdate()); + statement.setInt(50, getLvlJoinedAcademy()); + statement.setLong(51, getApprentice()); + statement.setLong(52, getSponsor()); + statement.setInt(53, getAllianceWithVarkaKetra()); + statement.setLong(54, getClanJoinExpiryTime()); + statement.setLong(55, getClanCreateExpiryTime()); + statement.setString(56, getName()); + statement.setLong(57, getDeathPenaltyBuffLevel()); + statement.setInt(58, getPcBangScore()); + statement.setString(59, StringToHex(Integer.toHexString(_originalNameColorOffline).toUpperCase())); + statement.setString(60, StringToHex(Integer.toHexString(getAppearance().getTitleColor()).toUpperCase())); + statement.setInt(61, isAio() ? 1 : 0); + statement.setLong(62, getAioEndTime()); + statement.setInt(63, getObjectId()); statement.execute(); statement.close(); } @@ -9056,6 +9095,15 @@ public class Player extends Playable return true; } } + + if (Config.FACTION_SYSTEM_ENABLED) + { + final Player player = attacker.getActingPlayer(); + if ((player != null) && ((isGood() && player.isEvil()) || (isEvil() && player.isGood()))) + { + return true; + } + } } else if (attacker instanceof SiegeGuard) { @@ -9073,6 +9121,13 @@ public class Player extends Playable return (fortsiege != null) && fortsiege.checkIsAttacker(getClan()); } } + else if (attacker instanceof Guard) + { + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((_isGood && Config.FACTION_EVIL_TEAM_NAME.equals(((Npc) attacker).getTemplate().getFactionId())) || (_isEvil && Config.FACTION_GOOD_TEAM_NAME.equals(((Npc) attacker).getTemplate().getFactionId())))) + { + return true; + } + } return false; } @@ -9644,12 +9699,15 @@ public class Player extends Playable if (!checkPvpSkill(target, skill) && !getAccessLevel().allowPeaceAttack() // && ((skill.getId() != 3260 /* Forgiveness */) && (skill.getId() != 3261 /* Heart Shot */) && (skill.getId() != 3262 /* Double Heart Shot */))) { - // Send a System Message to the Player - sendPacket(SystemMessageId.THAT_IS_THE_INCORRECT_TARGET); - - // Send a Server->Client packet ActionFailed to the Player - sendPacket(ActionFailed.STATIC_PACKET); - return; + if (!Config.FACTION_SYSTEM_ENABLED || ((!_isGood || !target.getActingPlayer().isEvil()) && (!_isEvil || !target.getActingPlayer().isGood()))) + { + // Send a System Message to the Player + sendPacket(SystemMessageId.THAT_IS_THE_INCORRECT_TARGET); + + // Send a Server->Client packet ActionFailed to the Player + sendPacket(ActionFailed.STATIC_PACKET); + return; + } } } } @@ -10827,6 +10885,28 @@ public class Player extends Playable return _donator; } + public boolean isGood() + { + return _isGood; + } + + public boolean isEvil() + { + return _isEvil; + } + + public void setGood() + { + _isGood = true; + _isEvil = false; + } + + public void setEvil() + { + _isGood = false; + _isEvil = true; + } + /** * Sets the checks if is in olympiad mode. * @param value the new checks if is in olympiad mode @@ -15129,12 +15209,6 @@ public class Player extends Playable } } - @Override - public Player getActingPlayer() - { - return this; - } - public void checkItemRestriction() { for (int i = 0; i < Inventory.PAPERDOLL_TOTALSLOTS; i++) @@ -15296,6 +15370,12 @@ public class Player extends Playable _currentPetSkill = new SkillUseHolder(currentSkill, ctrlPressed, shiftPressed); } + @Override + public Player getActingPlayer() + { + return this; + } + @Override public boolean isPlayer() { diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java index 9629cd5260..75a6bd5ad5 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java @@ -217,8 +217,7 @@ public class Guard extends Attackable // Set the Player Intention to AI_INTENTION_ATTACK player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this); } - else // Calculate the distance between the Player and the Npc - if (!canInteract(player)) + else if (!canInteract(player)) // Calculate the distance between the Player and the Npc { // Set the Player Intention to AI_INTENTION_INTERACT player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java index 97a596a776..e6c0929baf 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java @@ -21,6 +21,8 @@ import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.instance.Guard; import org.l2jmobius.gameserver.model.actor.instance.Monster; @@ -50,19 +52,21 @@ public class GuardKnownList extends AttackableKnownList return false; } - // Set home location of the GuardInstance (if not already done) + // Set home location of the Guard (if not already done) if (getActiveChar().getHomeX() == 0) { getActiveChar().getHomeLocation(); } - if (object instanceof Player) + if (object instanceof Playable) { - // Check if the object added is a Player that owns Karma - final Player player = (Player) object; + // Check if the object added is a Player that owns Karma. + final Player player = object.getActingPlayer(); - // Set the GuardInstance Intention to AI_INTENTION_ACTIVE - if ((player.getKarma() > 0) && (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)) + // Set the Guard Intention to AI_INTENTION_ACTIVE + if (((player.getKarma() > 0) // + || (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((player.isGood() && Config.FACTION_EVIL_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId())) || (player.isEvil() && Config.FACTION_GOOD_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId()))))) // + && (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)) { getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null); } @@ -72,7 +76,7 @@ public class GuardKnownList extends AttackableKnownList // Check if the object added is an aggressive Monster final Monster mob = (Monster) object; - // Set the GuardInstance Intention to AI_INTENTION_ACTIVE + // Set the Guard Intention to AI_INTENTION_ACTIVE if (mob.isAggressive() && (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)) { getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null); @@ -90,10 +94,10 @@ public class GuardKnownList extends AttackableKnownList return false; } - // Check if the _aggroList of the GuardInstance is Empty + // Check if the _aggroList of the Guard is Empty if (getActiveChar().noTarget()) { - // Set the GuardInstance to AI_INTENTION_IDLE + // Set the Guard to AI_INTENTION_IDLE final CreatureAI ai = getActiveChar().getAI(); if (ai != null) { diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/clan/Clan.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/clan/Clan.java index 91decdcdcc..f750a5447c 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/clan/Clan.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/clan/Clan.java @@ -1780,6 +1780,20 @@ public class Clan return false; } + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood() && target.isEvil()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + if (player.isEvil() && target.isGood()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + } + if (_charPenaltyExpiryTime > Chronos.currentTimeMillis()) { final SystemMessage sm = new SystemMessage(SystemMessageId.AFTER_A_CLAN_MEMBER_IS_DISMISSED_FROM_A_CLAN_THE_CLAN_MUST_WAIT_AT_LEAST_A_DAY_BEFORE_ACCEPTING_A_NEW_MEMBER); @@ -1869,6 +1883,20 @@ public class Clan return false; } + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood() && target.isEvil()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + if (player.isEvil() && target.isGood()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + } + if (target.getClan() == null) { player.sendPacket(SystemMessageId.THE_TARGET_MUST_BE_A_CLAN_MEMBER); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java index 989f4833b0..e462cd0e58 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java @@ -231,6 +231,10 @@ public class CharacterCreate implements IClientIncomingPacket { newChar.setXYZInvisible(Config.SPAWN_X, Config.SPAWN_Y, Config.SPAWN_Z); } + else if (Config.FACTION_SYSTEM_ENABLED) + { + newChar.setXYZInvisible(Config.FACTION_STARTING_LOCATION.getX(), Config.FACTION_STARTING_LOCATION.getY(), Config.FACTION_STARTING_LOCATION.getZ()); + } else { newChar.setXYZInvisible(template.getSpawnX(), template.getSpawnY(), template.getSpawnZ()); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java index ffe922f908..681833b6f4 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java @@ -16,13 +16,16 @@ */ package org.l2jmobius.gameserver.network.clientpackets; +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; +import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.PacketLogger; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.CharSelected; +import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; @SuppressWarnings("unused") public class CharacterSelected implements IClientIncomingPacket @@ -79,6 +82,28 @@ public class CharacterSelected implements IClientIncomingPacket return; } + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_BALANCE_ONLINE_PLAYERS) + { + if (cha.isGood() && (World.getInstance().getAllGoodPlayers().size() >= (World.getInstance().getAllEvilPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + final NpcHtmlMessage msg = new NpcHtmlMessage(0); + msg.setFile("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 (cha.isEvil() && (World.getInstance().getAllEvilPlayers().size() >= (World.getInstance().getAllGoodPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + final NpcHtmlMessage msg = new NpcHtmlMessage(0); + msg.setFile("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; + } + } + cha.setClient(client); client.setPlayer(cha); client.setConnectionState(ConnectionState.ENTERING); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java index afd1da5336..071de2d01a 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java @@ -261,6 +261,27 @@ public class EnterWorld implements IClientIncomingPacket player.sendPacket(new CreatureSay(0, ChatType.WHISPER, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); } + // Faction System + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood()) + { + player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR); + player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR); + player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction."); + player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.", 10000)); + player.broadcastUserInfo(); // for seeing self name color + } + else if (player.isEvil()) + { + player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR); + player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR); + player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction."); + player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.", 10000)); + player.broadcastUserInfo(); // for seeing self name color + } + } + loadTutorial(player); // Check for crowns diff --git a/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/characters.sql b/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/characters.sql index 9a357de631..34817f15e2 100644 --- a/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/characters.sql +++ b/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/characters.sql @@ -71,6 +71,7 @@ CREATE TABLE IF NOT EXISTS characters ( power_grade decimal(11,0) DEFAULT NULL, nobless decimal(1,0) NOT NULL DEFAULT 0, subpledge int(1) NOT NULL DEFAULT 0, + faction int(1) NOT NULL DEFAULT 0, last_recom_date decimal(20,0) NOT NULL DEFAULT 0, lvl_joined_academy int(1) NOT NULL DEFAULT 0, apprentice int(1) NOT NULL DEFAULT 0, diff --git a/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/custom_npc.sql b/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/custom_npc.sql index 54a354432b..2efad91993 100644 --- a/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/custom_npc.sql +++ b/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/custom_npc.sql @@ -49,6 +49,9 @@ CREATE TABLE `custom_npc`( ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; INSERT ignore INTO custom_npc values +('500', '30115', 'Jurek', '1', 'Faction Manager', '1', 'NPC.a_mageguild_master_MHuman', '8.00', '24.00', '70', 'male', 'Folk', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '0', '0', '1314', '470', '780', '382', '278', '0', '333', '0', '0', '0', '55', '132', null, '0', '1', '0', 'LAST_HIT'), +('501', '31033', 'Sentinel', '1', ' ', '1', 'NPC.a_guard_MElf', '8.00', '23.50', '80', 'male', 'Guard', '1100', '4551', '1859', '13.43', '3.09', '40', '43', '30', '21', '20', '10', '0', '0', '4031', '576', '1144', '468', '249', '1000', '333', '276', '0', '0', '55', '176', 'Good', '500', '1', '0', 'LAST_HIT'), +('502', '31036', 'Centurion', '1', ' ', '1', 'NPC.e_guard_MOrc', '8.00', '27.00', '80', 'male', 'Guard', '1100', '4551', '1859', '13.43', '3.09', '40', '43', '30', '21', '20', '10', '0', '0', '4031', '576', '1144', '468', '249', '1000', '333', '273', '0', '0', '55', '176', 'Evil', '500', '1', '0', 'LAST_HIT'), ('31288', '31228', 'Roy the Cat', '1', 'Class Master', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'ClassMaster', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), ('50000', '31228', 'Dom the Cat', '1', 'Merchant', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'Merchant', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', null, '0', '0', '0', 'LAST_HIT'), ('50007', '31324', 'Andromeda', '1', 'Wedding Manager', '1', 'NPC.a_casino_FDarkElf', '8.00', '23.00', '70', 'female', 'WeddingManager', '40', '3862', '1493', '500', '500', '40', '43', '30', '21', '20', '10', '0', '0', '9999', '9999', '999', '999', '278', '0', '333', '316', '0', '0', '55', '132', null, '0', '1', '0', 'LAST_HIT'), diff --git a/L2J_Mobius_C6_Interlude/dist/game/config/custom/FactionSystem.ini b/L2J_Mobius_C6_Interlude/dist/game/config/custom/FactionSystem.ini new file mode 100644 index 0000000000..ca1de8904b --- /dev/null +++ b/L2J_Mobius_C6_Interlude/dist/game/config/custom/FactionSystem.ini @@ -0,0 +1,64 @@ +# --------------------------------------------------------------------------- +# Faction System (Good vs Evil) +# --------------------------------------------------------------------------- + +# Enable faction system. +# Default: False +EnableFactionSystem = False + +# Starting location for all players. +# Default: 85332,16199,-1252 +StartingLocation = 85332,16199,-1252 + +# 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 + +# 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_C6_Interlude/dist/game/data/html/guard/501.htm b/L2J_Mobius_C6_Interlude/dist/game/data/html/guard/501.htm new file mode 100644 index 0000000000..ae4b343c3e --- /dev/null +++ b/L2J_Mobius_C6_Interlude/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_C6_Interlude/dist/game/data/html/guard/502.htm b/L2J_Mobius_C6_Interlude/dist/game/data/html/guard/502.htm new file mode 100644 index 0000000000..8910ad01a0 --- /dev/null +++ b/L2J_Mobius_C6_Interlude/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_C6_Interlude/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm b/L2J_Mobius_C6_Interlude/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm new file mode 100644 index 0000000000..858aa73517 --- /dev/null +++ b/L2J_Mobius_C6_Interlude/dist/game/data/html/mods/Faction/ExceededOnlineLimit.htm @@ -0,0 +1,3 @@ +RestrictionIt seems that there are currently more %more% than %less% players online.
    +Try selecting an opposing faction character or wait for some %more% players to logout. + \ No newline at end of file diff --git a/L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java b/L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java new file mode 100644 index 0000000000..c4aee45fef --- /dev/null +++ b/L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/FactionSystem.java @@ -0,0 +1,164 @@ +/* + * 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 org.l2jmobius.Config; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.Player; +import org.l2jmobius.gameserver.model.quest.Quest; +import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; + +/** + * @author Mobius + */ +public class FactionSystem extends Quest +{ + // NPC + private static final int MANAGER = 500; + // 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() + { + super(-1, "custom"); + + addSpawnId(MANAGER); + addStartNpc(MANAGER); + addTalkId(MANAGER); + addFirstTalkId(MANAGER); + + if (Config.FACTION_SYSTEM_ENABLED) + { + addSpawn(MANAGER, Config.FACTION_MANAGER_LOCATION, false, 0); + } + } + + @Override + public String onAdvEvent(String event, Npc npc, Player player) + { + switch (event) + { + case "selectGoodFaction": + { + if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (World.getInstance().getAllGoodPlayers().size() >= (World.getInstance().getAllEvilPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + String htmltext = getHtmlText("onlinelimit.html"); + htmltext = htmltext.replace("%name%", player.getName()); + htmltext = htmltext.replace("%more%", Config.FACTION_GOOD_TEAM_NAME); + htmltext = htmltext.replace("%less%", Config.FACTION_EVIL_TEAM_NAME); + 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, true); + broadcastMessageToFaction(Config.FACTION_GOOD_TEAM_NAME, Config.FACTION_GOOD_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + "."); + World.addFactionPlayerToWorld(player); + break; + } + case "selectEvilFaction": + { + if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (World.getInstance().getAllEvilPlayers().size() >= (World.getInstance().getAllGoodPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + String htmltext = getHtmlText("onlinelimit.html"); + htmltext = htmltext.replace("%name%", player.getName()); + htmltext = htmltext.replace("%more%", Config.FACTION_EVIL_TEAM_NAME); + htmltext = htmltext.replace("%less%", Config.FACTION_GOOD_TEAM_NAME); + 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, true); + broadcastMessageToFaction(Config.FACTION_EVIL_TEAM_NAME, Config.FACTION_EVIL_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + "."); + World.addFactionPlayerToWorld(player); + break; + } + case "SPEAK": + { + if (npc != null) + { + npc.broadcastPacket(new CreatureSay(npc.getObjectId(), ChatType.GENERAL, npc.getName(), getRandomEntry(TEXTS))); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onFirstTalk(Npc npc, Player player) + { + String htmltext = getHtmlText("manager.html"); + htmltext = htmltext.replace("%name%", player.getName()); + htmltext = htmltext.replace("%good%", Config.FACTION_GOOD_TEAM_NAME); + htmltext = htmltext.replace("%evil%", Config.FACTION_EVIL_TEAM_NAME); + return htmltext; + } + + @Override + public String onSpawn(Npc npc) + { + if (npc.getNpcId() == 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 (Player player : World.getInstance().getAllGoodPlayers()) + { + player.sendMessage(message); + } + } + else + { + for (Player player : World.getInstance().getAllEvilPlayers()) + { + player.sendMessage(message); + } + } + } + + public static void main(String[] args) + { + new FactionSystem(); + } +} diff --git a/L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/manager.html b/L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/manager.html new file mode 100644 index 0000000000..2b95871ec8 --- /dev/null +++ b/L2J_Mobius_C6_Interlude/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_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html b/L2J_Mobius_C6_Interlude/dist/game/data/scripts/custom/FactionSystem/onlinelimit.html new file mode 100644 index 0000000000..0f9fa95cc6 --- /dev/null +++ b/L2J_Mobius_C6_Interlude/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_C6_Interlude/java/org/l2jmobius/Config.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java index 1f15e1960a..237bcea611 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java @@ -55,6 +55,7 @@ import org.l2jmobius.commons.util.IXmlReader; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.commons.util.StringUtil; import org.l2jmobius.gameserver.enums.GeoType; +import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.olympiad.OlympiadPeriod; import org.l2jmobius.gameserver.util.FloodProtectorConfig; @@ -102,6 +103,7 @@ public class Config public static final String CLASS_DAMAGE_CONFIG_FILE = "./config/custom/ClassDamage.ini"; private static final String CUSTOM_AUTO_POTIONS_CONFIG_FILE = "./config/custom/AutoPotions.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/custom/CustomMailManager.ini"; + private static final String CUSTOM_FACTION_SYSTEM_CONFIG_FILE = "./config/Custom/FactionSystem.ini"; private static final String MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE = "./config/custom/MerchantZeroSellPrice.ini"; private static final String CUSTOM_RANDOM_SPAWNS_CONFIG_FILE = "./config/custom/RandomSpawns.ini"; private static final String OFFLINE_CONFIG_FILE = "./config/custom/Offline.ini"; @@ -494,6 +496,22 @@ public class Config public static boolean CUSTOM_MAIL_MANAGER_ENABLED; public static int CUSTOM_MAIL_MANAGER_DELAY; + public static boolean FACTION_SYSTEM_ENABLED; + public static Location FACTION_STARTING_LOCATION; + 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 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 MERCHANT_ZERO_SELL_PRICE; public static boolean ENABLE_RANDOM_MONSTER_SPAWNS; @@ -1684,6 +1702,32 @@ public class Config CUSTOM_MAIL_MANAGER_DELAY = customMailManagerConfig.getInt("DatabaseQueryDelay", 30) * 1000; } + public static void loadFactionSystemConfig() + { + // Load FactionSystem config file (if exists) + final PropertiesParser factionSystemConfig = new PropertiesParser(CUSTOM_FACTION_SYSTEM_CONFIG_FILE); + String[] tempString; + FACTION_SYSTEM_ENABLED = factionSystemConfig.getBoolean("EnableFactionSystem", false); + tempString = factionSystemConfig.getString("StartingLocation", "85332,16199,-1252").split(","); + FACTION_STARTING_LOCATION = new Location(Integer.parseInt(tempString[0]), Integer.parseInt(tempString[1]), Integer.parseInt(tempString[2])); + tempString = factionSystemConfig.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 = factionSystemConfig.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 = factionSystemConfig.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 = factionSystemConfig.getString("GoodTeamName", "Good"); + FACTION_EVIL_TEAM_NAME = factionSystemConfig.getString("EvilTeamName", "Evil"); + FACTION_GOOD_NAME_COLOR = Integer.decode("0x" + factionSystemConfig.getString("GoodNameColor", "00FF00")); + FACTION_EVIL_NAME_COLOR = Integer.decode("0x" + factionSystemConfig.getString("EvilNameColor", "0000FF")); + FACTION_GUARDS_ENABLED = factionSystemConfig.getBoolean("EnableFactionGuards", true); + FACTION_RESPAWN_AT_BASE = factionSystemConfig.getBoolean("RespawnAtFactionBase", true); + FACTION_AUTO_NOBLESS = factionSystemConfig.getBoolean("FactionAutoNobless", false); + FACTION_SPECIFIC_CHAT = factionSystemConfig.getBoolean("EnableFactionChat", true); + FACTION_BALANCE_ONLINE_PLAYERS = factionSystemConfig.getBoolean("BalanceOnlinePlayers", true); + FACTION_BALANCE_PLAYER_EXCEED_LIMIT = factionSystemConfig.getInt("BalancePlayerExceedLimit", 20); + } + public static void loadMerchantZeroPriceConfig() { final PropertiesParser merchantZeroSellPriceConfig = new PropertiesParser(MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE); @@ -2941,6 +2985,7 @@ public class Config loadChampionConfig(); loadAutoPotionsConfig(); loadCustomMailManagerConfig(); + loadFactionSystemConfig(); loadMerchantZeroPriceConfig(); loadRandomSpawnsConfig(); loadWeddingConfig(); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java index e5034dcf6f..24482d8f62 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -89,7 +89,7 @@ public class AttackableAI extends CreatureAI } /** - * Actor is a GuardInstance: + * Actor is a Guard: *
      *
    • The target isn't a Folk or a Door
    • *
    • The target isn't dead, isn't invulnerable, isn't in silent moving mode AND too far (>100)
    • @@ -233,18 +233,15 @@ public class AttackableAI extends CreatureAI } } - // Check if the actor is a GuardInstance + // Check if the actor is a Guard if (_actor instanceof Guard) { - // Check if the Player target has karma (=PK) - if ((target instanceof Player) && (((Player) target).getKarma() > 0)) + if ((target instanceof Playable) && ((target.getActingPlayer().getKarma() > 0) // Check if the Player target has karma (=PK) + || (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((target.getActingPlayer().isGood() && Config.FACTION_EVIL_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId())) || (target.getActingPlayer().isEvil() && Config.FACTION_GOOD_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId())))))) { - // Los Check return GeoEngine.getInstance().canSeeTarget(me, target); } - // if (target instanceof Summon) - // return ((Summon)target).getKarma() > 0; // Check if the Monster target is aggressive if (target instanceof Monster) { @@ -375,7 +372,7 @@ public class AttackableAI extends CreatureAI *
        *
      • Update every 1s the _globalAggro counter to come close to 0
      • *
      • If the actor is Aggressive and can attack, add all autoAttackable Creature in its Aggro Range to its _aggroList, chose a target and order to attack it
      • - *
      • If the actor is a GuardInstance that can't attack, order to it to return to its home location
      • + *
      • If the actor is a Guard that can't attack, order to it to return to its home location
      • *
      • If the actor is a Monster that can't attack, order to it to random walk (1/100)
      • *
      */ @@ -481,10 +478,10 @@ public class AttackableAI extends CreatureAI } } - // Check if the actor is a GuardInstance + // Check if the actor is a Guard if (_actor instanceof Guard) { - // Order to the GuardInstance to return to its home location because there's no target to attack + // Order to the Guard to return to its home location because there's no target to attack ((Guard) _actor).returnHome(); } @@ -1073,7 +1070,7 @@ public class AttackableAI extends CreatureAI * Actions: *
        *
      • Add the target to the actor _aggroList or update hate if already present
      • - *
      • Set the actor Intention to AI_INTENTION_ATTACK (if actor is GuardInstance check if it isn't too far from its home location)
      • + *
      • Set the actor Intention to AI_INTENTION_ATTACK (if actor is Guard check if it isn't too far from its home location)
      • *
      * @param target the Creature that attacks * @param aggro The value of hate to add to the actor against the target diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java index 7c4c8164ba..3db28ea021 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/MapRegionData.java @@ -24,6 +24,7 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import org.l2jmobius.Config; import org.l2jmobius.commons.util.IXmlReader; import org.l2jmobius.gameserver.data.sql.ClanHallTable; import org.l2jmobius.gameserver.enums.Race; @@ -235,6 +236,18 @@ public class MapRegionData implements IXmlReader return arena.getSpawnLoc(); } + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_RESPAWN_AT_BASE) + { + if (creature.getActingPlayer().isGood()) + { + return Config.FACTION_GOOD_BASE_LOCATION; + } + if (creature.getActingPlayer().isEvil()) + { + return Config.FACTION_EVIL_BASE_LOCATION; + } + } + // Retrieve a random spawn location of the nearest town. return getClosestTown(player).getSpawnLoc(); } diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java index 98745055d1..de3e74fd54 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/itemhandlers/ScrollOfEscape.java @@ -143,6 +143,12 @@ public class ScrollOfEscape implements IItemHandler return; } + if (Config.FACTION_SYSTEM_ENABLED && !player.isGood() && !player.isEvil()) + { + player.sendMessage("You cannot use this item while you are neutral."); + return; + } + // Check if this is a blessed scroll, if it is then shorten the cast time. final int itemId = item.getItemId(); final SystemMessage sm3 = new SystemMessage(SystemMessageId.USE_S1); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java index 1b3e54254d..9a3232c46d 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/usercommandhandlers/Escape.java @@ -82,6 +82,12 @@ public class Escape implements IUserCommandHandler return false; } + if (Config.FACTION_SYSTEM_ENABLED && !player.isGood() && !player.isEvil()) + { + player.sendMessage("You cannot use this function while you are neutral."); + return false; + } + // Check player status. if (player.isCastingNow() || player.isMovementDisabled() || player.isMuted() || player.isAlikeDead() || player.isInOlympiadMode()) { diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/BlockList.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/BlockList.java index 39f01e9b42..ac2d0ec1a5 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/BlockList.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/BlockList.java @@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import org.l2jmobius.Config; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.gameserver.data.sql.CharNameTable; import org.l2jmobius.gameserver.model.actor.Player; @@ -128,6 +129,10 @@ public class BlockList public boolean isInBlockList(Player target) { + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_SPECIFIC_CHAT && ((_owner.isGood() && target.isEvil()) || (_owner.isEvil() && target.isGood()))) + { + return true; + } return _blockList.contains(target.getObjectId()); } diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/World.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/World.java index 34f13ded04..3ff4827232 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/World.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/World.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; +import org.l2jmobius.Config; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.instance.Pet; @@ -64,6 +65,10 @@ public class World /** HashMap(String Player name, Player) containing all the players in game. */ private static 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<>(); /** WorldObjectHashMap(WorldObject) containing all visible objects. */ private static final Map _allObjects = new ConcurrentHashMap<>(); @@ -159,6 +164,28 @@ public class World return _allPlayers.values(); } + public Collection getAllGoodPlayers() + { + return _allGoodPlayers.values(); + } + + public Collection getAllEvilPlayers() + { + return _allEvilPlayers.values(); + } + + public static void addFactionPlayerToWorld(Player player) + { + if (player.isGood()) + { + _allGoodPlayers.put(player.getObjectId(), player); + } + else if (player.isEvil()) + { + _allEvilPlayers.put(player.getObjectId(), player); + } + } + /** * Return how many players are online. * @return number of online players. @@ -323,9 +350,11 @@ public class World return; } - synchronized (_allPlayers) + _allPlayers.put(player.getName().toLowerCase(), player); + + if (Config.FACTION_SYSTEM_ENABLED) { - _allPlayers.put(player.getName().toLowerCase(), player); + addFactionPlayerToWorld(player); } } @@ -373,6 +402,18 @@ public class World if ((player != null) && !player.isTeleporting()) { _allPlayers.remove(player.getName().toLowerCase()); + + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood()) + { + _allGoodPlayers.remove(player.getObjectId()); + } + else if (player.isEvil()) + { + _allEvilPlayers.remove(player.getObjectId()); + } + } } } diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Playable.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Playable.java index 6ad302c9ff..9ae00a7944 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Playable.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Playable.java @@ -16,6 +16,7 @@ */ package org.l2jmobius.gameserver.model.actor; +import org.l2jmobius.Config; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.knownlist.PlayableKnownList; import org.l2jmobius.gameserver.model.actor.stat.PlayableStat; @@ -124,10 +125,12 @@ public abstract class Playable extends Creature { return false; // Target is null } + if (target == this) { return false; // Target is self } + if (!(target instanceof Playable)) { return false; // Target is not a PlayableInstance @@ -147,6 +150,7 @@ public abstract class Playable extends Creature { return false; // Active player is null } + if (player.getKarma() != 0) { return false; // Active player has karma @@ -166,19 +170,27 @@ public abstract class Playable extends Creature { return false; // Target player is null } + if (targetPlayer == this) { return false; // Target player is self } + if (targetPlayer.getKarma() != 0) { return false; // Target player has karma } + if (targetPlayer.getPvpFlag() == 0) { return false; } + if (Config.FACTION_SYSTEM_ENABLED && ((player.isGood() && targetPlayer.isEvil()) || (player.isEvil() && targetPlayer.isGood()))) + { + return false; + } + return true; } diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Player.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Player.java index 80d6b7611b..e5bd4956a9 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Player.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/Player.java @@ -246,8 +246,8 @@ import org.l2jmobius.gameserver.util.Util; public class Player extends Playable { /** SQL queries */ - private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,str=?,con=?,dex=?,_int=?,men=?,wit=?,face=?,hairStyle=?,hairColor=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,maxload=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_timer=?,newbie=?,nobless=?,power_grade=?,subpledge=?,last_recom_date=?,lvl_joined_academy=?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,pc_point=?,name_color=?,title_color=?,aio=?,aio_end=? WHERE charId=?"; - private static final String RESTORE_CHARACTER = "SELECT account_name, charId, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon,punish_level,punish_timer,newbie, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,pc_point,name_color,title_color,first_log,aio,aio_end FROM characters WHERE charId=?"; + private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,str=?,con=?,dex=?,_int=?,men=?,wit=?,face=?,hairStyle=?,hairColor=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,maxload=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_timer=?,newbie=?,nobless=?,power_grade=?,subpledge=?,faction=?,last_recom_date=?,lvl_joined_academy=?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,pc_point=?,name_color=?,title_color=?,aio=?,aio_end=? WHERE charId=?"; + private static final String RESTORE_CHARACTER = "SELECT account_name, charId, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon,punish_level,punish_timer,newbie, nobless, power_grade, subpledge, faction, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,pc_point,name_color,title_color,first_log,aio,aio_end FROM characters WHERE charId=?"; private static final String RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? ORDER BY (skill_level+0)"; private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE char_obj_id=? ORDER BY class_index ASC"; private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (char_obj_id,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)"; @@ -363,6 +363,8 @@ public class Player extends Playable private boolean _noble = false; private boolean _hero = false; private boolean _donator = false; + private boolean _isGood = false; + private boolean _isEvil = false; private Folk _lastFolkNpc = null; private int _questNpcObject = 0; private int _partyFind = 0; @@ -4728,7 +4730,7 @@ public class Player extends Playable */ public void updatePvPColor(int pvpKillAmount) { - if (Config.PVP_COLOR_SYSTEM_ENABLED) + if (Config.PVP_COLOR_SYSTEM_ENABLED && !Config.FACTION_SYSTEM_ENABLED) // Faction system uses title colors. { // Check if the character has GM access and if so, let them be. if (isGM()) @@ -5974,7 +5976,18 @@ public class Player extends Playable } else if (targetPlayer.getPvpFlag() == 0) // Target player doesn't have karma { - increasePkKillsAndKarma(targetPlayer.getLevel()); + if (Config.FACTION_SYSTEM_ENABLED) + { + if ((_isGood && targetPlayer.isGood()) || (_isEvil && targetPlayer.isEvil())) + { + increasePkKillsAndKarma(targetPlayer.getLevel()); + } + } + else + { + increasePkKillsAndKarma(targetPlayer.getLevel()); + } + if ((target instanceof Player) && Config.ANNOUNCE_PK_KILL) { AnnouncementsTable.getInstance().announceToAll("Player " + getName() + " has assassinated Player " + target.getName()); @@ -6348,6 +6361,11 @@ public class Player extends Playable return; } + if (Config.FACTION_SYSTEM_ENABLED && target.isPlayer() && ((isGood() && targetPlayer.isEvil()) || (isEvil() && targetPlayer.isGood()))) + { + return; + } + if ((!isInsideZone(ZoneId.PVP) || !targetPlayer.isInsideZone(ZoneId.PVP)) && (targetPlayer.getKarma() == 0)) { if (checkIfPvP(targetPlayer)) @@ -7611,6 +7629,17 @@ public class Player extends Playable player.setOnlineTime(rset.getLong("onlinetime")); player.setNewbie(rset.getInt("newbie") == 1); 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")); player.setFirstLog(rset.getInt("first_log")); player._pcBangPoints = rset.getInt("pc_point"); @@ -8170,21 +8199,31 @@ public class Player extends Playable statement.setInt(45, isNoble() ? 1 : 0); statement.setLong(46, getPowerGrade()); statement.setInt(47, getPledgeType()); - statement.setLong(48, getLastRecomUpdate()); - statement.setInt(49, getLvlJoinedAcademy()); - statement.setLong(50, getApprentice()); - statement.setLong(51, getSponsor()); - statement.setInt(52, getAllianceWithVarkaKetra()); - statement.setLong(53, getClanJoinExpiryTime()); - statement.setLong(54, getClanCreateExpiryTime()); - statement.setString(55, getName()); - statement.setLong(56, getDeathPenaltyBuffLevel()); - statement.setInt(57, getPcBangScore()); - statement.setString(58, StringToHex(Integer.toHexString(_originalNameColorOffline).toUpperCase())); - statement.setString(59, StringToHex(Integer.toHexString(getAppearance().getTitleColor()).toUpperCase())); - statement.setInt(60, isAio() ? 1 : 0); - statement.setLong(61, getAioEndTime()); - statement.setInt(62, getObjectId()); + int factionId = 0; + if (_isGood) + { + factionId = 1; + } + if (_isEvil) + { + factionId = 2; + } + statement.setInt(48, factionId); + statement.setLong(49, getLastRecomUpdate()); + statement.setInt(50, getLvlJoinedAcademy()); + statement.setLong(51, getApprentice()); + statement.setLong(52, getSponsor()); + statement.setInt(53, getAllianceWithVarkaKetra()); + statement.setLong(54, getClanJoinExpiryTime()); + statement.setLong(55, getClanCreateExpiryTime()); + statement.setString(56, getName()); + statement.setLong(57, getDeathPenaltyBuffLevel()); + statement.setInt(58, getPcBangScore()); + statement.setString(59, StringToHex(Integer.toHexString(_originalNameColorOffline).toUpperCase())); + statement.setString(60, StringToHex(Integer.toHexString(getAppearance().getTitleColor()).toUpperCase())); + statement.setInt(61, isAio() ? 1 : 0); + statement.setLong(62, getAioEndTime()); + statement.setInt(63, getObjectId()); statement.execute(); statement.close(); } @@ -9174,6 +9213,7 @@ public class Player extends Playable { return true; } + // Check if the Player is in an arena or a siege area if (isInsideZone(ZoneId.PVP) && ((Player) attacker).isInsideZone(ZoneId.PVP)) { @@ -9219,6 +9259,15 @@ public class Player extends Playable return true; } } + + if (Config.FACTION_SYSTEM_ENABLED) + { + final Player player = attacker.getActingPlayer(); + if ((player != null) && ((isGood() && player.isEvil()) || (isEvil() && player.isGood()))) + { + return true; + } + } } else if (attacker instanceof SiegeGuard) { @@ -9236,6 +9285,13 @@ public class Player extends Playable return (fortsiege != null) && fortsiege.checkIsAttacker(getClan()); } } + else if (attacker instanceof Guard) + { + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((_isGood && Config.FACTION_EVIL_TEAM_NAME.equals(((Npc) attacker).getTemplate().getFactionId())) || (_isEvil && Config.FACTION_GOOD_TEAM_NAME.equals(((Npc) attacker).getTemplate().getFactionId())))) + { + return true; + } + } return false; } @@ -9816,12 +9872,15 @@ public class Player extends Playable if (!checkPvpSkill(target, skill) && !getAccessLevel().allowPeaceAttack() // && ((skill.getId() != 3260 /* Forgiveness */) && (skill.getId() != 3261 /* Heart Shot */) && (skill.getId() != 3262 /* Double Heart Shot */))) { - // Send a System Message to the Player - sendPacket(SystemMessageId.THAT_IS_THE_INCORRECT_TARGET); - - // Send a Server->Client packet ActionFailed to the Player - sendPacket(ActionFailed.STATIC_PACKET); - return; + if (!Config.FACTION_SYSTEM_ENABLED || ((!_isGood || !target.getActingPlayer().isEvil()) && (!_isEvil || !target.getActingPlayer().isGood()))) + { + // Send a System Message to the Player + sendPacket(SystemMessageId.THAT_IS_THE_INCORRECT_TARGET); + + // Send a Server->Client packet ActionFailed to the Player + sendPacket(ActionFailed.STATIC_PACKET); + return; + } } } } @@ -11001,6 +11060,28 @@ public class Player extends Playable return _donator; } + public boolean isGood() + { + return _isGood; + } + + public boolean isEvil() + { + return _isEvil; + } + + public void setGood() + { + _isGood = true; + _isEvil = false; + } + + public void setEvil() + { + _isGood = false; + _isEvil = true; + } + /** * Sets the checks if is in olympiad mode. * @param value the new checks if is in olympiad mode @@ -15499,12 +15580,6 @@ public class Player extends Playable } } - @Override - public Player getActingPlayer() - { - return this; - } - public void checkItemRestriction() { for (int i = 0; i < Inventory.PAPERDOLL_TOTALSLOTS; i++) @@ -15670,6 +15745,12 @@ public class Player extends Playable _currentPetSkill = new SkillUseHolder(currentSkill, ctrlPressed, shiftPressed); } + @Override + public Player getActingPlayer() + { + return this; + } + @Override public boolean isPlayer() { diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java index 9629cd5260..75a6bd5ad5 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/Guard.java @@ -217,8 +217,7 @@ public class Guard extends Attackable // Set the Player Intention to AI_INTENTION_ATTACK player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this); } - else // Calculate the distance between the Player and the Npc - if (!canInteract(player)) + else if (!canInteract(player)) // Calculate the distance between the Player and the Npc { // Set the Player Intention to AI_INTENTION_INTERACT player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java index 97a596a776..e6c0929baf 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/knownlist/GuardKnownList.java @@ -21,6 +21,8 @@ import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.instance.Guard; import org.l2jmobius.gameserver.model.actor.instance.Monster; @@ -50,19 +52,21 @@ public class GuardKnownList extends AttackableKnownList return false; } - // Set home location of the GuardInstance (if not already done) + // Set home location of the Guard (if not already done) if (getActiveChar().getHomeX() == 0) { getActiveChar().getHomeLocation(); } - if (object instanceof Player) + if (object instanceof Playable) { - // Check if the object added is a Player that owns Karma - final Player player = (Player) object; + // Check if the object added is a Player that owns Karma. + final Player player = object.getActingPlayer(); - // Set the GuardInstance Intention to AI_INTENTION_ACTIVE - if ((player.getKarma() > 0) && (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)) + // Set the Guard Intention to AI_INTENTION_ACTIVE + if (((player.getKarma() > 0) // + || (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((player.isGood() && Config.FACTION_EVIL_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId())) || (player.isEvil() && Config.FACTION_GOOD_TEAM_NAME.equals(((Npc) getActiveChar()).getTemplate().getFactionId()))))) // + && (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)) { getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null); } @@ -72,7 +76,7 @@ public class GuardKnownList extends AttackableKnownList // Check if the object added is an aggressive Monster final Monster mob = (Monster) object; - // Set the GuardInstance Intention to AI_INTENTION_ACTIVE + // Set the Guard Intention to AI_INTENTION_ACTIVE if (mob.isAggressive() && (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)) { getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null); @@ -90,10 +94,10 @@ public class GuardKnownList extends AttackableKnownList return false; } - // Check if the _aggroList of the GuardInstance is Empty + // Check if the _aggroList of the Guard is Empty if (getActiveChar().noTarget()) { - // Set the GuardInstance to AI_INTENTION_IDLE + // Set the Guard to AI_INTENTION_IDLE final CreatureAI ai = getActiveChar().getAI(); if (ai != null) { diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/clan/Clan.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/clan/Clan.java index 1d24ea2cb5..a5e32f33d2 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/clan/Clan.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/clan/Clan.java @@ -1797,6 +1797,20 @@ public class Clan return false; } + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood() && target.isEvil()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + if (player.isEvil() && target.isGood()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + } + if (_charPenaltyExpiryTime > Chronos.currentTimeMillis()) { final SystemMessage sm = new SystemMessage(SystemMessageId.AFTER_A_CLAN_MEMBER_IS_DISMISSED_FROM_A_CLAN_THE_CLAN_MUST_WAIT_AT_LEAST_A_DAY_BEFORE_ACCEPTING_A_NEW_MEMBER); @@ -1886,6 +1900,20 @@ public class Clan return false; } + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood() && target.isEvil()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + if (player.isEvil() && target.isGood()) + { + player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET)); + return false; + } + } + if (target.getClan() == null) { player.sendPacket(SystemMessageId.THE_TARGET_MUST_BE_A_CLAN_MEMBER); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java index 989f4833b0..e462cd0e58 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterCreate.java @@ -231,6 +231,10 @@ public class CharacterCreate implements IClientIncomingPacket { newChar.setXYZInvisible(Config.SPAWN_X, Config.SPAWN_Y, Config.SPAWN_Z); } + else if (Config.FACTION_SYSTEM_ENABLED) + { + newChar.setXYZInvisible(Config.FACTION_STARTING_LOCATION.getX(), Config.FACTION_STARTING_LOCATION.getY(), Config.FACTION_STARTING_LOCATION.getZ()); + } else { newChar.setXYZInvisible(template.getSpawnX(), template.getSpawnY(), template.getSpawnZ()); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java index ffe922f908..681833b6f4 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/CharacterSelected.java @@ -16,13 +16,16 @@ */ package org.l2jmobius.gameserver.network.clientpackets; +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; +import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.PacketLogger; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.CharSelected; +import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; @SuppressWarnings("unused") public class CharacterSelected implements IClientIncomingPacket @@ -79,6 +82,28 @@ public class CharacterSelected implements IClientIncomingPacket return; } + if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_BALANCE_ONLINE_PLAYERS) + { + if (cha.isGood() && (World.getInstance().getAllGoodPlayers().size() >= (World.getInstance().getAllEvilPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + final NpcHtmlMessage msg = new NpcHtmlMessage(0); + msg.setFile("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 (cha.isEvil() && (World.getInstance().getAllEvilPlayers().size() >= (World.getInstance().getAllGoodPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT))) + { + final NpcHtmlMessage msg = new NpcHtmlMessage(0); + msg.setFile("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; + } + } + cha.setClient(client); client.setPlayer(cha); client.setConnectionState(ConnectionState.ENTERING); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java index 752583ca39..f0b35d9a72 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java @@ -284,6 +284,27 @@ public class EnterWorld implements IClientIncomingPacket player.sendPacket(new CreatureSay(0, ChatType.WHISPER, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); } + // Faction System + if (Config.FACTION_SYSTEM_ENABLED) + { + if (player.isGood()) + { + player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR); + player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR); + player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction."); + player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.", 10000)); + player.broadcastUserInfo(); // for seeing self name color + } + else if (player.isEvil()) + { + player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR); + player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR); + player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction."); + player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.", 10000)); + player.broadcastUserInfo(); // for seeing self name color + } + } + loadTutorial(player); // Check for crowns