From 918b45db8ab9223593bf990bf9bfe902fc51209f Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Tue, 11 Jun 2019 23:22:54 +0000 Subject: [PATCH] Addition of custom class balance configurations. --- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- .../dist/game/config/Custom/ClassBalance.ini | 24 +++ .../java/org/l2jmobius/Config.java | 174 ++++++++++++++++++ .../gameserver/model/stats/Formulas.java | 30 +-- 36 files changed, 2568 insertions(+), 168 deletions(-) create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_2.5_Underground/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_3.0_Helios/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_6.0_Fafurion/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_Classic_2.1_Zaken/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_Classic_2.2_Antharas/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_Classic_2.3_SevenSigns/dist/game/config/Custom/ClassBalance.ini create mode 100644 L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/config/Custom/ClassBalance.ini diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_1.0_Ertheia/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/Config.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/Config.java index 7ed87cb4f8..55a881ef19 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -111,6 +112,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1104,6 +1106,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2493,6 +2507,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/stats/Formulas.java index be282a2c1f..f16bec2608 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_2.5_Underground/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_2.5_Underground/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/Config.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/Config.java index f0943edbd6..56d398cc27 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1111,6 +1113,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2510,6 +2524,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/stats/Formulas.java index be282a2c1f..f16bec2608 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_3.0_Helios/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_3.0_Helios/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/Config.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/Config.java index 28acf144fe..1b15a5754d 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1119,6 +1121,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2525,6 +2539,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/stats/Formulas.java index be282a2c1f..f16bec2608 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_4.0_GrandCrusade/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/Config.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/Config.java index 131c465532..9df6be7833 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1106,6 +1108,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2499,6 +2513,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/stats/Formulas.java index abe8a370d8..db206a9d8e 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_5.0_Salvation/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_5.0_Salvation/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/Config.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/Config.java index d6908bb807..0604c663ce 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -114,6 +115,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1102,6 +1104,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2575,6 +2589,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/stats/Formulas.java index abe8a370d8..db206a9d8e 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_5.5_EtinasFate/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/Config.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/Config.java index d6908bb807..0604c663ce 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -114,6 +115,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1102,6 +1104,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2575,6 +2589,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/stats/Formulas.java index abe8a370d8..db206a9d8e 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_6.0_Fafurion/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/Config.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/Config.java index 4dedaf02a7..1390fd4db3 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -114,6 +115,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1119,6 +1121,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2610,6 +2624,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/stats/Formulas.java index abe8a370d8..db206a9d8e 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_Classic_2.0_Saviors/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/Config.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/Config.java index 3c026be4c2..78b6e9209d 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1048,6 +1050,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2372,6 +2386,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/stats/Formulas.java index 52d3344386..201bcaed11 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_Classic_2.1_Zaken/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/Config.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/Config.java index bcfb106dde..6121dfb44c 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1052,6 +1054,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2379,6 +2393,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/stats/Formulas.java index 52d3344386..201bcaed11 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_Classic_2.2_Antharas/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/Config.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/Config.java index bcfb106dde..6121dfb44c 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1052,6 +1054,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2379,6 +2393,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/stats/Formulas.java index 52d3344386..201bcaed11 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/Config.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/Config.java index bcfb106dde..6121dfb44c 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1052,6 +1054,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2379,6 +2393,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/stats/Formulas.java index 52d3344386..201bcaed11 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; } diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/config/Custom/ClassBalance.ini b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/config/Custom/ClassBalance.ini new file mode 100644 index 0000000000..019dbc8995 --- /dev/null +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/config/Custom/ClassBalance.ini @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Class Balance +# --------------------------------------------------------------------------- + +# Multiply attack and defence based on player class. +# Example: ClassId1,Multiplier1;ClassId2,Multiplier2;... + +PveMagicalSkillDamageMultipiers = +PvpMagicalSkillDamageMultipiers = + +PveMagicalSkillDefenceMultipiers = +PvpMagicalSkillDefenceMultipiers = + +PvePhysicalSkillDamageMultipiers = +PvpPhysicalSkillDamageMultipiers = + +PvePhysicalSkillDefenceMultipiers = +PvpPhysicalSkillDefenceMultipiers = + +PvePhysicalAttackDamageMultipiers = +PvpPhysicalAttackDamageMultipiers = + +PvePhysicalAttackDefenceMultipiers = +PvpPhysicalAttackDefenceMultipiers = diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/Config.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/Config.java index bcfb106dde..6121dfb44c 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/Config.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -112,6 +113,7 @@ public final class Config private static final String CUSTOM_BANKING_CONFIG_FILE = "./config/Custom/Banking.ini"; private static final String CUSTOM_CHAMPION_MONSTERS_CONFIG_FILE = "./config/Custom/ChampionMonsters.ini"; private static final String CUSTOM_CHAT_MODERATION_CONFIG_FILE = "./config/Custom/ChatModeration.ini"; + private static final String CUSTOM_CLASS_BALANCE_CONFIG_FILE = "./config/Custom/ClassBalance.ini"; private static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini"; private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/Custom/CustomMailManager.ini"; private static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini"; @@ -1052,6 +1054,18 @@ public final class Config public static String TITLE_FOR_PVP_AMOUNT4; public static String TITLE_FOR_PVP_AMOUNT5; public static boolean CHAT_ADMIN; + public static Map PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); + public static Map PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS = new ConcurrentHashMap<>(); public static boolean MULTILANG_ENABLE; public static List MULTILANG_ALLOWED = new ArrayList<>(); public static String MULTILANG_DEFAULT; @@ -2379,6 +2393,166 @@ public final class Config CHAT_ADMIN = ChatModeration.getBoolean("ChatAdmin", true); + // Load ClassBalance config file (if exists) + final PropertiesParser ClassBalance = new PropertiesParser(CUSTOM_CLASS_BALANCE_CONFIG_FILE); + + final String[] pveMagicalSkillDamageMultipiers = ClassBalance.getString("PveMagicalSkillDamageMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pveMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pveMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDamageMultipiers = ClassBalance.getString("PvpMagicalSkillDamageMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pveMagicalSkillDefenceMultipiers = ClassBalance.getString("PveMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pveMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pveMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpMagicalSkillDefenceMultipiers = ClassBalance.getString("PvpMagicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpMagicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpMagicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDamageMultipiers = ClassBalance.getString("PvePhysicalSkillDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDamageMultipiers = ClassBalance.getString("PvpPhysicalSkillDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalSkillDefenceMultipiers = ClassBalance.getString("PvePhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalSkillDefenceMultipiers = ClassBalance.getString("PvpPhysicalSkillDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalSkillDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalSkillDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDamageMultipiers = ClassBalance.getString("PvePhysicalAttackDamageMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDamageMultipiers = ClassBalance.getString("PvpPhysicalAttackDamageMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDamageMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDamageMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvePhysicalAttackDefenceMultipiers = ClassBalance.getString("PvePhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvePhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvePhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + final String[] pvpPhysicalAttackDefenceMultipiers = ClassBalance.getString("PvpPhysicalAttackDefenceMultipiers", "").trim().split(";"); + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.clear(); + if (pvpPhysicalAttackDefenceMultipiers.length > 0) + { + for (String info : pvpPhysicalAttackDefenceMultipiers) + { + final String[] classInfo = info.trim().split(","); + if (classInfo.length == 2) + { + PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.put(Integer.parseInt(classInfo[0].trim()), Float.parseFloat(classInfo[1].trim())); + } + } + } + // Load CommunityBoard config file (if exists) final PropertiesParser CommunityBoard = new PropertiesParser(CUSTOM_COMMUNITY_BOARD_CONFIG_FILE); diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/stats/Formulas.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/stats/Formulas.java index 52d3344386..201bcaed11 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/stats/Formulas.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/stats/Formulas.java @@ -1527,6 +1527,8 @@ public final class Formulas public static double calculatePvpPveBonus(Creature attacker, Creature target, Skill skill, boolean crit) { + final PlayerInstance player = attacker.getActingPlayer(); + // PvP bonus if (attacker.isPlayable() && target.isPlayable()) { @@ -1537,21 +1539,21 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DAMAGE, 1) * Config.PVP_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_MAGICAL_SKILL_DEFENCE, 1) * Config.PVP_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } else { // Physical Skill PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DAMAGE, 1) * Config.PVP_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_SKILL_DEFENCE, 1) * Config.PVP_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } } else { // Autoattack PvP - pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1); - pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1); + pvpAttack = attacker.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DAMAGE, 1) * Config.PVP_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); + pvpDefense = target.getStat().getValue(Stats.PVP_PHYSICAL_ATTACK_DEFENCE, 1) * Config.PVP_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f); } return 1 + (pvpAttack - pvpDefense); @@ -1565,9 +1567,9 @@ public final class Formulas final double pveRaidDefense; double pvePenalty = 1; - if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (attacker.getActingPlayer() != null) && ((target.getLevel() - attacker.getActingPlayer().getLevel()) >= 2)) + if (!target.isRaid() && !target.isRaidMinion() && (target.getLevel() >= Config.MIN_NPC_LVL_DMG_PENALTY) && (player != null) && ((target.getLevel() - player.getLevel()) >= 2)) { - final int lvlDiff = target.getLevel() - attacker.getActingPlayer().getLevel() - 1; + final int lvlDiff = target.getLevel() - player.getLevel() - 1; if (lvlDiff >= Config.NPC_SKILL_DMG_PENALTY.size()) { pvePenalty = Config.NPC_SKILL_DMG_PENALTY.get(Config.NPC_SKILL_DMG_PENALTY.size() - 1); @@ -1583,23 +1585,23 @@ public final class Formulas if (skill.isMagic()) { // Magical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_MAGICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_MAGICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_MAGICAL_SKILL_DEFENCE, 1) : 1; } else { // Physical Skill PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_SKILL_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_SKILL_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_SKILL_DEFENCE, 1) : 1; } } else { // Autoattack PvE - pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1); - pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1); + pveAttack = attacker.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DAMAGE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DAMAGE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); + pveDefense = target.getStat().getValue(Stats.PVE_PHYSICAL_ATTACK_DEFENCE, 1) * (player == null ? 1 : Config.PVE_PHYSICAL_ATTACK_DEFENCE_MULTIPLIERS.getOrDefault(player.getClassId().getId(), 1f)); pveRaidDefense = attacker.isRaid() ? attacker.getStat().getValue(Stats.PVE_RAID_PHYSICAL_ATTACK_DEFENCE, 1) : 1; }