diff --git a/src/services/objects/ObjectAwareness.java b/src/services/objects/ObjectAwareness.java new file mode 100644 index 000000000..58c3a7400 --- /dev/null +++ b/src/services/objects/ObjectAwareness.java @@ -0,0 +1,94 @@ +package services.objects; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import resources.Location; +import resources.Terrain; +import resources.objects.SWGObject; +import resources.objects.creature.CreatureObject; +import resources.objects.quadtree.QuadTree; + +public class ObjectAwareness { + + private static final double AWARE_RANGE = 200; + + private final Map > quadTree; + + public ObjectAwareness() { + quadTree = new HashMap>(); + } + + public boolean initialize() { + loadQuadTree(); + return true; + } + + private void loadQuadTree() { + for (Terrain t : Terrain.values()) { + quadTree.put(t, new QuadTree(-8192, -8192, 8192, 8192)); + } + } + + public void add(SWGObject object) { + update(object); + Location l = object.getLocation(); + if (invalidLocation(l)) + return; + QuadTree tree = getTree(l); + synchronized (tree) { + tree.put(l.getX(), l.getZ(), object); + } + } + + public void remove(SWGObject object) { + Location l = object.getLocation(); + if (invalidLocation(l)) + return; + QuadTree tree = getTree(l); + synchronized (tree) { + tree.remove(l.getX(), l.getZ(), object); + } + } + + public void move(SWGObject object, Location nLocation) { + remove(object); + object.setLocation(nLocation); + add(object); + } + + public void update(SWGObject obj) { + Location l = obj.getLocation(); + if (invalidLocation(l)) + return; + List objectAware = new LinkedList(); + QuadTree tree = getTree(l); + synchronized (tree) { + List range = tree.getWithinRange(l.getX(), l.getZ(), AWARE_RANGE); + for (SWGObject inRange : range) { + if (isValidInRange(obj, inRange)) + objectAware.add(inRange); + } + } + obj.updateObjectAwareness(objectAware); + } + + private QuadTree getTree(Location l) { + return quadTree.get(l.getTerrain()); + } + + private boolean invalidLocation(Location l) { + return l == null || l.getTerrain() == null; + } + + private boolean isValidInRange(SWGObject obj, SWGObject inRange) { + if (inRange.getObjectId() == obj.getObjectId()) + return false; + if (inRange instanceof CreatureObject && inRange.getOwner() == null) + return false; + return true; + } + +} \ No newline at end of file diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java index 144b5550e..d64376fa6 100644 --- a/src/services/objects/ObjectManager.java +++ b/src/services/objects/ObjectManager.java @@ -33,7 +33,6 @@ import intents.network.GalacticPacketIntent; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -60,8 +59,6 @@ import resources.objects.SWGObject; import resources.objects.buildouts.BuildoutLoader; import resources.objects.creature.CreatureMood; import resources.objects.creature.CreatureObject; -import resources.objects.quadtree.QuadTree; -import resources.objects.waypoint.WaypointObject; import resources.player.Player; import resources.player.PlayerEvent; import resources.player.PlayerFlags; @@ -73,17 +70,19 @@ import services.player.PlayerManager; public class ObjectManager extends Manager { - private static final double AWARE_RANGE = 200; - private final Map > buildoutObjects; private final ObjectDatabase objects; - private final Map > quadTree; + private final ObjectAwareness objectAwareness; private long maxObjectId; public ObjectManager() { + this("odb/objects.db"); + } + + public ObjectManager(String odbFile) { buildoutObjects = new HashMap>(); - objects = new CachedObjectDatabase("odb/objects.db"); - quadTree = new HashMap>(); + objects = new CachedObjectDatabase(odbFile); + objectAwareness = new ObjectAwareness(); maxObjectId = 1; } @@ -92,18 +91,12 @@ public class ObjectManager extends Manager { registerForIntent(GalacticPacketIntent.TYPE); registerForIntent(PlayerEventIntent.TYPE); registerForIntent(ObjectTeleportIntent.TYPE); - loadQuadTree(); + objectAwareness.initialize(); loadObjects(); loadBuildouts(); return super.initialize(); } - private void loadQuadTree() { - for (Terrain t : Terrain.values()) { - quadTree.put(t, new QuadTree(-8192, -8192, 8192, 8192)); - } - } - private void loadObjects() { long startLoad = System.nanoTime(); System.out.println("ObjectManager: Loading objects from ObjectDatabase..."); @@ -157,15 +150,7 @@ public class ObjectManager extends Manager { private void loadObject(SWGObject obj) { obj.setOwner(null); - Location l = obj.getLocation(); - if (l.getTerrain() != null) { - QuadTree tree = quadTree.get(l.getTerrain()); - if (tree != null) { - tree.put(l.getX(), l.getZ(), obj); - } else { - System.err.println("ObjectManager: Unable to load QuadTree for object " + obj.getObjectId() + " and terrain: " + l.getTerrain()); - } - } + objectAwareness.add(obj); } @Override @@ -197,19 +182,13 @@ public class ObjectManager extends Manager { private void processObjectTeleportIntent(ObjectTeleportIntent oti) { SWGObject object = oti.getObject(); - - removeFromQuadTree(object); - object.setLocation(oti.getNewLocation()); - + objectAwareness.move(object, oti.getNewLocation()); - if(object instanceof CreatureObject && object.getOwner() != null){ + if (object instanceof CreatureObject && object.getOwner() != null){ sendPacket(object.getOwner(), new CmdStartScene(false, object.getObjectId(), ((CreatureObject)object).getRace(), object.getLocation(), (long)(ProjectSWG.getCoreTime()/1E3))); ((CreatureObject)object).createObject(object.getOwner()); ((CreatureObject)object).clearAware(); } - updateAwarenessForObject(object); - addToQuadTree(object); - } private void processGalacticPacketIntent(GalacticPacketIntent gpi) { @@ -239,13 +218,7 @@ public class ObjectManager extends Manager { SWGObject obj = objects.remove(objId); if (obj == null) return null; - Location loc = obj.getLocation(); - if (loc != null && loc.getTerrain() != null) { - QuadTree tree = quadTree.get(loc.getTerrain()); - synchronized (tree) { - tree.remove(loc.getX(), loc.getZ(), obj); - } - } + objectAwareness.remove(obj); for (SWGObject child : obj.getChildren()) if (child != null) deleteObject(child.getObjectId()); @@ -269,49 +242,18 @@ public class ObjectManager extends Manager { return null; } obj.setLocation(l); - updateAwarenessForObject(obj); - addToQuadTree(obj); + objectAwareness.add(obj); objects.put(objectId, obj); return obj; } } - private void addToQuadTree(SWGObject obj) { - if (obj == null || obj instanceof WaypointObject) - return; - Location loc = obj.getLocation(); - if (loc == null || loc.getTerrain() == null) - return; - QuadTree tree = quadTree.get(loc.getTerrain()); - synchronized (tree) { - tree.put(loc.getX(), loc.getZ(), obj); - } - } - - private void removeFromQuadTree(SWGObject obj) { - if (obj == null) - return; - Location loc = obj.getLocation(); - if (loc == null || loc.getTerrain() == null) - return; - double x = loc.getX(); - double y = loc.getZ(); - QuadTree tree = quadTree.get(loc.getTerrain()); - synchronized (tree) { - tree.remove(x, y, obj); - } - } - private void moveObject(SWGObject obj, DataTransform transform) { if (transform == null) return; - removeFromQuadTree(obj); Location newLocation = transform.getLocation(); newLocation.setTerrain(obj.getLocation().getTerrain()); - obj.setLocation(newLocation); - - updateAwarenessForObject(obj); - addToQuadTree(obj); + objectAwareness.move(obj, newLocation); if (obj instanceof CreatureObject && transform.getSpeed() > 1E-3) { if(((CreatureObject) obj).getPosture() == Posture.PRONE){ @@ -324,29 +266,6 @@ public class ObjectManager extends Manager { obj.sendDataTransforms(transform); } - private void updateAwarenessForObject(SWGObject obj) { - Location location = obj.getLocation(); - if (location == null || location.getTerrain() == null) - return; - List objectAware = new LinkedList(); - double x = location.getX(); - double y = location.getZ(); - QuadTree tree = quadTree.get(location.getTerrain()); - synchronized (tree) { - List range = tree.getWithinRange(x, y, AWARE_RANGE); - for (SWGObject inRange : range) { - if (inRange.getObjectId() != obj.getObjectId()) { - if (inRange instanceof CreatureObject) { - if (inRange.getOwner() != null) - objectAware.add(inRange); - } else - objectAware.add(inRange); - } - } - } - obj.updateObjectAwareness(objectAware); - } - private void zoneInCharacter(PlayerManager playerManager, String galaxy, long netId, long characterId) { Player player = playerManager.getPlayerFromNetworkId(netId); if (player == null) @@ -372,7 +291,7 @@ public class ObjectManager extends Manager { sendPacket(player, new UpdatePvpStatusMessage(creature.getPvpType(), creature.getPvpFactionId(), creature.getObjectId())); creature.createObject(player); creature.clearAware(); - updateAwarenessForObject(creature); + objectAwareness.update(creature); System.out.println("[" + player.getUsername() + "] " + player.getCharacterName() + " is zoning in"); new PlayerEventIntent(player, galaxy, PlayerEvent.PE_ZONE_IN).broadcast(); }