Browse Source

BETA: Transformations rework:
* Reworked mounts system as well:
* Removed 4th custom mount type (That's transformation not a mount!)
* Unhardcoded mount type.
* Unhardcoded Ride packet.
* Implemented retail like transformation system:
* Replacing character's default stats.
* Replacing character's default defenses.
* Replacing character's default attacking type (Bow, Fist, Sword, etc..)
* Unhardcoded water zone effect on transformations.
* Unhardcoded ExBasicActionList packet (For transformations at least).
* Thanks to: Nos
* Reviewed by: Zoey76, Nos.

Rumen Nikiforov 11 years ago
parent
commit
a9f9e88eb3
30 changed files with 1302 additions and 573 deletions
  1. 4 5
      L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java
  2. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2CharacterAI.java
  3. 247 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/TransformData.java
  4. 0 77
      L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/TransformationManager.java
  5. 8 16
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/CursedWeapon.java
  6. 0 209
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Transformation.java
  7. 45 30
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java
  8. 19 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Summon.java
  9. 83 123
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
  10. 33 7
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/CharStat.java
  11. 2 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
  12. 2 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PlayableStat.java
  13. 368 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/Transform.java
  14. 75 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/TransformLevelData.java
  15. 237 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/TransformTemplate.java
  16. 33 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/TransformType.java
  17. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCanTransform.java
  18. 1 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/BlockCheckerEngine.java
  19. 38 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/holders/AdditionalItemHolder.java
  20. 38 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/holders/AdditionalSkillHolder.java
  21. 2 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/type/L2WeaponType.java
  22. 5 5
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncMDefMod.java
  23. 8 8
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/funcs/formulas/FuncPDefMod.java
  24. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/type/L2WaterZone.java
  25. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
  26. 2 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java
  27. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestMagicSkillUse.java
  28. 2 10
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExBasicActionList.java
  29. 18 59
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/Ride.java
  30. 27 9
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/TransformEvent.java

+ 4 - 5
L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java

@@ -49,11 +49,11 @@ import com.l2jserver.gameserver.datatables.ClanTable;
 import com.l2jserver.gameserver.datatables.ClassListData;
 import com.l2jserver.gameserver.datatables.ClassListData;
 import com.l2jserver.gameserver.datatables.CrestTable;
 import com.l2jserver.gameserver.datatables.CrestTable;
 import com.l2jserver.gameserver.datatables.DoorTable;
 import com.l2jserver.gameserver.datatables.DoorTable;
-import com.l2jserver.gameserver.datatables.EnchantSkillGroupsData;
-import com.l2jserver.gameserver.datatables.EnchantItemHPBonusData;
 import com.l2jserver.gameserver.datatables.EnchantItemData;
 import com.l2jserver.gameserver.datatables.EnchantItemData;
 import com.l2jserver.gameserver.datatables.EnchantItemGroupsData;
 import com.l2jserver.gameserver.datatables.EnchantItemGroupsData;
+import com.l2jserver.gameserver.datatables.EnchantItemHPBonusData;
 import com.l2jserver.gameserver.datatables.EnchantItemOptionsData;
 import com.l2jserver.gameserver.datatables.EnchantItemOptionsData;
+import com.l2jserver.gameserver.datatables.EnchantSkillGroupsData;
 import com.l2jserver.gameserver.datatables.EventDroplist;
 import com.l2jserver.gameserver.datatables.EventDroplist;
 import com.l2jserver.gameserver.datatables.ExperienceTable;
 import com.l2jserver.gameserver.datatables.ExperienceTable;
 import com.l2jserver.gameserver.datatables.FishData;
 import com.l2jserver.gameserver.datatables.FishData;
@@ -81,6 +81,7 @@ import com.l2jserver.gameserver.datatables.SpawnTable;
 import com.l2jserver.gameserver.datatables.StaticObjects;
 import com.l2jserver.gameserver.datatables.StaticObjects;
 import com.l2jserver.gameserver.datatables.SummonSkillsTable;
 import com.l2jserver.gameserver.datatables.SummonSkillsTable;
 import com.l2jserver.gameserver.datatables.TeleportLocationTable;
 import com.l2jserver.gameserver.datatables.TeleportLocationTable;
+import com.l2jserver.gameserver.datatables.TransformData;
 import com.l2jserver.gameserver.datatables.UIData;
 import com.l2jserver.gameserver.datatables.UIData;
 import com.l2jserver.gameserver.geoeditorcon.GeoEditorListener;
 import com.l2jserver.gameserver.geoeditorcon.GeoEditorListener;
 import com.l2jserver.gameserver.handler.EffectHandler;
 import com.l2jserver.gameserver.handler.EffectHandler;
@@ -117,7 +118,6 @@ import com.l2jserver.gameserver.instancemanager.RaidBossPointsManager;
 import com.l2jserver.gameserver.instancemanager.RaidBossSpawnManager;
 import com.l2jserver.gameserver.instancemanager.RaidBossSpawnManager;
 import com.l2jserver.gameserver.instancemanager.SiegeManager;
 import com.l2jserver.gameserver.instancemanager.SiegeManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
-import com.l2jserver.gameserver.instancemanager.TransformationManager;
 import com.l2jserver.gameserver.instancemanager.WalkingManager;
 import com.l2jserver.gameserver.instancemanager.WalkingManager;
 import com.l2jserver.gameserver.instancemanager.ZoneManager;
 import com.l2jserver.gameserver.instancemanager.ZoneManager;
 import com.l2jserver.gameserver.model.AutoSpawnHandler;
 import com.l2jserver.gameserver.model.AutoSpawnHandler;
@@ -311,10 +311,10 @@ public class GameServer
 		PetitionManager.getInstance();
 		PetitionManager.getInstance();
 		AugmentationData.getInstance();
 		AugmentationData.getInstance();
 		CursedWeaponsManager.getInstance();
 		CursedWeaponsManager.getInstance();
+		TransformData.getInstance();
 		
 		
 		printSection("Scripts");
 		printSection("Scripts");
 		QuestManager.getInstance();
 		QuestManager.getInstance();
-		TransformationManager.getInstance();
 		BoatManager.getInstance();
 		BoatManager.getInstance();
 		AirShipManager.getInstance();
 		AirShipManager.getInstance();
 		GraciaSeedsManager.getInstance();
 		GraciaSeedsManager.getInstance();
@@ -338,7 +338,6 @@ public class GameServer
 		}
 		}
 		
 		
 		QuestManager.getInstance().report();
 		QuestManager.getInstance().report();
-		TransformationManager.getInstance().report();
 		
 		
 		if (Config.SAVE_DROPPED_ITEM)
 		if (Config.SAVE_DROPPED_ITEM)
 		{
 		{

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2CharacterAI.java

@@ -1083,7 +1083,7 @@ public class L2CharacterAI extends AbstractAI
 			// while flying there is no move to cast
 			// while flying there is no move to cast
 			if ((_actor.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST) && (_actor instanceof L2PcInstance) && ((L2PcInstance) _actor).isTransformed())
 			if ((_actor.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST) && (_actor instanceof L2PcInstance) && ((L2PcInstance) _actor).isTransformed())
 			{
 			{
-				if (!((L2PcInstance) _actor).getTransformation().canStartFollowToCast())
+				if (!((L2PcInstance) _actor).getTransformation().isCombat())
 				{
 				{
 					_actor.sendPacket(SystemMessageId.DIST_TOO_FAR_CASTING_STOPPED);
 					_actor.sendPacket(SystemMessageId.DIST_TOO_FAR_CASTING_STOPPED);
 					_actor.sendPacket(ActionFailed.STATIC_PACKET);
 					_actor.sendPacket(ActionFailed.STATIC_PACKET);

+ 247 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/TransformData.java

@@ -0,0 +1,247 @@
+/*
+ * 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.datatables;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import com.l2jserver.gameserver.engines.DocumentParser;
+import com.l2jserver.gameserver.model.StatsSet;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.transform.Transform;
+import com.l2jserver.gameserver.model.actor.transform.TransformLevelData;
+import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
+import com.l2jserver.gameserver.model.holders.AdditionalItemHolder;
+import com.l2jserver.gameserver.model.holders.AdditionalSkillHolder;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.network.serverpackets.ExBasicActionList;
+
+/**
+ * @author UnAfraid
+ */
+public final class TransformData extends DocumentParser
+{
+	private final Map<Integer, Transform> _transformData = new HashMap<>();
+	
+	protected TransformData()
+	{
+		load();
+	}
+	
+	@Override
+	public synchronized void load()
+	{
+		_transformData.clear();
+		parseDirectory("data/stats/transformations");
+		_log.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _transformData.size() + " transform templates.");
+	}
+	
+	@Override
+	protected void parseDocument()
+	{
+		NamedNodeMap attrs;
+		Node att;
+		StatsSet set;
+		for (Node n = getCurrentDocument().getFirstChild(); n != null; n = n.getNextSibling())
+		{
+			if ("list".equalsIgnoreCase(n.getNodeName()))
+			{
+				for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
+				{
+					if ("transform".equalsIgnoreCase(d.getNodeName()))
+					{
+						attrs = d.getAttributes();
+						set = new StatsSet();
+						for (int i = 0; i < attrs.getLength(); i++)
+						{
+							att = attrs.item(i);
+							set.set(att.getNodeName(), att.getNodeValue());
+						}
+						final Transform transform = new Transform(set);
+						for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
+						{
+							boolean isMale = "Male".equalsIgnoreCase(cd.getNodeName());
+							if ("Male".equalsIgnoreCase(cd.getNodeName()) || "Female".equalsIgnoreCase(cd.getNodeName()))
+							{
+								TransformTemplate templateData = null;
+								for (Node z = cd.getFirstChild(); z != null; z = z.getNextSibling())
+								{
+									switch (z.getNodeName())
+									{
+										case "common":
+										{
+											for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
+											{
+												switch (s.getNodeName())
+												{
+													case "base":
+													case "stats":
+													case "defense":
+													case "magicDefense":
+													case "collision":
+													case "moving":
+													{
+														attrs = s.getAttributes();
+														for (int i = 0; i < attrs.getLength(); i++)
+														{
+															att = attrs.item(i);
+															set.set(att.getNodeName(), att.getNodeValue());
+														}
+														break;
+													}
+												}
+											}
+											templateData = new TransformTemplate(set);
+											transform.setTemplate(isMale, templateData);
+											break;
+										}
+										case "skills":
+										{
+											if (templateData == null)
+											{
+												templateData = new TransformTemplate(set);
+												transform.setTemplate(isMale, templateData);
+											}
+											for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
+											{
+												if ("skill".equals(s.getNodeName()))
+												{
+													attrs = s.getAttributes();
+													int skillId = parseInt(attrs, "id");
+													int skillLevel = parseInt(attrs, "level");
+													templateData.addSkill(new SkillHolder(skillId, skillLevel));
+												}
+											}
+											break;
+										}
+										case "actions":
+										{
+											if (templateData == null)
+											{
+												templateData = new TransformTemplate(set);
+												transform.setTemplate(isMale, templateData);
+											}
+											set.set("actions", z.getTextContent());
+											final int[] actions = set.getIntegerArray("actions", " ");
+											templateData.setBasicActionList(new ExBasicActionList(actions));
+											break;
+										}
+										case "additionalSkills":
+										{
+											if (templateData == null)
+											{
+												templateData = new TransformTemplate(set);
+												transform.setTemplate(isMale, templateData);
+											}
+											for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
+											{
+												if ("skill".equals(s.getNodeName()))
+												{
+													attrs = s.getAttributes();
+													int skillId = parseInt(attrs, "id");
+													int skillLevel = parseInt(attrs, "level");
+													int minLevel = parseInt(attrs, "minLevel");
+													templateData.addAdditionalSkill(new AdditionalSkillHolder(skillId, skillLevel, minLevel));
+												}
+											}
+											break;
+										}
+										case "items":
+										{
+											if (templateData == null)
+											{
+												templateData = new TransformTemplate(set);
+												transform.setTemplate(isMale, templateData);
+											}
+											for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
+											{
+												if ("item".equals(s.getNodeName()))
+												{
+													attrs = s.getAttributes();
+													int itemId = parseInt(attrs, "id");
+													boolean allowed = parseBoolean(attrs, "allowed");
+													templateData.addAdditionalItem(new AdditionalItemHolder(itemId, allowed));
+												}
+											}
+											break;
+										}
+										case "levels":
+										{
+											if (templateData == null)
+											{
+												templateData = new TransformTemplate(set);
+												transform.setTemplate(isMale, templateData);
+											}
+											
+											final StatsSet levelsSet = new StatsSet();
+											for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
+											{
+												if ("level".equals(s.getNodeName()))
+												{
+													attrs = s.getAttributes();
+													for (int i = 0; i < attrs.getLength(); i++)
+													{
+														att = attrs.item(i);
+														levelsSet.set(att.getNodeName(), att.getNodeValue());
+													}
+												}
+											}
+											templateData.addLevelData(new TransformLevelData(levelsSet));
+											break;
+										}
+									}
+								}
+							}
+						}
+						_transformData.put(transform.getId(), transform);
+					}
+				}
+			}
+		}
+	}
+	
+	public Transform getTransform(int id)
+	{
+		return _transformData.get(id);
+	}
+	
+	public boolean transformPlayer(int id, L2PcInstance player)
+	{
+		final Transform transform = getTransform(id);
+		if (transform != null)
+		{
+			player.transform(transform);
+		}
+		return transform != null;
+	}
+	
+	public static TransformData getInstance()
+	{
+		return SingletonHolder._instance;
+	}
+	
+	private static class SingletonHolder
+	{
+		protected static final TransformData _instance = new TransformData();
+	}
+}

+ 0 - 77
L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/TransformationManager.java

@@ -1,77 +0,0 @@
-/*
- * 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.instancemanager;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import com.l2jserver.gameserver.model.L2Transformation;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
-/**
- * @author KenM
- */
-public class TransformationManager
-{
-	private static final Logger _log = Logger.getLogger(TransformationManager.class.getName());
-	
-	private final Map<Integer, L2Transformation> _transformations = new HashMap<>();
-	
-	protected TransformationManager()
-	{
-	}
-	
-	public void report()
-	{
-		_log.info(getClass().getSimpleName() + ": Loaded: " + _transformations.size() + " transformations.");
-	}
-	
-	public boolean transformPlayer(int id, L2PcInstance player)
-	{
-		L2Transformation template = getTransformationById(id);
-		if (template != null)
-		{
-			L2Transformation trans = template.createTransformationForPlayer(player);
-			trans.start();
-			return true;
-		}
-		return false;
-	}
-	
-	public L2Transformation getTransformationById(int id)
-	{
-		return _transformations.get(id);
-	}
-	
-	public L2Transformation registerTransformation(L2Transformation transformation)
-	{
-		return _transformations.put(transformation.getId(), transformation);
-	}
-	
-	public static TransformationManager getInstance()
-	{
-		return SingletonHolder._instance;
-	}
-	
-	private static class SingletonHolder
-	{
-		protected static final TransformationManager _instance = new TransformationManager();
-	}
-}

+ 8 - 16
L2J_Server_BETA/java/com/l2jserver/gameserver/model/CursedWeapon.java

@@ -29,8 +29,9 @@ import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.datatables.SkillTable;
 import com.l2jserver.gameserver.datatables.SkillTable;
+import com.l2jserver.gameserver.datatables.SkillTable.FrequentSkill;
+import com.l2jserver.gameserver.datatables.TransformData;
 import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
 import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
-import com.l2jserver.gameserver.instancemanager.TransformationManager;
 import com.l2jserver.gameserver.model.L2Party.messageType;
 import com.l2jserver.gameserver.model.L2Party.messageType;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Character;
@@ -83,12 +84,6 @@ public class CursedWeapon
 	private int _playerPkKills = 0;
 	private int _playerPkKills = 0;
 	protected int transformationId = 0;
 	protected int transformationId = 0;
 	
 	
-	private static final int[] TRANSFORM_IDS = new int[]
-	{
-		3630,
-		3631
-	};
-	
 	public CursedWeapon(int itemId, int skillId, String name)
 	public CursedWeapon(int itemId, int skillId, String name)
 	{
 	{
 		_name = name;
 		_name = name;
@@ -342,15 +337,12 @@ public class CursedWeapon
 		_player.addSkill(skill, false);
 		_player.addSkill(skill, false);
 		
 		
 		// Void Burst, Void Flow
 		// Void Burst, Void Flow
-		skill = SkillTable.FrequentSkill.VOID_BURST.getSkill();
+		skill = FrequentSkill.VOID_BURST.getSkill();
 		_player.addSkill(skill, false);
 		_player.addSkill(skill, false);
-		skill = SkillTable.FrequentSkill.VOID_FLOW.getSkill();
+		skill = FrequentSkill.VOID_FLOW.getSkill();
 		_player.addSkill(skill, false);
 		_player.addSkill(skill, false);
-		_player.setTransformAllowedSkills(TRANSFORM_IDS);
-		if (Config.DEBUG)
-		{
-			_log.info("Player " + _player.getName() + " has been awarded with skill " + skill);
-		}
+		_player.addTransformSkill(FrequentSkill.VOID_BURST.getId());
+		_player.addTransformSkill(FrequentSkill.VOID_FLOW.getId());
 		_player.sendSkillList();
 		_player.sendSkillList();
 	}
 	}
 	
 	
@@ -374,13 +366,13 @@ public class CursedWeapon
 				@Override
 				@Override
 				public void run()
 				public void run()
 				{
 				{
-					TransformationManager.getInstance().transformPlayer(transformationId, _player);
+					TransformData.getInstance().transformPlayer(transformationId, _player);
 				}
 				}
 			}, 500);
 			}, 500);
 		}
 		}
 		else
 		else
 		{
 		{
-			TransformationManager.getInstance().transformPlayer(transformationId, _player);
+			TransformData.getInstance().transformPlayer(transformationId, _player);
 		}
 		}
 	}
 	}
 	
 	

+ 0 - 209
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Transformation.java

@@ -1,209 +0,0 @@
-/*
- * 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;
-
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
-/**
- * @author KenM
- */
-public abstract class L2Transformation implements Cloneable, Runnable
-{
-	private final int _id;
-	private final int _graphicalId;
-	private double _collisionRadius;
-	private double _collisionHeight;
-	private final boolean _isStance;
-	
-	public static final int TRANSFORM_ZARICHE = 301;
-	public static final int TRANSFORM_AKAMANAH = 302;
-	
-	protected static final int[] EMPTY_ARRAY = {};
-	
-	private L2PcInstance _player;
-	
-	/**
-	 * @param id Internal id that server will use to associate this transformation
-	 * @param graphicalId Client visible transformation id
-	 * @param collisionRadius Collision Radius of the player while transformed
-	 * @param collisionHeight Collision Height of the player while transformed
-	 */
-	public L2Transformation(int id, int graphicalId, double collisionRadius, double collisionHeight)
-	{
-		_id = id;
-		_graphicalId = graphicalId;
-		_collisionRadius = collisionRadius;
-		_collisionHeight = collisionHeight;
-		_isStance = false;
-	}
-	
-	/**
-	 * @param id Internal id(will be used also as client graphical id) that server will use to associate this transformation
-	 * @param collisionRadius Collision Radius of the player while transformed
-	 * @param collisionHeight Collision Height of the player while transformed
-	 */
-	public L2Transformation(int id, double collisionRadius, double collisionHeight)
-	{
-		this(id, id, collisionRadius, collisionHeight);
-	}
-	
-	/**
-	 * @param id Internal id(will be used also as client graphical id) that server will use to associate this transformation Used for stances
-	 */
-	public L2Transformation(int id)
-	{
-		_id = id;
-		_graphicalId = id;
-		_isStance = true;
-	}
-	
-	/**
-	 * @return Returns the id.
-	 */
-	public int getId()
-	{
-		return _id;
-	}
-	
-	/**
-	 * @return Returns the graphicalId.
-	 */
-	public int getGraphicalId()
-	{
-		return _graphicalId;
-	}
-	
-	/**
-	 * Return true if this is a stance (vanguard/inquisitor)
-	 * @return
-	 */
-	public boolean isStance()
-	{
-		return _isStance;
-	}
-	
-	/**
-	 * @return Returns the collisionRadius.
-	 */
-	public double getCollisionRadius()
-	{
-		if (isStance())
-		{
-			return _player.getCollisionRadius();
-		}
-		return _collisionRadius;
-	}
-	
-	/**
-	 * @return Returns the collisionHeight.
-	 */
-	public double getCollisionHeight()
-	{
-		if (isStance())
-		{
-			return _player.getCollisionHeight();
-		}
-		return _collisionHeight;
-	}
-	
-	// Scriptable Events
-	public abstract void onTransform();
-	
-	public abstract void onUntransform();
-	
-	/**
-	 * @param player The player to set.
-	 */
-	private void setPlayer(L2PcInstance player)
-	{
-		_player = player;
-	}
-	
-	/**
-	 * @return Returns the player.
-	 */
-	public L2PcInstance getPlayer()
-	{
-		return _player;
-	}
-	
-	public void start()
-	{
-		resume();
-	}
-	
-	public void resume()
-	{
-		getPlayer().transform(this);
-	}
-	
-	@Override
-	public void run()
-	{
-		stop();
-	}
-	
-	public void stop()
-	{
-		getPlayer().untransform();
-	}
-	
-	public L2Transformation createTransformationForPlayer(L2PcInstance player)
-	{
-		try
-		{
-			L2Transformation transformation = (L2Transformation) clone();
-			transformation.setPlayer(player);
-			return transformation;
-		}
-		catch (CloneNotSupportedException e)
-		{
-			// should never happen
-			return null;
-		}
-	}
-	
-	// Override if necessary
-	public void onLevelUp()
-	{
-		
-	}
-	
-	/**
-	 * @return true if transformation can do melee attack
-	 */
-	public boolean canDoMeleeAttack()
-	{
-		return true;
-	}
-	
-	/**
-	 * @return true if transformation can start follow target when trying to cast an skill out of range
-	 */
-	public boolean canStartFollowToCast()
-	{
-		return true;
-	}
-	
-	@Override
-	public String toString()
-	{
-		return getClass().getSimpleName() + " [_id=" + _id + ", _graphicalId=" + _graphicalId + ", _collisionRadius=" + _collisionRadius + ", _collisionHeight=" + _collisionHeight + ", _isStance=" + _isStance + "]";
-	}
-}

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

@@ -81,6 +81,8 @@ import com.l2jserver.gameserver.model.actor.tasks.character.QueuedMagicUseTask;
 import com.l2jserver.gameserver.model.actor.tasks.character.UsePotionTask;
 import com.l2jserver.gameserver.model.actor.tasks.character.UsePotionTask;
 import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
 import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.actor.transform.Transform;
+import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
 import com.l2jserver.gameserver.model.effects.AbnormalEffect;
 import com.l2jserver.gameserver.model.effects.AbnormalEffect;
 import com.l2jserver.gameserver.model.effects.EffectFlag;
 import com.l2jserver.gameserver.model.effects.EffectFlag;
 import com.l2jserver.gameserver.model.effects.L2Effect;
 import com.l2jserver.gameserver.model.effects.L2Effect;
@@ -343,6 +345,11 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		return false;
 		return false;
 	}
 	}
 	
 	
+	public Transform getTransformation()
+	{
+		return null;
+	}
+	
 	/**
 	/**
 	 * This will untransform a player if they are an instance of L2Pcinstance and if they are transformed.
 	 * This will untransform a player if they are an instance of L2Pcinstance and if they are transformed.
 	 */
 	 */
@@ -801,7 +808,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 				
 				
 				L2PcInstance actor = getActingPlayer();
 				L2PcInstance actor = getActingPlayer();
 				// Players riding wyvern or with special (flying) transformations can do melee attacks, only with skills
 				// Players riding wyvern or with special (flying) transformations can do melee attacks, only with skills
-				if ((actor.isMounted() && (actor.getMountNpcId() == 12621)) || (actor.isTransformed() && !actor.getTransformation().canDoMeleeAttack()))
+				if ((actor.isMounted() && (actor.getMountNpcId() == 12621)) || (actor.isTransformed() && !actor.getTransformation().canAttack()))
 				{
 				{
 					sendPacket(ActionFailed.STATIC_PACKET);
 					sendPacket(ActionFailed.STATIC_PACKET);
 					return;
 					return;
@@ -1047,36 +1054,41 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		
 		
 		// Get the Attack Reuse Delay of the L2Weapon
 		// Get the Attack Reuse Delay of the L2Weapon
 		int reuse = calculateReuseTime(target, weaponItem);
 		int reuse = calculateReuseTime(target, weaponItem);
-		boolean hitted;
-		// Select the type of attack to start
-		if ((weaponItem == null) || isTransformed())
-		{
-			hitted = doAttackHitSimple(attack, target, timeToHit);
-		}
-		else if (weaponItem.getItemType() == L2WeaponType.BOW)
-		{
-			hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
-		}
-		else if (weaponItem.getItemType() == L2WeaponType.CROSSBOW)
-		{
-			hitted = doAttackHitByCrossBow(attack, target, timeAtk, reuse);
-		}
-		else if (weaponItem.getItemType() == L2WeaponType.POLE)
-		{
-			hitted = doAttackHitByPole(attack, target, timeToHit);
-		}
-		else if (isUsingDualWeapon())
-		{
-			hitted = doAttackHitByDual(attack, target, timeToHit);
-		}
-		else
+		
+		boolean hitted = false;
+		switch (getAttackType())
 		{
 		{
-			hitted = doAttackHitSimple(attack, target, timeToHit);
+			case BOW:
+			{
+				hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
+				break;
+			}
+			case CROSSBOW:
+			{
+				hitted = doAttackHitByCrossBow(attack, target, timeAtk, reuse);
+				break;
+			}
+			case POLE:
+			{
+				hitted = doAttackHitByPole(attack, target, timeToHit);
+				break;
+			}
+			case DUAL:
+			case DUALFIST:
+			case DUALDAGGER:
+			{
+				doAttackHitByDual(attack, target, timeToHit);
+				break;
+			}
+			default:
+			{
+				hitted = doAttackHitSimple(attack, target, timeToHit);
+				break;
+			}
 		}
 		}
 		
 		
 		// Flag the attacker if it's a L2PcInstance outside a PvP area
 		// Flag the attacker if it's a L2PcInstance outside a PvP area
-		L2PcInstance player = getActingPlayer();
-		
+		final L2PcInstance player = getActingPlayer();
 		if (player != null)
 		if (player != null)
 		{
 		{
 			AttackStanceTaskManager.getInstance().addAttackStanceTask(player);
 			AttackStanceTaskManager.getInstance().addAttackStanceTask(player);
@@ -7338,7 +7350,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		attacker.getEvents().onDamageDealt(damage, this, skill, critical);
 		attacker.getEvents().onDamageDealt(damage, this, skill, critical);
 	}
 	}
 	
 	
-	public L2WeaponType getAttackType()
+	public final L2WeaponType getAttackType()
 	{
 	{
 		final L2Weapon weapon = getActiveWeaponItem();
 		final L2Weapon weapon = getActiveWeaponItem();
 		if (weapon != null)
 		if (weapon != null)
@@ -7347,8 +7359,11 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		}
 		}
 		else if (isTransformed())
 		else if (isTransformed())
 		{
 		{
-			// TODO: implement me.
-			// return getTransform().getBaseAttackType();
+			final TransformTemplate template = getTransformation().getTemplate(getActingPlayer());
+			if (template != null)
+			{
+				return template.getBaseAttackType();
+			}
 		}
 		}
 		return getTemplate().getBaseAttackType();
 		return getTemplate().getBaseAttackType();
 	}
 	}

+ 19 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Summon.java

@@ -23,11 +23,13 @@ import com.l2jserver.gameserver.GameTimeController;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.ai.L2CharacterAI;
 import com.l2jserver.gameserver.ai.L2CharacterAI;
 import com.l2jserver.gameserver.ai.L2SummonAI;
 import com.l2jserver.gameserver.ai.L2SummonAI;
+import com.l2jserver.gameserver.datatables.CategoryData;
 import com.l2jserver.gameserver.datatables.ExperienceTable;
 import com.l2jserver.gameserver.datatables.ExperienceTable;
 import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.handler.IItemHandler;
 import com.l2jserver.gameserver.handler.IItemHandler;
 import com.l2jserver.gameserver.handler.ItemHandler;
 import com.l2jserver.gameserver.handler.ItemHandler;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
+import com.l2jserver.gameserver.model.CategoryType;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.L2Party;
 import com.l2jserver.gameserver.model.L2Party;
 import com.l2jserver.gameserver.model.L2WorldRegion;
 import com.l2jserver.gameserver.model.L2WorldRegion;
@@ -1221,4 +1223,21 @@ public abstract class L2Summon extends L2Playable
 	{
 	{
 		return (getOwner() != null) ? getOwner().getAllyId() : 0;
 		return (getOwner() != null) ? getOwner().getAllyId() : 0;
 	}
 	}
+	
+	public final int getMountType()
+	{
+		if (CategoryData.getInstance().isInCategory(CategoryType.STRIDER, getNpcId()))
+		{
+			return 1;
+		}
+		else if (CategoryData.getInstance().isInCategory(CategoryType.WYVERN_GROUP, getNpcId()))
+		{
+			return 2;
+		}
+		else if (CategoryData.getInstance().isInCategory(CategoryType.WOLF_GROUP, getNpcId()))
+		{
+			return 3;
+		}
+		return 0;
+	}
 }
 }

+ 83 - 123
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -29,6 +29,7 @@ import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.List;
@@ -123,7 +124,6 @@ import com.l2jserver.gameserver.model.L2RecipeList;
 import com.l2jserver.gameserver.model.L2Request;
 import com.l2jserver.gameserver.model.L2Request;
 import com.l2jserver.gameserver.model.L2ShortCut;
 import com.l2jserver.gameserver.model.L2ShortCut;
 import com.l2jserver.gameserver.model.L2SkillLearn;
 import com.l2jserver.gameserver.model.L2SkillLearn;
-import com.l2jserver.gameserver.model.L2Transformation;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.L2WorldRegion;
 import com.l2jserver.gameserver.model.L2WorldRegion;
 import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.Location;
@@ -175,6 +175,7 @@ import com.l2jserver.gameserver.model.actor.tasks.player.VitalityTask;
 import com.l2jserver.gameserver.model.actor.tasks.player.WarnUserTakeBreakTask;
 import com.l2jserver.gameserver.model.actor.tasks.player.WarnUserTakeBreakTask;
 import com.l2jserver.gameserver.model.actor.tasks.player.WaterTask;
 import com.l2jserver.gameserver.model.actor.tasks.player.WaterTask;
 import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
 import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
+import com.l2jserver.gameserver.model.actor.transform.Transform;
 import com.l2jserver.gameserver.model.base.ClassId;
 import com.l2jserver.gameserver.model.base.ClassId;
 import com.l2jserver.gameserver.model.base.ClassLevel;
 import com.l2jserver.gameserver.model.base.ClassLevel;
 import com.l2jserver.gameserver.model.base.PlayerClass;
 import com.l2jserver.gameserver.model.base.PlayerClass;
@@ -248,7 +249,6 @@ import com.l2jserver.gameserver.network.serverpackets.CharInfo;
 import com.l2jserver.gameserver.network.serverpackets.ConfirmDlg;
 import com.l2jserver.gameserver.network.serverpackets.ConfirmDlg;
 import com.l2jserver.gameserver.network.serverpackets.EtcStatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.EtcStatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.ExAutoSoulShot;
 import com.l2jserver.gameserver.network.serverpackets.ExAutoSoulShot;
-import com.l2jserver.gameserver.network.serverpackets.ExBasicActionList;
 import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExDominionWarStart;
 import com.l2jserver.gameserver.network.serverpackets.ExDominionWarStart;
 import com.l2jserver.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
@@ -558,7 +558,7 @@ public final class L2PcInstance extends L2Playable
 	
 	
 	private long _offlineShopStart = 0;
 	private long _offlineShopStart = 0;
 	
 	
-	private L2Transformation _transformation;
+	private Transform _transformation;
 	private int _transformationId = 0;
 	private int _transformationId = 0;
 	
 	
 	/** The table containing all L2RecipeList of the L2PcInstance */
 	/** The table containing all L2RecipeList of the L2PcInstance */
@@ -791,7 +791,7 @@ public final class L2PcInstance extends L2Playable
 	private int _fishy = 0;
 	private int _fishy = 0;
 	private int _fishz = 0;
 	private int _fishz = 0;
 	
 	
-	private int[] _transformAllowedSkills = {};
+	private Set<Integer> _transformAllowedSkills;
 	private ScheduledFuture<?> _taskRentPet;
 	private ScheduledFuture<?> _taskRentPet;
 	private ScheduledFuture<?> _taskWater;
 	private ScheduledFuture<?> _taskWater;
 	
 	
@@ -823,9 +823,6 @@ public final class L2PcInstance extends L2Playable
 	private double _mpUpdateDecCheck = .0;
 	private double _mpUpdateDecCheck = .0;
 	private double _mpUpdateInterval = .0;
 	private double _mpUpdateInterval = .0;
 	
 	
-	private boolean _isRidingStrider = false;
-	private boolean _isFlyingMounted = false;
-	
 	/** Char Coords from Client */
 	/** Char Coords from Client */
 	private int _clientX;
 	private int _clientX;
 	private int _clientY;
 	private int _clientY;
@@ -1256,6 +1253,20 @@ public final class L2PcInstance extends L2Playable
 		return getStat().getLevel();
 		return getStat().getLevel();
 	}
 	}
 	
 	
+	@Override
+	public double getLevelMod()
+	{
+		if (isTransformed())
+		{
+			double levelMod = getTransformation().getLevelMod(this);
+			if (levelMod > -1)
+			{
+				return levelMod;
+			}
+		}
+		return super.getLevelMod();
+	}
+	
 	/**
 	/**
 	 * @return the _newbie rewards state of the L2PcInstance.
 	 * @return the _newbie rewards state of the L2PcInstance.
 	 */
 	 */
@@ -5020,7 +5031,7 @@ public final class L2PcInstance extends L2Playable
 		return (_transformation != null) && _transformation.isStance();
 		return (_transformation != null) && _transformation.isStance();
 	}
 	}
 	
 	
-	public void transform(L2Transformation transformation)
+	public void transform(Transform transformation)
 	{
 	{
 		if (_transformation != null)
 		if (_transformation != null)
 		{
 		{
@@ -5029,6 +5040,7 @@ public final class L2PcInstance extends L2Playable
 			sendPacket(msg);
 			sendPacket(msg);
 			return;
 			return;
 		}
 		}
+		
 		if (!fireTransformListeners(transformation, true))
 		if (!fireTransformListeners(transformation, true))
 		{
 		{
 			return;
 			return;
@@ -5043,15 +5055,14 @@ public final class L2PcInstance extends L2Playable
 		
 		
 		_transformation = transformation;
 		_transformation = transformation;
 		stopAllToggles();
 		stopAllToggles();
-		transformation.onTransform();
+		transformation.onTransform(this);
 		sendSkillList();
 		sendSkillList();
 		sendPacket(new SkillCoolTime(this));
 		sendPacket(new SkillCoolTime(this));
-		sendPacket(ExBasicActionList.getStaticPacket(this));
 		broadcastUserInfo();
 		broadcastUserInfo();
 	}
 	}
 	
 	
 	@Override
 	@Override
-	public synchronized void untransform()
+	public void untransform()
 	{
 	{
 		if (_transformation != null)
 		if (_transformation != null)
 		{
 		{
@@ -5060,18 +5071,17 @@ public final class L2PcInstance extends L2Playable
 				return;
 				return;
 			}
 			}
 			setQueuedSkill(null, false, false);
 			setQueuedSkill(null, false, false);
-			setTransformAllowedSkills(new int[] {});
-			_transformation.onUntransform();
+			_transformation.onUntransform(this);
 			_transformation = null;
 			_transformation = null;
 			stopEffects(L2EffectType.TRANSFORMATION);
 			stopEffects(L2EffectType.TRANSFORMATION);
 			sendSkillList();
 			sendSkillList();
 			sendPacket(new SkillCoolTime(this));
 			sendPacket(new SkillCoolTime(this));
-			sendPacket(ExBasicActionList.getStaticPacket(this));
 			broadcastUserInfo();
 			broadcastUserInfo();
 		}
 		}
 	}
 	}
 	
 	
-	public L2Transformation getTransformation()
+	@Override
+	public Transform getTransformation()
 	{
 	{
 		return _transformation;
 		return _transformation;
 	}
 	}
@@ -5082,16 +5092,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	 */
 	public int getTransformationId()
 	public int getTransformationId()
 	{
 	{
-		return (_transformation == null ? 0 : _transformation.getId());
-	}
-	
-	/**
-	 * This returns the transformation Id stored inside the character table, selected by the method: transformSelectInfo() For example, if a player is transformed as a Buffalo, and then picks up the Zariche, the transform Id returned will be that of the Buffalo, and NOT the Zariche.
-	 * @return Transformation Id
-	 */
-	public int transformId()
-	{
-		return _transformationId;
+		return (isTransformed() ? getTransformation().getId() : 0);
 	}
 	}
 	
 	
 	/**
 	/**
@@ -5099,13 +5100,12 @@ public final class L2PcInstance extends L2Playable
 	 */
 	 */
 	public void transformInsertInfo()
 	public void transformInsertInfo()
 	{
 	{
-		_transformationId = getTransformationId();
-		
-		if ((_transformationId == L2Transformation.TRANSFORM_AKAMANAH) || (_transformationId == L2Transformation.TRANSFORM_ZARICHE))
+		if (isTransformed() && getTransformation().isCursed())
 		{
 		{
 			return;
 			return;
 		}
 		}
 		
 		
+		_transformationId = getTransformationId();
 		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
 		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement = con.prepareStatement(UPDATE_CHAR_TRANSFORM))
 			PreparedStatement statement = con.prepareStatement(UPDATE_CHAR_TRANSFORM))
 		{
 		{
@@ -6744,12 +6744,11 @@ public final class L2PcInstance extends L2Playable
 		}
 		}
 		
 		
 		stopAllToggles();
 		stopAllToggles();
-		Ride mount = new Ride(this, true, pet.getTemplate().getNpcId());
-		setMount(pet.getNpcId(), pet.getLevel(), mount.getMountType());
+		setMount(pet.getNpcId(), pet.getLevel(), pet.getMountType());
 		setMountObjectID(pet.getControlObjectId());
 		setMountObjectID(pet.getControlObjectId());
 		clearPetData();
 		clearPetData();
 		startFeed(pet.getNpcId());
 		startFeed(pet.getNpcId());
-		broadcastPacket(mount);
+		broadcastPacket(new Ride(this));
 		
 		
 		// Notify self and others about speed change
 		// Notify self and others about speed change
 		broadcastUserInfo();
 		broadcastUserInfo();
@@ -6759,7 +6758,7 @@ public final class L2PcInstance extends L2Playable
 		return true;
 		return true;
 	}
 	}
 	
 	
-	public boolean mount(int npcId, int controlItemObjId, boolean useFood)
+	public boolean mount(int npcId, int type, int controlItemObjId, boolean useFood)
 	{
 	{
 		if (!disarmWeapons())
 		if (!disarmWeapons())
 		{
 		{
@@ -6775,22 +6774,18 @@ public final class L2PcInstance extends L2Playable
 		}
 		}
 		
 		
 		stopAllToggles();
 		stopAllToggles();
-		Ride mount = new Ride(this, true, npcId);
-		if (setMount(npcId, getLevel(), mount.getMountType()))
+		setMount(npcId, getLevel(), type);
+		clearPetData();
+		setMountObjectID(controlItemObjId);
+		broadcastPacket(new Ride(this));
+		
+		// Notify self and others about speed change
+		broadcastUserInfo();
+		if (useFood)
 		{
 		{
-			clearPetData();
-			setMountObjectID(controlItemObjId);
-			broadcastPacket(mount);
-			
-			// Notify self and others about speed change
-			broadcastUserInfo();
-			if (useFood)
-			{
-				startFeed(npcId);
-			}
-			return true;
+			startFeed(npcId);
 		}
 		}
-		return false;
+		return true;
 	}
 	}
 	
 	
 	public boolean mountPlayer(L2Summon pet)
 	public boolean mountPlayer(L2Summon pet)
@@ -6902,23 +6897,19 @@ public final class L2PcInstance extends L2Playable
 		
 		
 		sendPacket(new SetupGauge(3, 0, 0));
 		sendPacket(new SetupGauge(3, 0, 0));
 		int petId = _mountNpcId;
 		int petId = _mountNpcId;
-		if (setMount(0, 0, 0))
+		setMount(0, 0, 0);
+		stopFeed();
+		clearPetData();
+		if (wasFlying)
 		{
 		{
-			stopFeed();
-			clearPetData();
-			if (wasFlying)
-			{
-				removeSkill(SkillTable.FrequentSkill.WYVERN_BREATH.getSkill());
-			}
-			Ride dismount = new Ride(this, false, 0);
-			broadcastPacket(dismount);
-			setMountObjectID(0);
-			storePetFood(petId);
-			// Notify self and others about speed change
-			broadcastUserInfo();
-			return true;
+			removeSkill(SkillTable.FrequentSkill.WYVERN_BREATH.getSkill());
 		}
 		}
-		return false;
+		broadcastPacket(new Ride(this));
+		setMountObjectID(0);
+		storePetFood(petId);
+		// Notify self and others about speed change
+		broadcastUserInfo();
+		return true;
 	}
 	}
 	
 	
 	public void setUptime(long time)
 	public void setUptime(long time)
@@ -8107,7 +8098,7 @@ public final class L2PcInstance extends L2Playable
 			}
 			}
 		}
 		}
 		
 		
-		if ((transformId() > 0) || isCursedWeaponEquipped())
+		if ((getTransformationId() > 0) || isCursedWeaponEquipped())
 		{
 		{
 			return oldSkill;
 			return oldSkill;
 		}
 		}
@@ -9453,10 +9444,6 @@ public final class L2PcInstance extends L2Playable
 		return _mountType > 0;
 		return _mountType > 0;
 	}
 	}
 	
 	
-	/**
-	 * Set the type of Pet mounted (0 : none, 1 : Strider, 2 : Wyvern) and send a Server->Client packet InventoryUpdate to the L2PcInstance.
-	 * @return
-	 */
 	public boolean checkLandingState()
 	public boolean checkLandingState()
 	{
 	{
 		// Check if char is in a no landing zone
 		// Check if char is in a no landing zone
@@ -9477,40 +9464,33 @@ public final class L2PcInstance extends L2Playable
 	}
 	}
 	
 	
 	// returns false if the change of mount type fails.
 	// returns false if the change of mount type fails.
-	public boolean setMount(int npcId, int npcLevel, int mountType)
+	public void setMount(int npcId, int npcLevel, int mountType)
 	{
 	{
 		switch (mountType)
 		switch (mountType)
 		{
 		{
-			case 0:
+			case 0: // None
+			{
 				setIsFlying(false);
 				setIsFlying(false);
-				/*
-				 * not used any more setIsRidingFenrirWolf(false); setIsRidingWFenrirWolf(false); setIsRidingGreatSnowWolf(false);
-				 */
-				setIsRidingStrider(false);
-				break; // Dismounted
-			case 1:
-				setIsRidingStrider(true);
+				break;
+			}
+			case 1: // Strider
+			{
 				if (isNoble())
 				if (isNoble())
 				{
 				{
-					L2Skill striderAssaultSkill = SkillTable.FrequentSkill.STRIDER_SIEGE_ASSAULT.getSkill();
-					addSkill(striderAssaultSkill, false); // not saved to DB
+					addSkill(FrequentSkill.STRIDER_SIEGE_ASSAULT.getSkill(), false);
 				}
 				}
 				break;
 				break;
-			case 2:
+			}
+			case 2: // Wyvern
+			{
 				setIsFlying(true);
 				setIsFlying(true);
-				break; // Flying Wyvern
-			case 3:
-				/*
-				 * not used any more switch (npcId) { case 16041: setIsRidingFenrirWolf(true); break; case 16042: setIsRidingWFenrirWolf(true); break; case 16037: setIsRidingGreatSnowWolf(true); break; }
-				 */
 				break;
 				break;
+			}
 		}
 		}
 		
 		
 		_mountType = mountType;
 		_mountType = mountType;
 		_mountNpcId = npcId;
 		_mountNpcId = npcId;
 		_mountLevel = npcLevel;
 		_mountLevel = npcLevel;
-		
-		return true;
 	}
 	}
 	
 	
 	/**
 	/**
@@ -10380,7 +10360,7 @@ public final class L2PcInstance extends L2Playable
 				continue;
 				continue;
 			}
 			}
 			
 			
-			if ((_transformation != null) && (!containsAllowedTransformSkill(s.getId()) && !s.allowOnTransform()))
+			if ((_transformation != null) && (!hasTransformSkill(s.getId()) && !s.allowOnTransform()))
 			{
 			{
 				continue;
 				continue;
 			}
 			}
@@ -12709,16 +12689,6 @@ public final class L2PcInstance extends L2Playable
 		_combatFlagEquippedId = value;
 		_combatFlagEquippedId = value;
 	}
 	}
 	
 	
-	public final void setIsRidingStrider(boolean mode)
-	{
-		_isRidingStrider = mode;
-	}
-	
-	public final boolean isRidingStrider()
-	{
-		return _isRidingStrider;
-	}
-	
 	/**
 	/**
 	 * Returns the Number of Souls this L2PcInstance got.
 	 * Returns the Number of Souls this L2PcInstance got.
 	 * @return
 	 * @return
@@ -13147,21 +13117,23 @@ public final class L2PcInstance extends L2Playable
 		}
 		}
 	}
 	}
 	
 	
-	public void setTransformAllowedSkills(int[] ids)
+	public void addTransformSkill(int id)
 	{
 	{
-		_transformAllowedSkills = ids;
+		if (_transformAllowedSkills == null)
+		{
+			_transformAllowedSkills = new HashSet<>();
+		}
+		_transformAllowedSkills.add(id);
 	}
 	}
 	
 	
-	public boolean containsAllowedTransformSkill(int id)
+	public boolean hasTransformSkill(int id)
 	{
 	{
-		for (int _transformAllowedSkill : _transformAllowedSkills)
-		{
-			if (_transformAllowedSkill == id)
-			{
-				return true;
-			}
-		}
-		return false;
+		return (_transformAllowedSkills != null) && _transformAllowedSkills.contains(id);
+	}
+	
+	public synchronized void removeAllTransformSkills()
+	{
+		_transformAllowedSkills = null;
 	}
 	}
 	
 	
 	protected void startFeed(int npcId)
 	protected void startFeed(int npcId)
@@ -13353,13 +13325,7 @@ public final class L2PcInstance extends L2Playable
 	
 	
 	public boolean isFlyingMounted()
 	public boolean isFlyingMounted()
 	{
 	{
-		return _isFlyingMounted;
-	}
-	
-	public void setIsFlyingMounted(boolean val)
-	{
-		_isFlyingMounted = val;
-		setIsFlying(val);
+		return (isTransformed() && (getTransformation().isFlying()));
 	}
 	}
 	
 	
 	/**
 	/**
@@ -13746,12 +13712,6 @@ public final class L2PcInstance extends L2Playable
 				}
 				}
 			}
 			}
 		}
 		}
-		if (getMountType() == 4)
-		{
-			// TODO: Remove when horse mounts fixed
-			activeChar.sendPacket(new Ride(this, false, 0));
-			activeChar.sendPacket(new Ride(this, true, getMountNpcId()));
-		}
 		
 		
 		switch (getPrivateStoreType())
 		switch (getPrivateStoreType())
 		{
 		{
@@ -14016,12 +13976,12 @@ public final class L2PcInstance extends L2Playable
 	
 	
 	public double getCollisionRadius()
 	public double getCollisionRadius()
 	{
 	{
-		return isMounted() ? (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(this) : (getAppearance().getSex() ? getBaseTemplate().getFCollisionRadiusFemale() : getBaseTemplate().getfCollisionRadius()));
 	}
 	}
 	
 	
 	public double getCollisionHeight()
 	public double getCollisionHeight()
 	{
 	{
-		return isMounted() ? (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(this) : (getAppearance().getSex() ? getBaseTemplate().getFCollisionHeightFemale() : getBaseTemplate().getfCollisionHeight()));
 	}
 	}
 	
 	
 	public final int getClientX()
 	public final int getClientX()
@@ -14739,7 +14699,7 @@ public final class L2PcInstance extends L2Playable
 	 * @param isTransforming
 	 * @param isTransforming
 	 * @return
 	 * @return
 	 */
 	 */
-	private boolean fireTransformListeners(L2Transformation transformation, boolean isTransforming)
+	private boolean fireTransformListeners(Transform transformation, boolean isTransforming)
 	{
 	{
 		if ((transformation != null) && !_transformListeners.isEmpty())
 		if ((transformation != null) && !_transformListeners.isEmpty())
 		{
 		{

+ 33 - 7
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/CharStat.java

@@ -24,6 +24,7 @@ import com.l2jserver.Config;
 import com.l2jserver.gameserver.model.Elementals;
 import com.l2jserver.gameserver.model.Elementals;
 import com.l2jserver.gameserver.model.PcCondOverride;
 import com.l2jserver.gameserver.model.PcCondOverride;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.L2WeaponType;
 import com.l2jserver.gameserver.model.items.type.L2WeaponType;
@@ -33,6 +34,7 @@ import com.l2jserver.gameserver.model.stats.Env;
 import com.l2jserver.gameserver.model.stats.MoveType;
 import com.l2jserver.gameserver.model.stats.MoveType;
 import com.l2jserver.gameserver.model.stats.Stats;
 import com.l2jserver.gameserver.model.stats.Stats;
 import com.l2jserver.gameserver.model.stats.TraitType;
 import com.l2jserver.gameserver.model.stats.TraitType;
+import com.l2jserver.gameserver.model.zone.ZoneId;
 
 
 public class CharStat
 public class CharStat
 {
 {
@@ -79,9 +81,9 @@ public class CharStat
 			return init;
 			return init;
 		}
 		}
 		
 		
-		int id = stat.ordinal();
+		final int id = stat.ordinal();
 		
 		
-		Calculator c = _activeChar.getCalculators()[id];
+		final Calculator c = _activeChar.getCalculators()[id];
 		
 		
 		// If no Func object found, no modifier is applied
 		// If no Func object found, no modifier is applied
 		if ((c == null) || (c.size() == 0))
 		if ((c == null) || (c.size() == 0))
@@ -89,8 +91,18 @@ public class CharStat
 			return init;
 			return init;
 		}
 		}
 		
 		
+		// Apply transformation stats.
+		if (getActiveChar().isPlayer() && getActiveChar().isTransformed())
+		{
+			double val = getActiveChar().getTransformation().getStat(getActiveChar().getActingPlayer(), stat);
+			if (val > 0)
+			{
+				init = val;
+			}
+		}
+		
 		// Create and init an Env object to pass parameters to the Calculator
 		// Create and init an Env object to pass parameters to the Calculator
-		Env env = new Env();
+		final Env env = new Env();
 		env.setCharacter(_activeChar);
 		env.setCharacter(_activeChar);
 		env.setTarget(target);
 		env.setTarget(target);
 		env.setSkill(skill);
 		env.setSkill(skill);
@@ -98,6 +110,7 @@ public class CharStat
 		
 		
 		// Launch the calculation
 		// Launch the calculation
 		c.calc(env);
 		c.calc(env);
+		
 		// avoid some troubles with negative stats (some stats should never be negative)
 		// avoid some troubles with negative stats (some stats should never be negative)
 		if (env.getValue() <= 0)
 		if (env.getValue() <= 0)
 		{
 		{
@@ -369,17 +382,30 @@ public class CharStat
 	
 	
 	public float getMovementSpeedMultiplier()
 	public float getMovementSpeedMultiplier()
 	{
 	{
-		final float baseSpeed = _activeChar.getTemplate().getBaseMoveSpd(_activeChar.isRunning() ? MoveType.RUN : MoveType.WALK);
-		return (getMoveSpeed() / baseSpeed);
+		return (getMoveSpeed() / getBaseMoveSpeed(getMoveType()));
 	}
 	}
 	
 	
 	/**
 	/**
 	 * @param mt movement type
 	 * @param mt movement type
 	 * @return the base move speed of given movement type.
 	 * @return the base move speed of given movement type.
 	 */
 	 */
-	protected double getBaseMoveSpeed(MoveType mt)
+	protected float getBaseMoveSpeed(MoveType mt)
 	{
 	{
-		return _activeChar.getTemplate().getBaseMoveSpd(mt);
+		final TransformTemplate template = _activeChar.isTransformed() ? _activeChar.getTransformation().getTemplate(_activeChar.getActingPlayer()) : null;
+		return (float) (template != null ? template.getSpeed(mt) : _activeChar.getTemplate().getBaseMoveSpd(mt));
+	}
+	
+	public MoveType getMoveType()
+	{
+		if (_activeChar.isFlying())
+		{
+			return _activeChar.isRunning() ? MoveType.FAST_FLY : MoveType.SLOW_FLY;
+		}
+		else if (_activeChar.isInsideZone(ZoneId.WATER))
+		{
+			return _activeChar.isRunning() ? MoveType.FAST_SWIM : MoveType.SLOW_SWIM;
+		}
+		return _activeChar.isRunning() ? MoveType.RUN : MoveType.WALK;
 	}
 	}
 	
 	
 	/**
 	/**

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

@@ -292,7 +292,7 @@ public class PcStat extends PlayableStat
 		
 		
 		if (getActiveChar().isTransformed() || getActiveChar().isInStance())
 		if (getActiveChar().isTransformed() || getActiveChar().isInStance())
 		{
 		{
-			getActiveChar().getTransformation().onLevelUp();
+			getActiveChar().getTransformation().onLevelUp(getActiveChar());
 		}
 		}
 		
 		
 		// Synchronize level with pet if possible.
 		// Synchronize level with pet if possible.
@@ -505,7 +505,7 @@ public class PcStat extends PlayableStat
 	 * @return the base move speed of given movement type.
 	 * @return the base move speed of given movement type.
 	 */
 	 */
 	@Override
 	@Override
-	protected double getBaseMoveSpeed(MoveType mt)
+	protected float getBaseMoveSpeed(MoveType mt)
 	{
 	{
 		L2PcInstance player = getActiveChar();
 		L2PcInstance player = getActiveChar();
 		int val = 0;
 		int val = 0;

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

@@ -239,9 +239,9 @@ public class PlayableStat extends CharStat
 	 * @return the base move speed of given movement type.
 	 * @return the base move speed of given movement type.
 	 */
 	 */
 	@Override
 	@Override
-	protected double getBaseMoveSpeed(MoveType mt)
+	protected float getBaseMoveSpeed(MoveType mt)
 	{
 	{
-		double val = super.getBaseMoveSpeed(mt);
+		float val = super.getBaseMoveSpeed(mt);
 		
 		
 		if (getActiveChar().isInsideZone(ZoneId.SWAMP))
 		if (getActiveChar().isInsideZone(ZoneId.SWAMP))
 		{
 		{

+ 368 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/Transform.java

@@ -0,0 +1,368 @@
+/*
+ * 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.actor.transform;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.l2jserver.gameserver.model.StatsSet;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.holders.AdditionalItemHolder;
+import com.l2jserver.gameserver.model.holders.AdditionalSkillHolder;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.stats.Stats;
+import com.l2jserver.gameserver.network.serverpackets.ExBasicActionList;
+
+/**
+ * @author UnAfraid
+ */
+public final class Transform
+{
+	private final int _id;
+	private final TransformType _type;
+	private final boolean _canSwim;
+	private final int _spawnHeight;
+	private final boolean _canAttack;
+	
+	private TransformTemplate _maleTemplate;
+	private TransformTemplate _femaleTemplate;
+	
+	public Transform(StatsSet set)
+	{
+		_id = set.getInteger("id");
+		_type = set.getEnum("type", TransformType.class, TransformType.COMBAT);
+		_canSwim = set.getInteger("can_swim", 0) == 1;
+		_canAttack = set.getInteger("normal_attackable", 1) == 1;
+		_spawnHeight = set.getInteger("spawn_height", 0);
+	}
+	
+	public int getId()
+	{
+		return _id;
+	}
+	
+	public TransformType getType()
+	{
+		return _type;
+	}
+	
+	public boolean canSwim()
+	{
+		return _canSwim;
+	}
+	
+	public boolean canAttack()
+	{
+		return _canAttack;
+	}
+	
+	public int getSpawnHeight()
+	{
+		return _spawnHeight;
+	}
+	
+	public TransformTemplate getTemplate(L2PcInstance player)
+	{
+		return player != null ? (player.getAppearance().getSex() ? _femaleTemplate : _maleTemplate) : null;
+	}
+	
+	public void setTemplate(boolean male, TransformTemplate template)
+	{
+		if (male)
+		{
+			_maleTemplate = template;
+		}
+		else
+		{
+			_femaleTemplate = template;
+		}
+	}
+	
+	/**
+	 * @return {@code true} if transform type is mode change, {@code false} otherwise.
+	 */
+	public boolean isStance()
+	{
+		return _type == TransformType.MODE_CHANGE;
+	}
+	
+	/**
+	 * @return {@code true} if transform type is combat, {@code false} otherwise.
+	 */
+	public boolean isCombat()
+	{
+		return _type == TransformType.COMBAT;
+	}
+	
+	/**
+	 * @return {@code true} if transform type is non combat, {@code false} otherwise.
+	 */
+	public boolean isNonCombat()
+	{
+		return _type == TransformType.NON_COMBAT;
+	}
+	
+	/**
+	 * @return {@code true} if transform type is flying, {@code false} otherwise.
+	 */
+	public boolean isFlying()
+	{
+		return _type == TransformType.FLYING;
+	}
+	
+	/**
+	 * @return {@code true} if transform type is cursed, {@code false} otherwise.
+	 */
+	public boolean isCursed()
+	{
+		return _type == TransformType.CURSED;
+	}
+	
+	/**
+	 * @return {@code true} if transform type is raiding, {@code false} otherwise.
+	 */
+	public boolean isRiding()
+	{
+		return _type == TransformType.RIDING_MODE;
+	}
+	
+	/**
+	 * @return {@code true} if transform type is pure stat, {@code false} otherwise.
+	 */
+	public boolean isPureStats()
+	{
+		return _type == TransformType.PURE_STAT;
+	}
+	
+	public double getCollisionHeight(L2PcInstance player)
+	{
+		final TransformTemplate template = getTemplate(player);
+		return template != null ? template.getCollisionHeight() : player.getCollisionHeight();
+	}
+	
+	public double getCollisionRadius(L2PcInstance player)
+	{
+		final TransformTemplate template = getTemplate(player);
+		return template != null ? template.getCollisionRadius() : player.getCollisionRadius();
+	}
+	
+	public void onTransform(L2PcInstance player)
+	{
+		final TransformTemplate template = getTemplate(player);
+		if (template != null)
+		{
+			// Start flying.
+			if (getType() == TransformType.FLYING)
+			{
+				player.setIsFlying(true);
+			}
+			
+			// Add common skills.
+			if (!template.getSkills().isEmpty())
+			{
+				for (SkillHolder holder : template.getSkills())
+				{
+					if (player.getSkillLevel(holder.getSkillId()) < holder.getSkillLvl())
+					{
+						player.addSkill(holder.getSkill(), false);
+						player.addTransformSkill(holder.getSkillId());
+					}
+				}
+			}
+			
+			// Add skills depending on level.
+			if (!template.getAdditionalSkills().isEmpty())
+			{
+				for (AdditionalSkillHolder holder : template.getAdditionalSkills())
+				{
+					if (player.getLevel() >= holder.getMinLevel())
+					{
+						if (player.getSkillLevel(holder.getSkillId()) < holder.getSkillLvl())
+						{
+							player.addSkill(holder.getSkill(), false);
+							player.addTransformSkill(holder.getSkillId());
+						}
+					}
+				}
+			}
+			
+			// Set inventory blocks if needed.
+			if (!template.getAdditionalItems().isEmpty())
+			{
+				final List<Integer> allowed = new ArrayList<>();
+				final List<Integer> notAllowed = new ArrayList<>();
+				for (AdditionalItemHolder holder : template.getAdditionalItems())
+				{
+					if (holder.isAllowedToUse())
+					{
+						allowed.add(holder.getId());
+					}
+					else
+					{
+						notAllowed.add(holder.getId());
+					}
+				}
+				
+				if (!allowed.isEmpty())
+				{
+					final int[] items = new int[allowed.size()];
+					for (int i = 0; i < items.length; i++)
+					{
+						items[i] = allowed.get(i);
+					}
+					player.getInventory().setInventoryBlock(items, 1);
+				}
+				
+				if (notAllowed.isEmpty())
+				{
+					final int[] items = new int[notAllowed.size()];
+					for (int i = 0; i < items.length; i++)
+					{
+						items[i] = notAllowed.get(i);
+					}
+					player.getInventory().setInventoryBlock(items, 2);
+				}
+			}
+			
+			// Send basic action list.
+			if (template.hasBasicActionList())
+			{
+				player.sendPacket(template.getBasicActionList());
+			}
+		}
+	}
+	
+	public void onUntransform(L2PcInstance player)
+	{
+		final TransformTemplate template = getTemplate(player);
+		if (template != null)
+		{
+			// Stop flying.
+			if (getType() == TransformType.FLYING)
+			{
+				player.setIsFlying(false);
+			}
+			
+			// Remove common skills.
+			if (!template.getSkills().isEmpty())
+			{
+				for (SkillHolder holder : template.getSkills())
+				{
+					player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive());
+				}
+			}
+			
+			// Remove skills depending on level.
+			if (!template.getAdditionalSkills().isEmpty())
+			{
+				for (AdditionalSkillHolder holder : template.getAdditionalSkills())
+				{
+					if (player.getLevel() >= holder.getMinLevel())
+					{
+						player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive());
+					}
+				}
+			}
+			
+			// Remove transformation skills.
+			player.removeAllTransformSkills();
+			
+			// Remove inventory blocks if needed.
+			if (!template.getAdditionalItems().isEmpty())
+			{
+				player.getInventory().unblock();
+			}
+			
+			player.sendPacket(ExBasicActionList.STATIC_PACKET);
+		}
+	}
+	
+	public void onLevelUp(L2PcInstance player)
+	{
+		final TransformTemplate template = getTemplate(player);
+		if (template != null)
+		{
+			// Add skills depending on level.
+			if (!template.getAdditionalSkills().isEmpty())
+			{
+				for (AdditionalSkillHolder holder : template.getAdditionalSkills())
+				{
+					if (player.getLevel() >= holder.getMinLevel())
+					{
+						if (player.getSkillLevel(holder.getSkillId()) < holder.getSkillLvl())
+						{
+							player.addSkill(holder.getSkill(), false);
+							player.addTransformSkill(holder.getSkillId());
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	public double getStat(L2PcInstance player, Stats stats)
+	{
+		double val = 0;
+		final TransformTemplate template = getTemplate(player);
+		if (template != null)
+		{
+			val = template.getStats(stats);
+			final TransformLevelData data = template.getData(player.getLevel());
+			if (data != null)
+			{
+				val = data.getStats(stats);
+			}
+		}
+		return val;
+	}
+	
+	/**
+	 * @param player
+	 * @param slot
+	 * @return
+	 */
+	public int getBaseDefBySlot(L2PcInstance player, int slot)
+	{
+		final TransformTemplate template = getTemplate(player);
+		if (template != null)
+		{
+			return template.getDefense(slot);
+		}
+		return player.getTemplate().getBaseDefBySlot(slot);
+	}
+	
+	/**
+	 * @param player
+	 * @return
+	 */
+	public double getLevelMod(L2PcInstance player)
+	{
+		double val = -1;
+		final TransformTemplate template = getTemplate(player);
+		if (template != null)
+		{
+			final TransformLevelData data = template.getData(player.getLevel());
+			if (data != null)
+			{
+				val = data.getLevelMod();
+			}
+		}
+		return val;
+	}
+}

+ 75 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/TransformLevelData.java

@@ -0,0 +1,75 @@
+/*
+ * 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.actor.transform;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.l2jserver.gameserver.model.StatsSet;
+import com.l2jserver.gameserver.model.stats.Stats;
+
+/**
+ * @author UnAfraid
+ */
+public final class TransformLevelData
+{
+	private final int _level;
+	private final double _levelMod;
+	private Map<Integer, Double> _stats;
+	
+	public TransformLevelData(StatsSet set)
+	{
+		_level = set.getInteger("val");
+		_levelMod = set.getDouble("levelMod");
+		addStats(Stats.MAX_HP, set.getDouble("hp"));
+		addStats(Stats.MAX_MP, set.getDouble("mp"));
+		addStats(Stats.MAX_CP, set.getDouble("cp"));
+		addStats(Stats.REGENERATE_HP_RATE, set.getDouble("hpRegen"));
+		addStats(Stats.REGENERATE_MP_RATE, set.getDouble("mpRegen"));
+		addStats(Stats.REGENERATE_CP_RATE, set.getDouble("cpRegen"));
+	}
+	
+	private void addStats(Stats stat, double val)
+	{
+		if (_stats == null)
+		{
+			_stats = new HashMap<>();
+		}
+		_stats.put(stat.ordinal(), val);
+	}
+	
+	public double getStats(Stats stats)
+	{
+		if ((_stats == null) || !_stats.containsKey(stats.ordinal()))
+		{
+			return 0;
+		}
+		return _stats.get(stats.ordinal());
+	}
+	
+	public int getLevel()
+	{
+		return _level;
+	}
+	
+	public double getLevelMod()
+	{
+		return _levelMod;
+	}
+}

+ 237 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/TransformTemplate.java

@@ -0,0 +1,237 @@
+/*
+ * 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.actor.transform;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.l2jserver.gameserver.model.StatsSet;
+import com.l2jserver.gameserver.model.holders.AdditionalItemHolder;
+import com.l2jserver.gameserver.model.holders.AdditionalSkillHolder;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.itemcontainer.Inventory;
+import com.l2jserver.gameserver.model.items.type.L2WeaponType;
+import com.l2jserver.gameserver.model.stats.MoveType;
+import com.l2jserver.gameserver.model.stats.Stats;
+import com.l2jserver.gameserver.network.serverpackets.ExBasicActionList;
+
+/**
+ * @author UnAfraid
+ */
+public final class TransformTemplate
+{
+	private final double _collisionRadius;
+	private final double _collisionHeight;
+	private final L2WeaponType _baseAttackType;
+	private final double _baseRandomDamage;
+	private List<SkillHolder> _skills;
+	private List<AdditionalSkillHolder> _additionalSkills;
+	private List<AdditionalItemHolder> _additionalItems;
+	private Map<Integer, Integer> _baseDefense;
+	private Map<Integer, Double> _baseStats;
+	private Map<Integer, Double> _baseSpeed;
+	
+	private ExBasicActionList _list;
+	private final Map<Integer, TransformLevelData> _data = new LinkedHashMap<>(100);
+	
+	public TransformTemplate(StatsSet set)
+	{
+		_collisionRadius = set.getDouble("radius", 0);
+		_collisionHeight = set.getDouble("height", 0);
+		_baseAttackType = L2WeaponType.findByName(set.getString("attackType", "FIST"));
+		_baseRandomDamage = set.getDouble("randomDamage", 0);
+		
+		addSpeed(MoveType.WALK, set.getDouble("walk", 0));
+		addSpeed(MoveType.RUN, set.getDouble("run", 0));
+		addSpeed(MoveType.SLOW_SWIM, set.getDouble("waterWalk", 0));
+		addSpeed(MoveType.FAST_SWIM, set.getDouble("waterRun", 0));
+		addSpeed(MoveType.SLOW_FLY, set.getDouble("flyWalk", 0));
+		addSpeed(MoveType.FAST_FLY, set.getDouble("flyRun", 0));
+		
+		addStats(Stats.POWER_ATTACK, set.getDouble("pAtk", 0));
+		addStats(Stats.MAGIC_ATTACK, set.getDouble("mAtk", 0));
+		addStats(Stats.POWER_ATTACK_RANGE, set.getInteger("range", 0));
+		addStats(Stats.POWER_ATTACK_SPEED, set.getInteger("attackSpeed", 0));
+		addStats(Stats.CRITICAL_RATE, set.getInteger("critRate", 0));
+		addStats(Stats.STAT_STR, set.getInteger("str", 0));
+		addStats(Stats.STAT_INT, set.getInteger("int", 0));
+		addStats(Stats.STAT_CON, set.getInteger("con", 0));
+		addStats(Stats.STAT_DEX, set.getInteger("dex", 0));
+		addStats(Stats.STAT_WIT, set.getInteger("wit", 0));
+		addStats(Stats.STAT_MEN, set.getInteger("men", 0));
+		
+		addDefense(Inventory.PAPERDOLL_CHEST, set.getInteger("chest", 0));
+		addDefense(Inventory.PAPERDOLL_LEGS, set.getInteger("legs", 0));
+		addDefense(Inventory.PAPERDOLL_HEAD, set.getInteger("head", 0));
+		addDefense(Inventory.PAPERDOLL_FEET, set.getInteger("feet", 0));
+		addDefense(Inventory.PAPERDOLL_GLOVES, set.getInteger("gloves", 0));
+		addDefense(Inventory.PAPERDOLL_UNDER, set.getInteger("underwear", 0));
+		addDefense(Inventory.PAPERDOLL_CLOAK, set.getInteger("cloak", 0));
+		addDefense(Inventory.PAPERDOLL_REAR, set.getInteger("rear", 0));
+		addDefense(Inventory.PAPERDOLL_LEAR, set.getInteger("lear", 0));
+		addDefense(Inventory.PAPERDOLL_RFINGER, set.getInteger("rfinger", 0));
+		addDefense(Inventory.PAPERDOLL_LFINGER, set.getInteger("lfinger", 0));
+		addDefense(Inventory.PAPERDOLL_NECK, set.getInteger("neck", 0));
+	}
+	
+	private void addSpeed(MoveType type, double val)
+	{
+		if (_baseSpeed == null)
+		{
+			_baseSpeed = new HashMap<>();
+		}
+		_baseSpeed.put(type.ordinal(), val);
+	}
+	
+	public double getSpeed(MoveType type)
+	{
+		if ((_baseSpeed == null) || !_baseSpeed.containsKey(type.ordinal()))
+		{
+			return 0;
+		}
+		return _baseSpeed.get(type.ordinal());
+	}
+	
+	private void addDefense(int type, int val)
+	{
+		if (_baseDefense == null)
+		{
+			_baseDefense = new HashMap<>();
+		}
+		_baseDefense.put(type, val);
+	}
+	
+	public int getDefense(int type)
+	{
+		if ((_baseDefense == null) || !_baseDefense.containsKey(type))
+		{
+			return 0;
+		}
+		return _baseDefense.get(type);
+	}
+	
+	private void addStats(Stats stats, double val)
+	{
+		if (_baseStats == null)
+		{
+			_baseStats = new HashMap<>();
+		}
+		_baseStats.put(stats.ordinal(), val);
+	}
+	
+	public double getStats(Stats stats)
+	{
+		if ((_baseStats == null) || !_baseStats.containsKey(stats.ordinal()))
+		{
+			return 0;
+		}
+		return _baseStats.get(stats.ordinal());
+	}
+	
+	public double getCollisionRadius()
+	{
+		return _collisionRadius;
+	}
+	
+	public double getCollisionHeight()
+	{
+		return _collisionHeight;
+	}
+	
+	public L2WeaponType getBaseAttackType()
+	{
+		return _baseAttackType;
+	}
+	
+	public double getBaseRandomDamage()
+	{
+		return _baseRandomDamage;
+	}
+	
+	public void addSkill(SkillHolder holder)
+	{
+		if (_skills == null)
+		{
+			_skills = new ArrayList<>();
+		}
+		_skills.add(holder);
+	}
+	
+	public List<SkillHolder> getSkills()
+	{
+		return _skills != null ? _skills : Collections.<SkillHolder> emptyList();
+	}
+	
+	public void addAdditionalSkill(AdditionalSkillHolder holder)
+	{
+		if (_additionalSkills == null)
+		{
+			_additionalSkills = new ArrayList<>();
+		}
+		_additionalSkills.add(holder);
+	}
+	
+	public List<AdditionalSkillHolder> getAdditionalSkills()
+	{
+		return _additionalSkills != null ? _additionalSkills : Collections.<AdditionalSkillHolder> emptyList();
+	}
+	
+	public void addAdditionalItem(AdditionalItemHolder holder)
+	{
+		if (_additionalItems == null)
+		{
+			_additionalItems = new ArrayList<>();
+		}
+		_additionalItems.add(holder);
+	}
+	
+	public List<AdditionalItemHolder> getAdditionalItems()
+	{
+		return _additionalItems != null ? _additionalItems : Collections.<AdditionalItemHolder> emptyList();
+	}
+	
+	public void setBasicActionList(ExBasicActionList list)
+	{
+		_list = list;
+	}
+	
+	public ExBasicActionList getBasicActionList()
+	{
+		return _list;
+	}
+	
+	public boolean hasBasicActionList()
+	{
+		return _list != null;
+	}
+	
+	public void addLevelData(TransformLevelData data)
+	{
+		_data.put(data.getLevel(), data);
+	}
+	
+	public TransformLevelData getData(int level)
+	{
+		return _data.get(level);
+	}
+}

+ 33 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/transform/TransformType.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.actor.transform;
+
+/**
+ * @author UnAfraid
+ */
+public enum TransformType
+{
+	MODE_CHANGE,
+	NON_COMBAT,
+	CURSED,
+	RIDING_MODE,
+	PURE_STAT,
+	FLYING,
+	COMBAT;
+}

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCanTransform.java

@@ -59,7 +59,7 @@ public class ConditionPlayerCanTransform extends Condition
 			player.sendPacket(SystemMessageId.YOU_CANNOT_POLYMORPH_INTO_THE_DESIRED_FORM_IN_WATER);
 			player.sendPacket(SystemMessageId.YOU_CANNOT_POLYMORPH_INTO_THE_DESIRED_FORM_IN_WATER);
 			canTransform = false;
 			canTransform = false;
 		}
 		}
-		else if (player.isFlyingMounted() || player.isMounted() || player.isRidingStrider())
+		else if (player.isFlyingMounted() || player.isMounted())
 		{
 		{
 			player.sendPacket(SystemMessageId.YOU_CANNOT_POLYMORPH_WHILE_RIDING_A_PET);
 			player.sendPacket(SystemMessageId.YOU_CANNOT_POLYMORPH_WHILE_RIDING_A_PET);
 			canTransform = false;
 			canTransform = false;

+ 1 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/BlockCheckerEngine.java

@@ -412,8 +412,7 @@ public final class BlockCheckerEngine
 				player.sendPacket(initialPoints);
 				player.sendPacket(initialPoints);
 				player.sendPacket(_closeUserInterface);
 				player.sendPacket(_closeUserInterface);
 				// ExBasicActionList
 				// ExBasicActionList
-				final ExBasicActionList actionList = ExBasicActionList.getStaticPacket(player);
-				player.sendPacket(actionList);
+				player.sendPacket(ExBasicActionList.STATIC_PACKET);
 				broadcastRelationChanged(player);
 				broadcastRelationChanged(player);
 			}
 			}
 		}
 		}

+ 38 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/holders/AdditionalItemHolder.java

@@ -0,0 +1,38 @@
+/*
+ * 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.holders;
+
+/**
+ * @author UnAfraid
+ */
+public class AdditionalItemHolder extends ItemHolder
+{
+	private final boolean _allowed;
+	
+	public AdditionalItemHolder(int id, boolean allowed)
+	{
+		super(id, 0);
+		_allowed = allowed;
+	}
+	
+	public boolean isAllowedToUse()
+	{
+		return _allowed;
+	}
+}

+ 38 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/holders/AdditionalSkillHolder.java

@@ -0,0 +1,38 @@
+/*
+ * 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.holders;
+
+/**
+ * @author UnAfraid
+ */
+public class AdditionalSkillHolder extends SkillHolder
+{
+	private final int _minLevel;
+	
+	public AdditionalSkillHolder(int skillId, int skillLevel, int minLevel)
+	{
+		super(skillId, skillLevel);
+		_minLevel = minLevel;
+	}
+	
+	public int getMinLevel()
+	{
+		return _minLevel;
+	}
+}

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/type/L2WeaponType.java

@@ -96,11 +96,11 @@ public enum L2WeaponType implements L2ItemType
 	
 	
 	public static L2WeaponType findByName(String name)
 	public static L2WeaponType findByName(String name)
 	{
 	{
-		if (name.equals("DUAL"))
+		if (name.equalsIgnoreCase("DUAL"))
 		{
 		{
 			name = "Dual Sword";
 			name = "Dual Sword";
 		}
 		}
-		else if (name.equals("DUALFIST"))
+		else if (name.equalsIgnoreCase("DUALFIST"))
 		{
 		{
 			name = "Dual Fist";
 			name = "Dual Fist";
 		}
 		}

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

@@ -50,23 +50,23 @@ public class FuncMDefMod extends Func
 			L2PcInstance p = env.getPlayer();
 			L2PcInstance p = env.getPlayer();
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_LFINGER))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_LFINGER))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_LFINGER));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_LFINGER) : Inventory.PAPERDOLL_LFINGER));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_RFINGER))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_RFINGER))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_RFINGER));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_RFINGER) : Inventory.PAPERDOLL_RFINGER));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_LEAR))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_LEAR))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_LEAR));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_LEAR) : Inventory.PAPERDOLL_LEAR));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_REAR))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_REAR))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_REAR));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_REAR) : Inventory.PAPERDOLL_REAR));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_NECK))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_NECK))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_NECK));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_NECK) : Inventory.PAPERDOLL_NECK));
 			}
 			}
 			env.mulValue(BaseStats.MEN.calcBonus(env.getPlayer()) * env.getPlayer().getLevelMod());
 			env.mulValue(BaseStats.MEN.calcBonus(env.getPlayer()) * env.getPlayer().getLevelMod());
 		}
 		}

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

@@ -47,34 +47,34 @@ public class FuncPDefMod extends Func
 	{
 	{
 		if (env.getCharacter().isPlayer())
 		if (env.getCharacter().isPlayer())
 		{
 		{
-			L2PcInstance p = env.getPlayer();
+			final L2PcInstance p = env.getPlayer();
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_CHEST))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_CHEST))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_CHEST));
+				env.subValue(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_CHEST) : p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_CHEST));
 			}
 			}
 			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)))
 			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(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_LEGS));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_LEGS) : Inventory.PAPERDOLL_LEGS));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_HEAD))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_HEAD))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_HEAD));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_HEAD) : Inventory.PAPERDOLL_HEAD));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_FEET))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_FEET))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_FEET));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_FEET) : Inventory.PAPERDOLL_FEET));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_GLOVES))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_GLOVES))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_GLOVES));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_GLOVES) : Inventory.PAPERDOLL_GLOVES));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_UNDER))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_UNDER))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_UNDER));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_UNDER) : Inventory.PAPERDOLL_UNDER));
 			}
 			}
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_CLOAK))
 			if (!p.getInventory().isPaperdollSlotEmpty(Inventory.PAPERDOLL_CLOAK))
 			{
 			{
-				env.subValue(p.getTemplate().getBaseDefBySlot(Inventory.PAPERDOLL_CLOAK));
+				env.subValue(p.getTemplate().getBaseDefBySlot(p.isTransformed() ? p.getTransformation().getBaseDefBySlot(p, Inventory.PAPERDOLL_CLOAK) : Inventory.PAPERDOLL_CLOAK));
 			}
 			}
 			env.mulValue(p.getLevelMod());
 			env.mulValue(p.getLevelMod());
 		}
 		}

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/type/L2WaterZone.java

@@ -44,7 +44,7 @@ public class L2WaterZone extends L2ZoneType
 		if (character.isPlayer())
 		if (character.isPlayer())
 		{
 		{
 			L2PcInstance player = character.getActingPlayer();
 			L2PcInstance player = character.getActingPlayer();
-			if (player.isTransformed() && !player.isCursedWeaponEquipped())
+			if (player.isTransformed() && !player.getTransformation().canSwim())
 			{
 			{
 				character.stopTransformation(true);
 				character.stopTransformation(true);
 			}
 			}

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java

@@ -375,7 +375,7 @@ public class EnterWorld extends L2GameClientPacket
 		sendPacket(new ShortCutInit(activeChar));
 		sendPacket(new ShortCutInit(activeChar));
 		
 		
 		// Send Action list
 		// Send Action list
-		activeChar.sendPacket(ExBasicActionList.getStaticPacket(activeChar));
+		activeChar.sendPacket(ExBasicActionList.STATIC_PACKET);
 		
 		
 		// Send Skill list
 		// Send Skill list
 		activeChar.sendSkillList();
 		activeChar.sendSkillList();

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java

@@ -998,7 +998,7 @@ public final class RequestActionUse extends L2GameClientPacket
 			sendPacket(sm);
 			sendPacket(sm);
 		}
 		}
 		
 		
-		if (requester.isMounted() || requester.isRidingStrider() || requester.isFlyingMounted() || requester.isInBoat() || requester.isInAirShip())
+		if (requester.isMounted() || requester.isFlyingMounted() || requester.isInBoat() || requester.isInAirShip())
 		{
 		{
 			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_RIDING_A_SHIP_STEED_OR_STRIDER_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION);
 			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_RIDING_A_SHIP_STEED_OR_STRIDER_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION);
 			sm.addPcName(requester);
 			sm.addPcName(requester);
@@ -1088,7 +1088,7 @@ public final class RequestActionUse extends L2GameClientPacket
 			return;
 			return;
 		}
 		}
 		
 		
-		if (partner.isMounted() || partner.isRidingStrider() || partner.isFlyingMounted() || partner.isInBoat() || partner.isInAirShip())
+		if (partner.isMounted() || partner.isFlyingMounted() || partner.isInBoat() || partner.isInAirShip())
 		{
 		{
 			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_RIDING_A_SHIP_STEED_OR_STRIDER_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION);
 			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_RIDING_A_SHIP_STEED_OR_STRIDER_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION);
 			sm.addPcName(partner);
 			sm.addPcName(partner);

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestMagicSkillUse.java

@@ -78,7 +78,7 @@ public final class RequestMagicSkillUse extends L2GameClientPacket
 			return;
 			return;
 		}
 		}
 		
 		
-		if ((activeChar.isTransformed() || activeChar.isInStance()) && !activeChar.containsAllowedTransformSkill(skill.getId()))
+		if ((activeChar.isTransformed() || activeChar.isInStance()) && !activeChar.hasTransformSkill(skill.getId()))
 		{
 		{
 			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
 			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
 			return;
 			return;

+ 2 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExBasicActionList.java

@@ -18,8 +18,6 @@
  */
  */
 package com.l2jserver.gameserver.network.serverpackets;
 package com.l2jserver.gameserver.network.serverpackets;
 
 
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
 /**
 /**
  * @author KenM
  * @author KenM
  */
  */
@@ -90,17 +88,11 @@ public final class ExBasicActionList extends L2GameServerPacket
 		}
 		}
 	}
 	}
 	
 	
-	private static final ExBasicActionList STATIC_PACKET_TRANSFORMED = new ExBasicActionList(ACTIONS_ON_TRANSFORM);
-	private static final ExBasicActionList STATIC_PACKET = new ExBasicActionList(DEFAULT_ACTION_LIST);
-	
-	public static final ExBasicActionList getStaticPacket(final L2PcInstance player)
-	{
-		return player.isTransformed() ? STATIC_PACKET_TRANSFORMED : STATIC_PACKET;
-	}
+	public static final ExBasicActionList STATIC_PACKET = new ExBasicActionList(DEFAULT_ACTION_LIST);
 	
 	
 	private final int[] _actionIds;
 	private final int[] _actionIds;
 	
 	
-	private ExBasicActionList(final int[] actionIds)
+	public ExBasicActionList(final int[] actionIds)
 	{
 	{
 		_actionIds = actionIds;
 		_actionIds = actionIds;
 	}
 	}

+ 18 - 59
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/Ride.java

@@ -18,77 +18,36 @@
  */
  */
 package com.l2jserver.gameserver.network.serverpackets;
 package com.l2jserver.gameserver.network.serverpackets;
 
 
+import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 
 
 public final class Ride extends L2GameServerPacket
 public final class Ride extends L2GameServerPacket
 {
 {
-	public static final int ACTION_MOUNT = 1;
-	public static final int ACTION_DISMOUNT = 0;
-	private final int _id;
-	private final int _bRide;
+	private final int _objectId;
+	private final int _mounted;
 	private final int _rideType;
 	private final int _rideType;
-	private final int _rideClassID;
-	private final int _x, _y, _z;
+	private final int _rideNpcId;
+	private final Location _loc;
 	
 	
-	public Ride(L2PcInstance cha, boolean mount, int rideClassId)
+	public Ride(L2PcInstance player)
 	{
 	{
-		_id = cha.getObjectId();
-		_bRide = mount ? 1 : 0;
-		_rideClassID = rideClassId + 1000000; // npcID
-		
-		_x = cha.getX();
-		_y = cha.getY();
-		_z = cha.getZ();
-		
-		// TODO: Unhardcode these
-		switch (rideClassId)
-		{
-			case 0: // dismount
-				_rideType = 0;
-				break;
-			case 12526: // Wind
-			case 12527: // Star
-			case 12528: // Twilight
-			case 16038: // red strider of wind
-			case 16039: // red strider of star
-			case 16040: // red strider of dusk
-			case 16068: // Guardian Strider
-				_rideType = 1;
-				break;
-			case 12621: // Wyvern
-				_rideType = 2;
-				break;
-			case 16037: // Great Snow Wolf
-			case 16041: // Fenrir Wolf
-			case 16042: // White Fenrir Wolf
-				_rideType = 3;
-				break;
-			case 32: // Jet Bike
-			case 13130: // Light Purple Maned Horse
-			case 13146: // Tawny-Maned Lion
-			case 13147: // Steam Sledge
-				_rideType = 4;
-				break;
-			default:
-				throw new IllegalArgumentException("Unsupported mount NpcId: " + rideClassId);
-		}
-	}
-	
-	public int getMountType()
-	{
-		return _rideType;
+		_objectId = player.getObjectId();
+		_mounted = player.isMounted() ? 1 : 0;
+		_rideType = player.getMountType();
+		_rideNpcId = player.getMountNpcId() + 1000000;
+		_loc = player.getLocation();
 	}
 	}
 	
 	
 	@Override
 	@Override
 	protected final void writeImpl()
 	protected final void writeImpl()
 	{
 	{
-		writeC(0x8c);
-		writeD(_id);
-		writeD(_bRide);
+		writeC(0x8C);
+		writeD(_objectId);
+		writeD(_mounted);
 		writeD(_rideType);
 		writeD(_rideType);
-		writeD(_rideClassID);
-		writeD(_x);
-		writeD(_y);
-		writeD(_z);
+		writeD(_rideNpcId);
+		writeD(_loc.getX());
+		writeD(_loc.getY());
+		writeD(_loc.getZ());
 	}
 	}
 }
 }

+ 27 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/TransformEvent.java

@@ -18,7 +18,8 @@
  */
  */
 package com.l2jserver.gameserver.scripting.scriptengine.events;
 package com.l2jserver.gameserver.scripting.scriptengine.events;
 
 
-import com.l2jserver.gameserver.model.L2Transformation;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.transform.Transform;
 import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
 import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
 
 
 /**
 /**
@@ -26,23 +27,40 @@ import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
  */
  */
 public class TransformEvent implements L2Event
 public class TransformEvent implements L2Event
 {
 {
-	private L2Transformation transformation;
-	private boolean transforming; // false = untransforming
+	private L2PcInstance _player;
+	private Transform _transformation;
+	private boolean _transforming; // false = untransforming
+	
+	/**
+	 * @return
+	 */
+	public L2PcInstance getPlayer()
+	{
+		return _player;
+	}
+	
+	/**
+	 * @param player
+	 */
+	public void setPlayer(L2PcInstance player)
+	{
+		_player = player;
+	}
 	
 	
 	/**
 	/**
 	 * @return the transformation
 	 * @return the transformation
 	 */
 	 */
-	public L2Transformation getTransformation()
+	public Transform getTransformation()
 	{
 	{
-		return transformation;
+		return _transformation;
 	}
 	}
 	
 	
 	/**
 	/**
 	 * @param transformation the transformation to set
 	 * @param transformation the transformation to set
 	 */
 	 */
-	public void setTransformation(L2Transformation transformation)
+	public void setTransformation(Transform transformation)
 	{
 	{
-		this.transformation = transformation;
+		_transformation = transformation;
 	}
 	}
 	
 	
 	/**
 	/**
@@ -50,7 +68,7 @@ public class TransformEvent implements L2Event
 	 */
 	 */
 	public boolean isTransforming()
 	public boolean isTransforming()
 	{
 	{
-		return transforming;
+		return _transforming;
 	}
 	}
 	
 	
 	/**
 	/**
@@ -58,6 +76,6 @@ public class TransformEvent implements L2Event
 	 */
 	 */
 	public void setTransforming(boolean transforming)
 	public void setTransforming(boolean transforming)
 	{
 	{
-		this.transforming = transforming;
+		this._transforming = transforming;
 	}
 	}
 }
 }