Преглед изворни кода

BETA: Character templates rework.
- Support for XML character templates
- Support for table level-upgain data (HP, CP, MP and HP-, CP-, MP-regeneration) instead of calculated data

Move speed stat:
- rework of calculation (getBaseMoveSpeed() method for CharStat and children)
- calculation of walk speed from run speed was replaced by table values
- core support for pet's template "speed_on_ride" parameter
- penalties for level diff with mount and hungry mount was implemented

PDef, MDef stats:
- values for empty paperdol slots were unhardcoded
- P.Def. formula was updated

Reviewed by: UnAfraid, Zoey76

VlLight пре 12 година
родитељ
комит
37f572f6b0
21 измењених фајлова са 522 додато и 273 уклоњено
  1. 120 62
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/CharTemplateTable.java
  2. 19 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/PetDataTable.java
  3. 40 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2PetLevelData.java
  4. 3 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java
  5. 10 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
  6. 16 10
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/CharStat.java
  7. 4 6
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/NpcStat.java
  8. 91 23
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
  9. 8 7
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PlayableStat.java
  10. 11 13
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2CharTemplate.java
  11. 114 84
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2PcTemplate.java
  12. 9 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java
  13. 10 10
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncMDefMod.java
  14. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncMoveSpeed.java
  15. 15 19
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncPDefMod.java
  16. 6 20
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/Formulas.java
  17. 33 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/MoveType.java
  18. 1 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/Stats.java
  19. 5 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/CharacterCreate.java
  20. 3 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/AbstractNpcInfo.java
  21. 3 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/PetInfo.java

+ 120 - 62
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/CharTemplateTable.java

@@ -18,89 +18,147 @@
  */
 package com.l2jserver.gameserver.datatables;
 
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.l2jserver.L2DatabaseFactory;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import com.l2jserver.gameserver.engines.DocumentParser;
+import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
 import com.l2jserver.gameserver.model.base.ClassId;
 
 /**
  * This will be reworked Soon(tm).
- * @author Unknown, Forsaiken, Zoey76
+ * @author Unknown, Forsaiken, Zoey76, GKR
  */
-public final class CharTemplateTable
+public final class CharTemplateTable extends DocumentParser
 {
 	private static final Logger _log = Logger.getLogger(CharTemplateTable.class.getName());
 	
 	private static final Map<ClassId, L2PcTemplate> _charTemplates = new HashMap<>();
 	
+	private int _dataCount = 0;
+	
 	protected CharTemplateTable()
 	{
-		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
-			Statement s = con.createStatement();
-			ResultSet rset = s.executeQuery("SELECT * FROM char_templates, lvlupgain WHERE char_templates.classId = lvlupgain.classId ORDER BY char_templates.ClassId"))
+		load();
+	}
+	
+	@Override
+	public void load()
+	{
+		parseDirectory("data/stats/chars/baseStats/");
+		_log.info(getClass().getSimpleName() + ": Loaded " + _charTemplates.size() + " Character Templates.");
+		_log.info(getClass().getSimpleName() + ": loaded " + _dataCount + " level upgain records");
+	}
+	
+	@Override
+	protected void parseDocument()
+	{
+		NamedNodeMap attrs;
+		int classId = 0;
+		
+		for (Node n = getCurrentDocument().getFirstChild(); n != null; n = n.getNextSibling())
 		{
-			StatsSet set;
-			int cId;
-			while (rset.next())
+			if ("list".equalsIgnoreCase(n.getNodeName()))
 			{
-				set = new StatsSet();
-				cId = rset.getInt("ClassId");
-				set.set("classId", cId);
-				set.set("raceId", rset.getInt("raceId"));
-				set.set("baseSTR", rset.getInt("STR"));
-				set.set("baseCON", rset.getInt("CON"));
-				set.set("baseDEX", rset.getInt("DEX"));
-				set.set("baseINT", rset.getInt("_INT"));
-				set.set("baseWIT", rset.getInt("WIT"));
-				set.set("baseMEN", rset.getInt("MEN"));
-				set.set("baseHpMax", rset.getFloat("defaultHpBase"));
-				set.set("lvlHpAdd", rset.getFloat("defaultHpAdd"));
-				set.set("lvlHpMod", rset.getFloat("defaultHpMod"));
-				set.set("baseMpMax", rset.getFloat("defaultMpBase"));
-				set.set("baseCpMax", rset.getFloat("defaultCpBase"));
-				set.set("lvlCpAdd", rset.getFloat("defaultCpAdd"));
-				set.set("lvlCpMod", rset.getFloat("defaultCpMod"));
-				set.set("lvlMpAdd", rset.getFloat("defaultMpAdd"));
-				set.set("lvlMpMod", rset.getFloat("defaultMpMod"));
-				set.set("baseHpReg", 2);
-				set.set("baseMpReg", 0.9);
-				set.set("basePAtk", rset.getInt("p_atk"));
-				set.set("basePDef", rset.getInt("p_def"));
-				set.set("baseMAtk", rset.getInt("m_atk"));
-				set.set("baseMDef", rset.getInt("m_def"));
-				set.set("classBaseLevel", rset.getInt("class_lvl"));
-				set.set("baseRunSpd", rset.getInt("move_spd"));
-				set.set("baseWalkSpd", 0);
-				set.set("baseShldDef", 0);
-				set.set("baseShldRate", 0);
-				set.set("baseAtkRange", 40);
-				
-				set.set("spawnX", rset.getInt("x"));
-				set.set("spawnY", rset.getInt("y"));
-				set.set("spawnZ", rset.getInt("z"));
-				
-				set.set("collision_radius", rset.getDouble("m_col_r"));
-				set.set("collision_height", rset.getDouble("m_col_h"));
-				set.set("collision_radius_female", rset.getDouble("f_col_r"));
-				set.set("collision_height_female", rset.getDouble("f_col_h"));
-				
-				final L2PcTemplate ct = new L2PcTemplate(set);
-				_charTemplates.put(ClassId.getClassId(cId), ct);
+				for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
+				{
+					if ("classId".equalsIgnoreCase(d.getNodeName()))
+					{
+						classId = Integer.parseInt(d.getTextContent());
+					}
+					else if ("staticData".equalsIgnoreCase(d.getNodeName()))
+					{
+						StatsSet set = new StatsSet();
+						set.set("classId", classId);
+						List<Location> creationPoints = new ArrayList<>();
+						
+						for (Node nd = d.getFirstChild(); nd != null; nd = nd.getNextSibling())
+						{
+							// Skip odd nodes
+							if (nd.getNodeName().equals("#text"))
+							{
+								continue;
+							}
+							
+							if (nd.getChildNodes().getLength() > 1)
+							{
+								for (Node cnd = nd.getFirstChild(); cnd != null; cnd = cnd.getNextSibling())
+								{
+									// use L2CharTemplate(superclass) fields for male collision height and collision radius
+									if (nd.getNodeName().equalsIgnoreCase("collisionMale"))
+									{
+										if (cnd.getNodeName().equalsIgnoreCase("radius"))
+										{
+											set.set("collision_radius", cnd.getTextContent());
+										}
+										else if (cnd.getNodeName().equalsIgnoreCase("height"))
+										{
+											set.set("collision_height", cnd.getTextContent());
+										}
+									}
+									if ("node".equalsIgnoreCase(cnd.getNodeName()))
+									{
+										attrs = cnd.getAttributes();
+										creationPoints.add(new Location(parseInt(attrs, "x"), parseInt(attrs, "y"), parseInt(attrs, "z")));
+									}
+									else if ("walk".equalsIgnoreCase(cnd.getNodeName()))
+									{
+										set.set("baseWalkSpd", cnd.getTextContent());
+									}
+									else if ("run".equalsIgnoreCase(cnd.getNodeName()))
+									{
+										set.set("baseRunSpd", cnd.getTextContent());
+									}
+									else if (!cnd.getNodeName().equals("#text"))
+									{
+										set.set((nd.getNodeName() + cnd.getNodeName()), cnd.getTextContent());
+									}
+								}
+							}
+							else
+							{
+								set.set(nd.getNodeName(), nd.getTextContent());
+							}
+						}
+						// calculate total pdef and mdef from parts
+						set.set("basePDef", (set.getInteger("basePDefchest", 0) + set.getInteger("basePDeflegs", 0) + set.getInteger("basePDefhead", 0) + set.getInteger("basePDeffeet", 0) + set.getInteger("basePDefgloves", 0) + set.getInteger("basePDefunderwear", 0) + set.getInteger("basePDefcloak", 0)));
+						set.set("baseMDef", (set.getInteger("baseMDefrear", 0) + set.getInteger("baseMDeflear", 0) + set.getInteger("baseMDefrfinger", 0) + set.getInteger("baseMDefrfinger", 0) + set.getInteger("baseMDefneck", 0)));
+						
+						final L2PcTemplate ct = new L2PcTemplate(set, creationPoints);
+						_charTemplates.put(ClassId.getClassId(classId), ct);
+					}
+					else if ("lvlUpgainData".equalsIgnoreCase(d.getNodeName()))
+					{
+						for (Node lvlNode = d.getFirstChild(); lvlNode != null; lvlNode = lvlNode.getNextSibling())
+						{
+							if ("level".equalsIgnoreCase(lvlNode.getNodeName()))
+							{
+								attrs = lvlNode.getAttributes();
+								int level = parseInt(attrs, "val");
+								
+								for (Node valNode = lvlNode.getFirstChild(); valNode != null; valNode = valNode.getNextSibling())
+								{
+									String nodeName = valNode.getNodeName();
+									
+									if ((nodeName.startsWith("hp") || nodeName.startsWith("mp") || nodeName.startsWith("cp")) && _charTemplates.containsKey(ClassId.getClassId(classId)))
+									{
+										_charTemplates.get(ClassId.getClassId(classId)).setUpgainValue(nodeName, level, Double.parseDouble(valNode.getTextContent()));
+										_dataCount++;
+									}
+								}
+							}
+						}
+					}
+				}
 			}
-			_log.info(getClass().getSimpleName() + ": Loaded " + _charTemplates.size() + " Character Templates.");
-		}
-		catch (SQLException e)
-		{
-			_log.log(Level.SEVERE, getClass().getSimpleName() + ": Failed loading char templates", e);
 		}
 	}
 	

+ 19 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/PetDataTable.java

@@ -118,7 +118,25 @@ public final class PetDataTable extends DocumentParser
 									if (bean.getNodeName().equals("set"))
 									{
 										attrs = bean.getAttributes();
-										set.set(attrs.getNamedItem("name").getNodeValue(), attrs.getNamedItem("val").getNodeValue());
+										if (attrs.getNamedItem("name").getNodeValue().equals("speed_on_ride"))
+										{
+											set.set("walkSpeedOnRide", attrs.getNamedItem("walk").getNodeValue());
+											set.set("runSpeedOnRide", attrs.getNamedItem("run").getNodeValue());
+											set.set("slowSwimSpeedOnRide", attrs.getNamedItem("slowSwim").getNodeValue());
+											set.set("fastSwimSpeedOnRide", attrs.getNamedItem("fastSwim").getNodeValue());
+											if (attrs.getNamedItem("slowFly") != null)
+											{
+												set.set("slowFlySpeedOnRide", attrs.getNamedItem("slowFly").getNodeValue());
+											}
+											if (attrs.getNamedItem("fastFly") != null)
+											{
+												set.set("fastFlySpeedOnRide", attrs.getNamedItem("fastFly").getNodeValue());
+											}
+										}
+										else
+										{
+											set.set(attrs.getNamedItem("name").getNodeValue(), attrs.getNamedItem("val").getNodeValue());
+										}
 									}
 								}
 								data.addNewStat(level, new L2PetLevelData(set));

+ 40 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2PetLevelData.java

@@ -18,6 +18,8 @@
  */
 package com.l2jserver.gameserver.model;
 
+import com.l2jserver.gameserver.model.stats.MoveType;
+
 /**
  * Stats definition for each pet level.
  * @author JIV, Zoey76
@@ -39,7 +41,13 @@ public class L2PetLevelData
 	private final float _petRegenMP;
 	private final short _petSoulShot;
 	private final short _petSpiritShot;
-	
+	private final int _walkSpeedOnRide;
+	private final int _runSpeedOnRide;
+	private final int _slowSwimSpeedOnRide;
+	private final int _fastSwimSpeedOnRide;
+	private final int _slowFlySpeedOnRide;
+	private final int _fastFlySpeedOnRide;
+
 	public L2PetLevelData(StatsSet set)
 	{
 		_ownerExpTaken = set.getInteger("get_exp_type");
@@ -57,6 +65,12 @@ public class L2PetLevelData
 		_petRegenMP = set.getFloat("org_mp_regen");
 		_petSoulShot = set.getShort("soulshot_count");
 		_petSpiritShot = set.getShort("spiritshot_count");
+		_walkSpeedOnRide = set.getInteger("walkSpeedOnRide", 0);
+		_runSpeedOnRide = set.getInteger("runSpeedOnRide", 0);
+		_slowSwimSpeedOnRide = set.getInteger("slowSwimSpeedOnRide", 0);
+		_fastSwimSpeedOnRide = set.getInteger("fastSwimSpeedOnRide", 0);
+		_slowFlySpeedOnRide = set.getInteger("slowFlySpeedOnRide", 0);
+		_fastFlySpeedOnRide = set.getInteger("fastFlySpeedOnRide", 0);
 	}
 	
 	/**
@@ -178,4 +192,29 @@ public class L2PetLevelData
 	{
 		return _petSpiritShot;
 	}
+
+	/**
+	 * @param mt movement type
+	 * @return the base riding speed of given movement type.
+	 */
+	public int getSpeedOnRide(MoveType mt)
+	{
+		switch(mt)
+		{
+			case WALK:
+				return _walkSpeedOnRide;
+			case RUN:
+				return _runSpeedOnRide;
+			case SLOW_SWIM:
+				return _slowSwimSpeedOnRide;
+			case FAST_SWIM:
+				return _fastSwimSpeedOnRide;
+			case SLOW_FLY:
+				return _slowFlySpeedOnRide;
+			case FAST_FLY:
+				return _fastFlySpeedOnRide;
+		}
+
+		return 0;
+	}
 }

+ 3 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -3979,7 +3979,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 				{
 					su.addAttribute(StatusUpdate.CAST_SPD, getMAtkSpd());
 				}
-				else if (stat == Stats.RUN_SPEED)
+				else if (stat == Stats.MOVE_SPEED)
 				{
 					broadcastFull = true;
 				}
@@ -6895,9 +6895,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 	/**
 	 * @return the Level Modifier ((level + 89) / 100).
 	 */
-	public float getLevelMod()
+	public double getLevelMod()
 	{
-		return ((getLevel() + 89) / 100f);
+		return ((getLevel() + 89) / 100d);
 	}
 	
 	public final void setSkillCast(Future<?> newSkillCast)

+ 10 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -14430,9 +14430,15 @@ public final class L2PcInstance extends L2Playable
 	
 	public void setCurrentFeed(int num)
 	{
+		boolean lastHungryState = isHungry();
 		_curFeed = num > getMaxFeed() ? getMaxFeed() : num;
 		SetupGauge sg = new SetupGauge(3, (getCurrentFeed() * 10000) / getFeedConsume(), (getMaxFeed() * 10000) / getFeedConsume());
 		sendPacket(sg);
+		// broadcast move speed change when strider becomes hungry / full 
+		if (lastHungryState != isHungry())
+		{
+			broadcastUserInfo();
+		}
 	}
 	
 	private int getMaxFeed()
@@ -14440,7 +14446,7 @@ public final class L2PcInstance extends L2Playable
 		return getPetLevelData(_mountNpcId).getPetMaxFeed();
 	}
 	
-	protected boolean isHungry()
+	public boolean isHungry()
 	{
 		return _canFeed ? (getCurrentFeed() < ((getPetData(getMountNpcId()).getHungryLimit() / 100f) * getPetLevelData(getMountNpcId()).getPetMaxFeed())) : false;
 	}
@@ -15282,12 +15288,12 @@ public final class L2PcInstance extends L2Playable
 	
 	public double getCollisionRadius()
 	{
-		return getMountType() != 0 ? (NpcTable.getInstance().getTemplate(getMountNpcId()).getfCollisionRadius()) : (isTransformed() && !getTransformation().isStance() ? getTransformation().getCollisionRadius() : (getAppearance().getSex() ? getBaseTemplate().getFCollisionRadiusFemale() : getBaseTemplate().getfCollisionRadius()));
+		return isMounted() ? (NpcTable.getInstance().getTemplate(getMountNpcId()).getfCollisionRadius()) : (isTransformed() && !getTransformation().isStance() ? getTransformation().getCollisionRadius() : (getAppearance().getSex() ? getBaseTemplate().getFCollisionRadiusFemale() : getBaseTemplate().getfCollisionRadius()));
 	}
 	
 	public double getCollisionHeight()
 	{
-		return getMountType() != 0 ? (NpcTable.getInstance().getTemplate(getMountNpcId()).getfCollisionHeight()) : (isTransformed() && !getTransformation().isStance() ? getTransformation().getCollisionHeight() : (getAppearance().getSex() ? getBaseTemplate().getFCollisionHeightFemale() : getBaseTemplate().getfCollisionHeight()));
+		return isMounted() ? (NpcTable.getInstance().getTemplate(getMountNpcId()).getfCollisionHeight()) : (isTransformed() && !getTransformation().isStance() ? getTransformation().getCollisionHeight() : (getAppearance().getSex() ? getBaseTemplate().getFCollisionHeightFemale() : getBaseTemplate().getfCollisionHeight()));
 	}
 	
 	public final int getClientX()
@@ -15347,7 +15353,7 @@ public final class L2PcInstance extends L2Playable
 		}
 		
 		final int deltaZ = getZ() - z;
-		if (deltaZ <= getBaseTemplate().getFallHeight())
+		if (deltaZ <= getBaseTemplate().getSafeFallHeight())
 		{
 			return false;
 		}

+ 16 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/CharStat.java

@@ -28,6 +28,7 @@ import com.l2jserver.gameserver.model.items.type.L2WeaponType;
 import com.l2jserver.gameserver.model.skills.L2Skill;
 import com.l2jserver.gameserver.model.stats.Calculator;
 import com.l2jserver.gameserver.model.stats.Env;
+import com.l2jserver.gameserver.model.stats.MoveType;
 import com.l2jserver.gameserver.model.stats.Stats;
 
 public class CharStat
@@ -440,7 +441,16 @@ public class CharStat
 			return 1;
 		}
 		
-		return getRunSpeed() / (float) _activeChar.getTemplate().getBaseRunSpd();
+		return getWalkSpeed() / (float) _activeChar.getTemplate().getBaseMoveSpd(MoveType.WALK);
+	}
+
+	/**
+	 * @param mt movement type
+	 * @return the base move speed of given movement type.
+	 */
+	protected double getBaseMoveSpeed(MoveType mt)
+	{
+		return _activeChar.getTemplate().getBaseMoveSpd(mt);
 	}
 	
 	/**
@@ -453,11 +463,7 @@ public class CharStat
 			return 1;
 		}
 		
-		if (_activeChar.isRunning())
-		{
-			return getRunSpeed();
-		}
-		return getWalkSpeed();
+		return  _activeChar.isRunning() ? getRunSpeed() : getWalkSpeed();
 	}
 	
 	/**
@@ -700,14 +706,14 @@ public class CharStat
 		
 		// err we should be adding TO the persons run speed
 		// not making it a constant
-		double baseRunSpd = _activeChar.getTemplate().getBaseRunSpd();
+		double baseRunSpd = getBaseMoveSpeed(MoveType.RUN);
 		
 		if (baseRunSpd == 0)
 		{
 			return 0;
 		}
 		
-		return (int) Math.round(calcStat(Stats.RUN_SPEED, baseRunSpd, null, null));
+		return (int) Math.round(calcStat(Stats.MOVE_SPEED, baseRunSpd, null, null));
 	}
 	
 	/**
@@ -751,14 +757,14 @@ public class CharStat
 			return 1;
 		}
 		
-		double baseWalkSpd = _activeChar.getTemplate().getBaseWalkSpd();
+		double baseWalkSpd = getBaseMoveSpeed(MoveType.WALK);
 		
 		if (baseWalkSpd == 0)
 		{
 			return 0;
 		}
 		
-		return (int) calcStat(Stats.WALK_SPEED, baseWalkSpd);
+		return (int) calcStat(Stats.MOVE_SPEED, baseWalkSpd);
 	}
 	
 	/**

+ 4 - 6
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/NpcStat.java

@@ -19,6 +19,7 @@
 package com.l2jserver.gameserver.model.actor.stat;
 
 import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.stats.MoveType;
 import com.l2jserver.gameserver.model.stats.Stats;
 
 public class NpcStat extends CharStat
@@ -43,7 +44,7 @@ public class NpcStat extends CharStat
 	@Override
 	public int getWalkSpeed()
 	{
-		return (int) calcStat(Stats.WALK_SPEED, getActiveChar().getTemplate().getBaseWalkSpd(), null, null);
+		return (int) calcStat(Stats.MOVE_SPEED, getActiveChar().getTemplate().getBaseMoveSpd(MoveType.WALK), null, null);
 	}
 	
 	@Override
@@ -53,10 +54,7 @@ public class NpcStat extends CharStat
 		{
 			return 1;
 		}
-		if (getActiveChar().isRunning())
-		{
-			return (getRunSpeed() * 1f) / getActiveChar().getTemplate().getBaseRunSpd();
-		}
-		return (getWalkSpeed() * 1f) / getActiveChar().getTemplate().getBaseWalkSpd();
+
+		return (getWalkSpeed() * 1f) / getActiveChar().getTemplate().getBaseMoveSpd(getActiveChar().isRunning() ? MoveType.RUN : MoveType.WALK);
 	}
 }

+ 91 - 23
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java

@@ -22,7 +22,8 @@ import javolution.util.FastList;
 
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.datatables.ExperienceTable;
-import com.l2jserver.gameserver.datatables.NpcTable;
+import com.l2jserver.gameserver.datatables.PetDataTable;
+import com.l2jserver.gameserver.instancemanager.ZoneManager;
 import com.l2jserver.gameserver.model.PcCondOverride;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.instance.L2ClassMasterInstance;
@@ -30,8 +31,10 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
 import com.l2jserver.gameserver.model.entity.RecoBonus;
 import com.l2jserver.gameserver.model.quest.QuestState;
+import com.l2jserver.gameserver.model.stats.MoveType;
 import com.l2jserver.gameserver.model.stats.Stats;
 import com.l2jserver.gameserver.model.zone.ZoneId;
+import com.l2jserver.gameserver.model.zone.type.L2SwampZone;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExVitalityPointInfo;
@@ -411,7 +414,7 @@ public class PcStat extends PlayableStat
 	public final int getMaxCp()
 	{
 		// Get the Max CP (base+modifier) of the L2PcInstance
-		int val = super.getMaxCp();
+		int val = (getActiveChar() == null) ? 1 : (int) calcStat(Stats.MAX_CP, getActiveChar().getTemplate().getBaseCpMax(getActiveChar().getLevel()));
 		if (val != _oldMaxCp)
 		{
 			_oldMaxCp = val;
@@ -429,7 +432,7 @@ public class PcStat extends PlayableStat
 	public final int getMaxHp()
 	{
 		// Get the Max HP (base+modifier) of the L2PcInstance
-		int val = super.getMaxHp();
+		int val = (getActiveChar() == null) ? 1 : (int) calcStat(Stats.MAX_HP, getActiveChar().getTemplate().getBaseHpMax(getActiveChar().getLevel()));
 		if (val != _oldMaxHp)
 		{
 			_oldMaxHp = val;
@@ -448,7 +451,7 @@ public class PcStat extends PlayableStat
 	public final int getMaxMp()
 	{
 		// Get the Max MP (base+modifier) of the L2PcInstance
-		int val = super.getMaxMp();
+		int val = (getActiveChar() == null) ? 1 : (int) calcStat(Stats.MAX_MP, getActiveChar().getTemplate().getBaseMpMax(getActiveChar().getLevel()));
 		
 		if (val != _oldMaxMp)
 		{
@@ -493,6 +496,74 @@ public class PcStat extends PlayableStat
 		}
 	}
 	
+	/**
+	 * @param mt movement type
+	 * @return the base move speed of given movement type.
+	 */
+	@Override
+	protected double getBaseMoveSpeed(MoveType mt)
+	{
+		L2PcInstance player = getActiveChar();
+		int val = 0;
+		
+		if (player.isInsideZone(ZoneId.WATER))
+		{
+			if (player.isMounted())
+			{
+				switch (mt)
+				{
+					case WALK:
+						val = PetDataTable.getInstance().getPetLevelData(player.getMountNpcId(), player.getMountLevel()).getSpeedOnRide(MoveType.SLOW_SWIM);
+						break;
+					case RUN:
+						val = PetDataTable.getInstance().getPetLevelData(player.getMountNpcId(), player.getMountLevel()).getSpeedOnRide(MoveType.FAST_SWIM);
+						break;
+				}
+			}
+			else
+			{
+				switch (mt)
+				{
+					case WALK:
+						val = player.getTemplate().getBaseSlowSwimSpd();
+						break;
+					case RUN:
+						val = player.getTemplate().getBaseFastSwimSpd();
+						break;
+				}
+			}
+		}
+		else
+		{
+			val = player.isMounted() ? PetDataTable.getInstance().getPetLevelData(player.getMountNpcId(), player.getMountLevel()).getSpeedOnRide(mt) : player.getTemplate().getBaseMoveSpd(mt);
+			
+			if (player.isInsideZone(ZoneId.SWAMP))
+			{
+				L2SwampZone zone = ZoneManager.getInstance().getZone(getActiveChar(), L2SwampZone.class);
+				int bonus = zone == null ? 0 : zone.getMoveBonus();
+				double dbonus = bonus / 100.0; // %
+				val += val * dbonus;
+			}
+		}
+		
+		// Check for mount penalties
+		if (player.isMounted())
+		{
+			// if level diff with mount >= 10, it decreases move speed by 50%
+			if ((player.getMountLevel() - player.getLevel()) >= 10)
+			{
+				val /= 2;
+			}
+			// if mount is hungry, it decreases move speed by 50%
+			if (player.isHungry())
+			{
+				val /= 2;
+			}
+		}
+		
+		return val;
+	}
+	
 	@Override
 	public int getRunSpeed()
 	{
@@ -501,19 +572,27 @@ public class PcStat extends PlayableStat
 			return 1;
 		}
 		
-		int val;
+		int val = super.getRunSpeed();
+		val += Config.RUN_SPD_BOOST;
 		
-		L2PcInstance player = getActiveChar();
-		if (player.isMounted())
+		// Apply max run speed cap.
+		if ((val > Config.MAX_RUN_SPEED) && !getActiveChar().canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
 		{
-			int baseRunSpd = NpcTable.getInstance().getTemplate(getActiveChar().getMountNpcId()).getBaseRunSpd();
-			val = (int) Math.round(calcStat(Stats.RUN_SPEED, baseRunSpd, null, null));
+			return Config.MAX_RUN_SPEED;
 		}
-		else
+		
+		return val;
+	}
+	
+	@Override
+	public int getWalkSpeed()
+	{
+		if (getActiveChar() == null)
 		{
-			val = super.getRunSpeed();
+			return 1;
 		}
 		
+		int val = super.getWalkSpeed();
 		val += Config.RUN_SPD_BOOST;
 		
 		// Apply max run speed cap.
@@ -574,23 +653,12 @@ public class PcStat extends PlayableStat
 		
 		if (getActiveChar().isMounted())
 		{
-			return (getRunSpeed() * 1f) / NpcTable.getInstance().getTemplate(getActiveChar().getMountNpcId()).getBaseRunSpd();
+			return (getRunSpeed() * 1f) / PetDataTable.getInstance().getPetLevelData(getActiveChar().getMountNpcId(), getActiveChar().getMountLevel()).getSpeedOnRide(MoveType.RUN);
 		}
 		
 		return super.getMovementSpeedMultiplier();
 	}
 	
-	@Override
-	public int getWalkSpeed()
-	{
-		if (getActiveChar() == null)
-		{
-			return 1;
-		}
-		
-		return (getRunSpeed() * 70) / 100;
-	}
-	
 	private void updateVitalityLevel(boolean quiet)
 	{
 		final byte level;

+ 8 - 7
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PlayableStat.java

@@ -27,6 +27,7 @@ import com.l2jserver.gameserver.instancemanager.ZoneManager;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.stats.MoveType;
 import com.l2jserver.gameserver.model.zone.ZoneId;
 import com.l2jserver.gameserver.model.zone.type.L2SwampZone;
 import com.l2jserver.gameserver.network.communityserver.CommunityServerThread;
@@ -228,15 +229,15 @@ public class PlayableStat extends CharStat
 		return level;
 	}
 	
+	/**
+	 * @param mt movement type
+	 * @return the base move speed of given movement type.
+	 */
 	@Override
-	public int getRunSpeed()
+	protected double getBaseMoveSpeed(MoveType mt)
 	{
-		int val = super.getRunSpeed();
-		if (getActiveChar().isInsideZone(ZoneId.WATER))
-		{
-			val /= 2;
-		}
-		
+		double val = super.getBaseMoveSpeed(mt);
+
 		if (getActiveChar().isInsideZone(ZoneId.SWAMP))
 		{
 			L2SwampZone zone = ZoneManager.getInstance().getZone(getActiveChar(), L2SwampZone.class);

+ 11 - 13
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2CharTemplate.java

@@ -22,6 +22,7 @@ import java.util.Map;
 
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.skills.L2Skill;
+import com.l2jserver.gameserver.model.stats.MoveType;
 
 /**
  * @author Zoey76
@@ -452,20 +453,17 @@ public class L2CharTemplate
 		return _baseMCritRate;
 	}
 	
-	/**
-	 * @return the baseWalkSpd
-	 */
-	public int getBaseWalkSpd()
-	{
-		return _baseWalkSpd;
-	}
-	
-	/**
-	 * @return the baseRunSpd
-	 */
-	public int getBaseRunSpd()
+	public int getBaseMoveSpd(MoveType mt)
 	{
-		return _baseRunSpd;
+		switch(mt)
+		{
+			case WALK:
+				return _baseWalkSpd;
+			case RUN:
+				return _baseRunSpd;
+		}
+
+		return 0;
 	}
 	
 	/**

+ 114 - 84
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2PcTemplate.java

@@ -18,13 +18,20 @@
  */
 package com.l2jserver.gameserver.model.actor.templates;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import com.l2jserver.gameserver.datatables.ExperienceTable;
 import com.l2jserver.gameserver.datatables.InitialEquipmentData;
+import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.base.ClassId;
 import com.l2jserver.gameserver.model.base.Race;
+import com.l2jserver.gameserver.model.itemcontainer.Inventory;
 import com.l2jserver.gameserver.model.items.PcItemTemplate;
+import com.l2jserver.gameserver.model.stats.MoveType;
+import com.l2jserver.util.Rnd;
 
 /**
  * @author mkizub, Zoey76
@@ -32,57 +39,61 @@ import com.l2jserver.gameserver.model.items.PcItemTemplate;
 public class L2PcTemplate extends L2CharTemplate
 {
 	private final ClassId _classId;
-	private final Race _race;
 	
-	private final int _spawnX;
-	private final int _spawnY;
-	private final int _spawnZ;
+	private final float[] _baseHp;
+	private final float[] _baseMp;
+	private final float[] _baseCp;
 	
-	private final int _classBaseLevel;
-	private final float _lvlHpAdd;
-	private final float _lvlHpMod;
-	private final float _lvlCpAdd;
-	private final float _lvlCpMod;
-	private final float _lvlMpAdd;
-	private final float _lvlMpMod;
-	
-	private final double _fCollisionHeightMale;
-	private final double _fCollisionRadiusMale;
+	private final double[] _baseHpReg;
+	private final double[] _baseMpReg;
+	private final double[] _baseCpReg;
 	
 	private final double _fCollisionHeightFemale;
 	private final double _fCollisionRadiusFemale;
 	
-	private final int _fallHeight;
+	private final int _baseSafeFallHeight;
+	private final int _baseSlowSwimSpd;
+	private final int _baseFastSwimSpd;
 	
 	private final List<PcItemTemplate> _initialEquipment;
+	private final List<Location> _creationPoints;
+	private final Map<Integer, Integer> _baseSlotDef;
 	
-	public L2PcTemplate(StatsSet set)
+	public L2PcTemplate(StatsSet set, List<Location> creationPoints)
 	{
 		super(set);
 		_classId = ClassId.getClassId(set.getInteger("classId"));
-		_race = Race.values()[set.getInteger("raceId")];
-		
-		_spawnX = set.getInteger("spawnX");
-		_spawnY = set.getInteger("spawnY");
-		_spawnZ = set.getInteger("spawnZ");
 		
-		_classBaseLevel = set.getInteger("classBaseLevel");
-		_lvlHpAdd = set.getFloat("lvlHpAdd");
-		_lvlHpMod = set.getFloat("lvlHpMod");
-		_lvlCpAdd = set.getFloat("lvlCpAdd");
-		_lvlCpMod = set.getFloat("lvlCpMod");
-		_lvlMpAdd = set.getFloat("lvlMpAdd");
-		_lvlMpMod = set.getFloat("lvlMpMod");
+		_baseHp = new float[ExperienceTable.getInstance().getMaxLevel()];
+		_baseMp = new float[ExperienceTable.getInstance().getMaxLevel()];
+		_baseCp = new float[ExperienceTable.getInstance().getMaxLevel()];
+		_baseHpReg = new double[ExperienceTable.getInstance().getMaxLevel()];
+		_baseMpReg = new double[ExperienceTable.getInstance().getMaxLevel()];
+		_baseCpReg = new double[ExperienceTable.getInstance().getMaxLevel()];
 		
-		_fCollisionRadiusMale = set.getDouble("collision_radius");
-		_fCollisionHeightMale = set.getDouble("collision_height");
+		_baseSlotDef = new HashMap<>(12);
+		_baseSlotDef.put(Inventory.PAPERDOLL_CHEST, set.getInteger("basePDefchest", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_LEGS, set.getInteger("basePDeflegs", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_HEAD, set.getInteger("basePDefhead", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_FEET, set.getInteger("basePDeffeet", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_GLOVES, set.getInteger("basePDefgloves", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_UNDER, set.getInteger("basePDefunderwear", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_CLOAK, set.getInteger("basePDefcloak", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_REAR, set.getInteger("baseMDefrear", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_LEAR, set.getInteger("baseMDeflear", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_RFINGER, set.getInteger("baseMDefrfinger", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_LFINGER, set.getInteger("baseMDefrfinger", 0));
+		_baseSlotDef.put(Inventory.PAPERDOLL_NECK, set.getInteger("baseMDefneck", 0));
 		
-		_fCollisionRadiusFemale = set.getDouble("collision_radius_female");
-		_fCollisionHeightFemale = set.getDouble("collision_height_female");
+		_fCollisionRadiusFemale = set.getDouble("collisionFemaleradius");
+		_fCollisionHeightFemale = set.getDouble("collisionFemaleheight");
 		
-		_fallHeight = 333; // TODO: Unhardcode it.
+		_baseSafeFallHeight = set.getInteger("baseSafeFall", 333);
+		_baseSlowSwimSpd = set.getInteger("baseMoveSpdslowSwim", (super.getBaseMoveSpd(MoveType.WALK) / 2));
+		_baseFastSwimSpd = set.getInteger("baseMoveSpdfastSwim", (super.getBaseMoveSpd(MoveType.RUN) / 2));
 		
 		_initialEquipment = InitialEquipmentData.getInstance().getEquipmentList(_classId);
+		_creationPoints = creationPoints;
 	}
 	
 	/**
@@ -98,127 +109,146 @@ public class L2PcTemplate extends L2CharTemplate
 	 */
 	public Race getRace()
 	{
-		return _race;
-	}
-	
-	/**
-	 * @return the template X spawn coordinate.
-	 */
-	public int getSpawnX()
-	{
-		return _spawnX;
+		return _classId.getRace();
 	}
 	
 	/**
-	 * @return the template Y spawn coordinate.
+	 * @return random Location of created character spawn.
 	 */
-	public int getSpawnY()
+	public Location getCreationPoint()
 	{
-		return _spawnY;
+		return _creationPoints.get(Rnd.get(_creationPoints.size()));
 	}
 	
 	/**
-	 * @return the template Z spawn coordinate.
+	 * Sets the value of level upgain parameter.
+	 * @param paramName name of parameter
+	 * @param level corresponding character level
+	 * @param val value of parameter
 	 */
-	public int getSpawnZ()
+	public void setUpgainValue(String paramName, int level, double val)
 	{
-		return _spawnZ;
+		switch (paramName)
+		{
+			case "hp":
+				_baseHp[level] = (float) val;
+				break;
+			case "mp":
+				_baseMp[level] = (float) val;
+				break;
+			case "cp":
+				_baseCp[level] = (float) val;
+				break;
+			case "hpRegen":
+				_baseHpReg[level] = val;
+			case "mpRegen":
+				_baseMpReg[level] = val;
+			case "cpRegen":
+				_baseCpReg[level] = val;
+		}
 	}
 	
 	/**
-	 * @return the template class base level.
+	 * @param level character level to return value
+	 * @return the baseHpMax for given character level
 	 */
-	public int getClassBaseLevel()
+	public float getBaseHpMax(int level)
 	{
-		return _classBaseLevel;
+		return _baseHp[level];
 	}
 	
 	/**
-	 * @return the template level Hp add.
+	 * @param level character level to return value
+	 * @return the baseMpMax for given character level
 	 */
-	public float getLvlHpAdd()
+	public float getBaseMpMax(int level)
 	{
-		return _lvlHpAdd;
+		return _baseMp[level];
 	}
 	
 	/**
-	 * @return the template level Hp mod.
+	 * @param level character level to return value
+	 * @return the baseCpMax for given character level
 	 */
-	public float getLvlHpMod()
+	public float getBaseCpMax(int level)
 	{
-		return _lvlHpMod;
+		return _baseCp[level];
 	}
 	
 	/**
-	 * @return the template level Cp add.
+	 * @param level character level to return value
+	 * @return the base HP Regeneration for given character level
 	 */
-	public float getLvlCpAdd()
+	public double getBaseHpRegen(int level)
 	{
-		return _lvlCpAdd;
+		return _baseHpReg[level];
 	}
 	
 	/**
-	 * @return the template level Cp mod.
+	 * @param level character level to return value
+	 * @return the base MP Regeneration for given character level
 	 */
-	public float getLvlCpMod()
+	public double getBaseMpRegen(int level)
 	{
-		return _lvlCpMod;
+		return _baseMpReg[level];
 	}
 	
 	/**
-	 * @return the template level Mp add.
+	 * @param level character level to return value
+	 * @return the base HP Regeneration for given character level
 	 */
-	public float getLvlMpAdd()
+	public double getBaseCpRegen(int level)
 	{
-		return _lvlMpAdd;
+		return _baseCpReg[level];
 	}
 	
 	/**
-	 * @return the template level Mp mod.
+	 * @param slotId id of inventory slot to return value
+	 * @return defence value of charactert for EMPTY given slot
 	 */
-	public float getLvlMpMod()
+	public int getBaseDefBySlot(int slotId)
 	{
-		return _lvlMpMod;
+		return _baseSlotDef.containsKey(slotId) ? _baseSlotDef.get(slotId) : 0;
 	}
 	
 	/**
-	 * @return the template collision height for male characters.
+	 * @return the template collision height for female characters.
 	 */
-	public double getFCollisionHeightMale()
+	public double getFCollisionHeightFemale()
 	{
-		return _fCollisionHeightMale;
+		return _fCollisionHeightFemale;
 	}
 	
 	/**
-	 * @return the template collision radius for male characters.
+	 * @return the template collision radius for female characters.
 	 */
-	public double getFCollisionRadiusMale()
+	public double getFCollisionRadiusFemale()
 	{
-		return _fCollisionRadiusMale;
+		return _fCollisionRadiusFemale;
 	}
 	
 	/**
-	 * @return the template collision height for female characters.
+	 * @return the safe fall height.
 	 */
-	public double getFCollisionHeightFemale()
+	public int getSafeFallHeight()
 	{
-		return _fCollisionHeightFemale;
+		return _baseSafeFallHeight;
 	}
 	
 	/**
-	 * @return the template collision radius for female characters.
+	 * @return the base slow (walk) swim speed.
 	 */
-	public double getFCollisionRadiusFemale()
+	public int getBaseSlowSwimSpd()
 	{
-		return _fCollisionRadiusFemale;
+		return _baseSlowSwimSpd;
 	}
 	
 	/**
-	 * @return the fall height.
+	 * @return the base fast (run) swim speed.
 	 */
-	public int getFallHeight()
+	public int getBaseFastSwimSpd()
 	{
-		return _fallHeight;
+		return _baseFastSwimSpd;
 	}
 	
 	/**

+ 9 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java

@@ -909,6 +909,15 @@ public abstract class Inventory extends ItemContainer
 	{
 		return _paperdoll[slot];
 	}
+
+	/**
+	 * @param slot the slot.
+	 * @return {@code true} if specified paperdoll slot is empty, {@code false} otherwise
+	 */
+	public boolean isPaperdollSlotEmpty(int slot)
+	{
+		return _paperdoll[slot] == null;
+	}
 	
 	public static int getPaperdollIndex(int slot)
 	{

+ 10 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncMDefMod.java

@@ -48,25 +48,25 @@ public class FuncMDefMod extends Func
 		if (env.getCharacter().isPlayer())
 		{
 			L2PcInstance p = env.getPlayer();
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LFINGER) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_LFINGER))
 			{
-				env.subValue(5);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_LFINGER));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RFINGER) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_RFINGER))
 			{
-				env.subValue(5);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_RFINGER));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEAR) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_LEAR))
 			{
-				env.subValue(9);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_LEAR));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_REAR) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_REAR))
 			{
-				env.subValue(9);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_REAR));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_NECK) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_NECK))
 			{
-				env.subValue(13);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_NECK));
 			}
 			env.mulValue(BaseStats.MEN.calcBonus(env.getPlayer()) * env.getPlayer().getLevelMod());
 		}

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncMoveSpeed.java

@@ -37,7 +37,7 @@ public class FuncMoveSpeed extends Func
 	
 	private FuncMoveSpeed()
 	{
-		super(Stats.RUN_SPEED, 0x30, null);
+		super(Stats.MOVE_SPEED, 0x30, null);
 	}
 	
 	@Override

+ 15 - 19
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncPDefMod.java

@@ -21,7 +21,6 @@ package com.l2jserver.gameserver.model.skills.funcs.formulas;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.itemcontainer.Inventory;
 import com.l2jserver.gameserver.model.items.L2Item;
-import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.skills.funcs.Func;
 import com.l2jserver.gameserver.model.stats.Env;
 import com.l2jserver.gameserver.model.stats.Stats;
@@ -49,38 +48,35 @@ public class FuncPDefMod extends Func
 		if (env.getCharacter().isPlayer())
 		{
 			L2PcInstance p = env.getPlayer();
-			boolean hasMagePDef = (p.getClassId().isMage() || (p.getClassId().getId() == 0x31)); // orc mystics are a special case
-			L2ItemInstance chest = p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
-			if (chest != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_CHEST))
 			{
-				env.subValue(hasMagePDef ? 15 : 31);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_CHEST));
 			}
-			if ((p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS) != null) || ((chest != null) && (chest.getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR)))
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_LEGS) || (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_CHEST) && (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST).getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR)))
 			{
-				env.subValue(hasMagePDef ? 8 : 18);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_LEGS));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_HEAD) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_HEAD))
 			{
-				env.subValue(12);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_HEAD));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_FEET) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_FEET))
 			{
-				env.subValue(7);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_FEET));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_GLOVES) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_GLOVES))
 			{
-				env.subValue(8);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_GLOVES));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_UNDER) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_UNDER))
 			{
-				env.subValue(3);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_UNDER));
 			}
-			if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_CLOAK) != null)
+			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_CLOAK))
 			{
-				env.subValue(1);
+				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_CLOAK));
 			}
-			env.addValue(4);
-			env.mulValue(env.getPlayer().getLevelMod());
+			env.mulValue(p.getLevelMod());
 		}
 		else
 		{

+ 6 - 20
L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/Formulas.java

@@ -68,11 +68,8 @@ import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMAtkCritical;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMAtkMod;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMAtkSpeed;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMDefMod;
-import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMaxCpAdd;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMaxCpMul;
-import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMaxHpAdd;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMaxHpMul;
-import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMaxMpAdd;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMaxMpMul;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncMoveSpeed;
 import com.l2jserver.gameserver.model.skills.funcs.formulas.FuncPAtkMod;
@@ -163,8 +160,9 @@ public final class Formulas
 		std[Stats.MAGIC_ATTACK_SPEED.ordinal()] = new Calculator();
 		std[Stats.MAGIC_ATTACK_SPEED.ordinal()].addFunc(FuncMAtkSpeed.getInstance());
 		
-		std[Stats.RUN_SPEED.ordinal()] = new Calculator();
-		std[Stats.RUN_SPEED.ordinal()].addFunc(FuncMoveSpeed.getInstance());
+		std[Stats.MOVE_SPEED.ordinal()] = new Calculator();
+		std[Stats.MOVE_SPEED.ordinal()].addFunc(FuncMoveSpeed.getInstance());
+
 		
 		return std;
 	}
@@ -203,11 +201,8 @@ public final class Formulas
 	{
 		if (cha.isPlayer())
 		{
-			cha.addStatFunc(FuncMaxHpAdd.getInstance());
 			cha.addStatFunc(FuncMaxHpMul.getInstance());
-			cha.addStatFunc(FuncMaxCpAdd.getInstance());
 			cha.addStatFunc(FuncMaxCpMul.getInstance());
-			cha.addStatFunc(FuncMaxMpAdd.getInstance());
 			cha.addStatFunc(FuncMaxMpMul.getInstance());
 			// cha.addStatFunc(FuncMultRegenResting.getInstance(Stats.REGENERATE_HP_RATE));
 			// cha.addStatFunc(FuncMultRegenResting.getInstance(Stats.REGENERATE_CP_RATE));
@@ -268,7 +263,7 @@ public final class Formulas
 	 */
 	public static final double calcHpRegen(L2Character cha)
 	{
-		double init = cha.getTemplate().getBaseHpReg();
+		double init = cha.isPlayer() ? cha.getActingPlayer().getTemplate().getBaseHpRegen(cha.getLevel()) : cha.getTemplate().getBaseHpReg();
 		double hpRegenMultiplier = cha.isRaid() ? Config.RAID_HP_REGEN_MULTIPLIER : Config.HP_REGEN_MULTIPLIER;
 		double hpRegenBonus = 0;
 		
@@ -281,9 +276,6 @@ public final class Formulas
 		{
 			L2PcInstance player = cha.getActingPlayer();
 			
-			// Calculate correct baseHpReg value for certain level of PC
-			init += (player.getLevel() > 10) ? ((player.getLevel() - 1) / 10.0) : 0.5;
-			
 			// SevenSigns Festival modifier
 			if (SevenSignsFestival.getInstance().isFestivalInProgress() && player.isFestivalParticipant())
 			{
@@ -392,7 +384,7 @@ public final class Formulas
 	 */
 	public static final double calcMpRegen(L2Character cha)
 	{
-		double init = cha.getTemplate().getBaseMpReg();
+		double init = cha.isPlayer() ? cha.getActingPlayer().getTemplate().getBaseMpRegen(cha.getLevel()) : cha.getTemplate().getBaseMpReg();
 		double mpRegenMultiplier = cha.isRaid() ? Config.RAID_MP_REGEN_MULTIPLIER : Config.MP_REGEN_MULTIPLIER;
 		double mpRegenBonus = 0;
 		
@@ -400,9 +392,6 @@ public final class Formulas
 		{
 			L2PcInstance player = cha.getActingPlayer();
 			
-			// Calculate correct baseMpReg value for certain level of PC
-			init += 0.3 * ((player.getLevel() - 1) / 10.0);
-			
 			// SevenSigns Festival modifier
 			if (SevenSignsFestival.getInstance().isFestivalInProgress() && player.isFestivalParticipant())
 			{
@@ -503,7 +492,7 @@ public final class Formulas
 	 */
 	public static final double calcCpRegen(L2Character cha)
 	{
-		double init = cha.getTemplate().getBaseHpReg();
+		double init = cha.isPlayer() ? cha.getActingPlayer().getTemplate().getBaseCpRegen(cha.getLevel()) : cha.getTemplate().getBaseHpReg();
 		double cpRegenMultiplier = Config.CP_REGEN_MULTIPLIER;
 		double cpRegenBonus = 0;
 		
@@ -511,9 +500,6 @@ public final class Formulas
 		{
 			L2PcInstance player = cha.getActingPlayer();
 			
-			// Calculate correct baseHpReg value for certain level of PC
-			init += (player.getLevel() > 10) ? ((player.getLevel() - 1) / 10.0) : 0.5;
-			
 			// Calculate Movement bonus
 			if (player.isSitting())
 			{

+ 33 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/MoveType.java

@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * L2J Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model.stats;
+
+/**
+ * Enum of move types.
+ * @author GKR
+ */
+public enum MoveType
+{
+	WALK,
+	RUN,
+	FAST_SWIM,
+	SLOW_SWIM,
+	FAST_FLY,
+	SLOW_FLY
+}

+ 1 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/Stats.java

@@ -93,8 +93,7 @@ public enum Stats
 	POWER_ATTACK_ANGLE("pAtkAngle"),
 	ATTACK_COUNT_MAX("atkCountMax"),
 	// Run speed, walk & escape speed are calculated proportionally, magic speed is a buff
-	RUN_SPEED("runSpd"),
-	WALK_SPEED("walkSpd"),
+	MOVE_SPEED("runSpd"),
 	
 	// BASIC STATS
 	STAT_STR("STR"),

+ 5 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/CharacterCreate.java

@@ -37,10 +37,12 @@ import com.l2jserver.gameserver.instancemanager.QuestManager;
 import com.l2jserver.gameserver.model.L2ShortCut;
 import com.l2jserver.gameserver.model.L2SkillLearn;
 import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.actor.appearance.PcAppearance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.stat.PcStat;
 import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
+import com.l2jserver.gameserver.model.base.ClassId;
 import com.l2jserver.gameserver.model.items.PcItemTemplate;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.quest.Quest;
@@ -187,7 +189,7 @@ public final class CharacterCreate extends L2GameClientPacket
 			}
 			
 			template = CharTemplateTable.getInstance().getTemplate(_classId);
-			if ((template == null) || (template.getClassBaseLevel() > 1))
+			if ((template == null) || (ClassId.getClassId(_classId).level() > 0))
 			{
 				if (Config.DEBUG)
 				{
@@ -256,9 +258,9 @@ public final class CharacterCreate extends L2GameClientPacket
 			newChar.addAdena("Init", Config.STARTING_ADENA, null, false);
 		}
 		
-		// TODO: Make it random.
 		final L2PcTemplate template = newChar.getTemplate();
-		newChar.setXYZInvisible(template.getSpawnX(), template.getSpawnY(), template.getSpawnZ());
+		Location createLoc = template.getCreationPoint();
+		newChar.setXYZInvisible(createLoc.getX(), createLoc.getY(), createLoc.getZ());
 		newChar.setTitle("");
 		
 		if (Config.ENABLE_VITALITY)

+ 3 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/AbstractNpcInfo.java

@@ -31,6 +31,7 @@ import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2NpcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.effects.AbnormalEffect;
+import com.l2jserver.gameserver.model.stats.MoveType;
 import com.l2jserver.gameserver.model.zone.ZoneId;
 
 public abstract class AbstractNpcInfo extends L2GameServerPacket
@@ -64,8 +65,8 @@ public abstract class AbstractNpcInfo extends L2GameServerPacket
 		_heading = cha.getHeading();
 		_mAtkSpd = cha.getMAtkSpd();
 		_pAtkSpd = cha.getPAtkSpd();
-		_runSpd = cha.getTemplate().getBaseRunSpd();
-		_walkSpd = cha.getTemplate().getBaseWalkSpd();
+		_runSpd = cha.getTemplate().getBaseMoveSpd(MoveType.RUN);
+		_walkSpd = cha.getTemplate().getBaseMoveSpd(MoveType.WALK);
 	}
 	
 	/**

+ 3 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/PetInfo.java

@@ -21,6 +21,7 @@ package com.l2jserver.gameserver.network.serverpackets;
 import com.l2jserver.gameserver.model.actor.L2Summon;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.stats.MoveType;
 
 public class PetInfo extends L2GameServerPacket
 {
@@ -53,8 +54,8 @@ public class PetInfo extends L2GameServerPacket
 		_mAtkSpd = _summon.getMAtkSpd();
 		_pAtkSpd = _summon.getPAtkSpd();
 		_multiplier = _summon.getMovementSpeedMultiplier();
-		_runSpd = _summon.getTemplate().getBaseRunSpd();
-		_walkSpd = _summon.getTemplate().getBaseWalkSpd();
+		_runSpd = _summon.getTemplate().getBaseMoveSpd(MoveType.RUN);
+		_walkSpd = _summon.getTemplate().getBaseMoveSpd(MoveType.WALK);
 		_swimRunSpd = _flRunSpd = _flyRunSpd = _runSpd;
 		_swimWalkSpd = _flWalkSpd = _flyWalkSpd = _walkSpd;
 		_maxHp = _summon.getMaxHp();