diff --git a/ngengine_public.jar b/ngengine_public.jar index 71e72b65..58350bf8 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/commands/transferitemarmor.py b/scripts/commands/transferitemarmor.py index ab107cf3..23e6dc42 100644 --- a/scripts/commands/transferitemarmor.py +++ b/scripts/commands/transferitemarmor.py @@ -15,15 +15,22 @@ def run(core, actor, target, commandString): return; replacedObject = None slotName = None + replacedObjects = [] + slotNames = None if actor == container: - slotName = container.getSlotNameForObject(target) - replacedObject = container.getSlottedObject(slotName) - + slotNames = container.getSlotNamesForObject(target) + for slotName in slotNames: + object = container.getSlottedObject(slotName) + if not object in replacedObjects and not object == None: + replacedObjects.append(object) + oldContainer.transferTo(actor, container, target) if actor == container: if target.getTemplate().find('/wearables/') or target.getTemplate().find('/weapon/'): - core.equipmentService.equip(actor, target, replacedObject) + core.equipmentService.equip(actor, target) + for object in replacedObjects: + core.equipmentService.unequip(actor, object) #path = 'scripts/' + target.getTemplate().rpartition('/')[0] + '/' #module = target.getTemplate().rpartition('/')[2].replace('shared_', '').replace('.iff', '') #core.scriptService.callScript(path, 'equip', module, core, actor, target) diff --git a/scripts/commands/transferitemmisc.py b/scripts/commands/transferitemmisc.py index 53eef0d6..e5c8b47e 100644 --- a/scripts/commands/transferitemmisc.py +++ b/scripts/commands/transferitemmisc.py @@ -17,15 +17,22 @@ def run(core, actor, target, commandString): replacedObject = None slotName = None + replacedObjects = [] + slotNames = None if actor == container: - slotName = container.getSlotNameForObject(target) - replacedObject = container.getSlottedObject(slotName) - + slotNames = container.getSlotNamesForObject(target) + for slotName in slotNames: + object = container.getSlottedObject(slotName) + if not object in replacedObjects and not object == None: + replacedObjects.append(object) + oldContainer.transferTo(actor, container, target) if actor == container: if target.getTemplate().find('/wearables/') or target.getTemplate().find('/weapon/'): - core.equipmentService.equip(actor, target, replacedObject) + core.equipmentService.equip(actor, target) + for object in replacedObjects: + core.equipmentService.unequip(actor, object) #path = 'scripts/' + target.getTemplate().rpartition('/')[0] + '/' #module = target.getTemplate().rpartition('/')[2].replace('shared_', '').replace('.iff', '') #core.scriptService.callScript(path, 'equip', module, core, actor, target) diff --git a/scripts/commands/transferitemweapon.py b/scripts/commands/transferitemweapon.py index 0bb7f55f..8c54e57a 100644 --- a/scripts/commands/transferitemweapon.py +++ b/scripts/commands/transferitemweapon.py @@ -16,15 +16,22 @@ def run(core, actor, target, commandString): replacedObject = None slotName = None + replacedObjects = [] + slotNames = None if actor == container: - slotName = container.getSlotNameForObject(target) - replacedObject = container.getSlottedObject(slotName) - + slotNames = container.getSlotNamesForObject(target) + for slotName in slotNames: + object = container.getSlottedObject(slotName) + if not object in replacedObjects and not object == None: + replacedObjects.append(object) + oldContainer.transferTo(actor, container, target) if actor == container: if target.getTemplate().find('/wearables/') or target.getTemplate().find('/weapon/'): - core.equipmentService.equip(actor, target, replacedObject) + core.equipmentService.equip(actor, target) + for object in replacedObjects: + core.equipmentService.unequip(actor, object) #path = 'scripts/' + target.getTemplate().rpartition('/')[0] + '/' #module = target.getTemplate().rpartition('/')[2].replace('shared_', '').replace('.iff', '') #core.scriptService.callScript(path, 'equip', module, core, actor, target) diff --git a/scripts/mobiles/lairgroups/tatooine_starter.py b/scripts/mobiles/lairgroups/tatooine_starter.py new file mode 100644 index 00000000..63eda38c --- /dev/null +++ b/scripts/mobiles/lairgroups/tatooine_starter.py @@ -0,0 +1,9 @@ +import sys +from services.spawn import LairSpawnTemplate +from java.util import Vector + +def addLairGroup(core): + spawnTemplate = LairSpawnTemplate(-1, 'tatooine_kreetle_lair_neutral_small', 5, 20) + spawnTemplates = Vector() + spawnTemplates.add(spawnTemplate) + core.spawnService.addLairGroup('tatooine_starter', spawnTemplates) \ No newline at end of file diff --git a/scripts/mobiles/lairs/tatooine_kreetle_lair_neutral_small.py b/scripts/mobiles/lairs/tatooine_kreetle_lair_neutral_small.py new file mode 100644 index 00000000..76e76ebe --- /dev/null +++ b/scripts/mobiles/lairs/tatooine_kreetle_lair_neutral_small.py @@ -0,0 +1,4 @@ +import sys + +def addTemplate(core): + core.spawnService.addLairTemplate('tatooine_kreetle_lair_neutral_small', 'kreetle', 15, 'object/tangible/lair/base/shared_poi_all_lair_brambles_small.iff') \ No newline at end of file diff --git a/scripts/mobiles/spawnareas/mos_eisley_lair.py b/scripts/mobiles/spawnareas/mos_eisley_lair.py new file mode 100644 index 00000000..fe0b5291 --- /dev/null +++ b/scripts/mobiles/spawnareas/mos_eisley_lair.py @@ -0,0 +1,6 @@ +import sys + +def addSpawnArea(core): + core.spawnService.addLairSpawnArea('tatooine_starter', 3400, -4775, 2048, 'tatooine') + + diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 77bac93b..6fd87731 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -218,7 +218,6 @@ public class NGECore { skillModService = new SkillModService(this); equipmentService = new EquipmentService(this); entertainmentService = new EntertainmentService(this); - spawnService = new SpawnService(this); aiService = new AIService(this); // Ping Server @@ -268,6 +267,7 @@ public class NGECore { terrainService.addPlanet(10, "dathomir", "terrain/dathomir.trn", true); terrainService.addPlanet(11, "mustafar", "terrain/mustafar.trn", true); terrainService.addPlanet(12, "kashyyyk_main", "terrain/kashyyyk_main.trn", true); + spawnService = new SpawnService(this); terrainService.loadClientPois(); // Travel Points travelService.loadTravelPoints(); @@ -302,10 +302,14 @@ public class NGECore { weatherService = new WeatherService(this); weatherService.loadPlanetSettings(); + // spawnService.loadLairTemplates(); + // spawnService.loadLairGroups(); + // spawnService.loadSpawnAreas(); + didServerCrash = false; System.out.println("Started Server."); setGalaxyStatus(2); - + } diff --git a/src/resources/objects/building/BuildingMessageBuilder.java b/src/resources/objects/building/BuildingMessageBuilder.java index 606f5f78..e05d9df0 100644 --- a/src/resources/objects/building/BuildingMessageBuilder.java +++ b/src/resources/objects/building/BuildingMessageBuilder.java @@ -43,7 +43,7 @@ public class BuildingMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); buffer.put(getAsciiString(building.getStfName())); buffer.putInt(0); - buffer.putInt(255); + buffer.putInt(0); buffer.putInt(0); buffer.putInt(0); buffer.putInt(0); diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 90ed5851..2ae391d4 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -58,7 +58,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(creature.getCashCredits()); buffer.putInt(6); // Base HAM List - so leveling knows the base HAM, before equipment etc - buffer.putInt(6); + buffer.putInt(0); buffer.putInt(creature.getHealth()); buffer.putInt(0); buffer.putInt(creature.getAction()); @@ -113,7 +113,8 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(1); buffer.putInt(0); // TANO Data buffer.putInt(0); - buffer.putInt(creature.getOptionsBitmask()); // 0x80 = Player, 0x08 = Quest NPC, + // buffer.putInt(creature.getOptionsBitmask()); // 0x80 = Player, 0x08 = Quest NPC, + buffer.putInt(0x80); buffer.putInt(creature.getIncapTimer()); buffer.putInt(0); buffer.putInt(0x3A98); @@ -268,7 +269,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); buffer.putInt(6); // Max HAM - buffer.putInt(0); + buffer.putInt(creature.getMaxHAMListCounter()); buffer.putInt(creature.getMaxHealth()); buffer.putInt(0); @@ -701,7 +702,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { return buffer; - } + } public IoBuffer buildMaxHealthDelta(int health) { diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index ea367d8f..0f313801 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -948,11 +948,12 @@ public class CreatureObject extends TangibleObject implements IPersistent { //destination.getSession().write(messageBuilder.buildBaseline9()); UpdatePostureMessage upm = new UpdatePostureMessage(getObjectID(), (byte) 0); - //destination.getSession().write(upm.serialize()); + // destination.getSession().write(upm.serialize()); if(destination != getClient()) { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()); - + if(getSlottedObject("ghost") != null) + upvpm.setStatus(16); /* if (factionStatus == 1 && faction == "imperial") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial); @@ -1067,7 +1068,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { if(health > maxHealth) health = maxHealth; setHamListCounter(getHamListCounter() + 1); - delta = messageBuilder.buildHealthDelta(health); + delta = messageBuilder.buildUpdateHAMListDelta(); notifyObservers(delta, true); this.health = health; @@ -1087,7 +1088,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { if(action > maxAction) action = maxAction; setHamListCounter(getHamListCounter() + 1); - delta = messageBuilder.buildActionDelta(action); + delta = messageBuilder.buildUpdateHAMListDelta(); notifyObservers(delta, true); this.action = action; } @@ -1225,6 +1226,13 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } + public void updateHAMList() { + synchronized(objectMutex) { + setHamListCounter(getHamListCounter() + 1); + notifyObservers(messageBuilder.buildUpdateHAMListDelta(), true); + } + } + public SWGList getDotList() { return dotList; } diff --git a/src/resources/objects/tangible/TangibleMessageBuilder.java b/src/resources/objects/tangible/TangibleMessageBuilder.java index fdb7142b..08d93f72 100644 --- a/src/resources/objects/tangible/TangibleMessageBuilder.java +++ b/src/resources/objects/tangible/TangibleMessageBuilder.java @@ -63,7 +63,8 @@ public class TangibleMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); buffer.putInt(0); - buffer.putInt(tangible.getOptionsBitmask()); + buffer.putInt(0); + //buffer.putInt(tangible.getOptionsBitmask()); buffer.putInt(0); // number of item uses buffer.putInt(tangible.getConditionDamage()); buffer.putInt(tangible.getMaxDamage()); diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 5a9a56f6..256c4415 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -358,7 +358,7 @@ public class TangibleObject extends SWGObject { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); - upvpm.setStatus(1); + upvpm.setStatus(getPvPBitmask()); destination.getSession().write(upvpm.serialize()); diff --git a/src/services/EquipmentService.java b/src/services/EquipmentService.java index 8223e3b0..ddb56bdb 100644 --- a/src/services/EquipmentService.java +++ b/src/services/EquipmentService.java @@ -50,10 +50,10 @@ public class EquipmentService implements INetworkDispatch { } - public void equip(CreatureObject actor, SWGObject item, SWGObject replacedItem) { + public void equip(CreatureObject actor, SWGObject item) { - if(replacedItem != null) - unequip(actor, replacedItem); + //if(replacedItem != null) + // unequip(actor, replacedItem); String template = item.getTemplate(); String serverTemplate = template.replace(".iff", ""); diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index 453c7945..8a986c22 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -127,6 +127,7 @@ public class PlayerService implements INetworkDispatch { } }, 0, 1000, TimeUnit.MILLISECONDS); + scheduler.scheduleAtFixedRate(new Runnable() { @@ -142,18 +143,6 @@ public class PlayerService implements INetworkDispatch { }, 0, 1000, TimeUnit.MILLISECONDS); - /*scheduler.scheduleAtFixedRate(new Runnable() { - - @Override - public void run() { - - if(creature.getCombatFlag() == 1) - creature.resetHAMList(); - - } - - }, 0, 10, TimeUnit.SECONDS);*/ - } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 31ee4181..46c605e5 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -169,18 +169,30 @@ public class SimulationService implements INetworkDispatch { return collidableQuadTrees.get(planet.getName()).get(x, y, range); } - public void add(SWGObject object, int x, int y) { - object.setIsInQuadtree(true); - core.objectService.loadServerTemplate(object); - quadTrees.get(object.getPlanet().getName()).put(x, y, object); - } - public boolean add(SWGObject object, float x, float y) { - object.setIsInQuadtree(true); - core.objectService.loadServerTemplate(object); - return quadTrees.get(object.getPlanet().getName()).put(x, y, object); + return add(object, x, y, false); } - + + public boolean add(SWGObject object, float x, float y, boolean notifyObservers) { + object.setIsInQuadtree(true); + //core.objectService.loadServerTemplate(object); + boolean success = quadTrees.get(object.getPlanet().getName()).put(x, y, object); + if(success && notifyObservers) { + Point3D pos = new Point3D(x, 0, y); + Collection newAwareObjects = get(object.getPlanet(), x, y, 512); + for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { + SWGObject obj = it.next(); + if(obj.getAttachment("bigSpawnRange") == null && obj.getWorldPosition().getDistance(pos) > 200) + continue; + if(object.getClient() != null) + object.makeAware(obj); + if(obj.getClient() != null) + obj.makeAware(object); + } + } + return success; + } + public boolean move(SWGObject object, int oldX, int oldY, int newX, int newY) { if(quadTrees.get(object.getPlanet().getName()).remove(oldX, oldY, object)) { return quadTrees.get(object.getPlanet().getName()).put(newX, newY, object); @@ -198,22 +210,27 @@ public class SimulationService implements INetworkDispatch { System.out.println("Move failed."); return false; } - - public List get(Planet planet, int x, int y, int range) { - return quadTrees.get(planet.getName()).get(x, y, range); - } - + public List get(Planet planet, float x, float y, int range) { List list = quadTrees.get(planet.getName()).get((int)x, (int)y, range); return list; } - public boolean remove(SWGObject object, int x, int y) { - return quadTrees.get(object.getPlanet().getName()).remove(x, y, object); - } - public boolean remove(SWGObject object, float x, float y) { + return remove(object, x, y, false); + } + + public boolean remove(SWGObject object, float x, float y, boolean notifyObservers) { boolean success = quadTrees.get(object.getPlanet().getName()).remove(x, y, object); + if(success) { + HashSet oldObservers = new HashSet(object.getObservers()); + for(Iterator it = oldObservers.iterator(); it.hasNext();) { + Client observerClient = it.next(); + if(observerClient.getParent() != null) { + observerClient.getParent().makeUnaware(object); + } + } + } return success; } @@ -284,6 +301,10 @@ public class SimulationService implements INetworkDispatch { object.makeUnaware(obj); if(obj.getClient() != null) obj.makeUnaware(object); + } else if(obj != object && obj.getWorldPosition().getDistance2D(newPos) > 200 && obj.isInQuadtree() && obj.getAttachment("bigSpawnRange") == null) { + object.makeUnaware(obj); + if(obj.getClient() != null) + obj.makeUnaware(object); } } for(int i = 0; i < newAwareObjects.size(); i++) { @@ -299,7 +320,10 @@ public class SimulationService implements INetworkDispatch { } checkForCollidables(object); - + MoveEvent event = new MoveEvent(); + event.object = object; + object.getEventBus().publish(event); + } @@ -512,11 +536,11 @@ public class SimulationService implements INetworkDispatch { } session.suspendWrite(); - + boolean remove = remove(object, object.getPosition().x, object.getPosition().z); if(remove) System.out.println("Successful quadtree remove"); - + //if(object.getContainer() == null) { HashSet oldObservers = new HashSet(object.getObservers()); for(Iterator it = oldObservers.iterator(); it.hasNext();) { @@ -551,19 +575,20 @@ public class SimulationService implements INetworkDispatch { Point3D pos = object.getWorldPosition(); - Collection newAwareObjects = get(object.getPlanet(), pos.x, pos.z, 512); - for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { - SWGObject obj = it.next(); - if(obj.getAttachment("bigSpawnRange") == null & obj.getWorldPosition().getDistance(pos) > 200) - continue; - object.makeAware(obj); - if(obj.getClient() != null) - obj.makeAware(object); + if(object.getParentId() != 0) { + Collection newAwareObjects = get(object.getPlanet(), pos.x, pos.z, 512); + for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { + SWGObject obj = it.next(); + if(obj.getAttachment("bigSpawnRange") == null & obj.getWorldPosition().getDistance(pos) > 200) + continue; + object.makeAware(obj); + if(obj.getClient() != null) + obj.makeAware(object); + } + } else { + add(object, pos.x, pos.z, true); } - if(object.getParentId() == 0) - add(object, pos.x, pos.z); - PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); if (ghost != null) { @@ -621,18 +646,18 @@ public class SimulationService implements INetworkDispatch { Point3D position = object.getPosition(); if(object.getParentId() == 0 && object.getContainer() == null) { - remove(object, position.x, position.z); + remove(object, position.x, position.z, true); } else { object.getContainer().remove(object); } - HashSet oldObservers = new HashSet(object.getObservers()); + /*HashSet oldObservers = new HashSet(object.getObservers()); for(Client observerClient : oldObservers) { if(observerClient.getParent() != null) { observerClient.getParent().makeUnaware(object); } - } + }*/ synchronized(object.getMutex()) { @@ -952,7 +977,7 @@ public class SimulationService implements INetworkDispatch { public void checkForCollidables(SWGObject object) { Point3D objectPos = object.getWorldPosition(); - List collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 256); + List collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 2050); for(AbstractCollidable collidable : collidables) { collidable.doCollisionCheck(object); diff --git a/src/services/TerrainService.java b/src/services/TerrainService.java index eb1c9808..e58d6cfa 100644 --- a/src/services/TerrainService.java +++ b/src/services/TerrainService.java @@ -79,12 +79,12 @@ public class TerrainService { private void loadClientRegions(Planet planet) { - if(!FileUtilities.doesFileExist("datatables/clientregion/" + planet.getName() + ".iff")) + if(!FileUtilities.doesFileExist("clientdata/datatables/clientregion/" + planet.getName() + ".iff")) return; - + try { - DatatableVisitor regionTable = ClientFileManager.loadFile("datatables/clientpoi/clientpoi.iff", DatatableVisitor.class); + DatatableVisitor regionTable = ClientFileManager.loadFile("datatables/clientregion/" + planet.getName() + ".iff", DatatableVisitor.class); for (int i = 0; i < regionTable.getRowCount(); i++) { @@ -222,14 +222,15 @@ public class TerrainService { public boolean canBuildAtPosition(SWGObject object, float x, float z) { - if(isWater(object.getPlanet(), z, z)) + if(isWater(object.getPlanet(), x, z)) return false; Point3D position = new Point3D(x, 0, z); for(CollidableCircle noBuildArea : noBuildAreas.get(object.getPlanet())) { - if(noBuildArea.doesCollide(position)) + if(noBuildArea.doesCollide(position)) { return false; + } } return true; diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index bb8efca5..39dd02ee 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -54,7 +54,7 @@ public class AIActor { } public void doAggro(CreatureObject defender) { - + creature.addDefender(defender); } public AIState getCurrentState() { diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index 06a84ce2..859d770d 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -90,7 +90,7 @@ public class CombatService implements INetworkDispatch { if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptCombat(attacker, target)) success = false; - if(!applySpecialCost(attacker, weapon, command)) + if(success && !applySpecialCost(attacker, weapon, command)) success = false; if(!success) { @@ -839,14 +839,14 @@ public class CombatService implements INetworkDispatch { boolean success = true; + if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptHeal(healer, target)) + target = healer; + if(target.getMaxHealth() == target.getHealth()) success = command.getAttackType() != 1; - if(!applySpecialCost(healer, weapon, command)) + if(success && !applySpecialCost(healer, weapon, command)) success = false; - - if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptHeal(healer, target)) - target = healer; if(!success) { IoSession session = healer.getClient().getSession(); diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index b08ad2f9..3ffae4e9 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -554,9 +554,9 @@ public class ObjectService implements INetworkDispatch { session.write(startScene.serialize()); creature.makeAware(core.guildService.getGuildObject()); + creature.makeAware(creature); core.simulationService.handleZoneIn(client); - creature.makeAware(creature); CmdSceneReady sceneReady = new CmdSceneReady(); client.getSession().write(sceneReady.serialize()); diff --git a/src/services/spawn/DynamicSpawnArea.java b/src/services/spawn/DynamicSpawnArea.java index e588e4cd..a5df57d7 100644 --- a/src/services/spawn/DynamicSpawnArea.java +++ b/src/services/spawn/DynamicSpawnArea.java @@ -25,6 +25,7 @@ import net.engio.mbassy.listener.Handler; import resources.common.collidables.AbstractCollidable; import resources.common.collidables.AbstractCollidable.EnterEvent; import resources.common.collidables.AbstractCollidable.ExitEvent; +import services.SimulationService.MoveEvent; import engine.resources.scene.Planet; public class DynamicSpawnArea extends SpawnArea { diff --git a/src/services/spawn/LairGroupTemplate.java b/src/services/spawn/LairGroupTemplate.java index 0f6347dd..4cca3ea2 100644 --- a/src/services/spawn/LairGroupTemplate.java +++ b/src/services/spawn/LairGroupTemplate.java @@ -5,6 +5,12 @@ import java.util.Vector; public class LairGroupTemplate { private Vector lairSpawnTemplates; + private String name; + + public LairGroupTemplate(String name, Vector lairSpawnTemplates) { + this.name = name; + this.lairSpawnTemplates = lairSpawnTemplates; + } public Vector getLairSpawnTemplates() { return lairSpawnTemplates; @@ -14,4 +20,12 @@ public class LairGroupTemplate { this.lairSpawnTemplates = lairSpawnTemplates; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } diff --git a/src/services/spawn/LairSpawnArea.java b/src/services/spawn/LairSpawnArea.java index da136ba6..31b26f96 100644 --- a/src/services/spawn/LairSpawnArea.java +++ b/src/services/spawn/LairSpawnArea.java @@ -39,9 +39,11 @@ import engine.resources.scene.Point3D; public class LairSpawnArea extends SpawnArea { private LairGroupTemplate lairGroup; + private long lastSpawnTime = 0; - public LairSpawnArea(Planet planet, AbstractCollidable area) { + public LairSpawnArea(Planet planet, AbstractCollidable area, LairGroupTemplate lairGroup) { super(planet, area); + this.lairGroup = lairGroup; } public LairGroupTemplate getLairGroup() { @@ -58,6 +60,9 @@ public class LairSpawnArea extends SpawnArea { if(lairGroup == null || lairTemplates.isEmpty()) return; + + if((System.currentTimeMillis() - lastSpawnTime) < 3000) + return; Point3D randomPosition = getRandomPosition(object.getWorldPosition(), 32.f, 256.f); @@ -79,6 +84,7 @@ public class LairSpawnArea extends SpawnArea { int level = random.nextInt((int) (lairSpawn.getMaxLevel() - lairSpawn.getMinLevel()) + 1) + lairSpawn.getMinLevel(); NGECore.getInstance().spawnService.spawnLair(lairSpawn.getLairTemplate(), getPlanet(), randomPosition, level); + lastSpawnTime = System.currentTimeMillis(); } @@ -97,13 +103,26 @@ public class LairSpawnArea extends SpawnArea { return; spawnLair(creature); - + creature.getEventBus().subscribe(this); + } @Override @Handler public void onExit(ExitEvent event) { + SWGObject object = event.object; + + if(object == null || !(object instanceof CreatureObject)) + return; + + CreatureObject creature = (CreatureObject) object; + + if(creature.getSlottedObject("ghost") == null) + return; + + creature.getEventBus().unsubscribe(this); + } @Handler @@ -123,6 +142,14 @@ public class LairSpawnArea extends SpawnArea { spawnLair(creature); } + + public long getLastSpawnTime() { + return lastSpawnTime; + } + + public void setLastSpawnTime(long lastSpawnTime) { + this.lastSpawnTime = lastSpawnTime; + } } diff --git a/src/services/spawn/LairSpawnTemplate.java b/src/services/spawn/LairSpawnTemplate.java index 50538b9a..74844770 100644 --- a/src/services/spawn/LairSpawnTemplate.java +++ b/src/services/spawn/LairSpawnTemplate.java @@ -24,9 +24,16 @@ package services.spawn; public class LairSpawnTemplate { private int maxSpawnLimit; - private LairTemplate lairTemplate; + private String lairTemplate; private int minLevel; private int maxLevel; + + public LairSpawnTemplate(int maxSpawnLimit, String lairTemplate, int minLevel, int maxLevel) { + this.maxSpawnLimit = maxSpawnLimit; + this.lairTemplate = lairTemplate; + this.minLevel = minLevel; + this.maxLevel = maxLevel; + } public int getMaxSpawnLimit() { return maxSpawnLimit; @@ -36,11 +43,11 @@ public class LairSpawnTemplate { this.maxSpawnLimit = maxSpawnLimit; } - public LairTemplate getLairTemplate() { + public String getLairTemplate() { return lairTemplate; } - public void setLairTemplate(LairTemplate lairTemplate) { + public void setLairTemplate(String lairTemplate) { this.lairTemplate = lairTemplate; } diff --git a/src/services/spawn/LairTemplate.java b/src/services/spawn/LairTemplate.java index 94df1517..2a97bfcc 100644 --- a/src/services/spawn/LairTemplate.java +++ b/src/services/spawn/LairTemplate.java @@ -23,8 +23,17 @@ package services.spawn; public class LairTemplate { + private String name; private String lairCRC; private String mobileName; + private int mobileLimit; + + public LairTemplate(String name, String mobile, int mobileLimit, String lairCRC) { + this.name = name; + this.mobileName = mobile; + this.mobileLimit = mobileLimit; + this.lairCRC = lairCRC; + } public String getLairCRC() { return lairCRC; @@ -42,4 +51,20 @@ public class LairTemplate { this.mobileName = mobileName; } + public int getMobileLimit() { + return mobileLimit; + } + + public void setMobileLimit(int mobileLimit) { + this.mobileLimit = mobileLimit; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } diff --git a/src/services/spawn/MobileTemplate.java b/src/services/spawn/MobileTemplate.java new file mode 100644 index 00000000..7af0d515 --- /dev/null +++ b/src/services/spawn/MobileTemplate.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.spawn; + +public class MobileTemplate { + +} diff --git a/src/services/spawn/SpawnArea.java b/src/services/spawn/SpawnArea.java index 2d64c576..aadb1746 100644 --- a/src/services/spawn/SpawnArea.java +++ b/src/services/spawn/SpawnArea.java @@ -28,6 +28,7 @@ import net.engio.mbassy.listener.Handler; import resources.common.collidables.AbstractCollidable; import resources.common.collidables.AbstractCollidable.EnterEvent; import resources.common.collidables.AbstractCollidable.ExitEvent; +import services.SimulationService.MoveEvent; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java index 1fd5152f..1b08bbf3 100644 --- a/src/services/spawn/SpawnService.java +++ b/src/services/spawn/SpawnService.java @@ -21,20 +21,45 @@ ******************************************************************************/ package services.spawn; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; + +import org.python.core.Py; + +import resources.common.Options; +import resources.common.PvpStatus; +import resources.common.collidables.CollidableCircle; +import resources.objects.tangible.TangibleObject; +import services.ai.LairActor; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; import main.NGECore; public class SpawnService { private NGECore core; private Map> spawnAreas = new ConcurrentHashMap>(); + private Map mobileTemplates = new ConcurrentHashMap(); + private Map lairGroupTemplates = new ConcurrentHashMap(); + private Map lairTemplates = new ConcurrentHashMap(); public SpawnService(NGECore core) { - + this.core = core; + for(Planet planet : core.terrainService.getPlanetList()) { + spawnAreas.put(planet, new ArrayList()); + } } public void spawnCreature(String template, float x, float y, float z) { @@ -45,8 +70,100 @@ public class SpawnService { } - public void spawnLair(LairTemplate lairTemplate, Planet planet, Point3D position, int level) { + public void spawnLair(String lairSpawnTemplate, Planet planet, Point3D position, int level) { + LairTemplate lairTemplate = lairTemplates.get(lairSpawnTemplate); + if(lairTemplate == null) + return; + TangibleObject lairObject = (TangibleObject) core.objectService.createObject(lairTemplate.getLairCRC(), 0, planet, position, new Quaternion(1, 0, 0, 0)); + + if(lairObject == null) + return; + + lairObject.setOptionsBitmask(Options.ATTACKABLE); + lairObject.setPvPBitmask(PvpStatus.Attackable); + lairObject.setMaxDamage(1000 * level); + + LairActor lairActor = new LairActor(lairObject, lairTemplate.getMobileName()); + lairObject.setAttachment("AI", lairActor); + + core.simulationService.add(lairObject, position.x, position.z, true); + + } + + public void loadMobileTemplates() { + + } + + public void addMobileTemplate() { + + } + + public void loadLairTemplates() { + Path p = Paths.get("scripts/mobiles/lairs"); + FileVisitor fv = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + core.scriptService.callScript("scripts/mobiles/lairs/", file.getFileName().toString().replace(".py", ""), "addTemplate", core); + return FileVisitResult.CONTINUE; + } + }; + try { + Files.walkFileTree(p, fv); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void addLairTemplate(String name, String mobile, int mobileLimit, String lairCRC) { + lairTemplates.put(name, new LairTemplate(name, mobile, mobileLimit, lairCRC)); + } + + public void loadLairGroups() { + Path p = Paths.get("scripts/mobiles/lairgroups"); + FileVisitor fv = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + core.scriptService.callScript("scripts/mobiles/lairgroups/", file.getFileName().toString().replace(".py", ""), "addLairGroup", core); + return FileVisitResult.CONTINUE; + } + }; + try { + Files.walkFileTree(p, fv); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void addLairGroup(String name, Vector lairSpawnTemplates) { + lairGroupTemplates.put(name, new LairGroupTemplate(name, lairSpawnTemplates)); + } + + public void loadSpawnAreas() { + Path p = Paths.get("scripts/mobiles/spawnareas"); + FileVisitor fv = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + core.scriptService.callScript("scripts/mobiles/spawnareas/", file.getFileName().toString().replace(".py", ""), "addSpawnArea", core); + return FileVisitResult.CONTINUE; + } + }; + try { + Files.walkFileTree(p, fv); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void addLairSpawnArea(String lairGroup, float x, float z, float radius, String planetName) { + LairGroupTemplate lairGroupTemplate = lairGroupTemplates.get(lairGroup); + Planet planet = core.terrainService.getPlanetByName(planetName); + if(lairGroupTemplate == null || planet == null) + return; + CollidableCircle collidableCircle = new CollidableCircle(new Point3D(x, 0, z), radius, planet); + LairSpawnArea lairSpawnArea = new LairSpawnArea(planet, collidableCircle, lairGroupTemplate); + spawnAreas.get(planet).add(lairSpawnArea); + core.simulationService.addCollidable(collidableCircle, x, z); } diff --git a/src/services/spawn/StaticSpawnArea.java b/src/services/spawn/StaticSpawnArea.java index 64de8d63..2bce6aef 100644 --- a/src/services/spawn/StaticSpawnArea.java +++ b/src/services/spawn/StaticSpawnArea.java @@ -25,6 +25,7 @@ import net.engio.mbassy.listener.Handler; import resources.common.collidables.AbstractCollidable; import resources.common.collidables.AbstractCollidable.EnterEvent; import resources.common.collidables.AbstractCollidable.ExitEvent; +import services.SimulationService.MoveEvent; import engine.resources.scene.Planet; public class StaticSpawnArea extends SpawnArea {