diff --git a/nge.backup b/nge.backup index 049637b4..7e15eff9 100644 Binary files a/nge.backup and b/nge.backup differ diff --git a/ngengine_public.jar b/ngengine_public.jar index 71e72b65..58350bf8 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/odb/creature/je.info.0.1 b/odb/creature/je.info.0.1 new file mode 100644 index 00000000..e69de29b diff --git a/scripts/commands/bandflourish.py b/scripts/commands/bandflourish.py new file mode 100644 index 00000000..e30daa8f --- /dev/null +++ b/scripts/commands/bandflourish.py @@ -0,0 +1,57 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + + if len(commandString) <= 0: + actor.sendSystemMessage('@performance:flourish_not_valid', 0) + return + + if commandString == 'on': + actor.setAcceptBandflourishes(1) + actor.sendSystemMessage('@performance:band_flourish_status_on', 0) + return + if commandString == 'off': + actor.setAcceptBandflourishes(0) + actor.sendSystemMessage('@performance:band_flourish_status_off', 0) + return + + try: + flourish = int(commandString) + except ValueError: + actor.sendSystemMessage('@performance:flourish_not_valid', 0) + return + + if flourish < 1 or flourish > 9: + actor.sendSystemMessage('@performance:flourish_not_valid', 0) + return + + if actor.getPerformanceId() <= 0: + actor.sendSystemMessage('@performance:flourish_not_performing', 0) + return + + animation = 'skill_action_' + str(flourish) + if flourish == 9: + animation = 'mistake' + + if actor.getAcceptBandflourishes(): + actor.sendSystemMessage('@performance:flourish_perform_band_self', 0) + actor.sendSystemMessage('@performance:flourish_perform', 0) + actor.doSkillAnimation(animation) + + group = core.objectService.getObject(actor.getGroupId()) + if not group: + return + + for creature in group.getMemberList(): + if creature == actor: + continue + if creature.getAcceptBandflourishes(): + creature.sendSystemMessage('@performance:flourish_perform_band_member', 0) + creature.sendSystemMessage('@performance:flourish_perform', 0) + creature.doSkillAnimation(animation) + return + + diff --git a/scripts/commands/findfriend.py b/scripts/commands/findfriend.py new file mode 100644 index 00000000..992efa35 --- /dev/null +++ b/scripts/commands/findfriend.py @@ -0,0 +1,18 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + ghost = actor.getSlottedObject('ghost') + friend = commandString.split(' ')[0] + + if ghost.getFriendList().contains(friend): + friendObj = core.chatService.getObjectByFirstName(friend) + if friendObj is not None: + if friendObj.getSlottedObject('ghost').getFriendList().contains(actor.getCustomName().lower().split(' ')[0]): + fPos = friendObj.getPosition() + core.commandService.callCommand(actor, 'waypoint', None, friendObj.getPlanet().name + ' ' + str(fPos.x) + ' ' + str(fPos.z) + ' ' + str(fPos.y) + ' blue ' + friendObj.getCustomName()) + return + return + return \ No newline at end of file diff --git a/scripts/commands/flourish.py b/scripts/commands/flourish.py new file mode 100644 index 00000000..0bb6cb93 --- /dev/null +++ b/scripts/commands/flourish.py @@ -0,0 +1,31 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + + if len(commandString) <= 0: + actor.sendSystemMessage('@performance:flourish_not_valid', 0) + return + + try: + flourish = int(commandString) + except ValueError: + actor.sendSystemMessage('@performance:flourish_not_valid', 0) + return + + if flourish < 1 or flourish > 9: + actor.sendSystemMessage('@performance:flourish_not_valid', 0) + return + + if actor.getPerformanceId() <= 0: + actor.sendSystemMessage('@performance:flourish_not_performing', 0) + return + + actor.sendSystemMessage('@performance:flourish_perform', 0) + animation = 'skill_action_' + str(flourish) + if flourish == 9: + animation = 'mistake' + + actor.doSkillAnimation(animation) diff --git a/scripts/commands/groupdance.py b/scripts/commands/groupdance.py new file mode 100644 index 00000000..ed38ed89 --- /dev/null +++ b/scripts/commands/groupdance.py @@ -0,0 +1,11 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + + newState = actor.toggleGroupDance() + msg = '@performance:dance_group_on' if newState else '@performance:dance_group_off' + actor.sendSystemMessage(msg, 0) + return diff --git a/scripts/commands/of_medical_sup_1.py b/scripts/commands/of_medical_sup_1.py new file mode 100644 index 00000000..b7186ab6 --- /dev/null +++ b/scripts/commands/of_medical_sup_1.py @@ -0,0 +1,52 @@ +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): + actor.sendSystemMessage('Stims incoming Mr. Bossman!', 0) + 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/drum/shared_supply_drop_crate.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') + + group = core.objectService.getObject(actor.getGroupId()) + + permissions = StaticContainerPermissions() + permissions.canRemove(group, crate) + permissions.canView(group, crate) + crate.setContainerPermissions(permissions) + + if actor.hasSkill('expertise_of_tactical_sup_1'): + for i in range(0, 8): + tactical = core.objectService.createObject('object/tangible/loot/generic_usable/shared_stim_syringe_generic.iff', actor.getPlanet()) #FIXME: Use the correct template + tactical.setCustomName('Tactical Serum A') + crate.add(tactical) + + for i in range(0, 8): + stimpack = core.objectService.createObject('object/tangible/medicine/instant_stimpack/shared_stimpack_e.iff', actor.getPlanet()) #FIXME: Use the correct template + stimpack.setCustomName('Field Stimpack A') + crate.add(stimpack) + + time.sleep(60) + core.objectService.destroyObject(crate) + + 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 deleted file mode 100644 index 7ec7b103..00000000 --- a/scripts/commands/of_tactical_sup_1.py +++ /dev/null @@ -1,72 +0,0 @@ -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 deleted file mode 100644 index 76c7b5aa..00000000 --- a/scripts/commands/of_tactical_sup_2.py +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 76c7b5aa..00000000 --- a/scripts/commands/of_tactical_sup_3.py +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 76c7b5aa..00000000 --- a/scripts/commands/of_tactical_sup_4.py +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 76c7b5aa..00000000 --- a/scripts/commands/of_tactical_sup_5.py +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index ec8f96db..00000000 --- a/scripts/commands/of_tactical_sup_6.py +++ /dev/null @@ -1,70 +0,0 @@ -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/requestwaypointatposition.py b/scripts/commands/requestwaypointatposition.py index 98c3fd2d..60b932ce 100644 --- a/scripts/commands/requestwaypointatposition.py +++ b/scripts/commands/requestwaypointatposition.py @@ -7,7 +7,7 @@ def run(core, actor, target, commandString): commandArgs = commandString.split("(^-,=+_)color_13548(,+-=_^)=1") - newString = commandArgs[1] + newString = commandArgs[0] print (newString) cmdService = core.commandService cmdService.callCommand(actor, 'waypoint', None, newString) # No need to re-create a script diff --git a/scripts/commands/startdance.py b/scripts/commands/startdance.py new file mode 100644 index 00000000..18aa211c --- /dev/null +++ b/scripts/commands/startdance.py @@ -0,0 +1,96 @@ +from services.sui import SUIWindow +from services.sui import SUIService +from services.sui.SUIWindow import Trigger +from services.sui.SUIService import ListBoxType +from java.util import Vector +from java.util import HashMap +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + + entSvc = core.entertainmentService + global actorObject + global coreObject + global availableDances + global suiWindow + actorObject = actor + coreObject = core + + if len(commandString) > 0: + params = commandString.split(" ") + startDance(core, actor, params[0], 0) + return + else: + + availableDances = entSvc.getAvailableDances(actor) + print availableDances + + suiSvc = core.suiService + suiWindow = suiSvc.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, "@performance:select_dance", "@performance:available_dances", availableDances, actor, None, 10) + + returnList = Vector() + returnList.add("List.lstList:SelectedRow") + suiWindow.addHandler(0, '', Trigger.TRIGGER_OK, returnList, handleStartdance) + + suiSvc.openSUIWindow(suiWindow) + return + return + + +def handleStartdance(core, owner, eventType, returnList): + + item = suiWindow.getMenuItems().get(int(returnList.get(0))) + + if not item: + return + + #if eventType == 0: + startDance(coreObject, actorObject, '', int(item.getObjectId())) + return + +def startDance(core, actor, danceName, visual): + + entSvc = core.entertainmentService + + if visual <= 0: + visual = entSvc.getDanceVisualId(danceName) + + if visual <= 0: + return + + if not entSvc.isDance(visual): + actor.sendSystemMessage('@performance:dance_unknown_self',0) + return + + if not entSvc.canDance(actor, visual): + actor.sendSystemMessage('@performance:dance_lack_skill_self',0) + return + + if actor.getPerformanceId() > 0: + actor.sendSystemMessage('@performance:already_performing_self',0) + return + + #TODO: check costume, posture, etc? + + actor.sendSystemMessage('@performance:dance_start_self',0); + actor.notifyAudience('@performance:dance_start_other'); + + danceVisual = 'dance_' + str(visual) + + if not actor.getPerformanceWatchee(): + #this also notifies the client with a delta4 + actor.setPerformanceWatchee(actor) + + #this should send a CREO3 + actor.setPosture(0x09); + + dance = entSvc.getDance(visual) + + # send CREO6 here + # second param is some sort of counter or start tick + actor.startPerformance(dance.getLineNumber(), -842249156 , danceVisual, 1) + + return diff --git a/scripts/commands/stopdance.py b/scripts/commands/stopdance.py new file mode 100644 index 00000000..0f2d4763 --- /dev/null +++ b/scripts/commands/stopdance.py @@ -0,0 +1,19 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + entSvc = core.entertainmentService + + if (actor.getPerformanceId() <= 0): + actor.sendSystemMessage('@performance:dance_not_performing', 0) + return + + #since we need to stop performance for any posture change, + # all packets are triggered in setPosture. + # this may not be very consistent, but it prevents + # duplicate code. + actor.setPosture(0x00) + + return diff --git a/scripts/commands/tip.py b/scripts/commands/tip.py index b0b4331c..b34992f2 100644 --- a/scripts/commands/tip.py +++ b/scripts/commands/tip.py @@ -1,6 +1,4 @@ -from resources.objects.creature import CreatureObject from java.util import Date -from engine.resources.objects import SWGObject from services.chat import ChatService from services.chat import Mail from services.sui import SUIWindow @@ -8,6 +6,7 @@ from services.sui import SUIService from services.sui.SUIWindow import Trigger from services.sui.SUIService import MessageBoxType from java.util import Vector +from main import NGECore import sys # initialize global vars (happens at compile time) @@ -81,7 +80,8 @@ def run(core, actor, target, commandString): return return -def handleBankTip(core, owner, eventType, returnList): +def handleBankTip(owner, window, eventType, returnList): + core = NGECore.getInstance() chatSvc = core.chatService actorGlobal = core.objectService.getObject(actorID) targetGlobal = core.objectService.getObject(targetID) @@ -115,7 +115,7 @@ def handleBankTip(core, owner, eventType, returnList): actorMail.setSubject('@base_player:wire_mail_subject') actorMail.setSenderName('bank') - targetGlobal.setBankCredits(int(tipAmount)) + targetGlobal.setBankCredits(int(tipAmount) + int(targetGlobal.getBankCredits())) actorGlobal.setBankCredits(int(actorFunds) - int(totalLost)) actorGlobal.sendSystemMessage('You have successfully sent ' + tipAmount + ' bank credits to ' + targetGlobal.getCustomName(), 0) targetGlobal.sendSystemMessage('You have successfully received ' + tipAmount + ' bank credits from ' + actorGlobal.getCustomName(), 0) diff --git a/scripts/commands/transferitemarmor.py b/scripts/commands/transferitemarmor.py index ab107cf3..23e6dc42 100644 --- a/scripts/commands/transferitemarmor.py +++ b/scripts/commands/transferitemarmor.py @@ -15,15 +15,22 @@ def run(core, actor, target, commandString): return; replacedObject = None slotName = None + replacedObjects = [] + slotNames = None if actor == container: - slotName = container.getSlotNameForObject(target) - replacedObject = container.getSlottedObject(slotName) - + slotNames = container.getSlotNamesForObject(target) + for slotName in slotNames: + object = container.getSlottedObject(slotName) + if not object in replacedObjects and not object == None: + replacedObjects.append(object) + oldContainer.transferTo(actor, container, target) if actor == container: if target.getTemplate().find('/wearables/') or target.getTemplate().find('/weapon/'): - core.equipmentService.equip(actor, target, replacedObject) + core.equipmentService.equip(actor, target) + for object in replacedObjects: + core.equipmentService.unequip(actor, object) #path = 'scripts/' + target.getTemplate().rpartition('/')[0] + '/' #module = target.getTemplate().rpartition('/')[2].replace('shared_', '').replace('.iff', '') #core.scriptService.callScript(path, 'equip', module, core, actor, target) diff --git a/scripts/commands/transferitemmisc.py b/scripts/commands/transferitemmisc.py index 53eef0d6..e5c8b47e 100644 --- a/scripts/commands/transferitemmisc.py +++ b/scripts/commands/transferitemmisc.py @@ -17,15 +17,22 @@ def run(core, actor, target, commandString): replacedObject = None slotName = None + replacedObjects = [] + slotNames = None if actor == container: - slotName = container.getSlotNameForObject(target) - replacedObject = container.getSlottedObject(slotName) - + slotNames = container.getSlotNamesForObject(target) + for slotName in slotNames: + object = container.getSlottedObject(slotName) + if not object in replacedObjects and not object == None: + replacedObjects.append(object) + oldContainer.transferTo(actor, container, target) if actor == container: if target.getTemplate().find('/wearables/') or target.getTemplate().find('/weapon/'): - core.equipmentService.equip(actor, target, replacedObject) + core.equipmentService.equip(actor, target) + for object in replacedObjects: + core.equipmentService.unequip(actor, object) #path = 'scripts/' + target.getTemplate().rpartition('/')[0] + '/' #module = target.getTemplate().rpartition('/')[2].replace('shared_', '').replace('.iff', '') #core.scriptService.callScript(path, 'equip', module, core, actor, target) diff --git a/scripts/commands/transferitemweapon.py b/scripts/commands/transferitemweapon.py index 0bb7f55f..8c54e57a 100644 --- a/scripts/commands/transferitemweapon.py +++ b/scripts/commands/transferitemweapon.py @@ -16,15 +16,22 @@ def run(core, actor, target, commandString): replacedObject = None slotName = None + replacedObjects = [] + slotNames = None if actor == container: - slotName = container.getSlotNameForObject(target) - replacedObject = container.getSlottedObject(slotName) - + slotNames = container.getSlotNamesForObject(target) + for slotName in slotNames: + object = container.getSlottedObject(slotName) + if not object in replacedObjects and not object == None: + replacedObjects.append(object) + oldContainer.transferTo(actor, container, target) if actor == container: if target.getTemplate().find('/wearables/') or target.getTemplate().find('/weapon/'): - core.equipmentService.equip(actor, target, replacedObject) + core.equipmentService.equip(actor, target) + for object in replacedObjects: + core.equipmentService.unequip(actor, object) #path = 'scripts/' + target.getTemplate().rpartition('/')[0] + '/' #module = target.getTemplate().rpartition('/')[2].replace('shared_', '').replace('.iff', '') #core.scriptService.callScript(path, 'equip', module, core, actor, target) diff --git a/scripts/expertise/expertise_of_tactical_sup_1.py b/scripts/expertise/expertise_of_tactical_sup_1.py index d95ef2a5..451c6fbe 100644 --- a/scripts/expertise/expertise_of_tactical_sup_1.py +++ b/scripts/expertise/expertise_of_tactical_sup_1.py @@ -37,12 +37,8 @@ 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/mobiles/lairgroups/tatooine_starter.py b/scripts/mobiles/lairgroups/tatooine_starter.py new file mode 100644 index 00000000..63eda38c --- /dev/null +++ b/scripts/mobiles/lairgroups/tatooine_starter.py @@ -0,0 +1,9 @@ +import sys +from services.spawn import LairSpawnTemplate +from java.util import Vector + +def addLairGroup(core): + spawnTemplate = LairSpawnTemplate(-1, 'tatooine_kreetle_lair_neutral_small', 5, 20) + spawnTemplates = Vector() + spawnTemplates.add(spawnTemplate) + core.spawnService.addLairGroup('tatooine_starter', spawnTemplates) \ No newline at end of file diff --git a/scripts/mobiles/lairs/tatooine_kreetle_lair_neutral_small.py b/scripts/mobiles/lairs/tatooine_kreetle_lair_neutral_small.py new file mode 100644 index 00000000..76e76ebe --- /dev/null +++ b/scripts/mobiles/lairs/tatooine_kreetle_lair_neutral_small.py @@ -0,0 +1,4 @@ +import sys + +def addTemplate(core): + core.spawnService.addLairTemplate('tatooine_kreetle_lair_neutral_small', 'kreetle', 15, 'object/tangible/lair/base/shared_poi_all_lair_brambles_small.iff') \ No newline at end of file diff --git a/scripts/mobiles/spawnareas/mos_eisley_lair.py b/scripts/mobiles/spawnareas/mos_eisley_lair.py new file mode 100644 index 00000000..fe0b5291 --- /dev/null +++ b/scripts/mobiles/spawnareas/mos_eisley_lair.py @@ -0,0 +1,6 @@ +import sys + +def addSpawnArea(core): + core.spawnService.addLairSpawnArea('tatooine_starter', 3400, -4775, 2048, 'tatooine') + + diff --git a/scripts/object/building/tatooine/starport_tatooine.py b/scripts/object/building/tatooine/starport_tatooine.py index 0e620101..8ba07743 100644 --- a/scripts/object/building/tatooine/starport_tatooine.py +++ b/scripts/object/building/tatooine/starport_tatooine.py @@ -10,7 +10,7 @@ def setup(core, object): stcSvc.spawnObject('object/tangible/terminal/shared_terminal_travel.iff', object.getPlanet().getName(), cell.getObjectID(), float(-2.7), float(0.6), float(49), float(0), float(1)) stcSvc.spawnObject('object/tangible/terminal/shared_terminal_travel.iff', object.getPlanet().getName(), cell.getObjectID(), float(-13.2), float(0.6), float(51.3), float(-0.195405), float(-0.980722)) objSvc.createChildObject(object, 'object/creature/npc/theme_park/shared_player_transport.iff', 0, 0, 0, 1, 0) - objSvc.createChildObject(object, 'object/tangible/travel/ticket_collector/shared_ticket_collector.iff', 10, 0, -10, 0.707107, 0.707107) + objSvc.createChildObject(object, 'object/tangible/travel/ticket_collector/shared_ticket_collector.iff', 10, 0, -10, 0.707107, 0.707107) core.mapService.addLocation(object.getPlanet(), 'Starport', object.getPosition().x, object.getPosition().z, 15, 0, 0) return \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_mission.py b/scripts/object/tangible/terminal/terminal_mission.py index 4884aa67..ccf684c0 100644 --- a/scripts/object/tangible/terminal/terminal_mission.py +++ b/scripts/object/tangible/terminal/terminal_mission.py @@ -1,7 +1,9 @@ +from resources.common import TerminalType import sys def setup(core, object): core.mapService.addLocation(object.getPlanet(), 'Mission Terminal', object.getPosition().x, object.getPosition().z, 41, 44, 0) + object.setAttachment("terminalType", TerminalType.MISSION_GENERIC) return \ No newline at end of file diff --git a/scripts/object/tangible/travel/travel_ticket/base/base_travel_ticket.py b/scripts/object/tangible/travel/travel_ticket/base/base_travel_ticket.py index ccad8904..77e1b16d 100644 --- a/scripts/object/tangible/travel/travel_ticket/base/base_travel_ticket.py +++ b/scripts/object/tangible/travel/travel_ticket/base/base_travel_ticket.py @@ -1,4 +1,5 @@ import sys def setup(core, object): + object.setAttachment('radial_filename', 'travel_ticket') return \ No newline at end of file diff --git a/scripts/radial/travel_terminal.py b/scripts/radial/travel_terminal.py index f8b984fb..eae686ca 100644 --- a/scripts/radial/travel_terminal.py +++ b/scripts/radial/travel_terminal.py @@ -8,13 +8,10 @@ def createRadial(core, owner, target, radials): def handleSelection(core, owner, target, option): if option == 21 and target: - print ('Owner: ' + str(owner.getObjectId())) - + if owner is not None: tpm = EnterTicketPurchaseModeMessage(owner.getPlanet().getName(), core.mapService.getClosestCityName(owner), owner) owner.getClient().getSession().write(tpm.serialize()) - print ('Planet name: ' + owner.getPlanet().getName()) - print ('City name: ' + core.mapService.getClosestCityName(owner)) return return diff --git a/scripts/radial/travel_ticket.py b/scripts/radial/travel_ticket.py new file mode 100644 index 00000000..a42df278 --- /dev/null +++ b/scripts/radial/travel_ticket.py @@ -0,0 +1,40 @@ +from resources.common import RadialOptions +import sys + +def createRadial(core, owner, target, radials): + radials.clear + + radials.add(RadialOptions(0, 21, 1, 'Use Travel Ticket')) + #radials.add(RadialOptions(0, 7, 1, '')) + #radials.add(RadialOptions(0, 15, 1, '')) + return + +def handleSelection(core, owner, target, option): + + if option == 21 and target: + + tp = core.travelService.getNearestTravelPoint(owner) + + if owner is not None and tp is not None: + print (str(tp.getLocation().getDistance2D(owner.getWorldPosition()))) + if tp.getLocation().getDistance2D(owner.getWorldPosition()) <= float(25): + if tp.isShuttleAvailable() is True: + core.travelService.doTransport(owner, core.travelService.getTravelPointByName(target.getStringAttribute('@obj_attr_n:travel_arrival_planet'), + target.getStringAttribute('@obj_attr_n:travel_arrival_point'))) + core.objectService.destroyObject(target) + return + return + else: + owner.sendSystemMessage('@travel:boarding_too_far', 0) + return + return + return + + if option == 15 and target: + core.commandService.callCommand(owner, 'serverdestroyobject', target, None) + return + return + +def handleSUI(owner, window, eventType, returnList): + + return \ No newline at end of file diff --git a/scripts/static_travel_points.py b/scripts/static_travel_points.py index 54b19a77..26ac3f85 100644 --- a/scripts/static_travel_points.py +++ b/scripts/static_travel_points.py @@ -40,11 +40,10 @@ def corelliaPoints(core, planet): trvSvc.addTravelPoint(planet, "Kor Vella Shuttleport", -3775, 86, 3234) trvSvc.addTravelPoint(planet, "Bela Vistal Shuttleport A", 6644, 330, -5922) trvSvc.addTravelPoint(planet, "Bela Vistal Shuttleport B", 6930, 330, -5534) - trvSvc.addTravelPoint(planet, "Coronet Starport", -51, 28, -4735) trvSvc.addTravelPoint(planet, "Tyrena Starport", -4975, 21, -2230) trvSvc.addTravelPoint(planet, "Kor Vella Starport", -3136, 31, 2894) - trvSvc.addTravelPoint(planet, "Doaba Guerful Starport", 3377, 308, 5605) + trvSvc.addTravelPoint(planet, "Doaba Guerfel Starport", 3377, 308, 5605) return def dantooinePoints(core, planet): diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 77bac93b..5f2b323b 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -34,8 +34,8 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import org.apache.mina.core.service.IoHandler; import net.engio.mbassy.bus.config.BusConfiguration; - import resources.common.RadialOptions; import resources.common.ThreadMonitor; import resources.objects.creature.CreatureObject; @@ -47,6 +47,7 @@ import services.EntertainmentService; import services.EquipmentService; import services.GroupService; import services.LoginService; +import services.MissionService; import services.PlayerService; import services.ScriptService; import services.SimulationService; @@ -64,6 +65,7 @@ import services.command.CommandService; import services.gcw.FactionService; import services.gcw.GCWService; import services.guild.GuildService; +import services.LoginService; import services.map.MapService; import services.object.ObjectService; import services.object.UpdateService; @@ -90,7 +92,9 @@ import engine.resources.database.ObjectDatabase; import engine.resources.objects.SWGObject; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; +import engine.resources.service.InteractiveJythonAcceptor; import engine.resources.service.NetworkDispatch; +import engine.servers.InteractiveJythonServer; import engine.servers.MINAServer; import engine.servers.PingServer; @@ -144,6 +148,7 @@ public class NGECore { public WeatherService weatherService; public SpawnService spawnService; public AIService aiService; + //public MissionService missionService; // Login Server public NetworkDispatch loginDispatch; @@ -152,6 +157,10 @@ public class NGECore { // Zone Server public NetworkDispatch zoneDispatch; private MINAServer zoneServer; + + // Interactive Jython Console + public InteractiveJythonAcceptor jythonAcceptor; + private InteractiveJythonServer jythonServer; private ObjectDatabase creatureODB; private ObjectDatabase mailODB; @@ -188,12 +197,18 @@ public class NGECore { // Database databaseConnection = new DatabaseConnection(); databaseConnection.connect(config.getString("DB.URL"), config.getString("DB.NAME"), config.getString("DB.USER"), config.getString("DB.PASS"), "postgresql"); + + String db2Url = config.getString("DB2.URL"); + if (db2Url == null || db2Url.matches("^\\s*$")) { + databaseConnection2 = null; + } else { + databaseConnection2 = new DatabaseConnection(); + databaseConnection2.connect(config.getString("DB2.URL"), config.getString("DB2.NAME"), config.getString("DB2.USER"), config.getString("DB2.PASS"), "mysql"); + } - databaseConnection2 = new DatabaseConnection(); setGalaxyStatus(1); creatureODB = new ObjectDatabase("creature", true, false, true); mailODB = new ObjectDatabase("mails", true, false, true); - // Services loginService = new LoginService(this); connectionService = new ConnectionService(this); @@ -218,8 +233,21 @@ public class NGECore { skillModService = new SkillModService(this); equipmentService = new EquipmentService(this); entertainmentService = new EntertainmentService(this); + + if (config.keyExists("JYTHONCONSOLE.PORT")) { + int jythonPort = config.getInt("JYTHONCONSOLE.PORT"); + if (jythonPort > 0) { + + System.out.println("Starting InteractiveJythonServer on Port " + jythonPort); + jythonAcceptor = new InteractiveJythonAcceptor(); + jythonServer = new InteractiveJythonServer((IoHandler) jythonAcceptor, jythonPort, this); + jythonAcceptor.setServer(jythonServer); + jythonServer.start(); + } + } spawnService = new SpawnService(this); aiService = new AIService(this); + //missionService = new MissionService(this); // Ping Server try { @@ -250,6 +278,7 @@ public class NGECore { zoneDispatch.addService(playerService); zoneDispatch.addService(buffService); zoneDispatch.addService(entertainmentService); + //zoneDispatch.addService(missionService); zoneServer = new MINAServer(zoneDispatch, config.getInt("ZONE.PORT")); zoneServer.start(); @@ -268,6 +297,7 @@ public class NGECore { terrainService.addPlanet(10, "dathomir", "terrain/dathomir.trn", true); terrainService.addPlanet(11, "mustafar", "terrain/mustafar.trn", true); terrainService.addPlanet(12, "kashyyyk_main", "terrain/kashyyyk_main.trn", true); + spawnService = new SpawnService(this); terrainService.loadClientPois(); // Travel Points travelService.loadTravelPoints(); @@ -302,13 +332,15 @@ public class NGECore { weatherService = new WeatherService(this); weatherService.loadPlanetSettings(); + // spawnService.loadLairTemplates(); + // spawnService.loadLairGroups(); + // spawnService.loadSpawnAreas(); + didServerCrash = false; System.out.println("Started Server."); setGalaxyStatus(2); - + } - - public void stop() { System.out.println("Stopping Servers and Connections."); diff --git a/src/protocol/Message.java b/src/protocol/Message.java index 5085a975..9792eaec 100644 --- a/src/protocol/Message.java +++ b/src/protocol/Message.java @@ -103,6 +103,7 @@ public abstract class Message { } + //TODO: Verify if character position is set correctly after reading a UTF-16 string buffer.position(bufferPosition + length); return result; @@ -146,8 +147,8 @@ public abstract class Message { return result.array(); } - - + + //FIXME: this is redundant and was also bugged. At some point, get rid of the redundant functions. /** * Reads the next string in. It gets the length of the * string from the short/int at the beginning of it @@ -161,7 +162,7 @@ public abstract class Message { if (charset.equals("US-ASCII") || charset.equals("UTF-8")) { length = bb.getShort(); } else { - length = bb.getInt(); + length = bb.getInt() * 2; } if (length > bb.remaining()) return ""; @@ -201,4 +202,4 @@ public abstract class Message { return getNextString(buffer, "UTF-16LE"); } -} +} diff --git a/src/protocol/swg/ClientVerifyAndLockNameRequest.java b/src/protocol/swg/ClientVerifyAndLockNameRequest.java index 7d9c9722..ea0011f5 100644 --- a/src/protocol/swg/ClientVerifyAndLockNameRequest.java +++ b/src/protocol/swg/ClientVerifyAndLockNameRequest.java @@ -38,8 +38,8 @@ public class ClientVerifyAndLockNameRequest extends SWGMessage { public void deserialize(IoBuffer buffer) { buffer.position(6); // Skips SOE and SWG opcodes raceTemplate = getNextAsciiString(buffer); - name = getNextUnicodeString(buffer);; - + name = getNextUnicodeString(buffer); + System.out.println("msg: " + name); // Gets the first and last names String [] splitName = name.split(" "); firstName = splitName[0]; diff --git a/src/protocol/swg/objectControllerObjects/CommandEnqueue.java b/src/protocol/swg/objectControllerObjects/CommandEnqueue.java index 40b228a6..bb1705a4 100644 --- a/src/protocol/swg/objectControllerObjects/CommandEnqueue.java +++ b/src/protocol/swg/objectControllerObjects/CommandEnqueue.java @@ -39,6 +39,15 @@ public class CommandEnqueue extends ObjControllerObject { public static final int STAND = 0xA8A25C79; public static final int ATTACK = 0xA8FEF90A; public static final int TRANSFERITEM = 0x3CFB449D; + + //ent + // this really needed? + public static final int STARTDANCE = 0x7B1DCBE0; + public static final int STOPDANCE = 0xECC171CC; + public static final int FLOURISH = 0xC8998CE9; + public static final int FLO = 0x3B159B76; + public static final int BANDFLOURISH = 0xF4C60EC3; + public static final int BANDFLO = 0xDD3FB008; private int actionCounter; private int commandCRC; diff --git a/src/protocol/swg/objectControllerObjects/MissionListRequest.java b/src/protocol/swg/objectControllerObjects/MissionListRequest.java index 1cafd618..7fbe2d02 100644 --- a/src/protocol/swg/objectControllerObjects/MissionListRequest.java +++ b/src/protocol/swg/objectControllerObjects/MissionListRequest.java @@ -39,6 +39,7 @@ public class MissionListRequest extends ObjControllerObject { public void deserialize(IoBuffer data) { Console.println("MissionListRequest: " + StringUtilities.bytesToHex(data.array())); setObjectId(data.getLong()); + data.getInt(); // unk data.get(); // unk byte setTickCount(data.get()); setTerminalId(data.getLong()); diff --git a/src/resources/common/ObjControllerOpcodes.java b/src/resources/common/ObjControllerOpcodes.java index bd462a73..db8ef253 100644 --- a/src/resources/common/ObjControllerOpcodes.java +++ b/src/resources/common/ObjControllerOpcodes.java @@ -31,6 +31,6 @@ public class ObjControllerOpcodes { public static final int OBJECT_MENU_REQUEST = 0x46010000; public static final int SECURE_TRADE = 0x15010000; public static final int BUFF_BUILDER_CHANGE = 0x5A020000; - public static final int MISSION_LIST_REQUEST = 0x5F000000; + public static final int MISSION_LIST_REQUEST = 0xF5000000; } diff --git a/src/resources/common/Performance.java b/src/resources/common/Performance.java new file mode 100644 index 00000000..9100e2f2 --- /dev/null +++ b/src/resources/common/Performance.java @@ -0,0 +1,254 @@ +package resources.common; + +public class Performance { + + + private String performanceName; + private int instrumentAudioId; + private String requiredSong; + private String requiredInstrument; + private String requiredDance; + private int danceVisualId; + private int actionPointsPerLoop; + private float loopDuration; + private int type; + private int baseXp; + private int flourishXpMod; + private int healMindWound; + private int healShockWound; + private String requiredSkillMod; + private int requiredSkillModValue; + private String mainloop; + private String flourish1; + private String flourish2; + private String flourish3; + private String flourish4; + private String flourish5; + private String flourish6; + private String flourish7; + private String flourish8; + private String intro; + private String outro; + private int lineNumber; + + public Performance() { + + } + + public int getBaseXp() { + return baseXp; + } + + public void setBaseXp(int baseXp) { + this.baseXp = baseXp; + } + + public String getPerformanceName() { + return performanceName; + } + + public void setPerformanceName(String performanceName) { + this.performanceName = performanceName; + } + + public int getInstrumentAudioId() { + return instrumentAudioId; + } + + public void setInstrumentAudioId(int instrumentAudioId) { + this.instrumentAudioId = instrumentAudioId; + } + + public int getRequiredSkillModValue() { + return requiredSkillModValue; + } + + public void setRequiredSkillModValue(int requiredSkillModValue) { + this.requiredSkillModValue = requiredSkillModValue; + } + + public String getRequiredSong() { + return requiredSong; + } + + public void setRequiredSong(String requiredSong) { + this.requiredSong = requiredSong; + } + + public String getRequiredInstrument() { + return requiredInstrument; + } + + public void setRequiredInstrument(String requiredInstrument) { + this.requiredInstrument = requiredInstrument; + } + + public String getRequiredDance() { + return requiredDance; + } + + public void setRequiredDance(String requiredDance) { + this.requiredDance = requiredDance; + } + + public int getDanceVisualId() { + return danceVisualId; + } + + public void setDanceVisualId(int danceVisualId) { + this.danceVisualId = danceVisualId; + } + + public int getActionPointsPerLoop() { + return actionPointsPerLoop; + } + + public void setActionPointsPerLoop(int actionPointsPerLoop) { + this.actionPointsPerLoop = actionPointsPerLoop; + } + + public float getLoopDuration() { + return loopDuration; + } + + public void setLoopDuration(float loopDuration) { + this.loopDuration = loopDuration; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public int getFlourishXpMod() { + return flourishXpMod; + } + + public void setFlourishXpMod(int flourishXpMod) { + this.flourishXpMod = flourishXpMod; + } + + public int getHealMindWound() { + return healMindWound; + } + + public void setHealMindWound(int healMindWound) { + this.healMindWound = healMindWound; + } + + public int getHealShockWound() { + return healShockWound; + } + + public int getLineNumber() { + return lineNumber; + } + + public void setHealShockWound(int healShockWound) { + this.healShockWound = healShockWound; + } + + public String getRequiredSkillMod() { + return requiredSkillMod; + } + + public void setRequiredSkillMod(String requiredSkillMod) { + this.requiredSkillMod = requiredSkillMod; + } + + public String getMainloop() { + return mainloop; + } + + public void setMainloop(String mainloop) { + this.mainloop = mainloop; + } + + public String getFlourish1() { + return flourish1; + } + + public void setFlourish1(String flourish1) { + this.flourish1 = flourish1; + } + + public String getFlourish2() { + return flourish2; + } + + public void setFlourish2(String flourish2) { + this.flourish2 = flourish2; + } + + public String getFlourish3() { + return flourish3; + } + + public void setFlourish3(String flourish3) { + this.flourish3 = flourish3; + } + + public String getFlourish4() { + return flourish4; + } + + public void setFlourish4(String flourish4) { + this.flourish4 = flourish4; + } + + public String getFlourish5() { + return flourish5; + } + + public void setFlourish5(String flourish5) { + this.flourish5 = flourish5; + } + + public String getFlourish6() { + return flourish6; + } + + public void setFlourish6(String flourish6) { + this.flourish6 = flourish6; + } + + public String getFlourish7() { + return flourish7; + } + + public void setFlourish7(String flourish7) { + this.flourish7 = flourish7; + } + + public String getFlourish8() { + return flourish8; + } + + public void setFlourish8(String flourish8) { + this.flourish8 = flourish8; + } + + public String getIntro() { + return intro; + } + + public void setIntro(String intro) { + this.intro = intro; + } + + public String getOutro() { + return outro; + } + + public void setOutro(String outro) { + this.outro = outro; + } + + public void setLineNumber(int lineNumber) { + this.lineNumber = lineNumber; + } + +} diff --git a/src/resources/objects/building/BuildingMessageBuilder.java b/src/resources/objects/building/BuildingMessageBuilder.java index 606f5f78..e05d9df0 100644 --- a/src/resources/objects/building/BuildingMessageBuilder.java +++ b/src/resources/objects/building/BuildingMessageBuilder.java @@ -43,7 +43,7 @@ public class BuildingMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); buffer.put(getAsciiString(building.getStfName())); buffer.putInt(0); - buffer.putInt(255); + buffer.putInt(0); buffer.putInt(0); buffer.putInt(0); buffer.putInt(0); diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 90ed5851..22051e7a 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -58,7 +58,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(creature.getCashCredits()); buffer.putInt(6); // Base HAM List - so leveling knows the base HAM, before equipment etc - buffer.putInt(6); + buffer.putInt(0); buffer.putInt(creature.getHealth()); buffer.putInt(0); buffer.putInt(creature.getAction()); @@ -113,7 +113,8 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(1); buffer.putInt(0); // TANO Data buffer.putInt(0); - buffer.putInt(creature.getOptionsBitmask()); // 0x80 = Player, 0x08 = Quest NPC, + // buffer.putInt(creature.getOptionsBitmask()); // 0x80 = Player, 0x08 = Quest NPC, + buffer.putInt(0x80); buffer.putInt(creature.getIncapTimer()); buffer.putInt(0); buffer.putInt(0x3A98); @@ -167,7 +168,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { } buffer.putFloat(creature.getSpeedMultiplierBase()); buffer.putFloat(creature.getSpeedMultiplierMod()); - buffer.putLong(0); // unk + buffer.putLong(creature.getListenToId()); buffer.putFloat(creature.getRunSpeed()); @@ -228,10 +229,12 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { //buffer.putShort((short) 90); buffer.putInt(creature.getGrantedHealth()); // From player_level.iff. Ranges from 0-2000 as you level, consistent with that table. + //0A if(creature.getCurrentAnimation() == null || creature.getCurrentAnimation().length() == 0) buffer.putShort((short) 0); else buffer.put(getAsciiString(creature.getCurrentAnimation())); + if(creature.getMoodAnimation() == null || creature.getMoodAnimation().length() == 0) buffer.put(getAsciiString("neutral")); else @@ -245,10 +248,11 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putShort((short) 0); else buffer.put(getAsciiString(creature.getInviteSenderName())); - + buffer.putLong(creature.getInviteCounter()); buffer.putInt(creature.getGuildId()); + //10 buffer.putLong(creature.getTargetId()); buffer.put(creature.getMoodId()); buffer.putInt(creature.getPerformanceCounter()); @@ -261,6 +265,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(creature.getHamListCounter()); buffer.putInt(creature.getHealth()); + //1A buffer.putInt(0); buffer.putInt(creature.getAction()); buffer.putInt(0); @@ -268,7 +273,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); buffer.putInt(6); // Max HAM - buffer.putInt(0); + buffer.putInt(creature.getMaxHAMListCounter()); buffer.putInt(creature.getMaxHealth()); buffer.putInt(0); @@ -701,7 +706,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { return buffer; - } + } public IoBuffer buildMaxHealthDelta(int health) { @@ -983,6 +988,43 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { } + public IoBuffer buildListenToId(long creatureObjectId) { + IoBuffer buffer = bufferPool.allocate(8, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putLong(creatureObjectId); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 4, (short) 1, (short) 0x09, buffer, size + 4); + return buffer; + } + + public IoBuffer buildPerformanceId(int performanceId) { + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(performanceId); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x14, buffer, size + 4); + return buffer; + } + + public IoBuffer buildPerformanceCounter(int performanceCounter) { + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(performanceCounter); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x13, buffer, size + 4); + return buffer; + } + + public IoBuffer buildStartPerformance(boolean doStart) { + IoBuffer buffer = bufferPool.allocate(1, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put((byte) ((doStart) ? 1 : 0)); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x1B, buffer, size + 4); + return buffer; + } + + public IoBuffer buildDifficultyDelta(byte difficulty) { IoBuffer buffer = bufferPool.allocate(1, false).order(ByteOrder.LITTLE_ENDIAN); buffer.put(difficulty); @@ -1002,5 +1044,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { public void sendBaselines() { } + + } diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 45b76ada..df850ddf 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -55,7 +55,7 @@ import engine.resources.scene.Quaternion; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; -@Entity(version=3) +@Entity(version=7) public class CreatureObject extends TangibleObject implements IPersistent { @NotPersistent @@ -115,6 +115,15 @@ public class CreatureObject extends TangibleObject implements IPersistent { private byte moodId = 0; private int performanceCounter = 0; private int performanceId = 0; + //FIXME: this is a bit of a hack. + private boolean performanceType = false; + //FIXME: hmm.. or persistent? + @NotPersistent + private boolean acceptBandflourishes = true; + @NotPersistent + private boolean groupDance = true; + private CreatureObject performanceWatchee; + private CreatureObject performanceListenee; private int health = 1000; private int action = 300; @NotPersistent @@ -305,15 +314,25 @@ public class CreatureObject extends TangibleObject implements IPersistent { } public void setPosture(byte posture) { + boolean needsStopPerformance = false; synchronized(objectMutex) { + if (this.posture == 0x09) { + needsStopPerformance = true; + } this.posture = posture; } + IoBuffer postureDelta = messageBuilder.buildPostureDelta(posture); Posture postureUpdate = new Posture(getObjectID(), posture); ObjControllerMessage objController = new ObjControllerMessage(0x1B, postureUpdate); notifyObservers(postureDelta, true); notifyObservers(objController, true); + + if (needsStopPerformance) { + stopPerformance(); + } + } @Override @@ -747,6 +766,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { notifyObservers(messageBuilder.buildCurrentAnimationDelta(currentAnimation), true); } + + public void doSkillAnimation(String skillAnimation) { + Animation animation = new Animation(getObjectId(), skillAnimation); + ObjControllerMessage objController = new ObjControllerMessage(0x1B, animation); + + notifyObservers(objController, true); + + } public String getMoodAnimation() { synchronized(objectMutex) { @@ -894,6 +921,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } + public boolean getAcceptBandflourishes() { + return acceptBandflourishes; + } + + public void setAcceptBandflourishes(boolean acceptBandflourishes) { + this.acceptBandflourishes = acceptBandflourishes; + } + public SWGList getEquipmentList() { return equipmentList; } @@ -948,11 +983,12 @@ public class CreatureObject extends TangibleObject implements IPersistent { //destination.getSession().write(messageBuilder.buildBaseline9()); UpdatePostureMessage upm = new UpdatePostureMessage(getObjectID(), (byte) 0); - //destination.getSession().write(upm.serialize()); + // destination.getSession().write(upm.serialize()); if(destination != getClient()) { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()); - + if(getSlottedObject("ghost") != null) + upvpm.setStatus(16); /* if (factionStatus == 1 && faction == "imperial") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial); @@ -1067,7 +1103,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { if(health > maxHealth) health = maxHealth; setHamListCounter(getHamListCounter() + 1); - delta = messageBuilder.buildHealthDelta(health); + delta = messageBuilder.buildUpdateHAMListDelta(); notifyObservers(delta, true); this.health = health; @@ -1087,7 +1123,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { if(action > maxAction) action = maxAction; setHamListCounter(getHamListCounter() + 1); - delta = messageBuilder.buildActionDelta(action); + delta = messageBuilder.buildUpdateHAMListDelta(); notifyObservers(delta, true); this.action = action; } @@ -1225,6 +1261,13 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } + public void updateHAMList() { + synchronized(objectMutex) { + setHamListCounter(getHamListCounter() + 1); + notifyObservers(messageBuilder.buildUpdateHAMListDelta(), true); + } + } + public SWGList getDotList() { return dotList; } @@ -1309,6 +1352,90 @@ public class CreatureObject extends TangibleObject implements IPersistent { return this.staticNPC = staticNPC; } + public boolean getGroupDance() { + synchronized(objectMutex) { + return groupDance; + } + } + + public void setGroupDance(boolean groupDance) { + synchronized(objectMutex) { + this.groupDance = groupDance; + } + } + + public boolean toggleGroupDance() { + synchronized(objectMutex) { + groupDance = !groupDance; + return groupDance; + } + } + + public CreatureObject getPerformanceWatchee() { + synchronized(objectMutex) { + return performanceWatchee; + } + } + + public void setPerformanceWatchee(CreatureObject performanceWatchee) { + synchronized(objectMutex) { + this.performanceWatchee = performanceWatchee; + } + // not sure at this point if it makes a difference really. + // on Live, an empty CREO4 was sent, at least when listenToId was empty. + //getClient().getSession().write(messageBuilder.buildListenToId(0)); + } + + public CreatureObject getPerformanceListenee() { + synchronized(objectMutex) { + return performanceListenee; + } + } + + public void setPerformanceListenee(CreatureObject performanceListenee) { + synchronized(objectMutex) { + this.performanceListenee = performanceListenee; + //possibly redundant, need to research this further. + this.listenToId = performanceListenee.getObjectId(); + } + getClient().getSession().write(messageBuilder.buildListenToId(this.listenToId)); + } + + public void startPerformance(int performanceId, int performanceCounter, String skillName, boolean isDance) { + synchronized(objectMutex) { + this.performanceId = performanceId; + this.performanceCounter = performanceCounter; + this.currentAnimation = skillName; + this.performanceType = isDance; + } + + getClient().getSession().write(messageBuilder.buildPerformanceId(performanceId)); + getClient().getSession().write(messageBuilder.buildPerformanceCounter(performanceCounter)); + getClient().getSession().write(messageBuilder.buildCurrentAnimationDelta(skillName)); + getClient().getSession().write(messageBuilder.buildStartPerformance(true)); + + } + + public void stopPerformance() { + String type = ""; + synchronized(objectMutex) { + this.performanceId = 0; + this.performanceCounter = 0; + this.currentAnimation = null; + type = (performanceType) ? "dance" : "music"; + } + + sendSystemMessage("@performance:" + type + "_stop_self",(byte)0); + notifyAudience("@performance:" + type + "_stop_other"); + + getClient().getSession().write(messageBuilder.buildStartPerformance(false)); + } + + public void notifyAudience(String message) { + //TODO: stub + } + + @Override public void setPvPBitmask(int pvpBitmask) { super.setPvPBitmask(pvpBitmask); diff --git a/src/resources/objects/mission/MissionMessageBuilder.java b/src/resources/objects/mission/MissionMessageBuilder.java index dff9bc55..190773ad 100644 --- a/src/resources/objects/mission/MissionMessageBuilder.java +++ b/src/resources/objects/mission/MissionMessageBuilder.java @@ -26,6 +26,8 @@ import java.nio.ByteOrder; import org.apache.mina.core.buffer.IoBuffer; import engine.resources.common.CRC; +import resources.common.Console; +import resources.common.StringUtilities; import resources.objects.ObjectMessageBuilder; import resources.objects.waypoint.WaypointObject; @@ -40,7 +42,7 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { IoBuffer buffer = IoBuffer.allocate(100, false).order(ByteOrder.LITTLE_ENDIAN); buffer.setAutoExpand(true); - buffer.putShort((short) 11); + buffer.putShort((short) 17); buffer.putFloat(1); // mission complexity ?? buffer.put(getAsciiString(mission.getStfFilename())); @@ -50,7 +52,7 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { if (mission.getCustomName() == null) { buffer.put(getUnicodeString("")); } else { buffer.put(getUnicodeString(mission.getCustomName())); } - buffer.putInt(mission.getVolume()); + buffer.putInt(0); // volume buffer.putInt(0); // unused buffer.putInt(mission.getMissionLevel()); @@ -60,8 +62,12 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { buffer.putLong(0); // ?? - buffer.putInt(CRC.StringtoCRC(mission.getMissionStartPlanet())); - + if (mission.getMissionStartPlanet() == null) { + buffer.putInt(0); + } else { + buffer.putInt(CRC.StringtoCRC(mission.getMissionStartPlanet())); + } + buffer.put(getUnicodeString(mission.getMissionCreator())); buffer.putInt(mission.getMissionCredits()); @@ -71,10 +77,18 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { buffer.putLong(0); // ?? - buffer.putInt(CRC.StringtoCRC(mission.getMissionDestinationPlanet())); - - buffer.putInt(CRC.StringtoCRC(mission.getMissionTemplateObject())); + if (mission.getMissionDestinationPlanet() == null) { + buffer.putInt(0); + } else { + buffer.putInt(CRC.StringtoCRC(mission.getMissionDestinationPlanet())); + } + if (mission.getTargetTemplateObject() == null) { + buffer.putInt(0); + } else { + buffer.putInt(CRC.StringtoCRC(mission.getTargetTemplateObject())); + } + buffer.put(getAsciiString(mission.getMissionDescription())); buffer.putInt(0); buffer.put(getAsciiString(mission.getMissionDescId())); @@ -85,8 +99,12 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); // refresh counter - buffer.putInt(CRC.StringtoCRC(mission.getMissionType())); - + if(mission.getMissionType() == null) { + buffer.putInt(0); + } else { + buffer.putInt(CRC.StringtoCRC(mission.getMissionType())); + } + buffer.put(getAsciiString(mission.getMissionTargetName())); WaypointObject wp = mission.getMissionAttachedWaypoint(); @@ -109,6 +127,8 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { buffer.putFloat(wp.getPosition().y); buffer.putLong(0); buffer.putInt(CRC.StringtoCRC(wp.getPlanet().name)); + buffer.put((byte) 0); + buffer.put((byte) 0x01); } int size = buffer.position(); buffer = bufferPool.allocate(size, false).put(buffer.array(), 0, size); @@ -116,6 +136,7 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { buffer.flip(); buffer = createBaseline("MISO", (byte) 3, buffer, size); + Console.println("Bytes: " + StringUtilities.bytesToHex(buffer.array())); return buffer; } @@ -132,14 +153,13 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildStfDelta() { - MissionObject mission = (MissionObject) object; + public IoBuffer buildStfDelta(String stfFile, String stfName) { - IoBuffer buffer = IoBuffer.allocate(4 + mission.getStfFilename().length() + mission.getStfName().length(), false).order(ByteOrder.LITTLE_ENDIAN); + IoBuffer buffer = IoBuffer.allocate(4 + stfFile.length() + stfName.length(), false).order(ByteOrder.LITTLE_ENDIAN); - buffer.put(getAsciiString(mission.getStfFilename())); + buffer.put(getAsciiString(stfFile)); buffer.putInt(0); - buffer.put(getAsciiString(mission.getStfName())); + buffer.put(getAsciiString(stfName)); int size = buffer.position(); buffer.flip(); @@ -148,12 +168,11 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildDifficultyLevelDelta() { - MissionObject mission = (MissionObject) object; + public IoBuffer buildDifficultyLevelDelta(int difficulty) { IoBuffer buffer = IoBuffer.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(mission.getMissionLevel()); + buffer.putInt(difficulty); int size = buffer.position(); buffer.flip(); @@ -162,18 +181,17 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildStartLocationDelta() { - MissionObject mission = (MissionObject) object; - + public IoBuffer buildStartLocationDelta(float x, float z, float y, String planet) { + IoBuffer buffer = IoBuffer.allocate(24, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putFloat(mission.getMissionStartX()); - buffer.putFloat(mission.getMissionStartZ()); - buffer.putFloat(mission.getMissionStartY()); + buffer.putFloat(x); + buffer.putFloat(z); + buffer.putFloat(y); buffer.putLong(0); - buffer.putInt(CRC.StringtoCRC(mission.getMissionStartPlanet())); + buffer.putInt(CRC.StringtoCRC(planet)); int size = buffer.position(); buffer.flip(); @@ -182,12 +200,11 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildCreatorNameDelta() { - MissionObject mission = (MissionObject) object; + public IoBuffer buildCreatorNameDelta(String creator) { + + IoBuffer buffer = IoBuffer.allocate(4 + creator.length(), false).order(ByteOrder.LITTLE_ENDIAN); - IoBuffer buffer = IoBuffer.allocate(4 + mission.getMissionCreator().length(), false).order(ByteOrder.LITTLE_ENDIAN); - - buffer.put(getAsciiString(mission.getMissionCreator())); + buffer.put(getAsciiString(creator)); int size = buffer.position(); buffer.flip(); @@ -196,12 +213,11 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildCreditsRewardDelta() { - MissionObject mission = (MissionObject) object; - + public IoBuffer buildCreditsRewardDelta(int creds) { + IoBuffer buffer = IoBuffer.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(mission.getMissionCredits()); + buffer.putInt(creds); int size = buffer.position(); buffer.flip(); @@ -210,18 +226,17 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildDestinationDelta() { - MissionObject mission = (MissionObject) object; - + public IoBuffer buildDestinationDelta(float x, float z, float y, String planet) { + IoBuffer buffer = IoBuffer.allocate(24, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putFloat(mission.getMissionDestinationX()); - buffer.putFloat(mission.getMissionDestinationZ()); - buffer.putFloat(mission.getMissionDestinationY()); + buffer.putFloat(x); + buffer.putFloat(z); + buffer.putFloat(y); buffer.putLong(0); // Destination Object ID - buffer.putInt(CRC.StringtoCRC(mission.getMissionDestinationPlanet())); + buffer.putInt(CRC.StringtoCRC(planet)); int size = buffer.position(); buffer.flip(); @@ -230,12 +245,11 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildTargetObjectIffDelta() { - MissionObject mission = (MissionObject) object; - + public IoBuffer buildTargetObjectIffDelta(String template) { + IoBuffer buffer = IoBuffer.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(CRC.StringtoCRC(mission.getMissionTemplateObject())); + buffer.putInt(CRC.StringtoCRC(template)); int size = buffer.position(); buffer.flip(); @@ -244,14 +258,13 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildMissionDescriptionDelta() { - MissionObject mission = (MissionObject) object; + public IoBuffer buildMissionDescriptionDelta(String desc, String id) { - IoBuffer buffer = IoBuffer.allocate(4 + mission.getMissionDescription().length() + mission.getMissionDescId().length(), false).order(ByteOrder.LITTLE_ENDIAN); + IoBuffer buffer = IoBuffer.allocate(8 + desc.length() + id.length(), false).order(ByteOrder.LITTLE_ENDIAN); - buffer.put(getAsciiString(mission.getMissionDescription())); + buffer.put(getAsciiString(desc)); buffer.putInt(0); - buffer.put(getAsciiString(mission.getMissionDescId())); + buffer.put(getAsciiString(id)); int size = buffer.position(); buffer.flip(); @@ -260,14 +273,13 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildMissionTitleDelta() { - MissionObject mission = (MissionObject) object; + public IoBuffer buildMissionTitleDelta(String title, String id) { + + IoBuffer buffer = IoBuffer.allocate(8 + title.length() + id.length(), false).order(ByteOrder.LITTLE_ENDIAN); - IoBuffer buffer = IoBuffer.allocate(4 + mission.getMissionTitle().length() + mission.getMissionTitleId().length(), false).order(ByteOrder.LITTLE_ENDIAN); - - buffer.put(getAsciiString(mission.getMissionTitle())); + buffer.put(getAsciiString(title)); buffer.putInt(0); - buffer.put(getAsciiString(mission.getMissionTitleId())); + buffer.put(getAsciiString(id)); int size = buffer.position(); buffer.flip(); @@ -276,12 +288,11 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildRepeatCounterDelta() { - MissionObject mission = (MissionObject) object; + public IoBuffer buildRepeatCounterDelta(int counter) { IoBuffer buffer = IoBuffer.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(mission.getMissionRepeatCounter()); + buffer.putInt(counter); int size = buffer.position(); buffer.flip(); @@ -290,12 +301,11 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildMissionTypeDelta() { - MissionObject mission = (MissionObject) object; - + public IoBuffer buildMissionTypeDelta(String type) { + IoBuffer buffer = IoBuffer.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(CRC.StringtoCRC(mission.getMissionType())); + buffer.putInt(CRC.StringtoCRC(type)); int size = buffer.position(); buffer.flip(); @@ -304,12 +314,11 @@ public class MissionMessageBuilder extends ObjectMessageBuilder { return buffer; } - public IoBuffer buildTargetNameDelta() { - MissionObject mission = (MissionObject) object; + public IoBuffer buildTargetNameDelta(String targetName) { - IoBuffer buffer = IoBuffer.allocate(4 + mission.getMissionTargetName().length(), false).order(ByteOrder.LITTLE_ENDIAN); + IoBuffer buffer = IoBuffer.allocate(4 + targetName.length(), false).order(ByteOrder.LITTLE_ENDIAN); - buffer.put(getAsciiString(mission.getMissionTargetName())); + buffer.put(getAsciiString(targetName)); int size = buffer.position(); buffer.flip(); diff --git a/src/resources/objects/mission/MissionObject.java b/src/resources/objects/mission/MissionObject.java index c98ab0c7..635da311 100644 --- a/src/resources/objects/mission/MissionObject.java +++ b/src/resources/objects/mission/MissionObject.java @@ -23,7 +23,9 @@ package resources.objects.mission; import com.sleepycat.je.Environment; import com.sleepycat.je.Transaction; +import com.sleepycat.persist.model.Entity; import com.sleepycat.persist.model.NotPersistent; +import com.sleepycat.persist.model.Persistent; import resources.objects.tangible.TangibleObject; import resources.objects.waypoint.WaypointObject; @@ -34,6 +36,7 @@ import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; +@Persistent(version=1) public class MissionObject extends SWGObject implements IPersistent { private float missionDestinationX; @@ -47,12 +50,12 @@ public class MissionObject extends SWGObject implements IPersistent { private String missionDestinationPlanet; private int missionRepeatCounter; // increases for each player using the mission; used for redisplaying on mission term too private int missionCredits; - private String missionCreator; - private String missionDescription; - private String missionTitle; - private String missionTargetName; // target/destination - private String missionDescId; - private String missionTitleId; + private String missionCreator = ""; + private String missionDescription = ""; + private String missionTitle = ""; + private String missionTargetName = ""; // Target object I guess? + private String missionDescId = ""; + private String missionTitleId = ""; private String missionType; private WaypointObject missionAttachedWaypoint; @@ -63,158 +66,222 @@ public class MissionObject extends SWGObject implements IPersistent { @NotPersistent private Transaction txn; - + + public MissionObject() { + super(); + } public MissionObject(long objectID, Planet planet, String template) { super(objectID, planet, new Point3D(0, 0, 0), new Quaternion(1, 0, 0, 0), template); } public float getMissionStartX() { - return missionStartX; + synchronized(objectMutex) { + return missionStartX; + } } public float getMissionStartY() { - return missionStartY; + synchronized(objectMutex) { + return missionStartY; + } } public float getMissionStartZ() { - return missionStartZ; + synchronized(objectMutex) { + return missionStartZ; + } } - public void setMissionStart(float x, float y, float z) { - this.missionStartZ = z; - this.missionStartX = x; - this.missionStartY = y; + public void setMissionStart(float x, float y, float z, String planet) { + synchronized(objectMutex) { + this.missionStartZ = z; + this.missionStartX = x; + this.missionStartY = y; + this.missionStartPlanet = planet; + } + + notifyObservers(messageBuilder.buildStartLocationDelta(x, z, y, planet), false); } public float getMissionDestinationX() { - return missionDestinationX; + synchronized(objectMutex) { + return missionDestinationX; + } } public float getMissionDestinationY() { - return missionDestinationY; + synchronized(objectMutex) { + return missionDestinationY; + } } public float getMissionDestinationZ() { - return missionDestinationZ; + synchronized(objectMutex) { + return missionDestinationZ; + } } - public void setMissionDestination(float x, float y, float z) { - this.missionDestinationZ = z; - this.missionDestinationY = y; - this.missionDestinationZ = z; + public void setMissionDestination(float x, float y, float z, String planet) { + synchronized(objectMutex) { + this.missionDestinationZ = z; + this.missionDestinationY = y; + this.missionDestinationZ = z; + this.missionDestinationPlanet = planet; + } } public String getMissionDestinationPlanet() { - return missionDestinationPlanet; - } - - public void setMissionDestinationPlanet(String missionDestinationPlanet) { - this.missionDestinationPlanet = missionDestinationPlanet; + synchronized(objectMutex) { + return missionDestinationPlanet; + } } public int getMissionLevel() { - return missionLevel; + synchronized(objectMutex) { + return missionLevel; + } } public void setMissionLevel(int missionLevel) { - this.missionLevel = missionLevel; + synchronized(objectMutex) { + this.missionLevel = missionLevel; + } } public String getMissionStartPlanet() { - return missionStartPlanet; - } - - public void setMissionStartPlanet(String missionStartPlanetCRC) { - this.missionStartPlanet = missionStartPlanetCRC; + synchronized(objectMutex) { + return missionStartPlanet; + } } public int getMissionRepeatCounter() { - return missionRepeatCounter; + synchronized(objectMutex) { + return missionRepeatCounter; + } } public void setMissionRepeatCounter(int missionRepeatCounter) { - this.missionRepeatCounter = missionRepeatCounter; + synchronized(objectMutex) { + this.missionRepeatCounter = missionRepeatCounter; + } } public int getMissionCredits() { - return missionCredits; + synchronized(objectMutex) { + return missionCredits; + } } public void setMissionCredits(int missionCredits) { - this.missionCredits = missionCredits; + synchronized(objectMutex) { + this.missionCredits = missionCredits; + } + notifyObservers(messageBuilder.buildCreditsRewardDelta(missionCredits), false); } public String getMissionCreator() { - return missionCreator; + synchronized(objectMutex) { + return missionCreator; + } } public void setMissionCreator(String missionCreator) { - this.missionCreator = missionCreator; + synchronized(objectMutex) { + this.missionCreator = missionCreator; + } + notifyObservers(messageBuilder.buildCreatorNameDelta(missionCreator), false); } public String getMissionDescription() { - return missionDescription; + synchronized(objectMutex) { + return missionDescription; + } } - public void setMissionDescription(String missionDescription) { - this.missionDescription = missionDescription; + public void setMissionDescription(String missionDescription, String id) { + synchronized(objectMutex) { + this.missionDescription = missionDescription; + this.missionDescId = id; + } + notifyObservers(messageBuilder.buildMissionDescriptionDelta(missionDescription, id), false); } public String getMissionTitle() { - return missionTitle; + synchronized(objectMutex) { + return missionTitle; + } } - public void setMissionTitle(String missionTitle) { - this.missionTitle = missionTitle; + public void setMissionTitle(String missionTitle, String id) { + synchronized(objectMutex) { + this.missionTitle = missionTitle; + this.missionTitleId = id; + } + notifyObservers(messageBuilder.buildMissionTitleDelta(missionTitle, id), false); } public String getMissionTargetName() { - return missionTargetName; + synchronized(objectMutex) { + return missionTargetName; + } } public void setMissionTargetName(String missionTargetName) { - this.missionTargetName = missionTargetName; + synchronized(objectMutex) { + this.missionTargetName = missionTargetName; + } + notifyObservers(messageBuilder.buildTargetNameDelta(missionTargetName), false); } public WaypointObject getMissionAttachedWaypoint() { - return missionAttachedWaypoint; + synchronized(objectMutex) { + return missionAttachedWaypoint; + } } public void setMissionAttachedWaypoint(WaypointObject missionAttachedWaypoint) { - this.missionAttachedWaypoint = missionAttachedWaypoint; + synchronized(objectMutex) { + this.missionAttachedWaypoint = missionAttachedWaypoint; + } } - public String getMissionTemplateObject() { - return missionTemplateObject; + public String getTargetTemplateObject() { + synchronized(objectMutex) { + return missionTemplateObject; + } } - public void setMissionTemplateObject(String missionTemplateObject) { - this.missionTemplateObject = missionTemplateObject; + public void setTargetTemplateObject(String missionTemplateObject) { + synchronized(objectMutex) { + this.missionTemplateObject = missionTemplateObject; + } + notifyObservers(messageBuilder.buildTargetObjectIffDelta(missionTemplateObject), false); } public String getMissionDescId() { - return missionDescId; - } - - public void setMissionDescId(String missionDescId) { - this.missionDescId = missionDescId; + synchronized(objectMutex) { + return missionDescId; + } } public String getMissionTitleId() { - return missionTitleId; - } - - public void setMissionTitleId(String missionTitleId) { - this.missionTitleId = missionTitleId; + synchronized(objectMutex) { + return missionTitleId; + } } public String getMissionType() { - return missionType; + synchronized(objectMutex) { + return missionType; + } } public void setMissionType(String missionType) { - this.missionType = missionType; + synchronized(objectMutex) { + this.missionType = missionType; + } + notifyObservers(messageBuilder.buildMissionTypeDelta(missionType), false); } public Transaction getTransaction() { diff --git a/src/resources/objects/tangible/TangibleMessageBuilder.java b/src/resources/objects/tangible/TangibleMessageBuilder.java index fdb7142b..08d93f72 100644 --- a/src/resources/objects/tangible/TangibleMessageBuilder.java +++ b/src/resources/objects/tangible/TangibleMessageBuilder.java @@ -63,7 +63,8 @@ public class TangibleMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); buffer.putInt(0); - buffer.putInt(tangible.getOptionsBitmask()); + buffer.putInt(0); + //buffer.putInt(tangible.getOptionsBitmask()); buffer.putInt(0); // number of item uses buffer.putInt(tangible.getConditionDamage()); buffer.putInt(tangible.getMaxDamage()); diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 5a9a56f6..256c4415 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -358,7 +358,7 @@ public class TangibleObject extends SWGObject { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); - upvpm.setStatus(1); + upvpm.setStatus(getPvPBitmask()); destination.getSession().write(upvpm.serialize()); diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 63550638..11025730 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -37,6 +37,7 @@ import engine.clients.Client; import engine.resources.common.CRC; import engine.resources.container.CreatureContainerPermissions; import engine.resources.container.CreaturePermissions; +import engine.resources.container.Traverser; import engine.resources.database.DatabaseConnection; import engine.resources.objects.SWGObject; import engine.resources.scene.Point3D; @@ -44,7 +45,6 @@ import engine.resources.scene.Quaternion; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import resources.common.*; - import protocol.swg.ClientCreateCharacter; import protocol.swg.ClientMfdStatusUpdateMessage; import protocol.swg.ClientRandomNameRequest; @@ -53,8 +53,8 @@ import protocol.swg.ClientVerifyAndLockNameRequest; import protocol.swg.ClientVerifyAndLockNameResponse; import protocol.swg.CreateCharacterSuccess; import protocol.swg.HeartBeatMessage; - import resources.objects.creature.CreatureObject; +import resources.objects.mission.MissionObject; import resources.objects.player.PlayerObject; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; @@ -87,6 +87,7 @@ public class CharacterService implements INetworkDispatch { swgOpcodes.put(Opcodes.ClientRandomNameRequest, new INetworkRemoteEvent() { public void handlePacket(IoSession session, IoBuffer data) throws Exception { + ClientRandomNameRequest randomNameRequest = new ClientRandomNameRequest(); ClientRandomNameResponse response; String name = null; @@ -95,16 +96,23 @@ public class CharacterService implements INetworkDispatch { data.position(0); randomNameRequest.deserialize(data); + while (name == null) { + + String firstName =""; + String lastName = ""; if (randomNameRequest.getSharedRaceTemplate().contains("wookie")) { - name = nameGenerator.compose(4); + firstName = nameGenerator.compose(4); + } else { - name = nameGenerator.compose(2) + " " + nameGenerator.compose(3); + firstName = nameGenerator.compose(2); + lastName = nameGenerator.compose(3); } try { - if (checkForDuplicateName(getfirstName(name, randomNameRequest.getSharedRaceTemplate()))) { - name = null; + //it's fine here to just use 0 as accountId because we don't want reserved names to be random generated for anyone. + if (!checkForDuplicateName(firstName, 0)) { + name = firstName + ((lastName.length() > 0 ) ? " " + lastName : ""); } } catch (SQLException e2) { e2.printStackTrace(); @@ -121,6 +129,8 @@ public class CharacterService implements INetworkDispatch { @Override public void handlePacket(IoSession session, IoBuffer data) throws Exception { + + Client client = core.getClient((Integer) session.getAttribute("connectionId")); data = data.order(ByteOrder.LITTLE_ENDIAN); data.position(0); ClientVerifyAndLockNameRequest message = new ClientVerifyAndLockNameRequest(); @@ -129,11 +139,11 @@ public class CharacterService implements INetworkDispatch { boolean isDeclined = false; String firstName = getfirstName(message.getName(), message.getRaceTemplate()); String lastName = getlastName(message.getName(), message.getRaceTemplate()); - if(message.getName() != null) System.out.println(message.getName()); + //if(message.getName() != null) System.out.println(message.getName()); int length = firstName.length(); try { - if (checkForDuplicateName(firstName)) { + if (checkForDuplicateName(firstName, client.getAccountId())) { approved_flag = "name_declined_in_use"; isDeclined = true; @@ -193,17 +203,16 @@ public class CharacterService implements INetworkDispatch { } int galaxyId = config.getInt("GALAXY_ID"); + Client client = core.getClient((Integer) session.getAttribute("connectionId")); try { - if (checkForDuplicateName(getfirstName(clientCreateCharacter.getName(), clientCreateCharacter.getRaceTemplate()))) { + if (checkForDuplicateName(getfirstName(clientCreateCharacter.getName(), clientCreateCharacter.getRaceTemplate()), client.getAccountId())) { return; } } catch (SQLException e2) { e2.printStackTrace(); } - Client client = core.getClient((Integer) session.getAttribute("connectionId")); - // TODO: Add starting location and items in a script String raceTemplate = clientCreateCharacter.getRaceTemplate(); // should set to some planet and starting location @@ -234,10 +243,12 @@ public class CharacterService implements INetworkDispatch { if (constitution >= 1) core.skillModService.addSkillMod(object, "constitution", (int) constitution); if (stamina >= 1) core.skillModService.addSkillMod(object, "stamina", (int) stamina); if (agility >= 1) core.skillModService.addSkillMod(object, "agility", (int) agility); + object.createTransaction(core.getCreatureODB().getEnvironment()); PlayerObject player = (PlayerObject) core.objectService.createObject("object/player/shared_player.iff", object.getPlanet()); object._add(player); + core.skillService.addSkill(object, "species_" + object.getStfName()); player.setProfession(clientCreateCharacter.getProfession()); player.setProfessionWheelPosition(clientCreateCharacter.getProfessionWheelPosition()); if(clientCreateCharacter.getHairObject().length() > 0) { @@ -264,6 +275,14 @@ public class CharacterService implements INetworkDispatch { object._add(datapad); object._add(bank); object._add(missionBag); + + /*for(int missionsAdded = 0; missionsAdded < 12; missionsAdded++) { + MissionObject mission = (MissionObject) core.objectService.createObject("object/mission/shared_mission_object.iff", object.getPlanet()); + + missionBag._add(mission); + Console.println("Added empty mission " + missionsAdded); + }*/ + TangibleObject backpack = (TangibleObject) core.objectService.createObject("object/tangible/wearables/backpack/shared_backpack_galactic_marine.iff", object.getPlanet()); inventory._add(backpack); //object.addObjectToEquipList(datapad); @@ -311,63 +330,72 @@ public class CharacterService implements INetworkDispatch { } - private boolean checkForDuplicateName(String firstName) throws SQLException + private boolean checkForDuplicateName(String firstName, long accountId) throws SQLException { firstName = firstName.replace("'", "''"); firstName = firstName.toLowerCase(); - PreparedStatement ps = databaseConnection.preparedStatement("SELECT id FROM characters WHERE LOWER(\"firstName\") ='" + firstName + "'"); + PreparedStatement ps = databaseConnection.preparedStatement("SELECT id FROM characters WHERE LOWER(\"firstName\")=?"); + ps.setString(1, firstName); + //System.out.println(ps.toString()); ResultSet resultSet = ps.executeQuery(); - - boolean bool = resultSet.next(); + + boolean isDuplicate = resultSet.next(); resultSet.getStatement().close(); - return bool; - } - + if (isDuplicate) { return true; } + //FIXME: this is a bit lazy... but it's only temporary :p + PreparedStatement psc = databaseConnection.preparedStatement("SELECT * FROM pg_tables WHERE \"tablename\"=?"); + psc.setString(1, "temp_reserved_char_names"); + ResultSet resultSetC = psc.executeQuery(); + boolean tableExists = resultSetC.next(); + resultSetC.getStatement().close(); + if (!tableExists) { return false; } + + PreparedStatement ps2 = databaseConnection.preparedStatement("SELECT \"accountId\" FROM temp_reserved_char_names WHERE \"accountId\"!=? AND LOWER(\"firstName\")=?"); + ps2.setLong(1, accountId); + ps2.setString(2, firstName); + ResultSet resultSet2 = ps2.executeQuery(); + boolean isReserved = resultSet2.next(); + resultSet2.getStatement().close(); + + return isReserved; + } + + private String getfirstName(String Name, String RaceTemplate) { - String[] splitName; - if (RaceTemplate != "object/creature/player/wookiee_male.iff" | RaceTemplate != "object/creature/player/wookiee_female.iff") + if (RaceTemplate.contains("/wookiee_") || + !Name.contains(" ")) { // wookies don't have lastNames - if (Name.contains(" ")) - { - splitName = Name.split(" ", 2); - return splitName[0]; - } - else - { return Name; - } - } - else - { - return Name; } + + return Name.split(" ", 2)[0]; + } private String getlastName(String Name, String RaceTemplate) { - String[] splitName; - if (RaceTemplate != "object/creature/player/wookiee_male.iff" && RaceTemplate != "object/creature/player/wookiee_female.iff") + if (RaceTemplate.contains("/wookiee_") || + !Name.contains(" ")) { // wookies don't have lastNames - if (Name.contains(" ")) - { - splitName = Name.split(" ", 2); - return splitName[1]; - } - else - { - return ""; - } - } - else - { return ""; } + + return Name.split(" ", 2)[1]; + } private String checkForReservedName(String firstName, String lastName) throws SQLException { + + PreparedStatement psc = databaseConnection.preparedStatement("SELECT * FROM pg_tables WHERE \"tablename\"=?"); + psc.setString(1, "reservednames"); + ResultSet rsc = psc.executeQuery(); + if (!rsc.next()) { + return null; + } + firstName = firstName.toLowerCase(); lastName = lastName.toLowerCase(); diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index b094b647..a2f291ed 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -69,6 +69,8 @@ public class ConnectionService implements INetworkDispatch { @Override public void handlePacket(IoSession session, IoBuffer data) throws Exception { + + System.out.println("xx"); data = data.order(ByteOrder.LITTLE_ENDIAN); ClientIdMsg clientIdMsg = new ClientIdMsg(); data.position(0); @@ -84,19 +86,22 @@ public class ConnectionService implements INetworkDispatch { PreparedStatement preparedStatement; try { - + preparedStatement = databaseConnection.preparedStatement("SELECT * FROM sessions WHERE key=?"); preparedStatement.setBytes(1, clientIdMsg.getSessionKey()); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { - client.setAccountId(resultSet.getInt("accountId")); + client.setAccountId(resultSet.getLong("accountId")); + client.setSessionKey(clientIdMsg.getSessionKey()); AccountFeatureBits accountFeatureBits = new AccountFeatureBits(); ClientPermissionsMessage clientPermissionsMessage = new ClientPermissionsMessage(); session.write(new HeartBeatMessage().serialize()); session.write(accountFeatureBits.serialize()); session.write(clientPermissionsMessage.serialize()); preparedStatement.close(); + + System.out.println("zyx"); } else { System.out.println("Cant get login session"); } @@ -105,8 +110,8 @@ public class ConnectionService implements INetworkDispatch { e.printStackTrace(); - } - + } + } diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index 896f2525..60a6d7a0 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -1,6 +1,8 @@ package services; import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; @@ -17,6 +19,7 @@ import protocol.swg.objectControllerObjects.BuffBuilderStartMessage; import resources.common.BuffBuilder; import resources.common.Console; import resources.common.ObjControllerOpcodes; +import resources.common.Performance; import resources.objects.Buff; import resources.objects.BuffItem; import resources.objects.creature.CreatureObject; @@ -33,10 +36,15 @@ public class EntertainmentService implements INetworkDispatch { private NGECore core; private Vector buffBuilderSkills = new Vector(); + //FIXME: create a wrapper class for double key lookup maps + private HashMap performances = new HashMap(); + private HashMap danceMap = new HashMap(); public EntertainmentService(NGECore core) { this.core = core; populateSkillCaps(); + populatePerformanceTable(); + registerCommands(); } @Override @@ -128,6 +136,59 @@ public class EntertainmentService implements INetworkDispatch { }); } + private void populatePerformanceTable() { + + try { + DatatableVisitor PerformanceVisitor = ClientFileManager.loadFile("datatables/performance/performance.iff", DatatableVisitor.class); + + //rformanceVisitor. + + for (int r = 0; r < PerformanceVisitor.getRowCount(); r++) { + Performance p = new Performance(); + + /* for (int j=0; j < PerformanceVisitor.getColumnCount(); j++) { + System.out.println(j + ": " + PerformanceVisitor.getObject(r, j)); + }*/ + + p.setPerformanceName( ( (String) PerformanceVisitor.getObject(r, 0) ).toLowerCase()); + p.setInstrumentAudioId((int) PerformanceVisitor.getObject(r, 1)); + p.setRequiredSong((String) PerformanceVisitor.getObject(r, 2)); + p.setRequiredInstrument((String) PerformanceVisitor.getObject(r, 3)); + p.setRequiredDance((String) PerformanceVisitor.getObject(r, 4)); + p.setDanceVisualId((int) PerformanceVisitor.getObject(r, 5)); + p.setActionPointsPerLoop((int) PerformanceVisitor.getObject(r, 6)); + p.setLoopDuration((float) PerformanceVisitor.getObject(r, 7)); + p.setType((int) PerformanceVisitor.getObject(r, 8)); + p.setBaseXp((int) PerformanceVisitor.getObject(r, 9)); + p.setFlourishXpMod((int) PerformanceVisitor.getObject(r, 10)); + p.setHealMindWound((int) PerformanceVisitor.getObject(r, 11)); + p.setHealShockWound((int) PerformanceVisitor.getObject(r, 12)); + p.setRequiredSkillMod((String) PerformanceVisitor.getObject(r, 13)); + p.setRequiredSkillModValue((int) PerformanceVisitor.getObject(r, 14)); + p.setMainloop((String) PerformanceVisitor.getObject(r, 15)); + p.setFlourish1((String) PerformanceVisitor.getObject(r, 16)); + p.setFlourish2((String) PerformanceVisitor.getObject(r, 17)); + p.setFlourish3((String) PerformanceVisitor.getObject(r, 18)); + p.setFlourish4((String) PerformanceVisitor.getObject(r, 19)); + p.setFlourish5((String) PerformanceVisitor.getObject(r, 20)); + p.setFlourish6((String) PerformanceVisitor.getObject(r, 21)); + p.setFlourish7((String) PerformanceVisitor.getObject(r, 22)); + p.setFlourish8((String) PerformanceVisitor.getObject(r, 23)); + p.setIntro((String) PerformanceVisitor.getObject(r, 24)); + p.setOutro((String) PerformanceVisitor.getObject(r, 25)); + p.setLineNumber(r); + + if (p.getType() == -1788534963) { + danceMap.put(new Integer(p.getDanceVisualId()), p); + } + performances.put(p.getPerformanceName(), p); + } + + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + } + private void populateSkillCaps() { try { DatatableVisitor buffBuilder = ClientFileManager.loadFile("datatables/buff/buff_builder.iff", DatatableVisitor.class); @@ -152,6 +213,15 @@ public class EntertainmentService implements INetworkDispatch { e.printStackTrace(); } } + + private void registerCommands() { + core.commandService.registerCommand("bandflourish"); + core.commandService.registerCommand("flourish"); + core.commandService.registerAlias("flo","flourish"); + core.commandService.registerCommand("groupdance"); + core.commandService.registerCommand("startdance"); + core.commandService.registerCommand("stopdance"); + } public void giveInspirationBuff(SWGObject reciever, Vector buffVector) { CreatureObject buffCreature = (CreatureObject) reciever; @@ -177,6 +247,49 @@ public class EntertainmentService implements INetworkDispatch { } + public int getDanceVisualId(String danceName) { + Performance p = performances.get(danceName); + + //if 0 , then it's no dance. need to handle that in the script. + return p.getDanceVisualId(); + } + + public Map getAvailableDances(CreatureObject actor) { + + Map dances = new HashMap(); + for (int index : danceMap.keySet()) { + if (!canDance(actor, danceMap.get(index) )) { continue; } + dances.put( new Long( danceMap.get(index).getDanceVisualId() ), danceMap.get(index).getPerformanceName() ); + } + + return dances; + + } + + public boolean isDance(int visualId) { + return ( danceMap.get(visualId) != null ) ; + } + + public boolean canDance(CreatureObject actor, Performance dance) { + if (actor.hasAbility(dance.getRequiredDance())) { + return true; + } + return false; + } + + public boolean canDance(CreatureObject actor, int visualId) { + if (!isDance(visualId)) { return false; } + return canDance(actor, danceMap.get(visualId)); + } + + public Performance getDance(int visualId) { + return danceMap.get(visualId); + } + + public Performance getPerformance(String name) { + return performances.get(name); + } + @Override public void shutdown() { diff --git a/src/services/EquipmentService.java b/src/services/EquipmentService.java index 8223e3b0..ddb56bdb 100644 --- a/src/services/EquipmentService.java +++ b/src/services/EquipmentService.java @@ -50,10 +50,10 @@ public class EquipmentService implements INetworkDispatch { } - public void equip(CreatureObject actor, SWGObject item, SWGObject replacedItem) { + public void equip(CreatureObject actor, SWGObject item) { - if(replacedItem != null) - unequip(actor, replacedItem); + //if(replacedItem != null) + // unequip(actor, replacedItem); String template = item.getTemplate(); String serverTemplate = template.replace(".iff", ""); diff --git a/src/services/LoginService.java b/src/services/LoginService.java index 92a3d42c..a4904be8 100644 --- a/src/services/LoginService.java +++ b/src/services/LoginService.java @@ -37,8 +37,11 @@ import org.apache.mina.core.session.IoSession; import engine.clients.Client; import engine.protocol.soe.Disconnect; import engine.resources.database.DatabaseConnection; +import engine.resources.service.ILoginProvider; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; +import engine.resources.service.LocalDbLoginProvider; +import engine.resources.service.VBLoginProvider; import protocol.swg.CharacterCreationDisabled; import protocol.swg.ClientUIErrorMessage; @@ -61,16 +64,22 @@ public class LoginService implements INetworkDispatch{ private int sessionKeyLength = 0; private NGECore core; - private DatabaseConnection databaseConnection; + private DatabaseConnection databaseConnection1; private DatabaseConnection databaseConnection2; private Random random; + private ILoginProvider LoginProvider; public LoginService(NGECore core) { this.core = core; this.sessionKeyLength = core.getConfig().getInt("LOGIN.SESSION_KEY_SIZE"); - this.databaseConnection = core.getDatabase1(); + this.databaseConnection1 = core.getDatabase1(); this.databaseConnection2 = core.getDatabase2(); this.random = new Random(); + if (databaseConnection2 == null) { + LoginProvider = new LocalDbLoginProvider(databaseConnection1); + } else { + LoginProvider = new VBLoginProvider(databaseConnection1, databaseConnection2); + } } public void insertTimedEventBindings(ScheduledExecutorService executor) { @@ -88,19 +97,24 @@ public class LoginService implements INetworkDispatch{ data.position(0); clientID.deserialize(data); - String err = ""; String user = clientID.getAccountName(); String pass = clientID.getPassword(); - int id = getAccountID(user); - if (id == -1) err = "Invalid Username"; - //String email = getAccountEmail(user); - //String encryptPass = getAccountPassword(user); + int id = LoginProvider.getAccountId(user, pass, session.getRemoteAddress().toString()); - if (err == "") - err = canUserLogin(user, /*email*/"", pass, /*encryptPass*/"", id, session.getRemoteAddress().toString()); - - if (err != "") { - System.out.println(user + " failed login because " + err); + if (id < 0) { + + String err = ""; + switch (id) { + case -1: + err = "Database error"; + break; + case -2: + err = "invalid user or password"; + break; + case -3: + err = "user is banned"; + break; + } ClientUIErrorMessage errMsg = new ClientUIErrorMessage("Invalid Login", err); session.write(errMsg.serialize()); Disconnect disconnect = new Disconnect((Integer)session.getAttribute("connectionId"), 6); @@ -167,7 +181,7 @@ public class LoginService implements INetworkDispatch{ PreparedStatement preparedStatement; - preparedStatement = databaseConnection.preparedStatement("DELETE FROM characters WHERE \"id\"=? AND \"galaxyId\"=? AND \"accountId\"=?"); + preparedStatement = databaseConnection1.preparedStatement("DELETE FROM characters WHERE \"id\"=? AND \"galaxyId\"=? AND \"accountId\"=?"); preparedStatement.setLong(1, packet.getcharId()); preparedStatement.setInt(2, packet.getgalaxyId()); preparedStatement.setInt(3, (int) client.getAccountId()); @@ -196,9 +210,9 @@ public class LoginService implements INetworkDispatch{ */ private void persistSession(Client client) throws SQLException { - String sessionValues = "?, " + client.getAccountId(); - PreparedStatement ps = databaseConnection.preparedStatement("INSERT INTO sessions (key, \"accountId\") VALUES (" + sessionValues + ")"); + PreparedStatement ps = databaseConnection1.preparedStatement("INSERT INTO sessions (\"key\", \"accountId\") VALUES (?, ?)"); ps.setBytes(1, client.getSessionKey()); + ps.setLong(2, client.getAccountId()); ps.executeUpdate(); ps.close(); @@ -226,7 +240,7 @@ public class LoginService implements INetworkDispatch{ PreparedStatement preparedStatement; try { - preparedStatement = databaseConnection.preparedStatement("SELECT * FROM characters WHERE \"accountId\"=" + id + ""); + preparedStatement = databaseConnection1.preparedStatement("SELECT * FROM characters WHERE \"accountId\"=" + id + ""); resultSet = preparedStatement.executeQuery(); while (resultSet.next() && !resultSet.isClosed()) { @@ -257,7 +271,7 @@ public class LoginService implements INetworkDispatch{ LoginEnumCluster servers = new LoginEnumCluster(9); PreparedStatement preparedStatement; try { - preparedStatement = databaseConnection.preparedStatement("SELECT * FROM galaxies"); + preparedStatement = databaseConnection1.preparedStatement("SELECT * FROM galaxies"); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next() && !resultSet.isClosed()) servers.addServer(resultSet.getInt("id"), resultSet.getString("name")); @@ -276,7 +290,7 @@ public class LoginService implements INetworkDispatch{ LoginClusterStatus clusterStatus = new LoginClusterStatus(); ResultSet resultSet; try { - PreparedStatement preparedStatement = databaseConnection.preparedStatement("SELECT * FROM \"connectionServers\""); + PreparedStatement preparedStatement = databaseConnection1.preparedStatement("SELECT * FROM \"connectionServers\""); resultSet = preparedStatement.executeQuery(); while (resultSet.next() && !resultSet.isClosed()) clusterStatus.addServer( @@ -294,111 +308,6 @@ public class LoginService implements INetworkDispatch{ return clusterStatus; } - /** - * Checks if account ID exists in game DB. - * @param id Account ID. - */ - private boolean checkIfAccountExistInGameDB(int id) { - try { - PreparedStatement preparedStatement = databaseConnection.preparedStatement("SELECT * FROM accounts WHERE id=?"); - preparedStatement.setInt(1, id); - ResultSet resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - return true; - } - } catch (SQLException e) { - e.printStackTrace(); - } - return false; - } - - /** - * Saves forum account to game DB if the account does not exist in the game DB already. - * @param id Account ID. - * @param user Username - * @param email User's email - * @param pass Hashed password - */ - private void createAccountForGameDB(int id, String user, String email, String pass) { - try { - PreparedStatement ps = databaseConnection.preparedStatement("INSERT INTO accounts (id, \"user\", \"pass\", \"email\") VALUES (?, ?, ?, ?)"); - ps.setInt(1, id); - ps.setString(2, user); - ps.setString(3, pass); - ps.setString(4, email); - ps.executeUpdate(); - ps.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Checks if user is allowed to login. - * @param id Account ID. - * @param user Username - * @param email User's email - * @param pass User password - * @param encryptPass encrypted password - * @param ip Users IP address - */ - private String canUserLogin(String user, String email, String pass, String encryptPass, int id, String ip) { - /*if ((new PHPBB3Auth()).phpbb_check_hash(pass, encryptPass)) { - if(checkBanlistforUserAndIP(id, ip)) { - return "You cannot login to the ProjectSWG server while being banned from ProjectSWG services"; - } - return ""; - } else { - return "Invalid Password"; - }*/ - - try { - PreparedStatement ps = databaseConnection.preparedStatement("SELECT * FROM accounts WHERE id=" + id + " AND \"pass\"='" + pass + "'"); - ResultSet resultSet = ps.executeQuery(); - - if (resultSet.next()) { - - return ""; - - } - } catch (SQLException e) { - e.printStackTrace(); - } - - return "Invalid Password"; - - - } - /** - * Checks if User has a forum account or IP ban. - * @param id Account ID. - * @param ip User's IP address. - */ - private boolean checkBanlistforUserAndIP(int id, String ip) { - if (!ip.contains("/")) - return false; - String IP = ((ip.split("/", 2)[1]).split(", ", 2)[0]).split(":", 2)[0]; - try { - PreparedStatement preparedStatement = databaseConnection2.preparedStatement("SELECT ban_id FROM phpbb_banlist WHERE ban_ip=?"); - preparedStatement.setString(1, IP); - ResultSet resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - return true; - } else { - preparedStatement.close(); - preparedStatement = databaseConnection2.preparedStatement("SELECT ban_id FROM phpbb_banlist WHERE ban_userid=?"); - preparedStatement.setInt(1, id); - resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - return true; - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - return false; - } - /** * Checks if User has correct client version. * @param version Client Version String @@ -407,61 +316,6 @@ public class LoginService implements INetworkDispatch{ System.out.println("Version Received: " + version); return true; } - - /** - * Gets Account ID from forum DB by username. - * @param user Username. - */ - private int getAccountID(String user) { - try { - PreparedStatement pStatement = databaseConnection.preparedStatement("SELECT id FROM accounts WHERE \"user\"='" + user + "'"); - ResultSet resultSet = pStatement.executeQuery(); - if (resultSet.next()) { - return resultSet.getInt("id"); - } - } catch (SQLException e) { - e.printStackTrace(); - }; - return -1; - } - - /** - * Gets Account Email from forum DB by username. - * @param user Username. - */ - private String getAccountEmail(String user) { - try { - PreparedStatement pStatement = databaseConnection2.preparedStatement("SELECT user_email FROM phpbb_users WHERE username=?"); - pStatement.setString(1, user); - ResultSet resultSet = pStatement.executeQuery(); - - if (resultSet.next()) { - return resultSet.getString("user_email"); - } - } catch (SQLException e) { - e.printStackTrace(); - }; - return ""; - } - - /** - * Gets hashed Account Password from forum DB by username. - * @param user Username. - */ - private String getAccountPassword(String user) { - try { - PreparedStatement pStatement = databaseConnection2.preparedStatement("SELECT user_password FROM phpbb_users WHERE username=?"); - pStatement.setString(1, user); - ResultSet resultSet = pStatement.executeQuery(); - - if (resultSet.next()) { - return resultSet.getString("user_password"); - } - pStatement.close(); - } catch (SQLException e) { - e.printStackTrace(); - }; - return ""; - } - + } + diff --git a/src/services/MissionService.java b/src/services/MissionService.java index d376f698..4eaca9bb 100644 --- a/src/services/MissionService.java +++ b/src/services/MissionService.java @@ -21,29 +21,192 @@ ******************************************************************************/ package services; +import java.nio.ByteOrder; import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import main.NGECore; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; +import protocol.swg.objectControllerObjects.MissionListRequest; +import resources.common.Console; +import resources.common.TerminalType; import resources.common.ObjControllerOpcodes; +import resources.objects.creature.CreatureObject; +import resources.objects.mission.MissionObject; +import resources.objects.tangible.TangibleObject; +import engine.clientdata.ClientFileManager; +import engine.clientdata.visitors.DatatableVisitor; +import engine.clients.Client; +import engine.resources.container.Traverser; +import engine.resources.objects.SWGObject; +import engine.resources.scene.Planet; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; public class MissionService implements INetworkDispatch { + private NGECore core; + + public MissionService(NGECore core) { + this.core = core; + } + @Override public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { objControllerOpcodes.put(ObjControllerOpcodes.MISSION_LIST_REQUEST, new INetworkRemoteEvent() { @Override public void handlePacket(IoSession session, IoBuffer data) throws Exception { + data.order(ByteOrder.LITTLE_ENDIAN); + + MissionListRequest request = new MissionListRequest(); + request.deserialize(data); + + Client client = core.getClient((Integer) session.getAttribute("connectionId")); + if(client == null || client.getSession() == null) + return; + + SWGObject object = client.getParent(); + + if(object == null) + return; + + SWGObject terminal = core.objectService.getObject(request.getTerminalId()); + + int terminalType = (int) terminal.getAttachment("terminalType"); + + if (terminalType == TerminalType.MISSION_GENERIC) { + populateMissions(core.objectService.getObject(request.getObjectId()), TerminalType.MISSION_GENERIC); + } else if (terminalType == TerminalType.MISSION_BOUNTYHUNTER) { + + } else if (terminalType == TerminalType.MISSION_ENTERTAINER) { + + } else if (terminalType == TerminalType.MISSION_ARTISAN) { + + } else { + Console.println("ERROR: Unsupported terminal " + terminal.getObjectId()); + } } }); } + + private void populateMissions(final SWGObject player, int type) { + CreatureObject creature = (CreatureObject) player; + TangibleObject missionBag = (TangibleObject) creature.getSlottedObject("mission_bag"); + + final AtomicInteger deliveryCount = new AtomicInteger(); + final AtomicInteger destroyCount = new AtomicInteger(); + final int deliveryEntries = 30; + + final Random ran = new Random(); + + final int bagSize = core.objectService.objsInContainer(creature, missionBag); + Console.println("Delivery Entries: " + deliveryEntries); + if (bagSize != 12) { + for(int missionsAdded = 0; missionsAdded < 12; missionsAdded++) { + MissionObject mission = (MissionObject) core.objectService.createObject("object/mission/shared_mission_object.iff", creature.getPlanet()); + + int textId = ran.nextInt(deliveryEntries); + + Console.println("Random Int Value: " + textId); + Console.println("Now the value is: " + textId); + + mission.setMissionLevel(5); + + mission.setMissionStart(0, 0, 0, player.getPlanet().name); + + mission.setMissionCreator("Waverunner"); + mission.setMissionCredits(9000); + + // TODO: Base this off of textId + f + mission.setTargetTemplateObject("object/tangible/mission/shared_mission_datadisk.iff"); + // TODO: Base this off of textId + l + mission.setMissionTargetName("Osskscosco"); + + mission.setMissionDescription("mission/mission_deliver_neutral_easy", "m" + textId + "d"); + mission.setMissionTitle("mission/mission_deliver_neutral_easy", "m" + textId + "t"); + + mission.setMissionType("deliver"); + + mission.setMissionDestination(-5962, 0, -6259, player.getPlanet().name); + deliveryCount.getAndIncrement(); + + + missionBag._add(mission); + Console.println("Added mission " + missionsAdded); + } + return; + } + + missionBag.viewChildren(player, false, false, new Traverser() { + + @Override + public void process(SWGObject child) { + if (deliveryCount.get() == 6) + return; + + MissionObject mission = (MissionObject) child; + int textId = ran.nextInt(deliveryEntries); + + Console.println("Random Int Value: " + textId); + Console.println("Now the value is: " + textId); + + mission.setMissionLevel(5); + + mission.setMissionStart(0, 0, 0, player.getPlanet().name); + + mission.setMissionCreator("Waverunner"); + mission.setMissionCredits(9000); + + // TODO: Base this off of textId + f + mission.setTargetTemplateObject("object/tangible/mission/shared_mission_datadisk.iff"); + // TODO: Base this off of textId + l + mission.setMissionTargetName("Osskscosco"); + + mission.setMissionDescription("mission/mission_deliver_neutral_easy", "m" + textId + "d"); + mission.setMissionTitle("mission/mission_deliver_neutral_easy", "m" + textId + "t"); + + mission.setMissionType("deliver"); + + mission.setMissionDestination(-5962, 0, -6259, player.getPlanet().name); + deliveryCount.getAndIncrement(); + } + + }); + + Console.println("Outside of the traverser now!"); + } + + // May want to create a map for the server with needed info + public int getNumberOfEntries(String stf) { + try { + DatatableVisitor stfFile = ClientFileManager.loadFile(stf, DatatableVisitor.class); + + for (int s = 0; s < stfFile.getRowCount(); s++) { + String name = ((String) stfFile.getObject(s, 3)); + Console.println("Name: " + name); + if (name.equals("number_of_entries")) { + int entryCount = ((int) stfFile.getObject(s, 4)); + Console.println("Entry Count: " + entryCount); + return entryCount; + } + } + } + catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + + return 0; + } + @Override public void shutdown() { diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index 453c7945..8a986c22 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -127,6 +127,7 @@ public class PlayerService implements INetworkDispatch { } }, 0, 1000, TimeUnit.MILLISECONDS); + scheduler.scheduleAtFixedRate(new Runnable() { @@ -142,18 +143,6 @@ public class PlayerService implements INetworkDispatch { }, 0, 1000, TimeUnit.MILLISECONDS); - /*scheduler.scheduleAtFixedRate(new Runnable() { - - @Override - public void run() { - - if(creature.getCombatFlag() == 1) - creature.resetHAMList(); - - } - - }, 0, 10, TimeUnit.SECONDS);*/ - } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 31ee4181..bdb41719 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -169,18 +169,30 @@ public class SimulationService implements INetworkDispatch { return collidableQuadTrees.get(planet.getName()).get(x, y, range); } - public void add(SWGObject object, int x, int y) { - object.setIsInQuadtree(true); - core.objectService.loadServerTemplate(object); - quadTrees.get(object.getPlanet().getName()).put(x, y, object); - } - public boolean add(SWGObject object, float x, float y) { + return add(object, x, y, false); + } + + public boolean add(SWGObject object, float x, float y, boolean notifyObservers) { object.setIsInQuadtree(true); core.objectService.loadServerTemplate(object); - return quadTrees.get(object.getPlanet().getName()).put(x, y, object); + boolean success = quadTrees.get(object.getPlanet().getName()).put(x, y, object); + if(success && notifyObservers) { + Point3D pos = new Point3D(x, 0, y); + Collection newAwareObjects = get(object.getPlanet(), x, y, 512); + for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { + SWGObject obj = it.next(); + if(obj.getAttachment("bigSpawnRange") == null && obj.getWorldPosition().getDistance(pos) > 200) + continue; + if(object.getClient() != null) + object.makeAware(obj); + if(obj.getClient() != null) + obj.makeAware(object); + } + } + return success; } - + public boolean move(SWGObject object, int oldX, int oldY, int newX, int newY) { if(quadTrees.get(object.getPlanet().getName()).remove(oldX, oldY, object)) { return quadTrees.get(object.getPlanet().getName()).put(newX, newY, object); @@ -198,22 +210,27 @@ public class SimulationService implements INetworkDispatch { System.out.println("Move failed."); return false; } - - public List get(Planet planet, int x, int y, int range) { - return quadTrees.get(planet.getName()).get(x, y, range); - } - + public List get(Planet planet, float x, float y, int range) { List list = quadTrees.get(planet.getName()).get((int)x, (int)y, range); return list; } - public boolean remove(SWGObject object, int x, int y) { - return quadTrees.get(object.getPlanet().getName()).remove(x, y, object); - } - public boolean remove(SWGObject object, float x, float y) { + return remove(object, x, y, false); + } + + public boolean remove(SWGObject object, float x, float y, boolean notifyObservers) { boolean success = quadTrees.get(object.getPlanet().getName()).remove(x, y, object); + if(success) { + HashSet oldObservers = new HashSet(object.getObservers()); + for(Iterator it = oldObservers.iterator(); it.hasNext();) { + Client observerClient = it.next(); + if(observerClient.getParent() != null) { + observerClient.getParent().makeUnaware(object); + } + } + } return success; } @@ -284,6 +301,10 @@ public class SimulationService implements INetworkDispatch { object.makeUnaware(obj); if(obj.getClient() != null) obj.makeUnaware(object); + } else if(obj != object && obj.getWorldPosition().getDistance2D(newPos) > 200 && obj.isInQuadtree() && obj.getAttachment("bigSpawnRange") == null) { + object.makeUnaware(obj); + if(obj.getClient() != null) + obj.makeUnaware(object); } } for(int i = 0; i < newAwareObjects.size(); i++) { @@ -299,7 +320,10 @@ public class SimulationService implements INetworkDispatch { } checkForCollidables(object); - + MoveEvent event = new MoveEvent(); + event.object = object; + object.getEventBus().publish(event); + } @@ -512,11 +536,11 @@ public class SimulationService implements INetworkDispatch { } session.suspendWrite(); - + boolean remove = remove(object, object.getPosition().x, object.getPosition().z); if(remove) System.out.println("Successful quadtree remove"); - + //if(object.getContainer() == null) { HashSet oldObservers = new HashSet(object.getObservers()); for(Iterator it = oldObservers.iterator(); it.hasNext();) { @@ -551,49 +575,21 @@ public class SimulationService implements INetworkDispatch { Point3D pos = object.getWorldPosition(); - Collection newAwareObjects = get(object.getPlanet(), pos.x, pos.z, 512); - for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { - SWGObject obj = it.next(); - if(obj.getAttachment("bigSpawnRange") == null & obj.getWorldPosition().getDistance(pos) > 200) - continue; - object.makeAware(obj); - if(obj.getClient() != null) - obj.makeAware(object); + if(object.getParentId() != 0) { + Collection newAwareObjects = get(object.getPlanet(), pos.x, pos.z, 512); + for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { + SWGObject obj = it.next(); + if(obj.getAttachment("bigSpawnRange") == null & obj.getWorldPosition().getDistance(pos) > 200) + continue; + object.makeAware(obj); + if(obj.getClient() != null) + obj.makeAware(object); + } + } else { + add(object, pos.x, pos.z, true); } - if(object.getParentId() == 0) - add(object, pos.x, pos.z); - - PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); - if (ghost != null) { - - String objectShortName = object.getCustomName().toLowerCase(); - - if (object.getCustomName().contains(" ")) { - String[] splitName = object.getCustomName().toLowerCase().split(" "); - objectShortName = splitName[0].toLowerCase(); - } - - core.chatService.playerStatusChange(objectShortName, (byte) 1); - - if (ghost.getFriendList().isEmpty() == false) { - // Find out what friends are online/offline - for (String friend : ghost.getFriendList()) { - SWGObject friendObject = (SWGObject) core.chatService.getObjectByFirstName(friend); - if (friendObject == null) - continue; - if(friendObject.isInQuadtree() == true) { - ChatFriendsListUpdate onlineNotifyStatus = new ChatFriendsListUpdate(friend, (byte) 1); - client.getSession().write(onlineNotifyStatus.serialize()); - - } else { - ChatOnChangeFriendStatus changeStatus = new ChatOnChangeFriendStatus(object.getObjectID(), friend, 0); - client.getSession().write(changeStatus.serialize()); - } - } - } - } core.weatherService.sendWeather(object); @@ -621,18 +617,18 @@ public class SimulationService implements INetworkDispatch { Point3D position = object.getPosition(); if(object.getParentId() == 0 && object.getContainer() == null) { - remove(object, position.x, position.z); + remove(object, position.x, position.z, true); } else { object.getContainer().remove(object); } - HashSet oldObservers = new HashSet(object.getObservers()); + /*HashSet oldObservers = new HashSet(object.getObservers()); for(Client observerClient : oldObservers) { if(observerClient.getParent() != null) { observerClient.getParent().makeUnaware(object); } - } + }*/ synchronized(object.getMutex()) { @@ -952,7 +948,7 @@ public class SimulationService implements INetworkDispatch { public void checkForCollidables(SWGObject object) { Point3D objectPos = object.getWorldPosition(); - List collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 256); + List collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 2050); for(AbstractCollidable collidable : collidables) { collidable.doCollisionCheck(object); diff --git a/src/services/SkillService.java b/src/services/SkillService.java index da016e3a..c90d1095 100644 --- a/src/services/SkillService.java +++ b/src/services/SkillService.java @@ -87,6 +87,8 @@ public class SkillService implements INetworkDispatch { String[] schematicsGranted = ((String) skillTable.getObject(s, 23)).split(","); String[] schematicsRevoked = ((String) skillTable.getObject(s, 24)).split(","); + boolean speciesSkill = skill.matches("^species.+$"); + if (isTitle == true) { core.playerService.addPlayerTitle(player, skill); Console.println("Gave skill title: " + skill); @@ -95,8 +97,9 @@ public class SkillService implements INetworkDispatch { if (isProfession) { return; } - - if (godOnly || isHidden) { + + //exempt species skills from being returned -- they're marked godOnly but really meant to be granted + if ((!speciesSkill) && ( godOnly || isHidden)) { return; } diff --git a/src/services/TerrainService.java b/src/services/TerrainService.java index eb1c9808..e58d6cfa 100644 --- a/src/services/TerrainService.java +++ b/src/services/TerrainService.java @@ -79,12 +79,12 @@ public class TerrainService { private void loadClientRegions(Planet planet) { - if(!FileUtilities.doesFileExist("datatables/clientregion/" + planet.getName() + ".iff")) + if(!FileUtilities.doesFileExist("clientdata/datatables/clientregion/" + planet.getName() + ".iff")) return; - + try { - DatatableVisitor regionTable = ClientFileManager.loadFile("datatables/clientpoi/clientpoi.iff", DatatableVisitor.class); + DatatableVisitor regionTable = ClientFileManager.loadFile("datatables/clientregion/" + planet.getName() + ".iff", DatatableVisitor.class); for (int i = 0; i < regionTable.getRowCount(); i++) { @@ -222,14 +222,15 @@ public class TerrainService { public boolean canBuildAtPosition(SWGObject object, float x, float z) { - if(isWater(object.getPlanet(), z, z)) + if(isWater(object.getPlanet(), x, z)) return false; Point3D position = new Point3D(x, 0, z); for(CollidableCircle noBuildArea : noBuildAreas.get(object.getPlanet())) { - if(noBuildArea.doesCollide(position)) + if(noBuildArea.doesCollide(position)) { return false; + } } return true; diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index bb8efca5..39dd02ee 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -54,7 +54,7 @@ public class AIActor { } public void doAggro(CreatureObject defender) { - + creature.addDefender(defender); } public AIState getCurrentState() { diff --git a/src/services/chat/ChatService.java b/src/services/chat/ChatService.java index 2d0c26c4..e9aa0576 100644 --- a/src/services/chat/ChatService.java +++ b/src/services/chat/ChatService.java @@ -74,6 +74,7 @@ public class ChatService implements INetworkDispatch { core.commandService.registerCommand("socialinternal"); core.commandService.registerCommand("addignore"); core.commandService.registerCommand("removeignore"); + core.commandService.registerCommand("findfriend"); mailODB = core.getMailODB(); } @@ -110,6 +111,10 @@ public class ChatService implements INetworkDispatch { for(Client client : observers) { float distance = client.getParent().getPosition().getDistance2D(position); if(client != null && client.getSession() != null && distance <= 80) { + + if(((PlayerObject)client.getParent().getSlottedObject("ghost")).getIgnoreList().contains(speaker.getCustomName().toLowerCase().split(" ")[0])) + continue; + spatialChat.setDestinationId(client.getParent().getObjectID()); ObjControllerMessage objControllerMessage2 = new ObjControllerMessage(0x0B, spatialChat); client.getSession().write(objControllerMessage2.serialize()); diff --git a/src/services/combat/CombatCommands.java b/src/services/combat/CombatCommands.java index 7ba5c596..1544a0ce 100644 --- a/src/services/combat/CombatCommands.java +++ b/src/services/combat/CombatCommands.java @@ -516,15 +516,10 @@ public class CombatCommands { core.commandService.registerCommand("of_buff_def_9"); core.commandService.registerCommand("of_emergency_shield"); core.commandService.registerCommand("of_firepower_1"); + core.commandService.registerCommand("of_medical_sup_1"); 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/CombatService.java b/src/services/combat/CombatService.java index 06a84ce2..54514c4f 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -90,7 +90,7 @@ public class CombatService implements INetworkDispatch { if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptCombat(attacker, target)) success = false; - if(!applySpecialCost(attacker, weapon, command)) + if(success && !applySpecialCost(attacker, weapon, command)) success = false; if(!success) { @@ -405,11 +405,21 @@ public class CombatService implements INetworkDispatch { private void sendHealPackets(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { + float cooldown = 0; + CombatAction combatAction = new CombatAction(CRC.StringtoCRC(command.getDefaultAnimations()[0]), attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); ObjControllerMessage objController = new ObjControllerMessage(0x1B, combatAction); attacker.notifyObserversInRange(objController, true, 125); - StartTask startTask = new StartTask(actionCounter, attacker.getObjectID(), command.getCommandCRC(), CRC.StringtoCRC(command.getCooldownGroup()), command.getCooldown()); + cooldown = command.getCooldown(); + System.out.println(cooldown); + + if(attacker.getSkillMod("expertise_cooldown_line_of_heal") != null) + cooldown -= attacker.getSkillMod("expertise_cooldown_line_of_heal").getBase(); + if(attacker.getSkillMod("expertise_cooldown_line_sh") != null) + cooldown -= ((attacker.getSkillMod("expertise_cooldown_line_sh").getBase())/10); + + StartTask startTask = new StartTask(actionCounter, attacker.getObjectID(), command.getCommandCRC(), CRC.StringtoCRC(command.getCooldownGroup()), cooldown); ObjControllerMessage objController2 = new ObjControllerMessage(0x0B, startTask); attacker.getClient().getSession().write(objController2.serialize()); @@ -839,14 +849,14 @@ public class CombatService implements INetworkDispatch { boolean success = true; + if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptHeal(healer, target)) + target = healer; + if(target.getMaxHealth() == target.getHealth()) success = command.getAttackType() != 1; - if(!applySpecialCost(healer, weapon, command)) + if(success && !applySpecialCost(healer, weapon, command)) success = false; - - if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptHeal(healer, target)) - target = healer; if(!success) { IoSession session = healer.getClient().getSession(); @@ -887,8 +897,10 @@ public class CombatService implements INetworkDispatch { healPotency += healer.getSkillMod("expertise_healing_line_sm_heal").getBase(); if(healer.getSkillMod("expertise_healing_line_sp_heal") != null) healPotency += healer.getSkillMod("expertise_healing_line_sp_heal").getBase(); + if(healer.getSkillMod("expertise_stance_healing_line_fs_heal") != null) + healPotency += healer.getSkillMod("expertise_stance_healing_line_fs_heal").getBase(); if(healPotency > 0) - healAmount += (healAmount * (healPotency / 100)); + healAmount += ((healAmount * healPotency) / 100); if(target.getSkillMod("expertise_healing_reduction") != null) healAmount *= (1 - target.getSkillMod("expertise_healing_reduction").getBase() / 100); diff --git a/src/services/command/CommandService.java b/src/services/command/CommandService.java index f6483fab..d02d5521 100644 --- a/src/services/command/CommandService.java +++ b/src/services/command/CommandService.java @@ -22,8 +22,11 @@ package services.command; import java.nio.ByteOrder; +import java.util.HashMap; import java.util.Map; import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; + import main.NGECore; import org.apache.mina.core.buffer.IoBuffer; @@ -50,6 +53,8 @@ import resources.objects.weapon.WeaponObject; public class CommandService implements INetworkDispatch { private Vector commandLookup = new Vector(); + private ConcurrentHashMap aliases = new ConcurrentHashMap(); + private ConcurrentHashMap aliasesByCRC = new ConcurrentHashMap(); private NGECore core; public CommandService(NGECore core) { @@ -125,9 +130,28 @@ public class CommandService implements INetworkDispatch { return command; } + + public void registerAlias(String name, String target) { + Vector commands = new Vector(commandLookup); // copy for thread safety + BaseSWGCommand targetCommand = null; + for(BaseSWGCommand command : commands) { + if(command.getCommandName().equalsIgnoreCase(target)) { + targetCommand = command; + } + } + if (targetCommand == null) { return; } + + aliases.put(name, targetCommand); + aliasesByCRC.put(CRC.StringtoCRC(name), targetCommand); + + } public BaseSWGCommand getCommandByCRC(int CRC) { + if (aliasesByCRC.containsKey(CRC)) { + return aliasesByCRC.get(CRC); + } + Vector commands = new Vector(commandLookup); // copy for thread safety for(BaseSWGCommand command : commands) { @@ -140,6 +164,10 @@ public class CommandService implements INetworkDispatch { public BaseSWGCommand getCommandByName(String name) { + if (aliases.containsKey(name)) { + return aliases.get(name); + } + Vector commands = new Vector(commandLookup); // copy for thread safety for(BaseSWGCommand command : commands) { @@ -256,7 +284,7 @@ public class CommandService implements INetworkDispatch { } - public void callCommand(CreatureObject actor, String commandName, SWGObject target, String commandArgs) { + public void callCommand(SWGObject actor, String commandName, SWGObject target, String commandArgs) { if (actor == null) return; diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 6ae5c535..c19f25a8 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -21,6 +21,7 @@ ******************************************************************************/ package services.object; +import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteOrder; import java.sql.PreparedStatement; @@ -36,6 +37,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import resources.common.*; @@ -47,6 +49,8 @@ import org.python.core.PyObject; import com.sleepycat.persist.EntityCursor; +import protocol.swg.ChatFriendsListUpdate; +import protocol.swg.ChatOnChangeFriendStatus; import protocol.swg.ChatOnGetFriendsList; import protocol.swg.CmdSceneReady; import protocol.swg.CmdStartScene; @@ -276,10 +280,11 @@ public class ObjectService implements INetworkDispatch { } } + } catch (FileNotFoundException e) { + System.out.println("!File Not Found:" + template.toString()); } catch (IOException e) { - e.printStackTrace(); + System.out.println("!IO error " + template.toString()); } - } public SWGObject createObject(String Template, Planet planet) { @@ -548,9 +553,9 @@ public class ObjectService implements INetworkDispatch { session.write(startScene.serialize()); creature.makeAware(core.guildService.getGuildObject()); + creature.makeAware(creature); core.simulationService.handleZoneIn(client); - creature.makeAware(creature); CmdSceneReady sceneReady = new CmdSceneReady(); client.getSession().write(sceneReady.serialize()); @@ -560,6 +565,35 @@ public class ObjectService implements INetworkDispatch { ChatOnGetFriendsList friendsListMessage = new ChatOnGetFriendsList(ghost); client.getSession().write(friendsListMessage.serialize()); + if (ghost != null) { + + String objectShortName = creature.getCustomName().toLowerCase(); + + if (creature.getCustomName().contains(" ")) { + String[] splitName = creature.getCustomName().toLowerCase().split(" "); + objectShortName = splitName[0].toLowerCase(); + } + + core.chatService.playerStatusChange(objectShortName, (byte) 1); + + if (ghost.getFriendList().isEmpty() == false) { + // Find out what friends are online/offline + for (String friend : ghost.getFriendList()) { + SWGObject friendObject = (SWGObject) core.chatService.getObjectByFirstName(friend); + if (friendObject == null) + continue; + if(friendObject.isInQuadtree() == true) { + ChatFriendsListUpdate onlineNotifyStatus = new ChatFriendsListUpdate(friend, (byte) 1); + client.getSession().write(onlineNotifyStatus.serialize()); + + } else { + ChatOnChangeFriendStatus changeStatus = new ChatOnChangeFriendStatus(creature.getObjectID(), friend, 0); + client.getSession().write(changeStatus.serialize()); + } + } + } + } + core.playerService.postZoneIn(creature); } @@ -734,5 +768,24 @@ public class ObjectService implements INetworkDispatch { } - + public int objsInContainer(SWGObject owner, TangibleObject container) { + if (owner == null) { + Console.println("Owner null!"); + } + if (container == null) { + Console.println("Container is null!"); + } + final AtomicInteger count = new AtomicInteger(); + + container.viewChildren(owner, false, false, new Traverser() { + + @Override + public void process(SWGObject child) { + count.getAndIncrement(); + } + + }); + + return count.get(); + } } diff --git a/src/services/spawn/DynamicSpawnArea.java b/src/services/spawn/DynamicSpawnArea.java index e588e4cd..a5df57d7 100644 --- a/src/services/spawn/DynamicSpawnArea.java +++ b/src/services/spawn/DynamicSpawnArea.java @@ -25,6 +25,7 @@ import net.engio.mbassy.listener.Handler; import resources.common.collidables.AbstractCollidable; import resources.common.collidables.AbstractCollidable.EnterEvent; import resources.common.collidables.AbstractCollidable.ExitEvent; +import services.SimulationService.MoveEvent; import engine.resources.scene.Planet; public class DynamicSpawnArea extends SpawnArea { diff --git a/src/services/spawn/LairGroupTemplate.java b/src/services/spawn/LairGroupTemplate.java index 0f6347dd..4cca3ea2 100644 --- a/src/services/spawn/LairGroupTemplate.java +++ b/src/services/spawn/LairGroupTemplate.java @@ -5,6 +5,12 @@ import java.util.Vector; public class LairGroupTemplate { private Vector lairSpawnTemplates; + private String name; + + public LairGroupTemplate(String name, Vector lairSpawnTemplates) { + this.name = name; + this.lairSpawnTemplates = lairSpawnTemplates; + } public Vector getLairSpawnTemplates() { return lairSpawnTemplates; @@ -14,4 +20,12 @@ public class LairGroupTemplate { this.lairSpawnTemplates = lairSpawnTemplates; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } diff --git a/src/services/spawn/LairSpawnArea.java b/src/services/spawn/LairSpawnArea.java index da136ba6..31b26f96 100644 --- a/src/services/spawn/LairSpawnArea.java +++ b/src/services/spawn/LairSpawnArea.java @@ -39,9 +39,11 @@ import engine.resources.scene.Point3D; public class LairSpawnArea extends SpawnArea { private LairGroupTemplate lairGroup; + private long lastSpawnTime = 0; - public LairSpawnArea(Planet planet, AbstractCollidable area) { + public LairSpawnArea(Planet planet, AbstractCollidable area, LairGroupTemplate lairGroup) { super(planet, area); + this.lairGroup = lairGroup; } public LairGroupTemplate getLairGroup() { @@ -58,6 +60,9 @@ public class LairSpawnArea extends SpawnArea { if(lairGroup == null || lairTemplates.isEmpty()) return; + + if((System.currentTimeMillis() - lastSpawnTime) < 3000) + return; Point3D randomPosition = getRandomPosition(object.getWorldPosition(), 32.f, 256.f); @@ -79,6 +84,7 @@ public class LairSpawnArea extends SpawnArea { int level = random.nextInt((int) (lairSpawn.getMaxLevel() - lairSpawn.getMinLevel()) + 1) + lairSpawn.getMinLevel(); NGECore.getInstance().spawnService.spawnLair(lairSpawn.getLairTemplate(), getPlanet(), randomPosition, level); + lastSpawnTime = System.currentTimeMillis(); } @@ -97,13 +103,26 @@ public class LairSpawnArea extends SpawnArea { return; spawnLair(creature); - + creature.getEventBus().subscribe(this); + } @Override @Handler public void onExit(ExitEvent event) { + SWGObject object = event.object; + + if(object == null || !(object instanceof CreatureObject)) + return; + + CreatureObject creature = (CreatureObject) object; + + if(creature.getSlottedObject("ghost") == null) + return; + + creature.getEventBus().unsubscribe(this); + } @Handler @@ -123,6 +142,14 @@ public class LairSpawnArea extends SpawnArea { spawnLair(creature); } + + public long getLastSpawnTime() { + return lastSpawnTime; + } + + public void setLastSpawnTime(long lastSpawnTime) { + this.lastSpawnTime = lastSpawnTime; + } } diff --git a/src/services/spawn/LairSpawnTemplate.java b/src/services/spawn/LairSpawnTemplate.java index 50538b9a..74844770 100644 --- a/src/services/spawn/LairSpawnTemplate.java +++ b/src/services/spawn/LairSpawnTemplate.java @@ -24,9 +24,16 @@ package services.spawn; public class LairSpawnTemplate { private int maxSpawnLimit; - private LairTemplate lairTemplate; + private String lairTemplate; private int minLevel; private int maxLevel; + + public LairSpawnTemplate(int maxSpawnLimit, String lairTemplate, int minLevel, int maxLevel) { + this.maxSpawnLimit = maxSpawnLimit; + this.lairTemplate = lairTemplate; + this.minLevel = minLevel; + this.maxLevel = maxLevel; + } public int getMaxSpawnLimit() { return maxSpawnLimit; @@ -36,11 +43,11 @@ public class LairSpawnTemplate { this.maxSpawnLimit = maxSpawnLimit; } - public LairTemplate getLairTemplate() { + public String getLairTemplate() { return lairTemplate; } - public void setLairTemplate(LairTemplate lairTemplate) { + public void setLairTemplate(String lairTemplate) { this.lairTemplate = lairTemplate; } diff --git a/src/services/spawn/LairTemplate.java b/src/services/spawn/LairTemplate.java index 94df1517..2a97bfcc 100644 --- a/src/services/spawn/LairTemplate.java +++ b/src/services/spawn/LairTemplate.java @@ -23,8 +23,17 @@ package services.spawn; public class LairTemplate { + private String name; private String lairCRC; private String mobileName; + private int mobileLimit; + + public LairTemplate(String name, String mobile, int mobileLimit, String lairCRC) { + this.name = name; + this.mobileName = mobile; + this.mobileLimit = mobileLimit; + this.lairCRC = lairCRC; + } public String getLairCRC() { return lairCRC; @@ -42,4 +51,20 @@ public class LairTemplate { this.mobileName = mobileName; } + public int getMobileLimit() { + return mobileLimit; + } + + public void setMobileLimit(int mobileLimit) { + this.mobileLimit = mobileLimit; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } diff --git a/src/services/spawn/MobileTemplate.java b/src/services/spawn/MobileTemplate.java new file mode 100644 index 00000000..7af0d515 --- /dev/null +++ b/src/services/spawn/MobileTemplate.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.spawn; + +public class MobileTemplate { + +} diff --git a/src/services/spawn/SpawnArea.java b/src/services/spawn/SpawnArea.java index 2d64c576..aadb1746 100644 --- a/src/services/spawn/SpawnArea.java +++ b/src/services/spawn/SpawnArea.java @@ -28,6 +28,7 @@ import net.engio.mbassy.listener.Handler; import resources.common.collidables.AbstractCollidable; import resources.common.collidables.AbstractCollidable.EnterEvent; import resources.common.collidables.AbstractCollidable.ExitEvent; +import services.SimulationService.MoveEvent; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java index 1fd5152f..1b08bbf3 100644 --- a/src/services/spawn/SpawnService.java +++ b/src/services/spawn/SpawnService.java @@ -21,20 +21,45 @@ ******************************************************************************/ package services.spawn; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; + +import org.python.core.Py; + +import resources.common.Options; +import resources.common.PvpStatus; +import resources.common.collidables.CollidableCircle; +import resources.objects.tangible.TangibleObject; +import services.ai.LairActor; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; import main.NGECore; public class SpawnService { private NGECore core; private Map> spawnAreas = new ConcurrentHashMap>(); + private Map mobileTemplates = new ConcurrentHashMap(); + private Map lairGroupTemplates = new ConcurrentHashMap(); + private Map lairTemplates = new ConcurrentHashMap(); public SpawnService(NGECore core) { - + this.core = core; + for(Planet planet : core.terrainService.getPlanetList()) { + spawnAreas.put(planet, new ArrayList()); + } } public void spawnCreature(String template, float x, float y, float z) { @@ -45,8 +70,100 @@ public class SpawnService { } - public void spawnLair(LairTemplate lairTemplate, Planet planet, Point3D position, int level) { + public void spawnLair(String lairSpawnTemplate, Planet planet, Point3D position, int level) { + LairTemplate lairTemplate = lairTemplates.get(lairSpawnTemplate); + if(lairTemplate == null) + return; + TangibleObject lairObject = (TangibleObject) core.objectService.createObject(lairTemplate.getLairCRC(), 0, planet, position, new Quaternion(1, 0, 0, 0)); + + if(lairObject == null) + return; + + lairObject.setOptionsBitmask(Options.ATTACKABLE); + lairObject.setPvPBitmask(PvpStatus.Attackable); + lairObject.setMaxDamage(1000 * level); + + LairActor lairActor = new LairActor(lairObject, lairTemplate.getMobileName()); + lairObject.setAttachment("AI", lairActor); + + core.simulationService.add(lairObject, position.x, position.z, true); + + } + + public void loadMobileTemplates() { + + } + + public void addMobileTemplate() { + + } + + public void loadLairTemplates() { + Path p = Paths.get("scripts/mobiles/lairs"); + FileVisitor fv = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + core.scriptService.callScript("scripts/mobiles/lairs/", file.getFileName().toString().replace(".py", ""), "addTemplate", core); + return FileVisitResult.CONTINUE; + } + }; + try { + Files.walkFileTree(p, fv); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void addLairTemplate(String name, String mobile, int mobileLimit, String lairCRC) { + lairTemplates.put(name, new LairTemplate(name, mobile, mobileLimit, lairCRC)); + } + + public void loadLairGroups() { + Path p = Paths.get("scripts/mobiles/lairgroups"); + FileVisitor fv = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + core.scriptService.callScript("scripts/mobiles/lairgroups/", file.getFileName().toString().replace(".py", ""), "addLairGroup", core); + return FileVisitResult.CONTINUE; + } + }; + try { + Files.walkFileTree(p, fv); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void addLairGroup(String name, Vector lairSpawnTemplates) { + lairGroupTemplates.put(name, new LairGroupTemplate(name, lairSpawnTemplates)); + } + + public void loadSpawnAreas() { + Path p = Paths.get("scripts/mobiles/spawnareas"); + FileVisitor fv = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + core.scriptService.callScript("scripts/mobiles/spawnareas/", file.getFileName().toString().replace(".py", ""), "addSpawnArea", core); + return FileVisitResult.CONTINUE; + } + }; + try { + Files.walkFileTree(p, fv); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void addLairSpawnArea(String lairGroup, float x, float z, float radius, String planetName) { + LairGroupTemplate lairGroupTemplate = lairGroupTemplates.get(lairGroup); + Planet planet = core.terrainService.getPlanetByName(planetName); + if(lairGroupTemplate == null || planet == null) + return; + CollidableCircle collidableCircle = new CollidableCircle(new Point3D(x, 0, z), radius, planet); + LairSpawnArea lairSpawnArea = new LairSpawnArea(planet, collidableCircle, lairGroupTemplate); + spawnAreas.get(planet).add(lairSpawnArea); + core.simulationService.addCollidable(collidableCircle, x, z); } diff --git a/src/services/spawn/StaticSpawnArea.java b/src/services/spawn/StaticSpawnArea.java index 64de8d63..2bce6aef 100644 --- a/src/services/spawn/StaticSpawnArea.java +++ b/src/services/spawn/StaticSpawnArea.java @@ -25,6 +25,7 @@ import net.engio.mbassy.listener.Handler; import resources.common.collidables.AbstractCollidable; import resources.common.collidables.AbstractCollidable.EnterEvent; import resources.common.collidables.AbstractCollidable.ExitEvent; +import services.SimulationService.MoveEvent; import engine.resources.scene.Planet; public class StaticSpawnArea extends SpawnArea { diff --git a/src/services/travel/TravelPoint.java b/src/services/travel/TravelPoint.java index 1f1771bd..b1d0596c 100644 --- a/src/services/travel/TravelPoint.java +++ b/src/services/travel/TravelPoint.java @@ -25,6 +25,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import resources.common.Console; import resources.common.SpawnPoint; import resources.objects.creature.CreatureObject; import engine.resources.scene.Point3D; @@ -102,6 +103,9 @@ public class TravelPoint { public void setShuttle(CreatureObject shuttleObj) { this.shuttle = shuttleObj; + if (shuttleObj == null) { + Console.println("NULL SHUTTLE SET FOR: " + getName()); + } startShuttleSchedule(); } diff --git a/src/services/travel/TravelService.java b/src/services/travel/TravelService.java index 541615a3..c27b75b1 100644 --- a/src/services/travel/TravelService.java +++ b/src/services/travel/TravelService.java @@ -116,7 +116,7 @@ public class TravelService implements INetworkDispatch { for(TravelPoint tp : travelMap.get(planet)) { if(tp.isStarport() || tp.getPlanetName().equalsIgnoreCase(object.getPlanet().getName())) { correctTravelPoints.add(tp); - Console.println(tp.getName()); + //Console.println(tp.getName()); } } PlanetTravelPointListResponse response = new PlanetTravelPointListResponse(planetString, correctTravelPoints); @@ -144,12 +144,23 @@ public class TravelService implements INetworkDispatch { public TravelPoint getNearestTravelPoint(SWGObject obj) { TravelPoint returnedPoint = null; Vector planetTp = travelMap.get(obj.getPlanet()); - + synchronized(travelMap) { for (TravelPoint tp : planetTp) { //System.out.println("Distance for point " + tp.getName() + " is " + tp.getLocation().getDistance2D(obj.getWorldPosition())); if (tp.getLocation().getDistance2D(obj.getWorldPosition()) <= 125) { - returnedPoint = tp; + if (returnedPoint != null) { + float returnPointDistance = returnedPoint.getLocation().getDistance2D(obj.getWorldPosition()); + float tpDistance = tp.getLocation().getDistance2D(obj.getWorldPosition()); + //Console.println("Current point: " + returnedPoint.getName()); + //Console.println("Return point distance: " + returnPointDistance + " for " + returnedPoint.getName()); + //Console.println("tp point distance: " + tpDistance + " for " + tp.getName()); + if (tpDistance < returnPointDistance) { + returnedPoint = tp; + } + } else { + returnedPoint = tp; + } } } } @@ -230,7 +241,7 @@ public class TravelService implements INetworkDispatch { Planet planet = core.terrainService.getPlanetByName(departurePlanet.toLowerCase()); SWGObject travelTicket = core.objectService.createObject("object/tangible/travel/travel_ticket/base/shared_base_travel_ticket.iff", planet); - + travelTicket.setStringAttribute("@obj_attr_n:travel_departure_planet", WordUtils.capitalize(departurePlanet)); travelTicket.setStringAttribute("@obj_attr_n:travel_departure_point", departureLoc); @@ -260,7 +271,7 @@ public class TravelService implements INetworkDispatch { } creatureObj.setBankCredits(0); - creatureObj.setCashCredits(cashDifference); + creatureObj.setCashCredits(creatureObj.getCashCredits() - cashDifference); } else { creatureObj.setBankCredits(playerBankCredits - fare); } @@ -274,7 +285,7 @@ public class TravelService implements INetworkDispatch { creatureObj.getSlottedObject("inventory").add(travelTicket); //Console.println("Total cost: " + fare); - SUIWindow window = core.suiService.createMessageBox(MessageBoxType.MESSAGE_BOX_OK, "STAR WARS GALAXIES", "Ticket purchase complete.", player, null, 0); + SUIWindow window = core.suiService.createMessageBox(MessageBoxType.MESSAGE_BOX_OK, "STAR WARS GALAXIES", "@travel:ticket_purchase_complete", player, null, 0); core.suiService.openSUIWindow(window); creatureObj.sendSystemMessage("You successfully make a payment of " + fare + " credits to the Galactic Travel Commission.", (byte) 0); @@ -367,7 +378,7 @@ public class TravelService implements INetworkDispatch { for (int f = 0; f < travelFares.getRowCount(); f++) { Planet planet = core.terrainService.getPlanetByName((String) travelFares.getObject(f, 0)); if (travelMap.containsKey(planet)) { - int corellia = ((Integer) travelFares.getObject(f, 1)); + int corellia = ((int) travelFares.getObject(f, 1)); int dantooine = ((int) travelFares.getObject(f, 2)); int dathomir = ((int) travelFares.getObject(f, 3)); int endor = ((int) travelFares.getObject(f, 4));