Prechádzať zdrojové kódy

Reworked random walk and minion spawn coords in more smart way (Pifagor rulez).
Added geodata check for dodge.
Part of attackable AI reworked for reduce number of NPEs.

_DS_ 15 rokov pred
rodič
commit
42eac785c5

+ 38 - 26
L2_GameServer/java/com/l2jserver/gameserver/ai/L2AttackableAI.java

@@ -520,13 +520,14 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 		// Minions following leader
 		// Minions following leader
 		if (_actor instanceof L2MinionInstance && ((L2MinionInstance) _actor).getLeader() != null)
 		if (_actor instanceof L2MinionInstance && ((L2MinionInstance) _actor).getLeader() != null)
 		{
 		{
-			int offset;
+			final int offset;
+			final int minRadius = 30;
 			
 			
 			if (_actor.isRaidMinion())
 			if (_actor.isRaidMinion())
 				offset = 500; // for Raids - need correction
 				offset = 500; // for Raids - need correction
 			else
 			else
 				offset = 200; // for normal minions - need correction :)
 				offset = 200; // for normal minions - need correction :)
-				
+	
 			if (((L2MinionInstance) _actor).getLeader().isRunning())
 			if (((L2MinionInstance) _actor).getLeader().isRunning())
 				_actor.setRunning();
 				_actor.setRunning();
 			else
 			else
@@ -535,8 +536,18 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 			if (_actor.getPlanDistanceSq(((L2MinionInstance) _actor).getLeader()) > offset * offset)
 			if (_actor.getPlanDistanceSq(((L2MinionInstance) _actor).getLeader()) > offset * offset)
 			{
 			{
 				int x1, y1, z1;
 				int x1, y1, z1;
-				x1 = ((L2MinionInstance) _actor).getLeader().getX() + Rnd.nextInt((offset - 30) * 2) - (offset - 30);
-				y1 = ((L2MinionInstance) _actor).getLeader().getY() + Rnd.nextInt((offset - 30) * 2) - (offset - 30);
+				x1 = Rnd.get(minRadius * 2, offset * 2); // x
+				y1 = Rnd.get(x1, offset * 2); // distance
+				y1 = (int)Math.sqrt(y1*y1 - x1*x1); // y
+				if (x1 > offset + minRadius)
+					x1 = ((L2MinionInstance) _actor).getLeader().getX() + x1 - offset;
+				else
+					x1 = ((L2MinionInstance) _actor).getLeader().getX() - x1 + minRadius;
+				if (y1 > offset - minRadius)
+					y1 = ((L2MinionInstance) _actor).getLeader().getY() + y1 - offset;
+				else
+					y1 = ((L2MinionInstance) _actor).getLeader().getY() - y1 + minRadius;
+
 				z1 = ((L2MinionInstance) _actor).getLeader().getZ();
 				z1 = ((L2MinionInstance) _actor).getLeader().getZ();
 				// Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
 				// Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
 				moveTo(x1, y1, z1);
 				moveTo(x1, y1, z1);
@@ -593,12 +604,15 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				y1 = npc.getSpawn().getLocy();
 				y1 = npc.getSpawn().getLocy();
 				z1 = npc.getSpawn().getLocz();
 				z1 = npc.getSpawn().getLocz();
 
 
-				if (!_actor.isInsideRadius(x1, y1, z1, range + range, true, false))
+				if (!_actor.isInsideRadius(x1, y1, range, false))
 					npc.setisReturningToSpawnPoint(true);
 					npc.setisReturningToSpawnPoint(true);
 				else
 				else
 				{
 				{
-					x1 += Rnd.nextInt(range * 2) - range;
-					y1 += Rnd.nextInt(range * 2) - range;
+					x1 = Rnd.nextInt(range * 2); // x
+					y1 = Rnd.get(x1, range * 2); // distance
+					y1 = (int)Math.sqrt(y1*y1 - x1*x1); // y
+					x1 += npc.getSpawn().getLocx() - range;
+					y1 += npc.getSpawn().getLocy() - range;
 					z1 = npc.getZ();
 					z1 = npc.getZ();
 				}
 				}
 			}
 			}
@@ -740,27 +754,24 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 		double dist = 0;
 		double dist = 0;
 		int dist2 = 0;
 		int dist2 = 0;
 		int range = 0;
 		int range = 0;
-		L2Character MostHate = ((L2Attackable) _actor).getMostHated();
-		//L2Character ctarget = (L2Character)_actor.getTarget();
-		try
-		{
-			setAttackTarget(MostHate);
-			_actor.setTarget(MostHate);
-			dist = Math.sqrt(_actor.getPlanDistanceSq(getAttackTarget().getX(), getAttackTarget().getY()));
-			dist2= (int) dist - _actor.getTemplate().collisionRadius;
-			range = _actor.getPhysicalAttackRange() + _actor.getTemplate().collisionRadius + getAttackTarget().getTemplate().collisionRadius;
-			if(getAttackTarget().isMoving())
-			{
-				range = range + 50;
-				if(_actor.isMoving())
-					range = range + 50;
-			}
-		}
-		catch (NullPointerException e)
+		L2Character mostHate = ((L2Attackable) _actor).getMostHated();
+		if (mostHate == null)
 		{
 		{
 			setIntention(AI_INTENTION_ACTIVE);
 			setIntention(AI_INTENTION_ACTIVE);
 			return;
 			return;
 		}
 		}
+		setAttackTarget(mostHate);
+		_actor.setTarget(mostHate);
+		dist = Math.sqrt(_actor.getPlanDistanceSq(mostHate.getX(), mostHate.getY()));
+		dist2= (int) dist - _actor.getTemplate().collisionRadius;
+		range = _actor.getPhysicalAttackRange() + _actor.getTemplate().collisionRadius + mostHate.getTemplate().collisionRadius;
+		if(mostHate.isMoving())
+		{
+			range = range + 50;
+			if(_actor.isMoving())
+				range = range + 50;
+		}
+
 		//------------------------------------------------------
 		//------------------------------------------------------
 		// In case many mobs are trying to hit from same place, move a bit,
 		// In case many mobs are trying to hit from same place, move a bit,
 		// circling around the target
 		// circling around the target
@@ -818,8 +829,9 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 						posY=posY + Rnd.get(100);
 						posY=posY + Rnd.get(100);
 					else
 					else
 						posY=posY - Rnd.get(100);
 						posY=posY - Rnd.get(100);
-					
-					setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(posX, posY, posZ, 0));
+
+					if (Config.GEODATA == 0 || GeoData.getInstance().canMoveFromToTarget(_actor.getX(), _actor.getY(), posZ, posX, posY, posZ, _actor.getInstanceId()))
+						setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(posX, posY, posZ, 0));
 					return;
 					return;
 				//}
 				//}
 			}
 			}

+ 15 - 16
L2_GameServer/java/com/l2jserver/gameserver/util/MinionList.java

@@ -241,22 +241,21 @@ public class MinionList
 		monster.setInstanceId(instanceId);
 		monster.setInstanceId(instanceId);
 		
 		
 		// Init the position of the Minion and add it in the world as a visible object
 		// Init the position of the Minion and add it in the world as a visible object
-		int spawnConstant;
-		int randSpawnLim = 170;
-		int randPlusMin = 1;
-		spawnConstant = Rnd.nextInt(randSpawnLim);
-		//randomize +/-
-		randPlusMin = Rnd.nextInt(2);
-		if (randPlusMin == 1)
-			spawnConstant *= -1;
-		int newX = master.getX() + Math.round(spawnConstant);
-		spawnConstant = Rnd.nextInt(randSpawnLim);
-		//randomize +/-
-		randPlusMin = Rnd.nextInt(2);
-		if (randPlusMin == 1)
-			spawnConstant *= -1;
-		int newY = master.getY() + Math.round(spawnConstant);
-		
+		final int offset = 200;
+		final int minRadius = 30;
+
+		int newX = Rnd.get(minRadius * 2, offset * 2); // x
+		int newY = Rnd.get(newX, offset * 2); // distance
+		newY = (int)Math.sqrt(newY*newY - newX*newX); // y
+		if (newX > offset + minRadius)
+			newX = master.getX() + newX - offset;
+		else
+			newX = master.getX() - newX + minRadius;
+		if (newY > offset - minRadius)
+			newY = master.getY() + newY - offset;
+		else
+			newY = master.getY() - newY + minRadius;
+
 		monster.spawnMe(newX, newY, master.getZ());
 		monster.spawnMe(newX, newY, master.getZ());
 		
 		
 		if (Config.DEBUG)
 		if (Config.DEBUG)