diff --git a/nge.cfg b/nge.cfg index 328f9018..e1d27c80 100644 --- a/nge.cfg +++ b/nge.cfg @@ -11,3 +11,5 @@ DB.URL=localhost DB.PASS=nge GALAXY_ID=2 GALAXY_NAME=Local Connection +XPMULTIPLIER=1.0 +MAXNUMBEROFCHARACTERS=2 \ No newline at end of file diff --git a/ngengine_public.jar b/ngengine_public.jar index 53e5bc95..ffa4476f 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/commands/serverdestroyobject.py b/scripts/commands/serverdestroyobject.py index e3541bce..81c01698 100644 --- a/scripts/commands/serverdestroyobject.py +++ b/scripts/commands/serverdestroyobject.py @@ -22,7 +22,7 @@ def run(core, actor, target, commandString): Console.println("Doesn't have permission!") return - parent.remove(target) + #parent.remove(target) core.objectService.destroyObject(target) return \ No newline at end of file diff --git a/scripts/commands/setgodmode.py b/scripts/commands/setgodmode.py index 536a588b..70d4c547 100644 --- a/scripts/commands/setgodmode.py +++ b/scripts/commands/setgodmode.py @@ -73,4 +73,12 @@ def run(core, actor, target, commandString): elif command == 'comm': comm = CommPlayerMessage(actor.getObjectId()) actor.getClient().getSession().write(comm.serialize()) + + elif command == 'spawn' and arg1 and arg2: + pos = actor.getWorldPosition() + core.spawnService.spawnCreature(arg1, actor.getPlanet().getName(), 0, pos.x, pos.y, pos.z, 1, 0, 1, 0, int(arg2)) + + elif command == 'instance' and arg1: + core.instanceService.queue(arg1, actor) + return diff --git a/scripts/mobiles/tatooine/krayt_dragon_ancient.py b/scripts/mobiles/tatooine/krayt_dragon_ancient.py new file mode 100644 index 00000000..23adfbc0 --- /dev/null +++ b/scripts/mobiles/tatooine/krayt_dragon_ancient.py @@ -0,0 +1,18 @@ +import sys +from services.spawn import MobileTemplate +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + templates = Vector() + templates.add('object/mobile/shared_krayt_dragon.iff') + mobileTemplate.setTemplates(templates) + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(2) + attacks = Vector() + mobileTemplate.setDefaultAttack('creatureMeleeAttack') + mobileTemplate.setAttacks(attacks) + mobileTemplate.setCreatureName('krayt_dragon_ancient') + mobileTemplate.setScale(2) + core.spawnService.addMobileTemplate('krayt_dragon_ancient', mobileTemplate) + \ No newline at end of file diff --git a/src/main/NGECore.java b/src/main/NGECore.java index b4b8eb5a..b58a3922 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -408,10 +408,10 @@ public class NGECore { weatherService = new WeatherService(this); weatherService.loadPlanetSettings(); - /*spawnService.loadMobileTemplates(); + spawnService.loadMobileTemplates(); spawnService.loadLairTemplates(); spawnService.loadLairGroups(); - spawnService.loadSpawnAreas();*/ + spawnService.loadSpawnAreas(); retroService.run(); diff --git a/src/resources/common/collidables/AbstractCollidable.java b/src/resources/common/collidables/AbstractCollidable.java index 443903b7..b7f9a157 100644 --- a/src/resources/common/collidables/AbstractCollidable.java +++ b/src/resources/common/collidables/AbstractCollidable.java @@ -60,6 +60,8 @@ public abstract class AbstractCollidable { } public void removeCollidedObject(SWGObject obj) { + if(!collidedObjects.contains(obj)) + return; collidedObjects.remove(obj); ExitEvent event = new ExitEvent(); event.object = obj; diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 2d1844c9..33241f1a 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -1085,7 +1085,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { } public void removeObjectFromEquipList(SWGObject object) { - if(object instanceof TangibleObject) { + if(object instanceof TangibleObject && equipmentList.contains(object)) { setEquipmentListUpdateCounter(getEquipmentListUpdateCounter() + 1); notifyObservers(messageBuilder.buildRemoveEquipmentDelta((TangibleObject) object), true); equipmentList.get().remove(object); @@ -1101,7 +1101,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { } public void removeObjectFromAppearanceEquipList(SWGObject object) { - if(object instanceof TangibleObject) { + if(object instanceof TangibleObject && appearanceEquipmentList.contains(object)) { setAppearanceEquipmentListUpdateCounter(getAppearanceEquipmentListUpdateCounter() + 1); notifyObservers(messageBuilder.buildRemoveAppearanceEquipmentDelta((TangibleObject) object), true); appearanceEquipmentList.get().remove(object); diff --git a/src/services/BuffService.java b/src/services/BuffService.java index aa822001..f712daf4 100644 --- a/src/services/BuffService.java +++ b/src/services/BuffService.java @@ -95,7 +95,7 @@ public class BuffService implements INetworkDispatch { return null; } - if (!core.simulationService.checkLineOfSight(buffer, target)) { + if (target != buffer && !core.simulationService.checkLineOfSight(buffer, target)) { return null; } diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index af6c7071..b5b47f9c 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -25,6 +25,7 @@ import java.nio.ByteOrder; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -45,7 +46,6 @@ import protocol.swg.ConnectionServerLagResponse; import protocol.swg.GalaxyLoopTimesResponse; import protocol.swg.GameServerLagResponse; import protocol.swg.HeartBeatMessage; - import engine.clients.Client; import engine.resources.database.DatabaseConnection; import engine.resources.scene.Point3D; @@ -64,7 +64,7 @@ public class ConnectionService implements INetworkDispatch { private NGECore core; private DatabaseConnection databaseConnection; private DatabaseConnection databaseConnection2; - + private int maxNumberOfCharacters; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public ConnectionService(final NGECore core) { @@ -72,6 +72,7 @@ public class ConnectionService implements INetworkDispatch { this.core = core; this.databaseConnection = core.getDatabase1(); this.databaseConnection2 = core.getDatabase2(); + this.maxNumberOfCharacters = core.getConfig().getInt("MAXNUMBEROFCHARACTERS"); scheduler.scheduleAtFixedRate(new Runnable() { @@ -125,7 +126,7 @@ public class ConnectionService implements INetworkDispatch { client.setSessionKey(clientIdMsg.getSessionKey()); client.setGM(core.loginService.checkForGmPermission((int) resultSet.getLong("accountId"))); AccountFeatureBits accountFeatureBits = new AccountFeatureBits(); - ClientPermissionsMessage clientPermissionsMessage = new ClientPermissionsMessage(2 - core.characterService.getNumberOfCharacters((int) resultSet.getLong("accountId"))); + ClientPermissionsMessage clientPermissionsMessage = new ClientPermissionsMessage(maxNumberOfCharacters - core.characterService.getNumberOfCharacters((int) resultSet.getLong("accountId"))); session.write(new HeartBeatMessage().serialize()); session.write(accountFeatureBits.serialize()); session.write(clientPermissionsMessage.serialize()); @@ -232,10 +233,7 @@ public class ConnectionService implements INetworkDispatch { List collidables = core.simulationService.getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 512); - for(AbstractCollidable collidable : collidables) { - collidables.remove(object); - } - + collidables.forEach(c -> c.removeCollidedObject(object)); if (ghost != null) { String objectShortName = object.getCustomName(); diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index 885d4999..89b6cdbe 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -125,7 +125,7 @@ public class EntertainmentService implements INetworkDispatch { end.setBufferId(buffer.getObjectId()); end.setBuffRecipientId(buffRecipient.getObjectId()); - + ObjControllerMessage closeMessage = new ObjControllerMessage(0x0B, end); buffer.getClient().getSession().write(closeMessage.serialize()); CreatureObject cre = (CreatureObject) buffer; @@ -480,30 +480,24 @@ public class EntertainmentService implements INetworkDispatch { } public void startPerformanceExperience(final CreatureObject entertainer) { - final ScheduledFuture experienceTask = scheduler.scheduleAtFixedRate(new Runnable() { - - @Override - public void run() { - - Performance p = performancesByIndex.get(entertainer.getPerformanceId()); - if (p == null) { - entertainer.setFlourishCount(0); - return; - } - - int floXP = p.getFlourishXpMod(); - int floCount = entertainer.getFlourishCount(); - - //FIXME: this is not an accurate implementation yet. It needs group bonuses and other things. - int XP = (int) Math.round( ((floCount > 2) ? 2 : floCount) * floXP * 3.8 ); - + final ScheduledFuture experienceTask = scheduler.scheduleAtFixedRate(() -> { + + Performance p = performancesByIndex.get(entertainer.getPerformanceId()); + if (p == null) { entertainer.setFlourishCount(0); - core.playerService.giveExperience(entertainer, XP); - - + return; } - },10000, 10000, TimeUnit.MILLISECONDS); + int floXP = p.getFlourishXpMod(); + int floCount = entertainer.getFlourishCount(); + + //FIXME: this is not an accurate implementation yet. It needs group bonuses and other things. + int XP = (int) Math.round( ((floCount > 2) ? 2 : floCount) * floXP * 3.8 ); + + entertainer.setFlourishCount(0); + core.playerService.giveExperience(entertainer, XP); + + }, 10000, 10000, TimeUnit.MILLISECONDS); entertainer.setEntertainerExperience(experienceTask); @@ -522,28 +516,25 @@ public class EntertainmentService implements INetworkDispatch { performer.addAudience(spectator); spectator.setMoodAnimation("entertained"); - final ScheduledFuture spectatorTask = scheduler.scheduleAtFixedRate(new Runnable() { + final ScheduledFuture spectatorTask = scheduler.scheduleAtFixedRate(() -> { + + if (spectator.getPosition().getDistance2D(performer.getWorldPosition()) > (float) 70) { - @Override - public void run() { - if (spectator.getPosition().getDistance2D(performer.getWorldPosition()) > (float) 70) { - - if(((performer.getPerformanceType()) ? "dance" : "music").equals("dance")) { - spectator.setPerformanceWatchee(null); - spectator.sendSystemMessage("You stop watching " + performer.getCustomName() + " because " + performer.getCustomName() - + " is out of range.", (byte) 0); - } - else { - spectator.setPerformanceListenee(null); - spectator.sendSystemMessage("You stop listening to " + performer.getCustomName() + " because " + performer.getCustomName() - + " is out of range.", (byte) 0); - } - spectator.setMoodAnimation("neutral"); - performer.removeAudience(spectator); - - if (spectator.getInspirationTick().cancel(true)) - spectator.getSpectatorTask().cancel(true); + if(((performer.getPerformanceType()) ? "dance" : "music").equals("dance")) { + spectator.setPerformanceWatchee(null); + spectator.sendSystemMessage("You stop watching " + performer.getCustomName() + " because " + performer.getCustomName() + + " is out of range.", (byte) 0); } + else { + spectator.setPerformanceListenee(null); + spectator.sendSystemMessage("You stop listening to " + performer.getCustomName() + " because " + performer.getCustomName() + + " is out of range.", (byte) 0); + } + spectator.setMoodAnimation("neutral"); + performer.removeAudience(spectator); + + if (spectator.getInspirationTick().cancel(true)) + spectator.getSpectatorTask().cancel(true); } }, 2, 2, TimeUnit.SECONDS); @@ -581,13 +572,8 @@ public class EntertainmentService implements INetworkDispatch { performer.sendSystemMessage("@performance:flourish_perform", (byte) 0); performer.doSkillAnimation(anmFlo); - scheduler.schedule(new Runnable() { - - @Override - public void run() { - performer.setFlourishCount(0); - } - + scheduler.schedule(() -> { + performer.setFlourishCount(0); }, (long) performance.getLoopDuration(), TimeUnit.SECONDS); } @@ -629,13 +615,8 @@ public class EntertainmentService implements INetworkDispatch { else performer.playEffectObject(effect, ""); - scheduler.schedule(new Runnable() { - - @Override - public void run() { - performer.setPerformingEffect(false); - } - + scheduler.schedule(() -> { + performer.setPerformingEffect(false); }, (long) pEffect.getEffectDuration(), TimeUnit.SECONDS); return true; @@ -644,42 +625,39 @@ public class EntertainmentService implements INetworkDispatch { public void handleInspirationTicks(final CreatureObject spectator, final CreatureObject performer) { // http://youtu.be/WqyAde-oC7o?t=11m14s << Player watching entertainer (Has ring only, no pet, + 15 min ticks) // TODO: Camp/Cantina checks for expertise and duration bonus %. Right now only using basic values. - final ScheduledFuture inspirationTick = scheduler.scheduleAtFixedRate(new Runnable() { + final ScheduledFuture inspirationTick = scheduler.scheduleAtFixedRate(() -> { - @Override - public void run() { - int time = 0; // current buff duration time (minutes) - int buffCap = 215; // 5 hours 35 minutes - 2 hours (buff duration increase bonus) << Taken from video, doesn't account for performance bonuses etc. + int time = 0; // current buff duration time (minutes) + int buffCap = 215; // 5 hours 35 minutes - 2 hours (buff duration increase bonus) << Taken from video, doesn't account for performance bonuses etc. - if (spectator.getAttachment("inspireDuration") != null) - time+= (int) spectator.getAttachment("inspireDuration"); + if (spectator.getAttachment("inspireDuration") != null) + time+= (int) spectator.getAttachment("inspireDuration"); - if (performer.getSkillMod("expertise_en_inspire_buff_duration_increase") != null) { - SkillMod durationMod = performer.getSkillMod("expertise_en_inspire_buff_duration_increase"); - buffCap += durationMod.getBase() + durationMod.getModifier(); - } - - if (time >= buffCap) { - spectator.setAttachment("inspireDuration", buffCap); // incase someone went over cap - spectator.getInspirationTick().cancel(true); - } else { - int entTick = 10; - if (performer.getSkillMod("expertise_en_inspire_pulse_duration_increase") != null) { - SkillMod pulseMod = performer.getSkillMod("expertise_en_inspire_pulse_duration_increase"); - entTick += pulseMod.getBase() + pulseMod.getModifier(); - } - - int duration = (time + entTick); // minutes - int hMinutes = MathUtilities.secondsToHourMinutes(duration * 60); - int hours = MathUtilities.secondsToWholeHours(duration * 60); - - spectator.showFlyText("spam", "buff_duration_tick_observer", String.valueOf(hours) + " hours , " + hMinutes + " minutes ", 0, (float) 0.66, new RGB(255, 182, 193), 3, 78); - - spectator.setAttachment("inspireDuration", duration); - //System.out.println("Inspire Duration: " + spectator.getAttachment("inspireDuration") + " on " + spectator.getCustomName()); - } + if (performer.getSkillMod("expertise_en_inspire_buff_duration_increase") != null) { + SkillMod durationMod = performer.getSkillMod("expertise_en_inspire_buff_duration_increase"); + buffCap += durationMod.getBase() + durationMod.getModifier(); } + if (time >= buffCap) { + spectator.setAttachment("inspireDuration", buffCap); // incase someone went over cap + spectator.getInspirationTick().cancel(true); + } else { + int entTick = 10; + if (performer.getSkillMod("expertise_en_inspire_pulse_duration_increase") != null) { + SkillMod pulseMod = performer.getSkillMod("expertise_en_inspire_pulse_duration_increase"); + entTick += pulseMod.getBase() + pulseMod.getModifier(); + } + + int duration = (time + entTick); // minutes + int hMinutes = MathUtilities.secondsToHourMinutes(duration * 60); + int hours = MathUtilities.secondsToWholeHours(duration * 60); + + spectator.showFlyText("spam", "buff_duration_tick_observer", String.valueOf(hours) + " hours , " + hMinutes + " minutes ", 0, (float) 0.66, new RGB(255, 182, 193), 3, 78); + + spectator.setAttachment("inspireDuration", duration); + //System.out.println("Inspire Duration: " + spectator.getAttachment("inspireDuration") + " on " + spectator.getCustomName()); + } + }, 10, 10, TimeUnit.SECONDS); spectator.setInspirationTick(inspirationTick); } @@ -697,22 +675,18 @@ public class EntertainmentService implements INetworkDispatch { returnParams.add("btnOk:Text"); - notification.addHandler(0, "", Trigger.TRIGGER_OK, returnParams, new SUICallback(){ + notification.addHandler(0, "", Trigger.TRIGGER_OK, returnParams, (owner, eventType, returnList) -> { + if (eventType == 0) { + if (charge > actor.getCashCredits()) { + actor.sendSystemMessage("You do not have enough credits to cover the charge.", (byte) 0); // TODO: Find the message in the STF files. + return; + } else{ + actor.setCashCredits(actor.getCashCredits() - charge); + actor.sendSystemMessage("You payed the cover charge of " + charge + " to " + performer.getCustomName(), (byte) 0); // TODO: Find the message in the STF files. + performer.setCashCredits(performer.getCashCredits() + charge); - @Override - public void process(SWGObject owner, int eventType, Vector returnList) { - if (eventType == 0) { - if (charge > actor.getCashCredits()) { - actor.sendSystemMessage("You do not have enough credits to cover the charge.", (byte) 0); // TODO: Find the message in the STF files. - return; - } else{ - actor.setCashCredits(actor.getCashCredits() - charge); - actor.sendSystemMessage("You payed the cover charge of " + charge + " to " + performer.getCustomName(), (byte) 0); // TODO: Find the message in the STF files. - performer.setCashCredits(performer.getCashCredits() + charge); + startSpectating(actor, performer, performer.getPerformanceType()); - startSpectating(actor, performer, performer.getPerformanceType()); - - } } } }); diff --git a/src/services/InstanceService.java b/src/services/InstanceService.java index 199b9ac4..386cc3cf 100644 --- a/src/services/InstanceService.java +++ b/src/services/InstanceService.java @@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit; import resources.objects.building.BuildingObject; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; - +import services.object.ObjectService; import main.NGECore; import engine.clientdata.ClientFileManager; @@ -192,12 +192,8 @@ public class InstanceService implements INetworkDispatch { } public synchronized void close() { - for (SWGObject object : objectList) { - core.objectService.destroyObject(object); - } - + objectList.stream().forEach(core.objectService::destroyObject); objectList.clear(); - closed = true; } @@ -286,18 +282,12 @@ public class InstanceService implements INetworkDispatch { public void run() { if (instance.getDuration() > 300 && instance.getTimeRemaining() <= 300 && !sentCloseWarning) { - for (CreatureObject player : instance.getActiveParticipants()) { - player.sendSystemMessage("@instance:five_minute_warning", (byte) 0); - } - + instance.getActiveParticipants().stream().forEach(p -> p.sendSystemMessage("@instance:five_minute_warning", (byte) 0)); sentCloseWarning = true; } if (!instance.isOpen()) { - for (CreatureObject player : instance.getActiveParticipants()) { - player.sendSystemMessage("@instance:instance_time_out", (byte) 0); - } - + instance.getActiveParticipants().stream().forEach(p -> p.sendSystemMessage("@instance:instance_time_out", (byte) 0)); close(instance); } @@ -696,11 +686,7 @@ public class InstanceService implements INetworkDispatch { List lockoutList = new ArrayList(); for (List instanceList : instanceMap.values()) { - for (Instance instance : instanceList) { - if (instance.isFormerParticipant(creature)) { - lockoutList.add(instance); - } - } + instanceList.stream().filter(i -> i.isFormerParticipant(creature)).forEach(i -> lockoutList.add(i)); } return lockoutList; diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index a910486f..70447466 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -95,12 +95,14 @@ public class PlayerService implements INetworkDispatch { private NGECore core; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - + private float xpMultiplier; protected final Object objectMutex = new Object(); public PlayerService(final NGECore core) { this.core = core; - + this.xpMultiplier = (float) core.getConfig().getDouble("XPMULTIPLIER"); + if(xpMultiplier == 0) + xpMultiplier = 1; } public void postZoneIn(final CreatureObject creature) { @@ -483,7 +485,7 @@ public class PlayerService implements INetworkDispatch { public void giveExperience(CreatureObject creature, int experience) { DatatableVisitor experienceTable; PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); - + experience *= xpMultiplier; //synchronized(objectMutex) { try { experienceTable = ClientFileManager.loadFile("datatables/player/player_level.iff", DatatableVisitor.class); diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 296cdf40..4c8666b8 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -981,7 +981,7 @@ public class SimulationService implements INetworkDispatch { Point3D origin = new Point3D(position1.x, position1.y + 1, position1.z); Point3D end = new Point3D(position2.x, position2.y + 1, position2.z); - Vector3D direction = new Vector3D(end.x - origin.x, end.y - origin.y, end.z - origin.z).normalize(); + Vector3D direction = new Vector3D(end.x - origin.x, end.y - origin.y, end.z - origin.z); if (direction.getNorm() != 0) { direction.normalize(); diff --git a/src/services/SkillService.java b/src/services/SkillService.java index e1cff8a2..d1f14e4e 100644 --- a/src/services/SkillService.java +++ b/src/services/SkillService.java @@ -181,7 +181,7 @@ public class SkillService implements INetworkDispatch { public void removeSkill(CreatureObject creature, String skill) { PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); DatatableVisitor skillTable; - + if (player == null) { return; } diff --git a/src/services/TerrainService.java b/src/services/TerrainService.java index 81f92a2f..151cf9a6 100644 --- a/src/services/TerrainService.java +++ b/src/services/TerrainService.java @@ -191,28 +191,25 @@ public class TerrainService { for(final Planet planet : planets) { if(planet.getSnapshotVisitor() != null) { - Thread thread = new Thread(new Runnable() { + Thread thread = new Thread(() -> { - @Override - public void run() { - Config config = new Config(); - config.setFilePath("options.cfg"); - boolean loaded = config.loadConfigFile(); - - if (loaded && config.getInt("LOAD.SNAPSHOT_OBJECTS") > 0) { - try { - core.objectService.loadSnapshotObjects(planet); - } catch (Exception e) { - e.printStackTrace(); - } + Config config = new Config(); + config.setFilePath("options.cfg"); + boolean loaded = config.loadConfigFile(); + + if (loaded && config.getInt("LOAD.SNAPSHOT_OBJECTS") > 0) { + try { + core.objectService.loadSnapshotObjects(planet); + } catch (Exception e) { + e.printStackTrace(); } - - if (loaded && config.getInt("LOAD.BUILDOUT_OBJECTS") > 0) { - try { - core.objectService.loadBuildoutObjects(planet); - } catch (InstantiationException | IllegalAccessException e) { - e.printStackTrace(); - } + } + + if (loaded && config.getInt("LOAD.BUILDOUT_OBJECTS") > 0) { + try { + core.objectService.loadBuildoutObjects(planet); + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); } } diff --git a/src/services/WeatherService.java b/src/services/WeatherService.java index 79e22d3d..d007d307 100644 --- a/src/services/WeatherService.java +++ b/src/services/WeatherService.java @@ -64,14 +64,8 @@ public class WeatherService { weatherStability.put(planet, stability); currentWeatherMap.put(planet, defaultWeather); - scheduler.scheduleAtFixedRate(new Runnable() { - - @Override - public void run() { - runWeatherCycle(planet); - } - - + scheduler.scheduleAtFixedRate(() -> { + runWeatherCycle(planet); }, 30, 30, TimeUnit.MINUTES); } diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index 081911cd..1f2247c0 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -233,4 +233,16 @@ public class AIActor { } } + + public void scheduleDespawn() { + scheduler.schedule(() -> { + + damageMap.clear(); + followObject = null; + creature.setAttachment("AI", null); + NGECore.getInstance().objectService.destroyObject(creature); + + }, 30000, TimeUnit.MILLISECONDS); + } + } diff --git a/src/services/ai/AIService.java b/src/services/ai/AIService.java index 76e46d69..786ac66d 100644 --- a/src/services/ai/AIService.java +++ b/src/services/ai/AIService.java @@ -77,7 +77,7 @@ public class AIService { float damagePercent = damage / creature.getMaxHealth(); int finalXP = (int) (damagePercent * baseXP); finalXP -= ((levelDifference > 20) ? (finalXP - 1) : (((levelDifference * 5) / 100) * finalXP)); - + core.playerService.giveExperience(player, finalXP); } } @@ -101,6 +101,8 @@ public class AIService { } + + //TODO: this is slightly inaccurate if the xp table in the prima guide is correct if(difficulty == 1) { baseXP += (6 + ((creature.getLevel() - 1) / 10) * 3); } else if(difficulty == 2) { diff --git a/src/services/ai/states/AttackState.java b/src/services/ai/states/AttackState.java index 193699ad..96baf032 100644 --- a/src/services/ai/states/AttackState.java +++ b/src/services/ai/states/AttackState.java @@ -57,7 +57,7 @@ public class AttackState extends AIState { return StateResult.DEAD; actor.getMovementPoints().clear(); if(actor.getFollowObject() != null) { - if(/*actor.getSpawnPosition().getWorldPosition().getDistance(creature.getWorldPosition()) > 128 ||*/ NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), actor.getFollowObject().getWorldPosition())) { + if(actor.getSpawnPosition().getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), actor.getFollowObject().getWorldPosition())) { actor.removeDefender(actor.getFollowObject()); //actor.scheduleMovement(); return StateResult.UNFINISHED; @@ -110,7 +110,7 @@ public class AttackState extends AIState { actor.scheduleRecovery(); return StateResult.UNFINISHED; } - if(/*target.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 ||*/ target.getPosture() == 13 || target.getPosture() == 14) { + if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || target.getPosture() == 13 || target.getPosture() == 14) { actor.removeDefender(target); actor.scheduleRecovery(); return StateResult.UNFINISHED; diff --git a/src/services/ai/states/DeathState.java b/src/services/ai/states/DeathState.java index e0924f66..13abdec0 100644 --- a/src/services/ai/states/DeathState.java +++ b/src/services/ai/states/DeathState.java @@ -21,13 +21,15 @@ ******************************************************************************/ package services.ai.states; +import main.NGECore; import services.ai.AIActor; public class DeathState extends AIState { @Override public byte onEnter(AIActor actor) { - // TODO Auto-generated method stub + NGECore.getInstance().aiService.awardExperience(actor); + actor.scheduleDespawn(); return 0; } diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index ad94babe..a107e39a 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -795,24 +795,19 @@ public class CombatService implements INetworkDispatch { target.setTurnRadius(0); target.setSpeedMultiplierBase(0); } - ScheduledFuture incapTask = scheduler.schedule(new Runnable() { - - @Override - public void run() { - - synchronized(target.getMutex()) { - - if(target.getPosture() != 13) - return; - - target.setPosture((byte) 0); - target.setTurnRadius(1); - target.setSpeedMultiplierBase(1); - - } - - } + ScheduledFuture incapTask = scheduler.schedule(() -> { + synchronized(target.getMutex()) { + + if(target.getPosture() != 13) + return; + + target.setPosture((byte) 0); + target.setTurnRadius(1); + target.setSpeedMultiplierBase(1); + + } + }, target.getIncapTimer(), TimeUnit.SECONDS); target.setIncapTask(incapTask); core.buffService.addBuffToCreature(target, "incapWeaken"); @@ -824,6 +819,8 @@ public class CombatService implements INetworkDispatch { target.setHealth(0); target.setPosture((byte) 14); } + attacker.removeDefender(target); + target.removeDefender(attacker); return; } synchronized(target.getMutex()) { diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index a67b1398..158d056e 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -78,6 +78,8 @@ import engine.clientdata.visitors.WorldSnapshotVisitor.SnapshotChunk; import engine.clients.Client; import engine.resources.common.CRC; import engine.resources.container.Traverser; +import engine.resources.container.WorldCellPermissions; +import engine.resources.container.WorldPermissions; import engine.resources.database.DatabaseConnection; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; @@ -415,9 +417,15 @@ public class ObjectService implements INetworkDispatch { } }); objectList.remove(object.getObjectID()); - if(object.getContainer() != null) { + SWGObject parent = object.getContainer(); + + if(parent != null) { + if(parent instanceof CreatureObject) { + ((CreatureObject) parent).removeObjectFromEquipList(object); + ((CreatureObject) parent).removeObjectFromAppearanceEquipList(object); + } long parentId = object.getParentId(); - object.getContainer()._remove(object); + parent.remove(object); object.setParentId(parentId); } else { core.simulationService.remove(object, object.getWorldPosition().x, object.getWorldPosition().z, true); @@ -696,10 +704,12 @@ public class ObjectService implements INetworkDispatch { int objectId = chunk.id; SWGObject obj = createObject(visitor.getName(chunk.nameId), objectId, planet, new Point3D(chunk.xPosition, chunk.yPosition, chunk.zPosition), new Quaternion(chunk.orientationW, chunk.orientationX, chunk.orientationY, chunk.orientationZ)); if(obj != null) { + obj.setContainerPermissions(WorldPermissions.WORLD_PERMISSIONS); obj.setisInSnapshot(true); obj.setParentId(chunk.parentId); if(obj instanceof CellObject) { ((CellObject) obj).setCellNumber(chunk.cellNumber); + obj.setContainerPermissions(WorldCellPermissions.WORLD_CELL_PERMISSIONS); } } //System.out.print("\rLoading Object [" + counter + "/" + visitor.getChunks().size() + "] : " + visitor.getName(chunk.nameId)); @@ -744,7 +754,7 @@ public class ObjectService implements INetworkDispatch { } SWGObject child = createObject(template, 0, parent.getPlanet(), position, orientation); - + child.setContainerPermissions(WorldPermissions.WORLD_PERMISSIONS); if(parent.getAttachment("childObjects") == null) parent.setAttachment("childObjects", new Vector()); @@ -890,17 +900,21 @@ public class ObjectService implements INetworkDispatch { } if(object == null) continue; + object.setContainerPermissions(WorldPermissions.WORLD_PERMISSIONS); if(radius > 256) object.setAttachment("bigSpawnRange", new Boolean(true)); quadtreeObjects.add(object); } else if(containerId != 0) { - object = createObject(template, 0, planet, new Point3D(px, py, pz), new Quaternion(qw, qx, qy, qz)); + object = createObject(template, 0, planet, new Point3D(px, py, pz), new Quaternion(qw, qx, qy, qz)); if(containers.contains(containerId)) { + object.setContainerPermissions(WorldPermissions.WORLD_PERMISSIONS); object.setisInSnapshot(false); containers.add(objectId); } - if(object instanceof CellObject && cellIndex != 0) + if(object instanceof CellObject && cellIndex != 0) { + object.setContainerPermissions(WorldCellPermissions.WORLD_CELL_PERMISSIONS); ((CellObject) object).setCellNumber(cellIndex); + } SWGObject parent = getObject(containerId); if(parent != null && object != null) { @@ -910,6 +924,7 @@ public class ObjectService implements INetworkDispatch { } } else { object = createObject(template, 0, planet, new Point3D(px + x1, py, pz + z1), new Quaternion(qw, qx, qy, qz)); + object.setContainerPermissions(WorldPermissions.WORLD_PERMISSIONS); quadtreeObjects.add(object); } diff --git a/src/services/spawn/MobileTemplate.java b/src/services/spawn/MobileTemplate.java index 7c2da0ff..5853ddf4 100644 --- a/src/services/spawn/MobileTemplate.java +++ b/src/services/spawn/MobileTemplate.java @@ -39,6 +39,8 @@ public class MobileTemplate { private int maxDamage; private int difficulty = 0; private int health, action; + private String creatureName; + private float scale = 1; public Vector getTemplates() { return templates; @@ -128,4 +130,20 @@ public class MobileTemplate { this.defaultAttack = defaultAttack; } + public String getCreatureName() { + return creatureName; + } + + public void setCreatureName(String creatureName) { + this.creatureName = creatureName; + } + + public float getScale() { + return scale; + } + + public void setScale(float scale) { + this.scale = scale; + } + } diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java index 039338fa..9c41ea92 100644 --- a/src/services/spawn/SpawnService.java +++ b/src/services/spawn/SpawnService.java @@ -103,6 +103,9 @@ public class SpawnService { creature.setOptionsBitmask(mobileTemplate.getOptionBitmask()); creature.setPvPBitmask(mobileTemplate.getPvpBitmask()); + creature.setStfFilename("mob/creature_names"); // TODO: set other STFs for NPCs other than creatures + creature.setStfName(mobileTemplate.getCreatureName()); + creature.setHeight(mobileTemplate.getScale()); int difficulty = mobileTemplate.getDifficulty(); creature.setDifficulty((byte) difficulty); if(level != -1) @@ -171,6 +174,10 @@ public class SpawnService { return creature; } + public CreatureObject spawnCreature(String mobileTemplate, String planetName, long cellId, float x, float y, float z, float qW, float qX, float qY, float qZ, int level) { + return spawnCreature(mobileTemplate, planetName, cellId, x, y, z, 1, 0, 0, 0, (short) level); + } + public CreatureObject spawnCreature(String mobileTemplate, String planetName, long cellId, float x, float y, float z) { return spawnCreature(mobileTemplate, planetName, cellId, x, y, z, 1, 0, 0, 0, (short) -1); } diff --git a/src/services/sui/SUIService.java b/src/services/sui/SUIService.java index 8f496dc1..f74c20d0 100644 --- a/src/services/sui/SUIService.java +++ b/src/services/sui/SUIService.java @@ -257,19 +257,7 @@ public class SUIService implements INetworkDispatch { window.clearDataSource("List.dataList"); - //int index = 0; - - for(Entry e : cloneData.entrySet()) { - - /*window.addDataItem("List.dataList:Name", String.valueOf(index)); - - window.setProperty("List.dataList." + index + ":Text", string); - - ++index;*/ - - window.addListBoxMenuItem(e.getValue(), e.getKey()); - - } + cloneData.entrySet().forEach(e -> window.addListBoxMenuItem(e.getValue(), e.getKey())); return window; diff --git a/src/services/travel/TravelService.java b/src/services/travel/TravelService.java index c81be385..6cd5c7c1 100644 --- a/src/services/travel/TravelService.java +++ b/src/services/travel/TravelService.java @@ -233,9 +233,7 @@ public class TravelService implements INetworkDispatch { public void loadTravelPoints() { List planetList = core.terrainService.getPlanetList(); - for (Planet planet : planetList) { - addPlanet(planet); - } + planetList.forEach(this::addPlanet); populateTravelFares(); }