diff --git a/.classpath b/.classpath index 6d739bfc..6da71800 100644 --- a/.classpath +++ b/.classpath @@ -28,8 +28,8 @@ - - + + diff --git a/lib/mbassador-1.1.7.jar b/lib/mbassador-1.1.7.jar deleted file mode 100644 index c7ae2c11..00000000 Binary files a/lib/mbassador-1.1.7.jar and /dev/null differ diff --git a/lib/mbassador-1.1.9.jar b/lib/mbassador-1.1.9.jar new file mode 100644 index 00000000..ff742d1c Binary files /dev/null and b/lib/mbassador-1.1.9.jar differ diff --git a/ngengine_public.jar b/ngengine_public.jar index 6da80c04..71e72b65 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/buffs/armor_break.py b/scripts/buffs/armor_break.py index 89b7585d..288a2db0 100644 --- a/scripts/buffs/armor_break.py +++ b/scripts/buffs/armor_break.py @@ -2,9 +2,11 @@ import sys def setup(core, actor, buff): actor.addSkillMod('expertise_innate_reduction_all_player', 6 * buff.getStacks()) + actor.addSkillMod('expertise_innate_reduction_all_mob', 600 * buff.getStacks()) return def removeBuff(core, actor, buff): + actor.deductSkillMod('expertise_innate_reduction_all_mob', 600 * buff.getStacks()) actor.deductSkillMod('expertise_innate_reduction_all_player', 6 * buff.getStacks()) return - \ No newline at end of file + diff --git a/scripts/buffs/co_position_secured.py b/scripts/buffs/co_position_secured.py index e0be4042..b0b2781c 100644 --- a/scripts/buffs/co_position_secured.py +++ b/scripts/buffs/co_position_secured.py @@ -43,8 +43,8 @@ def removeBuff(core, actor, buff): if actor.getGroupId() != 0 and core.objectService.getObject(actor.getGroupId()): group = core.objectService.getObject(actor.getGroupId()) for member in group.getMemberList(): - core.buffService.removeBuffToCreature(member, 'co_base_of_operations') + core.buffService.removeBuffFromCreature(member, member.getBuffByName('co_base_of_operations')) else: - core.buffService.removeBuffToCreature(actor, 'co_base_of_operations') + core.buffService.removeBuffFromCreature(actor, actor.getBuffByName('co_base_of_operations')) return \ No newline at end of file diff --git a/scripts/commands/co_position_secured.py b/scripts/commands/co_position_secured.py index 41be0614..a2165915 100644 --- a/scripts/commands/co_position_secured.py +++ b/scripts/commands/co_position_secured.py @@ -6,7 +6,7 @@ def setup(): def run(core, actor, target, commandString): if actor.hasBuff('co_position_secured'): - core.buffService.removeBuffFromCreature(actor, actor.getBuff('co_position_secured')) + core.buffService.removeBuffFromCreature(actor, actor.getBuffByName('co_position_secured')) else: core.buffService.addBuffToCreature(actor, 'co_position_secured') diff --git a/scripts/commands/inspire.py b/scripts/commands/inspire.py index 495c193f..38a789ab 100644 --- a/scripts/commands/inspire.py +++ b/scripts/commands/inspire.py @@ -6,6 +6,10 @@ def setup(): return def run(core, actor, target, commandString): + + if (actor.getProfession() != "entertainer_1a"): + return + print ('Buffing Player: ' + str(target.getObjectId()) + ' or: ' + target.getCustomName()) openBuffWindow = BuffBuilderStartMessage(actor.getObjectId(), actor.getObjectId(), target.getObjectId()) objController = ObjControllerMessage(11, openBuffWindow) diff --git a/scripts/commands/of_focus_fire_1.py b/scripts/commands/of_focus_fire_1.py index 4857b1ce..d3a2cfb8 100644 --- a/scripts/commands/of_focus_fire_1.py +++ b/scripts/commands/of_focus_fire_1.py @@ -6,7 +6,9 @@ def setup(core, actor, buff): def run(core, actor, target, commandString): core.buffService.addBuffToCreature(actor, 'of_focus_fire_1') group = core.objectService.getObject(actor.getGroupId()) - for creature in group.getMemberList(): - core.buffService.addBuffToCreature(creature, 'of_focus_fire_1') + if group is not None: + for creature in group.getMemberList(): + core.buffService.addBuffToCreature(creature, 'of_focus_fire_1') + return return \ No newline at end of file diff --git a/scripts/commands/of_focus_fire_2.py b/scripts/commands/of_focus_fire_2.py index 2eb8248d..cafae5bd 100644 --- a/scripts/commands/of_focus_fire_2.py +++ b/scripts/commands/of_focus_fire_2.py @@ -4,8 +4,11 @@ def setup(core, actor, buff): return def run(core, actor, target, commandString): - core.buffService.addBuffToCreature(actor, 'of_focus_fire_1') + core.buffService.addBuffToCreature(actor, 'of_focus_fire_2') group = core.objectService.getObject(actor.getGroupId()) - for creature in group.getMemberList(): - core.buffService.addBuffToCreature(creature, 'of_focus_fire_2') - return \ No newline at end of file + if group is not None: + for creature in group.getMemberList(): + core.buffService.addBuffToCreature(creature, 'of_focus_fire_2') + return + return + \ No newline at end of file diff --git a/scripts/commands/of_focus_fire_3.py b/scripts/commands/of_focus_fire_3.py index bac08eb4..75129446 100644 --- a/scripts/commands/of_focus_fire_3.py +++ b/scripts/commands/of_focus_fire_3.py @@ -4,8 +4,11 @@ def setup(core, actor, buff): return def run(core, actor, target, commandString): - core.buffService.addBuffToCreature(actor, 'of_focus_fire_1') + core.buffService.addBuffToCreature(actor, 'of_focus_fire_3') group = core.objectService.getObject(actor.getGroupId()) - for creature in group.getMemberList(): - core.buffService.addBuffToCreature(creature, 'of_focus_fire_3') - return \ No newline at end of file + if group is not None: + for creature in group.getMemberList(): + core.buffService.addBuffToCreature(creature, 'of_focus_fire_3') + return + return + \ No newline at end of file diff --git a/scripts/commands/of_tactical_sup_1.py b/scripts/commands/of_tactical_sup_1.py new file mode 100644 index 00000000..7ec7b103 --- /dev/null +++ b/scripts/commands/of_tactical_sup_1.py @@ -0,0 +1,72 @@ +from engine.resources.container import StaticContainerPermissions +import time +import sys + +def setup(core, actor, target, command): + return + +def run(core, actor, target, commandString): + doStimDrop(core, actor) + return + +def doStimDrop(core, actor): + stcSvc = core.staticService + shuttle = stcSvc.spawnObject('object/creature/npc/theme_park/shared_lambda_shuttle.iff', actor.getPlanet().getName(), long(0), actor.getPosition().x, actor.getPosition().y, actor.getPosition().z, actor.getOrientation().y, actor.getOrientation().w) + shuttle.setPosture(0) + time.sleep(10) # Wait time before shuttle arrives after command is called + shuttle.setPosture(2) + time.sleep(20) # wait time for the crate to show (length of landing animation for shuttle) + spawnCrate(core, actor, shuttle) + time.sleep(5) # Wait time for the shuttle to leave after crate is spawned + shuttle.setPosture(0) + time.sleep(20) # How long the take-off sequence is, until the Shuttle is destroyed + core.objectService.destroyObject(shuttle) + return + +def spawnCrate(core, actor, shuttle): + crate = core.staticService.spawnObject('object/tangible/container/loot/shared_npe_loot_crate_low.iff', shuttle.getPlanet().getName(), long(0), shuttle.getPosition().x, shuttle.getPosition().y, shuttle.getPosition().z, shuttle.getOrientation().y, shuttle.getOrientation().w) + crate.setCustomName('Supply Crate') + + permissions = StaticContainerPermissions() + permissions.canRemove(actor, crate) + permissions.canView(actor, crate) + crate.setContainerPermissions(permissions) + + tac1 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac1) + tac2 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac2) + tac3 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac3) + tac4 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac4) + tac5 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac5) + tac6 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac6) + tac7 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac7) + tac8 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac8) + + stim1 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim1) + stim2 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim2) + stim3 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim3) + stim4 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim4) + stim5 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim5) + stim6 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim6) + stim7 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim7) + stim8 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim8) + + time.sleep(60) + core.objectService.destroyObject(crate) + + return \ No newline at end of file diff --git a/scripts/commands/of_tactical_sup_2.py b/scripts/commands/of_tactical_sup_2.py new file mode 100644 index 00000000..76c7b5aa --- /dev/null +++ b/scripts/commands/of_tactical_sup_2.py @@ -0,0 +1,13 @@ +import sys + +def setup(core, actor, buff): + return + +def run(core, actor, target, commandString): + print (' shuttle called!') + lambdaShuttle = stcSvc.spawnObject('object/creature/npc/theme_park/shared_event_lambda_shuttle.iff', actor.getPlanet().getName(), + long(0), actor.getPosition().x, actor.getPosition().y, actor.getPosition().z, actor.getOrientation().y, actor.getOrientation().w) + + lambdaShuttle.setPosture(0) # 0 or 2? + print ('posture set!') + return \ No newline at end of file diff --git a/scripts/commands/of_tactical_sup_3.py b/scripts/commands/of_tactical_sup_3.py new file mode 100644 index 00000000..76c7b5aa --- /dev/null +++ b/scripts/commands/of_tactical_sup_3.py @@ -0,0 +1,13 @@ +import sys + +def setup(core, actor, buff): + return + +def run(core, actor, target, commandString): + print (' shuttle called!') + lambdaShuttle = stcSvc.spawnObject('object/creature/npc/theme_park/shared_event_lambda_shuttle.iff', actor.getPlanet().getName(), + long(0), actor.getPosition().x, actor.getPosition().y, actor.getPosition().z, actor.getOrientation().y, actor.getOrientation().w) + + lambdaShuttle.setPosture(0) # 0 or 2? + print ('posture set!') + return \ No newline at end of file diff --git a/scripts/commands/of_tactical_sup_4.py b/scripts/commands/of_tactical_sup_4.py new file mode 100644 index 00000000..76c7b5aa --- /dev/null +++ b/scripts/commands/of_tactical_sup_4.py @@ -0,0 +1,13 @@ +import sys + +def setup(core, actor, buff): + return + +def run(core, actor, target, commandString): + print (' shuttle called!') + lambdaShuttle = stcSvc.spawnObject('object/creature/npc/theme_park/shared_event_lambda_shuttle.iff', actor.getPlanet().getName(), + long(0), actor.getPosition().x, actor.getPosition().y, actor.getPosition().z, actor.getOrientation().y, actor.getOrientation().w) + + lambdaShuttle.setPosture(0) # 0 or 2? + print ('posture set!') + return \ No newline at end of file diff --git a/scripts/commands/of_tactical_sup_5.py b/scripts/commands/of_tactical_sup_5.py new file mode 100644 index 00000000..76c7b5aa --- /dev/null +++ b/scripts/commands/of_tactical_sup_5.py @@ -0,0 +1,13 @@ +import sys + +def setup(core, actor, buff): + return + +def run(core, actor, target, commandString): + print (' shuttle called!') + lambdaShuttle = stcSvc.spawnObject('object/creature/npc/theme_park/shared_event_lambda_shuttle.iff', actor.getPlanet().getName(), + long(0), actor.getPosition().x, actor.getPosition().y, actor.getPosition().z, actor.getOrientation().y, actor.getOrientation().w) + + lambdaShuttle.setPosture(0) # 0 or 2? + print ('posture set!') + return \ No newline at end of file diff --git a/scripts/commands/of_tactical_sup_6.py b/scripts/commands/of_tactical_sup_6.py new file mode 100644 index 00000000..ec8f96db --- /dev/null +++ b/scripts/commands/of_tactical_sup_6.py @@ -0,0 +1,70 @@ +from engine.resources.container import StaticContainerPermissions +import time +import sys + +def setup(core, actor, buff): + return + +def run(core, actor, target, commandString): + doStimDrop(core, actor) + return + +def doStimDrop(core, actor): + stcSvc = core.staticService + time.sleep(10) # Wait time before shuttle arrives after command is called + shuttle = stcSvc.spawnObject('object/creature/npc/theme_park/shared_lambda_shuttle.iff', actor.getPlanet().getName(), long(0), actor.getPosition().x, actor.getPosition().y, actor.getPosition().z, actor.getOrientation().y, actor.getOrientation().w) + shuttle.setPosture(0) + time.sleep(1) + shuttle.setPosture(2) + time.sleep(20) # wait time for the crate to show (length of landing animation for shuttle) + spawnCrate(core, actor, shuttle) + time.sleep(5) # Wait time for the shuttle to leave after crate is spawned + shuttle.setPosture(0) + time.sleep(20) # How long the take-off sequence is, until the Shuttle is destroyed + core.objectService.destroyObject(shuttle) + return + +def spawnCrate(core, actor, shuttle): + crate = core.staticService.spawnObject('object/tangible/container/loot/shared_npe_loot_crate_low.iff', shuttle.getPlanet().getName(), long(0), shuttle.getPosition().x, shuttle.getPosition().y, shuttle.getPosition().z, shuttle.getOrientation().y, shuttle.getOrientation().w) + crate.setCustomName('Supply Crate') + + permissions = StaticContainerPermissions() + permissions.canRemove(actor, crate) + permissions.canView(actor, crate) + crate.setContainerPermissions(permissions) + + tac1 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac1) + tac2 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac2) + tac3 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac3) + tac4 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac4) + tac5 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac5) + tac6 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac6) + tac7 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac7) + tac8 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_syren.iff', actor.getPlanet()) + crate.add(tac8) + + stim1 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim1) + stim2 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim2) + stim3 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim3) + stim4 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim4) + stim5 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim5) + stim6 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim6) + stim7 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim7) + stim8 = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_generic_a.iff', actor.getPlanet()) + crate.add(stim8) + + return \ No newline at end of file diff --git a/scripts/commands/pvp.py b/scripts/commands/pvp.py index 93e9051b..0155c528 100644 --- a/scripts/commands/pvp.py +++ b/scripts/commands/pvp.py @@ -1,74 +1,72 @@ from resources.objects.creature import CreatureObject -from protocol.swg import UpdatePVPStatusMessage +from resources.common import PvpStatus +from resources.common import FactionStatus import sys +import time def setup(): return def run(core, actor, target, commandString): - actorFaction = actor.getFaction() - actorStatus = actor.getFactionStatus() - pvpStatus = UpdatePVPStatusMessage(actor.getObjectId()) - - if commandString == ('imperial') and actorFaction != "imperial": - actor.setFaction('imperial') - return - - if commandString == ('rebel') and actorFaction != "rebel": - actor.setFaction('rebel') - return - - if commandString == ('neutral') and actorFaction != "neutral": - actor.setFaction('neutral') - return - - if actorStatus == 0 and actorFaction == "imperial": - actor.setFactionStatus(1) - #print ("FactionStatus: " + str(actor.getFactionStatus())) - actor.sendSystemMessage('You are no longer On Leave.', 0) - return + faction = actor.getFaction() + factionStatus = actor.getFactionStatus() - if actorStatus == 0 and actorFaction == "rebel": - actor.setFactionStatus(1) - #print ("FactionStatus: " + str(actor.getFactionStatus())) - actor.sendSystemMessage('You are no longer On Leave.', 0) - return + if actor.getPvpStatus(PvpStatus.GoingOvert) or actor.getPvpStatus(PvpStatus.GoingCovert): + actor.sendSystemMessage('@faction_recruiter:pvp_status_changing', 0) + return - if actorStatus == 1 and actorFaction == "imperial": - actor.setFactionStatus(2) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial) - pvpStatus.setStatus(55) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - if actorStatus == 1 and actorFaction == "rebel": - actor.setFactionStatus(2) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel) - pvpStatus.setStatus(55) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - if actorStatus == 2 and actorFaction == "imperial": - actor.setFactionStatus(1) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial) - pvpStatus.setStatus(16) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - if actorStatus == 2 and actorFaction == "rebel": - actor.setFactionStatus(1) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel) - pvpStatus.setStatus(16) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - - return \ No newline at end of file + if commandString != '' and commandString != faction: + if commandString == 'rebel' or commandString == 'imperial' or commandString == 'neutral': + actor.sendSystemMessage('@faction_recruiter:sui_resig_complete_in_5', 0) + + if actor.getFactionStatus() == FactionStatus.SpecialForces: + actor.setPvpStatus(PvpStatus.GoingCovert, True) + time.sleep(300) + + actor.setPvpStatus(PvpStatus.GoingCovert | PvpStatus.Overt | PvpStatus.Attackable | PvpStatus.Aggressive | PvpStatus.Enemy, False) + actor.setFactionStatus(FactionStatus.OnLeave) + + if actor.getFaction() != '' and actor.getFaction() != 'neutral': + time.sleep(1) + actor.setFaction('') + actor.sendSystemMessage('@faction_recruiter:resign_complete', 0) + + + time.sleep(1) + actor.setFaction(commandString) + return + + if faction == 'neutral' or faction == '': + actor.sendSystemMessage('@faction_recruiter:not_aligned', 0) + return + + if factionStatus == FactionStatus.OnLeave: + actor.sendSystemMessage('@faction_recruiter:on_leave_to_covert', 0) + actor.setPvpStatus(PvpStatus.GoingCovert, True) + time.sleep(1) + actor.setFactionStatus(FactionStatus.Combatant) + actor.setPvpStatus(PvpStatus.GoingCovert, False) + actor.setPvpStatus(PvpStatus.Enemy, True) + actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) + return + + if factionStatus == FactionStatus.Combatant: + actor.sendSystemMessage('@faction_recruiter:covert_to_overt', 0) + actor.setPvpStatus(PvpStatus.GoingOvert, True) + time.sleep(30) + actor.setFactionStatus(FactionStatus.SpecialForces) + actor.setPvpStatus(PvpStatus.GoingOvert, False) + actor.setPvpStatus(PvpStatus.Overt | PvpStatus.Attackable | PvpStatus.Aggressive, True) + actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) + return + + if factionStatus == FactionStatus.SpecialForces: + actor.sendSystemMessage('@faction_recruiter:overt_to_covert', 0) + actor.setPvpStatus(PvpStatus.GoingCovert, True) + time.sleep(300) + actor.setFactionStatus(FactionStatus.Combatant) + actor.setPvpStatus(PvpStatus.GoingCovert | PvpStatus.Overt | PvpStatus.Attackable | PvpStatus.Aggressive, False) + actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) + return + + return diff --git a/scripts/commands/setgodmode.py b/scripts/commands/setgodmode.py new file mode 100644 index 00000000..d8b9647d --- /dev/null +++ b/scripts/commands/setgodmode.py @@ -0,0 +1,39 @@ +import sys +from engine.resources.scene import Point3D + +def setup(): + return + +def run(core, actor, target, commandString): + + playerObject = actor.getSlottedObject('ghost') + + if not playerObject: + return + + commandArgs = commandString.split(' ') + command = commandArgs[0] + arg1 = commandArgs[1] + if commandArgs[2]: + arg2 = commandArgs[2] + if commandArgs[3]: + arg3 = commandArgs[3] + if commandArgs[4]: + arg4 = commandArgs[4] + + if not command: + return + + if command == 'giveExperience' and arg1: + core.playerService.giveExperience(actor, int(arg1)) + + if command == 'setSpeed' and arg1: + actor.sendSystemMessage('Your speed was ' + str(actor.getSpeedMultiplierBase()) + '. Don\'t forget to set this back or it\'ll permanently imbalance your speed. Default without buffs or mods is 1.', 2) + actor.setSpeedMultiplierBase(float(arg1)) + actor.sendSystemMessage('Your new speed is ' + str(actor.getSpeedMultiplierBase()) + '.', 2) + + if command == 'teleport' and arg2 and arg3 and arg4: + position = Point3D(float(arg2), float(arg3), float(arg4)) + core.simulationService.transferToPlanet(actor, core.terrainService.getPlanetByName(arg1), position, actor.getOrientation(), None) + + return diff --git a/scripts/expertise/expertise_of_tactical_sup_1.py b/scripts/expertise/expertise_of_tactical_sup_1.py index ce701bb6..d95ef2a5 100644 --- a/scripts/expertise/expertise_of_tactical_sup_1.py +++ b/scripts/expertise/expertise_of_tactical_sup_1.py @@ -36,11 +36,13 @@ def removeExpertisePoint(core, actor): # this checks what abilities the player gets by level, need to also call this on level-up def addAbilities(core, actor, player): - - + + actor.addAbility('of_tactical_sup_1') + return def removeAbilities(core, actor, player): - - + + actor.removeAbility('of_tactical_sup_1') + return diff --git a/scripts/object/creature/npc/theme_park/lambda_shuttle.py b/scripts/object/creature/npc/theme_park/lambda_shuttle.py index ccad8904..3e8a7cbb 100644 --- a/scripts/object/creature/npc/theme_park/lambda_shuttle.py +++ b/scripts/object/creature/npc/theme_park/lambda_shuttle.py @@ -1,4 +1,5 @@ import sys def setup(core, object): + #object.setPosture(2) return \ No newline at end of file diff --git a/scripts/skillMods/movement.py b/scripts/skillMods/movement.py index 47ce841d..a842f3db 100644 --- a/scripts/skillMods/movement.py +++ b/scripts/skillMods/movement.py @@ -2,13 +2,10 @@ import sys def add(core, actor, name, base): actor.addSkillMod(name, base) - actor.getSkillMod(name).setModifier(10) - modifier = actor.getSkillMod(name).getModifier() - actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() + float(float(base) / float(modifier))) + actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() + base / 100) return def deduct(core, actor, name, base): - modifier = actor.getSkillMod(name).getModifier() - actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() - float(float(base) / float(modifier))) + actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() - base / 100) actor.deductSkillMod(name, base) return \ No newline at end of file diff --git a/scripts/starter_clothing/crafting_artisan_trandoshan_male.py b/scripts/starter_clothing/crafting_artisan_trandoshan_male.py index fcabfeda..3862af73 100644 --- a/scripts/starter_clothing/crafting_artisan_trandoshan_male.py +++ b/scripts/starter_clothing/crafting_artisan_trandoshan_male.py @@ -2,10 +2,9 @@ import sys def CraftingArtisanTrandoshanMale(core, object): shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s03.iff', object.getPlanet()) - vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s09.if', object.getPlanet()) + vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s09.iff', object.getPlanet()) necklace = core.objectService.createObject('object/tangible/wearables/necklace/shared_necklace_primitive_03.iff', object.getPlanet()) - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s13.ifff', object.getPlanet()) - inventory = object.getSlottedObject('inventory') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s13.iff', object.getPlanet()) object._add(shirt) object._add(vest) object._add(necklace) diff --git a/scripts/static_map_locations.py b/scripts/static_map_locations.py index 46efc478..62070749 100644 --- a/scripts/static_map_locations.py +++ b/scripts/static_map_locations.py @@ -59,11 +59,11 @@ def corelliaLocations(core, planet): # Cities mapService.addLocation(planet, 'Coronet', -178, -4504, 17, 0, 0) - mapService.addLocation(planet, 'Tyrena', -5140, 2450, 17, 0, 0) + mapService.addLocation(planet, 'Tyrena', -5140, -2450, 17, 0, 0) mapService.addLocation(planet, 'Bela Vistal', 6766, -5692, 17, 0, 0) mapService.addLocation(planet, 'Kor Vella', -3420, 3146, 17, 0, 0) mapService.addLocation(planet, 'Doaba Guerfel', 3274, 5582, 17, 0, 0) - mapService.addLocation(planet, 'Vreni Island', -5538, 6176, 17, 0, 0) + mapService.addLocation(planet, 'Vreni Island', -5538, -6176, 17, 0, 0) def nabooLocations(core, planet): @@ -158,4 +158,4 @@ def lokLocations(core, planet): #mapService.addLocation(planet, 'Pandath Spaceport', 0, 0, 17, 0, 0) - \ No newline at end of file + diff --git a/scripts/static_travel_points.py b/scripts/static_travel_points.py index 70b156c3..54b19a77 100644 --- a/scripts/static_travel_points.py +++ b/scripts/static_travel_points.py @@ -26,10 +26,6 @@ def addPoints(core, planet): kashyyyk_mainPoints(core, planet) if planet.getName() == 'mustafar': mustafarPoints(core, planet) - if planet.getName() == 'kaas': - kaasPoints(core, planet) - if planet.getName() == 'taanab': - taanabPoints(core, planet) return def corelliaPoints(core, planet): @@ -154,12 +150,4 @@ def mustafarPoints(core, planet): trvSvc = core.travelService trvSvc.addTravelPoint(planet, "Mensix Mining Facility", 405, 230, -1352) - return - -#def kaasPoints(core, planet): - #trvSvc = core.travelService - #Return - -#def taanabPoints(core, planet): - #trvSvc = core.travelService - #return + return \ No newline at end of file diff --git a/src/main/NGECore.java b/src/main/NGECore.java index b714468f..06213f63 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -28,11 +28,13 @@ import java.util.HashMap; import java.util.Map; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; - - - - +import net.engio.mbassy.bus.config.BusConfiguration; import resources.common.RadialOptions; import resources.common.ThreadMonitor; @@ -54,9 +56,11 @@ import services.StaticService; import services.TerrainService; import services.WeatherService; import services.chat.ChatService; +import services.collections.CollectionService; import services.combat.CombatService; import services.command.CombatCommand; import services.command.CommandService; +import services.gcw.FactionService; import services.gcw.GCWService; import services.guild.GuildService; import services.map.MapService; @@ -111,6 +115,7 @@ public class NGECore { public ConnectionService connectionService; public CommandService commandService; public CharacterService characterService; + public FactionService factionService; public ObjectService objectService; public MapService mapService; public UpdateService updateService; @@ -132,6 +137,7 @@ public class NGECore { public SkillModService skillModService; public EquipmentService equipmentService; public TravelService travelService; + public CollectionService collectionService; public EntertainmentService entertainmentService; public WeatherService weatherService; @@ -145,6 +151,8 @@ public class NGECore { private ObjectDatabase creatureODB; private ObjectDatabase mailODB; + + private BusConfiguration eventBusConfig = BusConfiguration.Default(1, new ThreadPoolExecutor(1, 4, 1, TimeUnit.MINUTES, new LinkedBlockingQueue())); public NGECore() { @@ -188,7 +196,8 @@ public class NGECore { characterService = new CharacterService(this); mapService = new MapService(this); travelService = new TravelService(this); - + + factionService = new FactionService(this); objectService = new ObjectService(this); terrainService = new TerrainService(this); updateService = new UpdateService(this); @@ -226,6 +235,7 @@ public class NGECore { zoneDispatch = new NetworkDispatch(this, true); zoneDispatch.addService(connectionService); zoneDispatch.addService(characterService); + zoneDispatch.addService(factionService); zoneDispatch.addService(objectService); zoneDispatch.addService(commandService); zoneDispatch.addService(chatService); @@ -253,9 +263,7 @@ public class NGECore { terrainService.addPlanet(10, "dathomir", "terrain/dathomir.trn", true); terrainService.addPlanet(11, "mustafar", "terrain/mustafar.trn", true); terrainService.addPlanet(12, "kashyyyk_main", "terrain/kashyyyk_main.trn", true); - //terrainService.addPlanet(13, "kaas", "terrain/kaas.trn", true); - //terrainService.addPlanet(14, "taanab", "terrain/taanab.trn", true); - + terrainService.loadClientPois(); // Travel Points travelService.loadTravelPoints(); simulationService = new SimulationService(this); @@ -275,6 +283,9 @@ public class NGECore { gcwService = new GCWService(this); zoneDispatch.addService(gcwService); + + collectionService = new CollectionService(this); + zoneDispatch.addService(collectionService); tradeService = new TradeService(this); zoneDispatch.addService(tradeService); @@ -432,5 +443,10 @@ public class NGECore { public static NGECore getInstance() { return instance; } + + public BusConfiguration getEventBusConfig() { + return eventBusConfig; + } + } diff --git a/src/protocol/swg/objectControllerObjects/ShowFlyText.java b/src/protocol/swg/objectControllerObjects/ShowFlyText.java index b4f73d31..41325368 100644 --- a/src/protocol/swg/objectControllerObjects/ShowFlyText.java +++ b/src/protocol/swg/objectControllerObjects/ShowFlyText.java @@ -38,11 +38,12 @@ public class ShowFlyText extends ObjControllerObject { private int unknownInt2; private String stfFile; private String stfString; - private short unknownShort2; + private short xp; private float scale; private RGB color; private int displayType; private boolean alternativeStructure; + private String customText; public ShowFlyText(long recieverId, long objectId, String stfFile, String stfString, float scale, RGB color, int displayType) { this.recieverId = recieverId; @@ -55,7 +56,7 @@ public class ShowFlyText extends ObjControllerObject { this.alternativeStructure = false; } - public ShowFlyText(long recieverId, long objectId, int unknownInt1, int unknownShort1, int unknownByte1, int unknownInt2, String stfFile, String stfString, int unknownShort2, float scale, RGB color, int displayType) { + public ShowFlyText(long recieverId, long objectId, int unknownInt1, int unknownShort1, int unknownByte1, int unknownInt2, String stfFile, String stfString, String customText, int xp, float scale, RGB color, int displayType) { this.recieverId = recieverId; this.objectId = objectId; this.unknownInt1 = unknownInt1; @@ -64,7 +65,8 @@ public class ShowFlyText extends ObjControllerObject { this.unknownInt2 = unknownInt2; this.stfFile = stfFile; this.stfString = stfString; - this.unknownShort2 = (short) unknownShort2; + this.customText = customText; + this.xp = (short) xp; this.scale = scale; this.color = color; this.alternativeStructure = true; @@ -115,8 +117,8 @@ public class ShowFlyText extends ObjControllerObject { result.putLong(0); result.putLong(0); result.putLong(0); - result.putInt(0); - result.putShort((short) unknownShort2); + result.put(getUnicodeString(customText)); + result.putShort(xp); result.putLong(0); result.putFloat(scale); result.put(color.getBytes()); diff --git a/src/resources/common/Opcodes.java b/src/resources/common/Opcodes.java index 670abfde..7b9b948f 100644 --- a/src/resources/common/Opcodes.java +++ b/src/resources/common/Opcodes.java @@ -55,5 +55,6 @@ public class Opcodes { public static int ClientMfdStatusUpdateMessage = CRC.StringtoCRC("ClientMdfStatusUpdateMessage"); public static int PlayMusicMessage = CRC.StringtoCRC("PlayMusicMessage"); public static int PlanetTravelPointListRequest = 0x96405D4D; + public static int FactionRequestMessage = CRC.StringtoCRC("FactionRequestMessage"); } diff --git a/src/resources/common/Options.java b/src/resources/common/Options.java new file mode 100644 index 00000000..136c7462 --- /dev/null +++ b/src/resources/common/Options.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.common; + +public class Options { + + // Any uncommented ones are confirmed correct for NGE with detailed analysis + + public static int NONE = 0; + public static int SPACE_ATTACKABLE = 1; // Ships that are attackable in space. Includes everything except stations and asteroids so far + public static int USABLE = 2; // Vendors, collections (hand icon) + public static int INSURED = 4; // Unused in NGE + public static int CONVERSABLE = 8; // Conversable on ground / commable in space + //public static int FOLLOWINGWAYPOINT = 16; // Uncertain, could be "frozen" flag or "alert" flag or other. Seen on rare occasions on NPCs + public static int SOCKETED = 32; // Object has sockets + public static int AGGRESSIVE = 64; // Always aggressive no matter what regardless of faction standing. + public static int ATTACKABLE = 128; // Attackable + public static int INVULNERABLE = 256; // No HAM + public static int DISABLED = 512; // Disabled Vehicle + //public static int CRAFTED = 1024; // Wearable TANO objects. Isn't used for WEAOs (weapons), it's just for identifying if a TANO is a wearable probably as that's where this is seen. Also seen on naboo small house deed however... Could also be "crafted items" + public static int QUEST = 2048; // Quest icon + public static int MOUNT = 4096; // Vehicle and creature mounts + public static int SERIAL = 8192; // Has serial number + //public static int UNKNOWN = 16384; // Seen being requested by the client in objcontroller 0x02AB but probably not relevant + public static int PILOT = 32768; // Pilot trainers, chassis dealers + //public static int UNKNOWN = 65536; + //public static int UNKNOWN = 131072; + //public static int UNKNOWN = 262144; + //public static int UNKNOWN = 524288; + //public static int UNKNOWN = 1048576; + //public static int UNKNOWN = 2097152; + //public static int UNKNOWN = 4194304; + public static int STARTER_SHIP = 8388508; // Seen on player scyk fighters, but no others. Could also mean SPACE_OVERT + +} diff --git a/src/resources/common/PvpStatus.java b/src/resources/common/PvpStatus.java index 18365a58..e668ba56 100644 --- a/src/resources/common/PvpStatus.java +++ b/src/resources/common/PvpStatus.java @@ -23,6 +23,7 @@ package resources.common; public class PvpStatus { + public static int None = 0; public static int Attackable = 1; public static int Aggressive = 2; public static int Overt = 4; @@ -30,7 +31,7 @@ public class PvpStatus { public static int Player = 16; public static int Enemy = 32; public static int GoingOvert = 64; - public static int GoingCombatant = 128; + public static int GoingCovert = 128; public static int Dueling = 256; } diff --git a/src/resources/common/collidables/AbstractCollidable.java b/src/resources/common/collidables/AbstractCollidable.java new file mode 100644 index 00000000..dbdeed91 --- /dev/null +++ b/src/resources/common/collidables/AbstractCollidable.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.common.collidables; + +import java.util.Vector; + +import main.NGECore; + +import org.python.core.Py; +import org.python.core.PyObject; + +import engine.resources.objects.SWGObject; +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; + +public abstract class AbstractCollidable { + + private PyObject callback; + public Vector collidedObjects = new Vector(); + private Planet planet; + + public abstract boolean doesCollide(SWGObject obj); + public abstract boolean doesCollide(Point3D position); + + public PyObject getCallback() { + return callback; + } + + public void setCallback(PyObject callback) { + this.callback = callback; + } + + public void addCollidedObject(SWGObject obj) { + collidedObjects.add(obj); + } + + public void removeCollidedObject(SWGObject obj) { + collidedObjects.remove(obj); + } + + public boolean isInCollisionList(SWGObject obj) { + return collidedObjects.contains(obj); + } + + public void doCollisionCheck(SWGObject obj) { + // check if already collided + if(isInCollisionList(obj) && doesCollide(obj)) { + return; + } else if(isInCollisionList(obj) && !doesCollide(obj)) { + removeCollidedObject(obj); + } else if(doesCollide(obj) && !isInCollisionList(obj)) { + addCollidedObject(obj); + if(getCallback() != null) + getCallback().__call__(Py.java2py(NGECore.getInstance()), Py.java2py(obj), Py.java2py(this)); + } + } + + public Planet getPlanet() { + return planet; + } + + public void setPlanet(Planet planet) { + this.planet = planet; + } + +} diff --git a/src/resources/common/collidables/CollidableBox.java b/src/resources/common/collidables/CollidableBox.java new file mode 100644 index 00000000..4fd64080 --- /dev/null +++ b/src/resources/common/collidables/CollidableBox.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.common.collidables; + +public class CollidableBox { + + + +} diff --git a/src/resources/common/collidables/CollidableCircle.java b/src/resources/common/collidables/CollidableCircle.java new file mode 100644 index 00000000..f17cab76 --- /dev/null +++ b/src/resources/common/collidables/CollidableCircle.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.common.collidables; + +import engine.resources.objects.SWGObject; +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; + +public class CollidableCircle extends AbstractCollidable { + + private Point3D center; + private float radius; + // for bh traps + private boolean useYAxis = false; + + public CollidableCircle(Point3D center, float radius, Planet planet) { + this.setCenter(center); + this.setRadius(radius); + this.setPlanet(planet); + } + + public Point3D getCenter() { + return center; + } + + public void setCenter(Point3D center) { + this.center = center; + } + + public float getRadius() { + return radius; + } + + public void setRadius(float radius) { + this.radius = radius; + } + + public boolean isUseYAxis() { + return useYAxis; + } + + public void setUseYAxis(boolean useYAxis) { + this.useYAxis = useYAxis; + } + + @Override + public boolean doesCollide(SWGObject obj) { + Point3D objectPos = obj.getWorldPosition(); + if(useYAxis) { + return center.getDistance(objectPos) <= radius && objectPos.y == center.y; + } else { + return center.getDistance(objectPos) <= radius; + } + } + + @Override + public boolean doesCollide(Point3D position) { + if(useYAxis) { + return center.getDistance(position) <= radius && position.y == center.y; + } else { + return center.getDistance(position) <= radius; + } + } +} diff --git a/src/resources/objects/Buff.java b/src/resources/objects/Buff.java index db19f967..ea55a20e 100644 --- a/src/resources/objects/Buff.java +++ b/src/resources/objects/Buff.java @@ -31,7 +31,6 @@ import main.NGECore; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.buffer.SimpleBufferAllocator; -import resources.common.BuffBuilder; import resources.objects.creature.CreatureObject; import com.sleepycat.persist.model.NotPersistent; @@ -41,7 +40,7 @@ import engine.clientdata.ClientFileManager; import engine.clientdata.visitors.DatatableVisitor; import engine.resources.common.CRC; -@Persistent(version=7) +@Persistent(version=8) public class Buff implements IListObject { @NotPersistent @@ -53,6 +52,7 @@ public class Buff implements IListObject { private long ownerId; private String effect1Name, effect2Name, effect3Name, effect4Name, effect5Name; private float effect1Value, effect2Value, effect3Value, effect4Value, effect5Value; + private String callback; private String particleEffect; private boolean isDebuff; private boolean removeOnDeath; @@ -98,6 +98,7 @@ public class Buff implements IListObject { effect4Value = (Float) visitor.getObject(i, 14); effect5Name = (String) visitor.getObject(i, 15); effect5Value = (Float) visitor.getObject(i, 16); + callback = (String) visitor.getObject(i, 18); particleEffect = (String) visitor.getObject(i, 19); isDebuff = (Boolean) visitor.getObject(i, 22); removeOnDeath = (Integer) visitor.getObject(i, 25) != 0; @@ -266,6 +267,14 @@ public class Buff implements IListObject { public void setEffect5Value(float effect5Value) { this.effect5Value = effect5Value; } + + public String getCallback() { + return callback; + } + + public void setCallback(String callback) { + this.callback = callback; + } public String getParticleEffect() { return particleEffect; diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index ca4c6090..042f12eb 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -97,14 +97,8 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.put(getAsciiString(creature.getStfName())); if (creature.getCustomName() == null) { creature.setCustomName(""); }//Not all CreatureObjects have CustomName (Shuttles) buffer.put(getUnicodeString(creature.getCustomName())); - buffer.putInt(0x000F4240); // unk - String factionCRC = creature.getFaction(); - if(factionCRC == null) - buffer.putInt(0); - else if(factionCRC.equals("neutral")) - buffer.putInt(0); - else - buffer.putInt(CRC.StringtoCRC(factionCRC)); + buffer.putInt(0x000F4240); // volume + buffer.putInt(CRC.StringtoCRC(creature.getFaction())); buffer.putInt(creature.getFactionStatus()); @@ -545,7 +539,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { } - public IoBuffer buildSpeedModDelta(float speed) { + public IoBuffer buildSpeedModBaseDelta(float speed) { IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); buffer.putFloat(speed); @@ -556,6 +550,19 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { return buffer; } + + public IoBuffer buildSpeedModDelta(float speedModifier) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putFloat(speedModifier); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 4, (short) 1, (short) 5, buffer, size + 4); + + return buffer; + + } + public IoBuffer buildTurnRadiusDelta(float turnRadius) { diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index a17ac2b6..b1787033 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -31,8 +31,8 @@ import org.apache.mina.core.buffer.IoBuffer; import protocol.swg.ChatSystemMessage; import protocol.swg.ObjControllerMessage; import protocol.swg.PlayMusicMessage; -import protocol.swg.UpdatePVPStatusMessage; import protocol.swg.UpdatePostureMessage; +import protocol.swg.UpdatePVPStatusMessage; import protocol.swg.objectControllerObjects.Animation; import protocol.swg.objectControllerObjects.Posture; @@ -103,7 +103,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { // CREO6 private byte combatFlag = 0; - private short level = 1; + private short level = -1; private int grantedHealth = 0; private String currentAnimation; private String moodAnimation; @@ -261,7 +261,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } - + + @Override + public int getOptionsBitmask() { + synchronized(objectMutex) { + return optionsBitmask; + } + } + @Override public void setOptionsBitmask(int optionBitmask) { synchronized(objectMutex) { @@ -273,6 +280,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { notifyObservers(optionDelta, true); } + + public void addOption(int option) { + setOptionsBitmask(getOptionsBitmask() & option); + } + + public void removeOption(int option) { + setOptionsBitmask(getOptionsBitmask() |~ option); + } public byte getPosture() { synchronized(objectMutex) { @@ -298,10 +313,8 @@ public class CreatureObject extends TangibleObject implements IPersistent { this.faction = faction; } - IoBuffer factionDelta = messageBuilder.buildFactionDelta(faction); - - notifyObservers(factionDelta, true); - + notifyObservers(messageBuilder.buildFactionDelta(faction), true); + setPvpStatus(0, true); } public int getFactionStatus() { @@ -315,10 +328,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { this.factionStatus = factionStatus; } - IoBuffer factionStatusDelta = messageBuilder.buildFactionStatusDelta(factionStatus); - - notifyObservers(factionStatusDelta, true); - + notifyObservers(messageBuilder.buildFactionStatusDelta(factionStatus), true); } public float getHeight() { @@ -495,7 +505,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { synchronized(objectMutex) { this.speedMultiplierBase = speedMultiplierBase; } - IoBuffer speedDelta = messageBuilder.buildSpeedModDelta(speedMultiplierBase); + IoBuffer speedDelta = messageBuilder.buildSpeedModBaseDelta(speedMultiplierBase); notifyObservers(speedDelta, true); @@ -511,6 +521,9 @@ public class CreatureObject extends TangibleObject implements IPersistent { synchronized(objectMutex) { this.speedMultiplierMod = speedMultiplierMod; } + IoBuffer speedDelta = messageBuilder.buildSpeedModDelta(speedMultiplierMod); + + notifyObservers(speedDelta, true); } public long getListenToId() { @@ -929,26 +942,48 @@ public class CreatureObject extends TangibleObject implements IPersistent { //destination.getSession().write(upm.serialize()); if(destination != getClient()) { - UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); - if (factionStatus == 1 && faction.equals("imperial")) { + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()); + + /* + if (factionStatus == 1 && faction == "imperial") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial); upvpm.setStatus(16); - } else if (factionStatus == 1 && faction.equals("rebel")) { + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); + } + + if (factionStatus == 1 && faction == "rebel") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel); upvpm.setStatus(16); - } else if (factionStatus == 2 && faction.equals("imperial")) { + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); + } + + if (factionStatus == 2 && faction == "imperial") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial); upvpm.setStatus(55); - } else if (factionStatus == 2 && faction.equals("rebel")) { + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(39); + if (getOwnerId() != 0) upvpm.setStatus(295); + } + if (factionStatus == 2 && faction == "rebel") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel); upvpm.setStatus(55); - } else if(getSlottedObject("ghost") != null) { - upvpm.setFaction(CRC.StringtoCRC(faction)); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(39); + if (getOwnerId() != 0) upvpm.setStatus(295); + } + if(factionStatus == 0 && faction == "neutral") { + upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); upvpm.setStatus(16); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); } else { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); - upvpm.setStatus(0); - } + upvpm.setStatus(16); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); + } + */ + destination.getSession().write(upvpm.serialize()); } } @@ -1309,4 +1344,16 @@ public class CreatureObject extends TangibleObject implements IPersistent { + @Override + public void setPvPBitmask(int pvpBitmask) { + super.setPvPBitmask(pvpBitmask); + notifyObservers(new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()), false); + } + + @Override + public void setPvpStatus(int pvpBitmask, boolean add) { + super.setPvpStatus(pvpBitmask, add); + notifyObservers(new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()), false); + } + } diff --git a/src/resources/objects/guild/GuildObject.java b/src/resources/objects/guild/GuildObject.java index 0107ff79..504a10e6 100644 --- a/src/resources/objects/guild/GuildObject.java +++ b/src/resources/objects/guild/GuildObject.java @@ -21,6 +21,7 @@ ******************************************************************************/ package resources.objects.guild; +import java.util.HashMap; import java.util.Map; import java.util.TreeMap; @@ -35,6 +36,7 @@ import resources.guild.Guild; import resources.objects.SWGList; import resources.objects.SWGMap; import resources.objects.SWGMultiMap; +import services.collections.ServerFirst; import com.sleepycat.je.Environment; import com.sleepycat.je.Transaction; @@ -54,7 +56,8 @@ public class GuildObject extends SWGObject implements IPersistent { protected NGECore core; @NotPersistent private GuildMessageBuilder messageBuilder = new GuildMessageBuilder(this); - + + private Map serverFirst = new HashMap(); private Map> zoneMap = new TreeMap>(); @NotPersistent private Transaction txn; @@ -260,6 +263,20 @@ public class GuildObject extends SWGObject implements IPersistent { } } + public Map getServerFirst() { + synchronized(objectMutex) { + return serverFirst; + } + } + + public void addServerFirst(String collectionName, ServerFirst player) { + synchronized(objectMutex) { + if (!serverFirst.containsKey(collectionName)) { + serverFirst.put(collectionName, player); + } + } + } + @Override public void sendBaselines(Client destination) { destination.getSession().write(messageBuilder.buildBaseline3()); diff --git a/src/resources/objects/player/PlayerMessageBuilder.java b/src/resources/objects/player/PlayerMessageBuilder.java index fc89c30b..452acc19 100644 --- a/src/resources/objects/player/PlayerMessageBuilder.java +++ b/src/resources/objects/player/PlayerMessageBuilder.java @@ -22,12 +22,14 @@ package resources.objects.player; import java.nio.ByteOrder; +import java.util.BitSet; import java.util.Map.Entry; import org.apache.mina.core.buffer.IoBuffer; import engine.resources.common.CRC; +import resources.common.StringUtilities; import resources.objects.ObjectMessageBuilder; import resources.objects.waypoint.WaypointObject; @@ -86,46 +88,18 @@ public class PlayerMessageBuilder extends ObjectMessageBuilder { buffer.putInt(getProfData(player.getProfession())); // prof icon buffer.put(getAsciiString(player.getProfession())); - buffer.putInt(0); // unk - buffer.putInt(0); // unk + buffer.putInt(0); // GCW + buffer.putInt(0); // PvP Kills + buffer.putLong(0); // Lifetime GCW + buffer.putInt(0); // Lifetime PvP Kills + buffer.putInt(player.getCollections().length); + buffer.putInt(player.getHighestSetBit()); + buffer.put(player.getCollections()); + buffer.putInt(0); // Unknown, part of one delta, maybe a list + buffer.putInt(0); // Unknown, part of one delta, maybe a list + buffer.put((byte) 0); // Unknown Boolean used in Tansarii + buffer.put((byte) 0); // Unknown Boolean used in Tansarii - byte[] data1 = new byte[] { - - 0x76, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xCF, (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x78, (byte) 0x3E, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x41, (byte) 0x02, (byte) 0x88, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1F, (byte) 0x20, (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x84, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - buffer.put(data1); - byte[] data2 = new byte[] { - - 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xC0, (byte) 0x05, (byte) 0x04, (byte) 0x78, (byte) 0x34, (byte) 0x78, (byte) 0x78, (byte) 0x08, (byte) 0x08, (byte) 0x14, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x20, (byte) 0x81, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0xC0, (byte) 0xFF, (byte) 0xC7, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - buffer.put(data2); - byte[] data3 = new byte[] { - - 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xCB, (byte) 0x32, (byte) 0x06, (byte) 0x18, (byte) 0x60, (byte) 0x0C, (byte) 0x30, (byte) 0x60, (byte) 0x2D, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - buffer.put(data3); - byte[] data4 = new byte[] { - - 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - buffer.put(data4); - byte[] data5 = new byte[] { - - 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xC0, (byte) 0xFF, (byte) 0x1F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xD0, (byte) 0xD5, (byte) 0x68, (byte) 0x00, (byte) 0x1A, (byte) 0x46, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x30, (byte) 0x1A, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x03, (byte) 0xD0, (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - buffer.put(data5); - byte[] data6 = new byte[] { - - 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - buffer.put(data6); - byte[] data7 = new byte[] { - - 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xFF, (byte) 0x3F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x00 - }; - buffer.put(data7); - - int size = buffer.position(); buffer = bufferPool.allocate(size, false).put(buffer.array(), 0, size); @@ -377,6 +351,18 @@ public class PlayerMessageBuilder extends ObjectMessageBuilder { } + public IoBuffer buildCollectionsDelta(byte[] collections, int highestSetBit) { + IoBuffer buffer = bufferPool.allocate(8 + collections.length, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(collections.length); + buffer.putInt(highestSetBit); + for (byte collection : collections) buffer.put(collection); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("PLAY", (byte) 3, (short) 1, (short) 16, buffer, size + 4); + System.out.println(StringUtilities.bytesToHex(buffer.array())); + return buffer; + } + public IoBuffer buildXPListDelta(String type, int amount, boolean alreadyExists) { PlayerObject player = (PlayerObject) object; player.setXpListUpdateCounter(player.getXpListUpdateCounter() + 1); diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index 8e9dcfd0..5b679a34 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -22,9 +22,11 @@ package resources.objects.player; import java.util.ArrayList; +import java.util.BitSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; import resources.objects.waypoint.WaypointObject; @@ -39,7 +41,7 @@ import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; -@Persistent +@Persistent(version=1) public class PlayerObject extends SWGObject { // PLAY 3 @@ -51,6 +53,8 @@ public class PlayerObject extends SWGObject { private List titleList = new ArrayList(); private int bornDate = 0; private int totalPlayTime = 0; + private byte[] collections = new byte[] { }; + private int highestSetBit = 0; // PLAY 6 @@ -116,7 +120,7 @@ public class PlayerObject extends SWGObject { @NotPersistent private long lastPlayTimeUpdate = System.currentTimeMillis(); - + private Map factionStandingMap = new TreeMap(); public PlayerObject() { super(); @@ -136,12 +140,13 @@ public class PlayerObject extends SWGObject { public void setTitle(String title) { synchronized(objectMutex) { - if(!getTitleList().isEmpty() && getTitleList().contains(title)) { this.title = title; - notifyObservers(messageBuilder.buildTitleDelta(title), true); } + } + + notifyObservers(messageBuilder.buildTitleDelta(title), true); } public String getProfession() { @@ -551,7 +556,30 @@ public class PlayerObject extends SWGObject { this.jediState = jediState; } } - + + public Map getFactionStandingMap() { + return factionStandingMap; + } + + public void setFactionStanding(String faction, int factionStanding) { + synchronized(objectMutex) { + factionStandingMap.put(faction, ((factionStanding < -5000) ? -5000 : ((factionStanding > 5000) ? 5000 : factionStanding))); + } + } + + public void modifyFactionStanding(String faction, int modifier) { + synchronized(objectMutex) { + int factionStanding = (((factionStandingMap.containsKey(faction)) ? factionStandingMap.get(faction) : 0) + modifier); + factionStandingMap.put(faction, ((factionStanding < -5000) ? -5000 : ((factionStanding > 5000) ? 5000 : factionStanding))); + } + } + + public int getFactionStanding(String faction) { + synchronized(objectMutex) { + return ((factionStandingMap.containsKey(faction)) ? factionStandingMap.get(faction) : 0); + } + } + @Override public void sendBaselines(Client destination) { @@ -583,9 +611,30 @@ public class PlayerObject extends SWGObject { public List getTitleList() { return titleList; } - + public void setTitleList(List titleList) { this.titleList = titleList; } + public void setCollections(byte[] collections) { + synchronized(objectMutex) { + this.collections = collections; + this.highestSetBit = BitSet.valueOf(collections).length(); + } + + notifyObservers(messageBuilder.buildCollectionsDelta(collections, getHighestSetBit()), true); + } + + public byte[] getCollections() { + synchronized(objectMutex) { + return collections; + } + } + + public int getHighestSetBit() { + synchronized(objectMutex) { + return highestSetBit; + } + } + } diff --git a/src/resources/objects/tangible/TangibleMessageBuilder.java b/src/resources/objects/tangible/TangibleMessageBuilder.java index b15e4bbd..fdb7142b 100644 --- a/src/resources/objects/tangible/TangibleMessageBuilder.java +++ b/src/resources/objects/tangible/TangibleMessageBuilder.java @@ -51,7 +51,7 @@ public class TangibleMessageBuilder extends ObjectMessageBuilder { buffer.put(getUnicodeString(object.getCustomName())); buffer.putInt(object.getVolume()); buffer.putInt(0); - buffer.putInt(0); // unknowns + buffer.putInt(0); // faction vars if(tangible.getCustomization() == null || tangible.getCustomization().length < 1) buffer.putShort((short) 0); @@ -59,12 +59,14 @@ public class TangibleMessageBuilder extends ObjectMessageBuilder { buffer.putShort((short) tangible.getCustomization().length); buffer.put(tangible.getCustomization()); } + + buffer.putInt(0); + buffer.putInt(0); + buffer.putInt(tangible.getOptionsBitmask()); - buffer.putInt(tangible.getIncapTimer()); + buffer.putInt(0); // number of item uses buffer.putInt(tangible.getConditionDamage()); buffer.putInt(tangible.getMaxDamage()); - buffer.putInt(0); - buffer.putInt(0x64); buffer.put((byte) (tangible.isStaticObject() ? 1 : 0)); int size = buffer.position(); @@ -123,6 +125,18 @@ public class TangibleMessageBuilder extends ObjectMessageBuilder { return buffer; } + public IoBuffer buildConditionDamageDelta(int conditionDamage) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(conditionDamage); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("TANO", (byte) 3, (short) 1, (short) 0x0A, buffer, size + 4); + + return buffer; + + } + @Override public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { // TODO Auto-generated method stub diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 4fece110..7a1ae89d 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -29,6 +29,7 @@ import java.util.Vector; import protocol.swg.ObjControllerMessage; import protocol.swg.PlayClientEffectObjectMessage; import protocol.swg.StopClientEffectObjectByLabel; +import protocol.swg.UpdatePVPStatusMessage; import protocol.swg.objectControllerObjects.ShowFlyText; import resources.common.RGB; @@ -48,7 +49,6 @@ import engine.resources.scene.Quaternion; @Persistent public class TangibleObject extends SWGObject { - // TODO: Thread safety protected int incapTimer = 10; @@ -57,9 +57,9 @@ public class TangibleObject extends SWGObject { protected byte[] customization; private List componentCustomizations = new ArrayList(); protected int optionsBitmask = 0; - private int maxDamage = 0; + private int maxDamage = 1000; private boolean staticObject = false; - protected String faction = ""; + protected String faction = "neutral"; // Says you're "Imperial Special Forces" if it's 0 for some reason @NotPersistent private Vector defendersList = new Vector(); // unused in packets but useful for the server @NotPersistent @@ -68,15 +68,20 @@ public class TangibleObject extends SWGObject { private int respawnTime = 0; private Point3D spawnCoordinates = new Point3D(0, 0, 0); + @NotPersistent + private TangibleObject killer = null; + public TangibleObject(long objectID, Planet planet, String template) { super(objectID, planet, new Point3D(0, 0, 0), new Quaternion(1, 0, 1, 0), template); messageBuilder = new TangibleMessageBuilder(this); + if (this.getClass().getSimpleName().equals("TangibleObject")) setIntAttribute("volume", 1); } public TangibleObject(long objectID, Planet planet, String template, Point3D position, Quaternion orientation) { super(objectID, planet, position, orientation, template); messageBuilder = new TangibleMessageBuilder(this); spawnCoordinates = position.clone(); + if (this.getClass().getSimpleName().equals("TangibleObject")) setIntAttribute("volume", 1); } public TangibleObject() { @@ -92,12 +97,20 @@ public class TangibleObject extends SWGObject { this.incapTimer = incapTimer; } - public int getConditionDamage() { + public synchronized int getConditionDamage() { return conditionDamage; } - public void setConditionDamage(int conditionDamage) { + public synchronized void setConditionDamage(int conditionDamage) { + if(conditionDamage < 0) + conditionDamage = 0; + else if(conditionDamage > getMaxDamage()) + conditionDamage = getMaxDamage(); this.conditionDamage = conditionDamage; + notifyObservers(messageBuilder.buildConditionDamageDelta(conditionDamage), false); + if (maxDamage > 0) { + this.setStringAttribute("condition", (maxDamage + "/" + (maxDamage - conditionDamage))); + } } public byte[] getCustomization() { @@ -123,13 +136,15 @@ public class TangibleObject extends SWGObject { public void setOptionsBitmask(int optionsBitmask) { this.optionsBitmask = optionsBitmask; } - + public int getMaxDamage() { return maxDamage; } public void setMaxDamage(int maxDamage) { this.maxDamage = maxDamage; + + this.setStringAttribute("condition", (maxDamage + "/" + (maxDamage - conditionDamage))); } public boolean isStaticObject() { @@ -142,7 +157,7 @@ public class TangibleObject extends SWGObject { public int getPvPBitmask() { synchronized(objectMutex) { - return optionsBitmask; + return pvpBitmask; } } @@ -152,6 +167,24 @@ public class TangibleObject extends SWGObject { } } + public boolean getPvpStatus(int pvpStatus) { + synchronized(objectMutex) { + return ((pvpBitmask & pvpStatus) != 0); + } + } + + public void setPvpStatus(int pvpBitmask, boolean add) { + synchronized(objectMutex) { + if (pvpBitmask != 0) { + if (add) { + this.pvpBitmask |= pvpBitmask; + } else { + this.pvpBitmask &= ~pvpBitmask; + } + } + } + } + public String getFaction() { synchronized(objectMutex) { return faction; @@ -245,15 +278,15 @@ public class TangibleObject extends SWGObject { } } - public void showFlyText(String stfFile, String stfString, int xp, float scale, RGB color, int displayType) { + public void showFlyText(String stfFile, String stfString, String customText, int xp, float scale, RGB color, int displayType) { Set observers = getObservers(); if (getClient() != null) { - getClient().getSession().write((new ObjControllerMessage(0x0000000B, new ShowFlyText(getObjectID(), getObjectID(), 56, 1, 1, -1, stfFile, stfString, xp, scale, color, displayType))).serialize()); + getClient().getSession().write((new ObjControllerMessage(0x0000000B, new ShowFlyText(getObjectID(), getObjectID(), 56, 1, 1, -1, stfFile, stfString, customText, xp, scale, color, displayType))).serialize()); } for (Client client : observers) { - client.getSession().write((new ObjControllerMessage(0x0000000B, new ShowFlyText(client.getParent().getObjectID(), getObjectID(), 56, 1, 1, -1, stfFile, stfString, xp, scale, color, displayType))).serialize()); + client.getSession().write((new ObjControllerMessage(0x0000000B, new ShowFlyText(client.getParent().getObjectID(), getObjectID(), 56, 1, 1, -1, stfFile, stfString, customText, xp, scale, color, displayType))).serialize()); } } @@ -277,6 +310,18 @@ public class TangibleObject extends SWGObject { } } + public TangibleObject getKiller() { + synchronized(objectMutex) { + return killer; + } + } + + public void setKiller(TangibleObject killer) { + synchronized(objectMutex) { + this.killer = killer; + } + } + @Override public void sendBaselines(Client destination) { @@ -291,6 +336,11 @@ public class TangibleObject extends SWGObject { destination.getSession().write(messageBuilder.buildBaseline8()); destination.getSession().write(messageBuilder.buildBaseline9()); + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); + upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); + upvpm.setStatus(1); + destination.getSession().write(upvpm.serialize()); + } diff --git a/src/resources/objects/weapon/WeaponObject.java b/src/resources/objects/weapon/WeaponObject.java index 9f0b8381..368ebb18 100644 --- a/src/resources/objects/weapon/WeaponObject.java +++ b/src/resources/objects/weapon/WeaponObject.java @@ -54,6 +54,7 @@ public class WeaponObject extends SWGObject { public WeaponObject(long objectID, Planet planet, String template) { super(objectID, planet, new Point3D(0, 0, 0), new Quaternion(1, 0, 1, 0), template); messageBuilder = new WeaponMessageBuilder(this); + if (this.getClass().getSimpleName().equals("WeaponObject")) setIntAttribute("volume", 1); calculateRange(); calculateAttackSpeed(); } @@ -61,6 +62,7 @@ public class WeaponObject extends SWGObject { public WeaponObject(long objectID, Planet planet, String template, Point3D position, Quaternion orientation) { super(objectID, planet, position, orientation, template); messageBuilder = new WeaponMessageBuilder(this); + if (this.getClass().getSimpleName().equals("WeaponObject")) setIntAttribute("volume", 1); calculateRange(); calculateAttackSpeed(); } diff --git a/src/services/BuffService.java b/src/services/BuffService.java index c5db3a8e..1c2fd7a0 100644 --- a/src/services/BuffService.java +++ b/src/services/BuffService.java @@ -21,41 +21,22 @@ ******************************************************************************/ package services; -import java.nio.ByteOrder; 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 org.python.core.Py; +import org.python.core.PyObject; - - - - - - - - - - - -import org.apache.mina.core.buffer.IoBuffer; -import org.apache.mina.core.session.IoSession; - -import protocol.swg.ObjControllerMessage; -import protocol.swg.objectControllerObjects.BuffBuilderStartMessage; -import resources.common.Console; import resources.common.FileUtilities; -import resources.common.ObjControllerOpcodes; import resources.objects.Buff; -import resources.objects.BuffItem; import resources.objects.DamageOverTime; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; import resources.objects.player.PlayerObject; import main.NGECore; -import engine.clients.Client; import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; @@ -63,7 +44,7 @@ import engine.resources.service.INetworkRemoteEvent; public class BuffService implements INetworkDispatch { private NGECore core; - private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public BuffService(NGECore core) { this.core = core; @@ -149,10 +130,25 @@ public class BuffService implements INetworkDispatch { } + for (String effect : buff.getParticleEffect().split(",")) { + creature.playEffectObject(effect, buff.getBuffName()); + } + + if (!buff.getCallback().equals("")) { + if (FileUtilities.doesFileExist("scripts/buffs/" + buff.getBuffName() + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/buffs/", buff.getBuffName(), buff.getCallback()); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(core), Py.java2py(creature), Py.java2py(buff)); + } + } + } + return buff; } + @SuppressWarnings("unused") public void removeBuffFromCreature(CreatureObject creature, Buff buff) { if(!creature.getBuffList().contains(buff)) @@ -166,6 +162,10 @@ public class BuffService implements INetworkDispatch { core.scriptService.callScript("scripts/buffs/", "removeBuff", buff.getBuffName(), core, creature, buff); creature.removeBuff(buff); + for (String effect : buff.getParticleEffect().split(",")) { + creature.stopEffectObject(buff.getBuffName()); + } + } diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 7717b4bd..f5fa4608 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -38,6 +38,7 @@ import engine.resources.common.CRC; import engine.resources.container.CreatureContainerPermissions; import engine.resources.container.CreaturePermissions; import engine.resources.database.DatabaseConnection; +import engine.resources.objects.SWGObject; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; import engine.resources.service.INetworkDispatch; @@ -220,6 +221,7 @@ public class CharacterService implements INetworkDispatch { object.setOptionsBitmask(0x80); //object.setPosition(new Point3D(0, 0, 0)); object.setOrientation(new Quaternion(1, 0, 0, 0)); + object.setLevel((short) 1); float luck = (((((float) (core.scriptService.getMethod("scripts/roadmap/", clientCreateCharacter.getProfession(), "getLuck").__call__().asInt()) + (core.scriptService.getMethod("scripts/roadmap/", object.getStfName(), "getLuck").__call__().asInt())) / ((float) 90)) * ((float) object.getLevel())) - ((float) object.getSkillModBase("luck"))); float precision = (((((float) (core.scriptService.getMethod("scripts/roadmap/", clientCreateCharacter.getProfession(), "getPrecision").__call__().asInt()) + (core.scriptService.getMethod("scripts/roadmap/", object.getStfName(), "getPrecision").__call__().asInt())) / ((float) 90)) * ((float) object.getLevel())) - ((float) object.getSkillModBase("precision"))); float strength = (((((float) (core.scriptService.getMethod("scripts/roadmap/", clientCreateCharacter.getProfession(), "getStrength").__call__().asInt()) + (core.scriptService.getMethod("scripts/roadmap/", object.getStfName(), "getStrength").__call__().asInt())) / ((float) 90)) * ((float) object.getLevel())) - ((float) object.getSkillModBase("strength"))); @@ -304,7 +306,7 @@ public class CharacterService implements INetworkDispatch { session.write(core.loginService.getLoginClusterStatus().serialize()); session.write(success.serialize()); - session.write((new ClientMfdStatusUpdateMessage((float) 2, "/GroundHUD.MFDStatus.vsp.role.targetLevel")).serialize()); + session.write((new ClientMfdStatusUpdateMessage((float) 2, "/GroundHUD.MFDStatus.vsp.role.targetLevel")).serialize()); } }); diff --git a/src/services/GroupService.java b/src/services/GroupService.java index 86258f15..0df7fd2c 100644 --- a/src/services/GroupService.java +++ b/src/services/GroupService.java @@ -199,7 +199,7 @@ public class GroupService implements INetworkDispatch { } public void removeGroupBuffs(CreatureObject member) { - for(Buff buff : member.getBuffList().get()) { + for(Buff buff : new ArrayList(member.getBuffList().get())) { if(buff.isGroupBuff() && buff.getGroupBufferId() != member.getObjectID()) { core.buffService.removeBuffFromCreature(member, buff); } diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index dc422aec..453c7945 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -109,6 +109,7 @@ public class PlayerService implements INetworkDispatch { PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); player.setTotalPlayTime(player.getTotalPlayTime() + 30); player.setLastPlayTimeUpdate(System.currentTimeMillis()); + core.collectionService.checkExplorationRegions(creature); } @@ -329,7 +330,7 @@ public class PlayerService implements INetworkDispatch { // 1. Add the experience. if (experience > 0) { - creature.showFlyText("base_player", "prose_flytext_xp", experience, (float) 2.5, new RGB(180, 60, 240), 1); + creature.showFlyText("base_player", "prose_flytext_xp", "", experience, (float) 2.5, new RGB(180, 60, 240), 1); } String xpType = ((player.getProfession().contains("entertainer")) ? "entertainer" : ((player.getProfession().contains("trader")) ? "crafting" : "combat_general")); diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 48197155..35fa7d86 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -68,7 +68,10 @@ import protocol.swg.objectControllerObjects.TargetUpdate; import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; import resources.common.*; +import resources.common.collidables.AbstractCollidable; +import services.ai.LairActor; import toxi.geom.Line3D; import toxi.geom.Ray3D; import toxi.geom.Vec3D; @@ -91,6 +94,9 @@ import wblut.math.WB_M44; public class SimulationService implements INetworkDispatch { Map> quadTrees; + Map> collidableQuadTrees; + + private NGECore core; private Map cellMeshes = new ConcurrentHashMap(); @@ -98,9 +104,11 @@ public class SimulationService implements INetworkDispatch { this.core = core; TerrainService terrainService = core.terrainService; quadTrees = new ConcurrentHashMap>(); + collidableQuadTrees = new ConcurrentHashMap>(); for (int i = 0; i < core.terrainService.getPlanetList().size(); i++) { quadTrees.put(terrainService.getPlanetList().get(i).getName(), new QuadTree(-8192, -8192, 8192, 8192)); + collidableQuadTrees.put(terrainService.getPlanetList().get(i).getName(), new QuadTree(-8192, -8192, 8192, 8192)); } core.commandService.registerCommand("opencontainer"); @@ -135,6 +143,7 @@ public class SimulationService implements INetworkDispatch { core.commandService.registerCommand("boardshuttle"); core.commandService.registerCommand("getplayerid"); core.commandService.registerCommand("inspire"); + core.commandService.registerCommand("setgodmode"); } @@ -146,6 +155,18 @@ public class SimulationService implements INetworkDispatch { } } + public void addCollidable(AbstractCollidable collidable, float x, float y) { + collidableQuadTrees.get(collidable.getPlanet().getName()).put(x, y, collidable); + } + + public void removeCollidable(AbstractCollidable collidable, float x, float y) { + collidableQuadTrees.get(collidable.getPlanet().getName()).remove(x, y, collidable); + } + + public List getCollidables(Planet planet, float x, float y, float range) { + return collidableQuadTrees.get(planet.getName()).get(x, y, range); + } + public void add(SWGObject object, int x, int y) { object.setIsInQuadtree(true); core.objectService.loadServerTemplate(object); @@ -275,7 +296,7 @@ public class SimulationService implements INetworkDispatch { } } - + checkForCollidables(object); } @@ -326,6 +347,8 @@ public class SimulationService implements INetworkDispatch { object.setOrientation(newOrientation); object.setMovementCounter(dataTransform.getMovementCounter()); object.notifyObservers(utm, false); + + checkForCollidables(object); } @@ -466,6 +489,14 @@ public class SimulationService implements INetworkDispatch { if(object.getGroupId() != 0) core.groupService.handleGroupDisband(object); + Point3D objectPos = object.getWorldPosition(); + + List collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 512); + + for(AbstractCollidable collidable : collidables) { + collidables.remove(object); + } + if (ghost != null) { String objectShortName = object.getCustomName(); @@ -515,11 +546,9 @@ public class SimulationService implements INetworkDispatch { CreatureObject object = (CreatureObject) client.getParent(); Quaternion orientation = object.getOrientation(); Point3D position = object.getPosition(); - - Point3D pos = object.getWorldPosition(); - + Collection newAwareObjects = get(object.getPlanet(), pos.x, pos.z, 512); for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { SWGObject obj = it.next(); @@ -533,6 +562,7 @@ public class SimulationService implements INetworkDispatch { if(object.getParentId() == 0) add(object, pos.x, pos.z); + PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); if (ghost != null) { @@ -917,5 +947,14 @@ public class SimulationService implements INetworkDispatch { } } + + public void checkForCollidables(SWGObject object) { + Point3D objectPos = object.getWorldPosition(); + List collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 256); + + for(AbstractCollidable collidable : collidables) { + collidable.doCollisionCheck(object); + } + } } diff --git a/src/services/TerrainService.java b/src/services/TerrainService.java index 789f54f9..eb1c9808 100644 --- a/src/services/TerrainService.java +++ b/src/services/TerrainService.java @@ -26,9 +26,17 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import resources.common.FileUtilities; +import resources.common.collidables.CollidableCircle; + +import engine.clientdata.ClientFileManager; +import engine.clientdata.visitors.DatatableVisitor; import engine.resources.config.Config; +import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; import main.NGECore; @@ -36,13 +44,66 @@ public class TerrainService { private NGECore core; private List planets = Collections.synchronizedList(new ArrayList()); + private Map> noBuildAreas = new ConcurrentHashMap>(); public TerrainService(NGECore core) { - - this.core = core; - + this.core = core; } + public void loadClientPois() { + + try { + + DatatableVisitor poiTable = ClientFileManager.loadFile("datatables/clientpoi/clientpoi.iff", DatatableVisitor.class); + + for (int i = 0; i < poiTable.getRowCount(); i++) { + + Planet planet = getPlanetByName((String) poiTable.getObject(i, 0)); + + if(planet == null) + continue; + + float x = (Float) poiTable.getObject(i, 4); + float z = (Float) poiTable.getObject(i, 6); + + CollidableCircle poiArea = new CollidableCircle(new Point3D(x, 0, z), 150, planet); + noBuildAreas.get(planet).add(poiArea); + + } + + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + + } + + private void loadClientRegions(Planet planet) { + + if(!FileUtilities.doesFileExist("datatables/clientregion/" + planet.getName() + ".iff")) + return; + + try { + + DatatableVisitor regionTable = ClientFileManager.loadFile("datatables/clientpoi/clientpoi.iff", DatatableVisitor.class); + + for (int i = 0; i < regionTable.getRowCount(); i++) { + + float x = (Float) regionTable.getObject(i, 1); + float z = (Float) regionTable.getObject(i, 2); + float radius = (Float) regionTable.getObject(i, 3); + + CollidableCircle region = new CollidableCircle(new Point3D(x, 0, z), radius, planet); + noBuildAreas.get(planet).add(region); + + } + + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + + } + + public boolean isWater(int planetId, float x, float z) { if(getPlanetByID(planetId) == null) @@ -112,6 +173,8 @@ public class TerrainService { Planet planet = new Planet(ID, name, path, loadSnapshot); planets.add(planet); core.mapService.addPlanet(planet); + noBuildAreas.put(planet, new ArrayList()); + loadClientRegions(planet); } @@ -157,6 +220,21 @@ public class TerrainService { } + public boolean canBuildAtPosition(SWGObject object, float x, float z) { + + if(isWater(object.getPlanet(), z, z)) + return false; + + Point3D position = new Point3D(x, 0, z); + + for(CollidableCircle noBuildArea : noBuildAreas.get(object.getPlanet())) { + if(noBuildArea.doesCollide(position)) + return false; + } + + return true; + + } diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java new file mode 100644 index 00000000..bb8efca5 --- /dev/null +++ b/src/services/ai/AIActor.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai; + +import engine.resources.scene.Point3D; +import resources.objects.creature.CreatureObject; +import services.ai.states.AIState; + +public class AIActor { + + private CreatureObject creature; + private Point3D spawnPosition; + private volatile AIState currentState; + private CreatureObject followObject; + + public AIActor(CreatureObject creature, Point3D spawnPosition) { + this.creature = creature; + this.spawnPosition = spawnPosition; + } + + public CreatureObject getCreature() { + return creature; + } + + public void setCreature(CreatureObject creature) { + this.creature = creature; + } + + public Point3D getSpawnPosition() { + return spawnPosition; + } + + public void setSpawnPosition(Point3D spawnPosition) { + this.spawnPosition = spawnPosition; + } + + public void doAggro(CreatureObject defender) { + + } + + public AIState getCurrentState() { + return currentState; + } + + public void setCurrentState(AIState currentState) { + if(currentState == this.currentState) + return; + this.currentState.onExit(); + this.currentState = currentState; + currentState.onEnter(); + } + + public CreatureObject getFollowObject() { + return followObject; + } + + public void setFollowObject(CreatureObject followObject) { + this.followObject = followObject; + } + +} diff --git a/src/services/ai/AIService.java b/src/services/ai/AIService.java new file mode 100644 index 00000000..f55abe6a --- /dev/null +++ b/src/services/ai/AIService.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai; + +import java.util.Vector; + +import engine.resources.scene.Point3D; + +import main.NGECore; + +public class AIService { + + private Vector aiActors = new Vector(); + private NGECore core; + + public AIService(NGECore core) { + this.core = core; + } + + public void spawnCreature(String template, float x, float y, float z) { + spawnCreature(template, new Point3D(x, y, z)); + } + + public void spawnCreature(String template, Point3D position) { + + } + + +} diff --git a/src/services/ai/LairActor.java b/src/services/ai/LairActor.java new file mode 100644 index 00000000..09043e82 --- /dev/null +++ b/src/services/ai/LairActor.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai; + +import java.util.Vector; +import net.engio.mbassy.listener.Handler; +import resources.objects.tangible.TangibleObject; +import services.combat.CombatEvents.DamageTaken; + +public class LairActor { + + private Vector creatures = new Vector(); + private TangibleObject lairObject; + private int maxSpawns; + private String creatureTemplate; + private volatile int spawnWave = 0; + + public LairActor(TangibleObject lairObject, String creatureTemplate) { + this.lairObject = lairObject; + this.creatureTemplate = creatureTemplate; + lairObject.getEventBus().subscribe(this); + } + + public LairActor(TangibleObject lairObject, String creatureTemplate, int maxSpawns) { + this.lairObject = lairObject; + this.creatureTemplate = creatureTemplate; + this.maxSpawns = maxSpawns; + lairObject.getEventBus().subscribe(this); + } + + + public Vector getCreatures() { + return creatures; + } + + public TangibleObject getLairObject() { + return lairObject; + } + + public void setLairObject(TangibleObject lairObject) { + this.lairObject = lairObject; + } + + @Handler + public void handleLairDamageEvent(DamageTaken event) { + + for(AIActor ai : creatures) { + ai.doAggro(event.attacker); + } + + spawnNewCreatures(); + + } + + private void spawnNewCreatures() { + + if(creatures.size() >= maxSpawns) + return; + + int currentCondition = lairObject.getConditionDamage(); + int maxCondition = lairObject.getMaxDamage(); + + switch(spawnWave) { + // TODO: play damage effect + case 0: + spawnWave++; + break; + case 1: + if((currentCondition / maxCondition) < 0.7) { + spawnWave++; + } else { + return; + } + case 2: + if((currentCondition / maxCondition) < 0.3) { + spawnWave++; + } else { + return; + } + break; + case 3: + return; + + default: + return; + + } + + // TODO: spawn creatures + + healLair(); + + } + + private void healLair() { + + if(lairObject.getConditionDamage() == 0 || creatures.isEmpty()) + return; + + int healAmount = 0; + + for(AIActor ai : creatures) { + healAmount += lairObject.getMaxDamage() / 100; + } + + lairObject.setConditionDamage(lairObject.getConditionDamage() - healAmount); + lairObject.playEffectObject("clienteffect/healing_healdamage.cef", "root"); + + } + + public int getMaxSpawns() { + return maxSpawns; + } + + public void setMaxSpawns(int maxSpawns) { + this.maxSpawns = maxSpawns; + } + + public String getCreatureTemplate() { + return creatureTemplate; + } + + public void setCreatureTemplate(String creatureTemplate) { + this.creatureTemplate = creatureTemplate; + } +} diff --git a/src/services/ai/states/AIState.java b/src/services/ai/states/AIState.java new file mode 100644 index 00000000..3da9131c --- /dev/null +++ b/src/services/ai/states/AIState.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +public abstract class AIState { + + public abstract byte onEnter(); + public abstract byte onExit(); + public abstract byte move(); + public abstract byte recover(); + + public enum StateResult {; + + // default error state result + public static final byte NONE = 0; + // finished with state + public static final byte FINISHED = 1; + // unfinished with state, call recover() + public static final byte UNFINISHED = 2; + public static final byte DEAD = 3; + // for deaggro or idling + public static final byte IDLE = 4; + + } + + + +} diff --git a/src/services/ai/states/AttackState.java b/src/services/ai/states/AttackState.java new file mode 100644 index 00000000..fedb6112 --- /dev/null +++ b/src/services/ai/states/AttackState.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +public class AttackState extends AIState { + + @Override + public byte onEnter() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte onExit() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte move() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte recover() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/services/ai/states/DeathState.java b/src/services/ai/states/DeathState.java new file mode 100644 index 00000000..aee6e323 --- /dev/null +++ b/src/services/ai/states/DeathState.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +public class DeathState extends AIState { + + @Override + public byte onEnter() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte onExit() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte move() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte recover() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/services/ai/states/IdleState.java b/src/services/ai/states/IdleState.java new file mode 100644 index 00000000..597630e9 --- /dev/null +++ b/src/services/ai/states/IdleState.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +public class IdleState extends AIState { + + @Override + public byte onEnter() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte onExit() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte move() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte recover() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/services/ai/states/PatrolState.java b/src/services/ai/states/PatrolState.java new file mode 100644 index 00000000..81e4eace --- /dev/null +++ b/src/services/ai/states/PatrolState.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +public class PatrolState extends AIState { + + @Override + public byte onEnter() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte onExit() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte move() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte recover() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/services/ai/states/RetreatState.java b/src/services/ai/states/RetreatState.java new file mode 100644 index 00000000..64e4fa71 --- /dev/null +++ b/src/services/ai/states/RetreatState.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +public class RetreatState extends AIState { + + @Override + public byte onEnter() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte onExit() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte move() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte recover() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/services/ai/states/SpawnState.java b/src/services/ai/states/SpawnState.java new file mode 100644 index 00000000..4d46a557 --- /dev/null +++ b/src/services/ai/states/SpawnState.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +public class SpawnState extends AIState { + + @Override + public byte onEnter() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte onExit() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte move() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte recover() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/services/collections/CollectionService.java b/src/services/collections/CollectionService.java new file mode 100644 index 00000000..d86ee7ad --- /dev/null +++ b/src/services/collections/CollectionService.java @@ -0,0 +1,852 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.collections; + +import java.util.BitSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.python.core.Py; +import org.python.core.PyObject; + +import resources.common.FileUtilities; +import resources.objects.creature.CreatureObject; +import resources.objects.player.PlayerObject; + +import main.NGECore; + +import engine.clientdata.ClientFileManager; +import engine.clientdata.visitors.DatatableVisitor; +import engine.resources.scene.Point3D; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +public class CollectionService implements INetworkDispatch { + + private NGECore core; + + private Map> explorationLocations = new TreeMap>(); + + private class ExplorationRegion { + + public Point3D location; + public float range; + + public ExplorationRegion(Point3D location, float range) { + this.location = location; + this.range = range; + } + + } + + public CollectionService(NGECore core) { + this.core = core; + + if (FileUtilities.doesFileExist("scripts/collections/exploration_badges.py")) { + PyObject method = core.scriptService.getMethod("scripts/collections/", "exploration_badges", "setup"); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(this)); + } + } + } + + /* + * @see datatables/collection/collections.iff + * + * Count and exploration count badges are added automatically. + * + * You can add a new exploration location in scripts/collections + * /exploration_badges.py by defining setup(collectionService) + * and using collectionService.registerExplorationBadge(badge, x, z). + * + * Scripts named collection's slotName or collectionName should be + * put in scripts/collections/ and can use the modify(core, actor, count) + * method upon modification or complete(core, actor, count) on completion. + * + * Please distinguish a slot from a collection. A slot could be + * a type of blacksun ship where you have to kill 25 of them, and a + * collection could be a row of different blacksun ships. + * + * You'll need to choose carefully whether you make a script for the + * collection, or the specific slots, or both. + * + * @param creature The player's CreatureObject instance. + * @param collection slotName of the collection you want to add. + * + * @return True if added successfully. + */ + @SuppressWarnings("unused") + public boolean addCollection(CreatureObject creature, String collection) { + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + DatatableVisitor collectionTable; + + if (player == null) { + return false; + } + + collection = collection.toLowerCase(); + + if (isComplete(creature, collection)) { + return false; + } + + try { + collectionTable = ClientFileManager.loadFile("datatables/collection/collection.iff", DatatableVisitor.class); + BitSet collections; + String bookName = ""; + String pageName = ""; + String collectionName = ""; + boolean titleOnComplete = false; + + collections = BitSet.valueOf(player.getCollections()); + + for (int c = 0; c < collectionTable.getRowCount(); c++) { + if (collectionTable.getObject(c, 0) != null) { + if (((String) collectionTable.getObject(c, 0)) != "") { + bookName = ((String) collectionTable.getObject(c, 0)); + pageName = ""; + collectionName = ""; + titleOnComplete = false; + } else if (((String) collectionTable.getObject(c, 1)) != "") { + pageName = ((String) collectionTable.getObject(c, 1)); + collectionName = ""; + titleOnComplete = false; + } else if (((String) collectionTable.getObject(c, 2)) != "") { + collectionName = ((String) collectionTable.getObject(c, 2)); + titleOnComplete = ((Boolean) collectionTable.getObject(c, 27)); + } else if (((String) collectionTable.getObject(c, 3)) != "") { + String slotName = ((String) collectionTable.getObject(c, 3)); + + if (slotName.equals(collection)) { + int bits = 0; + boolean noScriptOnModify = false; + boolean clearOnComplete = false; + boolean noMessage = true; + boolean grantIfPreReqMet = true; + boolean buddyCollection = false; + int numAltTitles = 0; + int beginSlotId = ((Integer) collectionTable.getObject(c, 4)); + int endSlotId = ((Integer) collectionTable.getObject(c, 5)); + int maxSlotValue = ((Integer) collectionTable.getObject(c, 6)); + String music = ((String) collectionTable.getObject(c, 24)); + boolean hidden = ((Boolean) collectionTable.getObject(c, 26)); + boolean title = ((Boolean) collectionTable.getObject(c, 27)); + boolean noReward = ((Boolean) collectionTable.getObject(c, 33)); + boolean trackServerFirst = ((Boolean) collectionTable.getObject(c, 34)); + + String[] categories = { + ((String) collectionTable.getObject(c, 7)), + ((String) collectionTable.getObject(c, 8)), + ((String) collectionTable.getObject(c, 9)), + ((String) collectionTable.getObject(c, 10)), + ((String) collectionTable.getObject(c, 11)), + ((String) collectionTable.getObject(c, 12)), + ((String) collectionTable.getObject(c, 13)), + ((String) collectionTable.getObject(c, 14)), + ((String) collectionTable.getObject(c, 15)), + ((String) collectionTable.getObject(c, 16)), + ((String) collectionTable.getObject(c, 17)) + }; + + String[] prereqSlotNames = { + ((String) collectionTable.getObject(c, 18)), + ((String) collectionTable.getObject(c, 19)), + ((String) collectionTable.getObject(c, 20)), + ((String) collectionTable.getObject(c, 21)), + ((String) collectionTable.getObject(c, 22)) + }; + + String[] alternateTitles = { + ((String) collectionTable.getObject(c, 28)), + ((String) collectionTable.getObject(c, 29)), + ((String) collectionTable.getObject(c, 30)), + ((String) collectionTable.getObject(c, 31)), + ((String) collectionTable.getObject(c, 32)) + }; + + if (bookName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a book"); + throw new Exception(); + } + + if (pageName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a page"); + throw new Exception(); + } + + if (collectionName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a collection"); + throw new Exception(); + } + + if (endSlotId != -1) { + if (beginSlotId >= endSlotId) { + System.out.println(slotName + ", row " + c + ": begin slot id " + beginSlotId + " must be < end slot id" + endSlotId); + throw new Exception(); + } + + bits = (endSlotId - beginSlotId); + + if (bits > 32) { + System.out.println(slotName + ", row " + c + ": counter-type slot uses " + bits + " bits which exceeds the limit of 32 bits for counter-type slot"); + throw new Exception(); + } + + if (maxSlotValue > -1) { + if (!(maxSlotValue > 1)) { + System.out.println(slotName + ", row " + c + ": max slot value " + maxSlotValue + " must be > 1"); + throw new Exception(); + } + + BitSet bitValue = new BitSet(64); + bitValue.set(64-bits, 64); + + BitSet maxValue = new BitSet(64); + maxValue.set(64-maxSlotValue, 64); + + if (bitValue.toLongArray()[0] < maxValue.toLongArray()[0]) { + System.out.println(slotName + ", row " + c + ": counter-type slot uses " + bits + " bits, which can only hold a max value of " + bitValue.toLongArray()[0] + ", which is less than the specified max value of " + maxValue.toLongArray()[0]); + throw new Exception(); + } + } + } else { + bits = 1; + } + + for (String prereqSlotName : prereqSlotNames) { + if (!prereqSlotName.equals("") && getCollection(creature, prereqSlotName) < 1) { + if (prereqSlotName.equals(slotName)) { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " cannot have itself as a prereq"); + throw new Exception(); + } + + return false; + } + } + + for (String category : categories) { + if (category.equals("noScriptOnModify")) { + noScriptOnModify = true; + } else if (category.equals("clearOnComplete")) { + clearOnComplete = true; + } else if (category.equals("noMessage")) { + noMessage = true; + } else if (category.equals("grantIfPreReqMet")) { + grantIfPreReqMet = true; + } else if (category.equals("buddyCollection")) { + buddyCollection = true; + } else if (category.startsWith("numAltTitles")) { + numAltTitles = new Integer(category.split(":")[1]); + } else if (category.startsWith("kill")) { + continue; + } else if (category.contains("showFullInformationToOthers")) { + continue; + } else if (category.contains("collection")) { + continue; + } else if (category.startsWith("updateOnCount")) { + continue; + } else if (category.equals("rewardOnUpdate")) { + continue; + } else if (category.equals("rewardOnComplete")) { + continue; + } else if (category.contains("relic")) { + break; + } else if (!category.equals("")){ + continue; + } + } + + if (title) { + player.getTitleList().add(slotName); + + if (alternateTitles.length > 0) { + for (String altTitle : alternateTitles) { + if (altTitle != "") { + player.getTitleList().add(altTitle); + } + } + } + } else { + if (numAltTitles > 0 || alternateTitles.length > 0) { + System.out.println(slotName + ": slot " + slotName + " cannot have any alternative titles unless it is defined as \"titleable\""); + } + } + + if (bits > 1) { + int nextBit = collections.get(beginSlotId, (endSlotId + 1)).previousClearBit(endSlotId); + + if (nextBit == -1) { + return false; + } + + collections.set((beginSlotId + nextBit)); + } else { + collections.set(beginSlotId); + } + + player.setCollections(collections.toByteArray()); + + if (!hidden && !noMessage) { + creature.sendSystemMessage("collection_n", collection, 0, 0); + } + + if (!music.equals("")) { + creature.playMusic(music); + } + + if (!noScriptOnModify) { + if (FileUtilities.doesFileExist("scripts/collections/" + slotName + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/collections/", slotName, "modify"); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(core), Py.java2py(creature), Py.java2py(getCollection(creature, slotName))); + } + } + + if (FileUtilities.doesFileExist("scripts/collections/" + collectionName + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/collections/", collectionName, "modify"); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(core), Py.java2py(creature), Py.java2py(getCollection(creature, collectionName))); + } + } + } + + if (isComplete(creature, slotName)) { + if (FileUtilities.doesFileExist("scripts/collections/" + slotName + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/collections/", slotName, "complete"); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(core), Py.java2py(creature), Py.java2py(getCollection(creature, collectionName))); + } + } + } + + if (!isComplete(creature, collectionName)) { + if (!noReward) { + if (FileUtilities.doesFileExist("scripts/collections/" + collectionName + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/collections/", collectionName, "complete"); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(core), Py.java2py(creature), Py.java2py(getCollection(creature, collectionName))); + } + } + } + + if (titleOnComplete) { + player.getTitleList().add(collectionName); + } + + if (trackServerFirst) { + core.guildService.getGuildObject().addServerFirst(collectionName, new ServerFirst(creature.getCustomName(), System.currentTimeMillis())); + } + + if (clearOnComplete) { + if (endSlotId > -1) { + if (collections.get(beginSlotId, (endSlotId + 1)).cardinality() == bits) { + clearCollection(creature, collectionName); + } + } + } + + if (bookName.equals("badge_book")) { + int badges = getCollection(creature, "badge_book"); + + switch (badges) { + case 5: + addCollection(creature, "count_5"); + case 10: + addCollection(creature, "count_10"); + default: + if (((badges % 25) == 0) && !(badges > 500)) { + addCollection(creature, "count_" + badges); + } + } + } + + if (pageName.equals("bdg_explore")) { + int badges = getCollection(creature, "bdg_explore"); + + switch (badges) { + case 10: + addCollection(creature, "bdg_exp_10_badges"); + case 20: + addCollection(creature, "bdg_exp_20_badges"); + case 30: + addCollection(creature, "bdg_exp_30_badges"); + case 40: + addCollection(creature, "bdg_exp_40_badges"); + case 45: + addCollection(creature, "bdg_exp_45_badges"); + } + } + } + + return true; + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return false; + } + + /* + * @param creature The player's CreatureObject instance. + * @param collection slotName or collectionName from collection.iff. + * + * @return True if the slot or collection is complete. + */ + public boolean isComplete(CreatureObject creature, String collection) { + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + DatatableVisitor collectionTable; + + if (player == null) { + return false; + } + + collection = collection.toLowerCase(); + + try { + collectionTable = ClientFileManager.loadFile("datatables/collection/collection.iff", DatatableVisitor.class); + BitSet collections; + String bookName = ""; + String pageName = ""; + String collectionName = ""; + boolean found = false; + boolean collectionComplete = false; + + collections = BitSet.valueOf(player.getCollections()); + + for (int c = 0; c < collectionTable.getRowCount(); c++) { + if (collectionTable.getObject(c, 0) != null) { + if (((String) collectionTable.getObject(c, 0)) != "") { + bookName = ((String) collectionTable.getObject(c, 0)); + pageName = ""; + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 1)) != "") { + pageName = ((String) collectionTable.getObject(c, 1)); + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 2)) != "") { + collectionName = ((String) collectionTable.getObject(c, 2)); + } else if (((String) collectionTable.getObject(c, 3)) != "") { + String slotName = ((String) collectionTable.getObject(c, 3)); + + if (slotName.equals(collection)) { + int beginSlotId = ((Integer) collectionTable.getObject(c, 4)); + + if (bookName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a book"); + throw new Exception(); + } + + if (pageName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a page"); + throw new Exception(); + } + + if (collectionName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a collection"); + throw new Exception(); + } + + if (collection == bookName) { + System.out.println("Checking if a book is complete is unsupported at this time."); + throw new Exception(); + } else if (collection == pageName) { + System.out.println("Checking if a page is complete is unsupported at this time."); + throw new Exception(); + } else if (collection == collectionName) { + collectionComplete = collections.get(beginSlotId); + found = true; + } else if (collection == slotName) { + return collections.get(beginSlotId); + } + + if (found && collectionName != collection) { + return collectionComplete; + } + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return false; + } + + /* + * Returns number of completed bits in a slot or the number of completed + * slots in a collection, page or book. + * + * @param creature The player's CreatureObject instance. + * @param collection slotName, collectionName, pageName or bookName from collection.iff. + * + * @return Number of completed collections within the slot, collection, page or book. + */ + public int getCollection(CreatureObject creature, String collection) { + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + DatatableVisitor collectionTable; + + if (player == null) { + return 0; + } + + collection = collection.toLowerCase(); + + try { + collectionTable = ClientFileManager.loadFile("datatables/collection/collection.iff", DatatableVisitor.class); + BitSet collections; + String bookName = ""; + String pageName = ""; + String collectionName = ""; + int found = 0; + + collections = BitSet.valueOf(player.getCollections()); + + for (int c = 0; c < collectionTable.getRowCount(); c++) { + if (collectionTable.getObject(c, 0) != null) { + if (((String) collectionTable.getObject(c, 0)) != "") { + bookName = ((String) collectionTable.getObject(c, 0)); + pageName = ""; + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 1)) != "") { + pageName = ((String) collectionTable.getObject(c, 1)); + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 2)) != "") { + collectionName = ((String) collectionTable.getObject(c, 2)); + } else if (((String) collectionTable.getObject(c, 3)) != "") { + String slotName = ((String) collectionTable.getObject(c, 3)); + + int beginSlotId = ((Integer) collectionTable.getObject(c, 4)); + int endSlotId = ((Integer) collectionTable.getObject(c, 5)); + int maxSlotValue = ((Integer) collectionTable.getObject(c, 6)); + int bits = 0; + + if (bookName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a book"); + throw new Exception(); + } + + if (pageName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a page"); + throw new Exception(); + } + + if (collectionName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a collection"); + throw new Exception(); + } + + if (collection == bookName) { + found += getCollection(creature, pageName); + continue; + } else if (collection == pageName) { + found += getCollection(creature, collectionName); + continue; + } else if (collection == collectionName) { + if (collections.get(beginSlotId)) { + found++; + } + + continue; + } else if (collection == slotName) { + if (endSlotId != -1) { + if (beginSlotId >= endSlotId) { + System.out.println(slotName + ", row " + c + ": begin slot id " + beginSlotId + " must be < end slot id" + endSlotId); + throw new Exception(); + } + + bits = (endSlotId - beginSlotId); + + if (bits > 32) { + System.out.println(slotName + ", row " + c + ": counter-type slot uses " + bits + " bits which exceeds the limit of 32 bits for counter-type slot"); + throw new Exception(); + } + + if (maxSlotValue > -1) { + if (!(maxSlotValue > 1)) { + System.out.println(slotName + ", row " + c + ": max slot value " + maxSlotValue + " must be > 1"); + throw new Exception(); + } + + BitSet bitValue = new BitSet(64); + bitValue.set(64-bits, 64); + + BitSet maxValue = new BitSet(64); + maxValue.set(64-maxSlotValue, 64); + + if (bitValue.toLongArray()[0] < maxValue.toLongArray()[0]) { + System.out.println(slotName + ", row " + c + ": counter-type slot uses " + bits + " bits, which can only hold a max value of " + bitValue.toLongArray()[0] + ", which is less than the specified max value of " + maxValue.toLongArray()[0]); + throw new Exception(); + } + + return collections.get(beginSlotId, (endSlotId + 1)).cardinality(); + } + } else { + return ((collections.get(beginSlotId)) ? 1 : 0); + } + } + + if (found > 0) { + return found; + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return 0; + } + + /* + * Registers an exploration badge location. + * + * @param planet Name from Planet.getName(). + * @param badgeName slotName from collection.iff. + * @param x The first 2d coordinate. + * @param z The second 2d coordinate. + * @param range The radius from the coordinates at which this will check for players and award them the badge. + */ + public void registerExplorationBadge(String planet, String badgeName, int x, int z, int range) { + if (!explorationLocations.containsKey(planet)) { + explorationLocations.put(planet, new TreeMap()); + } + + explorationLocations.get(planet).put(badgeName, new ExplorationRegion(new Point3D(x, 0, z), range)); + } + + /* + * Checks if the player is in range of any exploration regions + * and grants any ungranted badges. + * + * @param creature The player's CreatreObject instance. + */ + public void checkExplorationRegions(CreatureObject creature) { + String planet = creature.getPlanet().getName(); + + if (explorationLocations.containsKey(planet)) { + for (Entry badge : explorationLocations.get(planet).entrySet()) { + if (creature.inRange(badge.getValue().location, badge.getValue().range)) { + if (!isComplete(creature, badge.getKey())) { + addCollection(creature, badge.getKey()); + } + } + } + } + } + + /* + * Clears the specified slot, collection, page or book. + * + * @param creature The player's CreatureObject instance. + * @param collection slotName, collectionName, pageName or bookName from collection.iff + * + * @return True if successful. + */ + public boolean clearCollection(CreatureObject creature, String collection) { + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + DatatableVisitor collectionTable; + + if (player == null) { + return false; + } + + collection = collection.toLowerCase(); + + try { + collectionTable = ClientFileManager.loadFile("datatables/collection/collection.iff", DatatableVisitor.class); + BitSet collections; + String bookName = ""; + String pageName = ""; + String collectionName = ""; + boolean found = false; + + collections = BitSet.valueOf(player.getCollections()); + + for (int c = 0; c < collectionTable.getRowCount(); c++) { + if (collectionTable.getObject(c, 0) != null) { + if (((String) collectionTable.getObject(c, 0)) != "") { + bookName = ((String) collectionTable.getObject(c, 0)); + pageName = ""; + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 1)) != "") { + pageName = ((String) collectionTable.getObject(c, 1)); + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 2)) != "") { + collectionName = ((String) collectionTable.getObject(c, 2)); + } else if (((String) collectionTable.getObject(c, 3)) != "") { + String slotName = ((String) collectionTable.getObject(c, 3)); + + int beginSlotId = ((Integer) collectionTable.getObject(c, 4)); + int endSlotId = ((Integer) collectionTable.getObject(c, 5)); + + if (bookName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a book"); + throw new Exception(); + } + + if (pageName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a page"); + throw new Exception(); + } + + if (collectionName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a collection"); + throw new Exception(); + } + + if (collection == bookName || collection == pageName || + collection == collectionName || collection == slotName) { + found = true; + + if (collections.get(beginSlotId, endSlotId + 1).cardinality() > 0) { + collections.clear(beginSlotId, (endSlotId + 1)); + + if (player.getTitleList().contains(slotName)) { + player.getTitleList().remove(slotName); + } + + continue; + } + } + + if (found) { + player.setCollections(collections.toByteArray()); + return true; + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return false; + } + + /* + * Clears all collections. + * + * This must cycle through all the collections because + * it needs to remove titles and other such things. + * + * @param creature The player's CreatureObject instance. + * + * @return True if successful. + */ + public boolean clearCollections(CreatureObject creature) { + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + DatatableVisitor collectionTable; + + if (player == null) { + return false; + } + + try { + collectionTable = ClientFileManager.loadFile("datatables/collection/collection.iff", DatatableVisitor.class); + BitSet collections; + String bookName = ""; + String pageName = ""; + String collectionName = ""; + boolean found = false; + + collections = BitSet.valueOf(player.getCollections()); + + for (int c = 0; c < collectionTable.getRowCount(); c++) { + if (collectionTable.getObject(c, 0) != null) { + if (((String) collectionTable.getObject(c, 0)) != "") { + bookName = ((String) collectionTable.getObject(c, 0)); + pageName = ""; + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 1)) != "") { + pageName = ((String) collectionTable.getObject(c, 1)); + collectionName = ""; + } else if (((String) collectionTable.getObject(c, 2)) != "") { + collectionName = ((String) collectionTable.getObject(c, 2)); + } else if (((String) collectionTable.getObject(c, 3)) != "") { + String slotName = ((String) collectionTable.getObject(c, 3)); + + int beginSlotId = ((Integer) collectionTable.getObject(c, 4)); + int endSlotId = ((Integer) collectionTable.getObject(c, 5)); + + if (bookName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a book"); + throw new Exception(); + } + + if (pageName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a page"); + throw new Exception(); + } + + if (collectionName == "") { + System.out.println(slotName + ", row " + c + ": slot " + slotName + " must be in a collection"); + throw new Exception(); + } + + if (collections.get(beginSlotId, endSlotId + 1).cardinality() > 0) { + found = true; + + collections.clear(beginSlotId, (endSlotId + 1)); + + if (player.getTitleList().contains(slotName)) { + player.getTitleList().remove(slotName); + } + + continue; + } + + if (found) { + player.setCollections(collections.toByteArray()); + return true; + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return ((player.getCollections().length > 0) ? false : true); + } + + @Override + public void insertOpcodes(Map arg0, Map arg1) { + + } + + @Override + public void shutdown() { + + } + +} diff --git a/src/services/collections/ServerFirst.java b/src/services/collections/ServerFirst.java new file mode 100644 index 00000000..a11a01f6 --- /dev/null +++ b/src/services/collections/ServerFirst.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.collections; + +import resources.objects.ListObject; + +import com.sleepycat.persist.model.Persistent; + +@Persistent +public class ServerFirst extends ListObject { + + private String name; + private long time; + + public ServerFirst(String name, long time) { + this.name = name; + this.time = time; + } + + public ServerFirst() { + + } + + public String getName() { + return name; + } + + public long getTime() { + return time; + } + + @Override + public byte[] getBytes() { + return new byte[] { }; + } + +} diff --git a/src/services/combat/CombatCommands.java b/src/services/combat/CombatCommands.java index 4c199d95..7ba5c596 100644 --- a/src/services/combat/CombatCommands.java +++ b/src/services/combat/CombatCommands.java @@ -519,6 +519,12 @@ public class CombatCommands { core.commandService.registerCommand("of_purge_1"); core.commandService.registerCommand("of_scatter_1"); core.commandService.registerCommand("of_stimulator_1"); + core.commandService.registerCommand("of_tactical_sup_1"); + core.commandService.registerCommand("of_tactical_sup_2"); + core.commandService.registerCommand("of_tactical_sup_3"); + core.commandService.registerCommand("of_tactical_sup_4"); + core.commandService.registerCommand("of_tactical_sup_5"); + core.commandService.registerCommand("of_tactical_sup_6"); // Smuggler diff --git a/src/services/combat/CombatEvents.java b/src/services/combat/CombatEvents.java new file mode 100644 index 00000000..f41a0098 --- /dev/null +++ b/src/services/combat/CombatEvents.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.combat; + +import resources.objects.creature.CreatureObject; +import engine.resources.common.Event; + +public class CombatEvents implements Event { + + public class DamageTaken implements Event { + + public CreatureObject attacker; + + } + +} diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index 305b2581..06a84ce2 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -48,6 +48,7 @@ import resources.objects.player.PlayerObject; import resources.objects.tangible.TangibleObject; import resources.objects.waypoint.WaypointObject; import resources.objects.weapon.WeaponObject; +import services.combat.CombatEvents.DamageTaken; import services.command.CombatCommand; import services.sui.SUIService.MessageBoxType; import services.sui.SUIWindow; @@ -64,6 +65,7 @@ public class CombatService implements INetworkDispatch { private NGECore core; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private CombatEvents events = new CombatEvents(); public CombatService(NGECore core) { this.core = core; @@ -240,8 +242,24 @@ public class CombatService implements INetworkDispatch { } float damage = calculateDamage(attacker, target, weapon, command); + + if(damage > 0) + applyDamage(attacker, target, (int) damage); + + sendCombatPackets(attacker, target, weapon, command, actionCounter, damage, 0, HitType.HIT); + + if(FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py")) + core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "run", core, attacker, target, null); + } + private void applyDamage(CreatureObject attacker, TangibleObject target, int damage) { + target.setConditionDamage(target.getConditionDamage() + damage); + DamageTaken event = events.new DamageTaken(); + event.attacker = attacker; + target.getEventBus().publish(event); + } + private void doAreaCombat(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { float x = attacker.getWorldPosition().x; @@ -322,7 +340,7 @@ public class CombatService implements INetworkDispatch { int armorAbsorbed = (int) (damageBeforeArmor - damage); if(mitigationType == HitType.BLOCK) { - float blockValue = (attacker.getStrength() + attacker.getSkillMod("combat_block_value").getBase()) / 2 + 25; + float blockValue = (attacker.getStrength() + attacker.getSkillModBase("combat_block_value")) / 2 + 25; damage -= blockValue; } @@ -358,7 +376,7 @@ public class CombatService implements INetworkDispatch { } - private void sendCombatPackets(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter, float damage, int armorAbsorbed, int hitType) { + private void sendCombatPackets(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter, float damage, int armorAbsorbed, int hitType) { String animationStr = command.getRandomAnimation(weapon); @@ -487,8 +505,7 @@ public class CombatService implements INetworkDispatch { if(actionCost == 0 && healthCost == 0) return true; - if(attacker.getSkillMod("expertise_action_all") != null) - actionCost *= attacker.getSkillMod("expertise_action_all").getBase(); + actionCost *= getWeaponActionCostReduction(attacker, weapon); float newAction = attacker.getAction() - actionCost; if(newAction <= 0) @@ -566,6 +583,8 @@ public class CombatService implements INetworkDispatch { } + rawDamage *= getWeaponDamageIncrease(attacker, weapon); + if(target.getSkillMod("damage_decrease_percentage") != null) { rawDamage *= (1 - (target.getSkillMod("damage_decrease_percentage").getBase() / 100)); } @@ -573,11 +592,7 @@ public class CombatService implements INetworkDispatch { if(target.getSkillMod("combat_divide_damage_dealt") != null) { rawDamage *= (1 - (target.getSkillMod("combat_divide_damage_dealt").getBase() / 100)); } - - if(attacker.getSkillMod("expertise_damage_melee") != null) { - rawDamage *= (1 + (attacker.getSkillMod("expertise_damage_melee").getBase() / 100)); - } - + return rawDamage; } @@ -701,7 +716,7 @@ public class CombatService implements INetworkDispatch { float r; Random random = new Random(); - float blockChance = (float) target.getSkillMod("display_only_block").getBase() / 10000; + float blockChance = (float) target.getSkillModBase("display_only_block") / 10000; r = random.nextFloat(); if(r <= blockChance) @@ -709,7 +724,7 @@ public class CombatService implements INetworkDispatch { if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3) { - float evasionChance = (float) target.getSkillMod("display_only_evasion").getBase() / 10000; + float evasionChance = (float) target.getSkillModBase("display_only_evasion") / 10000; r = random.nextFloat(); if(r <= evasionChance) @@ -719,7 +734,7 @@ public class CombatService implements INetworkDispatch { if(hitType == HitType.HIT && target.getSkillMod("display_only_glancing_blow") != null) { - float glanceChance = (float) target.getSkillMod("display_only_glancing_blow").getBase() / 10000; + float glanceChance = (float) target.getSkillModBase("display_only_glancing_blow") / 10000; r = random.nextFloat(); if(r <= glanceChance) @@ -1248,7 +1263,68 @@ public class CombatService implements INetworkDispatch { target.notifyObservers(new PlayClientEffectLocMessage("appearance/pt_heal_2.prt", target.getPlanet().getName(), target.getWorldPosition()), true); - } + } + + public float getWeaponActionCostReduction(CreatureObject attacker, WeaponObject weapon) { + + int weaponType = weapon.getWeaponType(); + int actionReduction; + + switch(weaponType) { + + case 0: actionReduction = attacker.getSkillModBase("expertise_action_weapon_0"); + case 1: actionReduction = attacker.getSkillModBase("expertise_action_weapon_1"); + case 2: actionReduction = attacker.getSkillModBase("expertise_action_weapon_2"); + case 4: actionReduction = attacker.getSkillModBase("expertise_action_weapon_4"); + case 5: actionReduction = attacker.getSkillModBase("expertise_action_weapon_5"); + case 6: actionReduction = attacker.getSkillModBase("expertise_action_weapon_6"); + case 7: actionReduction = attacker.getSkillModBase("expertise_action_weapon_7"); + case 8: actionReduction = attacker.getSkillModBase("expertise_action_weapon_8"); + case 9: actionReduction = attacker.getSkillModBase("expertise_action_weapon_9"); + case 10: actionReduction = attacker.getSkillModBase("expertise_action_weapon_10"); + case 11: actionReduction = attacker.getSkillModBase("expertise_action_weapon_11"); + case 12: actionReduction = attacker.getSkillModBase("expertise_action_weapon_3"); + + default: actionReduction = 0; + + } + + actionReduction += attacker.getSkillModBase("expertise_action_all"); + + return 1 + (actionReduction / 100); + + } + + public float getWeaponDamageIncrease(CreatureObject attacker, WeaponObject weapon) { + + int weaponType = weapon.getWeaponType(); + int weaponDmgIncrease; + + switch(weaponType) { + + case 0: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_0"); + case 1: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_1"); + case 2: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_2"); + case 4: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_4"); + case 5: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_5"); + case 6: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_6"); + case 7: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_7"); + case 8: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_8"); + case 9: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_9"); + case 10: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_10"); + case 11: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_11"); + case 12: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_3"); + + default: weaponDmgIncrease = 0; + + } + + weaponDmgIncrease += attacker.getSkillModBase("expertise_damage_all"); + + + return 1 + (weaponDmgIncrease / 100); + + } public enum HitType{; diff --git a/src/services/gcw/FactionService.java b/src/services/gcw/FactionService.java new file mode 100644 index 00000000..5792f2cd --- /dev/null +++ b/src/services/gcw/FactionService.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.gcw; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import main.NGECore; + +import org.apache.mina.core.buffer.IoBuffer; +import org.apache.mina.core.session.IoSession; +import org.python.core.Py; +import org.python.core.PyObject; + +import resources.common.FileUtilities; +import resources.common.Opcodes; +import resources.objects.creature.CreatureObject; +import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; + +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; + +public class FactionService implements INetworkDispatch { + + private NGECore core; + + private Map factionMap = new TreeMap(); + + public FactionService(NGECore core) { + DatatableVisitor factionTable; + + this.core = core; + + try { + factionTable = ClientFileManager.loadFile("strings/en/faction/faction_names.stf", DatatableVisitor.class); + + for (int s = 0; s < factionTable.getRowCount(); s++) { + if (factionTable.getObject(s, 0) != null) { + String faction = ((String) factionTable.getObject(s, 1)); + factionMap.put(faction, CRC.StringtoCRC(faction)); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public int getCRC(String faction) { + return CRC.StringtoCRC(faction); + } + + public String getName(int factionCrc) { + for (Entry entry : factionMap.entrySet()) { + if (factionCrc == entry.getValue()) { + return entry.getKey(); + } + } + + return ""; + } + + public void addFactionStanding(CreatureObject creature, String faction, int factionStanding) { + if (creature == null) { + return; + } + + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + + if (player == null) { + return; + } + + player.modifyFactionStanding(faction, factionStanding); + } + + public void removeFactionStanding(CreatureObject creature, String faction, int factionStanding) { + if (creature == null) { + return; + } + + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + + if (player == null) { + return; + } + + player.modifyFactionStanding(faction, factionStanding); + } + + public void updateFactionStanding(SWGObject killedObject) { + if (!(killedObject instanceof TangibleObject) || killedObject == null) { + return; + } + + TangibleObject target = (TangibleObject) killedObject; + + if (!(((TangibleObject) killedObject).getKiller() instanceof TangibleObject) || ((TangibleObject) killedObject).getKiller() == null) { + return; + } + + TangibleObject killer = ((TangibleObject) killedObject).getKiller(); + + if (killer != null && target != null && isFaction(target.getFaction())) { + if (FileUtilities.doesFileExist("scripts/faction/standing/" + target.getFaction() + ".py")) { + + PyObject method = core.scriptService.getMethod("scripts/faction/standing/", target.getFaction(), "update"); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(core), Py.java2py(killer), Py.java2py(target)); + } + } + } + } + + public boolean isFaction(String faction) { + if (factionMap.containsKey(faction)) { + return true; + } + + return false; + } + + public Map getFactionMap() { + return factionMap; + } + + @Override + public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { + + swgOpcodes.put(Opcodes.FactionRequestMessage, new INetworkRemoteEvent() { + + @Override + public void handlePacket(IoSession session, IoBuffer buffer) throws Exception { + + } + + }); + } + + @Override + public void shutdown() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 87f7ed73..77921de4 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -134,7 +134,7 @@ public class ObjectService implements INetworkDispatch { } } - public SWGObject createObject(String Template, long objectID, Planet planet, Point3D position, Quaternion orientation) { + public SWGObject createObject(String Template, long objectID, Planet planet, Point3D position, Quaternion orientation, String customServerTemplate) { SWGObject object = null; CrcStringTableVisitor crcTable; try { @@ -211,17 +211,51 @@ public class ObjectService implements INetworkDispatch { } object.setPlanetId(planet.getID()); + + object.setAttachment("serverTemplate", ((customServerTemplate != null) ? customServerTemplate : object.getTemplate())); + object.setisInSnapshot(isSnapshot); //loadServerTemplate(object); objectList.put(objectID, object); - + + // Set Default Tangible Options + /* + if (Template.startsWith("object/creature/") || Template.startsWith("object/mobile/")) { + ((CreatureObject) object).setOptionsBitmask(Options.MOBILE); + + if (Template.startsWith("object/mobile/beast_master/")) { + ((CreatureObject) object).setOptionsBitmask(Options.NONE); + } else if (Template.startsWith("object/mobile/vendor/")) { + ((CreatureObject) object).setOptionsBitmask(Options.INVULNERABLE | Options.USABLE); + } else if (Template.startsWith("object/mobile/vehicle/")) { + ((CreatureObject) object).addOption(Options.INVULNERABLE | Options.MOUNT); + } else if (Template.startsWith("object/mobile/hologram/")) { + ((CreatureObject) object).addOption(Options.INVULNERABLE); + } else if (Template.startsWith("object/creature/npc/theme_park/")) { + ((CreatureObject) object).addOption(Options.INVULNERABLE); + } else if (Template.startsWith("object/creature/general/")) { + ((CreatureObject) object).setOptionsBitmask(Options.INVULNERABLE | Options.CONVERSABLE); + } else if (Template.startsWith("object/creature/droid/")) { + ((CreatureObject) object).addOption(Options.INVULNERABLE); + } + } else if (object instanceof TangibleObject) { + ((TangibleObject) object).setOptionsBitmask(Options.INVULNERABLE); + + if (Template.startsWith("object/tangible/vendor/")) { + ((CreatureObject) object).addOption(Options.USABLE); + } else if (Template.startsWith("object/creature/droid/")) { + ((CreatureObject) object).addOption(Options.INVULNERABLE); + } + } + */ + return object; } public void loadServerTemplate(SWGObject object) { - String template = object.getTemplate(); + String template = ((object.getAttachment("serverTemplate") == null) ? object.getTemplate() : ((String) object.getAttachment("serverTemplate"))); String serverTemplate = template.replace(".iff", ""); // check if template is empty(4 default lines) to reduce RAM usage(saves about 500 MB of RAM) try { @@ -254,6 +288,10 @@ public class ObjectService implements INetworkDispatch { return createObject(Template, 0, planet, new Point3D(x, y, z), new Quaternion(1, 0, 0, 0)); } + public SWGObject createObject(String Template, long objectID, Planet planet, Point3D position, Quaternion orientation) { + return createObject(Template, objectID, planet, position, orientation, null); + } + public void addObjectToScene(SWGObject object) { core.simulationService.add(object, object.getPosition().x, object.getPosition().z); @@ -311,6 +349,18 @@ public class ObjectService implements INetworkDispatch { } } + if (object instanceof CreatureObject) { + if (core.factionService.getFactionMap().containsKey(((CreatureObject) object).getFaction())) { + if (FileUtilities.doesFileExist(filePath)) { + PyObject method = core.scriptService.getMethod("scripts/" + object.getTemplate().split("shared_" , 2)[0].replace("shared_", ""), object.getTemplate().split("shared_" , 2)[1].replace(".iff", ""), "destroy"); + + if (method != null && method.isCallable()) { + method.__call__(Py.java2py(core), Py.java2py(((TangibleObject) object).getKiller()), Py.java2py(object)); + } + } + } + } + if (object == null) { return; } @@ -388,7 +438,7 @@ public class ObjectService implements INetworkDispatch { } catch (SQLException e) { e.printStackTrace(); } - if(getObject(newId) == null) + if(getObject(newId) == null && getCreatureFromDB(newId) == null) return newId; else return generateObjectID(); @@ -520,6 +570,7 @@ public class ObjectService implements INetworkDispatch { }); + /* objControllerOpcodes.put(ObjControllerOpcodes.USE_OBJECT, new INetworkRemoteEvent() { @Override @@ -543,6 +594,7 @@ public class ObjectService implements INetworkDispatch { } }); + */ } diff --git a/src/services/spawn/DynamicSpawnArea.java b/src/services/spawn/DynamicSpawnArea.java new file mode 100644 index 00000000..09aafcd3 --- /dev/null +++ b/src/services/spawn/DynamicSpawnArea.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.spawn; + +public class DynamicSpawnArea extends SpawnArea { + +} diff --git a/src/services/spawn/LairSpawnArea.java b/src/services/spawn/LairSpawnArea.java new file mode 100644 index 00000000..63dc0200 --- /dev/null +++ b/src/services/spawn/LairSpawnArea.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.spawn; + +public class LairSpawnArea extends SpawnArea { + +} diff --git a/src/services/spawn/SpawnArea.java b/src/services/spawn/SpawnArea.java new file mode 100644 index 00000000..342749a5 --- /dev/null +++ b/src/services/spawn/SpawnArea.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.spawn; + +import engine.resources.scene.Planet; + +public abstract class SpawnArea { + + private Planet planet; + + public Planet getPlanet() { + return planet; + } + + public void setPlanet(Planet planet) { + this.planet = planet; + } + +} diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java new file mode 100644 index 00000000..7c6435e3 --- /dev/null +++ b/src/services/spawn/SpawnService.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.spawn; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import engine.resources.scene.Planet; +import main.NGECore; + +public class SpawnService { + + private NGECore core; + private Map> spawnAreas = new ConcurrentHashMap>(); + + public SpawnService(NGECore core) { + + } + +} diff --git a/src/services/spawn/StaticSpawnArea.java b/src/services/spawn/StaticSpawnArea.java new file mode 100644 index 00000000..9a0911fd --- /dev/null +++ b/src/services/spawn/StaticSpawnArea.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.spawn; + +public class StaticSpawnArea extends SpawnArea { + +}