diff --git a/trunk/dist/game/config/Character.ini b/trunk/dist/game/config/Character.ini index 3ebae86c57..b9cdc38af9 100644 --- a/trunk/dist/game/config/Character.ini +++ b/trunk/dist/game/config/Character.ini @@ -262,6 +262,12 @@ MaxAbnormalStateSuccessRate = 90 # Default: 50000000000 MaxSp = 50000000000 +# Maximum Player Level +# WARNING: Cannot exceed the maximum experince.xml level. +# Example: Set as 85 to force the maximum player level at 85. +# Default: 105 +MaximumPlayerLevel = 105 + # Maximum number of allowed subclasses for every player. # Do not use more than 3! # Default: 3 diff --git a/trunk/java/com/l2jmobius/Config.java b/trunk/java/com/l2jmobius/Config.java index bb7f8ddcf1..77bbc79426 100644 --- a/trunk/java/com/l2jmobius/Config.java +++ b/trunk/java/com/l2jmobius/Config.java @@ -163,6 +163,7 @@ public final class Config public static int MIN_ABNORMAL_STATE_SUCCESS_RATE; public static int MAX_ABNORMAL_STATE_SUCCESS_RATE; public static long MAX_SP; + public static byte PLAYER_MAXIMUM_LEVEL; public static byte MAX_SUBCLASS; public static byte BASE_SUBCLASS_LEVEL; public static byte BASE_DUALCLASS_LEVEL; @@ -1358,6 +1359,8 @@ public final class Config MIN_ABNORMAL_STATE_SUCCESS_RATE = Character.getInt("MinAbnormalStateSuccessRate", 10); MAX_ABNORMAL_STATE_SUCCESS_RATE = Character.getInt("MaxAbnormalStateSuccessRate", 90); MAX_SP = Character.getLong("MaxSp", 50000000000L) >= 0 ? Character.getLong("MaxSp", 50000000000L) : Long.MAX_VALUE; + PLAYER_MAXIMUM_LEVEL = Character.getByte("MaximumPlayerLevel", (byte) 99); + PLAYER_MAXIMUM_LEVEL++; MAX_SUBCLASS = (byte) Math.min(3, Character.getByte("MaxSubclass", (byte) 3)); BASE_SUBCLASS_LEVEL = Character.getByte("BaseSubclassLevel", (byte) 40); BASE_DUALCLASS_LEVEL = Character.getByte("BaseDualclassLevel", (byte) 85); diff --git a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/ExperienceData.java b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/ExperienceData.java index 846931591e..8cb3bf154f 100644 --- a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/ExperienceData.java +++ b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/ExperienceData.java @@ -25,6 +25,7 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import com.l2jmobius.Config; import com.l2jmobius.commons.util.IGameXmlReader; /** @@ -67,12 +68,27 @@ public final class ExperienceData implements IGameXmlReader MAX_LEVEL = (byte) (Byte.parseByte(tableAttr.getNamedItem("maxLevel").getNodeValue()) + 1); MAX_PET_LEVEL = (byte) (Byte.parseByte(tableAttr.getNamedItem("maxPetLevel").getNodeValue()) + 1); + if (MAX_LEVEL > Config.PLAYER_MAXIMUM_LEVEL) + { + MAX_LEVEL = Config.PLAYER_MAXIMUM_LEVEL; + } + if (MAX_PET_LEVEL > MAX_LEVEL) + { + MAX_PET_LEVEL = MAX_LEVEL; // Pet level should not exceed owner level. + } + + int maxLevel = 0; for (Node n = table.getFirstChild(); n != null; n = n.getNextSibling()) { if ("experience".equals(n.getNodeName())) { final NamedNodeMap attrs = n.getAttributes(); - _expTable.put(parseInteger(attrs, "level"), parseLong(attrs, "tolevel")); + maxLevel = parseInteger(attrs, "level"); + if (maxLevel > Config.PLAYER_MAXIMUM_LEVEL) + { + break; + } + _expTable.put(maxLevel, parseLong(attrs, "tolevel")); } } } @@ -84,6 +100,10 @@ public final class ExperienceData implements IGameXmlReader */ public long getExpForLevel(int level) { + if (level > Config.PLAYER_MAXIMUM_LEVEL) + { + level = Config.PLAYER_MAXIMUM_LEVEL; + } return _expTable.get(level); } diff --git a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/KarmaData.java b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/KarmaData.java index 00a4ea6b0d..ca826eba2e 100644 --- a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/KarmaData.java +++ b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/KarmaData.java @@ -25,6 +25,7 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import com.l2jmobius.Config; import com.l2jmobius.commons.util.IGameXmlReader; /** @@ -61,7 +62,12 @@ public class KarmaData implements IGameXmlReader if ("increase".equalsIgnoreCase(d.getNodeName())) { final NamedNodeMap attrs = d.getAttributes(); - _karmaTable.put(parseInteger(attrs, "lvl"), parseDouble(attrs, "val")); + final int level = parseInteger(attrs, "lvl"); + if (level >= Config.PLAYER_MAXIMUM_LEVEL) + { + break; + } + _karmaTable.put(level, parseDouble(attrs, "val")); } } } diff --git a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerTemplateData.java b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerTemplateData.java index 05fe06ffe4..5cf8f0a649 100644 --- a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerTemplateData.java +++ b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerTemplateData.java @@ -27,6 +27,7 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import com.l2jmobius.Config; import com.l2jmobius.commons.util.IGameXmlReader; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.StatsSet; @@ -156,7 +157,7 @@ public final class PlayerTemplateData implements IGameXmlReader { final String nodeName = valNode.getNodeName(); - if ((nodeName.startsWith("hp") || nodeName.startsWith("mp") || nodeName.startsWith("cp")) && _playerTemplates.containsKey(ClassId.getClassId(classId))) + if ((level < Config.PLAYER_MAXIMUM_LEVEL) && (nodeName.startsWith("hp") || nodeName.startsWith("mp") || nodeName.startsWith("cp")) && _playerTemplates.containsKey(ClassId.getClassId(classId))) { _playerTemplates.get(ClassId.getClassId(classId)).setUpgainValue(nodeName, level, Double.parseDouble(valNode.getTextContent())); _dataCount++; @@ -164,6 +165,7 @@ public final class PlayerTemplateData implements IGameXmlReader } } } + // TODO: Generate stats automatically. } } } diff --git a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerXpPercentLostData.java b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerXpPercentLostData.java index 24b3aff75d..2b867a18e4 100644 --- a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerXpPercentLostData.java +++ b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/PlayerXpPercentLostData.java @@ -61,7 +61,12 @@ public final class PlayerXpPercentLostData implements IGameXmlReader if ("xpLost".equalsIgnoreCase(d.getNodeName())) { final NamedNodeMap attrs = d.getAttributes(); - _playerXpPercentLost[parseInteger(attrs, "level")] = parseDouble(attrs, "val"); + final Integer level = parseInteger(attrs, "level"); + if (level > _maxlevel) + { + break; + } + _playerXpPercentLost[level] = parseDouble(attrs, "val"); } } }