diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 06213f63..77bac93b 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -55,6 +55,7 @@ import services.SkillService; import services.StaticService; import services.TerrainService; import services.WeatherService; +import services.ai.AIService; import services.chat.ChatService; import services.collections.CollectionService; import services.combat.CombatService; @@ -66,6 +67,7 @@ import services.guild.GuildService; import services.map.MapService; import services.object.ObjectService; import services.object.UpdateService; +import services.spawn.SpawnService; import services.sui.SUIService; import services.trade.TradeService; import services.travel.TravelService; @@ -140,6 +142,8 @@ public class NGECore { public CollectionService collectionService; public EntertainmentService entertainmentService; public WeatherService weatherService; + public SpawnService spawnService; + public AIService aiService; // Login Server public NetworkDispatch loginDispatch; @@ -214,7 +218,8 @@ 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 try { diff --git a/src/resources/common/collidables/AbstractCollidable.java b/src/resources/common/collidables/AbstractCollidable.java index dbdeed91..443903b7 100644 --- a/src/resources/common/collidables/AbstractCollidable.java +++ b/src/resources/common/collidables/AbstractCollidable.java @@ -24,10 +24,12 @@ package resources.common.collidables; import java.util.Vector; import main.NGECore; +import net.engio.mbassy.bus.SyncMessageBus; import org.python.core.Py; import org.python.core.PyObject; +import engine.resources.common.Event; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -37,6 +39,7 @@ public abstract class AbstractCollidable { private PyObject callback; public Vector collidedObjects = new Vector(); private Planet planet; + private SyncMessageBus eventBus = new SyncMessageBus(NGECore.getInstance().getEventBusConfig()); public abstract boolean doesCollide(SWGObject obj); public abstract boolean doesCollide(Point3D position); @@ -51,10 +54,16 @@ public abstract class AbstractCollidable { public void addCollidedObject(SWGObject obj) { collidedObjects.add(obj); + EnterEvent event = new EnterEvent(); + event.object = obj; + eventBus.publish(event); } public void removeCollidedObject(SWGObject obj) { collidedObjects.remove(obj); + ExitEvent event = new ExitEvent(); + event.object = obj; + eventBus.publish(event); } public boolean isInCollisionList(SWGObject obj) { @@ -82,4 +91,20 @@ public abstract class AbstractCollidable { this.planet = planet; } + public SyncMessageBus getEventBus() { + return eventBus; + } + + public class EnterEvent implements Event { + public SWGObject object; + } + + public class ExitEvent implements Event { + public SWGObject object; + } + + public abstract Point3D getRandomPosition(Point3D origin, float minDistance, float maxDistance); + public abstract Point3D getRandomPosition(); + + } diff --git a/src/resources/common/collidables/CollidableCircle.java b/src/resources/common/collidables/CollidableCircle.java index f17cab76..fef3eacc 100644 --- a/src/resources/common/collidables/CollidableCircle.java +++ b/src/resources/common/collidables/CollidableCircle.java @@ -21,6 +21,8 @@ ******************************************************************************/ package resources.common.collidables; +import java.util.Random; + import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -80,4 +82,26 @@ public class CollidableCircle extends AbstractCollidable { return center.getDistance(position) <= radius; } } + + @Override + public Point3D getRandomPosition(Point3D origin, float minDistance, float maxDistance) { + + Random random = new Random(); + float distance = random.nextInt((int) (maxDistance - minDistance) + 1) + minDistance; + float angle = (float) (random.nextInt(360) * (Math.PI / 180)); + + return new Point3D((float) (origin.x + distance * Math.cos(angle)), 0, (float) (origin.z + distance * Math.sin(angle))); + + } + + @Override + public Point3D getRandomPosition() { + + Random random = new Random(); + float distance = random.nextInt((int) radius); + float angle = (float) (random.nextInt(360) * (Math.PI / 180)); + + return new Point3D((float) (center.x + distance * Math.cos(angle)), 0, (float) (center.z + distance * Math.sin(angle))); + + } } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 35fa7d86..0c441fe6 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -42,6 +42,7 @@ import engine.clientdata.visitors.MeshVisitor; import engine.clientdata.visitors.PortalVisitor; import engine.clientdata.visitors.PortalVisitor.Cell; import engine.clients.Client; +import engine.resources.common.Event; import engine.resources.common.Mesh3DTriangle; import engine.resources.common.Ray; import engine.resources.objects.SWGObject; @@ -956,5 +957,11 @@ public class SimulationService implements INetworkDispatch { collidable.doCollisionCheck(object); } } + + public class MoveEvent implements Event { + + public SWGObject object; + + } } diff --git a/src/services/ai/AIService.java b/src/services/ai/AIService.java index f55abe6a..ea980a89 100644 --- a/src/services/ai/AIService.java +++ b/src/services/ai/AIService.java @@ -36,13 +36,6 @@ public class AIService { this.core = core; } - public void spawnCreature(String template, float x, float y, float z) { - spawnCreature(template, new Point3D(x, y, z)); - } - - public void spawnCreature(String template, Point3D position) { - - } } diff --git a/src/services/spawn/DynamicSpawnArea.java b/src/services/spawn/DynamicSpawnArea.java index 09aafcd3..e588e4cd 100644 --- a/src/services/spawn/DynamicSpawnArea.java +++ b/src/services/spawn/DynamicSpawnArea.java @@ -21,6 +21,28 @@ ******************************************************************************/ package services.spawn; +import net.engio.mbassy.listener.Handler; +import resources.common.collidables.AbstractCollidable; +import resources.common.collidables.AbstractCollidable.EnterEvent; +import resources.common.collidables.AbstractCollidable.ExitEvent; +import engine.resources.scene.Planet; + public class DynamicSpawnArea extends SpawnArea { + public DynamicSpawnArea(Planet planet, AbstractCollidable area) { + super(planet, area); + } + + @Override + @Handler + public void onEnter(EnterEvent event) { + + } + + @Override + @Handler + public void onExit(ExitEvent event) { + + } + } diff --git a/src/services/spawn/LairGroupTemplate.java b/src/services/spawn/LairGroupTemplate.java new file mode 100644 index 00000000..0f6347dd --- /dev/null +++ b/src/services/spawn/LairGroupTemplate.java @@ -0,0 +1,17 @@ +package services.spawn; + +import java.util.Vector; + +public class LairGroupTemplate { + + private Vector lairSpawnTemplates; + + public Vector getLairSpawnTemplates() { + return lairSpawnTemplates; + } + + public void setLairSpawnTemplates(Vector lairSpawnTemplates) { + this.lairSpawnTemplates = lairSpawnTemplates; + } + +} diff --git a/src/services/spawn/LairSpawnArea.java b/src/services/spawn/LairSpawnArea.java index 63dc0200..da136ba6 100644 --- a/src/services/spawn/LairSpawnArea.java +++ b/src/services/spawn/LairSpawnArea.java @@ -21,6 +21,108 @@ ******************************************************************************/ package services.spawn; -public class LairSpawnArea extends SpawnArea { +import java.util.Random; +import java.util.Vector; +import main.NGECore; +import net.engio.mbassy.listener.Handler; +import resources.common.collidables.AbstractCollidable; +import resources.common.collidables.AbstractCollidable.EnterEvent; +import resources.common.collidables.AbstractCollidable.ExitEvent; +import resources.objects.creature.CreatureObject; +import services.SimulationService.MoveEvent; +import services.TerrainService; +import engine.resources.objects.SWGObject; +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; + +public class LairSpawnArea extends SpawnArea { + + private LairGroupTemplate lairGroup; + + public LairSpawnArea(Planet planet, AbstractCollidable area) { + super(planet, area); + } + + public LairGroupTemplate getLairGroup() { + return lairGroup; + } + + public void setLairGroup(LairGroupTemplate lairGroup) { + this.lairGroup = lairGroup; + } + + public void spawnLair(CreatureObject object) { + + Vector lairTemplates = lairGroup.getLairSpawnTemplates(); + + if(lairGroup == null || lairTemplates.isEmpty()) + return; + + Point3D randomPosition = getRandomPosition(object.getWorldPosition(), 32.f, 256.f); + + if(randomPosition == null) + return; + + TerrainService terrainSvc = NGECore.getInstance().terrainService; + + float height = terrainSvc.getHeight(getPlanet().getID(), randomPosition.x, randomPosition.z); + randomPosition.y = height; + + if(!terrainSvc.canBuildAtPosition(object, randomPosition.x, randomPosition.z)) + return; + + Random random = new Random(); + + LairSpawnTemplate lairSpawn = lairTemplates.get(random.nextInt(lairTemplates.size())); + + int level = random.nextInt((int) (lairSpawn.getMaxLevel() - lairSpawn.getMinLevel()) + 1) + lairSpawn.getMinLevel(); + + NGECore.getInstance().spawnService.spawnLair(lairSpawn.getLairTemplate(), getPlanet(), randomPosition, level); + + } + + @Override + @Handler + public void onEnter(EnterEvent event) { + + SWGObject object = event.object; + + if(object == null || !(object instanceof CreatureObject)) + return; + + CreatureObject creature = (CreatureObject) object; + + if(creature.getSlottedObject("ghost") == null) + return; + + spawnLair(creature); + + } + + @Override + @Handler + public void onExit(ExitEvent event) { + + } + + @Handler + public void onMove(MoveEvent event) { + + SWGObject object = event.object; + + if(object == null || !(object instanceof CreatureObject) || object.getContainer() != null) + return; + + CreatureObject creature = (CreatureObject) object; + + if(creature.getSlottedObject("ghost") == null) + return; + + if(new Random().nextFloat() <= 0.10) + spawnLair(creature); + + } + + } diff --git a/src/services/spawn/LairSpawnTemplate.java b/src/services/spawn/LairSpawnTemplate.java new file mode 100644 index 00000000..50538b9a --- /dev/null +++ b/src/services/spawn/LairSpawnTemplate.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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 LairSpawnTemplate { + + private int maxSpawnLimit; + private LairTemplate lairTemplate; + private int minLevel; + private int maxLevel; + + public int getMaxSpawnLimit() { + return maxSpawnLimit; + } + + public void setMaxSpawnLimit(int maxSpawnLimit) { + this.maxSpawnLimit = maxSpawnLimit; + } + + public LairTemplate getLairTemplate() { + return lairTemplate; + } + + public void setLairTemplate(LairTemplate lairTemplate) { + this.lairTemplate = lairTemplate; + } + + public int getMinLevel() { + return minLevel; + } + + public void setMinLevel(int minLevel) { + this.minLevel = minLevel; + } + + public int getMaxLevel() { + return maxLevel; + } + + public void setMaxLevel(int maxLevel) { + this.maxLevel = maxLevel; + } + + + +} diff --git a/src/services/spawn/LairTemplate.java b/src/services/spawn/LairTemplate.java new file mode 100644 index 00000000..94df1517 --- /dev/null +++ b/src/services/spawn/LairTemplate.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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 LairTemplate { + + private String lairCRC; + private String mobileName; + + public String getLairCRC() { + return lairCRC; + } + + public void setLairCRC(String lairCRC) { + this.lairCRC = lairCRC; + } + + public String getMobileName() { + return mobileName; + } + + public void setMobileName(String mobileName) { + this.mobileName = mobileName; + } + +} diff --git a/src/services/spawn/SpawnArea.java b/src/services/spawn/SpawnArea.java index 342749a5..2d64c576 100644 --- a/src/services/spawn/SpawnArea.java +++ b/src/services/spawn/SpawnArea.java @@ -21,11 +21,30 @@ ******************************************************************************/ package services.spawn; +import java.util.Vector; + +import net.engio.mbassy.listener.Handler; + +import resources.common.collidables.AbstractCollidable; +import resources.common.collidables.AbstractCollidable.EnterEvent; +import resources.common.collidables.AbstractCollidable.ExitEvent; + +import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; public abstract class SpawnArea { private Planet planet; + private Vector templates; + private AbstractCollidable area; + private Vector observers = new Vector(); + + public SpawnArea(Planet planet, AbstractCollidable area) { + this.planet = planet; + this.area = area; + area.getEventBus().subscribe(this); + } public Planet getPlanet() { return planet; @@ -35,4 +54,58 @@ public abstract class SpawnArea { this.planet = planet; } + public Vector getTemplates() { + return templates; + } + + public void setTemplates(Vector templates) { + this.templates = templates; + } + + public AbstractCollidable getArea() { + return area; + } + + public void setArea(AbstractCollidable area) { + this.area = area; + } + + @Handler + public abstract void onEnter(EnterEvent event); + @Handler + public abstract void onExit(ExitEvent event); + + public Vector getObservers() { + return observers; + } + + public Point3D getRandomPosition() { + + int tries = 0; + + while(tries++ < 10) { + Point3D randomPos = area.getRandomPosition(); + if(area.doesCollide(randomPos)) + return randomPos; + } + + return null; + + } + + public Point3D getRandomPosition(Point3D origin, float minDistance, float maxDistance) { + + int tries = 0; + + while(tries++ < 10) { + Point3D randomPos = area.getRandomPosition(origin, minDistance, maxDistance); + if(area.doesCollide(randomPos)) + return randomPos; + } + + return null; + + } + + } diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java index 7c6435e3..1fd5152f 100644 --- a/src/services/spawn/SpawnService.java +++ b/src/services/spawn/SpawnService.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; import main.NGECore; public class SpawnService { @@ -34,6 +35,19 @@ public class SpawnService { public SpawnService(NGECore core) { + } + + public void spawnCreature(String template, float x, float y, float z) { + spawnCreature(template, new Point3D(x, y, z)); } + public void spawnCreature(String template, Point3D position) { + + } + + public void spawnLair(LairTemplate lairTemplate, Planet planet, Point3D position, int level) { + + } + + } diff --git a/src/services/spawn/StaticSpawnArea.java b/src/services/spawn/StaticSpawnArea.java index 9a0911fd..64de8d63 100644 --- a/src/services/spawn/StaticSpawnArea.java +++ b/src/services/spawn/StaticSpawnArea.java @@ -21,6 +21,28 @@ ******************************************************************************/ package services.spawn; +import net.engio.mbassy.listener.Handler; +import resources.common.collidables.AbstractCollidable; +import resources.common.collidables.AbstractCollidable.EnterEvent; +import resources.common.collidables.AbstractCollidable.ExitEvent; +import engine.resources.scene.Planet; + public class StaticSpawnArea extends SpawnArea { + public StaticSpawnArea(Planet planet, AbstractCollidable area) { + super(planet, area); + } + + @Override + @Handler + public void onEnter(EnterEvent event) { + + } + + @Override + @Handler + public void onExit(ExitEvent event) { + + } + }