All pastes #68564 Raw Edit

Someone

public text v1 · immutable
#68564 ·published 2006-06-21 20:07 UTC
rendered paste body
Index: D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2MinionInstance.java
===================================================================
--- D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2MinionInstance.java	(revision 2117)
+++ D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2MinionInstance.java	(working copy)
@@ -18,7 +18,10 @@
  */
 package net.sf.l2j.gameserver.model.actor.instance;
 
+import net.sf.l2j.gameserver.ai.L2AttackableAI;
 import net.sf.l2j.gameserver.model.L2Character;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.L2WorldRegion;
 import net.sf.l2j.gameserver.templates.L2NpcTemplate;
 
 /**
@@ -69,6 +72,12 @@
     {
         // Notify Leader that Minion has Spawned
         getLeader().notifyMinionSpawned(this);
+        
+        // check the region where this mob is, do not activate the AI if region is inactive.
+        L2WorldRegion region = L2World.getInstance().getRegion(getX(),getY());
+        if ((region !=null) && (!region.isActive()))
+            ((L2AttackableAI) getAI()).stopAITask();        
+
     }
 	
 	/**
Index: D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2GuardInstance.java
===================================================================
--- D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2GuardInstance.java	(revision 2117)
+++ D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2GuardInstance.java	(working copy)
@@ -23,9 +23,12 @@
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.ThreadPoolManager;
 import net.sf.l2j.gameserver.ai.CtrlIntention;
+import net.sf.l2j.gameserver.ai.L2AttackableAI;
 import net.sf.l2j.gameserver.model.L2Attackable;
 import net.sf.l2j.gameserver.model.L2CharPosition;
 import net.sf.l2j.gameserver.model.L2Character;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.L2WorldRegion;
 import net.sf.l2j.gameserver.model.actor.knownlist.GuardKnownList;
 import net.sf.l2j.gameserver.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.serverpackets.MyTargetSelected;
@@ -131,7 +134,12 @@
 		_homeZ = getZ();
 		
 		if (Config.DEBUG)
-			_log.finer(getObjectId()+": Home location set to"+" X:" + _homeX + " Y:" + _homeY + " Z:" + _homeZ);		
+			_log.finer(getObjectId()+": Home location set to"+" X:" + _homeX + " Y:" + _homeY + " Z:" + _homeZ);
+
+        // check the region where this mob is, do not activate the AI if region is inactive.
+        L2WorldRegion region = L2World.getInstance().getRegion(getX(),getY());
+        if ((region !=null) && (!region.isActive()))
+            ((L2AttackableAI) getAI()).stopAITask();        
 	}
 	
 	
Index: D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java
===================================================================
--- D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java	(revision 2117)
+++ D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java	(working copy)
@@ -76,7 +76,7 @@
 import net.sf.l2j.gameserver.templates.L2Item;
 import net.sf.l2j.gameserver.templates.L2NpcTemplate;
 import net.sf.l2j.gameserver.templates.L2Weapon;
-
+import net.sf.l2j.gameserver.model.L2WorldRegion;
 /**
  * This class represents a Non-Player-Character in the world. It can be a monster or a friendly character.
  * It also uses a template to fetch some static values. The templates are hardcoded in the client, so we can rely on them.<BR><BR>
Index: D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2WorldRegion.java
===================================================================
--- D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2WorldRegion.java	(revision 2117)
+++ D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2WorldRegion.java	(working copy)
@@ -23,12 +23,16 @@
 import java.util.logging.Logger;
 
 import javolution.util.FastList;
+import java.util.concurrent.ScheduledFuture;
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.SpawnTable;
 import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.ai.L2AttackableAI;
+import net.sf.l2j.gameserver.ThreadPoolManager;
 import net.sf.l2j.util.L2ObjectSet;
 
+
 /**
  * This class ...
  * 
@@ -46,6 +50,8 @@
 
     private List<L2WorldRegion> _surroundingRegions;
     private int tileX, tileY;
+    private Boolean _active = false;   
+    private ScheduledFuture _neighborsTask = null;
 
     public L2WorldRegion(int pTileX, int pTileY)
     {
@@ -56,9 +62,172 @@
 
         this.tileX = pTileX;
         this.tileY = pTileY;
+        
+        // default a newly initialized region to inactive
+        _active = false;
     }
+    
+    /** Task of AI notification */
+    public class NeighborsTask implements Runnable
+    {
+        private boolean _isActivating;
+        
+        public NeighborsTask(boolean isActivating)
+        {
+            _isActivating = isActivating;
+        }
+        
+        public void run()
+        {
+            if (_isActivating)
+            {
+                // for each neighbor, if it's not active, activate.
+                for (L2WorldRegion neighbor: getSurroundingRegions())
+                    neighbor.setActive(true);
+            }
+            else
+            {
+                if(areNeighborsEmpty())
+                    setActive(false);
+                
+                // check and deactivate
+                for (L2WorldRegion neighbor: getSurroundingRegions())
+                    if(neighbor.areNeighborsEmpty())
+                        neighbor.setActive(false);   
+            }
+        }
+    }
+    
+    private void switchAI(Boolean isOn)
+    {
+        int c = 0;
+        if (!isOn)
+        {
+            for(L2Object o: _visibleObjects)
+                if (o instanceof L2Attackable)
+                {
+                    c++;
+                    L2Attackable mob = (L2Attackable)o;
+                    // Set target to null and cancel Attack or Cast
+                    mob.setTarget(null);
+                    
+                    // Stop movement
+                    mob.stopMove(null);
+                    
+                    // Stop HP/MP/CP Regeneration task
+                    mob.getStatus().stopHpMpRegeneration();
+                    
+                    // Stop all active skills effects in progress on the L2Character
+                    mob.stopAllEffects();
+                    
+                    // stop the ai tasks
+                    ((L2AttackableAI) mob.getAI()).stopAITask();
+                }
+            System.out.println(c+ " mobs were turned off");
+        }
+        else
+        {
+            for(L2Object o: _visibleObjects)
+                if (o instanceof L2Attackable)
+                {
+                    c++;
+                    L2Attackable mob = (L2Attackable)o;
+                    // Start HP/MP/CP Regeneration task
+                    mob.getStatus().startHpMpRegeneration();
+                    
+                    // start the ai
+                    ((L2AttackableAI) mob.getAI()).startAITask();
+                }
+            System.out.println(c+ " mobs were turned on");
+        }
+        
+    }
 
+    public Boolean isActive()
+    {
+        return _active;
+    }
+    
+    // check if all 9 neighbors (including self) are inactive or active but with no players.
+    // returns true if the above condition is met. 
+    public Boolean areNeighborsEmpty()
+    {
+        // if this region is occupied, return false.
+        if (isActive() && (_allPlayers.size() > 0 ))
+            return false;
+        
+        // if any one of the neighbors is occupied, return false
+        for (L2WorldRegion neighbor: _surroundingRegions)
+            if (neighbor.isActive() && (neighbor._allPlayers.size() > 0))
+                return false;
+        
+        // in all other cases, return true.
+        return true;
+    }
+    
     /**
+     * this function turns this region's AI and geodata on or off
+     * @param value
+     */   
+    public void setActive(Boolean value)
+    {
+        if (_active == value)
+            return;
+        
+        _active = value;
+        
+        // turn the AI on or off to match the region's activation.
+        switchAI(value);
+        
+        // TODO
+        // turn the geodata on or off to match the region's activation.
+        if(value)
+            _log.fine("Starting Grid " + tileX + ","+ tileY);
+        else
+            _log.fine("Stoping Grid " + tileX + ","+ tileY);
+    }
+
+    /** Immediately sets self as active and starts a timer to set neighbors as active
+     * this timer is to avoid turning on neighbors in the case when a person just 
+     * teleported into a region and then teleported out immediately...there is no 
+     * reason to activate all the neighbors in that case.
+     */
+    public void startActivation()
+    {
+        // first set self to active and do self-tasks...
+        setActive(true);
+        
+        // if the timer to deactivate neighbors is running, cancel it.
+        if(_neighborsTask !=null)
+        {
+            _neighborsTask.cancel(true);
+            _neighborsTask = null;
+        }
+        
+        // then, set a timer to activate the neighbors
+        _neighborsTask = ThreadPoolManager.getInstance().scheduleGeneral(new NeighborsTask(true), 30000);
+    }
+    
+    /** starts a timer to set neighbors (including self) as inactive
+     * this timer is to avoid turning off neighbors in the case when a person just 
+     * moved out of a region that he may very soon return to.  There is no reason
+     * to turn self & neighbors off in that case.
+     */
+    public void startDeactivation()
+    {
+        // if the timer to activate neighbors is running, cancel it.
+        if(_neighborsTask !=null)
+        {
+            _neighborsTask.cancel(true);
+            _neighborsTask = null;
+        }
+        
+        // start a timer to "suggest" a deactivate to self and neighbors.
+        // suggest means: first check if a neighbor has L2PcInstances in it.  If not, deactivate.
+        _neighborsTask = ThreadPoolManager.getInstance().scheduleGeneral(new NeighborsTask(false), 30000);
+    }
+    
+    /**
      * Add the L2Object in the L2ObjectHashSet(L2Object) _visibleObjects containing L2Object visible in this L2WorldRegion <BR>
      * If L2Object is a L2PcInstance, Add the L2PcInstance in the L2ObjectHashSet(L2PcInstance) _allPlayers
      * containing L2PcInstance of all player in game in this L2WorldRegion <BR>
@@ -73,6 +242,10 @@
         if (object instanceof L2PcInstance)
         {
             _allPlayers.put((L2PcInstance) object);
+
+            // if this is the first player to enter the region, activate self & neighbors
+            if (_allPlayers.size() == 1 )
+                startActivation();
         }
     }
 
@@ -92,6 +265,9 @@
         if (object instanceof L2PcInstance)
         {
             _allPlayers.remove((L2PcInstance) object);
+            
+            if (_allPlayers.size() == 0 )
+                startDeactivation();
         }
     }
 
Index: D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2World.java
===================================================================
--- D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2World.java	(revision 2117)
+++ D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2World.java	(working copy)
@@ -46,7 +46,7 @@
      * note, shifting by 15 will result in regions corresponding to map tiles
      * shifting by 12 divides one tile to 8x8 regions
      */
-    private static final int SHIFT_BY = 13;
+    private static final int SHIFT_BY = 12;
     
     /** Map dimensions */
     public static final int MAP_MIN_X = -131072;
@@ -75,7 +75,6 @@
         
     private L2WorldRegion[][] _worldRegions;
     
-    
     /**
      * Constructor of L2World.<BR><BR>
      */
Index: D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2Attackable.java
===================================================================
--- D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2Attackable.java	(revision 2117)
+++ D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/model/L2Attackable.java	(working copy)
@@ -1591,7 +1591,6 @@
         return true;
     }
     
-    @Override
     public void OnSpawn()
     {
         // Clear mob spoil,seed
@@ -1604,6 +1603,11 @@
         _absorbersList = null;
         
         setWalking();
+        
+        // check the region where this mob is, do not activate the AI if region is inactive.
+        L2WorldRegion region = L2World.getInstance().getRegion(getX(),getY());
+        if ((region !=null) && (!region.isActive()))
+            ((L2AttackableAI) getAI()).stopAITask();        
     }
     
     public void setSeeded(int id, int seederLvl)
Index: D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/lib/Rnd.java
===================================================================
--- D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/lib/Rnd.java	(revision 2117)
+++ D:/l2jc4/L2_GameServer_c4/java/net/sf/l2j/gameserver/lib/Rnd.java	(working copy)
@@ -18,7 +18,7 @@
  */
 package net.sf.l2j.gameserver.lib;
 
-import java.util.Random;
+import net.sf.l2j.util.MTRandom;
 
 /**$
  * 
@@ -27,7 +27,7 @@
  */
 public class Rnd
 {
-	private static Random _rnd = new Random();;
+    private static MTRandom _rnd = new MTRandom();
 	
 	public static final float get()	// get random number from 0 to 1
 	{
@@ -41,7 +41,7 @@
 
 	public static final int get(int min, int max)  // get random number from min to max (not max-1 !)
 	{
-		return min + _rnd.nextInt(max - min + 1);
+        return min + (int)Math.floor(_rnd.nextDouble()*(max - min + 1));
 	}
 	public static final int nextInt(int n)  
 	{