Browse Source

Big vehicle rework. New template instance L2Vehicle, two new AI types for both vehicle types. All movement stuff transferred to the AI.
REQUIRE DP UPDATE !

_DS_ 15 years ago
parent
commit
48e16ba63b
27 changed files with 992 additions and 1808 deletions
  1. 71 0
      L2_GameServer/java/com/l2jserver/gameserver/ai/L2AirShipAI.java
  2. 76 0
      L2_GameServer/java/com/l2jserver/gameserver/ai/L2BoatAI.java
  3. 0 11
      L2_GameServer/java/com/l2jserver/gameserver/ai/L2CharacterAI.java
  4. 124 0
      L2_GameServer/java/com/l2jserver/gameserver/ai/L2VehicleAI.java
  5. 35 88
      L2_GameServer/java/com/l2jserver/gameserver/instancemanager/AirShipManager.java
  6. 120 133
      L2_GameServer/java/com/l2jserver/gameserver/instancemanager/BoatManager.java
  7. 6 0
      L2_GameServer/java/com/l2jserver/gameserver/model/L2WorldRegion.java
  8. 42 0
      L2_GameServer/java/com/l2jserver/gameserver/model/VehiclePathPoint.java
  9. 1 18
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/L2Character.java
  10. 351 0
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/L2Vehicle.java
  11. 5 7
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2AirShipControllerInstance.java
  12. 35 583
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2AirShipInstance.java
  13. 26 806
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2BoatInstance.java
  14. 22 30
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
  15. 5 12
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/knownlist/PcKnownList.java
  16. 2 8
      L2_GameServer/java/com/l2jserver/gameserver/model/actor/stat/VehicleStat.java
  17. 9 17
      L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/MoveToLocationInAirShip.java
  18. 1 1
      L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/RequestGetOffVehicle.java
  19. 1 1
      L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/RequestGetOnVehicle.java
  20. 1 1
      L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/RequestMoveToLocationInVehicle.java
  21. 25 34
      L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/ExMoveToLocationAirShip.java
  22. 4 4
      L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/ExStopMoveAirShip.java
  23. 6 8
      L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/ExStopMoveInAirShip.java
  24. 9 19
      L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleCheckLocation.java
  25. 9 18
      L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleDeparture.java
  26. 1 3
      L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleInfo.java
  27. 5 6
      L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleStarted.java

+ 71 - 0
L2_GameServer/java/com/l2jserver/gameserver/ai/L2AirShipAI.java

@@ -0,0 +1,71 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.ai;
+
+import com.l2jserver.gameserver.model.L2CharPosition;
+import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.ExMoveToLocationAirShip;
+import com.l2jserver.gameserver.network.serverpackets.ExStopMoveAirShip;
+
+/**
+ * 
+ * @author DS
+ *
+ */
+public class L2AirShipAI extends L2VehicleAI
+{
+	public L2AirShipAI(L2AirShipInstance.AIAccessor accessor)
+	{
+		super(accessor);
+	}
+
+	@Override
+	protected void moveTo(int x, int y, int z)
+	{
+		if (!_actor.isMovementDisabled())
+		{
+			_clientMoving = true;
+			_accessor.moveTo(x, y, z);
+			_actor.broadcastPacket(new ExMoveToLocationAirShip(getActor()));
+		}
+	}
+
+	@Override
+	protected void clientStopMoving(L2CharPosition pos)
+	{
+		if (_actor.isMoving())
+			_accessor.stopMove(pos);
+
+		if (_clientMoving || pos != null)
+		{
+			_clientMoving = false;
+			_actor.broadcastPacket(new ExStopMoveAirShip(getActor()));
+		}
+	}
+
+	@Override
+	public void describeStateToPlayer(L2PcInstance player)
+	{
+		if (_clientMoving)
+			player.sendPacket(new ExMoveToLocationAirShip(getActor()));
+	}
+
+	@Override
+	public L2AirShipInstance getActor()
+	{
+		return (L2AirShipInstance)_actor;
+	}
+}

+ 76 - 0
L2_GameServer/java/com/l2jserver/gameserver/ai/L2BoatAI.java

@@ -0,0 +1,76 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.ai;
+
+import com.l2jserver.gameserver.model.L2CharPosition;
+import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.VehicleDeparture;
+import com.l2jserver.gameserver.network.serverpackets.VehicleInfo;
+import com.l2jserver.gameserver.network.serverpackets.VehicleStarted;
+
+/**
+ * 
+ * @author DS
+ *
+ */
+public class L2BoatAI extends L2VehicleAI
+{
+	public L2BoatAI(L2BoatInstance.AIAccessor accessor)
+	{
+		super(accessor);
+	}
+
+	@Override
+	protected void moveTo(int x, int y, int z)
+	{
+		if (!_actor.isMovementDisabled())
+		{
+			if (!_clientMoving)
+				_actor.broadcastPacket(new VehicleStarted(getActor(), 1));
+
+			_clientMoving = true;
+			_accessor.moveTo(x, y, z);
+			_actor.broadcastPacket(new VehicleDeparture(getActor()));
+		}
+	}
+
+	@Override
+	protected void clientStopMoving(L2CharPosition pos)
+	{
+		if (_actor.isMoving())
+			_accessor.stopMove(pos);
+
+		if (_clientMoving || pos != null)
+		{
+			_clientMoving = false;
+			_actor.broadcastPacket(new VehicleStarted(getActor(), 0));
+			_actor.broadcastPacket(new VehicleInfo(getActor()));
+		}
+	}
+
+	@Override
+	public void describeStateToPlayer(L2PcInstance player)
+	{
+		if (_clientMoving)
+			player.sendPacket(new VehicleDeparture(getActor()));
+	}
+
+	@Override
+	public L2BoatInstance getActor()
+	{
+		return (L2BoatInstance)_actor;
+	}
+}

+ 0 - 11
L2_GameServer/java/com/l2jserver/gameserver/ai/L2CharacterAI.java

@@ -36,8 +36,6 @@ import com.l2jserver.gameserver.model.L2ItemInstance.ItemLocation;
 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;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.L2Npc;
-import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.SystemMessageId;
@@ -695,15 +693,6 @@ public class L2CharacterAI extends AbstractAI
 		
 		
 		// Launch actions corresponding to the Event Think
 		// Launch actions corresponding to the Event Think
 		onEvtThink();
 		onEvtThink();
-		
-		if (_actor instanceof L2BoatInstance)
-		{
-			((L2BoatInstance) _actor).evtArrived();
-		}
-		else if (_actor instanceof L2AirShipInstance)
-		{
-			((L2AirShipInstance) _actor).evtArrived();
-		}
 	}
 	}
 	
 	
 	/**
 	/**

+ 124 - 0
L2_GameServer/java/com/l2jserver/gameserver/ai/L2VehicleAI.java

@@ -0,0 +1,124 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.ai;
+
+import com.l2jserver.gameserver.model.L2Object;
+import com.l2jserver.gameserver.model.L2Skill;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Vehicle;
+
+public abstract class L2VehicleAI extends L2CharacterAI
+{
+	/**
+	 * 
+	 * @author DS
+	 * Simple AI for vehicles
+	 * 
+	 */
+	public L2VehicleAI(L2Vehicle.AIAccessor accessor)
+	{
+		super(accessor);
+	}
+
+	@Override
+	protected void onIntentionAttack(L2Character target)
+	{
+	}
+
+	@Override
+	protected void onIntentionCast(L2Skill skill, L2Object target)
+	{
+	}
+
+	@Override
+	protected void onIntentionFollow(L2Character target)
+	{
+	}
+
+	@Override
+	protected void onIntentionPickUp(L2Object item)
+	{
+	}
+
+	@Override
+	protected void onIntentionInteract(L2Object object)
+	{
+	}
+
+	@Override
+	protected void onEvtAttacked(L2Character attacker)
+	{
+	}
+
+	@Override
+	protected void onEvtAggression(L2Character target, int aggro)
+	{
+	}
+
+	@Override
+	protected void onEvtStunned(L2Character attacker)
+	{
+	}
+
+	@Override
+	protected void onEvtSleeping(L2Character attacker)
+	{
+	}
+
+	@Override
+	protected void onEvtRooted(L2Character attacker)
+	{
+	}
+
+	@Override
+	protected void onEvtForgetObject(L2Object object)
+	{
+	}
+
+	@Override
+	protected void onEvtCancel()
+	{
+	}
+
+	@Override
+	protected void onEvtDead()
+	{
+	}
+
+	@Override
+	protected void onEvtFakeDeath()
+	{
+	}
+
+	@Override
+	protected void onEvtFinishCasting()
+	{
+	}
+
+	@Override
+	protected void clientActionFailed()
+	{
+	}
+
+	@Override
+	protected void moveToPawn(L2Object pawn, int offset)
+	{
+	}
+
+	@Override
+	protected void clientStoppedMoving()
+	{
+	}
+}

+ 35 - 88
L2_GameServer/java/com/l2jserver/gameserver/instancemanager/AirShipManager.java

@@ -14,17 +14,10 @@
  */
  */
 package com.l2jserver.gameserver.instancemanager;
 package com.l2jserver.gameserver.instancemanager;
 
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.LineNumberReader;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 
-import com.l2jserver.Config;
+import javolution.util.FastMap;
+
 import com.l2jserver.gameserver.idfactory.IdFactory;
 import com.l2jserver.gameserver.idfactory.IdFactory;
 import com.l2jserver.gameserver.model.actor.instance.L2AirShipControllerInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2AirShipControllerInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
@@ -34,9 +27,8 @@ import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
 
 
 public class AirShipManager
 public class AirShipManager
 {
 {
-	private static final Logger _log = Logger.getLogger(AirShipManager.class.getName());
-	
-	private L2AirShipInstance _airShip = null;
+	private L2CharTemplate _airShipTemplate = null;
+	private FastMap<Integer, L2AirShipInstance> _airShips = new FastMap<Integer, L2AirShipInstance>();
 	private ArrayList<L2AirShipControllerInstance> _atcs = new ArrayList<L2AirShipControllerInstance>(2);
 	private ArrayList<L2AirShipControllerInstance> _atcs = new ArrayList<L2AirShipControllerInstance>(2);
 	
 	
 	public static final AirShipManager getInstance()
 	public static final AirShipManager getInstance()
@@ -46,84 +38,24 @@ public class AirShipManager
 	
 	
 	private AirShipManager()
 	private AirShipManager()
 	{
 	{
-		load();
-	}
-	
-	private final void load()
-	{
-		LineNumberReader lnr = null;
-		try
-		{
-			File doorData = new File(Config.DATAPACK_ROOT, "data/airship.csv");
-			lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData)));
-			
-			String line = null;
-			while ((line = lnr.readLine()) != null)
-			{
-				if (line.trim().length() == 0 || line.startsWith("#"))
-					continue;
-				L2AirShipInstance airShip = parseLine(line);
-				airShip.spawn();
-				_airShip = airShip;
-				if (Config.DEBUG)
-				{
-					_log.info("AirShip ID : " + airShip.getObjectId());
-				}
-			}
-		}
-		catch (FileNotFoundException e)
-		{
-			_log.warning("airship.csv is missing in data folder");
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "Error while creating AirShip table " + e.getMessage(), e);
-		}
-		finally
-		{
-			try
-			{
-				lnr.close();
-			}
-			catch (Exception e1)
-			{ /* ignore problems */
-			}
-		}
-	}
-	
-	/**
-	 * @param line
-	 * @return
-	 */
-	private L2AirShipInstance parseLine(String line)
-	{
-		L2AirShipInstance airShip;
-		StringTokenizer st = new StringTokenizer(line, ";");
-		
-		int xspawn = Integer.parseInt(st.nextToken());
-		int yspawn = Integer.parseInt(st.nextToken());
-		int zspawn = Integer.parseInt(st.nextToken());
-		int heading = Integer.parseInt(st.nextToken());
-		
 		StatsSet npcDat = new StatsSet();
 		StatsSet npcDat = new StatsSet();
 		npcDat.set("npcId", 9);
 		npcDat.set("npcId", 9);
 		npcDat.set("level", 0);
 		npcDat.set("level", 0);
 		npcDat.set("jClass", "boat");
 		npcDat.set("jClass", "boat");
-		
+
 		npcDat.set("baseSTR", 0);
 		npcDat.set("baseSTR", 0);
 		npcDat.set("baseCON", 0);
 		npcDat.set("baseCON", 0);
 		npcDat.set("baseDEX", 0);
 		npcDat.set("baseDEX", 0);
 		npcDat.set("baseINT", 0);
 		npcDat.set("baseINT", 0);
 		npcDat.set("baseWIT", 0);
 		npcDat.set("baseWIT", 0);
 		npcDat.set("baseMEN", 0);
 		npcDat.set("baseMEN", 0);
-		
+
 		npcDat.set("baseShldDef", 0);
 		npcDat.set("baseShldDef", 0);
 		npcDat.set("baseShldRate", 0);
 		npcDat.set("baseShldRate", 0);
 		npcDat.set("baseAccCombat", 38);
 		npcDat.set("baseAccCombat", 38);
 		npcDat.set("baseEvasRate", 38);
 		npcDat.set("baseEvasRate", 38);
 		npcDat.set("baseCritRate", 38);
 		npcDat.set("baseCritRate", 38);
-		
-		// npcDat.set("name", "");
+
 		npcDat.set("collision_radius", 0);
 		npcDat.set("collision_radius", 0);
 		npcDat.set("collision_height", 0);
 		npcDat.set("collision_height", 0);
 		npcDat.set("sex", "male");
 		npcDat.set("sex", "male");
@@ -149,23 +81,24 @@ public class AirShipManager
 		npcDat.set("baseMpReg", 3.e-3f);
 		npcDat.set("baseMpReg", 3.e-3f);
 		npcDat.set("basePDef", 100);
 		npcDat.set("basePDef", 100);
 		npcDat.set("baseMDef", 100);
 		npcDat.set("baseMDef", 100);
-		L2CharTemplate template = new L2CharTemplate(npcDat);
-		airShip = new L2AirShipInstance(IdFactory.getInstance().getNextId(), template);
-		airShip.setIsFlying(true);
-		airShip.getPosition().setHeading(heading);
-		airShip.setXYZ(xspawn, yspawn, zspawn);
-		airShip.setTrajet1(1);
-		airShip.setTrajet2(2);
-		airShip.setTrajet3(3);
-		airShip.setTrajet4(4);
-		return airShip;
+		_airShipTemplate = new L2CharTemplate(npcDat);
 	}
 	}
 	
 	
-	public L2AirShipInstance getAirShip()
+	public L2AirShipInstance getAirShip(int objectId)
 	{
 	{
-		return _airShip;
+		return _airShips.get(objectId);
 	}
 	}
-	
+
+	public L2AirShipInstance getNewAirShip(int x, int y, int z, int heading)
+	{
+		L2AirShipInstance airShip = new L2AirShipInstance(IdFactory.getInstance().getNextId(), _airShipTemplate);
+		_airShips.put(airShip.getObjectId(), airShip);
+		airShip.setHeading(heading);
+		airShip.setXYZInvisible(x, y, z);
+		airShip.spawnMe();
+		return airShip;
+	}
+
 	public void registerATC(L2AirShipControllerInstance atc)
 	public void registerATC(L2AirShipControllerInstance atc)
 	{
 	{
 		_atcs.add(atc);
 		_atcs.add(atc);
@@ -176,6 +109,20 @@ public class AirShipManager
 		return _atcs;
 		return _atcs;
 	}
 	}
 
 
+	public L2AirShipControllerInstance getNearestATC(L2AirShipInstance ship, int radius)
+	{
+		if (_atcs == null || _atcs.isEmpty())
+			return null;
+
+		for (L2AirShipControllerInstance atc : _atcs)
+		{
+			if (atc != null && atc.isInsideRadius(ship, radius, true, false))
+				return atc;
+		}
+
+		return null;
+	}
+
 	@SuppressWarnings("synthetic-access")
 	@SuppressWarnings("synthetic-access")
 	private static class SingletonHolder
 	private static class SingletonHolder
 	{
 	{

+ 120 - 133
L2_GameServer/java/com/l2jserver/gameserver/instancemanager/BoatManager.java

@@ -14,19 +14,16 @@
  */
  */
 package com.l2jserver.gameserver.instancemanager;
 package com.l2jserver.gameserver.instancemanager;
 
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.LineNumberReader;
+import java.util.Collection;
 import java.util.Map;
 import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 
 import com.l2jserver.Config;
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.idfactory.IdFactory;
 import com.l2jserver.gameserver.idfactory.IdFactory;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.VehiclePathPoint;
 import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
 import com.l2jserver.gameserver.templates.StatsSet;
 import com.l2jserver.gameserver.templates.StatsSet;
 import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
 import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
 
 
@@ -34,116 +31,49 @@ import javolution.util.FastMap;
 
 
 public class BoatManager
 public class BoatManager
 {
 {
-	private static final Logger _log = Logger.getLogger(BoatManager.class.getName());
-	
+	private Map<Integer, L2BoatInstance> _boats = new FastMap<Integer, L2BoatInstance>();
+	private boolean[] _docksBusy = new boolean[3];
+
+	public static final int TALKING_ISLAND = 0;
+	public static final int GLUDIN_HARBOR = 1;
+	public static final int RUNE_HARBOR = 2;
+
+	private static final double BROADCAST_DISTANCE = 400000000; // 20000
+
 	public static final BoatManager getInstance()
 	public static final BoatManager getInstance()
 	{
 	{
 		return SingletonHolder._instance;
 		return SingletonHolder._instance;
 	}
 	}
-	
-	// =========================================================
-	
-	// =========================================================
-	// Data Field
-	private Map<Integer, L2BoatInstance> _staticItems = new FastMap<Integer, L2BoatInstance>();
-	
-	@SuppressWarnings("unused")
-	private boolean _initialized;
-	
-	// =========================================================
-	// Constructor
+
 	private BoatManager()
 	private BoatManager()
 	{
 	{
-		_log.info("Initializing BoatManager");
-		load();
+		for (int i = 0; i < _docksBusy.length; i++)
+			_docksBusy[i] = false;
 	}
 	}
-	
-	// =========================================================
-	// Method - Private
-	private final void load()
+
+	public L2BoatInstance getNewBoat(int boatId, int x, int y, int z, int heading)
 	{
 	{
-		_initialized = true;
 		if (!Config.ALLOW_BOAT)
 		if (!Config.ALLOW_BOAT)
-		{
-			_initialized = false;
-			return;
-		}
-		LineNumberReader lnr = null;
-		try
-		{
-			File doorData = new File(Config.DATAPACK_ROOT, "data/boat.csv");
-			lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData)));
-			
-			String line = null;
-			while ((line = lnr.readLine()) != null)
-			{
-				if (line.trim().length() == 0 || line.startsWith("#"))
-					continue;
-				L2BoatInstance boat = parseLine(line);
-				boat.spawn();
-				_staticItems.put(boat.getObjectId(), boat);
-				if (Config.DEBUG)
-				{
-					_log.info("Boat ID : " + boat.getObjectId());
-				}
-			}
-		}
-		catch (FileNotFoundException e)
-		{
-			_initialized = false;
-			_log.warning("boat.csv is missing in data folder");
-		}
-		catch (Exception e)
-		{
-			_initialized = false;
-			_log.log(Level.WARNING, "Error while creating boat table " + e.getMessage(), e);
-		}
-		finally
-		{
-			try
-			{
-				lnr.close();
-			}
-			catch (Exception e1)
-			{ /* ignore problems */
-			}
-		}
-	}
-	
-	/**
-	 * @param line
-	 * @return
-	 */
-	private L2BoatInstance parseLine(String line)
-	{
-		L2BoatInstance boat;
-		StringTokenizer st = new StringTokenizer(line, ";");
-		
-		String name = st.nextToken();
-		int id = Integer.parseInt(st.nextToken());
-		int xspawn = Integer.parseInt(st.nextToken());
-		int yspawn = Integer.parseInt(st.nextToken());
-		int zspawn = Integer.parseInt(st.nextToken());
-		int heading = Integer.parseInt(st.nextToken());
-		
+			return null;
+
 		StatsSet npcDat = new StatsSet();
 		StatsSet npcDat = new StatsSet();
-		npcDat.set("npcId", id);
+		npcDat.set("npcId", boatId);
 		npcDat.set("level", 0);
 		npcDat.set("level", 0);
 		npcDat.set("jClass", "boat");
 		npcDat.set("jClass", "boat");
-		
+
 		npcDat.set("baseSTR", 0);
 		npcDat.set("baseSTR", 0);
 		npcDat.set("baseCON", 0);
 		npcDat.set("baseCON", 0);
 		npcDat.set("baseDEX", 0);
 		npcDat.set("baseDEX", 0);
 		npcDat.set("baseINT", 0);
 		npcDat.set("baseINT", 0);
 		npcDat.set("baseWIT", 0);
 		npcDat.set("baseWIT", 0);
 		npcDat.set("baseMEN", 0);
 		npcDat.set("baseMEN", 0);
-		
+
 		npcDat.set("baseShldDef", 0);
 		npcDat.set("baseShldDef", 0);
 		npcDat.set("baseShldRate", 0);
 		npcDat.set("baseShldRate", 0);
 		npcDat.set("baseAccCombat", 38);
 		npcDat.set("baseAccCombat", 38);
 		npcDat.set("baseEvasRate", 38);
 		npcDat.set("baseEvasRate", 38);
 		npcDat.set("baseCritRate", 38);
 		npcDat.set("baseCritRate", 38);
-		
+
 		// npcDat.set("name", "");
 		// npcDat.set("name", "");
 		npcDat.set("collision_radius", 0);
 		npcDat.set("collision_radius", 0);
 		npcDat.set("collision_height", 0);
 		npcDat.set("collision_height", 0);
@@ -164,59 +94,116 @@ public class BoatManager
 		npcDat.set("armor", 0);
 		npcDat.set("armor", 0);
 		npcDat.set("baseWalkSpd", 0);
 		npcDat.set("baseWalkSpd", 0);
 		npcDat.set("baseRunSpd", 0);
 		npcDat.set("baseRunSpd", 0);
-		npcDat.set("name", name);
 		npcDat.set("baseHpMax", 50000);
 		npcDat.set("baseHpMax", 50000);
 		npcDat.set("baseHpReg", 3.e-3f);
 		npcDat.set("baseHpReg", 3.e-3f);
 		npcDat.set("baseMpReg", 3.e-3f);
 		npcDat.set("baseMpReg", 3.e-3f);
 		npcDat.set("basePDef", 100);
 		npcDat.set("basePDef", 100);
 		npcDat.set("baseMDef", 100);
 		npcDat.set("baseMDef", 100);
 		L2CharTemplate template = new L2CharTemplate(npcDat);
 		L2CharTemplate template = new L2CharTemplate(npcDat);
-		boat = new L2BoatInstance(IdFactory.getInstance().getNextId(), template, name);
-		boat.getPosition().setHeading(heading);
-		boat.setXYZ(xspawn, yspawn, zspawn);
-		boat.setId(id);
-		// boat.spawnMe();
-		
-		int IdWaypoint1 = Integer.parseInt(st.nextToken());
-		int IdWTicket1 = Integer.parseInt(st.nextToken());
-		int ntx1 = Integer.parseInt(st.nextToken());
-		int nty1 = Integer.parseInt(st.nextToken());
-		int ntz1 = Integer.parseInt(st.nextToken());
-		String npc1 = st.nextToken();
-		String mess10_1 = st.nextToken();
-		String mess5_1 = st.nextToken();
-		String mess1_1 = st.nextToken();
-		String mess0_1 = st.nextToken();
-		String messb_1 = st.nextToken();
-		boat.setTrajet1(IdWaypoint1, IdWTicket1, ntx1, nty1, ntz1, npc1, mess10_1, mess5_1, mess1_1, mess0_1, messb_1);
-		IdWaypoint1 = Integer.parseInt(st.nextToken());
-		IdWTicket1 = Integer.parseInt(st.nextToken());
-		ntx1 = Integer.parseInt(st.nextToken());
-		nty1 = Integer.parseInt(st.nextToken());
-		ntz1 = Integer.parseInt(st.nextToken());
-		npc1 = st.nextToken();
-		mess10_1 = st.nextToken();
-		mess5_1 = st.nextToken();
-		mess1_1 = st.nextToken();
-		mess0_1 = st.nextToken();
-		messb_1 = st.nextToken();
-		boat.setTrajet2(IdWaypoint1, IdWTicket1, ntx1, nty1, ntz1, npc1, mess10_1, mess5_1, mess1_1, mess0_1, messb_1);
+		L2BoatInstance boat = new L2BoatInstance(IdFactory.getInstance().getNextId(), template);
+		_boats.put(boat.getObjectId(), boat);
+		boat.setHeading(heading);
+		boat.setXYZInvisible(x, y, z);
+		boat.spawnMe();
 		return boat;
 		return boat;
 	}
 	}
-	
-	// =========================================================
-	// Property - Public
+
 	/**
 	/**
 	 * @param boatId
 	 * @param boatId
 	 * @return
 	 * @return
 	 */
 	 */
 	public L2BoatInstance getBoat(int boatId)
 	public L2BoatInstance getBoat(int boatId)
 	{
 	{
-		if (_staticItems == null)
-			_staticItems = new FastMap<Integer, L2BoatInstance>();
-		return _staticItems.get(boatId);
+		return _boats.get(boatId);
 	}
 	}
-	
+
+	/**
+	 * Lock/unlock dock so only one ship can be docked
+	 * @param h Dock Id
+	 * @param value True if dock is locked
+	 */
+	public void dockShip(int h, boolean value)
+	{
+		try
+		{
+			_docksBusy[h] = value;
+		}
+		catch (ArrayIndexOutOfBoundsException e)
+		{}
+	}
+
+	/**
+	 * Check if dock is busy
+	 * @param h Dock Id
+	 * @return Trye if dock is locked
+	 */
+	public boolean dockBusy(int h)
+	{
+		try
+		{
+			return _docksBusy[h];
+		}
+		catch (ArrayIndexOutOfBoundsException e)
+		{
+			return false;
+		}
+	}
+
+	/**
+	 * Broadcast one packet in both path points 
+	 */
+	public void broadcastPacket(VehiclePathPoint point1, VehiclePathPoint point2, L2GameServerPacket packet)
+	{
+		double dx, dy;
+		final Collection<L2PcInstance> players = L2World.getInstance().getAllPlayers().values();
+		for (L2PcInstance player : players)
+		{
+			if (player == null)
+				continue;
+
+			dx = (double)player.getX() - point1.x;
+			dy = (double)player.getY() - point1.y;
+			if ((dx*dx + dy*dy) < BROADCAST_DISTANCE)
+				player.sendPacket(packet);
+			else
+			{
+				dx = (double)player.getX() - point2.x;
+				dy = (double)player.getY() - point2.y;
+				if ((dx*dx + dy*dy) < BROADCAST_DISTANCE)
+					player.sendPacket(packet);
+			}
+		}
+	}
+
+	/**
+	 * Broadcast several packets in both path points
+	 */
+	public void broadcastPackets(VehiclePathPoint point1, VehiclePathPoint point2, L2GameServerPacket... packets)
+	{
+		double dx, dy;
+		final Collection<L2PcInstance> players = L2World.getInstance().getAllPlayers().values();
+		for (L2PcInstance player : players)
+		{
+			if (player == null)
+				continue;
+			dx = (double)player.getX() - point1.x;
+			dy = (double)player.getY() - point1.y;
+			if ((dx*dx + dy*dy) < BROADCAST_DISTANCE)
+			{
+				for (L2GameServerPacket p : packets)
+					player.sendPacket(p);
+			}
+			else
+			{
+				dx = (double)player.getX() - point2.x;
+				dy = (double)player.getY() - point2.y;
+				if ((dx*dx + dy*dy) < BROADCAST_DISTANCE)
+					for (L2GameServerPacket p : packets)
+						player.sendPacket(p);
+			}
+		}
+	}
+
 	@SuppressWarnings("synthetic-access")
 	@SuppressWarnings("synthetic-access")
 	private static class SingletonHolder
 	private static class SingletonHolder
 	{
 	{

+ 6 - 0
L2_GameServer/java/com/l2jserver/gameserver/model/L2WorldRegion.java

@@ -29,6 +29,7 @@ import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.L2Playable;
+import com.l2jserver.gameserver.model.actor.L2Vehicle;
 import com.l2jserver.gameserver.model.zone.L2ZoneType;
 import com.l2jserver.gameserver.model.zone.L2ZoneType;
 import com.l2jserver.gameserver.model.zone.type.L2DerbyTrackZone;
 import com.l2jserver.gameserver.model.zone.type.L2DerbyTrackZone;
 import com.l2jserver.gameserver.model.zone.type.L2PeaceZone;
 import com.l2jserver.gameserver.model.zone.type.L2PeaceZone;
@@ -235,6 +236,11 @@ public final class L2WorldRegion
         				// stop the ai tasks
         				// stop the ai tasks
         				((L2AttackableAI) mob.getAI()).stopAITask();
         				((L2AttackableAI) mob.getAI()).stopAITask();
         			}
         			}
+        			else if (o instanceof L2Vehicle)
+        			{
+        				c++;
+        				((L2Vehicle)o).getKnownList().removeAllKnownObjects();
+        			}
         		}
         		}
         	}
         	}
             _log.fine(c+ " mobs were turned off");
             _log.fine(c+ " mobs were turned off");

+ 42 - 0
L2_GameServer/java/com/l2jserver/gameserver/model/VehiclePathPoint.java

@@ -0,0 +1,42 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model;
+
+public class VehiclePathPoint
+{
+	public int x;
+	public int y;
+	public int z;
+	public int moveSpeed;
+	public int rotationSpeed;
+
+	public VehiclePathPoint(int _x,int _y,int _z)
+	{
+		x = _x;
+		y = _y;
+		z = _z;
+		moveSpeed = 350;
+		rotationSpeed = 4000;
+	}
+
+	public VehiclePathPoint(int _x,int _y,int _z,int _m,int _r)
+	{
+		x = _x;
+		y = _y;
+		z = _z;
+		moveSpeed = _m;
+		rotationSpeed = _r;
+	}
+}

+ 1 - 18
L2_GameServer/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -60,8 +60,6 @@ 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;
 import com.l2jserver.gameserver.model.L2Skill.SkillTargetType;
 import com.l2jserver.gameserver.model.L2Skill.SkillTargetType;
-import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2MinionInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2MinionInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2NpcWalkerInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2NpcWalkerInstance;
@@ -4158,8 +4156,6 @@ public abstract class L2Character extends L2Object
 			&& !m.disregardingGeodata
 			&& !m.disregardingGeodata
 			&& GameTimeController.getGameTicks() % 10 == 0 // once a second to reduce possible cpu load
 			&& GameTimeController.getGameTicks() % 10 == 0 // once a second to reduce possible cpu load
 			&& GeoData.getInstance().hasGeo(xPrev, yPrev))
 			&& GeoData.getInstance().hasGeo(xPrev, yPrev))
-//			&& !(this instanceof L2BoatInstance)
-//			&& !(this instanceof L2AirShipInstance))
 		{
 		{
 			short geoHeight = GeoData.getInstance().getSpawnHeight(xPrev, yPrev, zPrev-30, zPrev+30, this.getObjectId());
 			short geoHeight = GeoData.getInstance().getSpawnHeight(xPrev, yPrev, zPrev-30, zPrev+30, this.getObjectId());
 			dz = m._zDestination - geoHeight;
 			dz = m._zDestination - geoHeight;
@@ -4198,16 +4194,8 @@ public abstract class L2Character extends L2Object
 		// if (Config.DEVELOPER) _log.warning("Move Ticks:" + (gameTicks - m._moveTimestamp) + ", distPassed:" + distPassed + ", distFraction:" + distFraction);
 		// if (Config.DEVELOPER) _log.warning("Move Ticks:" + (gameTicks - m._moveTimestamp) + ", distPassed:" + distPassed + ", distFraction:" + distFraction);
 		
 		
 		if (distFraction > 1) // already there
 		if (distFraction > 1) // already there
-		{
 			// Set the position of the L2Character to the destination
 			// Set the position of the L2Character to the destination
 			super.getPosition().setXYZ(m._xDestination, m._yDestination, m._zDestination);
 			super.getPosition().setXYZ(m._xDestination, m._yDestination, m._zDestination);
-			if (this instanceof L2BoatInstance)
-				((L2BoatInstance)this).updatePeopleInTheBoat(m._xDestination, m._yDestination, m._zDestination);
-			else if (this instanceof L2AirShipInstance)
-				((L2AirShipInstance)this).updatePeopleInTheAirShip(m._xDestination, m._yDestination, m._zDestination);
-			else
-				revalidateZone(false);
-		}
 		else
 		else
 		{
 		{
 			m._xAccurate += dx * distFraction;
 			m._xAccurate += dx * distFraction;
@@ -4215,13 +4203,8 @@ public abstract class L2Character extends L2Object
 			
 			
 			// Set the position of the L2Character to estimated after parcial move
 			// Set the position of the L2Character to estimated after parcial move
 			super.getPosition().setXYZ((int)(m._xAccurate), (int)(m._yAccurate), zPrev + (int)(dz * distFraction + 0.5));
 			super.getPosition().setXYZ((int)(m._xAccurate), (int)(m._yAccurate), zPrev + (int)(dz * distFraction + 0.5));
-			if(this instanceof L2BoatInstance )
-				((L2BoatInstance)this).updatePeopleInTheBoat((int)(m._xAccurate), (int)(m._yAccurate), zPrev + (int)(dz * distFraction + 0.5));
-			else if (this instanceof L2AirShipInstance)
-				((L2AirShipInstance)this).updatePeopleInTheAirShip(m._xDestination, m._yDestination, m._zDestination);
-			else
-				revalidateZone(false);
 		}
 		}
+		revalidateZone(false);
 
 
 		// Set the timer of last position update to now
 		// Set the timer of last position update to now
 		m._moveTimestamp = gameTicks;
 		m._moveTimestamp = gameTicks;

+ 351 - 0
L2_GameServer/java/com/l2jserver/gameserver/model/actor/L2Vehicle.java

@@ -0,0 +1,351 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model.actor;
+
+import java.util.Collection;
+
+import javolution.util.FastList;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.GameTimeController;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.ai.CtrlIntention;
+import com.l2jserver.gameserver.ai.L2CharacterAI;
+import com.l2jserver.gameserver.datatables.MapRegionTable;
+import com.l2jserver.gameserver.model.L2CharPosition;
+import com.l2jserver.gameserver.model.L2ItemInstance;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.VehiclePathPoint;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.knownlist.VehicleKnownList;
+import com.l2jserver.gameserver.model.actor.stat.VehicleStat;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
+import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
+import com.l2jserver.gameserver.templates.item.L2Weapon;
+import com.l2jserver.gameserver.util.Util;
+
+/**
+ * 
+ * @author DS
+ * 
+ */
+public class L2Vehicle extends L2Character
+{
+	protected final FastList<L2PcInstance> _passengers = new FastList<L2PcInstance>();
+	protected Location _oustLoc = null;
+	private Runnable _engine = null;
+	protected VehiclePathPoint[] _currentPath = null;
+	protected int _runState = 0;
+
+	public L2Vehicle(int objectId, L2CharTemplate template)
+	{
+		super(objectId, template);
+		setIsFlying(true);
+	}
+
+	public boolean isBoat()
+	{
+		return false;
+	}
+
+	public boolean isAirShip()
+	{
+		return false;
+	}
+
+	public void registerEngine(Runnable r)
+	{
+		if (_engine == null)
+			_engine = r;
+	}
+
+	public void runEngine(int delay)
+	{
+		if (_engine != null)
+			ThreadPoolManager.getInstance().scheduleGeneral(_engine, delay);
+	}
+
+	public void executePath(VehiclePathPoint[] path)
+	{
+		_currentPath = path;
+		_runState = 0;
+		if (path != null && path.length > 0)
+		{
+			final VehiclePathPoint point = _currentPath[0];
+			getStat().setMoveSpeed(point.moveSpeed);
+			getStat().setRotationSpeed(point.rotationSpeed);
+			getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(point.x, point.y, point.z, 0));
+			return;
+		}
+		getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
+	}
+
+	@Override
+	public boolean moveToNextRoutePoint()
+	{
+		_move = null;
+		if (_currentPath == null)
+			return false;
+
+		_runState++;
+		if (_runState < _currentPath.length)
+		{
+			final VehiclePathPoint point = _currentPath[_runState];
+			if (!isMovementDisabled())
+			{
+				getStat().setMoveSpeed(point.moveSpeed);
+				getStat().setRotationSpeed(point.rotationSpeed);
+
+				MoveData m = new MoveData();
+				m.disregardingGeodata = false;
+				m.onGeodataPathIndex = -1;
+				m._xDestination = point.x;
+				m._yDestination = point.y;
+				m._zDestination = point.z;
+				m._heading = 0;
+				setHeading(Util.calculateHeadingFrom(getX(), getY(), point.x, point.y));
+
+				m._moveStartTime = GameTimeController.getGameTicks();
+				_move = m;
+
+				GameTimeController.getInstance().registerMovingObject(this);
+				return true;
+			}
+		}
+
+		runEngine(10);
+		return false;
+	}
+
+	@Override
+    public void initKnownList()
+    {
+		setKnownList(new VehicleKnownList(this));
+    }
+
+	@Override
+	public VehicleStat getStat()
+	{
+		return (VehicleStat)super.getStat();
+	}
+
+	@Override
+	public void initCharStat()
+	{
+		setStat(new VehicleStat(this));
+	}
+
+	public void setOustLoc(Location loc)
+	{
+		_oustLoc = loc;
+	}
+
+	public Location getOustLoc()
+	{
+		return _oustLoc != null ? _oustLoc : MapRegionTable.getInstance().getTeleToLocation(this, MapRegionTable.TeleportWhereType.Town);
+	}
+
+	public void oustPlayers()
+	{
+		if (!_passengers.isEmpty())
+		{
+			for (L2PcInstance player : _passengers)
+				oustPlayer(player);
+		}
+	}
+
+	public void oustPlayer(L2PcInstance player)
+	{
+		player.setVehicle(null);
+		player.setInVehiclePosition(null);
+	}
+
+	public boolean addPassenger(L2PcInstance player)
+	{
+		if (player == null || _passengers.contains(player))
+			return false;
+
+		_passengers.add(player);
+		return true;
+	}
+
+	public void removePassenger(L2PcInstance player)
+	{
+		try
+		{
+			_passengers.remove(player);
+		}
+		catch (Exception e)
+		{}
+	}
+
+	/**
+	 * Consume ticket(s) and teleport player from boat if no correct ticket
+	 * @param itemId Ticket itemId
+	 * @param count Ticket count
+	 * @param oustX
+	 * @param oustY
+	 * @param oustZ
+	 */
+	public void payForRide(int itemId, int count, int oustX, int oustY, int oustZ)
+	{
+		final Collection<L2PcInstance> passengers = getKnownList().getKnownPlayersInRadius(1000);
+		if (passengers != null && !passengers.isEmpty())
+		{
+			L2ItemInstance ticket;
+			InventoryUpdate iu;
+			for (L2PcInstance player : passengers)
+			{
+				if (player == null)
+					continue;
+				if (player.isInBoat() && player.getBoat() == this)
+				{
+					if (itemId > 0)
+					{
+						ticket = player.getInventory().getItemByItemId(itemId);
+						if (ticket == null || player.getInventory().destroyItem("Boat", ticket, count, player, this) == null)
+						{
+							player.sendPacket(new SystemMessage(SystemMessageId.NOT_CORRECT_BOAT_TICKET));
+							player.teleToLocation(oustX, oustY, oustZ, true);
+							continue;
+						}
+						iu = new InventoryUpdate();
+						iu.addModifiedItem(ticket);
+						player.sendPacket(iu);
+					}
+					addPassenger(player);
+				}
+			}
+		}
+	}
+
+	@Override
+	public boolean updatePosition(int gameTicks)
+	{
+		final boolean result = super.updatePosition(gameTicks);
+		if (!_passengers.isEmpty())
+		{
+			for (L2PcInstance player : _passengers)
+			{
+				if (player != null && player.getVehicle() == this)
+				{
+					player.getPosition().setXYZ(getX(), getY(), getZ());
+					player.revalidateZone(false);
+				}
+			}
+		}
+		return result;
+	}
+
+	@Override
+	public void teleToLocation(int x, int y, int z, int heading, boolean allowRandomOffset)
+	{
+		stopMove(null, false);
+		setIsTeleporting(true);
+
+		getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
+
+		for (L2PcInstance player : _passengers)
+		{
+			if (player != null)
+				player.teleToLocation(x, y, z);
+		}
+
+		broadcastPacket(new DeleteObject(this));
+
+		decayMe();
+		setXYZ(x, y, z);
+
+		// temporary fix for heading on teleports
+		if (heading != 0)
+			getPosition().setHeading(heading);
+
+		onTeleported();
+		revalidateZone(true);
+	}
+
+	@Override
+	public void stopMove(L2CharPosition pos, boolean updateKnownObjects)
+	{
+		_move = null;
+		if (pos != null)
+		{
+			setXYZ(pos.x, pos.y, pos.z);
+			setHeading(pos.heading);
+			revalidateZone(true);
+		}
+
+		if (Config.MOVE_BASED_KNOWNLIST && updateKnownObjects)
+			this.getKnownList().findObjects();
+	}
+
+	@Override
+	public void updateAbnormalEffect()
+	{
+	}
+	
+	@Override
+	public L2ItemInstance getActiveWeaponInstance()
+	{
+		return null;
+	}
+	
+	@Override
+	public L2Weapon getActiveWeaponItem()
+	{
+		return null;
+	}
+	
+	@Override
+	public L2ItemInstance getSecondaryWeaponInstance()
+	{
+		return null;
+	}
+	
+	@Override
+	public L2Weapon getSecondaryWeaponItem()
+	{
+		return null;
+	}
+	
+	@Override
+	public int getLevel()
+	{
+		return 0;
+	}
+	
+	@Override
+	public boolean isAutoAttackable(L2Character attacker)
+	{
+		return false;
+	}
+
+	@Override
+	public void setAI(L2CharacterAI newAI)
+	{
+		if (_ai == null)
+			_ai = newAI;
+	}
+
+	public class AIAccessor extends L2Character.AIAccessor
+	{
+		@Override
+		public void detachAI()
+		{}
+	}
+}

+ 5 - 7
L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2AirShipControllerInstance.java

@@ -27,7 +27,7 @@ import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
  */
  */
 public class L2AirShipControllerInstance extends L2NpcInstance
 public class L2AirShipControllerInstance extends L2NpcInstance
 {
 {
-	private boolean _isBoardAllowed = false;
+	private L2AirShipInstance _ship = null;
 
 
 	/**
 	/**
 	 * @param objectId
 	 * @param objectId
@@ -61,11 +61,9 @@ public class L2AirShipControllerInstance extends L2NpcInstance
 				return;
 				return;
 			}
 			}
 
 
-			L2AirShipInstance ship = AirShipManager.getInstance().getAirShip();
-
-			if (ship.isInDock() && _isBoardAllowed)
+			if (_ship != null)
 			{
 			{
-				ship.onPlayerBoarding(player);
+				_ship.addPassenger(player);
 				return;
 				return;
 			}
 			}
 		}
 		}
@@ -78,8 +76,8 @@ public class L2AirShipControllerInstance extends L2NpcInstance
 		broadcastPacket(new NpcSay(getObjectId(), 1, getNpcId(), message));
 		broadcastPacket(new NpcSay(getObjectId(), 1, getNpcId(), message));
 	}
 	}
 
 
-	public void setIsBoardAllowed(boolean val)
+	public void dockShip(L2AirShipInstance ship)
 	{
 	{
-		_isBoardAllowed = val;
+		_ship = ship;
 	}
 	}
 }
 }

+ 35 - 583
L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2AirShipInstance.java

@@ -14,643 +14,95 @@
  */
  */
 package com.l2jserver.gameserver.model.actor.instance;
 package com.l2jserver.gameserver.model.actor.instance;
 
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.LineNumberReader;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
 
 
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.GameTimeController;
-import com.l2jserver.gameserver.ThreadPoolManager;
-import com.l2jserver.gameserver.ai.L2CharacterAI;
-import com.l2jserver.gameserver.instancemanager.AirShipManager;
-import com.l2jserver.gameserver.model.L2ItemInstance;
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.actor.knownlist.VehicleKnownList;
-import com.l2jserver.gameserver.model.actor.stat.VehicleStat;
+import com.l2jserver.gameserver.ai.L2AirShipAI;
+import com.l2jserver.gameserver.model.L2CharPosition;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.actor.L2Vehicle;
 import com.l2jserver.gameserver.network.serverpackets.ExAirShipInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExAirShipInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExGetOffAirShip;
 import com.l2jserver.gameserver.network.serverpackets.ExGetOffAirShip;
 import com.l2jserver.gameserver.network.serverpackets.ExGetOnAirShip;
 import com.l2jserver.gameserver.network.serverpackets.ExGetOnAirShip;
 import com.l2jserver.gameserver.network.serverpackets.ExMoveToLocationAirShip;
 import com.l2jserver.gameserver.network.serverpackets.ExMoveToLocationAirShip;
 import com.l2jserver.gameserver.network.serverpackets.ExStopMoveAirShip;
 import com.l2jserver.gameserver.network.serverpackets.ExStopMoveAirShip;
 import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
 import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
-import com.l2jserver.gameserver.templates.item.L2Weapon;
 import com.l2jserver.util.Point3D;
 import com.l2jserver.util.Point3D;
 
 
-import javolution.util.FastList;
-import javolution.util.FastMap;
-
 /**
 /**
  * Flying airships. Very similar to Maktakien boats (see L2BoatInstance) but these do fly :P
  * Flying airships. Very similar to Maktakien boats (see L2BoatInstance) but these do fly :P
  *
  *
- * @author  DrHouse
+ * @author  DrHouse, reworked by DS
  */
  */
-public class L2AirShipInstance extends L2Character
+public class L2AirShipInstance extends L2Vehicle
 {
 {
-	protected final FastList<L2PcInstance> _passengers = new FastList<L2PcInstance>();
 	protected static final Logger _airShiplog = Logger.getLogger(L2AirShipInstance.class.getName());
 	protected static final Logger _airShiplog = Logger.getLogger(L2AirShipInstance.class.getName());
 	
 	
-	private class L2AirShipTrajet
-	{
-		private Map<Integer, L2AirShipPoint> _path;
-		public int idWaypoint;
-		public int max;
-		
-		protected class L2AirShipPoint
-		{
-			public int speed1 = 350;
-			//public int speed2 = 4000;
-			public int x;
-			public int y;
-			public int z;
-			public int time;
-		}
-		/**
-		 * @param idWaypoint
-
-		 */
-		public L2AirShipTrajet(int pIdWaypoint)
-		{
-			idWaypoint = pIdWaypoint;
-			loadBoatPath();
-		}
-		/**
-		 * @param line
-		 * @return
-		 */
-		public void parseLine(String line)
-		{
-			_path = new FastMap<Integer, L2AirShipPoint>();
-			StringTokenizer st = new StringTokenizer(line, ";");
-			Integer.parseInt(st.nextToken());
-			max = Integer.parseInt(st.nextToken());
-			for (int i = 0; i < max; i++)
-			{
-				L2AirShipPoint bp = new L2AirShipPoint();
-				bp.x = Integer.parseInt(st.nextToken());
-				bp.y = Integer.parseInt(st.nextToken());
-				bp.z = Integer.parseInt(st.nextToken());
-				bp.time = Integer.parseInt(st.nextToken());
-				_path.put(i, bp);
-			}
-		}
-		/**
-		 * 
-		 */
-		private void loadBoatPath()
-		{
-			LineNumberReader lnr = null;
-			try
-			{
-				File doorData = new File(Config.DATAPACK_ROOT, "data/airshippath.csv");
-				lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData)));
-				
-				String line = null;
-				while ((line = lnr.readLine()) != null)
-				{
-					if (line.trim().length() == 0
-					        || !line.startsWith(idWaypoint + ";"))
-						continue;
-					parseLine(line);
-					return;
-				}
-				_airShiplog.warning("No path for airShip!!!");
-			}
-			catch (FileNotFoundException e)
-			{
-				_airShiplog.warning("airship.csv is missing in data folder");
-			}
-			catch (Exception e)
-			{
-				_airShiplog.log(Level.WARNING, "Error while creating airship table " + e.getMessage(), e);
-			}
-			finally
-			{
-				try
-				{
-					lnr.close();
-				}
-				catch (Exception e1)
-				{ /* ignore problems */
-				}
-			}
-		}
-	
-		/**
-		 * @param state
-		 * @return
-		 */
-        public int state(int state, L2AirShipInstance _boat)
-		{
-			if (state < max)
-			{
-				L2AirShipPoint bp = _path.get(state);
-				
-				getStat().setMoveSpeed(bp.speed1);
-				getStat().setRotationSpeed(4000); // hardcoded for now
-				_boat._easi = new ExMoveToLocationAirShip(L2AirShipInstance.this,bp.x, bp.y, bp.z);
-				_boat.moveAirShipToLocation(bp.x, bp.y, bp.z, bp.speed1);
-				if (bp.time == 0)
-					bp.time = 1;
-				_boat.broadcastPacket(_boat._easi);
-				return bp.time;
-			}
-			else
-				return 0;
-		}
-		
-	}
-	
-	protected L2AirShipTrajet _t1;
-	protected L2AirShipTrajet _t2;
-	protected L2AirShipTrajet _t3;
-	protected L2AirShipTrajet _t4;
-	protected int _cycle = 0;
-	protected int _runstate = 0;
-	protected ExMoveToLocationAirShip _easi = null;
-	
 	public L2AirShipInstance(int objectId, L2CharTemplate template)
 	public L2AirShipInstance(int objectId, L2CharTemplate template)
 	{
 	{
 		super(objectId, template);
 		super(objectId, template);
 		setInstanceType(InstanceType.L2AirShipInstance);
 		setInstanceType(InstanceType.L2AirShipInstance);
-		setAI(new L2CharacterAI(new AIAccessor()));
-	}	
-	
-	@Override
-    public void initKnownList()
-    {
-		setKnownList(new VehicleKnownList(this));
-    }
+		setAI(new L2AirShipAI(new AIAccessor()));
+	}
 
 
 	@Override
 	@Override
-	public VehicleStat getStat()
+	public boolean isAirShip()
 	{
 	{
-		return (VehicleStat)super.getStat();
+		return true;
 	}
 	}
 
 
 	@Override
 	@Override
-	public void initCharStat()
+	public boolean moveToNextRoutePoint()
 	{
 	{
-		setStat(new VehicleStat(this));
-	}
+		final boolean result = super.moveToNextRoutePoint();
+		if (result)
+			broadcastPacket(new ExMoveToLocationAirShip(this));
 
 
-	/**
-	 * @param x
-	 * @param y
-	 * @param z
-	 */
-	public void moveAirShipToLocation(int x, int y, int z, float speed)
-	{
-		final int curX = getX();
-		final int curY = getY();
-		
-		// Calculate distance (dx,dy) between current position and destination
-		final int dx = (x - curX);
-		final int dy = (y - curY);
-		double distance = Math.sqrt(dx * dx + dy * dy);
-		
-		if (Config.DEBUG)
-			_airShiplog.fine("distance to target:" + distance);
-		
-		// Define movement angles needed
-		// ^
-		// | X (x,y)
-		// | /
-		// | /distance
-		// | /
-		// |/ angle
-		// X ---------->
-		// (curx,cury)
-		
-		double cos;
-		double sin;
-		sin = dy / distance;
-		cos = dx / distance;
-		// Create and Init a MoveData object
-		MoveData m = new MoveData();
-		
-		// Caclulate the Nb of ticks between the current position and the
-		// destination
-		int ticksToMove = (int) (GameTimeController.TICKS_PER_SECOND * distance / speed);
-		
-		// Calculate and set the heading of the L2Character
-		int heading = (int) (Math.atan2(-sin, -cos) * 10430.378350470452724949566316381);
-		heading += 32768;
-		getPosition().setHeading(heading);
-		
-		if (Config.DEBUG)
-			_airShiplog.fine("dist:" + distance + "speed:" + speed + " ttt:"
-			        + ticksToMove + " heading:" + heading);
-		
-		m._xDestination = x;
-		m._yDestination = y;
-		m._zDestination = z; // this is what was requested from client
-		m._heading = 0; // initial value for coordinate sync
-		m.onGeodataPathIndex = -1; // Initialize not on geodata path
-		m.disregardingGeodata = true;
-		m._moveStartTime = GameTimeController.getGameTicks();
-		
-		if (Config.DEBUG)
-			_airShiplog.fine("time to target:" + ticksToMove);
-		
-		// Set the L2Character _move object to MoveData object
-		_move = m;
-		
-		// Add the L2Character to movingObjects of the GameTimeController
-		// The GameTimeController manage objects movement
-		GameTimeController.getInstance().registerMovingObject(this);
-	}
-	
-	class AirShipCaptain implements Runnable
-	{
-		private L2AirShipInstance _airShip;
-		
-		/**
-		 * @param i
-		 * @param instance
-		 */
-		public AirShipCaptain(L2AirShipInstance instance)
-		{
-			_airShip = instance;
-		}
-		
-		public void run()
-		{
-			_airShip.begin();
-		}
-	}
-	class AirShiprun implements Runnable
-	{
-		private int _state;
-		
-		private L2AirShipInstance _airShip;
-		
-		/**
-		 * @param i
-		 * @param instance
-		 */
-		public AirShiprun(int i, L2AirShipInstance instance)
-		{
-			_state = i;
-			_airShip = instance;
-		}
-		
-		public void run()
-		{
-			_airShip._easi = null;
-			if (_airShip._cycle == 1)
-			{
-				int time = _airShip._t1.state(_state, _airShip);
-				if (time == 0)
-				{
-					_airShip._cycle = 2;
-					teleportAirShip(-167874,256731,-509,41035);
-					AirShiprun asr = new AirShiprun(0, _airShip);
-					ThreadPoolManager.getInstance().scheduleGeneral(asr, 5000);
-				}
-				else
-					_state++;
-			}
-			else if (_airShip._cycle == 2)
-			{
-				int time = _airShip._t2.state(_state, _airShip);
-				if (time == 0)
-				{
-					setIsInDock(true);
-					for (L2PcInstance player : _passengers)
-					{
-						if (player == null)
-							continue;
-						oustPlayer(player);
-					}
-					airShipControllerShout(32607,true);
-					AirShipCaptain asc = new AirShipCaptain(_airShip);
-					ThreadPoolManager.getInstance().scheduleGeneral(asc, 60000);
-				}
-				else
-					_state++;
-			}
-			else if (_airShip._cycle == 3)
-			{
-				int time = _airShip._t3.state(_state, _airShip);
-				if (time == 0)
-				{
-					_airShip._cycle = 4;
-					teleportAirShip(-157261,255664,221,64781);
-					AirShiprun asr = new AirShiprun(0, _airShip);
-					ThreadPoolManager.getInstance().scheduleGeneral(asr, 5000);
-				}
-				else
-					_state++;
-			}
-			else if (_airShip._cycle == 4)
-			{
-				int time = _airShip._t4.state(_state, _airShip);
-				if (time == 0)
-				{
-					setIsInDock(true);
-					for (L2PcInstance player : _passengers)
-					{
-						if (player == null)
-							continue;
-						oustPlayer(player);
-					}
-					airShipControllerShout(32609,true);
-					AirShipCaptain asc = new AirShipCaptain(_airShip);
-					ThreadPoolManager.getInstance().scheduleGeneral(asc, 60000);
-				}
-				else
-					_state++;
-			}
-			_airShip._runstate = _state;
-		}
-	}
-	
-	/**
-	 * 
-	 */
-	public void evtArrived()
-	{
-		if (_runstate != 0)
-		{
-			AirShiprun asr = new AirShiprun(_runstate, this);
-			ThreadPoolManager.getInstance().executeTask(asr);
-		}
-	}
-	
-	public void airShipControllerShout(int npcId, boolean isArraived)
-	{
-		String message = "";
-		switch (npcId)
-		{
-			case 32607:
-				message = (isArraived ? "The regurarly scheduled airship has arrived. It will depart for the Aden continent in 1 minute." : "The regurarly scheduled airship that flies to the Aden continent has departed.");
-				break;
-			case 32609:
-				message = (isArraived ? "The regurarly scheduled airship has arrived. It will depart for the Gracia continent in 1 minute." : "The regurarly scheduled airship that flies to the Gracia continent has departed.");
-				break;
-			default:
-				_log.warning("Invalid AirShipController npcId: " + npcId);
-				return;
-		}
-		for (L2AirShipControllerInstance asci : AirShipManager.getInstance().getATCs())
-			if (asci != null && asci.getNpcId() == npcId)
-			{
-				asci.setIsBoardAllowed(isArraived);
-				asci.broadcastMessage(message);
-			}
+		return result;
 	}
 	}
 
 
-	public ExMoveToLocationAirShip getAirShipInfo()
-	{
-		return _easi;
-	}
-	
-	public void beginCycle()
-	{
-		AirShipCaptain asc = new AirShipCaptain( this);
-		ThreadPoolManager.getInstance().scheduleGeneral(asc, 60000);
-	}
-	
-	/**
-	 * @param destination
-	 * @param destination2
-	 * @param destination3
-	 */
-	private int lastx = -1;
-	private int lasty = -1;
-	private boolean _isInDock = true;
-	
-	public void updatePeopleInTheAirShip(int x, int y, int z)
-	{
-		
-		if (!_passengers.isEmpty())
-		{
-			if ((lastx == -1) || (lasty == -1))
-			{
-				lastx = x;
-				lasty = y;
-			}
-			else if ((x - lastx) * (x - lastx) + (y - lasty) * (y - lasty) > 2250000) // 1500 * 1500 =  2250000 
-			{
-				lastx = x;
-				lasty = y;
-			}
-			for (L2PcInstance player : _passengers)
-			{
-				if (player != null && player.isInAirShip())
-				{
-					if (player.getAirShip() == this)
-					{
-						// player.getKnownList().addKnownObject(this);
-						player.setXYZ(x, y, z);
-						player.revalidateZone(false);
-					}
-				}
-			}
-		}
-		
-	}
-	/**
-	 * @param i
-	 */
-	public void begin()
-	{
-		_cycle++;
-		if (_cycle == 1 || _cycle == 5)
-		{
-			_cycle = 1;
-			setIsInDock(false);
-			airShipControllerShout(32609,false);
-			AirShiprun asr = new AirShiprun(0, this);
-			ThreadPoolManager.getInstance().executeTask(asr);
-		}
-		else if (_cycle == 3)
-		{
-			setIsInDock(false);
-			airShipControllerShout(32607,false);
-			AirShiprun asr = new AirShiprun(0, this);
-			ThreadPoolManager.getInstance().executeTask(asr);
-		}
-	}
-	
-	public void spawn()
-	{
-		_cycle = 0;
-		beginCycle();
-		broadcastPacket(new ExAirShipInfo(this));
-	}
-	
-	/**
-	 * @param idWaypoint1
-	 */
-	public void setTrajet1(int idWaypoint1)
-	{
-		_t1 = new L2AirShipTrajet(idWaypoint1);
-	}
-	
-	public void setTrajet2(int idWaypoint2)
-	{
-		_t2 = new L2AirShipTrajet(idWaypoint2);
-	}
-	
-	public void setTrajet3(int idWaypoint3)
-	{
-		_t3 = new L2AirShipTrajet(idWaypoint3);
-	}
-	public void setTrajet4(int idWaypoint4)
-	{
-		_t4 = new L2AirShipTrajet(idWaypoint4);
-	}
-	
-	public void setIsInDock(boolean val)
-	{
-		_isInDock = val;
-	}
-	public boolean isInDock()
-	{
-		return _isInDock;
-	}
-	public void onPlayerBoarding(L2PcInstance player)
+	@Override
+	public boolean addPassenger(L2PcInstance player)
 	{
 	{
-		// cannot board
-		if (!isInDock()	|| _passengers.contains(player))
-			return;
-			
-		_passengers.add(player);
-		player.setAirShip(this);
+		if (!super.addPassenger(player))
+			return false;
+
+		player.setVehicle(this);
 		player.setInVehiclePosition(new Point3D(0,0,0));
 		player.setInVehiclePosition(new Point3D(0,0,0));
 		player.broadcastPacket(new ExGetOnAirShip(player, this));
 		player.broadcastPacket(new ExGetOnAirShip(player, this));
 		player.getKnownList().removeAllKnownObjects();
 		player.getKnownList().removeAllKnownObjects();
 		player.setXYZ(getX(), getY(), getZ());
 		player.setXYZ(getX(), getY(), getZ());
 		player.revalidateZone(true);
 		player.revalidateZone(true);
+		return true;
 	}
 	}
 
 
+	@Override
 	public void oustPlayer(L2PcInstance player)
 	public void oustPlayer(L2PcInstance player)
 	{
 	{
-		final int x,y,z;
-		if (_cycle == 1 || _cycle == 4)
-		{
-			x = -149379;
-			y = 255246;
-			z = -80;
-		}
-		else
-		{
-			x = -186563;
-			y = 243590;
-			z = 2608;			
-		}
-		removePassenger(player);
-		player.setAirShip(null);
-		player.setInVehiclePosition(null);
+		super.oustPlayer(player);
+
+		final Location loc = getOustLoc();
 		if (player.isOnline() > 0)
 		if (player.isOnline() > 0)
 		{
 		{
-			player.broadcastPacket(new ExGetOffAirShip(player, this, x ,y ,z));
+			player.broadcastPacket(new ExGetOffAirShip(player, this, loc.getX(), loc.getY(), loc.getZ()));
 			player.getKnownList().removeAllKnownObjects();
 			player.getKnownList().removeAllKnownObjects();
-			player.setXYZ(x, y, z);
+			player.setXYZ(loc.getX(), loc.getY(), loc.getZ());
 			player.revalidateZone(true);
 			player.revalidateZone(true);
 		}
 		}
 		else
 		else
-			player.setXYZInvisible(x, y, z); // disconnects handling
-	}
-
-	public void removePassenger(L2PcInstance player)
-	{
-		try
-		{
-			_passengers.remove(player);
-		}
-		catch (Exception e)
-		{}
+			player.setXYZInvisible(loc.getX(), loc.getY(), loc.getZ());
 	}
 	}
 
 
-	public void teleportAirShip(int x, int y, int z,int heading)
-	{
-		teleToLocation(x, y, z, heading, false);
-		final ExStopMoveAirShip as = new ExStopMoveAirShip(this);
-		final ExAirShipInfo ai = new ExAirShipInfo(this);
-		final ExGetOnAirShip[] gas = new ExGetOnAirShip[_passengers.size()];
-		int i = 0;
-		for (L2PcInstance player : _passengers)
-			gas[i++] = (new ExGetOnAirShip(player, this));
-
-		for (L2PcInstance player : _passengers)
-		{
-			player.sendPacket(as);
-			player.setXYZ(x, y, z);
-			player.sendPacket(ai);
-			for (ExGetOnAirShip packet : gas)
-				player.sendPacket(packet);
-
-			player.revalidateZone(true);
-		}
-	}
-	
 	@Override
 	@Override
-	public void updateAbnormalEffect()
+	public void stopMove(L2CharPosition pos, boolean updateKnownObjects)
 	{
 	{
+		super.stopMove(pos, updateKnownObjects);
+
+		broadcastPacket(new ExStopMoveAirShip(this));
 	}
 	}
-	
-	@Override
-	public L2ItemInstance getActiveWeaponInstance()
-	{
-		return null;
-	}
-	
-	@Override
-	public L2Weapon getActiveWeaponItem()
-	{
-		return null;
-	}
-	
-	@Override
-	public L2ItemInstance getSecondaryWeaponInstance()
-	{
-		return null;
-	}
-	
-	@Override
-	public L2Weapon getSecondaryWeaponItem()
-	{
-		return null;
-	}
-	
-	@Override
-	public int getLevel()
-	{
-		return 0;
-	}
-	
-	@Override
-	public boolean isAutoAttackable(L2Character attacker)
-	{
-		return false;
-	}
-	
-	@Override
-	public void setAI(L2CharacterAI newAI)
-	{
-		if (_ai == null)
-			_ai = newAI;
-	}
-	
-	public class AIAccessor extends L2Character.AIAccessor
-	{
-		@Override
-		public void detachAI()
-		{}
-	}
-	
+
 	@Override
 	@Override
 	public void sendInfo(L2PcInstance activeChar)
 	public void sendInfo(L2PcInstance activeChar)
 	{
 	{
-		if (this != activeChar.getAirShip())
-			activeChar.sendPacket(new ExAirShipInfo(this));
+		activeChar.sendPacket(new ExAirShipInfo(this));
 	}
 	}
 }
 }

+ 26 - 806
L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2BoatInstance.java

@@ -14,852 +14,72 @@
  */
  */
 package com.l2jserver.gameserver.model.actor.instance;
 package com.l2jserver.gameserver.model.actor.instance;
 
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.LineNumberReader;
-import java.util.Collection;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
 
 
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.GameTimeController;
-import com.l2jserver.gameserver.ThreadPoolManager;
-import com.l2jserver.gameserver.ai.L2CharacterAI;
-import com.l2jserver.gameserver.model.L2ItemInstance;
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.actor.knownlist.VehicleKnownList;
-import com.l2jserver.gameserver.model.actor.stat.VehicleStat;
-import com.l2jserver.gameserver.network.clientpackets.Say2;
-import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
-import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
-import com.l2jserver.gameserver.network.serverpackets.PlaySound;
-import com.l2jserver.gameserver.network.serverpackets.VehicleCheckLocation;
+import com.l2jserver.gameserver.ai.L2BoatAI;
+import com.l2jserver.gameserver.model.L2CharPosition;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.actor.L2Vehicle;
 import com.l2jserver.gameserver.network.serverpackets.VehicleDeparture;
 import com.l2jserver.gameserver.network.serverpackets.VehicleDeparture;
 import com.l2jserver.gameserver.network.serverpackets.VehicleInfo;
 import com.l2jserver.gameserver.network.serverpackets.VehicleInfo;
 import com.l2jserver.gameserver.network.serverpackets.VehicleStarted;
 import com.l2jserver.gameserver.network.serverpackets.VehicleStarted;
 import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
 import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
-import com.l2jserver.gameserver.templates.item.L2Weapon;
-import com.l2jserver.gameserver.util.Util;
-
-import javolution.util.FastList;
-import javolution.util.FastMap;
 
 
 /**
 /**
- * @author Maktakien
+ * @author Maktakien, reworked by DS
  * 
  * 
  */
  */
-public class L2BoatInstance extends L2Character
+public class L2BoatInstance extends L2Vehicle
 {
 {
 	protected static final Logger _logBoat = Logger.getLogger(L2BoatInstance.class.getName());
 	protected static final Logger _logBoat = Logger.getLogger(L2BoatInstance.class.getName());
-	protected final FastList<L2PcInstance> _passengers = new FastList<L2PcInstance>();
-	
-	private class L2BoatTrajet
-	{
-		private Map<Integer, L2BoatPoint> _path;
-		
-		public int idWaypoint1;
-		
-		public int idWTicket1;
-		
-		public int ntx1;
-		
-		public int nty1;
-		
-		public int ntz1;
-		
-		public int max;
-		
-		public String boatName;
-		
-		public String npc1;
-		
-		public String sysmess10_1;
-		
-		public String sysmess5_1;
-		
-		public String sysmess1_1;
-		
-		public String sysmessb_1;
-		
-		public String sysmess0_1;
-		
-		protected class L2BoatPoint
-		{
-			public int speed1;
-			
-			public int speed2;
-			
-			public int x;
-			
-			public int y;
-			
-			public int z;
-			
-			public int time;
-		}
-		
-		/**
-		 * @param idWaypoint1
-		 * @param idWTicket1
-		 * @param ntx1
-		 * @param nty1
-		 * @param ntz1
-		 * @param idnpc1
-		 * @param sysmess10_1
-		 * @param sysmess5_1
-		 * @param sysmess1_1
-		 * @param sysmessb_1
-		 */
-		public L2BoatTrajet(int pIdWaypoint1, int pIdWTicket1, int pNtx1, int pNty1, int pNtz1, String pNpc1, String pSysmess10_1,
-				String pSysmess5_1, String pSysmess1_1, String pSysmess0_1, String pSysmessb_1, String pBoatname)
-		{
-			idWaypoint1 = pIdWaypoint1;
-			idWTicket1 = pIdWTicket1;
-			ntx1 = pNtx1;
-			nty1 = pNty1;
-			ntz1 = pNtz1;
-			npc1 = pNpc1;
-			sysmess10_1 = pSysmess10_1;
-			sysmess5_1 = pSysmess5_1;
-			sysmess1_1 = pSysmess1_1;
-			sysmessb_1 = pSysmessb_1;
-			sysmess0_1 = pSysmess0_1;
-			boatName = pBoatname;
-			loadBoatPath();
-		}
-		
-		/**
-		 * @param line
-		 * @return
-		 */
-		public void parseLine(String line)
-		{
-			// L2BoatPath bp = new L2BoatPath();
-			_path = new FastMap<Integer, L2BoatPoint>();
-			StringTokenizer st = new StringTokenizer(line, ";");
-			Integer.parseInt(st.nextToken());
-			max = Integer.parseInt(st.nextToken());
-			for (int i = 0; i < max; i++)
-			{
-				L2BoatPoint bp = new L2BoatPoint();
-				bp.speed1 = Integer.parseInt(st.nextToken());
-				bp.speed2 = Integer.parseInt(st.nextToken());
-				bp.x = Integer.parseInt(st.nextToken());
-				bp.y = Integer.parseInt(st.nextToken());
-				bp.z = Integer.parseInt(st.nextToken());
-				bp.time = Integer.parseInt(st.nextToken());
-				_path.put(i, bp);
-			}
-		}
-		
-		/**
-		 * 
-		 */
-		private void loadBoatPath()
-		{
-			LineNumberReader lnr = null;
-			try
-			{
-				File doorData = new File(Config.DATAPACK_ROOT, "data/boatpath.csv");
-				lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData)));
-				
-				String line = null;
-				while ((line = lnr.readLine()) != null)
-				{
-					if (line.trim().length() == 0 || !line.startsWith(idWaypoint1 + ";"))
-						continue;
-					parseLine(line);
-					return;
-				}
-				_logBoat.warning("No path for boat " + boatName + " !!!");
-			}
-			catch (FileNotFoundException e)
-			{
-				_logBoat.warning("boatpath.csv is missing in data folder");
-			}
-			catch (Exception e)
-			{
-				_logBoat.log(Level.WARNING, "Error while creating boat table " + e.getMessage(), e);
-			}
-			finally
-			{
-				try
-				{
-					lnr.close();
-				}
-				catch (Exception e1)
-				{ /* ignore problems */
-				}
-			}
-		}
-		
-		/**
-		 * @param state
-		 * @return
-		 */
-		public int state(int state, L2BoatInstance _boat)
-		{
-			if (state < max)
-			{
-				L2BoatPoint bp = _path.get(state);
-				double dx = (_boat.getX() - bp.x);
-				double dy = (_boat.getY() - bp.y);
-				double distance = Math.sqrt(dx * dx + dy * dy);
-				double cos;
-				double sin;
-				sin = dy / distance;
-				cos = dx / distance;
-				
-				_boat.getPosition().setHeading(Util.calculateHeadingFrom(cos, sin));
-				
-				getStat().setMoveSpeed(bp.speed1);
-				getStat().setRotationSpeed(bp.speed2);
-				_boat.moveToLocation(bp.x, bp.y, bp.z, (float) bp.speed1);
-				if (bp.time == 0)
-					bp.time = 1;
 
 
-//				_boat.broadcastPacket(new VehicleInfo(_boat));
-				_boat.broadcastPacket(new VehicleDeparture(_boat));
-				return bp.time;
-			}
-			else
-			{
-				return 0;
-			}
-		}
-		
-	}
-	
-	private String _name;
-	
-	protected L2BoatTrajet _t1;
-	
-	protected L2BoatTrajet _t2;
-	
-	protected int _cycle = 0;
-	
-	public L2BoatInstance(int objectId, L2CharTemplate template, String name)
+	public L2BoatInstance(int objectId, L2CharTemplate template)
 	{
 	{
 		super(objectId, template);
 		super(objectId, template);
 		setInstanceType(InstanceType.L2BoatInstance);
 		setInstanceType(InstanceType.L2BoatInstance);
-		setAI(new L2CharacterAI(new AIAccessor()));
-		/*
-		 * super.setStat(new DoorStat(new L2DoorInstance[] {this}));
-		 * super.setStatus(new DoorStatus(new L2DoorInstance[] {this}));
-		 */
-		_name = name;
-	}
-	
-	@Override
-    public void initKnownList()
-    {
-		setKnownList(new VehicleKnownList(this));
-    }
-	
-	@Override
-	public VehicleStat getStat()
-	{
-		return (VehicleStat)super.getStat();
+		setAI(new L2BoatAI(new AIAccessor()));
 	}
 	}
 
 
 	@Override
 	@Override
-	public void initCharStat()
+	public boolean isBoat()
 	{
 	{
-		setStat(new VehicleStat(this));
+		return true;
 	}
 	}
 
 
-	/**
-	 * @param x
-	 * @param y
-	 * @param z
-	 */
-	public void moveToLocation(int x, int y, int z, float speed)
-	{
-		final int curX = getX();
-		final int curY = getY();
-		
-		// Calculate distance (dx,dy) between current position and destination
-		final int dx = (x - curX);
-		final int dy = (y - curY);
-		double distance = Math.sqrt(dx * dx + dy * dy);
-		
-		if (Config.DEBUG)
-			_logBoat.fine("distance to target:" + distance);
-		
-		// Define movement angles needed
-		// ^
-		// | X (x,y)
-		// | /
-		// | /distance
-		// | /
-		// |/ angle
-		// X ---------->
-		// (curx,cury)
-		
-		double cos;
-		double sin;
-		sin = dy / distance;
-		cos = dx / distance;
-		// Create and Init a MoveData object
-		MoveData m = new MoveData();
-		
-		// Caclulate the Nb of ticks between the current position and the
-		// destination
-		int ticksToMove = (int) (GameTimeController.TICKS_PER_SECOND * distance / speed);
-		
-		// Calculate and set the heading of the L2Character
-		int heading = (int) (Math.atan2(-sin, -cos) * 10430.378350470452724949566316381);
-		heading += 32768;
-		getPosition().setHeading(heading);
-		
-		if (Config.DEBUG)
-			_logBoat.fine("dist:" + distance + "speed:" + speed + " ttt:" + ticksToMove + " heading:" + heading);
-		
-		m._xDestination = x;
-		m._yDestination = y;
-		m._zDestination = z; // this is what was requested from client
-		m._heading = 0; // initial value for coordinate sync
-		m.onGeodataPathIndex = -1; // Initialize not on geodata path
-		m.disregardingGeodata = true;
-		m._moveStartTime = GameTimeController.getGameTicks();
-		
-		if (Config.DEBUG)
-			_logBoat.fine("time to target:" + ticksToMove);
-		
-		// Set the L2Character _move object to MoveData object
-		_move = m;
-		
-		// Add the L2Character to movingObjects of the GameTimeController
-		// The GameTimeController manage objects movement
-		GameTimeController.getInstance().registerMovingObject(this);
-	}
-	
-	class BoatCaptain implements Runnable
-	{
-		private int _state;
-		
-		private L2BoatInstance _boat;
-		
-		/**
-		 * @param i
-		 * @param instance
-		 */
-		public BoatCaptain(int i, L2BoatInstance instance)
-		{
-			_state = i;
-			_boat = instance;
-		}
-		
-		public void run()
-		{
-			if (_boat.getId() == 5) // Rune <-> Primeval Isle
-			{
-				switch (_state)
-				{
-					case 1:
-						_boat.say(-1);
-						_boat.begin();
-						break;
-				}
-			}
-			else
-			{
-				BoatCaptain bc;
-				switch (_state)
-				{
-					case 1:
-						_boat.say(5);
-						bc = new BoatCaptain(2, _boat);
-						ThreadPoolManager.getInstance().scheduleGeneral(bc, 240000);
-						break;
-					case 2:
-						_boat.say(1);
-						bc = new BoatCaptain(3, _boat);
-						ThreadPoolManager.getInstance().scheduleGeneral(bc, 40000);
-						break;
-					case 3:
-						_boat.say(0);
-						bc = new BoatCaptain(4, _boat);
-						ThreadPoolManager.getInstance().scheduleGeneral(bc, 20000);
-						break;
-					case 4:
-						_boat.say(-1);
-						_boat.begin();
-						break;
-				}
-			}
-		}
-	}
-	
-	class Boatrun implements Runnable
-	{
-		private int _state;
-		
-		private L2BoatInstance _boat;
-		
-		/**
-		 * @param i
-		 * @param instance
-		 */
-		public Boatrun(int i, L2BoatInstance instance)
-		{
-			_state = i;
-			_boat = instance;
-		}
-		
-		public void run()
-		{
-			_boat.needOnVehicleCheckLocation = false;
-			if (_boat._cycle == 1)
-			{
-				int time = _boat._t1.state(_state, _boat);
-				if (time > 0)
-				{
-					_state++;
-					Boatrun bc = new Boatrun(_state, _boat);
-					ThreadPoolManager.getInstance().scheduleGeneral(bc, time);
-					
-				}
-				else if (time == 0)
-				{
-					_boat._cycle = 2;
-					_boat.say(10);
-					BoatCaptain bc = new BoatCaptain(1, _boat);
-					if (getId() == 5)
-						ThreadPoolManager.getInstance().scheduleGeneral(bc, 180000);
-					else
-						ThreadPoolManager.getInstance().scheduleGeneral(bc, 300000);
-				}
-				else
-				{
-					_boat.needOnVehicleCheckLocation = true;
-					_state++;
-					_boat._runstate = _state;
-				}
-			}
-			else if (_boat._cycle == 2)
-			{
-				int time = _boat._t2.state(_state, _boat);
-				if (time > 0)
-				{
-					_state++;
-					Boatrun bc = new Boatrun(_state, _boat);
-					ThreadPoolManager.getInstance().scheduleGeneral(bc, time);
-				}
-				else if (time == 0)
-				{
-					_boat._cycle = 1;
-					_boat.say(10);
-					BoatCaptain bc = new BoatCaptain(1, _boat);
-					if (getId() == 5)
-						ThreadPoolManager.getInstance().scheduleGeneral(bc, 180000);
-					else
-						ThreadPoolManager.getInstance().scheduleGeneral(bc, 300000);
-				}
-				else
-				{
-					_boat.needOnVehicleCheckLocation = true;
-					_state++;
-					_boat._runstate = _state;
-				}
-			}
-		}
-	}
-	
-	public int _runstate = 0;
-	
-	/**
-	 * 
-	 */
-	public void evtArrived()
-	{
-		
-		if (_runstate != 0)
-		{
-			// _runstate++;
-			Boatrun bc = new Boatrun(_runstate, this);
-			ThreadPoolManager.getInstance().scheduleGeneral(bc, 10);
-			_runstate = 0;
-		}
-	}
-	
-	/**
-	 * @return
-	 */
-	public int getId()
-	{
-		return _id;
-	}
-	
-	public void beginCycle()
-	{
-		say(10);
-		BoatCaptain bc = new BoatCaptain(1, this);
-		if (getId() == 5)
-			ThreadPoolManager.getInstance().scheduleGeneral(bc, 180000);
-		else
-			ThreadPoolManager.getInstance().scheduleGeneral(bc, 300000);
-	}
-	
-	/**
-	 * @param destination
-	 * @param destination2
-	 * @param destination3
-	 */
-	private int lastx = -1;
-	
-	private int lasty = -1;
-	
-	protected boolean needOnVehicleCheckLocation = false;
-	
-	private int _id;
-	
-	public void updatePeopleInTheBoat(int x, int y, int z)
-	{
-		
-		if (!_passengers.isEmpty())
-		{
-			boolean check = false;
-			if ((lastx == -1) || (lasty == -1))
-			{
-				check = true;
-				lastx = x;
-				lasty = y;
-			}
-			else if ((x - lastx) * (x - lastx) + (y - lasty) * (y - lasty) > 2250000) // 1500
-			// *
-			// 1500
-			// =
-			// 2250000
-			{
-				check = true;
-				lastx = x;
-				lasty = y;
-			}
-			VehicleCheckLocation vcl = null;
-			if (needOnVehicleCheckLocation == true)
-				vcl = new VehicleCheckLocation(this, x, y, z);
-
-			for (L2PcInstance player : _passengers)
-			{
-				if (player != null && player.isInBoat())
-				{
-					if (player.getBoat() == this)
-					{
-						player.getPosition().setXYZ(x, y, z);
-						player.revalidateZone(false);
-					}
-				}
-				if (check == true && vcl != null)
-					player.sendPacket(vcl);
-			}
-		}
-		
-	}
-	
-	/**
-	 * @param i
-	 */
-	public void begin()
-	{
-		_passengers.clear();
-		final Collection<L2PcInstance> knownPlayers = getKnownList().getKnownPlayersInRadius(1000);
-		if (knownPlayers != null && !knownPlayers.isEmpty())
-		{
-			//synchronized (getKnownList().getKnownPlayers())
-			{
-				for (L2PcInstance player : knownPlayers)
-				{
-					if (player.isInBoat() && player.getBoat() == this)
-						addPassenger(player);
-				}
-			}
-		}
-		ThreadPoolManager.getInstance().scheduleGeneral(new Boatrun(0, this), 0);
-		broadcastPacket(new VehicleStarted(this, 1));
-	}
-
-	private void addPassenger(L2PcInstance player)
+	@Override
+	public boolean moveToNextRoutePoint()
 	{
 	{
-		final int itemId;
-		if (_cycle == 1)
-			itemId = _t1.idWTicket1;
-		else
-			itemId = _t2.idWTicket1;
+		final boolean result = super.moveToNextRoutePoint();
+		if (result)
+			broadcastPacket(new VehicleDeparture(this));
 
 
-		if (itemId != 0)
-		{
-			final L2ItemInstance it = player.getInventory().getItemByItemId(itemId);
-			if ((it != null) && (it.getCount() >= 1))
-			{
-				player.getInventory().destroyItem("Boat", it, 1, player, this);
-				InventoryUpdate iu = new InventoryUpdate();
-				iu.addModifiedItem(it);
-				player.sendPacket(iu);
-			}
-			else
-			{
-				oustPlayer(player);
-				return;
-			}
-		}
-		_passengers.add(player);
+		return result;
 	}
 	}
 
 
+	@Override
 	public void oustPlayer(L2PcInstance player)
 	public void oustPlayer(L2PcInstance player)
 	{
 	{
-		final int x, y, z;
-		if (_cycle == 1)
-		{
-			x = _t1.ntx1;
-			y = _t1.nty1;
-			z = _t1.ntz1;
-		}
-		else
-		{
-			x = _t2.ntx1;
-			y = _t2.nty1;
-			z = _t2.ntz1;
-		}
-
-		removePassenger(player);
+		super.oustPlayer(player);
 
 
+		final Location loc = getOustLoc();
 		if (player.isOnline() > 0)
 		if (player.isOnline() > 0)
-			player.teleToLocation(x, y, z);
+			player.teleToLocation(loc.getX(), loc.getY(), loc.getZ());
 		else
 		else
-			player.setXYZInvisible(x, y, z); // disconnects handling
+			player.setXYZInvisible(loc.getX(), loc.getY(), loc.getZ()); // disconnects handling
 	}
 	}
 
 
-	public void removePassenger(L2PcInstance player)
-	{
-		try
-		{
-			_passengers.remove(player);
-		}
-		catch (Exception e)
-		{}
-	}
-
-	/**
-	 * @param i
-	 */
-	public void say(int i)
+	@Override
+	public void stopMove(L2CharPosition pos, boolean updateKnownObjects)
 	{
 	{
-		final Collection<L2PcInstance> knownPlayers = getKnownList().getKnownPlayers().values();
-		if (knownPlayers == null || knownPlayers.isEmpty())
-			return;
+		super.stopMove(pos, updateKnownObjects);
 
 
-		CreatureSay sm;
-		CreatureSay sm2 = null;
-		PlaySound ps;
-		switch (i)
-		{
-			case 10:
-				if (_cycle == 1)
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t1.npc1, _t1.sysmess10_1);
-					if (getId() == 5)
-						sm2 = new CreatureSay(0, Say2.SHOUT, _t1.npc1, _t1.sysmess5_1);
-				}
-				else
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t2.npc1, _t2.sysmess10_1);
-					if (getId() == 5)
-						sm2 = new CreatureSay(0, Say2.SHOUT, _t2.npc1, _t2.sysmess5_1);
-				}
-				ps = new PlaySound(0, "itemsound.ship_arrival_departure", 1, getObjectId(), getX(), getY(), getZ());
-				VehicleStarted vs = new VehicleStarted(this, 0);
-				VehicleInfo vi = new VehicleInfo(this);
-				for (L2PcInstance player : knownPlayers)
-				{
-					player.sendPacket(sm);
-					player.sendPacket(ps);
-					player.sendPacket(vs);
-					player.sendPacket(vi);
-					if (sm2 != null)
-						player.sendPacket(sm2);
-				}
-				break;
-			case 5:
-				if (_cycle == 1)
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t1.npc1, _t1.sysmess5_1);
-				}
-				else
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t2.npc1, _t2.sysmess5_1);
-				}
-				ps = new PlaySound(0, "itemsound.ship_5min", 1, getObjectId(), getX(), getY(), getZ());
-				for (L2PcInstance player : knownPlayers)
-				{
-					player.sendPacket(sm);
-					player.sendPacket(ps);
-				}
-				break;
-			case 1:
-
-				if (_cycle == 1)
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t1.npc1, _t1.sysmess1_1);
-				}
-				else
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t2.npc1, _t2.sysmess1_1);
-				}
-				ps = new PlaySound(0, "itemsound.ship_1min", 1, getObjectId(), getX(), getY(), getZ());
-				for (L2PcInstance player : knownPlayers)
-				{
-					player.sendPacket(sm);
-					player.sendPacket(ps);
-				}
-				break;
-			case 0:
-
-				if (_cycle == 1)
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t1.npc1, _t1.sysmess0_1);
-				}
-				else
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t2.npc1, _t2.sysmess0_1);
-				}
-				for (L2PcInstance player : knownPlayers)
-				{
-					player.sendPacket(sm);
-				}
-				break;
-			case -1:
-				if (_cycle == 1)
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t1.npc1, _t1.sysmessb_1);
-				}
-				else
-				{
-					sm = new CreatureSay(0, Say2.SHOUT, _t2.npc1, _t2.sysmessb_1);
-				}
-				ps = new PlaySound(0, "itemsound.ship_arrival_departure", 1, getObjectId(), getX(), getY(), getZ());
-				for (L2PcInstance player : knownPlayers)
-				{
-					player.sendPacket(sm);
-					player.sendPacket(ps);
-				}
-				break;
-		}
-	}
-	
-	/**
-	 * 
-	 */
-	public void spawn()
-	{
-		_cycle = 1;
-		beginCycle();
+		broadcastPacket(new VehicleStarted(this, 0));
 		broadcastPacket(new VehicleInfo(this));
 		broadcastPacket(new VehicleInfo(this));
 	}
 	}
-	
-	/**
-	 * @param idWaypoint1
-	 * @param idWTicket1
-	 * @param ntx1
-	 * @param nty1
-	 * @param ntz1
-	 * @param idnpc1
-	 * @param sysmess10_1
-	 * @param sysmess5_1
-	 * @param sysmess1_1
-	 * @param sysmessb_1
-	 */
-	public void setTrajet1(int idWaypoint1, int idWTicket1, int ntx1, int nty1, int ntz1, String idnpc1, String sysmess10_1,
-			String sysmess5_1, String sysmess1_1, String sysmess0_1, String sysmessb_1)
-	{
-		_t1 = new L2BoatTrajet(idWaypoint1, idWTicket1, ntx1, nty1, ntz1, idnpc1, sysmess10_1, sysmess5_1, sysmess1_1, sysmess0_1, sysmessb_1, _name);
-	}
-	
-	public void setTrajet2(int idWaypoint1, int idWTicket1, int ntx1, int nty1, int ntz1, String idnpc1, String sysmess10_1,
-			String sysmess5_1, String sysmess1_1, String sysmess0_1, String sysmessb_1)
-	{
-		_t2 = new L2BoatTrajet(idWaypoint1, idWTicket1, ntx1, nty1, ntz1, idnpc1, sysmess10_1, sysmess5_1, sysmess1_1, sysmess0_1, sysmessb_1, _name);
-	}
-	
-	@Override
-	public void updateAbnormalEffect()
-	{
-	}
-	
-	@Override
-	public L2ItemInstance getActiveWeaponInstance()
-	{
-		return null;
-	}
-	
-	@Override
-	public L2Weapon getActiveWeaponItem()
-	{
-		return null;
-	}
-	
-	@Override
-	public L2ItemInstance getSecondaryWeaponInstance()
-	{
-		return null;
-	}
-	
-	@Override
-	public L2Weapon getSecondaryWeaponItem()
-	{
-		return null;
-	}
-	
-	@Override
-	public int getLevel()
-	{
-		return 0;
-	}
-	
-	@Override
-	public boolean isAutoAttackable(L2Character attacker)
-	{
-		return false;
-	}
-	
-	/*
-	 * Allow setup of the boat AI only once 
-	 */
-	@Override
-	public void setAI(L2CharacterAI newAI)
-	{
-		if (_ai == null)
-			_ai = newAI;
-	}
-	
-	/*
-	 * boat AI can't be detached
-	 */
-	public class AIAccessor extends L2Character.AIAccessor
-	{
-		@Override
-		public void detachAI()
-		{
-		}
-	}
-	
-	/**
-	 * @param id
-	 */
-	public void setId(int id)
-	{
-		_id = id;
-	}
-	
+
     @Override
     @Override
     public void sendInfo(L2PcInstance activeChar)
     public void sendInfo(L2PcInstance activeChar)
     {
     {
     	activeChar.sendPacket(new VehicleInfo(this));
     	activeChar.sendPacket(new VehicleInfo(this));
-    	if (isMoving())
-    		sendPacket(new VehicleDeparture(this));
     }
     }
 }
 }

+ 22 - 30
L2_GameServer/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -130,6 +130,7 @@ import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.L2Summon;
 import com.l2jserver.gameserver.model.actor.L2Summon;
 import com.l2jserver.gameserver.model.actor.L2Trap;
 import com.l2jserver.gameserver.model.actor.L2Trap;
+import com.l2jserver.gameserver.model.actor.L2Vehicle;
 import com.l2jserver.gameserver.model.actor.appearance.PcAppearance;
 import com.l2jserver.gameserver.model.actor.appearance.PcAppearance;
 import com.l2jserver.gameserver.model.actor.knownlist.PcKnownList;
 import com.l2jserver.gameserver.model.actor.knownlist.PcKnownList;
 import com.l2jserver.gameserver.model.actor.position.PcPosition;
 import com.l2jserver.gameserver.model.actor.position.PcPosition;
@@ -493,8 +494,7 @@ public final class L2PcInstance extends L2Playable
     private SystemMessageId _noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
     private SystemMessageId _noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
 
 
 	/** Boat and AirShip */
 	/** Boat and AirShip */
-    private L2BoatInstance _boat = null;
-    private L2AirShipInstance _airShip = null;
+    private L2Vehicle _vehicle = null;
     private Point3D _inVehiclePosition;
     private Point3D _inVehiclePosition;
 
 
 	public ScheduledFuture<?> _taskforfish;
 	public ScheduledFuture<?> _taskforfish;
@@ -11171,10 +11171,8 @@ public final class L2PcInstance extends L2Playable
 	@Override
 	@Override
 	public void teleToLocation(int x, int y, int z, int heading, boolean allowRandomOffset)
 	public void teleToLocation(int x, int y, int z, int heading, boolean allowRandomOffset)
 	{
 	{
-		if (isInBoat())
-			setBoat(null);
-		if (isInAirShip())
-			setAirShip(null);
+		if (getVehicle() != null && !getVehicle().isTeleporting())
+			setVehicle(null);
 
 
 		super.teleToLocation(x, y, z, heading, allowRandomOffset);
 		super.teleToLocation(x, y, z, heading, allowRandomOffset);
 	}
 	}
@@ -11183,7 +11181,10 @@ public final class L2PcInstance extends L2Playable
 	public final void onTeleported()
 	public final void onTeleported()
 	{
 	{
 		super.onTeleported();
 		super.onTeleported();
-		
+
+		if (isInAirShip())
+			getAirShip().sendInfo(this);
+
 		// Force a revalidation
 		// Force a revalidation
 		revalidateZone(true);
 		revalidateZone(true);
 
 
@@ -11499,7 +11500,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	 */
 	public boolean isInBoat()
 	public boolean isInBoat()
 	{
 	{
-		return _boat != null;
+		return _vehicle != null && _vehicle.isBoat();
 	}
 	}
 
 
 	/**
 	/**
@@ -11507,18 +11508,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	 */
 	public L2BoatInstance getBoat()
 	public L2BoatInstance getBoat()
 	{
 	{
-		return _boat;
-	}
-
-	/**
-	 * @param boat
-	 */
-	public void setBoat(L2BoatInstance boat)
-	{
-		if (boat == null && _boat != null)
-			_boat.removePassenger(this);
-
-		_boat = boat;
+		return (L2BoatInstance)_vehicle;
 	}
 	}
 
 
 	/**
 	/**
@@ -11526,7 +11516,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	 */
 	public boolean isInAirShip()
 	public boolean isInAirShip()
 	{
 	{
-		return _airShip != null;
+		return _vehicle != null && _vehicle.isAirShip();
 	}
 	}
 
 
 	/**
 	/**
@@ -11534,20 +11524,22 @@ public final class L2PcInstance extends L2Playable
 	 */
 	 */
 	public L2AirShipInstance getAirShip()
 	public L2AirShipInstance getAirShip()
 	{
 	{
-		return _airShip;
+		return (L2AirShipInstance) _vehicle;
 	}
 	}
 
 
-	/**
-	 * @param airShip
-	 */
-	public void setAirShip(L2AirShipInstance airShip)
+	public L2Vehicle getVehicle()
 	{
 	{
-		if (airShip == null && _airShip != null)
-			_airShip.removePassenger(this);
+		return _vehicle;
+	}
 
 
-		_airShip = airShip;
+	public void setVehicle(L2Vehicle v)
+	{
+		if (v == null && _vehicle != null)
+			_vehicle.removePassenger(this);
+
+		_vehicle = v;
 	}
 	}
-	
+
 	public void setInCrystallize(boolean inCrystallize)
 	public void setInCrystallize(boolean inCrystallize)
 	{
 	{
 		_inCrystallize = inCrystallize;
 		_inCrystallize = inCrystallize;

+ 5 - 12
L2_GameServer/java/com/l2jserver/gameserver/model/actor/knownlist/PcKnownList.java

@@ -19,8 +19,7 @@ import com.l2jserver.Config;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.L2Npc;
-import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
+import com.l2jserver.gameserver.model.actor.L2Vehicle;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
 import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
 import com.l2jserver.gameserver.network.serverpackets.SpawnItem;
 import com.l2jserver.gameserver.network.serverpackets.SpawnItem;
@@ -121,11 +120,8 @@ public class PcKnownList extends PlayableKnownList
     @Override
     @Override
 	public int getDistanceToForgetObject(L2Object object)
 	public int getDistanceToForgetObject(L2Object object)
     {
     {
-    	if (object instanceof L2BoatInstance)
-    		return 5000;
-
-    	if (object instanceof L2AirShipInstance)
-    		return 12000;
+    	if (object instanceof L2Vehicle)
+    		return 10000;
 
 
     	// when knownlist grows, the distance to forget should be at least
     	// when knownlist grows, the distance to forget should be at least
     	// the same as the previous watch range, or it becomes possible that
     	// the same as the previous watch range, or it becomes possible that
@@ -140,11 +136,8 @@ public class PcKnownList extends PlayableKnownList
     @Override
     @Override
 	public int getDistanceToWatchObject(L2Object object)
 	public int getDistanceToWatchObject(L2Object object)
     {
     {
-    	if (object instanceof L2BoatInstance)
-    		return 4000;
-
-    	if (object instanceof L2AirShipInstance)
-    		return 10000;
+    	if (object instanceof L2Vehicle)
+    		return 8000;
 
 
     	final int knownlistSize = getKnownObjects().size();
     	final int knownlistSize = getKnownObjects().size();
         if (knownlistSize <= 25) return 3400; // empty field
         if (knownlistSize <= 25) return 3400; // empty field

+ 2 - 8
L2_GameServer/java/com/l2jserver/gameserver/model/actor/stat/VehicleStat.java

@@ -14,20 +14,14 @@
  */
  */
 package com.l2jserver.gameserver.model.actor.stat;
 package com.l2jserver.gameserver.model.actor.stat;
 
 
-import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
+import com.l2jserver.gameserver.model.actor.L2Vehicle;
 
 
 public class VehicleStat extends CharStat
 public class VehicleStat extends CharStat
 {
 {
 	private float _moveSpeed = 0;
 	private float _moveSpeed = 0;
 	private int _rotationSpeed = 0;
 	private int _rotationSpeed = 0;
 
 
-	public VehicleStat(L2BoatInstance activeChar)
-	{
-		super(activeChar);
-	}
-
-	public VehicleStat(L2AirShipInstance activeChar)
+	public VehicleStat(L2Vehicle activeChar)
 	{
 	{
 		super(activeChar);
 		super(activeChar);
 	}
 	}

+ 9 - 17
L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/MoveToLocationInAirShip.java

@@ -15,7 +15,6 @@
 package com.l2jserver.gameserver.network.clientpackets;
 package com.l2jserver.gameserver.network.clientpackets;
 
 
 import com.l2jserver.gameserver.TaskPriority;
 import com.l2jserver.gameserver.TaskPriority;
-import com.l2jserver.gameserver.instancemanager.AirShipManager;
 import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
@@ -75,27 +74,20 @@ public class MoveToLocationInAirShip extends L2GameClientPacket
 			return;
 			return;
 		}
 		}
 
 
-		final L2AirShipInstance airShip;
-		if (activeChar.isInAirShip())
+		if (!activeChar.isInAirShip())
 		{
 		{
-			airShip = activeChar.getAirShip();
-			if (airShip.getObjectId() != _shipId)
-			{
-				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
-				return;
-			}
+			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
+			return;
 		}
 		}
-		else
+
+		final L2AirShipInstance airShip = activeChar.getAirShip();
+		if (airShip.getObjectId() != _shipId)
 		{
 		{
-			airShip = AirShipManager.getInstance().getAirShip();
-			if (airShip == null)
-			{
-				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
-				return;
-			}
+			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
+			return;
 		}
 		}
 
 
-		activeChar.setAirShip(airShip);
+		activeChar.setVehicle(airShip);
 		activeChar.setInVehiclePosition(_pos);
 		activeChar.setInVehiclePosition(_pos);
 		activeChar.broadcastPacket(new ExMoveToLocationInAirShip(activeChar));
 		activeChar.broadcastPacket(new ExMoveToLocationInAirShip(activeChar));
 	}
 	}

+ 1 - 1
L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/RequestGetOffVehicle.java

@@ -51,7 +51,7 @@ public final class RequestGetOffVehicle extends L2GameClientPacket
 		}
 		}
 
 
 		activeChar.broadcastPacket(new StopMoveInVehicle(activeChar, _boatId));
 		activeChar.broadcastPacket(new StopMoveInVehicle(activeChar, _boatId));
-		activeChar.setBoat(null);
+		activeChar.setVehicle(null);
 		activeChar.setInVehiclePosition(null);
 		activeChar.setInVehiclePosition(null);
 		sendPacket(ActionFailed.STATIC_PACKET);	
 		sendPacket(ActionFailed.STATIC_PACKET);	
 		activeChar.broadcastPacket(new GetOffVehicle(activeChar.getObjectId(), _boatId, _x, _y, _z));
 		activeChar.broadcastPacket(new GetOffVehicle(activeChar.getObjectId(), _boatId, _x, _y, _z));

+ 1 - 1
L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/RequestGetOnVehicle.java

@@ -75,7 +75,7 @@ public final class RequestGetOnVehicle extends L2GameClientPacket
 
 
 
 
 		activeChar.setInVehiclePosition(_pos);
 		activeChar.setInVehiclePosition(_pos);
-		activeChar.setBoat(boat);
+		activeChar.setVehicle(boat);
 		activeChar.broadcastPacket(new GetOnVehicle(activeChar.getObjectId(), boat.getObjectId(), _pos));
 		activeChar.broadcastPacket(new GetOnVehicle(activeChar.getObjectId(), boat.getObjectId(), _pos));
 
 
 		activeChar.setXYZ(boat.getX(), boat.getY(), boat.getZ());
 		activeChar.setXYZ(boat.getX(), boat.getY(), boat.getZ());

+ 1 - 1
L2_GameServer/java/com/l2jserver/gameserver/network/clientpackets/RequestMoveToLocationInVehicle.java

@@ -108,7 +108,7 @@ public final class RequestMoveToLocationInVehicle extends L2GameClientPacket
 				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
 				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
 				return;
 				return;
 			}
 			}
-			activeChar.setBoat(boat);
+			activeChar.setVehicle(boat);
 		}
 		}
 
 
 		activeChar.setInVehiclePosition(_pos);
 		activeChar.setInVehiclePosition(_pos);

+ 25 - 34
L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/ExMoveToLocationAirShip.java

@@ -14,46 +14,37 @@
  */
  */
 package com.l2jserver.gameserver.network.serverpackets;
 package com.l2jserver.gameserver.network.serverpackets;
 
 
-import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
+import com.l2jserver.gameserver.model.actor.L2Character;
 
 
 public class ExMoveToLocationAirShip extends L2GameServerPacket
 public class ExMoveToLocationAirShip extends L2GameServerPacket
-{
-	
-	private static final String _S__FE_65_EXAIRSHIPMOVETOLOCATION = "[S] FE:65 ExGetOnAirShip";
+{	
+	private static final String _S__FE_65_EXAIRSHIPMOVETOLOCATION = "[S] FE:65 ExMoveToLocationAirShip";
 
 
-	private final int _airShipId;
-	private final int _x, _y, _z, _dx, _dy, _dz;
-	
-	public ExMoveToLocationAirShip(L2AirShipInstance cha, int x, int y, int z)
+	private L2Character _ship;
+
+	public ExMoveToLocationAirShip(L2Character cha)
 	{
 	{
-		_airShipId = cha.getObjectId();
-		_x = cha.getX();
-		_y = cha.getY();
-		_z = cha.getZ();
-		_dx = x;
-		_dy = y;
-		_dz = z;
+		_ship = cha;
 	}
 	}
-	
+
 	@Override
 	@Override
-    protected void writeImpl()
-    {
-	    writeC(0xfe);
-	    writeH(0x65);
-	    
-	    writeD(_airShipId);
-	    writeD(_dx);
-	    writeD(_dy);
-	    writeD(_dz);
-	    writeD(_x);
-	    writeD(_y);
-	    writeD(_z);
+	protected void writeImpl()
+	{
+		writeC(0xfe);
+		writeH(0x65);
+
+		writeD(_ship.getObjectId());
+		writeD(_ship.getXdestination());
+		writeD(_ship.getYdestination());
+		writeD(_ship.getZdestination());
+		writeD(_ship.getX());
+		writeD(_ship.getY());
+		writeD(_ship.getZ());
 	}
 	}
-	
+
 	@Override
 	@Override
-    public String getType()
-    {
-	    return _S__FE_65_EXAIRSHIPMOVETOLOCATION;
-    }
-	
+	public String getType()
+	{
+		return _S__FE_65_EXAIRSHIPMOVETOLOCATION;
+	}	
 }
 }

+ 4 - 4
L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/ExStopMoveAirShip.java

@@ -14,17 +14,17 @@
  */
  */
 package com.l2jserver.gameserver.network.serverpackets;
 package com.l2jserver.gameserver.network.serverpackets;
 
 
-import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
+import com.l2jserver.gameserver.model.actor.L2Character;
+
 /**
 /**
  * @authos kerberos
  * @authos kerberos
  *
  *
  */
  */
 public class ExStopMoveAirShip extends L2GameServerPacket
 public class ExStopMoveAirShip extends L2GameServerPacket
 {
 {
-    private L2AirShipInstance _ship;
-
+	private L2Character _ship;
 
 
-    public ExStopMoveAirShip(L2AirShipInstance ship)
+    public ExStopMoveAirShip(L2Character ship)
     {
     {
     	_ship = ship;
     	_ship = ship;
     }
     }

+ 6 - 8
L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/ExStopMoveInAirShip.java

@@ -14,22 +14,20 @@
  */
  */
 package com.l2jserver.gameserver.network.serverpackets;
 package com.l2jserver.gameserver.network.serverpackets;
 
 
-import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.L2Character;
 /**
 /**
  * @authos kerberos
  * @authos kerberos
  *
  *
  */
  */
 public class ExStopMoveInAirShip extends L2GameServerPacket
 public class ExStopMoveInAirShip extends L2GameServerPacket
 {
 {
-	private L2PcInstance _activeChar;
-    private L2AirShipInstance _ship;
+	private L2Character _activeChar;
+    private int _shipObjId;
 
 
-
-    public ExStopMoveInAirShip(L2PcInstance player, L2AirShipInstance ship)
+    public ExStopMoveInAirShip(L2Character player, int shipObjId)
     {
     {
     	_activeChar = player;
     	_activeChar = player;
-    	_ship = ship;
+    	_shipObjId = shipObjId;
     }
     }
 
 
     @Override
     @Override
@@ -38,7 +36,7 @@ public class ExStopMoveInAirShip extends L2GameServerPacket
         writeC(0xfe);
         writeC(0xfe);
         writeH(0x6e);
         writeH(0x6e);
         writeD(_activeChar.getObjectId());
         writeD(_activeChar.getObjectId());
-        writeD(_ship.getObjectId());
+        writeD(_shipObjId);
         writeD(_activeChar.getX());
         writeD(_activeChar.getX());
         writeD(_activeChar.getY());
         writeD(_activeChar.getY());
         writeD(_activeChar.getZ());
         writeD(_activeChar.getZ());

+ 9 - 19
L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleCheckLocation.java

@@ -14,7 +14,7 @@
  */
  */
 package com.l2jserver.gameserver.network.serverpackets;
 package com.l2jserver.gameserver.network.serverpackets;
 
 
-import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
+import com.l2jserver.gameserver.model.actor.L2Character;
 
 
 /**
 /**
  * @author Maktakien
  * @author Maktakien
@@ -22,23 +22,14 @@ import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
  */
  */
 public class VehicleCheckLocation extends L2GameServerPacket
 public class VehicleCheckLocation extends L2GameServerPacket
 {
 {
-	private L2BoatInstance _boat;
-	private int _x;
-	private int _y;
-	private int _z;
+	private L2Character _boat;
     
     
 	/**
 	/**
 	 * @param instance
 	 * @param instance
-	 * @param x
-	 * @param y
-	 * @param z
 	 */
 	 */
-	public VehicleCheckLocation(L2BoatInstance instance, int x, int y, int z)
+	public VehicleCheckLocation(L2Character boat)
 	{
 	{
-		_boat = instance;
-		_x = x;
-		_y = y;
-		_z = z;
+		_boat = boat;
 	}
 	}
 
 
 	@Override
 	@Override
@@ -47,16 +38,15 @@ public class VehicleCheckLocation extends L2GameServerPacket
 	{
 	{
 		writeC(0x6d);
 		writeC(0x6d);
 		writeD(_boat.getObjectId());
 		writeD(_boat.getObjectId());
-		writeD(_x);
-		writeD(_y);
-		writeD(_z);
-		writeD(_boat.getPosition().getHeading());
+		writeD(_boat.getX());
+		writeD(_boat.getY());
+		writeD(_boat.getZ());
+		writeD(_boat.getHeading());
 	}
 	}
 
 
 	@Override
 	@Override
 	public String getType()
 	public String getType()
 	{
 	{
-		return null;
+		return "[S] 6D VehicleCheckLocation";
 	}
 	}
-
 }
 }

+ 9 - 18
L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleDeparture.java

@@ -22,12 +22,8 @@ import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
  */
  */
 public class VehicleDeparture extends L2GameServerPacket
 public class VehicleDeparture extends L2GameServerPacket
 {
 {
-	private int _boatObjId;
-	private int _speed1;
-	private int _speed2;//rotation
-	private int _x;
-	private int _y;
-	private int _z;
+	private L2BoatInstance _boat;
+
 	/**
 	/**
 	 * @param _boat
 	 * @param _boat
 	 * @param speed1
 	 * @param speed1
@@ -38,12 +34,7 @@ public class VehicleDeparture extends L2GameServerPacket
 	 */
 	 */
 	public VehicleDeparture(L2BoatInstance boat)
 	public VehicleDeparture(L2BoatInstance boat)
 	{
 	{
-		_boatObjId = boat.getObjectId();
-		_speed1 = (int)boat.getStat().getMoveSpeed();
-		_speed2 = boat.getStat().getRotationSpeed();
-		_x = boat.getXdestination();
-		_y = boat.getYdestination();
-		_z = boat.getZdestination();
+		_boat = boat;
 	}
 	}
 
 
 	@Override
 	@Override
@@ -51,12 +42,12 @@ public class VehicleDeparture extends L2GameServerPacket
 	void writeImpl()
 	void writeImpl()
 	{
 	{
 		writeC(0x6c);
 		writeC(0x6c);
-		writeD(_boatObjId);
-		writeD(_speed1);
-		writeD(_speed2);
-		writeD(_x);
-		writeD(_y);
-		writeD(_z);
+		writeD(_boat.getObjectId());
+		writeD((int)_boat.getStat().getMoveSpeed());
+		writeD(_boat.getStat().getRotationSpeed());
+		writeD(_boat.getXdestination());
+		writeD(_boat.getYdestination());
+		writeD(_boat.getZdestination());
 
 
 	}
 	}
 
 

+ 1 - 3
L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleInfo.java

@@ -42,8 +42,7 @@ public class VehicleInfo  extends L2GameServerPacket
 		writeD(_boat.getX());
 		writeD(_boat.getX());
 		writeD(_boat.getY());
 		writeD(_boat.getY());
         writeD(_boat.getZ());
         writeD(_boat.getZ());
-        writeD(_boat.getPosition().getHeading());
-
+        writeD(_boat.getHeading());
 	}
 	}
 
 
 	/* (non-Javadoc)
 	/* (non-Javadoc)
@@ -54,5 +53,4 @@ public class VehicleInfo  extends L2GameServerPacket
 	{
 	{
 		return "[S] 59 VehicleInfo";
 		return "[S] 59 VehicleInfo";
 	}
 	}
-
 }
 }

+ 5 - 6
L2_GameServer/java/com/l2jserver/gameserver/network/serverpackets/VehicleStarted.java

@@ -14,7 +14,7 @@
  */
  */
 package com.l2jserver.gameserver.network.serverpackets;
 package com.l2jserver.gameserver.network.serverpackets;
 
 
-import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
+import com.l2jserver.gameserver.model.actor.L2Character;
 
 
 /**
 /**
  * @author Kerberos
  * @author Kerberos
@@ -22,16 +22,15 @@ import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
  */
  */
 public class VehicleStarted extends L2GameServerPacket
 public class VehicleStarted extends L2GameServerPacket
 {
 {
-	private L2BoatInstance _boat;
-	
+	private int _objectId;
 	private int _state;
 	private int _state;
 	
 	
 	/**
 	/**
 	 * @param instance
 	 * @param instance
 	 */
 	 */
-	public VehicleStarted(L2BoatInstance boat, int state)
+	public VehicleStarted(L2Character boat, int state)
 	{
 	{
-		_boat = boat;
+		_objectId = boat.getObjectId();;
 		_state = state;
 		_state = state;
 	}
 	}
 	
 	
@@ -44,7 +43,7 @@ public class VehicleStarted extends L2GameServerPacket
 	protected void writeImpl()
 	protected void writeImpl()
 	{
 	{
 		writeC(0xC0);
 		writeC(0xC0);
-		writeD(_boat.getObjectId());
+		writeD(_objectId);
 		writeD(_state);
 		writeD(_state);
 	}
 	}