Ver código fonte

BETA: Renamed `GeoData.canMoveFromTo` to `GeoData.canMove` and added 2 overloads of it using `ILocational`.
* Fixed a bug with skills using `FlyType.CHARGE` making it possible to bypass geodata move restrictions.
* Reported by: d!go

Reviewed by: Zoey76

Nos 11 anos atrás
pai
commit
94a1a5110e

+ 46 - 22
L2J_Server_BETA/java/com/l2jserver/gameserver/GeoData.java

@@ -479,26 +479,26 @@ public class GeoData implements IGeoDriver
 	}
 	
 	/**
-	 * Can move from to target.
-	 * @param x the x coordinate
-	 * @param y the y coordinate
-	 * @param z the z coordinate
-	 * @param tx the target's x coordinate
-	 * @param ty the target's y coordinate
-	 * @param tz the target's z coordinate
-	 * @param instanceId the instance id
-	 * @return {@code true} if the character at x,y,z can move to tx,ty,tz, {@code false} otherwise
+	 * Checks if its possible to move from one location to another.
+	 * @param fromX the X coordinate to start checking from
+	 * @param fromY the Y coordinate to start checking from
+	 * @param fromZ the Z coordinate to start checking from
+	 * @param toX the X coordinate to end checking at
+	 * @param toY the Y coordinate to end checking at
+	 * @param toZ the Z coordinate to end checking at
+	 * @param instanceId the instance ID
+	 * @return {@code true} if the character at start coordinates can move to end coordinates, {@code false} otherwise
 	 */
-	public boolean canMoveFromToTarget(int x, int y, int z, int tx, int ty, int tz, int instanceId)
+	public boolean canMove(int fromX, int fromY, int fromZ, int toX, int toY, int toZ, int instanceId)
 	{
-		int geoX = getGeoX(x);
-		int geoY = getGeoY(y);
-		z = getNearestZ(geoX, geoY, z);
-		int tGeoX = getGeoX(tx);
-		int tGeoY = getGeoY(ty);
-		tz = getNearestZ(tGeoX, tGeoY, tz);
+		int geoX = getGeoX(fromX);
+		int geoY = getGeoY(fromY);
+		fromZ = getNearestZ(geoX, geoY, fromZ);
+		int tGeoX = getGeoX(toX);
+		int tGeoY = getGeoY(toY);
+		toZ = getNearestZ(tGeoX, tGeoY, toZ);
 		
-		if (DoorTable.getInstance().checkIfDoorsBetween(x, y, z, tx, ty, tz, instanceId, false))
+		if (DoorTable.getInstance().checkIfDoorsBetween(fromX, fromY, fromZ, toX, toY, toZ, instanceId, false))
 		{
 			return false;
 		}
@@ -508,7 +508,7 @@ public class GeoData implements IGeoDriver
 		pointIter.next();
 		int prevX = pointIter.x();
 		int prevY = pointIter.y();
-		int prevZ = z;
+		int prevZ = fromZ;
 		
 		while (pointIter.next())
 		{
@@ -554,7 +554,7 @@ public class GeoData implements IGeoDriver
 			prevZ = curZ;
 		}
 		
-		if (hasGeoPos(prevX, prevY) && (prevZ != tz))
+		if (hasGeoPos(prevX, prevY) && (prevZ != toZ))
 		{
 			// different floors
 			return false;
@@ -564,9 +564,33 @@ public class GeoData implements IGeoDriver
 	}
 	
 	/**
-	 * Checks for geodata.
-	 * @param x the x coordinate
-	 * @param y the y coordinate
+	 * Checks if its possible to move from one location to another.
+	 * @param from the {@code ILocational} to start checking from
+	 * @param toX the X coordinate to end checking at
+	 * @param toY the Y coordinate to end checking at
+	 * @param toZ the Z coordinate to end checking at
+	 * @return {@code true} if the character at start coordinates can move to end coordinates, {@code false} otherwise
+	 */
+	public boolean canMove(ILocational from, int toX, int toY, int toZ)
+	{
+		return canMove(from.getX(), from.getY(), from.getZ(), toX, toY, toZ, from.getInstanceId());
+	}
+	
+	/**
+	 * Checks if its possible to move from one location to another.
+	 * @param from the {@code ILocational} to start checking from
+	 * @param to the {@code ILocational} to end checking at
+	 * @return {@code true} if the character at start coordinates can move to end coordinates, {@code false} otherwise
+	 */
+	public boolean canMove(ILocational from, ILocational to)
+	{
+		return canMove(from, to.getX(), to.getY(), to.getZ());
+	}
+	
+	/**
+	 * Checks the specified position for available geodata.
+	 * @param x the X coordinate
+	 * @param y the Y coordinate
 	 * @return {@code true} if there is geodata for the given coordinates, {@code false} otherwise
 	 */
 	public boolean hasGeo(int x, int y)

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2AttackableAI.java

@@ -909,7 +909,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 					if (!npc.isInsideRadius(newX, newY, 0, collision, false, false))
 					{
 						int newZ = npc.getZ() + 30;
-						if ((Config.GEODATA == 0) || GeoData.getInstance().canMoveFromToTarget(npc.getX(), npc.getY(), npc.getZ(), newX, newY, newZ, npc.getInstanceId()))
+						if ((Config.GEODATA == 0) || GeoData.getInstance().canMove(npc.getX(), npc.getY(), npc.getZ(), newX, newY, newZ, npc.getInstanceId()))
 						{
 							moveTo(newX, newY, newZ);
 						}
@@ -949,7 +949,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 						posY = posY - 300;
 					}
 					
-					if ((Config.GEODATA == 0) || GeoData.getInstance().canMoveFromToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, posZ, npc.getInstanceId()))
+					if ((Config.GEODATA == 0) || GeoData.getInstance().canMove(npc.getX(), npc.getY(), npc.getZ(), posX, posY, posZ, npc.getInstanceId()))
 					{
 						setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, posZ, 0));
 					}

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

@@ -236,7 +236,7 @@ public class L2SummonAI extends L2PlayableAI implements Runnable
 				
 				final int targetX = ownerX + (int) (AVOID_RADIUS * Math.cos(angle));
 				final int targetY = ownerY + (int) (AVOID_RADIUS * Math.sin(angle));
-				if ((Config.GEODATA == 0) || GeoData.getInstance().canMoveFromToTarget(_actor.getX(), _actor.getY(), _actor.getZ(), targetX, targetY, _actor.getZ(), _actor.getInstanceId()))
+				if ((Config.GEODATA == 0) || GeoData.getInstance().canMove(_actor.getX(), _actor.getY(), _actor.getZ(), targetX, targetY, _actor.getZ(), _actor.getInstanceId()))
 				{
 					moveTo(targetX, targetY, _actor.getZ());
 				}

+ 8 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -270,6 +270,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExSetCompassZoneCode;
 import com.l2jserver.gameserver.network.serverpackets.ExStartScenePlayer;
 import com.l2jserver.gameserver.network.serverpackets.ExStorageMaxCount;
 import com.l2jserver.gameserver.network.serverpackets.ExUseSharedGroupItem;
+import com.l2jserver.gameserver.network.serverpackets.FlyToLocation.FlyType;
 import com.l2jserver.gameserver.network.serverpackets.FriendStatusPacket;
 import com.l2jserver.gameserver.network.serverpackets.GameGuardQuery;
 import com.l2jserver.gameserver.network.serverpackets.GetOnVehicle;
@@ -9113,6 +9114,13 @@ public final class L2PcInstance extends L2Playable
 				return false;
 			}
 		}
+		
+		if ((skill.getFlyType() == FlyType.CHARGE) && (Config.GEODATA > 0) && !GeoData.getInstance().canMove(this, target))
+		{
+			sendPacket(SystemMessageId.THE_TARGET_IS_LOCATED_WHERE_YOU_CANNOT_CHARGE);
+			return false;
+		}
+		
 		// finally, after passing all conditions
 		return true;
 	}

+ 1 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/tasks/character/FlyToLocationTask.java

@@ -22,7 +22,6 @@ import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.skills.L2Skill;
 import com.l2jserver.gameserver.network.serverpackets.FlyToLocation;
-import com.l2jserver.gameserver.network.serverpackets.FlyToLocation.FlyType;
 
 /**
  * Task dedicated to fly a player to the location
@@ -46,7 +45,7 @@ public final class FlyToLocationTask implements Runnable
 	{
 		if (_character != null)
 		{
-			_character.broadcastPacket(new FlyToLocation(_character, _target, FlyType.valueOf(_skill.getFlyType())));
+			_character.broadcastPacket(new FlyToLocation(_character, _target, _skill.getFlyType()));
 			_character.setXYZ(_target.getX(), _target.getY(), _target.getZ());
 		}
 	}

+ 4 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/L2Skill.java

@@ -62,6 +62,7 @@ import com.l2jserver.gameserver.model.stats.Env;
 import com.l2jserver.gameserver.model.stats.Formulas;
 import com.l2jserver.gameserver.model.stats.TraitType;
 import com.l2jserver.gameserver.model.zone.ZoneId;
+import com.l2jserver.gameserver.network.serverpackets.FlyToLocation.FlyType;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.util.Util;
 import com.l2jserver.util.Rnd;
@@ -202,7 +203,7 @@ public abstract class L2Skill implements IChanceSkillTrigger, IIdentifiable
 	protected ChanceCondition _chanceCondition = null;
 	
 	// Flying support
-	private final String _flyType;
+	private final FlyType _flyType;
 	private final int _flyRadius;
 	private final float _flyCourse;
 	
@@ -362,7 +363,7 @@ public abstract class L2Skill implements IChanceSkillTrigger, IIdentifiable
 		_isTriggeredSkill = set.getBoolean("isTriggeredSkill", false);
 		_effectPoint = set.getInt("effectPoint", 0);
 		
-		_flyType = set.getString("flyType", null);
+		_flyType = set.getEnum("flyType", FlyType.class, null);
 		_flyRadius = set.getInt("flyRadius", 0);
 		_flyCourse = set.getFloat("flyCourse", 0);
 		
@@ -971,7 +972,7 @@ public abstract class L2Skill implements IChanceSkillTrigger, IIdentifiable
 		return _directHpDmg;
 	}
 	
-	public final String getFlyType()
+	public final FlyType getFlyType()
 	{
 		return _flyType;
 	}

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/network/SystemMessageId.java

@@ -12864,7 +12864,7 @@ public final class SystemMessageId
 	 * ID: 2187<br>
 	 * Message: The target is located where you cannot charge.
 	 */
-	public static final SystemMessageId CANT_REACH_TARGET_TO_CHARGE;
+	public static final SystemMessageId THE_TARGET_IS_LOCATED_WHERE_YOU_CANNOT_CHARGE;
 	
 	/**
 	 * ID: 2188<br>
@@ -17343,7 +17343,7 @@ public final class SystemMessageId
 		S1_CLAN_IS_VICTORIOUS_IN_THE_FORTRESS_BATTLE_OF_S2 = new SystemMessageId(2184);
 		ONLY_PARTY_LEADER_CAN_ENTER = new SystemMessageId(2185);
 		SOUL_CANNOT_BE_ABSORBED_ANYMORE = new SystemMessageId(2186);
-		CANT_REACH_TARGET_TO_CHARGE = new SystemMessageId(2187);
+		THE_TARGET_IS_LOCATED_WHERE_YOU_CANNOT_CHARGE = new SystemMessageId(2187);
 		ENCHANTMENT_ALREADY_IN_PROGRESS = new SystemMessageId(2188);
 		LOC_KAMAEL_VILLAGE_S1_S2_S3 = new SystemMessageId(2189);
 		LOC_WASTELANDS_CAMP_S1_S2_S3 = new SystemMessageId(2190);

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/pathfinding/cellnodes/CellPathFinding.java

@@ -212,7 +212,7 @@ public class CellPathFinding extends PathFinding
 			{
 				locEnd = endPoint.next();
 				locMiddle = middlePoint.next();
-				if (GeoData.getInstance().canMoveFromToTarget(currentX, currentY, currentZ, locEnd.getX(), locEnd.getY(), locEnd.getZ(), instanceId))
+				if (GeoData.getInstance().canMove(currentX, currentY, currentZ, locEnd.getX(), locEnd.getY(), locEnd.getZ(), instanceId))
 				{
 					middlePoint.remove();
 					remove = true;