소스 검색

Random walk and return to spawn rework. Still not perfect, I will continue to work on it.

_DS_ 15 년 전
부모
커밋
13c8281248

+ 14 - 6
L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java

@@ -36,7 +36,6 @@ import net.sf.l2j.gameserver.model.actor.L2Character;
 import net.sf.l2j.gameserver.model.actor.L2Npc;
 import net.sf.l2j.gameserver.model.actor.L2Playable;
 import net.sf.l2j.gameserver.model.actor.L2Summon;
-import net.sf.l2j.gameserver.model.actor.instance.L2ChestInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2FestivalMonsterInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
@@ -316,6 +315,15 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				// If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE
 				if (!npc.getKnownList().getKnownPlayers().isEmpty())
 					intention = AI_INTENTION_ACTIVE;
+				else
+				{
+					if (npc.getSpawn() != null)
+					{
+						final int range = Config.MAX_DRIFT_RANGE;
+						if (!npc.isInsideRadius(npc.getSpawn().getLocx(), npc.getSpawn().getLocy(), npc.getSpawn().getLocz(), range + range, true, false))
+							intention = AI_INTENTION_ACTIVE;
+					}
+				}
 			}
 			
 			if (intention == AI_INTENTION_IDLE)
@@ -565,10 +573,10 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 		}
 		// Order to the L2MonsterInstance to random walk (1/100)
 		else if (npc.getSpawn() != null && Rnd.nextInt(RANDOM_WALK_RATE) == 0 
-				&& !(_actor.isRaid() || _actor instanceof L2MinionInstance || _actor instanceof L2ChestInstance || _actor instanceof L2GuardInstance || _actor.isNoRndWalk()))
+				&& !_actor.isNoRndWalk())
 		{
 			int x1, y1, z1;
-			int range = Config.MAX_DRIFT_RANGE;
+			final int range = Config.MAX_DRIFT_RANGE;
 			
 			// self and clan buffs
 			for (L2Skill sk : _selfAnalysis.buffSkills)
@@ -603,7 +611,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				// Calculate the distance between the current position of the L2Character and the target (x,y)
 				double distance2 = _actor.getPlanDistanceSq(x1, y1);
 				
-				if (distance2 > range * range)
+				if (distance2 > (range + range) * (range + range))
 				{
 					npc.setisReturningToSpawnPoint(true);
 					float delay = (float) Math.sqrt(distance2) / range;
@@ -621,8 +629,8 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				x1 = npc.getSpawn().getLocx();
 				y1 = npc.getSpawn().getLocy();
 				z1 = npc.getSpawn().getLocz();
-				
-				if (_actor.getPlanDistanceSq(x1, y1) > range * range)
+
+				if (!_actor.isInsideRadius(x1, y1, z1, range + range, true, false))
 					npc.setisReturningToSpawnPoint(true);
 				else
 				{

+ 1 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2ChestInstance.java

@@ -35,6 +35,7 @@ public final class L2ChestInstance extends L2MonsterInstance
 	public L2ChestInstance(int objectId, L2NpcTemplate template)
 	{
 		super(objectId, template);
+		setIsNoRndWalk(true);
 		_isInteracted = false;
 		_specialDrop = false;
 	}

+ 1 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2GrandBossInstance.java

@@ -50,6 +50,7 @@ public final class L2GrandBossInstance extends L2MonsterInstance
 	public void onSpawn()
     {
     	setIsRaid(true);
+    	setIsNoRndWalk(true);
     	if (getNpcId() == 29020 || getNpcId() == 29028) // baium and valakas are all the time in passive mode, theirs attack AI handled in AI scripts
     		super.disableCoreAI(true);
     	super.onSpawn();

+ 1 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2GuardInstance.java

@@ -115,6 +115,7 @@ public final class L2GuardInstance extends L2Attackable
 	@Override
 	public void onSpawn()
 	{
+		setIsNoRndWalk(true);
 		super.onSpawn();
 
         // check the region where this mob is, do not activate the AI if region is inactive.

+ 1 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2MinionInstance.java

@@ -64,6 +64,7 @@ public class L2MinionInstance extends L2MonsterInstance
 		{
 			setIsRaidMinion(true);
 		}
+		setIsNoRndWalk(true);
 		super.onSpawn();
 		// Notify Leader that Minion has Spawned
 		getLeader().notifyMinionSpawned(this);

+ 171 - 161
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2MonsterInstance.java

@@ -14,7 +14,6 @@
  */
 package net.sf.l2j.gameserver.model.actor.instance;
 
-import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.ScheduledFuture;
 
@@ -40,11 +39,11 @@ public class L2MonsterInstance extends L2Attackable
 {
 	//private static Logger _log = Logger.getLogger(L2MonsterInstance.class.getName());
 
-    protected final MinionList _minionList;
+	protected final MinionList _minionList;
 
-    protected ScheduledFuture<?> _minionMaintainTask = null;
+	protected ScheduledFuture<?> _maintenanceTask = null;
 
-    private static final int MONSTER_MAINTENANCE_INTERVAL = 1000;
+	private static final int MONSTER_MAINTENANCE_INTERVAL = 1000;
 
 	/**
 	 * Constructor of L2MonsterInstance (use L2Character and L2NpcInstance constructor).<BR><BR>
@@ -60,20 +59,23 @@ public class L2MonsterInstance extends L2Attackable
 	public L2MonsterInstance(int objectId, L2NpcTemplate template)
 	{
 		super(objectId, template);
-        _minionList  = new MinionList(this);
+		if (getTemplate().getMinionData() != null)
+			_minionList  = new MinionList(this);
+		else
+			_minionList = null;
 	}
 
-    @Override
+	@Override
 	public final MonsterKnownList getKnownList()
-    {
-    	return (MonsterKnownList)super.getKnownList();
-    }
-    
+	{
+		return (MonsterKnownList)super.getKnownList();
+	}
+
 	@Override
-    public void initKnownList()
-    {
+	public void initKnownList()
+	{
 		setKnownList(new MonsterKnownList(this));
-    }
+	}
 
 	/**
 	 * Return True if the attacker is not another L2MonsterInstance.<BR><BR>
@@ -96,181 +98,189 @@ public class L2MonsterInstance extends L2Attackable
 		return (getTemplate().aggroRange > 0) && !isEventMob;
 	}
 
-    @Override
+	@Override
 	public void onSpawn()
-    {
-        super.onSpawn();
-
-        if (getTemplate().getMinionData() != null)
-        {
-            try
-            {
-                for (L2MinionInstance minion : getSpawnedMinions())
-                {
-                    if (minion == null) continue;
-                    getSpawnedMinions().remove(minion);
-                    minion.deleteMe();
-                }
-                _minionList.clearRespawnList();
-
-                manageMinions();
-            }
-            catch ( NullPointerException e )
-            {
-            }
-        }
-    }
+	{
+		super.onSpawn();
+
+		if (_minionList != null)
+		{
+			try
+			{
+				for (L2MinionInstance minion : getSpawnedMinions())
+				{
+					if (minion == null) continue;
+					getSpawnedMinions().remove(minion);
+					minion.deleteMe();
+				}
+				_minionList.clearRespawnList();
+			}
+			catch ( NullPointerException e )
+			{
+			}
+		}
+		startMaintenanceTask();
+	}
 
-    protected int getMaintenanceInterval() { return MONSTER_MAINTENANCE_INTERVAL; }
+	protected int getMaintenanceInterval()
+	{
+		return MONSTER_MAINTENANCE_INTERVAL;
+	}
 
-    /**
-     * Spawn all minions at a regular interval
-     *
-     */
-    protected void manageMinions ()
-    {
-        _minionMaintainTask = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
-            public void run()
-            {
-                _minionList.spawnMinions();
-            }
-        }, getMaintenanceInterval());
-    }
+	/**
+	 * Spawn all minions at a regular interval
+	 *
+	 */
+	protected void startMaintenanceTask()
+	{
+		// maintenance task now used only for minions spawn
+		if (_minionList == null)
+			return;
+
+		_maintenanceTask = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
+			public void run()
+			{
+				_minionList.spawnMinions();
+			}
+		}, getMaintenanceInterval() + Rnd.get(1000));
+	}
 
-    public void callMinions()
-    {
-        if (_minionList.hasMinions())
-        {
-            for (L2MinionInstance minion : _minionList.getSpawnedMinions())
-            {
-                // Get actual coords of the minion and check to see if it's too far away from this L2MonsterInstance
-                if (!isInsideRadius(minion, 200, false, false))
-                {
-                    // Get the coords of the master to use as a base to move the minion to
-                    int masterX = getX();
-                    int masterY = getY();
-                    int masterZ = getZ();
-
-                    // Calculate a new random coord for the minion based on the master's coord
-                    int minionX = masterX + (Rnd.nextInt(401) - 200);
-                    int minionY = masterY + (Rnd.nextInt(401) - 200);
-                    int minionZ = masterZ;
-                    while (((minionX != (masterX + 30)) && (minionX != (masterX - 30))) || ((minionY != (masterY + 30)) && (minionY != (masterY - 30))))
-                    {
-                        minionX = masterX + (Rnd.nextInt(401) - 200);
-                        minionY = masterY + (Rnd.nextInt(401) - 200);
-                    }
-
-                    // Move the minion to the new coords
-                    if (!minion.isInCombat() && !minion.isDead() && !minion.isMovementDisabled())
-                    {
-                        minion.moveToLocation(minionX, minionY, minionZ, 0);
-                    }
-                }
-            }
-        }
-    }
+	public void callMinions()
+	{
+		if (hasMinions())
+		{
+			for (L2MinionInstance minion : _minionList.getSpawnedMinions())
+			{
+				if (minion == null || minion.isDead() || minion.isMovementDisabled())
+					continue;
+
+				// Get actual coords of the minion and check to see if it's too far away from this L2MonsterInstance
+				if (!isInsideRadius(minion, 200, false, false))
+				{
+					// Calculate a new random coord for the minion based on the master's coord
+					// but with minimum distance from master = 30
+					int minionX = Rnd.nextInt(340);
+					int minionY = Rnd.nextInt(340);
+
+					if (minionX < 171)
+						minionX = getX() + minionX + 30;
+					else
+						minionX = getX() - minionX + 140;
+
+					if (minionY < 171)
+						minionY = getY() + minionY + 30;
+					else
+						minionY = getY() - minionY + 140;
+
+					// Move the minion to the new coords
+					if (!minion.isInCombat() && !minion.isDead() && !minion.isMovementDisabled())
+						minion.moveToLocation(minionX, minionY, getZ(), 0);
+				}
+			}
+		}
+	}
 
-    public void callMinionsToAssist(L2Character attacker)
-    {
-        if (_minionList.hasMinions())
-        {
-            List<L2MinionInstance> spawnedMinions = _minionList.getSpawnedMinions();
-            if (spawnedMinions != null && !spawnedMinions.isEmpty())
-            {
-                Iterator<L2MinionInstance> itr = spawnedMinions.iterator();
-                L2MinionInstance minion;
-                while (itr.hasNext())
-                {
-                    minion = itr.next();
-                    // Trigger the aggro condition of the minion
-                    if (minion != null && !minion.isDead())
-                    {
-                        if(isRaid()&&!isRaidMinion())
-                        	minion.addDamage(attacker, 100, null);
-                        else minion.addDamage(attacker, 1, null);
-                    }
-                }
-            }
-        }
-    }
+	public void callMinionsToAssist(L2Character attacker)
+	{
+		if (hasMinions())
+		{
+			for (L2MinionInstance minion : _minionList.getSpawnedMinions())
+			{
+				if (minion == null || minion.isDead())
+					continue;
+
+				// Trigger the aggro condition of the minion
+				if(isRaid()&&!isRaidMinion())
+					minion.addDamage(attacker, 100, null);
+				else minion.addDamage(attacker, 1, null);
+			}
+		}
+	}
 
-    @Override
+	@Override
 	public boolean doDie(L2Character killer)
-    {
-    	if (!super.doDie(killer))
-    		return false;
+	{
+		if (!super.doDie(killer))
+			return false;
 
-    	if (_minionMaintainTask != null)
-            _minionMaintainTask.cancel(true); // doesn't do it?
+		if (_maintenanceTask != null)
+			_maintenanceTask.cancel(true); // doesn't do it?
 
-        if (isRaid() && !isRaidMinion())
-        	deleteSpawnedMinions();
-        return true;
-    }
+		if (hasMinions() && isRaid())
+			deleteSpawnedMinions();
+		return true;
+	}
 
-    public List<L2MinionInstance> getSpawnedMinions()
-    {
-        return _minionList.getSpawnedMinions();
-    }
+	public List<L2MinionInstance> getSpawnedMinions()
+	{
+		if (_minionList == null)
+			return null;
+		return _minionList.getSpawnedMinions();
+	}
 
-    public int getTotalSpawnedMinionsInstances()
-    {
-        return _minionList.countSpawnedMinions();
-    }
+	public int getTotalSpawnedMinionsInstances()
+	{
+		if (_minionList == null)
+			return 0;
+		return _minionList.countSpawnedMinions();
+	}
 
-    public int getTotalSpawnedMinionsGroups()
-    {
-        return _minionList.lazyCountSpawnedMinionsGroups();
-    }
+	public int getTotalSpawnedMinionsGroups()
+	{
+		if (_minionList == null)
+			return 0;
+		return _minionList.lazyCountSpawnedMinionsGroups();
+	}
 
-    public void notifyMinionDied(L2MinionInstance minion)
-    {
-        _minionList.moveMinionToRespawnList(minion);
-    }
+	public void notifyMinionDied(L2MinionInstance minion)
+	{
+		_minionList.moveMinionToRespawnList(minion);
+	}
 
-    public void notifyMinionSpawned(L2MinionInstance minion)
-    {
-        _minionList.addSpawnedMinion(minion);
-    }
+	public void notifyMinionSpawned(L2MinionInstance minion)
+	{
+		_minionList.addSpawnedMinion(minion);
+	}
 
-    public boolean hasMinions()
-    {
-        return _minionList.hasMinions();
-    }
+	public boolean hasMinions()
+	{
+		if (_minionList == null)
+			return false;
+		return _minionList.hasMinions();
+	}
 
-    @Override
+	@Override
 	public void addDamageHate(L2Character attacker, int damage, int aggro)
     {
-        if (!(attacker instanceof L2MonsterInstance))
-        {
-            super.addDamageHate(attacker, damage, aggro);
-        }
+		if (!(attacker instanceof L2MonsterInstance))
+		{
+			super.addDamageHate(attacker, damage, aggro);
+		}
     }
 
     @Override
 	public void deleteMe()
     {
-        if (hasMinions())
-        {
-            if (_minionMaintainTask != null)
-                _minionMaintainTask.cancel(true);
-
-            deleteSpawnedMinions();
-        }
-        super.deleteMe();
+    	if (hasMinions())
+    	{
+    		if (_maintenanceTask != null)
+    			_maintenanceTask.cancel(true);
+
+    		deleteSpawnedMinions();
+    	}
+    	super.deleteMe();
     }
 
     public void deleteSpawnedMinions()
     {
-        for(L2MinionInstance minion : getSpawnedMinions())
-        {
-        	if (minion == null) continue;
-        	minion.abortAttack();
-        	minion.abortCast();
-        	minion.deleteMe();
-        	getSpawnedMinions().remove(minion);
-        }
+    	for(L2MinionInstance minion : getSpawnedMinions())
+    	{
+    		if (minion == null) continue;
+    		minion.abortAttack();
+    		minion.abortCast();
+    		minion.deleteMe();
+    		getSpawnedMinions().remove(minion);
+    	}
     	_minionList.clearRespawnList();
     }
 }

+ 79 - 57
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2RaidBossInstance.java

@@ -14,6 +14,7 @@
  */
 package net.sf.l2j.gameserver.model.actor.instance;
 
+import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.ThreadPoolManager;
 import net.sf.l2j.gameserver.instancemanager.RaidBossPointsManager;
 import net.sf.l2j.gameserver.instancemanager.RaidBossSpawnManager;
@@ -54,27 +55,32 @@ public class L2RaidBossInstance extends L2MonsterInstance
 		super(objectId, template);
 	}
 
-    @Override
+	@Override
 	public void onSpawn()
-    {
-    	setIsRaid(true);
-    	super.onSpawn();
-    }
-    @Override
-    protected int getMaintenanceInterval() { return RAIDBOSS_MAINTENANCE_INTERVAL; }
+	{
+		setIsRaid(true);
+		setIsNoRndWalk(true);
+		super.onSpawn();
+	}
+
+	@Override
+	protected int getMaintenanceInterval()
+	{
+		return RAIDBOSS_MAINTENANCE_INTERVAL;
+	}
 
-    @Override
-    public boolean doDie(L2Character killer)
+	@Override
+	public boolean doDie(L2Character killer)
 	{
 		if (!super.doDie(killer))
 			return false;
-		
+
 		L2PcInstance player = null;
 		if (killer instanceof L2PcInstance)
 			player = (L2PcInstance) killer;
 		else if (killer instanceof L2Summon)
 			player = ((L2Summon) killer).getOwner();
-		
+
 		if (player != null)
 		{
 			broadcastPacket(new SystemMessage(SystemMessageId.RAID_WAS_SUCCESSFUL));
@@ -88,70 +94,86 @@ public class L2RaidBossInstance extends L2MonsterInstance
 			else
 				RaidBossPointsManager.addPoints(player, this.getNpcId(), (this.getLevel() / 2) + Rnd.get(-5, 5));
 		}
-		
+
 		RaidBossSpawnManager.getInstance().updateStatus(this, true);
 		return true;
 	}
 
-    /**
+	/**
 	 * Spawn all minions at a regular interval Also if boss is too far from home
 	 * location at the time of this check, teleport it home
 	 * 
 	 */
-    @Override
-    protected void manageMinions()
-    {
-        _minionList.spawnMinions();
-        _minionMaintainTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Runnable() {
-            public void run()
-            {
-                // teleport raid boss home if it's too far from home location
-                L2Spawn bossSpawn = getSpawn();
-                if(!isInsideRadius(bossSpawn.getLocx(),bossSpawn.getLocy(),bossSpawn.getLocz(), 5000, true, false))
-                {
-                    teleToLocation(bossSpawn.getLocx(),bossSpawn.getLocy(),bossSpawn.getLocz(), true);
-                    healFull(); // prevents minor exploiting with it
-                }
-                _minionList.maintainMinions();
-            }
-        }, 60000, getMaintenanceInterval()+Rnd.get(5000));
-    }
+	@Override
+	protected void startMaintenanceTask()
+	{
+		if (_minionList != null)
+			_minionList.spawnMinions();
 
-    public void setRaidStatus (RaidBossSpawnManager.StatusEnum status)
-    {
-        _raidStatus = status;
-    }
+		_maintenanceTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Runnable() {
+			public void run()
+			{
+				checkAndReturnToSpawn();
 
-    public RaidBossSpawnManager.StatusEnum getRaidStatus()
-    {
-        return _raidStatus;
-    }
+				if (_minionList != null)
+					_minionList.maintainMinions();
+			}
+		}, 60000, getMaintenanceInterval()+Rnd.get(5000));
+	}
+
+	protected void checkAndReturnToSpawn()
+	{
+		if (isDead() || isMovementDisabled())
+			return;
 
-    /**
+		// Gordon does not have permanent spawn
+		if (getNpcId() == 29095)
+			return;
+
+		final L2Spawn spawn = getSpawn();
+		if (spawn == null)
+			return;
+
+		final int spawnX = spawn.getLocx();
+		final int spawnY = spawn.getLocy();
+		final int spawnZ = spawn.getLocz();
+
+		if (!isInCombat() && !isMovementDisabled())
+		{
+			if (!isInsideRadius(spawnX, spawnY, spawnZ, Math.max(Config.MAX_DRIFT_RANGE, 200), true, false))
+				teleToLocation(spawnX, spawnY, spawnZ, false);
+		}
+	}
+
+	/**
      * Reduce the current HP of the L2Attackable, update its _aggroList and launch the doDie Task if necessary.<BR><BR>
      *
      */
-    @Override
+	@Override
     public void reduceCurrentHp(double damage, L2Character attacker, boolean awake, boolean isDOT, L2Skill skill)
     {
-        super.reduceCurrentHp(damage, attacker, awake, isDOT, skill);
+    	super.reduceCurrentHp(damage, attacker, awake, isDOT, skill);
     }
 
-    public void healFull()
-    {
-        super.setCurrentHp(super.getMaxHp());
-        super.setCurrentMp(super.getMaxMp());
-    }
+    public void setRaidStatus (RaidBossSpawnManager.StatusEnum status)
+	{
+		_raidStatus = status;
+	}
 
-    @Override
-    public float getVitalityPoints(int damage)
-    {
-    	return - super.getVitalityPoints(damage) / 100;
-    }
+	public RaidBossSpawnManager.StatusEnum getRaidStatus()
+	{
+		return _raidStatus;
+	}
 
-    @Override
-    public boolean useVitalityRate()
-    {
-    	return false;
-    }
+	@Override
+	public float getVitalityPoints(int damage)
+	{
+		return - super.getVitalityPoints(damage) / 100;
+	}
+
+	@Override
+	public boolean useVitalityRate()
+	{
+		return false;
+	}
 }