diff --git a/nge.cfg b/nge.cfg index 036d6202..6d4d88df 100644 --- a/nge.cfg +++ b/nge.cfg @@ -13,4 +13,5 @@ GALAXY_ID=2 GALAXY_NAME=Local Connection XPMULTIPLIER=1.0 MAXNUMBEROFCHARACTERS=2 +LOAD.RESOURCE.SYSTEM=1 MOTD=Welcome to PSWG Test Center! \ No newline at end of file diff --git a/scripts/commands/getplayerid.py b/scripts/commands/getplayerid.py index 9b334674..bb4141a4 100644 --- a/scripts/commands/getplayerid.py +++ b/scripts/commands/getplayerid.py @@ -4,22 +4,18 @@ def setup(): return def run(core, actor, target, commandString): - - if commandString.startswith("quart"): - print ('commnad: ' + commandString) - #cmdArgs = commandString.split(" ") - #qY = cmdArgs[1] - #qW = cmdArgs[2] - - quaternion = actor.getOrientation() - #tp = core.travelService.getTravelPointByName(actor.getPlanet().name, "Mos Eisley Starport") - #obj = tp.getShuttle() - target.setOrientation(quaternion) - print ('Orientation: qY- ' + str(quaternion.y) + ' --- qW- ' + str(quaternion.w)) - Console.println('Orientation: qY- ' + str(quaternion.y) + ' --- qW- ' + str(quaternion.w)) - return - - elif commandString.startswith("id"): - print ( str(target.getObjectId())) + commandArgs = commandString.split(" ") + target = core.chatService.getObjectByFirstName(commandArgs[0]) + + if len(commandArgs) > 1: + if commandArgs[1].startswith("id"): + actor.sendSystemMessage('Player Object ID: ' + target.getObjectId()) + return + + elif commandArgs[1].startswith("pid"): + actor.sendSystemMessage('Account ID: ' + str(core.characterService.getAccountId(target.getObjectId())), 0) + return + else: + actor.sendSystemMessage('Player Object ID: ' + str(target.getObjectId()) + ' Account ID: ' + str(core.characterService.getAccountId(target.getObjectId())), 0) return return \ No newline at end of file diff --git a/scripts/commands/holoemote.py b/scripts/commands/holoemote.py index 022e7746..36c15235 100644 --- a/scripts/commands/holoemote.py +++ b/scripts/commands/holoemote.py @@ -48,7 +48,7 @@ def run(core, actor, target, commandString): actor.playEffectObject(effectObj, 'head') player.setHoloEmoteUses(player.getHoloEmoteUses() - 1) - actor.addCooldown('holoEmote', long(30 * 1000)) + actor.addCooldown('holoEmote', float(30)) return @@ -73,4 +73,4 @@ def holoPrompt(player, emote): "Kitty\t\t Phonytail\tRebel\n" \ "Sparky" - return emotesToPlay + remainingCharges + body \ No newline at end of file + return emotesToPlay + remainingCharges + body diff --git a/scripts/expertise/expertise_fs_general_force_shockwave_1.py b/scripts/expertise/expertise_fs_general_force_shockwave_1.py index bd222493..a17dbe47 100644 --- a/scripts/expertise/expertise_fs_general_force_shockwave_1.py +++ b/scripts/expertise/expertise_fs_general_force_shockwave_1.py @@ -2,24 +2,21 @@ import sys def addAbilities(core, actor, player): if actor.getLevel() >= 26: - actor.addAbility("fs_ae_dm_cc_1") + actor.addAbility("fs_dm_cc_crit_1") if actor.getLevel() >= 34: - actor.addAbility("fs_ae_dm_cc_2") + actor.addAbility("fs_dm_cc_crit_2") if actor.getLevel() >= 48: - actor.addAbility("fs_ae_dm_cc_3") + actor.addAbility("fs_dm_cc_crit_3") if actor.getLevel() >= 62: - actor.addAbility("fs_ae_dm_cc_4") + actor.addAbility("fs_dm_cc_crit_4") if actor.getLevel() >= 76: - actor.addAbility("fs_ae_dm_cc_5") - if actor.getLevel() >= 90: - actor.addAbility("fs_ae_dm_cc_6") + actor.addAbility("fs_dm_cc_crit_5") return def removeAbilities(core, actor, player): - actor.removeAbility("fs_ae_dm_cc_1") - actor.removeAbility("fs_ae_dm_cc_2") - actor.removeAbility("fs_ae_dm_cc_3") - actor.removeAbility("fs_ae_dm_cc_4") - actor.removeAbility("fs_ae_dm_cc_5") - actor.removeAbility("fs_ae_dm_cc_6") + actor.removeAbility("fs_dm_cc_crit_1") + actor.removeAbility("fs_dm_cc_crit_2") + actor.removeAbility("fs_dm_cc_crit_3") + actor.removeAbility("fs_dm_cc_crit_4") + actor.removeAbility("fs_dm_cc_crit_5") return diff --git a/scripts/expertise/expertise_fs_path_dark_lightning_1.py b/scripts/expertise/expertise_fs_path_dark_lightning_1.py index 0e8503fd..bd222493 100644 --- a/scripts/expertise/expertise_fs_path_dark_lightning_1.py +++ b/scripts/expertise/expertise_fs_path_dark_lightning_1.py @@ -1,9 +1,25 @@ import sys def addAbilities(core, actor, player): - actor.addAbility("fs_ae_dm_cc_1") + if actor.getLevel() >= 26: + actor.addAbility("fs_ae_dm_cc_1") + if actor.getLevel() >= 34: + actor.addAbility("fs_ae_dm_cc_2") + if actor.getLevel() >= 48: + actor.addAbility("fs_ae_dm_cc_3") + if actor.getLevel() >= 62: + actor.addAbility("fs_ae_dm_cc_4") + if actor.getLevel() >= 76: + actor.addAbility("fs_ae_dm_cc_5") + if actor.getLevel() >= 90: + actor.addAbility("fs_ae_dm_cc_6") return def removeAbilities(core, actor, player): actor.removeAbility("fs_ae_dm_cc_1") + actor.removeAbility("fs_ae_dm_cc_2") + actor.removeAbility("fs_ae_dm_cc_3") + actor.removeAbility("fs_ae_dm_cc_4") + actor.removeAbility("fs_ae_dm_cc_5") + actor.removeAbility("fs_ae_dm_cc_6") return diff --git a/scripts/expertise/expertise_fs_path_force_choke_1.py b/scripts/expertise/expertise_fs_path_force_choke_1.py index 7ceb9e53..ad9a5d82 100644 --- a/scripts/expertise/expertise_fs_path_force_choke_1.py +++ b/scripts/expertise/expertise_fs_path_force_choke_1.py @@ -1,9 +1,25 @@ import sys def addAbilities(core, actor, player): - actor.addAbility("fs_dm_cc_1") + if actor.getLevel() >= 26: + actor.addAbility("fs_dm_cc_1") + if actor.getLevel() >= 34: + actor.addAbility("fs_dm_cc_2") + if actor.getLevel() >= 48: + actor.addAbility("fs_dm_cc_3") + if actor.getLevel() >= 62: + actor.addAbility("fs_dm_cc_4") + if actor.getLevel() >= 76: + actor.addAbility("fs_dm_cc_5") + if actor.getLevel() >= 90: + actor.addAbility("fs_dm_cc_6") return def removeAbilities(core, actor, player): actor.removeAbility("fs_dm_cc_1") + actor.removeAbility("fs_dm_cc_2") + actor.removeAbility("fs_dm_cc_3") + actor.removeAbility("fs_dm_cc_4") + actor.removeAbility("fs_dm_cc_5") + actor.removeAbility("fs_dm_cc_6") return diff --git a/scripts/expertise/expertise_fs_path_force_drain_1.py b/scripts/expertise/expertise_fs_path_force_drain_1.py index 1ec21f58..6d310e3a 100644 --- a/scripts/expertise/expertise_fs_path_force_drain_1.py +++ b/scripts/expertise/expertise_fs_path_force_drain_1.py @@ -1,9 +1,22 @@ import sys def addAbilities(core, actor, player): - actor.addAbility("fs_drain_1") + if actor.getLevel() >= 26: + actor.addAbility("fs_drain_1") + if actor.getLevel() >= 34: + actor.addAbility("fs_drain_2") + if actor.getLevel() >= 48: + actor.addAbility("fs_drain_3") + if actor.getLevel() >= 62: + actor.addAbility("fs_drain_4") + if actor.getLevel() >= 76: + actor.addAbility("fs_drain_5") return def removeAbilities(core, actor, player): actor.removeAbility("fs_drain_1") + actor.removeAbility("fs_drain_2") + actor.removeAbility("fs_drain_3") + actor.removeAbility("fs_drain_4") + actor.removeAbility("fs_drain_5") return diff --git a/scripts/expertise/expertise_fs_path_maelstrom_1.py b/scripts/expertise/expertise_fs_path_maelstrom_1.py index 3fbdb051..84a05ef5 100644 --- a/scripts/expertise/expertise_fs_path_maelstrom_1.py +++ b/scripts/expertise/expertise_fs_path_maelstrom_1.py @@ -1,9 +1,22 @@ import sys def addAbilities(core, actor, player): - actor.addAbility("fs_maelstrom_1") + if actor.getLevel() >= 26: + actor.addAbility("fs_maelstrom_1") + if actor.getLevel() >= 34: + actor.addAbility("fs_maelstrom_2") + if actor.getLevel() >= 48: + actor.addAbility("fs_maelstrom_3") + if actor.getLevel() >= 62: + actor.addAbility("fs_maelstrom_4") + if actor.getLevel() >= 76: + actor.addAbility("fs_maelstrom_5") return def removeAbilities(core, actor, player): actor.removeAbility("fs_maelstrom_1") + actor.removeAbility("fs_maelstrom_2") + actor.removeAbility("fs_maelstrom_3") + actor.removeAbility("fs_maelstrom_4") + actor.removeAbility("fs_maelstrom_5") return diff --git a/scripts/expertise/expertise_fs_path_saber_reflect_1.py b/scripts/expertise/expertise_fs_path_saber_reflect_1.py index ff019b2d..8a78f62b 100644 --- a/scripts/expertise/expertise_fs_path_saber_reflect_1.py +++ b/scripts/expertise/expertise_fs_path_saber_reflect_1.py @@ -1,9 +1,9 @@ import sys def addAbilities(core, actor, player): - actor.addAbility("fs_saber_reflect_buff") + actor.addAbility("fs_saber_reflect") return def removeAbilities(core, actor, player): - actor.removeAbility("fs_saber_reflect_buff") + actor.removeAbility("fs_saber_reflect") return diff --git a/scripts/expertise/expertise_me_enhancement_specialist_1.py b/scripts/expertise/expertise_me_enhancement_specialist_1.py index 4c9429e5..ebf28d79 100644 --- a/scripts/expertise/expertise_me_enhancement_specialist_1.py +++ b/scripts/expertise/expertise_me_enhancement_specialist_1.py @@ -7,10 +7,18 @@ def addAbilities(core, actor, player): actor.addAbility("me_enhance_action_2") if actor.getLevel() >= 62: actor.addAbility("me_enhance_action_3") + + if actor.getLevel() >= 48: + actor.addAbility("me_buff_health_2") + if actor.getLevel() >= 76: + actor.addAbility("me_buff_health_3") return def removeAbilities(core, actor, player): actor.removeAbility("me_enhance_action_1") actor.removeAbility("me_enhance_action_2") actor.removeAbility("me_enhance_action_3") + + actor.removeAbility("me_buff_health_2") + actor.removeAbility("me_buff_health_3") return diff --git a/scripts/object/tangible/wearables/robe/robe_jedi_dark_s03.py b/scripts/object/tangible/wearables/robe/robe_jedi_dark_s03.py index ba216204..101fa13f 100644 --- a/scripts/object/tangible/wearables/robe/robe_jedi_dark_s03.py +++ b/scripts/object/tangible/wearables/robe/robe_jedi_dark_s03.py @@ -5,12 +5,17 @@ def setup(core, object): object.setStfName('item_jedi_robe_dark_03_03') object.setDetailFilename('static_item_d') object.setDetailName('item_jedi_robe_dark_03_03') - object.setIntAttribute('cat_stat_mod_bonus.@stat_n:constitution_modified', 185) - object.setIntAttribute('cat_stat_mod_bonus.@stat_n:precision_modified', 185) - object.setIntAttribute('cat_stat_mod_bonus.@stat_n:luck_modified', 185) + object.setStringAttribute('protection_level', 'Luminous') object.setStringAttribute('class_required', 'Jedi') object.setIntAttribute('required_combat_level', 80) - object.setAttachment('type', 'jedi_robe') + + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:constitution_modified', 185) + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:precision_modified', 185) + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:luck_modified', 185) + object.setStringAttribute('@set_bonus:piece_bonus_count_2', '@set_bonus:set_bonus_jedi_robe_1') + + object.setAttachment('type', 'jedi_robe') + object.setAttachment('setBonus', 'set_bonus_jedi_robe') return diff --git a/scripts/object/tangible/wearables/robe/robe_jedi_dark_s04.py b/scripts/object/tangible/wearables/robe/robe_jedi_dark_s04.py index 8c145ab4..5b1543e3 100644 --- a/scripts/object/tangible/wearables/robe/robe_jedi_dark_s04.py +++ b/scripts/object/tangible/wearables/robe/robe_jedi_dark_s04.py @@ -1,31 +1,22 @@ import sys def setup(core, object): - return + object.setStfFilename('static_item_n') + object.setStfName('item_jedi_robe_dark_04_04') + object.setDetailFilename('static_item_d') + object.setDetailName('item_jedi_robe_dark_04_04') -def equip(core, actor, target): - core.skillModService.addSkillMod(actor, 'constitution_modified', 250) - core.skillModService.addSkillMod(actor, 'precision_modified', 250) - core.skillModService.addSkillMod(actor, 'luck_modified', 250) + object.setStringAttribute('protection_level', 'Radiant') + object.setStringAttribute('class_required', 'Jedi') + object.setIntAttribute('required_combat_level', 80) - Buff = actor.getBuffByName('proc_old_dark_jedi_gift') - if actor.getBuffList().contains(Buff): - core.buffService.removeBuffFromCreature(actor, Buff) - return - - if actor: - core.buffService.addBuffToCreature(actor, 'proc_old_dark_jedi_gift') - return - return + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:constitution_modified', 250) + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:precision_modified', 250) + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:luck_modified', 250) -def unequip(core, actor, target): - core.skillModService.deductSkillMod(actor, 'constitution_modified', 250) - core.skillModService.deductSkillMod(actor, 'precision_modified', 250) - core.skillModService.deductSkillMod(actor, 'luck_modified', 250) + object.setStringAttribute('proc_name', '@ui_buff:proc_old_dark_jedi_gift') + object.setStringAttribute('@set_bonus:piece_bonus_count_2', '@set_bonus:set_bonus_jedi_robe_1') - Buff = actor.getBuffByName('proc_old_dark_jedi_gift') - if actor.getBuffList().contains(Buff): - core.buffService.removeBuffFromCreature(actor, Buff) - return - return - \ No newline at end of file + object.setAttachment('type', 'jedi_robe') + object.setAttachment('setBonus', 'set_bonus_jedi_robe') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/robe/robe_jedi_light_s04.py b/scripts/object/tangible/wearables/robe/robe_jedi_light_s04.py index cbbd49cd..c540ba74 100644 --- a/scripts/object/tangible/wearables/robe/robe_jedi_light_s04.py +++ b/scripts/object/tangible/wearables/robe/robe_jedi_light_s04.py @@ -8,7 +8,7 @@ def setup(core, object): object.setStringAttribute('protection_level', 'Radiant') object.setStringAttribute('class_required', 'Jedi') - object.setIntAttribute('required_combat_level', 90) + object.setIntAttribute('required_combat_level', 80) object.setIntAttribute('cat_stat_mod_bonus.@stat_n:constitution_modified', 250) object.setIntAttribute('cat_stat_mod_bonus.@stat_n:strength_modified', 250) diff --git a/src/main/NGECore.java b/src/main/NGECore.java index af8330a3..0762507f 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -301,8 +301,11 @@ public class NGECore { spawnService = new SpawnService(this); aiService = new AIService(this); //missionService = new MissionService(this); - surveyService = new SurveyService(this); - resourceService = new ResourceService(this); + + if (config.getInt("LOAD.RESOURCE.SYSTEM") == 1) { + surveyService = new SurveyService(this); + resourceService = new ResourceService(this); + } // Ping Server try { @@ -403,8 +406,10 @@ public class NGECore { objectService.loadBuildings(); - objectService.loadResourceRoots(); - objectService.loadResources(); + if (config.getInt("LOAD.RESOURCE.SYSTEM") == 1) { + objectService.loadResourceRoots(); + objectService.loadResources(); + } terrainService.loadSnapShotObjects(); objectService.loadServerTemplates(); diff --git a/src/resources/objects/Buff.java b/src/resources/objects/Buff.java index 9a1c70ee..f8fc8dff 100644 --- a/src/resources/objects/Buff.java +++ b/src/resources/objects/Buff.java @@ -71,7 +71,36 @@ public class Buff implements IDelta { private long groupBufferId; private int buffCRC; - public Buff(String buffName, long ownerId) { + public Buff(Buff baseBuff, long ownerId) { + this.buffName = baseBuff.getBuffName(); + this.buffCRC = baseBuff.getBuffCRC(); + this.group1 = baseBuff.getGroup1(); + this.group2 = baseBuff.getGroup2(); + this.priority = baseBuff.getPriority(); + this.duration = baseBuff.getDuration(); + this.effect1Name = baseBuff.getEffect1Name(); + this.effect1Value = baseBuff.getEffect1Value(); + this.effect2Name = baseBuff.getEffect2Name(); + this.effect2Value = baseBuff.getEffect2Value(); + this.effect3Name = baseBuff.getEffect3Name(); + this.effect3Value = baseBuff.getEffect3Value(); + this.effect4Name = baseBuff.getEffect4Name(); + this.effect4Value = baseBuff.getEffect4Value(); + this.effect5Name = baseBuff.getEffect5Name(); + this.effect5Value = baseBuff.getEffect5Value(); + this.callback = baseBuff.getCallback(); + this.particleEffect = baseBuff.getParticleEffect(); + this.isDebuff = baseBuff.isDebuff(); + this.removeOnDeath = baseBuff.isRemoveOnDeath(); + this.isRemovableByPlayer = baseBuff.isRemovableByPlayer(); + this.maxStacks = baseBuff.getMaxStacks(); + this.isPersistent = baseBuff.isPersistent(); + this.removeOnRespec = baseBuff.isRemoveOnRespec(); + this.aiRemoveOnEndCombat = baseBuff.isAiRemoveOnEndCombat(); + this.decayOnPvPDeath = baseBuff.isDecayOnPvPDeath(); + } + + /*public Buff(String buffName, long ownerId) { this.buffName = buffName; this.ownerId = ownerId; @@ -119,12 +148,8 @@ public class Buff implements IDelta { } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } - - + }*/ - - } - public Buff() { } @Override @@ -159,7 +184,7 @@ public class Buff implements IDelta { this.group1 = group1; } - public float getPriority() { + public int getPriority() { return priority; } @@ -454,5 +479,9 @@ public class Buff implements IDelta { public int getBuffCRC() { return buffCRC; } + + public void setBuffCRC(int buffCRC) { + this.buffCRC = buffCRC; + } } diff --git a/src/resources/objects/SWGMap.java b/src/resources/objects/SWGMap.java index 48638350..b8f9610d 100644 --- a/src/resources/objects/SWGMap.java +++ b/src/resources/objects/SWGMap.java @@ -127,9 +127,7 @@ public class SWGMap implements Map { } else { V oldValue = map.put(key, value); - if (oldValue != null) { - queue(item(0, (String) key, ((IDelta) value).getBytes(), true, true)); - } + queue(item(0, (String) key, ((IDelta) value).getBytes(), true, true)); return oldValue; } diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index c76f6309..2043b928 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -1728,43 +1728,42 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } - public void addCooldown(String ability, long duration) { - if (cooldowns.containsKey(ability)) - cooldowns.remove(ability); + public void addCooldown(String cooldownGroup, float cooldownTime) { + if (cooldowns.containsKey(cooldownGroup)) { + cooldowns.remove(cooldownGroup); + } - Cooldown cd = new Cooldown(duration); - cd.setRemovalTask(Executors.newScheduledThreadPool(1).schedule(new Runnable() { - + long duration = ((long) (cooldownTime * 1000F)); + + Cooldown cooldown = new Cooldown(duration); + + cooldown.setRemovalTask(Executors.newScheduledThreadPool(1).schedule(new Runnable() { + @Override public void run() { - removeCooldown(ability); + removeCooldown(cooldownGroup); } }, duration, TimeUnit.MILLISECONDS)); - cooldowns.put(ability, cd); + + cooldowns.put(cooldownGroup, cooldown); } - public boolean hasCooldown(String ability) { - if (cooldowns.containsKey(ability)) + public boolean hasCooldown(String cooldownGroup) { + return cooldowns.containsKey(cooldownGroup); + } + + public boolean removeCooldown(String cooldownGroup) { + if (cooldowns.containsKey(cooldownGroup)) { + cooldowns.remove(cooldownGroup); return true; - else - return false; + } + + return false; } - public boolean removeCooldown(String ability) { - if (cooldowns.containsKey(ability)) { - cooldowns.remove(ability); - return true; - } else { - return false; - } + public Cooldown getCooldown(String cooldownGroup) { + return cooldowns.get(cooldownGroup); } - public Cooldown getCooldown(String ability) { - if (cooldowns.containsKey(ability)) { - return cooldowns.get(ability); - } else { - return null; - } - } } diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index ef0b97b3..9448144d 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -45,7 +45,7 @@ import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; -@Persistent(version=8) +@Persistent(version=9) public class PlayerObject extends IntangibleObject { // PLAY 3 diff --git a/src/services/BuffService.java b/src/services/BuffService.java index ff0c51af..97032e4e 100644 --- a/src/services/BuffService.java +++ b/src/services/BuffService.java @@ -22,6 +22,7 @@ package services; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -37,6 +38,9 @@ import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; import resources.objects.player.PlayerObject; import main.NGECore; +import engine.clientdata.ClientFileManager; +import engine.clientdata.visitors.DatatableVisitor; +import engine.resources.common.CRC; import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; @@ -45,10 +49,13 @@ public class BuffService implements INetworkDispatch { private NGECore core; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - + private ConcurrentHashMap buffMap = new ConcurrentHashMap(); + public BuffService(NGECore core) { this.core = core; core.commandService.registerCommand("removeBuff"); + + loadBuffs(); } @Override @@ -80,7 +87,7 @@ public class BuffService implements INetworkDispatch { return; }*/ - final Buff buff = new Buff(buffName, buffer.getObjectID()); + Buff buff = buffMap.get(buffName); if(buff.isGroupBuff()) { addGroupBuff(buffer, buffName, buffer); return true; @@ -100,7 +107,7 @@ public class BuffService implements INetworkDispatch { return null; } - final Buff buff = new Buff(buffName, target.getObjectID()); + final Buff buff = new Buff(buffMap.get(buffName), target.getObjectID()); if(target.getSlottedObject("ghost") != null) buff.setTotalPlayTime(((PlayerObject) target.getSlottedObject("ghost")).getTotalPlayTime()); else @@ -311,4 +318,47 @@ public class BuffService implements INetworkDispatch { } } + + private void loadBuffs() { + try { + DatatableVisitor visitor = ClientFileManager.loadFile("datatables/buff/buff.iff", DatatableVisitor.class); + for(int i = 0; i < visitor.getRowCount(); i++) { + Buff buff = new Buff(); + + String name = (String) visitor.getObject(i, 0); + + buff.setBuffName(name); + buff.setBuffCRC(CRC.StringtoCRC(name)); + buff.setGroup1((String) visitor.getObject(i, 1)); + buff.setGroup2((String) visitor.getObject(i, 2)); + buff.setPriority((int) visitor.getObject(i, 4)); + buff.setDuration((Float) visitor.getObject(i, 6)); + buff.setEffect1Name((String) visitor.getObject(i, 7)); + buff.setEffect1Value((Float) visitor.getObject(i, 8)); + buff.setEffect2Name((String) visitor.getObject(i, 9)); + buff.setEffect2Value((Float) visitor.getObject(i, 10)); + buff.setEffect3Name((String) visitor.getObject(i, 11)); + buff.setEffect3Value((Float) visitor.getObject(i, 12)); + buff.setEffect4Name((String) visitor.getObject(i, 13)); + buff.setEffect4Value((Float) visitor.getObject(i, 14)); + buff.setEffect5Name((String) visitor.getObject(i, 15)); + buff.setEffect5Value((Float) visitor.getObject(i, 16)); + buff.setCallback((String) visitor.getObject(i, 18)); + buff.setParticleEffect((String) visitor.getObject(i, 19)); + buff.setDebuff((Boolean) visitor.getObject(i, 22)); + buff.setRemoveOnDeath((Integer) visitor.getObject(i, 25) != 0); + buff.setRemovableByPlayer((Integer) visitor.getObject(i, 26) != 0); + buff.setMaxStacks((Integer) visitor.getObject(i, 28)); + buff.setPersistent((Integer) visitor.getObject(i, 29) != 0); + buff.setRemoveOnRespec((Integer) visitor.getObject(i, 31) != 0); + buff.setAiRemoveOnEndCombat((Integer) visitor.getObject(i, 32) != 0); + buff.setDecayOnPvPDeath((Integer) visitor.getObject(i, 33) != 0); + + buffMap.put(name, buff); + } + + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + } } diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index b0900a76..ec394752 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -564,7 +564,25 @@ public class CharacterService implements INetworkDispatch { return false; } - + /** + * Checks the database for the Account ID associated with the Object ID. + * Intended for GM use only! + * @param objectId Object ID of the player, used to obtain the Account ID. + * @return Returns Account ID + */ + public int getAccountId(long objectId) { + try { + PreparedStatement ps = databaseConnection.preparedStatement("SELECT * FROM characters WHERE id=?"); + ps.setLong(1, objectId); + ResultSet resultSet = ps.executeQuery(); + resultSet.next(); + return resultSet.getInt("accountId"); + } catch (SQLException e) { + e.printStackTrace(); + } + return 0; + } + private void createStarterClothing(CreatureObject creature, String raceTemplate, String profession) { try { ProfessionTemplateVisitor visitor = ClientFileManager.loadFile("creation/profession_defaults_" + profession + ".iff", ProfessionTemplateVisitor.class); diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index 1ca12d05..fd2d475a 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import main.NGECore; @@ -264,7 +265,12 @@ public class ConnectionService implements INetworkDispatch { object.setPerformanceListenee(null); object.setPerformanceWatchee(null); object.setAttachment("disconnectTask", null); - + + List> schedulers = core.playerService.getSchedulers().get(object.getObjectID()); + schedulers.forEach(s -> s.cancel(true)); + schedulers.clear(); + core.playerService.getSchedulers().remove(object.getObjectID()); + object.createTransaction(core.getCreatureODB().getEnvironment()); core.getCreatureODB().put(object, Long.class, CreatureObject.class, object.getTransaction()); object.getTransaction().commitSync(); diff --git a/src/services/DevService.java b/src/services/DevService.java index 16754e29..0cde2b83 100644 --- a/src/services/DevService.java +++ b/src/services/DevService.java @@ -249,6 +249,7 @@ public class DevService implements INetworkDispatch { inventory.add(pistol); + /* == Disabled until Elemental Damage is implemented. == SWGObject heavy = core.objectService.createObject("object/weapon/ranged/heavy/shared_som_lava_cannon_generic.iff", planet); heavy.setIntAttribute("required_combat_level", 90); heavy.setFloatAttribute("cat_wpn_damage.wpn_attack_speed", 1); @@ -256,7 +257,7 @@ public class DevService implements INetworkDispatch { heavy.setStringAttribute("cat_wpn_damage.wpn_damage_type", "Energy"); heavy.setStringAttribute("cat_wpn_damage.damage", "700-1400"); - inventory.add(heavy); + inventory.add(heavy);*/ return; case 40: TangibleObject ring = (TangibleObject) core.objectService.createObject("object/tangible/wearables/ring/shared_ring_s01.iff", planet); diff --git a/src/services/EquipmentService.java b/src/services/EquipmentService.java index de9c7bb4..d19d838f 100644 --- a/src/services/EquipmentService.java +++ b/src/services/EquipmentService.java @@ -29,6 +29,7 @@ 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.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; @@ -152,9 +153,7 @@ public class EquipmentService implements INetworkDispatch { // TODO: crit enhancement from crafted weapons // TODO: check for armor category in order to add resistance to certain DoT types - Map attributes = new TreeMap(item.getAttributes()); - - calculateArmorProtection(creature, equipping); + Map attributes = new TreeMap(item.getAttributes()); if(equipping) { @@ -211,6 +210,8 @@ public class EquipmentService implements INetworkDispatch { } } + calculateArmorProtection(creature, equipping); + if(item.getAttachment("setBonus") != null) { BonusSetTemplate bonus = bonusSetTemplates.get((String)item.getAttachment("setBonus")); @@ -223,15 +224,19 @@ public class EquipmentService implements INetworkDispatch { int wornArmourPieces = 0, forceProtection = 0; Map protection = new TreeMap(); - for(SWGObject item : creature.getEquipmentList()) + for(SWGObject item : new ArrayList(creature.getEquipmentList())) { Map attributes = new TreeMap(item.getAttributes()); boolean incPieceCount = false; + if(item.getStringAttribute("protection_level") != null) + { + forceProtection = getForceProtection(item); + break; + } + for(Entry e : attributes.entrySet()) - { - if(item.getStringAttribute("protection_level") != null) forceProtection = getForceProtection(item); - + { if(e.getKey().startsWith("cat_armor_standard_protection")) { String protectionType = e.getKey().replace("cat_armor_standard_protection.armor_eff_", ""); @@ -251,11 +256,21 @@ public class EquipmentService implements INetworkDispatch { if(protection.containsKey(protectionType)) protection.replace(protectionType, protection.get(protectionType) + protectionAmount); else protection.put(protectionType, protectionAmount); incPieceCount = true; - } + } } if(incPieceCount) wornArmourPieces++; } + if(protection.size() == 0) + { + protection.put("kinetic", (float) 0); + protection.put("energy", (float) 0); + protection.put("heat", (float) 0); + protection.put("cold", (float) 0); + protection.put("acid", (float) 0); + protection.put("electricity", (float) 0); + } + for(Entry e : protection.entrySet()) { core.skillModService.deductSkillMod(creature, e.getKey(), creature.getSkillModBase(e.getKey())); diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index f355b367..a1dc9eb3 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -32,6 +32,7 @@ import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.concurrent.atomic.AtomicBoolean; @@ -100,6 +101,7 @@ public class PlayerService implements INetworkDispatch { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private float xpMultiplier; protected final Object objectMutex = new Object(); + private ConcurrentHashMap>> schedulers = new ConcurrentHashMap>>(); public PlayerService(final NGECore core) { this.core = core; @@ -110,33 +112,36 @@ public class PlayerService implements INetworkDispatch { public void postZoneIn(final CreatureObject creature) { - scheduler.scheduleAtFixedRate(() -> { + if(schedulers.get(creature.getObjectID()) != null) + return; + List> scheduleList = new ArrayList>(); + scheduleList.add(scheduler.scheduleAtFixedRate(() -> { ServerTimeMessage time = new ServerTimeMessage(core.getGalacticTime() / 1000); IoBuffer packet = time.serialize(); creature.getClient().getSession().write(packet); - }, 45, 45, TimeUnit.SECONDS); + }, 45, 45, TimeUnit.SECONDS)); - scheduler.scheduleAtFixedRate(() -> { + scheduleList.add(scheduler.scheduleAtFixedRate(() -> { PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); player.setTotalPlayTime((int) (player.getTotalPlayTime() + ((System.currentTimeMillis() - player.getLastPlayTimeUpdate()) / 1000))); player.setLastPlayTimeUpdate(System.currentTimeMillis()); core.collectionService.checkExplorationRegions(creature); - }, 30, 30, TimeUnit.SECONDS); + }, 30, 30, TimeUnit.SECONDS)); - scheduler.scheduleAtFixedRate(() -> { + scheduleList.add(scheduler.scheduleAtFixedRate(() -> { if(creature.getAction() < creature.getMaxAction() && creature.getPosture() != 14) { if(creature.getCombatFlag() == 0) creature.setAction(creature.getAction() + (15 + creature.getLevel() * 5)); else creature.setAction(creature.getAction() + ((15 + creature.getLevel() * 5) / 2)); } - }, 0, 1000, TimeUnit.MILLISECONDS); + }, 0, 1000, TimeUnit.MILLISECONDS)); - scheduler.scheduleAtFixedRate(() -> { + scheduleList.add(scheduler.scheduleAtFixedRate(() -> { if(creature.getHealth() < creature.getMaxHealth() && creature.getCombatFlag() == 0 && creature.getPosture() != 13 && creature.getPosture() != 14) creature.setHealth(creature.getHealth() + (36 + creature.getLevel() * 4)); - }, 0, 1000, TimeUnit.MILLISECONDS); - + }, 0, 1000, TimeUnit.MILLISECONDS)); + schedulers.put(creature.getObjectID(), scheduleList); /*final PlayerObject ghost = (PlayerObject) creature.getSlottedObject("ghost"); scheduler.schedule(new Runnable() { @@ -204,25 +209,29 @@ public class PlayerService implements INetworkDispatch { }); objControllerOpcodes.put(ObjControllerOpcodes.ChangeRoleIconChoice, (session, data) -> { - - Client c = core.getClient(session); - ChangeRoleIconChoice packet = new ChangeRoleIconChoice(); - PlayerObject player; - SWGObject o; - - packet.deserialize(data); - o = core.objectService.getObject(packet.getObjectId()); - - if (c.getParent() == null || o == null || c.getParent() != o - || !(o instanceof CreatureObject) || !(o.getSlottedObject("ghost") - instanceof PlayerObject)) { + + Client client = core.getClient(session); + + if (client == null) return; - } - - player = (PlayerObject) o.getSlottedObject("ghost"); - + + SWGObject object = client.getParent(); + + if (object == null) + return; + + PlayerObject player = (PlayerObject) object.getSlottedObject("ghost"); + + if (player == null) + return; + + data.order(ByteOrder.LITTLE_ENDIAN); + + ChangeRoleIconChoice packet = new ChangeRoleIconChoice(); + packet.deserialize(data); + player.setProfessionIcon(packet.getIcon()); - + }); swgOpcodes.put(Opcodes.SetWaypointColor, (session, data) -> { @@ -718,14 +727,20 @@ public class PlayerService implements INetworkDispatch { String[] wookieeItems = ((String) roadmap.getObject(s, 5)).split(","); String[] ithorianItems = ((String) roadmap.getObject(s, 6)).split(","); - for (int n = 0; n < items.length; n++) { + int arrayLength = items.length; + + if (wookieeItems.length > 0 && creature.getStfName().contains("wookiee")) + arrayLength = wookieeItems.length; + else if (ithorianItems.length > 0 && creature.getStfName().contains("ithorian")) + arrayLength = ithorianItems.length; + + for (int n = 0; n < arrayLength; n++) { String item = items[n]; - if (wookieeItems[0].length() > 0 && creature.getStfName().contains("wookiee")) { + if (creature.getStfName().contains("wookiee")) item = wookieeItems[n]; - } else if (ithorianItems[0].length() > 0 && creature.getStfName().contains("ithorian")) { + else if (creature.getStfName().contains("ithorian")) item = ithorianItems[n]; - } try { String customServerTemplate = null; @@ -1253,4 +1268,8 @@ public class PlayerService implements INetworkDispatch { } + public Map>> getSchedulers() { + return schedulers; + } + } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 5f38d4b7..051f1690 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -168,6 +168,7 @@ public class SimulationService implements INetworkDispatch { core.commandService.registerCommand("eject"); core.commandService.registerGmCommand("broadcast"); core.commandService.registerGmCommand("teleporttarget"); + core.commandService.registerGmCommand("getplayerid"); core.commandService.registerCommand("npcconversationselect"); core.commandService.registerCommand("npcconversationstop"); diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index fcaf3e7d..f3f406b7 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -237,7 +237,6 @@ public class AIActor { case StateResult.DEAD: setCurrentState(new DeathState()); case StateResult.FINISHED: - // TODO: add state transitions case StateResult.UNFINISHED: return; case StateResult.IDLE: diff --git a/src/services/ai/states/AIState.java b/src/services/ai/states/AIState.java index e36a8c3a..41eb253b 100644 --- a/src/services/ai/states/AIState.java +++ b/src/services/ai/states/AIState.java @@ -123,8 +123,8 @@ public abstract class AIState { dx = currentPathPosition.x - oldPosition.x; dz = currentPathPosition.z - oldPosition.z; float deltaDist = (float) Math.sqrt((dx * dx) + (dz * dz)); - newX = (float) (oldPosition.x + (travelDistance * (dx / deltaDist))); - newZ = (float) (oldPosition.z + (travelDistance * (dz / deltaDist))); + newX = (float) (oldPosition.x + (speed * (dx / deltaDist))); + newZ = (float) (oldPosition.z + (speed * (dz / deltaDist))); } else { newX = currentPathPosition.x; @@ -200,7 +200,7 @@ public abstract class AIState { quaternion.w *= -1; } - core.simulationService.moveObject(creature, newPosition, quaternion, creature.getMovementCounter(), 0, newPosition.getCell()); + core.simulationService.moveObject(creature, newPosition, quaternion, creature.getMovementCounter(), speed, newPosition.getCell()); } diff --git a/src/services/ai/states/AttackState.java b/src/services/ai/states/AttackState.java index ab2323f6..dbc0a54d 100644 --- a/src/services/ai/states/AttackState.java +++ b/src/services/ai/states/AttackState.java @@ -75,7 +75,7 @@ public class AttackState extends AIState { if(weapon != null) maxDistance = weapon.getMaxRange() - 1; } - if(actor.getFollowObject().getWorldPosition().getDistance2D(creature.getWorldPosition()) > maxDistance) + if(actor.getFollowObject().getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) actor.setNextPosition(actor.getFollowObject().getPosition()); else { //recover(actor); @@ -120,6 +120,7 @@ public class AttackState extends AIState { creature.setLookAtTarget(0); creature.setIntendedTarget(0); actor.setFollowObject(null); + actor.setCurrentState(new RetreatState()); return StateResult.FINISHED; } CreatureObject target = actor.getFollowObject(); @@ -133,7 +134,7 @@ public class AttackState extends AIState { return StateResult.UNFINISHED; } if(target.getPosture() == 13 || target.getPosture() == 14) { - actor.getDamageMap().remove(target); + actor.removeDefender(target); actor.setFollowObject(actor.getHighestDamageDealer()); target = actor.getFollowObject(); if(target == null) @@ -148,7 +149,7 @@ public class AttackState extends AIState { actor.scheduleRecovery(); return StateResult.UNFINISHED; } - if(target.getWorldPosition().getDistance2D(creature.getWorldPosition()) > maxDistance) { + if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) { actor.scheduleRecovery(); return StateResult.UNFINISHED; } diff --git a/src/services/ai/states/RetreatState.java b/src/services/ai/states/RetreatState.java index ec4b93f3..61db1785 100644 --- a/src/services/ai/states/RetreatState.java +++ b/src/services/ai/states/RetreatState.java @@ -23,6 +23,7 @@ package services.ai.states; import resources.objects.creature.CreatureObject; import services.ai.AIActor; +import services.ai.states.AIState.StateResult; public class RetreatState extends AIState { @@ -41,15 +42,17 @@ public class RetreatState extends AIState { @Override public byte onExit(AIActor actor) { // TODO Auto-generated method stub - return 0; + return StateResult.FINISHED; } @Override public byte move(AIActor actor) { actor.setNextPosition(actor.getSpawnPosition()); doMove(actor); - if(actor.getCreature().getWorldPosition().getDistance2D(actor.getSpawnPosition()) > 4) { + if(actor.getCreature().getWorldPosition().getDistance(actor.getSpawnPosition()) > 3) { actor.scheduleMovement(); + } else { + return StateResult.IDLE; } return StateResult.UNFINISHED; } diff --git a/src/services/command/BaseSWGCommand.java b/src/services/command/BaseSWGCommand.java index cca19f25..6eee3c22 100644 --- a/src/services/command/BaseSWGCommand.java +++ b/src/services/command/BaseSWGCommand.java @@ -25,34 +25,125 @@ import engine.clientdata.ClientFileManager; import engine.clientdata.visitors.DatatableVisitor; import engine.resources.common.CRC; +import java.util.ArrayList; +import java.util.List; + public class BaseSWGCommand implements Cloneable { private String commandName; private String clientEffectSelf; private String clientEffectTarget; - private int maxRangeToTarget; private int commandCRC; private boolean isGmCommand = false; - private String requiredAbility; + private String characterAbility; + private int target; + private int targetType; + private boolean callOnTarget = false; + private int commandGroup; + private boolean disabled = true; + private float maxRangeToTarget; + private int godLevel; + private int displayGroup; + private boolean combatCommand = false; + private int validWeapon; + private int invalidWeapon; private String cooldownGroup; private float cooldown; private float executeTime; private float warmupTime; + //private Long[] invalidLocomotions; // Not tracked anywhere + private Byte[] invalidPostures; + private Long[] invalidStates; public BaseSWGCommand(String commandName) { setCommandName(commandName); setCommandCRC(CRC.StringtoCRC(commandName)); try { + List invalidStates = new ArrayList(); + List invalidPostures = new ArrayList(); + DatatableVisitor visitor2 = ClientFileManager.loadFile("datatables/command/command_table.iff", DatatableVisitor.class); + for (int i = 0; i < visitor2.getRowCount(); i++) { if (visitor2.getObject(i, 0) != null) { if (((String) visitor2.getObject(i, 0)).equalsIgnoreCase(commandName)) { - requiredAbility = (String) visitor2.getObject(i, 7); + characterAbility = (String) visitor2.getObject(i, 7); + target = (Integer) visitor2.getObject(i, 72); + targetType = (Integer) visitor2.getObject(i, 73); + callOnTarget = (Boolean) visitor2.getObject(i, 76); + commandGroup = (Integer) visitor2.getObject(i, 77); + disabled = (Boolean) visitor2.getObject(i, 78); + maxRangeToTarget = (Float) visitor2.getObject(i, 79); + godLevel = (Integer) visitor2.getObject(i, 80); + displayGroup = (Integer) visitor2.getObject(i, 81); + combatCommand = (Boolean) visitor2.getObject(i, 82); + validWeapon = (Integer) visitor2.getObject(i, 83); + invalidWeapon = (Integer) visitor2.getObject(i, 84); cooldownGroup = (String) visitor2.getObject(i, 85); warmupTime = (Float) visitor2.getObject(i, 86); executeTime = (Float) visitor2.getObject(i, 87); cooldown = (Float) visitor2.getObject(i, 88); + + if (!((Boolean) visitor2.getObject(i, 8))) invalidPostures.add((byte) 0); + if (!((Boolean) visitor2.getObject(i, 9))) invalidPostures.add((byte) 3); + if (!((Boolean) visitor2.getObject(i, 16))) invalidPostures.add((byte) 2); + if (!((Boolean) visitor2.getObject(i, 19))) invalidPostures.add((byte) 5); + if (!((Boolean) visitor2.getObject(i, 21))) invalidPostures.add((byte) 6); + if (!((Boolean) visitor2.getObject(i, 22))) invalidPostures.add((byte) 7); + if (!((Boolean) visitor2.getObject(i, 23))) invalidPostures.add((byte) 8); + if (!((Boolean) visitor2.getObject(i, 24))) invalidPostures.add((byte) 9); + if (!((Boolean) visitor2.getObject(i, 25))) invalidPostures.add((byte) 10); + if (!((Boolean) visitor2.getObject(i, 26))) invalidPostures.add((byte) 11); + if (!((Boolean) visitor2.getObject(i, 27))) invalidPostures.add((byte) 12); + if (!((Boolean) visitor2.getObject(i, 28))) invalidPostures.add((byte) 13); + if (!((Boolean) visitor2.getObject(i, 29))) invalidPostures.add((byte) 14); + if (!((Boolean) visitor2.getObject(i, 30))) invalidPostures.add((byte) 4); + + if (!((Boolean) visitor2.getObject(i, 32))) invalidStates.add(1L); + if (!((Boolean) visitor2.getObject(i, 33))) invalidStates.add(2L); + if (!((Boolean) visitor2.getObject(i, 34))) invalidStates.add(4L); + if (!((Boolean) visitor2.getObject(i, 35))) invalidStates.add(8L); + if (!((Boolean) visitor2.getObject(i, 36))) invalidStates.add(16L); + if (!((Boolean) visitor2.getObject(i, 37))) invalidStates.add(32L); + if (!((Boolean) visitor2.getObject(i, 38))) invalidStates.add(64L); + if (!((Boolean) visitor2.getObject(i, 39))) invalidStates.add(128L); + if (!((Boolean) visitor2.getObject(i, 40))) invalidStates.add(256L); + if (!((Boolean) visitor2.getObject(i, 41))) invalidStates.add(512L); + if (!((Boolean) visitor2.getObject(i, 42))) invalidStates.add(1024L); + if (!((Boolean) visitor2.getObject(i, 43))) invalidStates.add(2048L); + if (!((Boolean) visitor2.getObject(i, 44))) invalidStates.add(4096L); + if (!((Boolean) visitor2.getObject(i, 45))) invalidStates.add(8192L); + if (!((Boolean) visitor2.getObject(i, 46))) invalidStates.add(16384L); + if (!((Boolean) visitor2.getObject(i, 47))) invalidStates.add(32768L); + if (!((Boolean) visitor2.getObject(i, 48))) invalidStates.add(65536L); + if (!((Boolean) visitor2.getObject(i, 49))) invalidStates.add(131072L); + if (!((Boolean) visitor2.getObject(i, 50))) invalidStates.add(262144L); + if (!((Boolean) visitor2.getObject(i, 51))) invalidStates.add(524288L); + if (!((Boolean) visitor2.getObject(i, 52))) invalidStates.add(1048576L); + if (!((Boolean) visitor2.getObject(i, 53))) invalidStates.add(2097152L); + if (!((Boolean) visitor2.getObject(i, 54))) invalidStates.add(4194304L); + if (!((Boolean) visitor2.getObject(i, 55))) invalidStates.add(8388608L); + if (!((Boolean) visitor2.getObject(i, 56))) invalidStates.add(16777216L); + if (!((Boolean) visitor2.getObject(i, 57))) invalidStates.add(33554432L); + if (!((Boolean) visitor2.getObject(i, 58))) invalidStates.add(67108864L); + if (!((Boolean) visitor2.getObject(i, 59))) invalidStates.add(134217728L); + if (!((Boolean) visitor2.getObject(i, 60))) invalidStates.add(268435456L); + if (!((Boolean) visitor2.getObject(i, 61))) invalidStates.add(536870912L); + if (!((Boolean) visitor2.getObject(i, 62))) invalidStates.add(1073741824L); + if (!((Boolean) visitor2.getObject(i, 63))) invalidStates.add(2147483648L); + if (!((Boolean) visitor2.getObject(i, 64))) invalidStates.add(4294967296L); + if (!((Boolean) visitor2.getObject(i, 65))) invalidStates.add(8589934592L); + if (!((Boolean) visitor2.getObject(i, 66))) invalidStates.add(17179869184L); + if (!((Boolean) visitor2.getObject(i, 67))) invalidStates.add(34359738368L); + if (!((Boolean) visitor2.getObject(i, 68))) invalidStates.add(68719476736L); + if (!((Boolean) visitor2.getObject(i, 69))) invalidStates.add(137438953472L); + if (!((Boolean) visitor2.getObject(i, 70))) invalidStates.add(274877906944L); + + this.invalidPostures = invalidPostures.toArray(new Byte[] { }); + this.invalidStates = invalidStates.toArray(new Long[] { }); + + break; } } } @@ -60,97 +151,185 @@ public class BaseSWGCommand implements Cloneable { e.printStackTrace(); } } - + public String getCommandName() { return commandName; } - + public void setCommandName(String commandName) { this.commandName = commandName; } - + public String getClientEffectSelf() { return clientEffectSelf; } - + public void setClientEffectSelf(String clientEffectSelf) { this.clientEffectSelf = clientEffectSelf; } - + public String getClientEffectTarget() { return clientEffectTarget; } - + public void setClientEffectTarget(String clientEffectTarget) { this.clientEffectTarget = clientEffectTarget; } - - public int getMaxRangeToTarget() { - return maxRangeToTarget; - } - - public void setMaxRangeToTarget(int maxRangeToTarget) { - this.maxRangeToTarget = maxRangeToTarget; - } - + public int getCommandCRC() { return commandCRC; } - + public void setCommandCRC(int commandCRC) { this.commandCRC = commandCRC; } - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + public boolean isGmCommand() { - return isGmCommand; + return (godLevel > 0); } - + public void setGmCommand(boolean isGmCommand) { this.isGmCommand = isGmCommand; } - - public String getRequiredAbility() { - return requiredAbility; + + public String getCharacterAbility() { + return characterAbility; } - - public void setRequiredAbility(String requiredAbility) { - this.requiredAbility = requiredAbility; + + public void setcharacterAbility(String characterAbility) { + this.characterAbility = characterAbility; } - + + public Byte[] getInvalidPostures() { + return invalidPostures; + } + + public Long[] getInvalidStates() { + return invalidStates; + } + + public int getTarget() { + return target; + } + + public void setTarget(int target) { + this.target = target; + } + + public void getTargetType() { + return targetType; + } + + public void setTargetType() { + return targetType; + } + + public boolean shouldCallOnTarget() { + return callOnTarget; + } + + public void setCallOnTarget(boolean callOnTarget) { + this.callOnTarget = callOnTarget; + } + + public int getCommandGroup() { + return commandGroup; + } + + public void setCommandGroup(int commandGroup) { + this.commandGroup = commandGroup; + } + + public boolean isDisabled() { + return disabled; + } + + public void setDisabled(boolean disabled) { + this.disabled = disabled; + } + + public float getMaxRangeToTarget() { + return maxRangeToTarget; + } + + public void setMaxRangeToTarget(float maxRangeToTarget) { + this.maxRangeToTarget = maxRangeToTarget; + } + + public int getGodLevel() { + return godLevel; + } + + public void setGodLevel(int godLevel) { + this.godLevel = godLevel; + } + + public int getDisplayGroup() { + return displayGroup; + } + + public void setDisplayGroup(int displayGroup) { + this.displayGroup = displayGroup; + } + + public boolean isCombatCommand() { + return combatCommand; + } + + public void setCombatCommand(boolean combatCommand) { + this.combatCommand = combatCommand; + } + + public int getValidWeapon() { + return validWeapon; + } + + public void setValidWeapon(int validWeapon) { + this.validWeapon = validWeapon; + } + + public int getInvalidWeapon() { + return invalidWeapon; + } + + public void setInvalidWeapon(int invalidWeapon) { + this.invalidWeapon = invalidWeapon; + } + public String getCooldownGroup() { return cooldownGroup; } - + public void setCooldownGroup(String cooldownGroup) { this.cooldownGroup = cooldownGroup; } - + public float getCooldown() { return cooldown; } - + public void setCooldown(float cooldown) { this.cooldown = cooldown; } - + public float getExecuteTime() { return executeTime; } - + public void setExecuteTime(float executeTime) { this.executeTime = executeTime; } - + public float getWarmupTime() { return warmupTime; } - + public void setWarmupTime(float warmupTime) { this.warmupTime = warmupTime; } - + } diff --git a/src/services/command/CommandService.java b/src/services/command/CommandService.java index 1a94d8ed..f3364e5b 100644 --- a/src/services/command/CommandService.java +++ b/src/services/command/CommandService.java @@ -34,6 +34,8 @@ import main.NGECore; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; +import engine.clientdata.ClientFileManager; +import engine.clientdata.visitors.DatatableVisitor; import engine.clients.Client; import engine.resources.common.CRC; import engine.resources.objects.SWGObject; @@ -41,6 +43,7 @@ import engine.resources.scene.Point3D; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import resources.common.*; +import resources.datatables.StateStatus; import protocol.swg.ObjControllerMessage; import protocol.swg.objectControllerObjects.CommandEnqueue; import protocol.swg.objectControllerObjects.CommandEnqueueRemove; @@ -53,168 +56,286 @@ import resources.objects.weapon.WeaponObject; public class CommandService implements INetworkDispatch { private Vector commandLookup = new Vector(); - private ConcurrentHashMap aliases = new ConcurrentHashMap(); - private ConcurrentHashMap aliasesByCRC = new ConcurrentHashMap(); private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private NGECore core; public CommandService(NGECore core) { this.core = core; } - - - @Override - public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { - - objControllerOpcodes.put(ObjControllerOpcodes.COMMAND_QUEUE_ENQUEUE, new INetworkRemoteEvent() { - - @Override - public void handlePacket(IoSession session, IoBuffer data) throws Exception { - - data.order(ByteOrder.LITTLE_ENDIAN); - Client client = core.getClient(session); - - if(client == null) { - System.out.println("NULL Client"); - return; - } - - CommandEnqueue commandEnqueue = new CommandEnqueue(); - commandEnqueue.deserialize(data); - - - BaseSWGCommand command = getCommandByCRC(commandEnqueue.getCommandCRC()); - - if(command == null) { - //System.out.println("Unknown Command CRC: " + commandEnqueue.getCommandCRC()); - return; - } - - // TODO: command filters for state, posture etc. - - if(client.getParent() == null) { - System.out.println("NULL Object"); - return; - } - - if(command.isGmCommand() && !client.isGM()) - return; - - CreatureObject actor = (CreatureObject) client.getParent(); - - if (command.getRequiredAbility().length() > 0 && !actor.hasAbility(command.getRequiredAbility())) - return; - - if (actor.hasCooldown(command.getCommandName())) - return; - - SWGObject target = core.objectService.getObject(commandEnqueue.getTargetID()); - - // May want to have a warmup def to be called at some point in the future. - if (command.getWarmupTime() != 0 && !(command instanceof CombatCommand)) { - scheduler.schedule(new Runnable() { - - @Override - public void run() { - core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandEnqueue.getCommandArguments()); - } - }, (long) command.getWarmupTime(), TimeUnit.SECONDS); - } else { - - if(command instanceof CombatCommand) { - CombatCommand command2 = (CombatCommand) command.clone(); - processCombatCommand(actor, target, command2, commandEnqueue.getActionCounter(), commandEnqueue.getCommandArguments()); - return; - } - - core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandEnqueue.getCommandArguments()); - } - } - - }); - - objControllerOpcodes.put(ObjControllerOpcodes.COMMAND_QUEUE_REMOVE, new INetworkRemoteEvent() { - - @Override - public void handlePacket(IoSession session, IoBuffer data) throws Exception { - - } - - }); - - - } - public BaseSWGCommand registerCommand(String name) { + public boolean callCommand(CreatureObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { + if (actor == null) { + return false; + } - BaseSWGCommand command = new BaseSWGCommand(name.toLowerCase()); - commandLookup.add(command); - return command; + if (command == null) { + return false; + } - } - - public CombatCommand registerCombatCommand(String name) { + if (command.getCharacterAbility().length() > 0 && !actor.hasAbility(command.getCharacterAbility())) { + return false; + } - CombatCommand command = new CombatCommand(name.toLowerCase()); - commandLookup.add(command); - return command; + if (command.isDisabled()) { + return false; + } - } - - public BaseSWGCommand registerGmCommand(String name) { + if (command.getGodLevel() > 0 && !client.isGM()) { + return false; + } - BaseSWGCommand command = new BaseSWGCommand(name.toLowerCase()); - command.setGmCommand(true); - commandLookup.add(command); - return command; + if (actor.hasCooldown(command.getCooldownGroup()) || actor.hasCooldown(command.getCommandName())) { + return false; + } - } - - public void registerAlias(String name, String target) { - Vector commands = new Vector(commandLookup); // copy for thread safety - BaseSWGCommand targetCommand = null; - for(BaseSWGCommand command : commands) { - if(command.getCommandName().equalsIgnoreCase(target)) { - targetCommand = command; + WeaponObject weapon = (WeaponObject) core.objectService.getObject(actor.getWeaponId()); + + if (weapon != null && weapon.getWeaponType() == command.getInvalidWeapon()) { + return false; + } + + // The two below statements need testing before use + + for (long state : command.getInvalidStates()) { + if ((actor.getStateBitmask() & state) == state) { + //return false; } } - if (targetCommand == null) { return; } - aliases.put(name, targetCommand); - aliasesByCRC.put(CRC.StringtoCRC(name), targetCommand); + for (byte posture : command.getInvalidPostures()) { + if (actor.getPosture() == posture) { + //return false; + } + } + switch (command.getTargetType()) { + case 0: // Target Not Used For This Command or Self + target = actor; + + break; + case 1: // Other Only + if (target == null || target == actor) { + return false; + } + + if (target != null && actor.getPosition().getDistance(target.getPosition) > command.getMaxRangeToTarget()) { + return false; + } + + if (!core.simulationService.checkLineOfSight(actor, target)) { + return false; + } + + break; + case 2: // Self Only + if (target == null) { + target = actor; + } + + if (target != actor) { + return false; + } + + break; + case 3: // Free Target Mode (rally points, group waypoints) + target = null; + + break; + case 4: // Anyone + if (target == null) { + target = actor; + } + + if (!core.simulationService.checkLineOfSight(actor, target)) { + return false; + } + + break; + default: + break; + } + + switch (command.getTarget()) { + case 0: // Ally Only + if (target == null) { + target = actor; + } + + if (!(target instanceof TangibleObject)) { + return false; + } + + TangibleObject object = (TangibleObject) target; + + if (object.isAttackableBy(actor) || actor.getFactionStatus() < object.getFactionStatus() || (!object.getFaction().equals("") && !object.getFaction().equals(actor.getFaction()))) { + return false; + } + + // Without this we could be buffing ally NPCs and such + if (object.getSlottedObject("ghost") == null) { + return; + } + + break; + case 1: // Enemy Only + if (target == null || !(target instanceof TangibleObject)) { + return false; + } + + TangibleObject object = (TangibleObject) target; + + if (!object.isAttackableBy(actor)) { + return false; + } + + break; + case 2: // Indifferent + break; + default: + break; + } + + if (command.shouldCallOnTarget()) { + if (target == null || !(target instanceof CreatureObject)) { + return false; + } + + actor = (CreatureObject) target; + } + + long warmupTime = (command.getWarmupTime() * 1000F); + + if (warmupTime != 0) { + scheduler.schedule(new Runnable() { + + @Override + public void run() { + processCommand(actor, target, command, actionCounter, commandArgs); + } + + }, warmupTime, TimeUnit.MILLISECONDS); + } else { + processCommand(actor, target, command, actionCounter, commandArgs); + } + + return true; } - + + public void callCommand(SWGObject actor, String commandName, SWGObject target, String commandArgs) { + if (actor == null) + return; + + BaseSWGCommand command = getCommandByName(commandName); + + if (command == null) + return; + + if(command instanceof CombatCommand) { + CombatCommand command2; + try { + command2 = (CombatCommand) command.clone(); + processCombatCommand((CreatureObject) actor, target, command2, 0, ""); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + return; + } + + core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandArgs); + } + public BaseSWGCommand getCommandByCRC(int CRC) { + Vector commands = new Vector(commandLookup); - if (aliasesByCRC.containsKey(CRC)) { - return aliasesByCRC.get(CRC); - } - - Vector commands = new Vector(commandLookup); // copy for thread safety - - for(BaseSWGCommand command : commands) { - if(command.getCommandCRC() == CRC) + for (BaseSWGCommand command : commands) { + if (command.getCommandCRC() == CRC) { return command; + } } + + try { + DatatableVisitor visitor = ClientFileManager.loadFile("datatables/command/command_table.iff", DatatableVisitor.class); + + for (int i = 0; i < visitor.getRowCount(); i++) { + if (visitor.getObject(i, 0) != null) { + String name = ((String) visitor.getObject(i, 0)).toLowerCase(); + + if (CRC.StringtoCRC(name) == CRC) { + boolean hasCharacterAbility = (((String) visitor.getObject(i, 7)).length() > 0); + boolean isCombatCommand = (Boolean) visitor.getObject(i, 82); + + if (hasCharacterAbility || isCombatCommand) { + CombatCommand command = new CombatCommand(name.toLowerCase()); + commandLookup.add(command); + return command; + } else { + BaseSWGCommand command = new BaseSWGCommand(name.toLowerCase()); + commandLookup.add(command); + return command; + } + } + } + } + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + return null; - } public BaseSWGCommand getCommandByName(String name) { + Vector commands = new Vector(commandLookup); - if (aliases.containsKey(name)) { - return aliases.get(name); - } + name = name.toLowerCase(); - Vector commands = new Vector(commandLookup); // copy for thread safety - - for(BaseSWGCommand command : commands) { - if(command.getCommandName().equalsIgnoreCase(name)) + for (BaseSWGCommand command : commands) { + if (command.getCommandName().equalsIgnoreCase(name)) { return command; + } } + + try { + DatatableVisitor visitor = ClientFileManager.loadFile("datatables/command/command_table.iff", DatatableVisitor.class); + + for (int i = 0; i < visitor.getRowCount(); i++) { + if (visitor.getObject(i, 0) != null) { + String commandName = ((String) visitor.getObject(i, 0)).toLowerCase(); + + if (commandName.equalsIgnoreCase(name)) { + boolean hasCharacterAbility = (((String) visitor.getObject(i, 7)).length() > 0); + boolean isCombatCommand = (Boolean) visitor.getObject(i, 82); + + if (hasCharacterAbility || isCombatCommand) { + CombatCommand command = new CombatCommand(commandName); + commandLookup.add(command); + return command; + } else { + BaseSWGCommand command = new BaseSWGCommand(commandName); + commandLookup.add(command); + return command; + } + } + } + } + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + return null; - + } + + public void processCommand(CreatureObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { + if (command.getCooldown() > (float) 1) { + actor.addCooldown(command.getCooldownGroup(), command.getCooldown()); + } + + if (command instanceof CombatCommand) { + processCombatCommand(actor, target, (CombatCommand) command, actionCounter, commandArgs); + } else { + if (FileUtilities.doesFileExist("scripts/commands/" + command.getCommandName() + ".py")) { + core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandEnqueue.getCommandArguments()); + } + } } public void processCombatCommand(CreatureObject attacker, SWGObject target, CombatCommand command, int actionCounter, String commandArgs) { @@ -324,34 +445,85 @@ public class CommandService implements INetworkDispatch { } } - - public void callCommand(SWGObject actor, String commandName, SWGObject target, String commandArgs) { - if (actor == null) - return; - - BaseSWGCommand command = getCommandByName(commandName); - - if (command == null) - return; - - if(command instanceof CombatCommand) { - CombatCommand command2; - try { - command2 = (CombatCommand) command.clone(); - processCombatCommand((CreatureObject) actor, target, command2, 0, ""); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - return; - } - - core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandArgs); - } @Override - public void shutdown() { - // TODO Auto-generated method stub + public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { + + objControllerOpcodes.put(ObjControllerOpcodes.COMMAND_QUEUE_ENQUEUE, new INetworkRemoteEvent() { + + @Override + public void handlePacket(IoSession session, IoBuffer data) throws Exception { + + data.order(ByteOrder.LITTLE_ENDIAN); + Client client = core.getClient(session); + + if (client == null) { + System.out.println("NULL Client"); + return; + } + + CommandEnqueue commandEnqueue = new CommandEnqueue(); + commandEnqueue.deserialize(data); + + BaseSWGCommand command = getCommandByCRC(commandEnqueue.getCommandCRC()); + + if (command == null) { + //System.out.println("Unknown Command CRC: " + commandEnqueue.getCommandCRC()); + return; + } + + if (client.getParent() == null) { + System.out.println("NULL Object"); + return; + } + + CreatureObject actor = (CreatureObject) client.getParent(); + + SWGObject target = core.objectService.getObject(commandEnqueue.getTargetID()); + + if (!callCommand(actor, target, command, commandEnqueue.getActionCounter(), commandEnqueue.getCommandArguments())) { + // Call failScriptHook + } + } + + }); + + objControllerOpcodes.put(ObjControllerOpcodes.COMMAND_QUEUE_REMOVE, new INetworkRemoteEvent() { + + @Override + public void handlePacket(IoSession session, IoBuffer data) throws Exception { + + } + + }); + } - + + public void shutdown() { + + } + + public CombatCommand registerCombatCommand(String name) { + BaseSWGCommand command = getCommandByName(name); + + if (command == null) { + return null; + } + + if (command instanceof CombatCommand) { + return (CombatCommand) command; + } else { + System.out.println("Warning: Forced to make non-combat command " + name + " a combat command."); + commandLookup.remove(command); + CombatCommand combatCommand = new CombatCommand(name.toLowerCase()); + commandLookup.add(combatCommand); + return combatCommand; + } + } + + public BaseSWGCommand registerCommand(String name) { return getCommandByName(name); } + public BaseSWGCommand registerGmCommand(String name) { return getCommandByName(name); } + public void registerAlias(String name, String target) { } + }