diff --git a/accesslevels/cs.txt b/accesslevels/cs.txt new file mode 100644 index 00000000..dfa80f53 --- /dev/null +++ b/accesslevels/cs.txt @@ -0,0 +1,95 @@ +goto +findobject +teleport +teleportto +invulnerable +kill +setspeed +planetwarp +harmfull +harmless +object +searchcorpse +giveitem +sethue +editbank +editbankaccount +editappearance +editstats +snoop +wipeitems +findplayer +findobject +findobjectbytemplate +findcreature +getgametime +getplayerid +getstationname +grantbadge +grantbadgearea +granttitle +revokebadge +revoketitle +gmrevive +getrank +setfaction +settef +setfactionstanding +setrank +killplayer +teleporttarget +planetwarptarget +freezeplayer +unfreezeplayer +squelch +unsquelch +adjustlotcount +credits +editappearance +kick +maxcombatability +maxstats +money +setfirstname +setlastname +setname +setplayerstate +uncityban +setbiographyadmin +activtequest +activateinstance +clearcompletedquest +completequest +listactivequests +listcompletedquests +grantskill +revokeskill +setexperience +listguildes +cityinfo +broadcast +broadcastarea +broadcastplanet +broadcastgalaxy +addbannedplayer +emptymailtarget +getaccountinfo +removebannedplayer +createcreature +createnpc +createmissionelement +createspawningelement +createspawningelementwithdifficulty +createstaticitem +getspawndelays +setmaximumspawntime +setminimumspawntime +showspawnregion +startspawner +starttargetspawner +stopspawner +stoptargetspawner +clearveteranreward +hasveteranreward +setveteranrewardtimecs +setveteranreward \ No newline at end of file diff --git a/accesslevels/dev.txt b/accesslevels/dev.txt new file mode 100644 index 00000000..a16093fa --- /dev/null +++ b/accesslevels/dev.txt @@ -0,0 +1,102 @@ +gmforcecommand +goto +findobject +teleport +teleportto +invulnerable +kill +setspeed +planetwarp +harmfull +harmless +object +searchcorpse +giveitem +sethue +editbank +editbankaccount +editappearance +editstats +snoop +wipeitems +findplayer +findobject +findobjectbytemplate +findcreature +getgametime +getplayerid +getstationname +gmrevive +getrank +setfaction +settef +setfactionstanding +setrank +killplayer +teleporttarget +planetwarptarget +adjustlotcount +editappearance +kick +maxcombatability +maxstats +setfirstname +setlastname +setname +setplayerstate +activtequest +activateinstance +clearcompletedquest +completequest +listactivequests +listcompletedquests +grantskill +revokeskill +setexperience +listguildes +cityinfo +createcreature +createnpc +createmissionelement +createspawningelement +createspawningelementwithdifficulty +createstaticitem +getspawndelays +setmaximumspawntime +setminimumspawntime +showspawnregion +startspawner +starttargetspawner +stopspawner +stoptargetspawner +clearveteranreward +hasveteranreward +setveteranrewardtimecs +setveteranreward +aiignore +combat +craft +forcecommand +generatecrafteditem +getobjvars +gmcreateclassresource +gmcreatespecificresource +manufacture +showfactioninformation +qatool +startrestussstagetwo +completerestusstageone +spewcommandqueue +combatdatarecord +combatdataclear +combatdatareport +combatdatastop +combatmodecheck +database +destroy +dumptargetinformation +dumpzoneinformation +initializecomponent +script +lag +csdumptarget \ No newline at end of file diff --git a/accesslevels/ec.txt b/accesslevels/ec.txt new file mode 100644 index 00000000..7c2236a2 --- /dev/null +++ b/accesslevels/ec.txt @@ -0,0 +1,98 @@ +goto +findobject +teleport +teleportto +invulnerable +kill +setspeed +planetwarp +harmfull +harmless +object +searchcorpse +giveitem +sethue +findplayer +findobject +findobjectbytemplate +findcreature +getgametime +getplayerid +getstationname +grantbadge +grantbadgearea +granttitle +revokebadge +revoketitle +gmrevive +getrank +setfaction +settef +setfactionstanding +setrank +killplayer +teleporttarget +planetwarptarget +freezeplayer +unfreezeplayer +squelch +unsquelch +adjustlotcount +credits +editappearance +kick +maxcombatability +maxstats +money +setfirstname +setlastname +setname +setplayerstate +activtequest +activateinstance +clearcompletedquest +completequest +listactivequests +listcompletedquests +grantskill +revokeskill +setexperience +broadcast +broadcastarea +broadcastplanet +broadcastgalaxy +createcreature +createnpc +createmissionelement +createspawningelement +createspawningelementwithdifficulty +createstaticitem +getspawndelays +setmaximumspawntime +setminimumspawntime +showspawnregion +startspawner +starttargetspawner +stopspawner +stoptargetspawner +eventbuff +eventbuffarea +eventbufftarget +eventclearstates +eventdamage +eventmovetome +eventstorepet +eventtefarea +eventtefclear +eventteftarget +eventundomovetome +eventvaderchoke +eventweapon +setplayerappearance +revokeplayerappearance +csstorytellerdestroynpcs +csstorytellerdestroyprops +csstorytellerdestroyparticles +csstorytellerdestroyallobjects +startrestussstagetwo +completerestusstageone \ No newline at end of file diff --git a/accesslevels/lead.txt b/accesslevels/lead.txt new file mode 100644 index 00000000..5d1056bf --- /dev/null +++ b/accesslevels/lead.txt @@ -0,0 +1,163 @@ +gmforcecommand +goto +findobject +teleport +teleportto +invulnerable +kill +setspeed +planetwarp +harmfull +harmless +object +searchcorpse +giveitem +sethue +editbank +editbankaccount +editappearance +editstats +snoop +wipeitems +findplayer +findobject +findobjectbytemplate +findcreature +getgametime +getplayerid +getstationname +grantbadge +grantbadgearea +granttitle +revokebadge +revoketitle +gmrevive +getrank +setfaction +settef +setfactionstanding +setrank +killplayer +teleporttarget +planetwarptarget +freezeplayer +unfreezeplayer +squelch +unsquelch +adjustlotcount +credits +editappearance +kick +maxcombatability +maxstats +money +setfirstname +setlastname +setname +setplayerstate +uncityban +setbiographyadmin +activtequest +activateinstance +clearcompletedquest +completequest +listactivequests +listcompletedquests +grantskill +revokeskill +setexperience +listguildes +cityinfo +broadcast +broadcastarea +broadcastplanet +broadcastgalaxy +addbannedplayer +emptymailtarget +getaccountinfo +removebannedplayer +createcreature +createnpc +createmissionelement +createspawningelement +createspawningelementwithdifficulty +createstaticitem +getspawndelays +setmaximumspawntime +setminimumspawntime +showspawnregion +startspawner +starttargetspawner +stopspawner +stoptargetspawner +clearveteranreward +hasveteranreward +setveteranrewardtimecs +setveteranreward +aiignore +combat +craft +forcecommand +generatecrafteditem +getobjvars +gmcreateclassresource +gmcreatespecificresource +manufacture +showfactioninformation +qatool +startrestussstagetwo +completerestusstageone +spewcommandqueue +combatdatarecord +combatdataclear +combatdatareport +combatdatastop +combatmodecheck +database +destroy +dumptargetinformation +dumpzoneinformation +initializecomponent +script +lag +csdumptarget +eventbuff +eventbuffarea +eventbufftarget +eventclearstates +eventdamage +eventmovetome +eventstorepet +eventtefarea +eventtefclear +eventteftarget +eventundomovetome +eventvaderchoke +eventweapon +setplayerappearance +revokeplayerappearance +csstorytellerdestroynpcs +csstorytellerdestroyprops +csstorytellerdestroyparticles +csstorytellerdestroyallobjects +startrestussstagetwo +completerestusstageone +setgodmode +server +addallowedplayer +removeallowedplayer +setlogintitle +setloginmessage +setplanetlimit +resendloginmessagetoall +gmforcerank +gmfsvillage +gmjedistate +grantpadawantrialseligibility +overridepadawantrialseligibility +resetjedi +setwardenloginmessage +findwarden +activatequest +grantwarden +revokewarden diff --git a/accesslevels/qa.txt b/accesslevels/qa.txt new file mode 100644 index 00000000..6127f135 --- /dev/null +++ b/accesslevels/qa.txt @@ -0,0 +1,82 @@ +goto +findobject +teleport +teleportto +invulnerable +kill +setspeed +planetwarp +harmfull +harmless +object +searchcorpse +giveitem +sethue +findplayer +findobject +findobjectbytemplate +findcreature +getgametime +getplayerid +getstationname +gmrevive +getrank +setfaction +settef +setfactionstanding +setrank +killplayer +teleporttarget +planetwarptarget +setfirstname +setlastname +setname +setplayerstate +activatequest +activateinstance +clearcompletedquest +completequest +listactivequests +listcompletedquests +grantskill +revokeskill +setexperience +listguildes +cityinfo +createcreature +createnpc +createmissionelement +createspawningelement +createspawningelementwithdifficulty +createstaticitem +getspawndelays +setmaximumspawntime +setminimumspawntime +showspawnregion +startspawner +starttargetspawner +stopspawner +stoptargetspawner +aiignore +combat +craft +forcecommand +generatecrafteditem +getobjvars +gmcreateclassresource +gmcreatespecificresource +manufacture +showfactioninformation +qatool +startrestussstagetwo +completerestusstageone +spewcommandqueue +combatdatarecord +combatdataclear +combatdatareport +combatdatastop +combatmodecheck +dumptargetinformation +dumpzoneinformation +csdumptarget +destroy diff --git a/accesslevels/staff.txt b/accesslevels/staff.txt new file mode 100644 index 00000000..9aadf55a --- /dev/null +++ b/accesslevels/staff.txt @@ -0,0 +1,12 @@ +gmforcecommand +goto +findobject +teleport +teleportto +invulnerable +kill +gmrevive +setspeed +planetwarp +harmfull +harmless \ No newline at end of file diff --git a/logs/placeHolder.txt b/logs/placeHolder.txt new file mode 100644 index 00000000..e69de29b diff --git a/nge.backup b/nge.backup index 1a761380..3091c7ff 100644 Binary files a/nge.backup and b/nge.backup differ diff --git a/ngengine_public.jar b/ngengine_public.jar index 2a5cd790..df399469 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/options.cfg b/options.cfg index c96f5a3b..9a4da26a 100644 --- a/options.cfg +++ b/options.cfg @@ -1,7 +1,31 @@ +# Toggles the loading of /clientdata/snapshot. +# 1 = Enabled, 0 = Disabled. LOAD.SNAPSHOT_OBJECTS=1 + +# Toggles the loading of /clientdata/buildouts. +# 1 = Enabled, 0 = Disabled. LOAD.BUILDOUT_OBJECTS=0 + +# Toggles the loading of /clinetdata/buildouts for a paticular terrain. +# Specify the terrain. This line should be commented out to be disabled. #LOAD.BUILDOUT_ONLY_FOR="dathomir" + +# Toggles Loading Old/Creating new/Spawning New Resources. +# 1 = On, 0 = Off. LOAD.RESOURCE.SYSTEM=1 -# Misc +# Toggles full wipe of Object Database (Characters, Items, etc.) +# 1 = Enabled, 0 = Disabled. CLEAN.ODB.FOLDERS=0 + +# Toggles wipe of characters in Datatable +# 1 = Enabled, 0 = Disabled +CLEAN.CHARACTERS.TABLE=0 + +# Toggles Isolation System Spawning at Tatooine 0 0 0 around no NPC's. +# 1 = On, 0 = Off. +DO.ISOLATION.TESTS=0 + +# Toggles GCW Invasions System. +# 1 = On, 0 = Off. +ENABLE.INVASIONS=0 diff --git a/scripts/buffs/banner_buff_bounty_hunter.py b/scripts/buffs/banner_buff_bounty_hunter.py new file mode 100644 index 00000000..3ceeb3b3 --- /dev/null +++ b/scripts/buffs/banner_buff_bounty_hunter.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_critical_niche_all', 5) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_critical_niche_all', 5) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_commando.py b/scripts/buffs/banner_buff_commando.py new file mode 100644 index 00000000..c51d7521 --- /dev/null +++ b/scripts/buffs/banner_buff_commando.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'proc_buff', 1) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'proc_buff', 1) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_entertainer.py b/scripts/buffs/banner_buff_entertainer.py new file mode 100644 index 00000000..624cbcde --- /dev/null +++ b/scripts/buffs/banner_buff_entertainer.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_dodge', 2) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_dodge', 2) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_force_sensitive.py b/scripts/buffs/banner_buff_force_sensitive.py new file mode 100644 index 00000000..c0a1286f --- /dev/null +++ b/scripts/buffs/banner_buff_force_sensitive.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'strength_modified', 100) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'strength_modified', 100) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_medic.py b/scripts/buffs/banner_buff_medic.py new file mode 100644 index 00000000..e01d7147 --- /dev/null +++ b/scripts/buffs/banner_buff_medic.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'constitution_modified', 100) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'constitution_modified', 100) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_officer.py b/scripts/buffs/banner_buff_officer.py new file mode 100644 index 00000000..3adb49d7 --- /dev/null +++ b/scripts/buffs/banner_buff_officer.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'precision_modified', 100) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'precision_modified', 100) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_smuggler.py b/scripts/buffs/banner_buff_smuggler.py new file mode 100644 index 00000000..694c9c9a --- /dev/null +++ b/scripts/buffs/banner_buff_smuggler.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'luck_modified', 100) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'luck_modified', 100) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_spy.py b/scripts/buffs/banner_buff_spy.py new file mode 100644 index 00000000..4500cd97 --- /dev/null +++ b/scripts/buffs/banner_buff_spy.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'agility_modified', 100) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'agility_modified', 100) + return + \ No newline at end of file diff --git a/scripts/buffs/banner_buff_trader.py b/scripts/buffs/banner_buff_trader.py new file mode 100644 index 00000000..ff5f0868 --- /dev/null +++ b/scripts/buffs/banner_buff_trader.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_glancing_blow_all', 100) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_glancing_blow_all', 100) + return + \ No newline at end of file diff --git a/scripts/buffs/barricade_defender.py b/scripts/buffs/barricade_defender.py new file mode 100644 index 00000000..9acc5d3c --- /dev/null +++ b/scripts/buffs/barricade_defender.py @@ -0,0 +1,18 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.addSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.addSkillMod(actor, 'combat_evasion_value', 50) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.deductSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.deductSkillMod(actor, 'combat_evasion_value', 50) + return + \ No newline at end of file diff --git a/scripts/buffs/gcw_fatigue.py b/scripts/buffs/gcw_fatigue.py new file mode 100644 index 00000000..2fc75c61 --- /dev/null +++ b/scripts/buffs/gcw_fatigue.py @@ -0,0 +1,25 @@ +import sys +from java.lang import Short + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + + #fatigue = actor.getGCWFatigue() + 1 + #actor.setGCWFatigue(fatigue) + return + +def remove(core, actor, buff): + #if actor.getGCWFatigue()>0: + #fatigue = actor.getGCWFatigue() - 1 + #actor.setGCWFatigue(fatigue) + # Major flaw in Buff system. It does not consider infinite, stackable buffs + # The GCW buff gets automatically removed upon each new stack + # resulting in +1-1 Fatigue, if the fatigue gets set here. + # Only way is to set it, is in the java methods + # and then invent a way so that entertainer can heal this + + return + \ No newline at end of file diff --git a/scripts/buffs/gcw_general_resistance_stack_rebel.py b/scripts/buffs/gcw_general_resistance_stack_rebel.py new file mode 100644 index 00000000..9acc5d3c --- /dev/null +++ b/scripts/buffs/gcw_general_resistance_stack_rebel.py @@ -0,0 +1,18 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.addSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.addSkillMod(actor, 'combat_evasion_value', 50) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.deductSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.deductSkillMod(actor, 'combat_evasion_value', 50) + return + \ No newline at end of file diff --git a/scripts/buffs/tower_defender.py b/scripts/buffs/tower_defender.py new file mode 100644 index 00000000..8ca5e20c --- /dev/null +++ b/scripts/buffs/tower_defender.py @@ -0,0 +1,14 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_damage_npc', 200) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_damage_npc', -200) + return + \ No newline at end of file diff --git a/scripts/character_builder_terminal.py b/scripts/character_builder_terminal.py index d58927ff..43771be2 100644 --- a/scripts/character_builder_terminal.py +++ b/scripts/character_builder_terminal.py @@ -142,8 +142,9 @@ def travelHandler(owner): window.addHandler(0, '', Trigger.TRIGGER_OK, returnList, travelHandlerCallback) window.addListBoxMenuItem('Tatooine, Mos Eisley', 0) window.addListBoxMenuItem('Dantooine, Jedi Ruins', 1) - window.addListBoxMenuItem('Blank', 2) - window.addListBoxMenuItem('Blank', 3) + window.addListBoxMenuItem('Talus, Dearic Starport', 2) + window.addListBoxMenuItem('Naboo, Keren Starport', 3) + window.addListBoxMenuItem('Tatooine, Bestine Starport', 4) core.suiService.openSUIWindow(window); def travelHandlerCallback(owner, window, eventType, returnList): @@ -158,6 +159,15 @@ def travelHandlerCallback(owner, window, eventType, returnList): if returnList.get(0)=='1': jediRuinsTravel(owner) return + if returnList.get(0)=='2': + GCWDearicTravel(owner) + return + if returnList.get(0)=='3': + GCWKerenTravel(owner) + return + if returnList.get(0)=='4': + GCWBestineTravel(owner) + return return @@ -307,6 +317,9 @@ def miscHandler(owner): window.addListBoxMenuItem('Heroism Jewelry Set', 1) window.addListBoxMenuItem('Belt of Master Bodo Baas', 2) window.addListBoxMenuItem('Starter Equipment Box', 3) + window.addListBoxMenuItem('GCW Banners', 4) + window.addListBoxMenuItem('Bounty Droids', 5) + core.suiService.openSUIWindow(window); def miscHandlerCallback(owner, window, eventType, returnList): @@ -327,6 +340,13 @@ def miscHandlerCallback(owner, window, eventType, returnList): if returnList.get(0)=='3': starterEquipmentBox(owner, inventory) return + if returnList.get(0)=='4': + GCWBanners(owner, inventory) + return + if returnList.get(0)=='5': + bountyDroids(owner, inventory) + return + return def combatLevel(owner): @@ -652,6 +672,21 @@ def jediRuinsTravel(owner): core.simulationService.transferToPlanet(owner, core.terrainService.getPlanetByName("dantooine"), position, owner.getOrientation(), None) return +def GCWDearicTravel(owner): + position = Point3D(264, 4, -2950) + core.simulationService.transferToPlanet(owner, core.terrainService.getPlanetByName("talus"), position, owner.getOrientation(), None) + return + +def GCWKerenTravel(owner): + position = Point3D(1366, 13, 2747) + core.simulationService.transferToPlanet(owner, core.terrainService.getPlanetByName("naboo"), position, owner.getOrientation(), None) + return + +def GCWBestineTravel(owner): + position = Point3D(-1385,12, -3597) + core.simulationService.transferToPlanet(owner, core.terrainService.getPlanetByName("tatooine"), position, owner.getOrientation(), None) + return + def surveyDevices(owner, inventory): mineralSurveyTool = core.objectService.createObject("object/tangible/survey_tool/shared_survey_tool_mineral.iff", owner.getPlanet()) chemicalSurveyTool = core.objectService.createObject("object/tangible/survey_tool/shared_survey_tool_inorganic.iff", owner.getPlanet()) @@ -668,4 +703,29 @@ def surveyDevices(owner, inventory): inventory.add(windSurveyTool) inventory.add(solarSurveyTool) return - \ No newline at end of file + +def GCWBanners(owner, inventory): + + gcwBanner1 = core.objectService.createObject('object/tangible/gcw/pvp_rank_rewards/shared_rebel_battle_banner.iff', owner.getPlanet()) + gcwBanner1.setStfFilename('static_item_n') + gcwBanner1.setStfName('item_pvp_captain_battle_banner_rebel_reward_04_01') + gcwBanner1.setDetailFilename('static_item_d') + gcwBanner1.setDetailName('item_pvp_captain_battle_banner_rebel_reward_04_01') + inventory.add(gcwBanner1) + gcwBanner2 = core.objectService.createObject('object/tangible/gcw/pvp_rank_rewards/shared_imperial_battle_banner.iff', owner.getPlanet()) + gcwBanner2.setStfFilename('static_item_n') + gcwBanner2.setStfName('item_pvp_captain_battle_banner_imperial_reward_04_01') + gcwBanner2.setDetailFilename('static_item_d') + gcwBanner2.setDetailName('item_pvp_captain_battle_banner_imperial_reward_04_01') + inventory.add(gcwBanner2) + return + +def bountyDroids(owner, inventory): + seekers = core.objectService.createObject('object/tangible/mission/shared_mission_bounty_droid_seeker.iff', owner.getPlanet()) + seekers.setUses(20) + inventory.add(seekers) + + probe = core.objectService.createObject('object/tangible/mission/shared_mission_bounty_droid_probot.iff', owner.getPlanet()) + probe.setUses(20) + inventory.add(probe) + return \ No newline at end of file diff --git a/scripts/commands/activatequest.py b/scripts/commands/activatequest.py new file mode 100644 index 00000000..2a08666e --- /dev/null +++ b/scripts/commands/activatequest.py @@ -0,0 +1,13 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + if core.questService.adminActivateQuest(actor, commandString) is False: + actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF ActivateQuest: You entered a quest that does not exist or forgot to enter one!', 0) + return + + core.questService.sendQuestWindow(actor, commandString) + actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF ActivateQuest: Command completed successfully.', 0) + return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_2.py b/scripts/commands/combat/bh_dm_crit_2.py deleted file mode 100644 index c12e2a2a..00000000 --- a/scripts/commands/combat/bh_dm_crit_2.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_dm_crit'): - command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) - - if actor.getSkillMod('expertise_damage_line_dm_crit'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_action_line_dm_crit'): - command.setActionCost(command.getActionCost() - ((command.getActionCost()*actor.getSkillModBase('expertise_action_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_critical_line_dm_crit'): - command.setCriticalChance(command.getCriticalChance + actor.getSkillModBase('expertise_critical_line_dm_crit')) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_3.py b/scripts/commands/combat/bh_dm_crit_3.py deleted file mode 100644 index 59349465..00000000 --- a/scripts/commands/combat/bh_dm_crit_3.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_dm_crit'): - command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) - - if actor.getSkillMod('expertise_damage_line_dm_crit'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_action_line_dm_crit'): - command.setActionCost(command.getActionCost() - ((command.getActionCost()*actor.getSkillModBase('expertise_action_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_critical_line_dm_crit'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillModBase('expertise_critical_line_dm_crit')) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_4.py b/scripts/commands/combat/bh_dm_crit_4.py deleted file mode 100644 index c12e2a2a..00000000 --- a/scripts/commands/combat/bh_dm_crit_4.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_dm_crit'): - command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) - - if actor.getSkillMod('expertise_damage_line_dm_crit'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_action_line_dm_crit'): - command.setActionCost(command.getActionCost() - ((command.getActionCost()*actor.getSkillModBase('expertise_action_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_critical_line_dm_crit'): - command.setCriticalChance(command.getCriticalChance + actor.getSkillModBase('expertise_critical_line_dm_crit')) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_5.py b/scripts/commands/combat/bh_dm_crit_5.py deleted file mode 100644 index c12e2a2a..00000000 --- a/scripts/commands/combat/bh_dm_crit_5.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_dm_crit'): - command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) - - if actor.getSkillMod('expertise_damage_line_dm_crit'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_action_line_dm_crit'): - command.setActionCost(command.getActionCost() - ((command.getActionCost()*actor.getSkillModBase('expertise_action_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_critical_line_dm_crit'): - command.setCriticalChance(command.getCriticalChance + actor.getSkillModBase('expertise_critical_line_dm_crit')) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_6.py b/scripts/commands/combat/bh_dm_crit_6.py deleted file mode 100644 index c12e2a2a..00000000 --- a/scripts/commands/combat/bh_dm_crit_6.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_dm_crit'): - command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) - - if actor.getSkillMod('expertise_damage_line_dm_crit'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_action_line_dm_crit'): - command.setActionCost(command.getActionCost() - ((command.getActionCost()*actor.getSkillModBase('expertise_action_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_critical_line_dm_crit'): - command.setCriticalChance(command.getCriticalChance + actor.getSkillModBase('expertise_critical_line_dm_crit')) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_7.py b/scripts/commands/combat/bh_dm_crit_7.py deleted file mode 100644 index c12e2a2a..00000000 --- a/scripts/commands/combat/bh_dm_crit_7.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_dm_crit'): - command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) - - if actor.getSkillMod('expertise_damage_line_dm_crit'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_action_line_dm_crit'): - command.setActionCost(command.getActionCost() - ((command.getActionCost()*actor.getSkillModBase('expertise_action_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_critical_line_dm_crit'): - command.setCriticalChance(command.getCriticalChance + actor.getSkillModBase('expertise_critical_line_dm_crit')) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_8.py b/scripts/commands/combat/bh_dm_crit_8.py deleted file mode 100644 index c12e2a2a..00000000 --- a/scripts/commands/combat/bh_dm_crit_8.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_dm_crit'): - command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) - - if actor.getSkillMod('expertise_damage_line_dm_crit'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_action_line_dm_crit'): - command.setActionCost(command.getActionCost() - ((command.getActionCost()*actor.getSkillModBase('expertise_action_line_dm_crit'))/100)) - - if actor.getSkillMod('expertise_critical_line_dm_crit'): - command.setCriticalChance(command.getCriticalChance + actor.getSkillModBase('expertise_critical_line_dm_crit')) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_spiral_kick_1.py b/scripts/commands/combat/en_spiral_kick_1.py deleted file mode 100644 index 62a7efb2..00000000 --- a/scripts/commands/combat/en_spiral_kick_1.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_spiral_kick_snare', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_spiral_kick_2.py b/scripts/commands/combat/en_spiral_kick_2.py deleted file mode 100644 index 62a7efb2..00000000 --- a/scripts/commands/combat/en_spiral_kick_2.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_spiral_kick_snare', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_spiral_kick_3.py b/scripts/commands/combat/en_spiral_kick_3.py deleted file mode 100644 index 62a7efb2..00000000 --- a/scripts/commands/combat/en_spiral_kick_3.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_spiral_kick_snare', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_spiral_kick_4.py b/scripts/commands/combat/en_spiral_kick_4.py deleted file mode 100644 index 62a7efb2..00000000 --- a/scripts/commands/combat/en_spiral_kick_4.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_spiral_kick_snare', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_thrill_1.py b/scripts/commands/combat/en_thrill_1.py deleted file mode 100644 index 41d4b0aa..00000000 --- a/scripts/commands/combat/en_thrill_1.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_debuff_thrill_1', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_thrill_2.py b/scripts/commands/combat/en_thrill_2.py deleted file mode 100644 index 41d4b0aa..00000000 --- a/scripts/commands/combat/en_thrill_2.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_debuff_thrill_1', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_thrill_3.py b/scripts/commands/combat/en_thrill_3.py deleted file mode 100644 index 7e1892d5..00000000 --- a/scripts/commands/combat/en_thrill_3.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_debuff_thrill_2', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_void_dance_1.py b/scripts/commands/combat/en_void_dance_1.py deleted file mode 100644 index ce94693c..00000000 --- a/scripts/commands/combat/en_void_dance_1.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_void_dance_buff_1', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_void_dance_2.py b/scripts/commands/combat/en_void_dance_2.py deleted file mode 100644 index b6167823..00000000 --- a/scripts/commands/combat/en_void_dance_2.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_void_dance_buff_2', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/en_void_dance_3.py b/scripts/commands/combat/en_void_dance_3.py deleted file mode 100644 index 268bbd4e..00000000 --- a/scripts/commands/combat/en_void_dance_3.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'en_void_dance_buff_3', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_ae_dm_cc_2.py b/scripts/commands/combat/fs_ae_dm_cc_2.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_ae_dm_cc_2.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_ae_dm_cc_3.py b/scripts/commands/combat/fs_ae_dm_cc_3.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_ae_dm_cc_3.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_ae_dm_cc_4.py b/scripts/commands/combat/fs_ae_dm_cc_4.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_ae_dm_cc_4.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_ae_dm_cc_5.py b/scripts/commands/combat/fs_ae_dm_cc_5.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_ae_dm_cc_5.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_ae_dm_cc_6.py b/scripts/commands/combat/fs_ae_dm_cc_6.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_ae_dm_cc_6.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_2.py b/scripts/commands/combat/fs_dm_2.py deleted file mode 100644 index 825798d5..00000000 --- a/scripts/commands/combat/fs_dm_2.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_dm'): - command.setCooldown(command.getCooldown() + (actor.getSkillMod('expertise_cooldown_line_fs_dm').getBase()/10)) - - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - if actor.getSkillMod('expertise_action_line_fs_dm'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillMod('expertise_action_line_fs_dm').getBase())/100)) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_3.py b/scripts/commands/combat/fs_dm_3.py deleted file mode 100644 index 825798d5..00000000 --- a/scripts/commands/combat/fs_dm_3.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_dm'): - command.setCooldown(command.getCooldown() + (actor.getSkillMod('expertise_cooldown_line_fs_dm').getBase()/10)) - - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - if actor.getSkillMod('expertise_action_line_fs_dm'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillMod('expertise_action_line_fs_dm').getBase())/100)) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_4.py b/scripts/commands/combat/fs_dm_4.py deleted file mode 100644 index 825798d5..00000000 --- a/scripts/commands/combat/fs_dm_4.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_dm'): - command.setCooldown(command.getCooldown() + (actor.getSkillMod('expertise_cooldown_line_fs_dm').getBase()/10)) - - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - if actor.getSkillMod('expertise_action_line_fs_dm'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillMod('expertise_action_line_fs_dm').getBase())/100)) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_5.py b/scripts/commands/combat/fs_dm_5.py deleted file mode 100644 index 825798d5..00000000 --- a/scripts/commands/combat/fs_dm_5.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_dm'): - command.setCooldown(command.getCooldown() + (actor.getSkillMod('expertise_cooldown_line_fs_dm').getBase()/10)) - - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - if actor.getSkillMod('expertise_action_line_fs_dm'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillMod('expertise_action_line_fs_dm').getBase())/100)) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_6.py b/scripts/commands/combat/fs_dm_6.py deleted file mode 100644 index 825798d5..00000000 --- a/scripts/commands/combat/fs_dm_6.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_dm'): - command.setCooldown(command.getCooldown() + (actor.getSkillMod('expertise_cooldown_line_fs_dm').getBase()/10)) - - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - if actor.getSkillMod('expertise_action_line_fs_dm'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillMod('expertise_action_line_fs_dm').getBase())/100)) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_7.py b/scripts/commands/combat/fs_dm_7.py deleted file mode 100644 index 825798d5..00000000 --- a/scripts/commands/combat/fs_dm_7.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_dm'): - command.setCooldown(command.getCooldown() + (actor.getSkillMod('expertise_cooldown_line_fs_dm').getBase()/10)) - - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - if actor.getSkillMod('expertise_action_line_fs_dm'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillMod('expertise_action_line_fs_dm').getBase())/100)) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_cc_crit_1.py b/scripts/commands/combat/fs_dm_cc_crit_1.py deleted file mode 100644 index 493481d7..00000000 --- a/scripts/commands/combat/fs_dm_cc_crit_1.py +++ /dev/null @@ -1,10 +0,0 @@ -import sys - -def setup(core, actor, buff): - actor.setSpeedMultiplierBase(0.5) - return - -def removeBuff(core, actor, buff): - actor.setSpeedMultiplierBase(1) - return - \ No newline at end of file diff --git a/scripts/commands/combat/fs_drain_1.py b/scripts/commands/combat/fs_drain_1.py index c7937d1e..151d2a84 100644 --- a/scripts/commands/combat/fs_drain_1.py +++ b/scripts/commands/combat/fs_drain_1.py @@ -1,10 +1,6 @@ import sys def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - return def run(core, actor, target, damage): diff --git a/scripts/commands/combat/fs_drain_2.py b/scripts/commands/combat/fs_drain_2.py index c7937d1e..151d2a84 100644 --- a/scripts/commands/combat/fs_drain_2.py +++ b/scripts/commands/combat/fs_drain_2.py @@ -1,10 +1,6 @@ import sys def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - return def run(core, actor, target, damage): diff --git a/scripts/commands/combat/fs_drain_3.py b/scripts/commands/combat/fs_drain_3.py index c7937d1e..151d2a84 100644 --- a/scripts/commands/combat/fs_drain_3.py +++ b/scripts/commands/combat/fs_drain_3.py @@ -1,10 +1,6 @@ import sys def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - return def run(core, actor, target, damage): diff --git a/scripts/commands/combat/fs_drain_4.py b/scripts/commands/combat/fs_drain_4.py index c7937d1e..151d2a84 100644 --- a/scripts/commands/combat/fs_drain_4.py +++ b/scripts/commands/combat/fs_drain_4.py @@ -1,10 +1,6 @@ import sys def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - return def run(core, actor, target, damage): diff --git a/scripts/commands/combat/fs_drain_5.py b/scripts/commands/combat/fs_drain_5.py index c7937d1e..151d2a84 100644 --- a/scripts/commands/combat/fs_drain_5.py +++ b/scripts/commands/combat/fs_drain_5.py @@ -1,10 +1,6 @@ import sys def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - return def run(core, actor, target, damage): diff --git a/scripts/commands/combat/fs_flurry_1.py b/scripts/commands/combat/fs_flurry_1.py deleted file mode 100644 index 5e5c429e..00000000 --- a/scripts/commands/combat/fs_flurry_1.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_flurry_2.py b/scripts/commands/combat/fs_flurry_2.py deleted file mode 100644 index 5e5c429e..00000000 --- a/scripts/commands/combat/fs_flurry_2.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_flurry_3.py b/scripts/commands/combat/fs_flurry_3.py deleted file mode 100644 index 5e5c429e..00000000 --- a/scripts/commands/combat/fs_flurry_3.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_flurry_4.py b/scripts/commands/combat/fs_flurry_4.py deleted file mode 100644 index 5e5c429e..00000000 --- a/scripts/commands/combat/fs_flurry_4.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_flurry_5.py b/scripts/commands/combat/fs_flurry_5.py deleted file mode 100644 index 5e5c429e..00000000 --- a/scripts/commands/combat/fs_flurry_5.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_flurry_6.py b/scripts/commands/combat/fs_flurry_6.py deleted file mode 100644 index 5e5c429e..00000000 --- a/scripts/commands/combat/fs_flurry_6.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_flurry_7.py b/scripts/commands/combat/fs_flurry_7.py deleted file mode 100644 index 5e5c429e..00000000 --- a/scripts/commands/combat/fs_flurry_7.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_damage_line_fs_dm'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillMod('expertise_damage_line_fs_dm').getBase())/100)) - - if actor.getSkillMod('expertise_critical_line_fs_dm'): - command.setCriticalChance(command.getCriticalChance() + actor.getSkillMod('expertise_critical_line_fs_dm').getBase()) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_maelstrom_1.py b/scripts/commands/combat/fs_maelstrom_1.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_maelstrom_1.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_maelstrom_2.py b/scripts/commands/combat/fs_maelstrom_2.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_maelstrom_2.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_maelstrom_3.py b/scripts/commands/combat/fs_maelstrom_3.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_maelstrom_3.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_maelstrom_4.py b/scripts/commands/combat/fs_maelstrom_4.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_maelstrom_4.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_maelstrom_5.py b/scripts/commands/combat/fs_maelstrom_5.py deleted file mode 100644 index 70a66b61..00000000 --- a/scripts/commands/combat/fs_maelstrom_5.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): - command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/fs_sweep_2.py b/scripts/commands/combat/fs_sweep_2.py deleted file mode 100644 index 6671e0ad..00000000 --- a/scripts/commands/combat/fs_sweep_2.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_sweep'): - command.setCooldown(command.getCooldown() + (actor.getSkillModBase('expertise_cooldown_line_fs_sweep')/10)) - - if actor.getSkillMod('expertise_damage_line_fs_sweep'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillModBase('expertise_damage_line_fs_sweep'))/100)) - - if actor.getSkillMod('expertise_action_line_fs_sweep'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillModBase('expertise_action_line_fs_sweep'))/100)) - - return - -def run(core, actor, target, commandString): - return - \ No newline at end of file diff --git a/scripts/commands/combat/fs_sweep_3.py b/scripts/commands/combat/fs_sweep_3.py deleted file mode 100644 index 6671e0ad..00000000 --- a/scripts/commands/combat/fs_sweep_3.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_sweep'): - command.setCooldown(command.getCooldown() + (actor.getSkillModBase('expertise_cooldown_line_fs_sweep')/10)) - - if actor.getSkillMod('expertise_damage_line_fs_sweep'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillModBase('expertise_damage_line_fs_sweep'))/100)) - - if actor.getSkillMod('expertise_action_line_fs_sweep'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillModBase('expertise_action_line_fs_sweep'))/100)) - - return - -def run(core, actor, target, commandString): - return - \ No newline at end of file diff --git a/scripts/commands/combat/fs_sweep_4.py b/scripts/commands/combat/fs_sweep_4.py deleted file mode 100644 index 6671e0ad..00000000 --- a/scripts/commands/combat/fs_sweep_4.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_sweep'): - command.setCooldown(command.getCooldown() + (actor.getSkillModBase('expertise_cooldown_line_fs_sweep')/10)) - - if actor.getSkillMod('expertise_damage_line_fs_sweep'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillModBase('expertise_damage_line_fs_sweep'))/100)) - - if actor.getSkillMod('expertise_action_line_fs_sweep'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillModBase('expertise_action_line_fs_sweep'))/100)) - - return - -def run(core, actor, target, commandString): - return - \ No newline at end of file diff --git a/scripts/commands/combat/fs_sweep_5.py b/scripts/commands/combat/fs_sweep_5.py deleted file mode 100644 index 6671e0ad..00000000 --- a/scripts/commands/combat/fs_sweep_5.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_sweep'): - command.setCooldown(command.getCooldown() + (actor.getSkillModBase('expertise_cooldown_line_fs_sweep')/10)) - - if actor.getSkillMod('expertise_damage_line_fs_sweep'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillModBase('expertise_damage_line_fs_sweep'))/100)) - - if actor.getSkillMod('expertise_action_line_fs_sweep'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillModBase('expertise_action_line_fs_sweep'))/100)) - - return - -def run(core, actor, target, commandString): - return - \ No newline at end of file diff --git a/scripts/commands/combat/fs_sweep_6.py b/scripts/commands/combat/fs_sweep_6.py deleted file mode 100644 index 6671e0ad..00000000 --- a/scripts/commands/combat/fs_sweep_6.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_sweep'): - command.setCooldown(command.getCooldown() + (actor.getSkillModBase('expertise_cooldown_line_fs_sweep')/10)) - - if actor.getSkillMod('expertise_damage_line_fs_sweep'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillModBase('expertise_damage_line_fs_sweep'))/100)) - - if actor.getSkillMod('expertise_action_line_fs_sweep'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillModBase('expertise_action_line_fs_sweep'))/100)) - - return - -def run(core, actor, target, commandString): - return - \ No newline at end of file diff --git a/scripts/commands/combat/fs_sweep_7.py b/scripts/commands/combat/fs_sweep_7.py deleted file mode 100644 index 6671e0ad..00000000 --- a/scripts/commands/combat/fs_sweep_7.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys - -def setup(core, actor, target, command): - - if actor.getSkillMod('expertise_cooldown_line_fs_sweep'): - command.setCooldown(command.getCooldown() + (actor.getSkillModBase('expertise_cooldown_line_fs_sweep')/10)) - - if actor.getSkillMod('expertise_damage_line_fs_sweep'): - command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage() * actor.getSkillModBase('expertise_damage_line_fs_sweep'))/100)) - - if actor.getSkillMod('expertise_action_line_fs_sweep'): - command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillModBase('expertise_action_line_fs_sweep'))/100)) - - return - -def run(core, actor, target, commandString): - return - \ No newline at end of file diff --git a/scripts/commands/combat/of_cc_melee_2.py b/scripts/commands/combat/of_cc_melee_2.py deleted file mode 100644 index 045fbdaa..00000000 --- a/scripts/commands/combat/of_cc_melee_2.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_cc_melee_2', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_cc_melee_3.py b/scripts/commands/combat/of_cc_melee_3.py deleted file mode 100644 index cf690edf..00000000 --- a/scripts/commands/combat/of_cc_melee_3.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_cc_melee_3', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_cc_melee_4.py b/scripts/commands/combat/of_cc_melee_4.py deleted file mode 100644 index 46ace711..00000000 --- a/scripts/commands/combat/of_cc_melee_4.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_cc_melee_4', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_cc_melee_5.py b/scripts/commands/combat/of_cc_melee_5.py deleted file mode 100644 index 5d476219..00000000 --- a/scripts/commands/combat/of_cc_melee_5.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_cc_melee_5', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_cc_melee_6.py b/scripts/commands/combat/of_cc_melee_6.py deleted file mode 100644 index 1401aebc..00000000 --- a/scripts/commands/combat/of_cc_melee_6.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_cc_melee_6', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_cc_melee_7.py b/scripts/commands/combat/of_cc_melee_7.py deleted file mode 100644 index a31ea5ef..00000000 --- a/scripts/commands/combat/of_cc_melee_7.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_cc_melee_7', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_1.py b/scripts/commands/combat/of_deb_def_1.py deleted file mode 100644 index 97a9e475..00000000 --- a/scripts/commands/combat/of_deb_def_1.py +++ /dev/null @@ -1,15 +0,0 @@ -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_deb_def_1', actor) - if actor.getSkillMod('expertise_of_adv_paint_debuff'): - core.buffService.addBuffToCreature(target, 'of_deb_def_1', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_debuff_1', actor) - if actor.getSkillMod('expertise_of_adv_paint_expose'): - core.buffService.addBuffToCreature(target, 'of_deb_def_1', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_expose_1', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_2.py b/scripts/commands/combat/of_deb_def_2.py deleted file mode 100644 index 3343fc97..00000000 --- a/scripts/commands/combat/of_deb_def_2.py +++ /dev/null @@ -1,15 +0,0 @@ -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_deb_def_2', actor) - if actor.getSkillMod('expertise_of_adv_paint_debuff'): - core.buffService.addBuffToCreature(target, 'of_deb_def_2', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_debuff_2', actor) - if actor.getSkillMod('expertise_of_adv_paint_expose'): - core.buffService.addBuffToCreature(target, 'of_deb_def_2', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_expose_2', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_3.py b/scripts/commands/combat/of_deb_def_3.py deleted file mode 100644 index 77e1d3fc..00000000 --- a/scripts/commands/combat/of_deb_def_3.py +++ /dev/null @@ -1,15 +0,0 @@ -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_deb_def_3', actor) - if actor.getSkillMod('expertise_of_adv_paint_debuff'): - core.buffService.addBuffToCreature(target, 'of_deb_def_3', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_debuff_3', actor) - if actor.getSkillMod('expertise_of_adv_paint_expose'): - core.buffService.addBuffToCreature(target, 'of_deb_def_3', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_expose_3', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_4.py b/scripts/commands/combat/of_deb_def_4.py deleted file mode 100644 index b9aa9a9c..00000000 --- a/scripts/commands/combat/of_deb_def_4.py +++ /dev/null @@ -1,15 +0,0 @@ -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_deb_def_4', actor) - if actor.getSkillMod('expertise_of_adv_paint_debuff'): - core.buffService.addBuffToCreature(target, 'of_deb_def_4', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_debuff_4', actor) - if actor.getSkillMod('expertise_of_adv_paint_expose'): - core.buffService.addBuffToCreature(target, 'of_deb_def_4', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_expose_4', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_5.py b/scripts/commands/combat/of_deb_def_5.py deleted file mode 100644 index c641d203..00000000 --- a/scripts/commands/combat/of_deb_def_5.py +++ /dev/null @@ -1,15 +0,0 @@ -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_deb_def_5', actor) - if actor.getSkillMod('expertise_of_adv_paint_debuff'): - core.buffService.addBuffToCreature(target, 'of_deb_def_5', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_debuff_5', actor) - if actor.getSkillMod('expertise_of_adv_paint_expose'): - core.buffService.addBuffToCreature(target, 'of_deb_def_5', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_expose_5', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_6.py b/scripts/commands/combat/of_deb_def_6.py deleted file mode 100644 index 0dfde469..00000000 --- a/scripts/commands/combat/of_deb_def_6.py +++ /dev/null @@ -1,15 +0,0 @@ -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_deb_def_6', actor) - if actor.getSkillMod('expertise_of_adv_paint_debuff'): - core.buffService.addBuffToCreature(target, 'of_deb_def_6', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_debuff_6', actor) - if actor.getSkillMod('expertise_of_adv_paint_expose'): - core.buffService.addBuffToCreature(target, 'of_deb_def_6', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_expose_6', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_7.py b/scripts/commands/combat/of_deb_def_7.py deleted file mode 100644 index a5f19a81..00000000 --- a/scripts/commands/combat/of_deb_def_7.py +++ /dev/null @@ -1,15 +0,0 @@ -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_deb_def_7', actor) - if actor.getSkillMod('expertise_of_adv_paint_debuff'): - core.buffService.addBuffToCreature(target, 'of_deb_def_7', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_debuff_7', actor) - if actor.getSkillMod('expertise_of_adv_paint_expose'): - core.buffService.addBuffToCreature(target, 'of_deb_def_7', actor) - core.buffService.addBuffToCreature(target, 'of_adv_paint_expose_7', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_decapitate_2.py b/scripts/commands/combat/of_decapitate_2.py deleted file mode 100644 index fb2cecf3..00000000 --- a/scripts/commands/combat/of_decapitate_2.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_decap_bleed_2', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_decapitate_3.py b/scripts/commands/combat/of_decapitate_3.py deleted file mode 100644 index ffe4fa2f..00000000 --- a/scripts/commands/combat/of_decapitate_3.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_decap_bleed_3', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_decapitate_4.py b/scripts/commands/combat/of_decapitate_4.py deleted file mode 100644 index 99481e70..00000000 --- a/scripts/commands/combat/of_decapitate_4.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_decap_bleed_4', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_decapitate_5.py b/scripts/commands/combat/of_decapitate_5.py deleted file mode 100644 index a282c4ae..00000000 --- a/scripts/commands/combat/of_decapitate_5.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_decap_bleed_5', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_decapitate_6.py b/scripts/commands/combat/of_decapitate_6.py deleted file mode 100644 index dae1edb5..00000000 --- a/scripts/commands/combat/of_decapitate_6.py +++ /dev/null @@ -1,11 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_decap_bleed_6', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_sh_0.py b/scripts/commands/combat/of_sh_0.py deleted file mode 100644 index dcf378ac..00000000 --- a/scripts/commands/combat/of_sh_0.py +++ /dev/null @@ -1,8 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_of_heal'): - command.setCooldown(command.getCooldown() - actor.getSkillMod('expertise_cooldown_line_of_heal').getBase()) - return -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_sh_1.py b/scripts/commands/combat/of_sh_1.py deleted file mode 100644 index dcf378ac..00000000 --- a/scripts/commands/combat/of_sh_1.py +++ /dev/null @@ -1,8 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_of_heal'): - command.setCooldown(command.getCooldown() - actor.getSkillMod('expertise_cooldown_line_of_heal').getBase()) - return -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_sh_2.py b/scripts/commands/combat/of_sh_2.py deleted file mode 100644 index dcf378ac..00000000 --- a/scripts/commands/combat/of_sh_2.py +++ /dev/null @@ -1,8 +0,0 @@ -import sys - -def setup(core, actor, target, command): - if actor.getSkillMod('expertise_cooldown_line_of_heal'): - command.setCooldown(command.getCooldown() - actor.getSkillMod('expertise_cooldown_line_of_heal').getBase()) - return -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_vortex_2.py b/scripts/commands/combat/of_vortex_2.py deleted file mode 100644 index 61b586d4..00000000 --- a/scripts/commands/combat/of_vortex_2.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_vortex_bleed_2', actor) - core.buffService.addBuffToCreature(target, 'of_vortex_root', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_vortex_3.py b/scripts/commands/combat/of_vortex_3.py deleted file mode 100644 index 4507ec9d..00000000 --- a/scripts/commands/combat/of_vortex_3.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_vortex_bleed_3', actor) - core.buffService.addBuffToCreature(target, 'of_vortex_root', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_vortex_4.py b/scripts/commands/combat/of_vortex_4.py deleted file mode 100644 index ff87ce05..00000000 --- a/scripts/commands/combat/of_vortex_4.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_vortex_bleed_4', actor) - core.buffService.addBuffToCreature(target, 'of_vortex_root', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/of_vortex_5.py b/scripts/commands/combat/of_vortex_5.py deleted file mode 100644 index ae7aacee..00000000 --- a/scripts/commands/combat/of_vortex_5.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys - -def setup(core, actor, target, command): - core.buffService.addBuffToCreature(target, 'of_vortex_bleed_5', actor) - core.buffService.addBuffToCreature(target, 'of_vortex_root', actor) - return - -def preRun(core, actor, target, command): - return - -def run(core, actor, target, commandString): - return \ No newline at end of file diff --git a/scripts/commands/combat/bh_dm_crit_1.py b/scripts/commands/combat/specialline/dm_crit.py similarity index 99% rename from scripts/commands/combat/bh_dm_crit_1.py rename to scripts/commands/combat/specialline/dm_crit.py index c12e2a2a..255abc90 100644 --- a/scripts/commands/combat/bh_dm_crit_1.py +++ b/scripts/commands/combat/specialline/dm_crit.py @@ -1,6 +1,7 @@ import sys def setup(core, actor, target, command): + if actor.getSkillMod('expertise_cooldown_line_dm_crit'): command.setCooldown(command.getCooldown() - (actor.getSkillModBase('expertise_cooldown_line_dm_crit')/10)) diff --git a/scripts/commands/combat/en_spiral_kick_0.py b/scripts/commands/combat/specialline/en_spiral_kick.py similarity index 79% rename from scripts/commands/combat/en_spiral_kick_0.py rename to scripts/commands/combat/specialline/en_spiral_kick.py index 62a7efb2..411ab81b 100644 --- a/scripts/commands/combat/en_spiral_kick_0.py +++ b/scripts/commands/combat/specialline/en_spiral_kick.py @@ -4,8 +4,6 @@ def setup(core, actor, target, command): core.buffService.addBuffToCreature(target, 'en_spiral_kick_snare', actor) return -def preRun(core, actor, target, command): - return - def run(core, actor, target, commandString): - return \ No newline at end of file + return + \ No newline at end of file diff --git a/scripts/commands/combat/en_thrill.py b/scripts/commands/combat/specialline/en_thrill.py similarity index 78% rename from scripts/commands/combat/en_thrill.py rename to scripts/commands/combat/specialline/en_thrill.py index 1dbabf6a..3a190ed7 100644 --- a/scripts/commands/combat/en_thrill.py +++ b/scripts/commands/combat/specialline/en_thrill.py @@ -4,8 +4,6 @@ def setup(core, actor, target, command): core.buffService.addBuffToCreature(target, 'en_debuff_thrill', actor) return -def preRun(core, actor, target, command): - return - def run(core, actor, target, commandString): - return \ No newline at end of file + return + \ No newline at end of file diff --git a/scripts/commands/combat/en_void_dance.py b/scripts/commands/combat/specialline/en_void_dance.py similarity index 78% rename from scripts/commands/combat/en_void_dance.py rename to scripts/commands/combat/specialline/en_void_dance.py index 2354238e..11c05b4b 100644 --- a/scripts/commands/combat/en_void_dance.py +++ b/scripts/commands/combat/specialline/en_void_dance.py @@ -4,8 +4,6 @@ def setup(core, actor, target, command): core.buffService.addBuffToCreature(target, 'en_void_dance_buff') return -def preRun(core, actor, target, command): - return - def run(core, actor, target, commandString): - return \ No newline at end of file + return + \ No newline at end of file diff --git a/scripts/commands/combat/fs_ae_dm_cc_1.py b/scripts/commands/combat/specialline/fs_ae_dm_cc.py similarity index 98% rename from scripts/commands/combat/fs_ae_dm_cc_1.py rename to scripts/commands/combat/specialline/fs_ae_dm_cc.py index 70a66b61..0d144ace 100644 --- a/scripts/commands/combat/fs_ae_dm_cc_1.py +++ b/scripts/commands/combat/specialline/fs_ae_dm_cc.py @@ -1,10 +1,8 @@ import sys def setup(core, actor, target, command): - if actor.getSkillMod('expertise_fs_dm_armor_bypass'): command.setBypassArmor(actor.getSkillModBase("expertise_fs_dm_armor_bypass")) - return def run(core, actor, target, commandString): diff --git a/scripts/commands/combat/specialline/fs_cc_crit.py b/scripts/commands/combat/specialline/fs_cc_crit.py new file mode 100644 index 00000000..77f1dfa2 --- /dev/null +++ b/scripts/commands/combat/specialline/fs_cc_crit.py @@ -0,0 +1,17 @@ +import sys + +def setup(core, actor, target, command): + if actor.getSkillMod('expertise_damage_line_fs_cc_crit'): + command.setAddedDamage(command.getAddedDamage() + ((command.getAddedDamage()*actor.getSkillModBase('expertise_damage_line_fs_cc_crit'))/100)) + + if actor.getSkillMod('expertise_action_line_fs_cc_crit'): + command.setActionCost(command.getActionCost() - ((command.getActionCost() * actor.getSkillModBase('expertise_action_line_fs_cc_crit'))/100)) + + if actor.getSkillMod('expertise_cooldown_line_fs_cc_crit'): + command.setCooldown(command.getCooldown() + (actor.getSkillModBase('expertise_cooldown_line_fs_cc_crit')/10)) + + return + +def run(core, actor, target, commandString): + return + \ No newline at end of file diff --git a/scripts/commands/combat/fs_dm_1.py b/scripts/commands/combat/specialline/fs_dm.py similarity index 100% rename from scripts/commands/combat/fs_dm_1.py rename to scripts/commands/combat/specialline/fs_dm.py diff --git a/scripts/commands/combat/fs_sweep_1.py b/scripts/commands/combat/specialline/fs_sweep.py similarity index 100% rename from scripts/commands/combat/fs_sweep_1.py rename to scripts/commands/combat/specialline/fs_sweep.py diff --git a/scripts/commands/combat/of_cc_melee_1.py b/scripts/commands/combat/specialline/of_cc_melee.py similarity index 78% rename from scripts/commands/combat/of_cc_melee_1.py rename to scripts/commands/combat/specialline/of_cc_melee.py index d6c0b925..becf4445 100644 --- a/scripts/commands/combat/of_cc_melee_1.py +++ b/scripts/commands/combat/specialline/of_cc_melee.py @@ -4,8 +4,6 @@ def setup(core, actor, target, command): core.buffService.addBuffToCreature(target, 'of_cc_melee_1', actor) return -def preRun(core, actor, target, command): - return - def run(core, actor, target, commandString): - return \ No newline at end of file + return + \ No newline at end of file diff --git a/scripts/commands/combat/of_decapitate_1.py b/scripts/commands/combat/specialline/of_decapitate.py similarity index 100% rename from scripts/commands/combat/of_decapitate_1.py rename to scripts/commands/combat/specialline/of_decapitate.py diff --git a/scripts/commands/combat/of_sh_3.py b/scripts/commands/combat/specialline/of_heal.py similarity index 96% rename from scripts/commands/combat/of_sh_3.py rename to scripts/commands/combat/specialline/of_heal.py index e19f3ca1..6ee2d927 100644 --- a/scripts/commands/combat/of_sh_3.py +++ b/scripts/commands/combat/specialline/of_heal.py @@ -7,4 +7,5 @@ def setup(core, actor, target, command): return def run(core, actor, target, commandString): - return \ No newline at end of file + return + \ No newline at end of file diff --git a/scripts/commands/combat/of_deb_def_8.py b/scripts/commands/combat/specialline/of_paint.py similarity index 100% rename from scripts/commands/combat/of_deb_def_8.py rename to scripts/commands/combat/specialline/of_paint.py diff --git a/scripts/commands/combat/of_vortex_1.py b/scripts/commands/combat/specialline/of_vortex.py similarity index 83% rename from scripts/commands/combat/of_vortex_1.py rename to scripts/commands/combat/specialline/of_vortex.py index 72cf4b13..b17983e6 100644 --- a/scripts/commands/combat/of_vortex_1.py +++ b/scripts/commands/combat/specialline/of_vortex.py @@ -5,8 +5,5 @@ def setup(core, actor, target, command): core.buffService.addBuffToCreature(target, 'of_vortex_root', actor) return -def preRun(core, actor, target, command): - return - def run(core, actor, target, commandString): return \ No newline at end of file diff --git a/scripts/commands/credits.py b/scripts/commands/credits.py index 2ba1d840..6355c894 100644 --- a/scripts/commands/credits.py +++ b/scripts/commands/credits.py @@ -9,7 +9,7 @@ def run(core, actor, target, commandString): if actor: actor.setCashCredits(actor.getCashCredits() + int(arg1)) - actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF Credits: Command completed successfully. You have given yourself ' + arg1 + 'credits.', 0) + actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF Credits: Command completed successfully. You have given yourself ' + arg1 + ' credits.', 0) if actor and target: target.setCashCredits(target.getCashCredits() + int(arg1)) diff --git a/scripts/commands/giveitem.py b/scripts/commands/giveitem.py index 65791788..0b9d2642 100644 --- a/scripts/commands/giveitem.py +++ b/scripts/commands/giveitem.py @@ -9,10 +9,7 @@ def run(core, actor, target, commandString): arg1 = commandArgs[0] if len(commandArgs) > 1: arg2 = commandArgs[1] - - if actor.getClient() and actor.getClient().isGM() == False: - return - + if not commandString.startswith('object/tangible') and not commandString.startswith('object/weapon'): return diff --git a/scripts/commands/gmforcecommand.py b/scripts/commands/gmforcecommand.py new file mode 100644 index 00000000..d04fe80a --- /dev/null +++ b/scripts/commands/gmforcecommand.py @@ -0,0 +1,250 @@ +import sys +from engine.resources.scene import Point3D +from protocol.swg import ObjControllerMessage +from protocol.swg import GrantCommand +from protocol.swg import PlayClientEffectLocMessage +from engine.resources.objects import SWGObject +from java.awt.datatransfer import StringSelection +from java.awt.datatransfer import Clipboard +from java.awt import Toolkit +from resources.datatables import GcwRank +from services.gcw import GCWService + + +def setup(): + return + +def run(core, actor, target, commandString): + + playerObject = actor.getSlottedObject('ghost') + + global str + + if not playerObject: + return + + commandArgs = commandString.split(' ') + command = commandArgs[0] + if len(commandArgs) > 1: + arg1 = commandArgs[1] + if len(commandArgs) > 2: + arg2 = commandArgs[2] + if len(commandArgs) > 3: + arg3 = commandArgs[3] + if len(commandArgs) > 4: + arg4 = commandArgs[4] + if len(commandArgs) > 5: + arg5 = commandArgs[5] + + if command == 'giveExperience' and arg1: + core.playerService.giveExperience(actor, int(arg1)) + + if command == 'level' and arg1: + core.playerService.grantLevel(actor, int(arg1)) + + elif command == 'addability' and arg1: + actor.addAbility(str(arg1)) + actor.sendSystemMessage('You have learned ' + arg1 + '.', 0) + + elif command == 'anim' and arg1: + actor.doSkillAnimation(arg1) + actor.sendSystemMessage('Performed ' + arg1 ,0) + + elif command == 'changeBio' and arg1: + actor.getSlottedObject('ghost').setBiography(arg1) + + elif command == 'spawn' and arg1 and arg2: + pos = actor.getWorldPosition() + core.spawnService.spawnCreature(arg1, actor.getPlanet().getName(), 0, pos.x, pos.y, pos.z, 1, 0, 1, 0, int(arg2)) + + elif command == 'instance' and arg1: + core.instanceService.queue(arg1, actor) + + elif command == 'action' and arg1: + actor.setAction(int(arg1)) + + elif command == 'health' and arg1: + actor.setHealth(int(arg1)) + + elif command == 'cust' and arg1 and arg2 and arg3: + obj = core.objectService.getObject(long(arg1)) + obj.setCustomizationVariable(str(arg2), int(arg3)) + + elif command == 'buff' and arg1: + core.buffService.addBuffToCreature(actor, str(arg1), actor) + + elif command == 'holoEmote' and arg1: + playerObject.setHoloEmote('holoemote_' + arg1) + playerObject.setHoloEmoteUses(20) + actor.sendSystemMessage('Holo-Emote Generator set to ' + 'holoemote_' + arg1, 0) + + elif command == 'off': + if playerObject.getGodLevel > 0: + actor.removeAbility("admin") + playerObject.setGodLevel(0) + + elif command == 'setBounty': + if actor.getFaction() == "": + actor.sendSystemMessage('You must be aligned in order to place a bounty on yourself.', 0) + return + core.playerService.sendSetBountyWindow(actor, actor) + return + + elif command == 'genloot': + object = core.lootService.generateLootItem(actor, arg1) + + inventory = actor.getSlottedObject('inventory') + + if inventory: + inventory.add(object) + + elif command == 'spawnobj': + pos = actor.getPosition() + core.staticService.spawnObject(arg1, actor.getPlanet().getName(), 0, pos.x, pos.y, pos.z, 0, 0) + + elif command == 'showpos': + pos = actor.getPosition() + ori = actor.getOrientation() + cellid = 0 + planetName = actor.getPlanet().getName() + + actor.sendSystemMessage('Position.x : %s' % pos.x, 0) + print ('Position.x : %s' % pos.x, 0) + actor.sendSystemMessage('Position.y : %s' % pos.y, 0) + print ('Position.y : %s' % pos.y, 0) + actor.sendSystemMessage('Position.z : %s' % pos.z, 0) + print ('Position.z : %s' % pos.z, 0) + actor.sendSystemMessage('Orientation.w : %s' % ori.w, 0) + print ('Orientation.x : %s' % ori.w, 0) + actor.sendSystemMessage('Orientation.x : %s' % ori.x, 0) + print ('Orientation.w : %s' % ori.x, 0) + actor.sendSystemMessage('Orientation.y : %s' % ori.y, 0) + print ('Orientation.y : %s' % ori.y, 0) + actor.sendSystemMessage('Orientation.z : %s' % ori.z, 0) + print ('Orientation.z : %s' % ori.z, 0) + if (actor.getContainer()): + building_id = actor.getGrandparent().getObjectID() + cid = actor.getContainer().getCellNumber() + cellid = cid + actor.sendSystemMessage('Cell ID : %s' % cid, 0) + actor.sendSystemMessage('Building ID : %s' % building_id, 0) + print('Cell ID : %s' % cid, 0) + print('Building ID : %s' % building_id, 0) + if cellid == 0: + str = " = stcSvc.spawnObject('', '" + planetName + "', long(%s" % cellid + "), float(%.4f" % pos.x + "), float(%.4f" % pos.y + "), float(%.4f" % pos.z + "), float(%.4f" % ori.w + "), float(%.4f" % ori.x + "), float(%.4f" % ori.y + "), float(%.4f" % ori.z + "))" + elif cellid != 0: + str = "\tbuilding = core.objectService.getObject(long(%s" % building_id + "))\n\t = stcSvc.spawnObject('', '" + planetName + "', building.getCellByCellNumber(long(%s" % cellid + ")), float(%.4f" % pos.x + "), float(%.4f" % pos.y + "), float(%.4f" % pos.z + "), float(%.4f" % ori.w + "), float(%.4f" % ori.x + "), float(%.4f" % ori.y + "), float(%.4f" % ori.z + "))" + toolkit = Toolkit.getDefaultToolkit() + clipboard = toolkit.getSystemClipboard() + clipboard.setContents(StringSelection(str), None) + + elif command == 'patrolpoint': + pos = actor.getPosition() + str = "patrolpoints.add(Point3D(float(%.2f" % pos.x + "), float(%.2f" % pos.y + "), float(%.2f" % pos.z + ")))" + toolkit = Toolkit.getDefaultToolkit() + clipboard = toolkit.getSystemClipboard() + clipboard.setContents(StringSelection(str), None) + actor.sendSystemMessage('Patrolpoint copied to clipboard', 0) + + elif command == 'checkai': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + actor.sendSystemMessage('Checking AI handling for unit ' + latarget.getCustomName(), 0) + core.aiService.setCheckAI(latarget) + + elif command == 'checkaitarget': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + if latarget.getAttachment('AI'): + if latarget.getAttachment('AI').getFollowObject(): + actor.sendSystemMessage('Checking AI target ' + latarget.getAttachment('AI').getFollowObject().getTemplate(), 0) + + elif command == 'checkaistate': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + if latarget.getAttachment('AI'): + if latarget.getAttachment('AI').getCurrentState(): + actor.sendSystemMessage('Checking AI state ' + latarget.getAttachment('AI').getCurrentState().getClass().getName(), 0) + + elif command == 'checkairepos': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + if latarget.getAttachment('AI'): + if latarget.getAttachment('AI').getRepositionStartTime()(): + actor.sendSystemMessage('Checking AI state ' + latarget.getAttachment('AI').getRepositionStartTime(), 0) + + elif command == 'checkaiprog': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + if latarget.getAttachment('AI'): + actor.sendSystemMessage('Checking AI progression %s' % latarget.getAttachment('AI').getProgressionMarker(), 0) + + elif command == 'checkwithdrawn': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + if latarget.getAttachment('isWithdrawn'): + actor.sendSystemMessage('Checking AIisWithdrawn %s' % latarget.getAttachment('isWithdrawn'), 0) + + elif command == 'showbitmask': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + actor.sendSystemMessage('Optionsbitmask for unit ' + latarget.getCustomName() + ' is %s' % latarget.getOptionsBitmask(), 0) + + elif command == 'spawninst': + + #String campTemplate = "object/building/poi/shared_gcw_rebel_clone_tent_small.iff"; // LOL why doesn't this spawn?!?!?! + inst = core.objectService.createObject(arg1, 0, actor.getPlanet(), actor.getWorldPosition(), actor.getOrientation()) + if inst: + #TangibleObject inst = (TangibleObject) core.objectService.createObject(campTemplate, 0, core.terrainService.getPlanetByName("talus"), new Point3D(-890,9, -2994), quaternion) + core.simulationService.add(inst, inst.getPosition().x, inst.getPosition().z, True) + positionY = core.terrainService.getHeight(inst.getPlanetId(), inst.getPosition().x, inst.getPosition().z) + instpos = Point3D(inst.getPosition().x,positionY+2, inst.getPosition().z) + inst.setPosition(instpos) + + elif command == 'los': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + los = core.simulationService.checkLineOfSight(actor, latarget) + if los: + actor.sendSystemMessage('Line of sight between player and target', 0) + else: + actor.sendSystemMessage('NO Line of sight between player and target', 0) + + elif command == 'playfx': + effectFile = arg1 + cEffMsg = PlayClientEffectLocMessage(effectFile, actor.getPlanet().getName(), actor.getPosition()) + actor.getClient().getSession().write(cEffMsg.serialize()) + + elif command == 'toinvasion': + invasionplanet = core.invasionService.getInvasionPlanetName() + position = Point3D(float(1366), float(13), float(2747)) + if invasionplanet == 'talus': + position = Point3D(float(264), float(4), float(-2950)) + if invasionplanet == 'tatooine': + position = Point3D(float(-1385), float(12), float(-3597)) + + core.simulationService.transferToPlanet(actor, core.terrainService.getPlanetByName(invasionplanet), position, actor.getOrientation(), None) + + elif command == 'unknownAbilityPacket' and arg1: + packet = UnknownAbilityPacket(arg1) + actor.getClient().getSession().write(packet.serialize()) + actor.sendSystemMessage('Sent UnknownAbilityPacket for ability ' + arg1, 0) + return + + elif command == 'rank' and arg1: + playerObject.setCurrentRank(int(arg1)) + print (playerObject.getCurrentRank()) + return + + elif command == 'addToFrogAdminList': + frogBuilding = core.objectService.getObject(core.devService.getFrogBuildingId()) + + if frogBuilding is None: + return + + frogBuilding.addPlayerToAdminList(None, actor.getObjectID(), actor.getCustomName().split(' ')[0]) + actor.sendSystemMessage('You were added to the Admin list for the Frog Building.', 0) + return + return + + \ No newline at end of file diff --git a/scripts/commands/pvp.py b/scripts/commands/pvp.py index 34f6c5ff..cc30e82b 100644 --- a/scripts/commands/pvp.py +++ b/scripts/commands/pvp.py @@ -10,7 +10,7 @@ def setup(): def run(core, actor, target, commandString): faction = actor.getFaction() factionStatus = actor.getFactionStatus() - + if actor.getPvpStatus(PvpStatus.GoingOvert) or actor.getPvpStatus(PvpStatus.GoingCovert): actor.sendSystemMessage('@faction_recruiter:pvp_status_changing', 0) return @@ -18,9 +18,10 @@ def run(core, actor, target, commandString): actor.sendSystemMessage('@gcw:pvp_advanced_region_cannot_go_covert', 0) return - if commandString != '' and commandString != faction: + if commandString != '' and commandString != faction and len(faction)!=0: if commandString == 'rebel' or commandString == 'imperial' or commandString == 'neutral': - if faction != 'neutral': + + if faction != 'neutral' and len(faction)!=0: actor.sendSystemMessage('@faction_recruiter:sui_resig_complete_in_5', 0) if actor.getFactionStatus() == FactionStatus.SpecialForces: @@ -37,7 +38,7 @@ def run(core, actor, target, commandString): if commandString == 'neutral' or commandString == 'resign': time.sleep(1) - actor.setFaction('') + actor.setFaction('') # ??? actor.sendSystemMessage('@faction_recruiter:resign_complete', 0) return @@ -45,6 +46,15 @@ def run(core, actor, target, commandString): actor.setFaction(commandString) return + #This can be removed if player is required to see the recruiter first + if faction == '': + actor.setFactionStatus(FactionStatus.Combatant) # Must be! otherwise updatePVPstatus will be called with onLeave! + actor.setFaction(commandString) + player = actor.getSlottedObject("ghost") + if player.getCurrentRank()==0: + player.setCurrentRank(1); + faction = commandString + if faction == 'neutral' or faction == '': actor.sendSystemMessage('@faction_recruiter:not_aligned', 0) return @@ -53,10 +63,11 @@ def run(core, actor, target, commandString): actor.sendSystemMessage('@faction_recruiter:on_leave_to_covert', 0) actor.setPvpStatus(PvpStatus.GoingCovert, True) time.sleep(1) - actor.setFactionStatus(FactionStatus.Combatant) actor.setPvpStatus(PvpStatus.GoingCovert, False) + actor.setFactionStatus(FactionStatus.Combatant) actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) actor.updatePvpStatus() + core.factionService.updatePVPFromNearbyNPCs(actor, actor.getClient()) return if factionStatus == FactionStatus.Combatant: @@ -65,8 +76,8 @@ def run(core, actor, target, commandString): time.sleep(30) if core.gcwService.isInPvpZone(actor): return - actor.setFactionStatus(FactionStatus.SpecialForces) actor.setPvpStatus(PvpStatus.GoingOvert, False) + actor.setFactionStatus(FactionStatus.SpecialForces) actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) actor.updatePvpStatus() return diff --git a/scripts/commands/setgodmode.py b/scripts/commands/setgodmode.py index e00e103d..aeff3947 100644 --- a/scripts/commands/setgodmode.py +++ b/scripts/commands/setgodmode.py @@ -1,217 +1,12 @@ +# This file will be updated at a later date with a new command. + import sys -from engine.resources.scene import Point3D -from protocol.swg import ObjControllerMessage -from protocol.swg import UnknownAbilityPacket -from engine.resources.objects import SWGObject -from java.awt.datatransfer import StringSelection -from java.awt.datatransfer import Clipboard -from java.awt import Toolkit -from resources.datatables import GcwRank -from services.gcw import GCWService - - +from resources.common import ProsePackage +from resources.common import OutOfBand +from protocol.swg import CreateClientPathMessage def setup(): - return - -def run(core, actor, target, commandString): - - playerObject = actor.getSlottedObject('ghost') - - global str - - if not playerObject: - return - - commandArgs = commandString.split(' ') - command = commandArgs[0] - if len(commandArgs) > 1: - arg1 = commandArgs[1] - if len(commandArgs) > 2: - arg2 = commandArgs[2] - if len(commandArgs) > 3: - arg3 = commandArgs[3] - if len(commandArgs) > 4: - arg4 = commandArgs[4] - if len(commandArgs) > 5: - arg5 = commandArgs[5] - - if not command: - return - - if actor.getClient().isGM() is False: - return - - if playerObject.getGodLevel() == 0: - actor.addAbility("admin") - playerObject.setGodLevel(50) - - if command == 'giveExperience' and arg1: - core.playerService.giveExperience(actor, int(arg1)) - - if command == 'level' and arg1: - core.playerService.grantLevel(actor, int(arg1)) - - elif command == 'setSpeed' and arg1: - #actor.sendSystemMessage("Your speed was " + str(actor.getSpeedMultiplierBase()) + ". Don\'t forget to set this back or it\'ll permanently imbalance your speed. Default without buffs or mods is 1.", 2) - actor.setSpeedMultiplierBase(float(arg1)) - actor.sendSystemMessage('Your new speed is ' + arg1 + '.', 2) - - elif command == 'teleport' and arg2 and arg3 and arg4: - position = Point3D(float(arg2), float(arg3), float(arg4)) - core.simulationService.transferToPlanet(actor, core.terrainService.getPlanetByName(arg1), position, actor.getOrientation(), None) - - elif command == 'teleportplayer' and arg1 and arg2 and arg3 and arg4 and arg5: - player = core.chatService.getObjectByFirstName(arg1) - if player: - position = Point3D(float(arg3), float(arg4), float(arg5)) - core.simulationService.transferToPlanet(player, core.terrainService.getPlanetByName(arg2), position, player.getOrientation(), None) - - elif command == 'credits' and arg1: - actor.setCashCredits(actor.getCashCredits() + int(arg1)) - actor.sendSystemMessage('The Galactic Empire has transferred ' + arg1 + ' credits to you for your service.', 0) - - elif command == 'addability' and arg1: - actor.addAbility(str(arg1)) - actor.sendSystemMessage('You have learned ' + arg1 + '.', 0) - - elif command == 'anim' and arg1: - actor.doSkillAnimation(arg1) - actor.sendSystemMessage('Performed ' + arg1 ,0) - - elif command == 'changeBio' and arg1: - actor.getSlottedObject('ghost').setBiography(arg1) - - elif command == 'spawn' and arg1 and arg2: - pos = actor.getWorldPosition() - core.spawnService.spawnCreature(arg1, actor.getPlanet().getName(), 0, pos.x, pos.y, pos.z, 1, 0, 1, 0, int(arg2)) - - elif command == 'instance' and arg1: - core.instanceService.queue(arg1, actor) - - elif command == 'action' and arg1: - actor.setAction(int(arg1)) - - elif command == 'health' and arg1: - actor.setHealth(int(arg1)) - - elif command == 'id': - actor.sendSystemMessage('Your id is: ' + str(actor.getObjectId()), 0) - - elif command == 'cust' and arg1 and arg2 and arg3: - obj = core.objectService.getObject(long(arg1)) - obj.setCustomizationVariable(str(arg2), int(arg3)) - - elif command == 'buff' and arg1: - core.buffService.addBuffToCreature(actor, str(arg1), actor) - - elif command == 'stealth': - if (actor.isInStealth()): - actor.setInStealth(False) - actor.setRadarVisible(True) - else: - actor.setInStealth(True) - actor.setRadarVisible(False) - - elif command == 'holoEmote' and arg1: - playerObject.setHoloEmote('holoemote_' + arg1) - playerObject.setHoloEmoteUses(20) - actor.sendSystemMessage('Holo-Emote Generator set to ' + 'holoemote_' + arg1, 0) - - elif command == 'off': - if playerObject.getGodLevel > 0: - actor.removeAbility("admin") - playerObject.setGodLevel(0) - - elif command == 'setBounty': - if actor.getFaction() == "": - actor.sendSystemMessage('You must be aligned in order to place a bounty on yourself.', 0) - return - core.playerService.sendSetBountyWindow(actor, actor) - return - - elif command == 'genloot': - object = core.lootService.generateLootItem(actor, arg1) - - inventory = actor.getSlottedObject('inventory') - - if inventory: - inventory.add(object) - - elif command == 'spawnobj': - pos = actor.getPosition() - core.staticService.spawnObject(arg1, actor.getPlanet().getName(), 0, pos.x, pos.y, pos.z, 0, 0) - - elif command == 'showpos': - pos = actor.getPosition() - ori = actor.getOrientation() - cellid = 0 - planetName = actor.getPlanet().getName() - - actor.sendSystemMessage('Position.x : %s' % pos.x, 0) - print ('Position.x : %s' % pos.x, 0) - actor.sendSystemMessage('Position.y : %s' % pos.y, 0) - print ('Position.y : %s' % pos.y, 0) - actor.sendSystemMessage('Position.z : %s' % pos.z, 0) - print ('Position.z : %s' % pos.z, 0) - actor.sendSystemMessage('Orientation.w : %s' % ori.w, 0) - print ('Orientation.x : %s' % ori.w, 0) - actor.sendSystemMessage('Orientation.x : %s' % ori.x, 0) - print ('Orientation.w : %s' % ori.x, 0) - actor.sendSystemMessage('Orientation.y : %s' % ori.y, 0) - print ('Orientation.y : %s' % ori.y, 0) - actor.sendSystemMessage('Orientation.z : %s' % ori.z, 0) - print ('Orientation.z : %s' % ori.z, 0) - if (actor.getContainer()): - building_id = actor.getGrandparent().getObjectID() - cid = actor.getContainer().getCellNumber() - cellid = cid - actor.sendSystemMessage('Cell ID : %s' % cid, 0) - actor.sendSystemMessage('Building ID : %s' % building_id, 0) - print('Cell ID : %s' % cid, 0) - print('Building ID : %s' % building_id, 0) - if cellid == 0: - str = " = stcSvc.spawnObject('', '" + planetName + "', long(%s" % cellid + "), float(%.4f" % pos.x + "), float(%.4f" % pos.y + "), float(%.4f" % pos.z + "), float(%.4f" % ori.w + "), float(%.4f" % ori.x + "), float(%.4f" % ori.y + "), float(%.4f" % ori.z + "))" - elif cellid != 0: - str = "\tbuilding = core.objectService.getObject(long(%s" % building_id + "))\n\t = stcSvc.spawnObject('', '" + planetName + "', building.getCellByCellNumber(long(%s" % cellid + ")), float(%.4f" % pos.x + "), float(%.4f" % pos.y + "), float(%.4f" % pos.z + "), float(%.4f" % ori.w + "), float(%.4f" % ori.x + "), float(%.4f" % ori.y + "), float(%.4f" % ori.z + "))" - toolkit = Toolkit.getDefaultToolkit() - clipboard = toolkit.getSystemClipboard() - clipboard.setContents(StringSelection(str), None) - - elif command == 'patrolpoint': - pos = actor.getPosition() - str = "patrolpoints.add(Point3D(float(%.2f" % pos.x + "), float(%.2f" % pos.y + "), float(%.2f" % pos.z + ")))" - toolkit = Toolkit.getDefaultToolkit() - clipboard = toolkit.getSystemClipboard() - clipboard.setContents(StringSelection(str), None) - actor.sendSystemMessage('Patrolpoint copied to clipboard', 0) - - elif command == 'jesus': - actor.setHealth(actor.getMaxHealth()) - actor.setAction(actor.getMaxAction()) - actor.setPosture(0) - actor.setSpeedMultiplierBase(1) - actor.setTurnRadius(1) - - elif command == 'unknownAbilityPacket' and arg1: - packet = UnknownAbilityPacket(arg1) - actor.getClient().getSession().write(packet.serialize()) - actor.sendSystemMessage('Sent UnknownAbilityPacket for ability ' + arg1, 0) - return - - elif command == 'rank' and arg1: - playerObject.setCurrentRank(int(arg1)) - print (playerObject.getCurrentRank()) - return - - elif command == 'addToFrogAdminList': - frogBuilding = core.objectService.getObject(core.devService.getFrogBuildingId()) - - if frogBuilding is None: - return - - frogBuilding.addPlayerToAdminList(None, actor.getObjectID(), actor.getCustomName().split(' ')[0]) - actor.sendSystemMessage('You were added to the Admin list for the Frog Building.', 0) - return return - - \ No newline at end of file + +def run(core, actor, target, commandString): + core.questService.giveBasicQuest(actor) + return \ No newline at end of file diff --git a/scripts/commands/teleporttarget.py b/scripts/commands/teleporttarget.py index 9a9fde95..f3fbf450 100644 --- a/scripts/commands/teleporttarget.py +++ b/scripts/commands/teleporttarget.py @@ -11,12 +11,15 @@ def run(core, actor, target, commandString): if not playerObject: return + if target is None: + target = core.objectService.getObjectByFirstName(commandString) + if target and target.getSlottedObject('ghost') is not None: actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF teleportTarget: Command completed successfully.', 0) core.simulationService.teleport(target, actor.getPosition(), actor.getOrientation(), 0) return else: - actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF teleportTarget: Invalid Syntax. Syntax is: /teleportTarget ', 0) + actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF teleportTarget: Invalid Syntax. Syntax is: /teleportTarget or /teleportTarget ', 0) return return diff --git a/scripts/faction/imperial.py b/scripts/faction/imperial.py index b5bc8cc0..f7b1232c 100644 --- a/scripts/faction/imperial.py +++ b/scripts/faction/imperial.py @@ -1,6 +1,8 @@ import sys def isAlly(ally): + if ally == 'imperial': + return 1 return 0 def isEnemy(enemy): diff --git a/scripts/faction/rebel.py b/scripts/faction/rebel.py index 0d685a6a..f435ab8c 100644 --- a/scripts/faction/rebel.py +++ b/scripts/faction/rebel.py @@ -1,6 +1,8 @@ import sys def isAlly(ally): + if ally == 'rebel': + return 1 return 0 def isEnemy(enemy): diff --git a/scripts/mobiles/generic/faction/imperial/elite_imperial_stormtrooper_90.py b/scripts/mobiles/generic/faction/imperial/elite_imperial_stormtrooper_90.py new file mode 100644 index 00000000..e1fa305b --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/elite_imperial_stormtrooper_90.py @@ -0,0 +1,43 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('crackdown_stormtrooper_hard') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + + templates = Vector() + templates.add('object/mobile/shared_dressed_stormtrooper_black_white.iff') + templates.add('object/mobile/shared_dressed_stormtrooper_white_black.iff') + templates.add('object/mobile/shared_dressed_stormtrooper_white_white.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('elite_imperial_stormtrooper_90', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_defensive_quest_officer.py b/scripts/mobiles/generic/faction/imperial/imp_defensive_quest_officer.py new file mode 100644 index 00000000..02c3d8a9 --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_defensive_quest_officer.py @@ -0,0 +1,43 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('fbase_imperial_colonel_extreme') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(False) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE) + mobileTemplate.setNoAI(True) + + templates = Vector() + templates.add('object/mobile/shared_dressed_imperial_colonel_m.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_defensive_quest_officer', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_at_at.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_at.py new file mode 100644 index 00000000..99e1234c --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_at.py @@ -0,0 +1,42 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('at_at') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.BOSS) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + + templates = Vector() + templates.add('object/mobile/shared_atat.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_invasion_at_at', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_at_st.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_st.py new file mode 100644 index 00000000..b6e60b36 --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_st.py @@ -0,0 +1,44 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('eow_gcw_city_at_st_2') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) + + templates = Vector() + templates.add('object/mobile/shared_atst.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() # object/weapon/ranged/turret/shared_turret_heat.iff object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff + weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 2.0, 55, 'energy') + #weapontemplate = WeaponTemplate('object/weapon/ranged/rifle/shared_rifle_t21.iff', WeaponType.RIFLE, 1.0, 24, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('gcw_atst_attack_tower') #gcw_atst_attack_tower #rangedShot + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_invasion_at_st', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_captain.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_captain.py new file mode 100644 index 00000000..5fa32db5 --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_captain.py @@ -0,0 +1,44 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('gcw_city_imperial_captain') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.NORMAL) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(False) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE) + mobileTemplate.setNoAI(True) + + templates = Vector() + templates.add('object/mobile/shared_dressed_imperial_captain_m.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_invasion_captain', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_demoralized_soldier.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_demoralized_soldier.py new file mode 100644 index 00000000..62962707 --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_demoralized_soldier.py @@ -0,0 +1,45 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCustomName('A demoralized imperial soldier') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_dressed_stormtrooper_black_white.iff') + templates.add('object/mobile/shared_dressed_stormtrooper_white_black.iff') + templates.add('object/mobile/shared_dressed_stormtrooper_white_white.iff') + templates.add('object/mobile/shared_dark_trooper.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_invasion_demoralized_soldier', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_disabled_atst.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_disabled_atst.py new file mode 100644 index 00000000..9b9040b8 --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_disabled_atst.py @@ -0,0 +1,45 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCustomName('A disabled AT-ST') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_atst.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() # object/weapon/ranged/turret/shared_turret_heat.iff object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff + weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 2.0, 55, 'energy') + #weapontemplate = WeaponTemplate('object/weapon/ranged/rifle/shared_rifle_t21.iff', WeaponType.RIFLE, 1.0, 24, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('gcw_atst_attack_tower') #gcw_atst_attack_tower #rangedShot + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_invasion_disabled_atst', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_general.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_general.py new file mode 100644 index 00000000..7b19a8cc --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_general.py @@ -0,0 +1,45 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('gcw_city_imperial_general') + mobileTemplate.setLevel(110) + mobileTemplate.setHealth(1000000) + mobileTemplate.setDifficulty(Difficulty.BOSS) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.INVULNERABLE) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_dressed_imperial_general_m.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_invasion_general', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_soldier_cl90.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_soldier_cl90.py new file mode 100644 index 00000000..6ad094e2 --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_soldier_cl90.py @@ -0,0 +1,44 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('crackdown_stormtrooper_hard') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + + templates = Vector() + templates.add('object/mobile/shared_dressed_stormtrooper_black_white.iff') + templates.add('object/mobile/shared_dressed_stormtrooper_white_black.iff') + templates.add('object/mobile/shared_dressed_stormtrooper_white_white.iff') + templates.add('object/mobile/shared_dark_trooper.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_invasion_soldier_cl90', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/imperial/imp_offensive_invasion_general.py b/scripts/mobiles/generic/faction/imperial/imp_offensive_invasion_general.py new file mode 100644 index 00000000..b13bdac1 --- /dev/null +++ b/scripts/mobiles/generic/faction/imperial/imp_offensive_invasion_general.py @@ -0,0 +1,45 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('gcw_city_offensive_imperial_general') + mobileTemplate.setLevel(110) + mobileTemplate.setHealth(1000000) + mobileTemplate.setDifficulty(Difficulty.BOSS) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("imperial") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("imperial") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_dressed_imperial_general_m.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('imp_offensive_invasion_general', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/gcw_city_rebel_soldier.py b/scripts/mobiles/generic/faction/rebel/gcw_city_rebel_soldier.py new file mode 100644 index 00000000..c6c75763 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/gcw_city_rebel_soldier.py @@ -0,0 +1,45 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('cheerleader_rebel_commando_hard') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(True) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + + templates = Vector() + templates.add('object/mobile/shared_dressed_rebel_commando_human_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_human_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_moncal_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_rodian_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_twilek_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_zabrak_female_01.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('gcw_city_rebel_soldier', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_defensive_quest_officer.py b/scripts/mobiles/generic/faction/rebel/rebel_defensive_quest_officer.py new file mode 100644 index 00000000..4570cb07 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_defensive_quest_officer.py @@ -0,0 +1,46 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('crackdown_rebel_colonel') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE) + mobileTemplate.setNoAI(True) + + templates = Vector() + templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_human_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_human_male_02.iff') + templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_moncal_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_rodian_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_rodian_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_zabrak_male_01.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_defensive_quest_officer', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_invasion_at_xt.py b/scripts/mobiles/generic/faction/rebel/rebel_invasion_at_xt.py new file mode 100644 index 00000000..64c7258d --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_invasion_at_xt.py @@ -0,0 +1,43 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('eow_gcw_city_at_xt_2') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) + + templates = Vector() + templates.add('object/mobile/shared_atxt.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('gcw_atst_attack_tower') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_invasion_at_xt', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_invasion_captain.py b/scripts/mobiles/generic/faction/rebel/rebel_invasion_captain.py new file mode 100644 index 00000000..9ef28ca6 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_invasion_captain.py @@ -0,0 +1,46 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('gcw_city_rebel_captain') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE) + mobileTemplate.setNoAI(True) + + templates = Vector() + templates.add('object/mobile/shared_dressed_rebel_army_captain_bothan_male.iff') + templates.add('object/mobile/shared_dressed_rebel_army_captain_human_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_army_captain_moncal_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_army_captain_trandoshan_female.iff') + templates.add('object/mobile/shared_dressed_rebel_army_captain_twk_male.iff') + templates.add('object/mobile/shared_dressed_rebel_army_captain_zabrak_female.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_invasion_captain', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_invasion_demoralized_soldier.py b/scripts/mobiles/generic/faction/rebel/rebel_invasion_demoralized_soldier.py new file mode 100644 index 00000000..8af3c215 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_invasion_demoralized_soldier.py @@ -0,0 +1,46 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('A demoralized rebel soldier') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(True) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_dressed_rebel_commando_human_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_human_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_moncal_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_rodian_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_twilek_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_zabrak_female_01.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_invasion_demoralized_soldier', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_invasion_disabled_atxt.py b/scripts/mobiles/generic/faction/rebel/rebel_invasion_disabled_atxt.py new file mode 100644 index 00000000..bbc7b026 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_invasion_disabled_atxt.py @@ -0,0 +1,44 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCustomName('A disabled AT-XT') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_atxt.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('gcw_atst_attack_tower') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_invasion_disabled_atxt', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_invasion_general.py b/scripts/mobiles/generic/faction/rebel/rebel_invasion_general.py new file mode 100644 index 00000000..db7458e8 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_invasion_general.py @@ -0,0 +1,48 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('gcw_city_rebel_general') + mobileTemplate.setLevel(110) + mobileTemplate.setHealth(1000000) + mobileTemplate.setDifficulty(Difficulty.BOSS) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.INVULNERABLE) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_dressed_rebel_general_human_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_human_female_02.iff') + templates.add('object/mobile/shared_dressed_rebel_general_moncal_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_old_twilek_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_rieekan_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_rodian_female_01.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_invasion_general', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_invasion_hailfire_droid.py b/scripts/mobiles/generic/faction/rebel/rebel_invasion_hailfire_droid.py new file mode 100644 index 00000000..b6e1d362 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_invasion_hailfire_droid.py @@ -0,0 +1,42 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('rebel_battle_droid') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.BOSS) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setScale(1) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + + templates = Vector() + templates.add('object/mobile/shared_hailfire_droid.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/droid/shared_droid_rocket_launcher.iff', WeaponType.RIFLE, 1.0, 55, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('gcw_rocket_launch') #fireRocketLauncher #gcw_atst_attack_tower + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_invasion_hailfire_droid', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_offensive_invasion_general.py b/scripts/mobiles/generic/faction/rebel/rebel_offensive_invasion_general.py new file mode 100644 index 00000000..c627f8c8 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/rebel_offensive_invasion_general.py @@ -0,0 +1,48 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('gcw_city_offensive_rebel_general') + mobileTemplate.setLevel(110) + mobileTemplate.setHealth(1000000) + mobileTemplate.setDifficulty(Difficulty.BOSS) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(False) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE) + mobileTemplate.setAIEnabled(False) + + templates = Vector() + templates.add('object/mobile/shared_dressed_rebel_general_human_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_human_female_02.iff') + templates.add('object/mobile/shared_dressed_rebel_general_moncal_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_old_twilek_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_rieekan_01.iff') + templates.add('object/mobile/shared_dressed_rebel_general_rodian_female_01.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('rebel_offensive_invasion_general', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/tatooine/mos_eisley_police_officer.py b/scripts/mobiles/tatooine/mos_eisley_police_officer.py index 2e7a335f..99bec986 100644 --- a/scripts/mobiles/tatooine/mos_eisley_police_officer.py +++ b/scripts/mobiles/tatooine/mos_eisley_police_officer.py @@ -19,6 +19,7 @@ def addTemplate(core): mobileTemplate.setAssistRange(0) mobileTemplate.setStalker(True) mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) + mobileTemplate.setRespawnTime(5) templates = Vector() templates.add('object/mobile/shared_dressed_eisley_officer_aqualish_female_01.iff') diff --git a/scripts/mobiles/tatooine/mos_eisley_police_sergeant.py b/scripts/mobiles/tatooine/mos_eisley_police_sergeant.py index ad35c65e..f92baa28 100644 --- a/scripts/mobiles/tatooine/mos_eisley_police_sergeant.py +++ b/scripts/mobiles/tatooine/mos_eisley_police_sergeant.py @@ -19,6 +19,7 @@ def addTemplate(core): mobileTemplate.setAssistRange(0) mobileTemplate.setStalker(True) mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) + mobileTemplate.setRespawnTime(5) templates = Vector() templates.add('object/mobile/shared_dressed_eisley_officer_bothan_female_01.iff') diff --git a/scripts/object/installation/turret/gcw/adv_turret_block_med_heat.py b/scripts/object/installation/turret/gcw/adv_turret_block_med_heat.py index ccad8904..04e68ef9 100644 --- a/scripts/object/installation/turret/gcw/adv_turret_block_med_heat.py +++ b/scripts/object/installation/turret/gcw/adv_turret_block_med_heat.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.useTurret(owner, target); return \ No newline at end of file diff --git a/scripts/object/installation/turret/gcw/adv_turret_dish_large_heat.py b/scripts/object/installation/turret/gcw/adv_turret_dish_large_heat.py index ccad8904..04e68ef9 100644 --- a/scripts/object/installation/turret/gcw/adv_turret_dish_large_heat.py +++ b/scripts/object/installation/turret/gcw/adv_turret_dish_large_heat.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.useTurret(owner, target); return \ No newline at end of file diff --git a/scripts/object/installation/turret/gcw/adv_turret_dish_sm_heat.py b/scripts/object/installation/turret/gcw/adv_turret_dish_sm_heat.py index ccad8904..04e68ef9 100644 --- a/scripts/object/installation/turret/gcw/adv_turret_dish_sm_heat.py +++ b/scripts/object/installation/turret/gcw/adv_turret_dish_sm_heat.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.useTurret(owner, target); return \ No newline at end of file diff --git a/scripts/object/tangible/destructible/gcw_city_construction_beacon.py b/scripts/object/tangible/destructible/gcw_city_construction_beacon.py index ccad8904..52398bbc 100644 --- a/scripts/object/tangible/destructible/gcw_city_construction_beacon.py +++ b/scripts/object/tangible/destructible/gcw_city_construction_beacon.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.usePylon(owner, target); return \ No newline at end of file diff --git a/scripts/object/tangible/destructible/gcw_imperial_barricade.py b/scripts/object/tangible/destructible/gcw_imperial_barricade.py index ccad8904..3fce58db 100644 --- a/scripts/object/tangible/destructible/gcw_imperial_barricade.py +++ b/scripts/object/tangible/destructible/gcw_imperial_barricade.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.useBarricade(owner, target); return \ No newline at end of file diff --git a/scripts/object/tangible/destructible/gcw_imperial_tower.py b/scripts/object/tangible/destructible/gcw_imperial_tower.py index ccad8904..287f3df3 100644 --- a/scripts/object/tangible/destructible/gcw_imperial_tower.py +++ b/scripts/object/tangible/destructible/gcw_imperial_tower.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.useTower(owner, target); return \ No newline at end of file diff --git a/scripts/object/tangible/destructible/gcw_rebel_barricade.py b/scripts/object/tangible/destructible/gcw_rebel_barricade.py index ccad8904..3fce58db 100644 --- a/scripts/object/tangible/destructible/gcw_rebel_barricade.py +++ b/scripts/object/tangible/destructible/gcw_rebel_barricade.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.useBarricade(owner, target); return \ No newline at end of file diff --git a/scripts/object/tangible/destructible/gcw_rebel_tower.py b/scripts/object/tangible/destructible/gcw_rebel_tower.py index ccad8904..287f3df3 100644 --- a/scripts/object/tangible/destructible/gcw_rebel_tower.py +++ b/scripts/object/tangible/destructible/gcw_rebel_tower.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.useTower(owner, target); return \ No newline at end of file diff --git a/scripts/object/tangible/gcw/pvp_rank_rewards/imperial_battle_banner.py b/scripts/object/tangible/gcw/pvp_rank_rewards/imperial_battle_banner.py index ccad8904..0a4b00e0 100644 --- a/scripts/object/tangible/gcw/pvp_rank_rewards/imperial_battle_banner.py +++ b/scripts/object/tangible/gcw/pvp_rank_rewards/imperial_battle_banner.py @@ -1,4 +1,5 @@ import sys def setup(core, object): + object.setAttachment('radial_filename', 'item/gcwbanner') return \ No newline at end of file diff --git a/scripts/object/tangible/gcw/pvp_rank_rewards/rebel_battle_banner.py b/scripts/object/tangible/gcw/pvp_rank_rewards/rebel_battle_banner.py index ccad8904..0a4b00e0 100644 --- a/scripts/object/tangible/gcw/pvp_rank_rewards/rebel_battle_banner.py +++ b/scripts/object/tangible/gcw/pvp_rank_rewards/rebel_battle_banner.py @@ -1,4 +1,5 @@ import sys def setup(core, object): + object.setAttachment('radial_filename', 'item/gcwbanner') return \ No newline at end of file diff --git a/scripts/object/tangible/npe/npe_uniform_box.py b/scripts/object/tangible/npe/npe_uniform_box.py index 959298b9..e14bbaf7 100644 --- a/scripts/object/tangible/npe/npe_uniform_box.py +++ b/scripts/object/tangible/npe/npe_uniform_box.py @@ -15,89 +15,242 @@ def use(core, actor, object): items.add(robe) elif profession =='entertainer_1a': - boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s15.iff', actor.getPlanet(), 'item_entertainer_boots_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s13.iff', actor.getPlanet(), 'item_entertainer_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s04.iff', actor.getPlanet(), 'item_entertainer_shirt_02_01') - hat = core.objectService.createObject('object/tangible/wearables/hat/shared_hat_s02.iff', actor.getPlanet(), 'item_entertainer_hat_02_01') - items.add(boots) - items.add(pants) - items.add(shirt) - items.add(hat) + if "ithorian" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_gloves_s02.iff', actor.getPlanet(), 'item_entertainer_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_entertainer_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_entertainer_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_entertainer_vest_02_01') + items.add(gloves) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_entertainer_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_entertainer_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_entertainer_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_entertainer_hat_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s15.iff', actor.getPlanet(), 'item_entertainer_boots_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s13.iff', actor.getPlanet(), 'item_entertainer_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s04.iff', actor.getPlanet(), 'item_entertainer_shirt_02_01') + hat = core.objectService.createObject('object/tangible/wearables/hat/shared_hat_s02.iff', actor.getPlanet(), 'item_entertainer_hat_02_01') + items.add(boots) + items.add(pants) + items.add(shirt) + items.add(hat) elif profession =='officer_1a': - boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s22.iff', actor.getPlanet(), 'item_officer_boots_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s15.iff', actor.getPlanet(), 'item_officer_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s34.iff', actor.getPlanet(), 'item_officer_shirt_02_01') - belt = core.objectService.createObject('object/tangible/wearables/belt/shared_belt_s11.iff', actor.getPlanet(), 'item_officer_belt_02_01') - items.add(boots) - items.add(pants) - items.add(shirt) - items.add(belt) + if "ithorian" in actor.getTemplate(): + belt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_belt_s02.iff', actor.getPlanet(), 'item_officer_belt_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_officer_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_officer_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_officer_vest_02_01') + items.add(belt) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_officer_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_officer_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_officer_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_officer_hood_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s22.iff', actor.getPlanet(), 'item_officer_boots_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s15.iff', actor.getPlanet(), 'item_officer_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s34.iff', actor.getPlanet(), 'item_officer_shirt_02_01') + belt = core.objectService.createObject('object/tangible/wearables/belt/shared_belt_s11.iff', actor.getPlanet(), 'item_officer_belt_02_01') + items.add(boots) + items.add(pants) + items.add(shirt) + items.add(belt) elif profession =='bounty_hunter_1a': - boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s12.iff', actor.getPlanet(), 'item_bounty_hunter_boots_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s08.iff', actor.getPlanet(), 'item_bounty_hunter_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s42.iff', actor.getPlanet(), 'item_bounty_hunter_shirt_02_01') - vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s09.iff', actor.getPlanet(), 'item_bounty_hunter_vest_02_01') - items.add(boots) - items.add(pants) - items.add(shirt) - items.add(vest) + if "ithorian" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_gloves_s02.iff', actor.getPlanet(), 'item_bounty_hunter_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_bounty_hunter_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_bounty_hunter_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_bounty_hunter_vest_02_01') + items.add(gloves) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_bounty_hunter_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_bounty_hunter_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_bounty_hunter_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_bounty_hunter_hood_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s12.iff', actor.getPlanet(), 'item_bounty_hunter_boots_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s08.iff', actor.getPlanet(), 'item_bounty_hunter_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s42.iff', actor.getPlanet(), 'item_bounty_hunter_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s09.iff', actor.getPlanet(), 'item_bounty_hunter_vest_02_01') + items.add(boots) + items.add(pants) + items.add(shirt) + items.add(vest) elif profession =='smuggler_1a': - boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s15.iff', actor.getPlanet(), 'item_smuggler_boots_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s05.iff', actor.getPlanet(), 'item_smuggler_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s16.iff', actor.getPlanet(), 'item_smuggler_shirt_02_01') - vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s15.iff', actor.getPlanet(), 'item_smuggler_vest_02_01') - items.add(boots) - items.add(pants) - items.add(shirt) - items.add(vest) - + if "ithorian" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_gloves_s02.iff', actor.getPlanet(), 'item_smuggler_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_smuggler_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_smuggler_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_smuggler_vest_02_01') + items.add(gloves) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_smuggler_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_smuggler_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_smuggler_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_smuggler_hood_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s15.iff', actor.getPlanet(), 'item_smuggler_boots_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s05.iff', actor.getPlanet(), 'item_smuggler_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s16.iff', actor.getPlanet(), 'item_smuggler_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s15.iff', actor.getPlanet(), 'item_smuggler_vest_02_01') + items.add(boots) + items.add(pants) + items.add(shirt) + items.add(vest) + elif profession =='commando_1a': - boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s22.iff', actor.getPlanet(), 'item_commando_boots_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s05.iff', actor.getPlanet(), 'item_commando_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s42.iff', actor.getPlanet(), 'item_commando_shirt_02_01') - vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s04.iff', actor.getPlanet(), 'item_commando_vest_02_01') - items.add(boots) - items.add(pants) - items.add(shirt) - items.add(vest) + if "ithorian" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_gloves_s02.iff', actor.getPlanet(), 'item_commando_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_commando_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_commando_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_commando_vest_02_01') + items.add(gloves) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_commando_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_commando_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_commando_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_commando_hood_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s22.iff', actor.getPlanet(), 'item_commando_boots_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s05.iff', actor.getPlanet(), 'item_commando_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s42.iff', actor.getPlanet(), 'item_commando_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s04.iff', actor.getPlanet(), 'item_commando_vest_02_01') + items.add(boots) + items.add(pants) + items.add(shirt) + items.add(vest) elif profession =='spy_1a': - boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s12.iff', actor.getPlanet(), 'item_spy_boots_02_01') - gloves = core.objectService.createObject('object/tangible/wearables/gloves/shared_gloves_s12.iff', actor.getPlanet(), 'item_spy_gloves_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s30.iff', actor.getPlanet(), 'item_spy_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s30.iff', actor.getPlanet(), 'item_spy_shirt_02_01') - items.add(boots) - items.add(gloves) - items.add(pants) - items.add(shirt) - + if "ithorian" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_gloves_s02.iff', actor.getPlanet(), 'item_spy_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_spy_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_spy_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_spy_vest_02_01') + items.add(gloves) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_spy_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_spy_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_spy_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_spy_hood_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s12.iff', actor.getPlanet(), 'item_spy_boots_02_01') + gloves = core.objectService.createObject('object/tangible/wearables/gloves/shared_gloves_s12.iff', actor.getPlanet(), 'item_spy_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s30.iff', actor.getPlanet(), 'item_spy_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s30.iff', actor.getPlanet(), 'item_spy_shirt_02_01') + items.add(boots) + items.add(gloves) + items.add(pants) + items.add(shirt) + elif profession == 'medic_1a': - boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s22.iff', actor.getPlanet(), 'item_medic_boots_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s08.iff', actor.getPlanet(), 'item_medic_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s27.iff', actor.getPlanet(), 'item_medic_shirt_02_01') - vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s05.iff', actor.getPlanet(), 'item_medic_vest_02_01') - items.add(shoes) - items.add(pants) - items.add(shirt) - items.add(vest) + if "ithorian" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_gloves_s02.iff', actor.getPlanet(), 'item_medic_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_medic_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_medic_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_medic_vest_02_01') + items.add(gloves) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_medic_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_medic_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_medic_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_medic_hood_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + boots = core.objectService.createObject('object/tangible/wearables/boots/shared_boots_s22.iff', actor.getPlanet(), 'item_medic_boots_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s08.iff', actor.getPlanet(), 'item_medic_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s27.iff', actor.getPlanet(), 'item_medic_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/vest/shared_vest_s05.iff', actor.getPlanet(), 'item_medic_vest_02_01') + items.add(boots) + items.add(pants) + items.add(shirt) + items.add(vest) elif "trader" in profession: - shoes = core.objectService.createObject('object/tangible/wearables/shoes/shared_shoes_s01.iff', actor.getPlanet(), 'item_trader_shoes_02_01') - pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s15.iff', actor.getPlanet(), 'item_trader_pants_02_01') - shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s05.iff', actor.getPlanet(), 'item_trader_shirt_02_01') - belt = core.objectService.createObject('object/tangible/wearables/armor/zam/shared_armor_zam_wesell_belt.iff', actor.getPlanet()) - items.add(shoes) - items.add(pants) - items.add(shirt) - items.add(belt) - + if "ithorian" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_gloves_s02.iff', actor.getPlanet(), 'item_trader_gloves_02_01') + pants = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_pants_s02.iff', actor.getPlanet(), 'item_trader_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_shirt_s02.iff', actor.getPlanet(), 'item_trader_shirt_02_01') + vest = core.objectService.createObject('object/tangible/wearables/ithorian/shared_ith_vest_s02.iff', actor.getPlanet(), 'item_trader_vest_02_01') + items.add(gloves) + items.add(pants) + items.add(shirt) + items.add(vest) + elif "wookie" in actor.getTemplate(): + gloves = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_gloves_s02.iff', actor.getPlanet(), 'item_trader_gloves_02_01') + skirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_skirt_s02.iff', actor.getPlanet(), 'item_trader_skirt_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_shirt_s02.iff', actor.getPlanet(), 'item_trader_shirt_02_01') + hood = core.objectService.createObject('object/tangible/wearables/wookiee/shared_wke_hood_s02.iff', actor.getPlanet(), 'item_trader_hood_02_01') + items.add(gloves) + items.add(skirt) + items.add(shirt) + items.add(hood) + elif "wookie" not in actor.getTemplate() or "ithorian" not in actor.getTemplate(): + shoes = core.objectService.createObject('object/tangible/wearables/shoes/shared_shoes_s01.iff', actor.getPlanet(), 'item_trader_shoes_02_01') + pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s15.iff', actor.getPlanet(), 'item_trader_pants_02_01') + shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s05.iff', actor.getPlanet(), 'item_trader_shirt_02_01') + belt = core.objectService.createObject('object/tangible/wearables/armor/zam/shared_armor_zam_wesell_belt.iff', actor.getPlanet(), 'item_trader_belt_02_01') + items.add(shoes) + items.add(pants) + items.add(shirt) + items.add(belt) + else: actor.sendSystemMessage('@base_player:not_correct_skill', 0) items.add(createProfessionItem(core, actor)) + print(items) core.playerService.giveItems(actor, items) core.objectService.destroyObject(object) return @@ -113,8 +266,7 @@ def createProfessionItem(core, actor): return core.objectService.createObject('object/weapon/ranged/carbine/shared_carbine_dh17_black_npe.iff', actor.getPlanet(), 'weapon_npe_commando_carbine_03_01') elif profession == 'entertainer_1a': - print("Entertainer Professionitem disabled for now") - #return core.objectService.createObject('object/tangible/dance_prob/shared_prop_sparkler_l.iff', actor.getPlanet()) + return core.objectService.createObject('object/weapon/melee/special/shared_vibroknuckler_npe.iff', actor.getPlanet(), 'weapon_knuckler_ent_roadmap_02_01') elif profession == 'force_sensitive_1a': return core.objectService.createObject('object/weapon/melee/polearm/shared_polearm_vibro_axe_npe.iff', actor.getPlanet(), 'weapon_polearm_02_03') @@ -132,10 +284,9 @@ def createProfessionItem(core, actor): return core.objectService.createObject('object/weapon/ranged/carbine/shared_carbine_dh17_black_npe.iff', actor.getPlanet(), 'weapon_npe_carbine_spy_03_01') elif "trader" in profession: - print("Trader Professionitem disabled until crafting is in") - #return core.objectService.createObject('object/tangible/crafting/station/shared_generic_generic_tool.iff', actor.getPlanet(), 'item_npe_gen_craft_tool_trader_03_01') - + return core.objectService.createObject('object/tangible/crafting/station/shared_generic_generic_tool.iff', actor.getPlanet(), 'item_npe_gen_craft_tool_trader_03_01') return - \ No newline at end of file + + diff --git a/scripts/object/tangible/terminal/terminal_gcw_imp_def.py b/scripts/object/tangible/terminal/terminal_gcw_imp_def.py index ccad8904..046f166e 100644 --- a/scripts/object/tangible/terminal/terminal_gcw_imp_def.py +++ b/scripts/object/tangible/terminal/terminal_gcw_imp_def.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.supplyTerminalSUI(owner, 0); return \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_gcw_imp_offensiv.py b/scripts/object/tangible/terminal/terminal_gcw_imp_offensiv.py index ccad8904..142710d8 100644 --- a/scripts/object/tangible/terminal/terminal_gcw_imp_offensiv.py +++ b/scripts/object/tangible/terminal/terminal_gcw_imp_offensiv.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.supplyOffensiveTerminalSUI(owner, 0); return \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_gcw_reb_def.py b/scripts/object/tangible/terminal/terminal_gcw_reb_def.py index ccad8904..046f166e 100644 --- a/scripts/object/tangible/terminal/terminal_gcw_reb_def.py +++ b/scripts/object/tangible/terminal/terminal_gcw_reb_def.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.supplyTerminalSUI(owner, 0); return \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_gcw_reb_offensiv.py b/scripts/object/tangible/terminal/terminal_gcw_reb_offensiv.py index ccad8904..142710d8 100644 --- a/scripts/object/tangible/terminal/terminal_gcw_reb_offensiv.py +++ b/scripts/object/tangible/terminal/terminal_gcw_reb_offensiv.py @@ -1,4 +1,7 @@ -import sys - def setup(core, object): + object.setAttachment('radial_filename', 'object/usable') + return + +def use(core, owner, target): + core.invasionService.supplyOffensiveTerminalSUI(owner, 0); return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/belt/item_bounty_hunter_boots_02_01.py b/scripts/object/tangible/wearables/belt/item_officer_belt_02_01.py similarity index 100% rename from scripts/object/tangible/wearables/belt/item_bounty_hunter_boots_02_01.py rename to scripts/object/tangible/wearables/belt/item_officer_belt_02_01.py diff --git a/scripts/object/tangible/wearables/belt/item_trader_belt_02_01.py b/scripts/object/tangible/wearables/belt/item_trader_belt_02_01.py new file mode 100644 index 00000000..39bb745e --- /dev/null +++ b/scripts/object/tangible/wearables/belt/item_trader_belt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_trader_belt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_trader_belt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/boots/item_commando_pants_02_01.py b/scripts/object/tangible/wearables/boots/item_commando_boots_02_01.py similarity index 100% rename from scripts/object/tangible/wearables/boots/item_commando_pants_02_01.py rename to scripts/object/tangible/wearables/boots/item_commando_boots_02_01.py diff --git a/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_gloves_02_01.py b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_gloves_02_01.py new file mode 100644 index 00000000..b35297f9 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_pants_02_01.py new file mode 100644 index 00000000..72be2264 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_pants_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_bounty_hunter_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_bounty_hunter_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_shirt_02_01.py new file mode 100644 index 00000000..077c13bc --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_bounty_hunter_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_bounty_hunter_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_vest_02_01.py new file mode 100644 index 00000000..09c0b935 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_bounty_hunter_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_bounty_hunter_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_bounty_hunter_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_commando_gloves_02_01.py b/scripts/object/tangible/wearables/ithorian/item_commando_gloves_02_01.py new file mode 100644 index 00000000..30a3f679 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_commando_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_commando_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_commando_pants_02_01.py new file mode 100644 index 00000000..5e58f989 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_commando_pants_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_commando_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_commando_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_commando_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_commando_shirt_02_01.py new file mode 100644 index 00000000..1bdd8f9f --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_commando_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_commando_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_commando_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_commando_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_commando_vest_02_01.py new file mode 100644 index 00000000..80685679 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_commando_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_commando_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_commando_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_entertainer_gloves_02_01.py b/scripts/object/tangible/wearables/ithorian/item_entertainer_gloves_02_01.py new file mode 100644 index 00000000..1d006b71 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_entertainer_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Entertainer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_entertainer_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_entertainer_pants_02_01.py new file mode 100644 index 00000000..07594377 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_entertainer_pants_02_01.py @@ -0,0 +1,11 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_entertainer_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_entertainer_pants_02_01') + #object.setCustomizationVariable('/private/index_color_1', 44); + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Entertainer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_entertainer_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_entertainer_shirt_02_01.py new file mode 100644 index 00000000..7d9fc542 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_entertainer_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_entertainer_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_entertainer_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Entertainer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_entertainer_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_entertainer_vest_02_01.py new file mode 100644 index 00000000..7a0a365e --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_entertainer_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_medic_gloves_02_01.py b/scripts/object/tangible/wearables/ithorian/item_medic_gloves_02_01.py new file mode 100644 index 00000000..79011d0c --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_medic_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_medic_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_medic_pants_02_01.py new file mode 100644 index 00000000..e9c590ea --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_medic_pants_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_medic_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_medic_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_medic_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_medic_shirt_02_01.py new file mode 100644 index 00000000..b7a24faf --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_medic_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_medic_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_medic_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_medic_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_medic_vest_02_01.py new file mode 100644 index 00000000..c889ee17 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_medic_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_medic_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_medic_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_officer_belt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_officer_belt_02_01.py new file mode 100644 index 00000000..093bcef0 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_officer_belt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_officer_belt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_officer_belt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_officer_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_officer_pants_02_01.py new file mode 100644 index 00000000..666fc886 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_officer_pants_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_officer_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_officer_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_officer_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_officer_shirt_02_01.py new file mode 100644 index 00000000..e2c47968 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_officer_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_officer_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_officer_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_officer_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_officer_vest_02_01.py new file mode 100644 index 00000000..7a0a365e --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_officer_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_smuggler_gloves_02_01.py b/scripts/object/tangible/wearables/ithorian/item_smuggler_gloves_02_01.py new file mode 100644 index 00000000..db027fb7 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_smuggler_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_smuggler_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_smuggler_pants_02_01.py new file mode 100644 index 00000000..12b3bd30 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_smuggler_pants_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_smuggler_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_smuggler_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_smuggler_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_smuggler_shirt_02_01.py new file mode 100644 index 00000000..c331d0b1 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_smuggler_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_smuggler_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_smuggler_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_smuggler_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_smuggler_vest_02_01.py new file mode 100644 index 00000000..35c0cd30 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_smuggler_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_smuggler_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_smuggler_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_spy_gloves_02_01.py b/scripts/object/tangible/wearables/ithorian/item_spy_gloves_02_01.py new file mode 100644 index 00000000..f5f06373 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_spy_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_spy_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_spy_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_spy_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_spy_pants_02_01.py new file mode 100644 index 00000000..a1021bf4 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_spy_pants_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_spy_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_spy_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_spy_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_spy_shirt_02_01.py new file mode 100644 index 00000000..8bda143e --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_spy_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_spy_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_spy_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_spy_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_spy_vest_02_01.py new file mode 100644 index 00000000..3dd5fc58 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_spy_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_trader_gloves_02_01.py b/scripts/object/tangible/wearables/ithorian/item_trader_gloves_02_01.py new file mode 100644 index 00000000..e37e33d1 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_trader_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_ithorian_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_ithorian_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_trader_pants_02_01.py b/scripts/object/tangible/wearables/ithorian/item_trader_pants_02_01.py new file mode 100644 index 00000000..20459a52 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_trader_pants_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_trader_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_trader_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_trader_shirt_02_01.py b/scripts/object/tangible/wearables/ithorian/item_trader_shirt_02_01.py new file mode 100644 index 00000000..f0e8d1ad --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_trader_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_trader_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_trader_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ithorian/item_trader_vest_02_01.py b/scripts/object/tangible/wearables/ithorian/item_trader_vest_02_01.py new file mode 100644 index 00000000..26b38431 --- /dev/null +++ b/scripts/object/tangible/wearables/ithorian/item_trader_vest_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_trader_vest_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_trader_vest_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py b/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py index e2c47968..7d9fc542 100644 --- a/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py +++ b/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py @@ -2,9 +2,9 @@ import sys def setup(core, object): object.setStfFilename('static_item_n') - object.setStfName('item_officer_shirt_02_01') + object.setStfName('item_entertainer_shirt_02_01') object.setDetailFilename('static_item_d') - object.setDetailName('item_officer_shirt_02_01') + object.setDetailName('item_entertainer_shirt_02_01') object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) - object.setStringAttribute('class_required', 'Officer') + object.setStringAttribute('class_required', 'Entertainer') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py b/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py index 7d9fc542..e2c47968 100644 --- a/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py +++ b/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py @@ -2,9 +2,9 @@ import sys def setup(core, object): object.setStfFilename('static_item_n') - object.setStfName('item_entertainer_shirt_02_01') + object.setStfName('item_officer_shirt_02_01') object.setDetailFilename('static_item_d') - object.setDetailName('item_entertainer_shirt_02_01') + object.setDetailName('item_officer_shirt_02_01') object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) - object.setStringAttribute('class_required', 'Entertainer') + object.setStringAttribute('class_required', 'Officer') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/shirt/item_trader_shirt_02_01.py b/scripts/object/tangible/wearables/shirt/item_trader_shirt_02_01.py index b7a24faf..f0e8d1ad 100644 --- a/scripts/object/tangible/wearables/shirt/item_trader_shirt_02_01.py +++ b/scripts/object/tangible/wearables/shirt/item_trader_shirt_02_01.py @@ -2,9 +2,9 @@ import sys def setup(core, object): object.setStfFilename('static_item_n') - object.setStfName('item_medic_shirt_02_01') + object.setStfName('item_trader_shirt_02_01') object.setDetailFilename('static_item_d') - object.setDetailName('item_medic_shirt_02_01') + object.setDetailName('item_trader_shirt_02_01') object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) - object.setStringAttribute('class_required', 'Medic') + object.setStringAttribute('class_required', 'Trader') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_gloves_02_01.py new file mode 100644 index 00000000..e5343452 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_hood_02_01.py b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_hood_02_01.py new file mode 100644 index 00000000..24448eda --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_hood_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_shirt_02_01.py new file mode 100644 index 00000000..077c13bc --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_bounty_hunter_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_bounty_hunter_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_skirt_02_01.py new file mode 100644 index 00000000..86969df3 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_bounty_hunter_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Bounty Hunter') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_commando_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_commando_gloves_02_01.py new file mode 100644 index 00000000..82a5c39d --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_commando_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_commando_hood_02_01.py b/scripts/object/tangible/wearables/wookiee/item_commando_hood_02_01.py new file mode 100644 index 00000000..07fbd311 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_commando_hood_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_commando_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_commando_shirt_02_01.py new file mode 100644 index 00000000..1bdd8f9f --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_commando_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_commando_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_commando_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_commando_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_commando_skirt_02_01.py new file mode 100644 index 00000000..89b0eb0b --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_commando_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Commando') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_entertainer_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_entertainer_gloves_02_01.py new file mode 100644 index 00000000..00b4d513 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_entertainer_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Entertainer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_entertainer_hat_02_01.py b/scripts/object/tangible/wearables/wookiee/item_entertainer_hat_02_01.py new file mode 100644 index 00000000..c8a61881 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_entertainer_hat_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_entertainer_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_entertainer_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Entertainer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_entertainer_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_entertainer_shirt_02_01.py new file mode 100644 index 00000000..7d9fc542 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_entertainer_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_entertainer_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_entertainer_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Entertainer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_entertainer_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_entertainer_skirt_02_01.py new file mode 100644 index 00000000..38b9abfa --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_entertainer_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Entertainer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_medic_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_medic_gloves_02_01.py new file mode 100644 index 00000000..5f54e5f2 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_medic_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_medic_hood_02_01.py b/scripts/object/tangible/wearables/wookiee/item_medic_hood_02_01.py new file mode 100644 index 00000000..84271561 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_medic_hood_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_medic_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_medic_shirt_02_01.py new file mode 100644 index 00000000..b7a24faf --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_medic_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_medic_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_medic_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_medic_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_medic_skirt_02_01.py new file mode 100644 index 00000000..35a2dbc2 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_medic_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Medic') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_officer_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_officer_gloves_02_01.py new file mode 100644 index 00000000..1832bd57 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_officer_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_officer_hood_02_01.py b/scripts/object/tangible/wearables/wookiee/item_officer_hood_02_01.py new file mode 100644 index 00000000..b03c7db3 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_officer_hood_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_officer_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_officer_shirt_02_01.py new file mode 100644 index 00000000..e2c47968 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_officer_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_officer_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_officer_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_officer_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_officer_skirt_02_01.py new file mode 100644 index 00000000..fbde2322 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_officer_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Officer') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_smuggler_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_smuggler_gloves_02_01.py new file mode 100644 index 00000000..585bdad8 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_smuggler_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_smuggler_hood_02_01.py b/scripts/object/tangible/wearables/wookiee/item_smuggler_hood_02_01.py new file mode 100644 index 00000000..02910436 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_smuggler_hood_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_smuggler_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_smuggler_shirt_02_01.py new file mode 100644 index 00000000..c331d0b1 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_smuggler_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_smuggler_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_smuggler_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_smuggler_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_smuggler_skirt_02_01.py new file mode 100644 index 00000000..9d5e83db --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_smuggler_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Smuggler') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_spy_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_spy_gloves_02_01.py new file mode 100644 index 00000000..f5f06373 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_spy_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_spy_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_spy_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_spy_hood_02_01.py b/scripts/object/tangible/wearables/wookiee/item_spy_hood_02_01.py new file mode 100644 index 00000000..c9a28b5b --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_spy_hood_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_spy_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_spy_shirt_02_01.py new file mode 100644 index 00000000..8bda143e --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_spy_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_spy_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_spy_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_spy_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_spy_skirt_02_01.py new file mode 100644 index 00000000..81d9cf2c --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_spy_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Spy') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_trader_gloves_02_01.py b/scripts/object/tangible/wearables/wookiee/item_trader_gloves_02_01.py new file mode 100644 index 00000000..7fe65ccf --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_trader_gloves_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_gloves_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_gloves_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_trader_hood_02_01.py b/scripts/object/tangible/wearables/wookiee/item_trader_hood_02_01.py new file mode 100644 index 00000000..f22f08e4 --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_trader_hood_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_hat_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_hat_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_trader_shirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_trader_shirt_02_01.py new file mode 100644 index 00000000..f0e8d1ad --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_trader_shirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_trader_shirt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_trader_shirt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/wookiee/item_trader_skirt_02_01.py b/scripts/object/tangible/wearables/wookiee/item_trader_skirt_02_01.py new file mode 100644 index 00000000..5102d8af --- /dev/null +++ b/scripts/object/tangible/wearables/wookiee/item_trader_skirt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_wookiee_pants_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_wookiee_pants_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/weapon/melee/special/weapon_knuckler_ent_roadmap_02_01.py b/scripts/object/weapon/melee/special/weapon_knuckler_ent_roadmap_02_01.py new file mode 100644 index 00000000..463da023 --- /dev/null +++ b/scripts/object/weapon/melee/special/weapon_knuckler_ent_roadmap_02_01.py @@ -0,0 +1,18 @@ +import sys +from resources.datatables import WeaponType + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('weapon_knuckler_ent_roadmap_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('weapon_knuckler_ent_roadmap_02_01') + object.setStringAttribute('class_required', 'Entertainer') + object.setIntAttribute('required_combat_level', 1) + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:strength_modified', 5) + object.setAttackSpeed(1); + object.setMaxRange(5); + object.setDamageType('kinetic'); + object.setMinDamage(25); + object.setMaxDamage(45); + object.setWeaponType(WeaponType.UNARMED); + return \ No newline at end of file diff --git a/scripts/object/weapon/melee/sword/weapon_pistol_02_02.py b/scripts/object/weapon/melee/sword/weapon_pistol_02_02.py new file mode 100644 index 00000000..055d033d --- /dev/null +++ b/scripts/object/weapon/melee/sword/weapon_pistol_02_02.py @@ -0,0 +1,15 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('weapon_pistol_02_02') + object.setDetailFilename('static_item_d') + object.setDetailName('weapon_pistol_02_02') + object.setIntAttribute('required_combat_level', 1) + object.setFloatAttribute('cat_wpn_damage.wpn_attack_speed', 0.4) + object.setStringAttribute('cat_wpn_damage.wpn_damage_type', 'Energy') + object.setStringAttribute('cat_wpn_damage.damage', '10-26') + object.setStringAttribute('cat_wpn_damage.wpn_range', '0-35m') + object.setStringAttribute('cat_wpn_damage.wpn_category', 'Pistol') + object.setIntAttribute('cat_wpn_damage.dps', object.getDamagePerSecond()) + return \ No newline at end of file diff --git a/scripts/radial/item/gcwbanner.py b/scripts/radial/item/gcwbanner.py new file mode 100644 index 00000000..abcee8c7 --- /dev/null +++ b/scripts/radial/item/gcwbanner.py @@ -0,0 +1,49 @@ +from resources.common import RadialOptions +import sys + +def createRadial(core, owner, target, radials): + radials.add(RadialOptions(0, 21, 1, '')) + radials.add(RadialOptions(0, 7, 1, '')) + radials.add(RadialOptions(0, 15, 1, '')) + return + +def handleSelection(core, owner, target, option): + if option == 21 and target: + handleBanner(core, owner, target, option) + if option == 15 and target: + core.objectService.destroyObject(target) + return + +def handleBanner(core, owner, bannerinventoryobject, option): + + # check if faction alignment matches + if len(owner.getFaction()) == 0: + owner.sendSystemMessage('You are not aligned appropriately to use this banner' , 0) + return + if bannerinventoryobject.getTemplate().find(owner.getFaction()) == -1: + owner.sendSystemMessage('You are not aligned appropriately to use this banner' , 0) + return + + # check if banner object is not already spawned + #if bannerinventoryobject.getAttachment('BannerSpawned'): + #owner.sendSystemMessage('Banner already spawned' , 0) + #return + + # spawn banner object + stcSvc = core.staticService + banner = stcSvc.spawnObject(bannerinventoryobject.getTemplate(), owner.getPlanet().getName(), long(0), owner.getWorldPosition().x + 1, owner.getWorldPosition().y, owner.getWorldPosition().z, owner.getOrientation().w, owner.getOrientation().x, owner.getOrientation().y, owner.getOrientation().z) + if len(bannerinventoryobject.getStfFilename())>0: + banner.setStfFilename(bannerinventoryobject.getStfFilename()) + if len(bannerinventoryobject.getStfName())>0: + banner.setStfName(bannerinventoryobject.getStfName()) + if len(bannerinventoryobject.getDetailFilename())>0: + banner.setDetailFilename(bannerinventoryobject.getDetailFilename()) + if len(bannerinventoryobject.getDetailName())>0: + #banner.setDetailDescription(bannerinventoryobject.getBaseline(6).get("detailedDescription").getString()) + banner.setDetailName(bannerinventoryobject.getDetailName()) + bannerinventoryobject.setAttachment('BannerSpawned', True) + + # start buffing process + core.buffService.initiateBannerBuffProcess(owner, banner) + + return \ No newline at end of file diff --git a/scripts/radial/terminal/city_maintenance_terminal.py b/scripts/radial/terminal/city_maintenance_terminal.py index 50259cfa..b16bb4be 100644 --- a/scripts/radial/terminal/city_maintenance_terminal.py +++ b/scripts/radial/terminal/city_maintenance_terminal.py @@ -34,7 +34,7 @@ def createRadial(core, owner, target, radials): if owner.getPlayerObject().getCitizenship() != 3 and core.playerCityService.getPlayerCity(owner) == city: radials.add(RadialOptions(2, 230, 0, '@city/city:revoke_citizenship')) - if owner.getClient().isGM(): + if core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()) is not None: radials.add(RadialOptions(2, 231, 0, 'Add 10 citizens')) radials.add(RadialOptions(2, 232, 0, 'Deduct 10 citizens')) diff --git a/src/main/NGECore.java b/src/main/NGECore.java index a23d5d75..d68e1493 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -23,20 +23,15 @@ package main; import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -44,19 +39,13 @@ import java.util.concurrent.TimeUnit; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.session.IoSession; -import com.sleepycat.je.Transaction; -import com.sleepycat.persist.EntityCursor; - -import protocol.swg.chat.ChatSystemMessage; import net.engio.mbassy.bus.config.BusConfiguration; import resources.common.BountyListItem; -import resources.common.RadialOptions; import resources.common.ThreadMonitor; import resources.datatables.GalaxyStatus; import resources.objects.creature.CreatureObject; import resources.objects.guild.GuildObject; import resources.objects.resource.GalacticResource; -import resources.objects.resource.ResourceRoot; import services.AttributeService; import services.BuffService; import services.CharacterService; @@ -65,6 +54,7 @@ import services.ConversationService; import services.EntertainmentService; import services.GroupService; import services.housing.HousingService; +import services.AdminService; import services.BrowserService; import services.InstanceService; import services.LoginService; @@ -91,6 +81,7 @@ import services.command.CommandService; import services.equipment.EquipmentService; import services.gcw.FactionService; import services.gcw.GCWService; +import services.gcw.InvasionService; import services.GuildService; import services.LoginService; import services.map.MapService; @@ -103,6 +94,7 @@ import services.pet.MountService; import services.pet.PetService; import services.playercities.PlayerCity; import services.playercities.PlayerCityService; +import services.quest.QuestService; import services.resources.HarvesterService; import services.resources.ResourceService; import services.retro.RetroService; @@ -142,20 +134,22 @@ import engine.servers.InteractiveJythonServer; import engine.servers.MINAServer; import engine.servers.PingServer; -@SuppressWarnings("unused") +@SuppressWarnings("unused") public class NGECore { - private static boolean logUnhandledExceptions = false; + private static boolean logUnhandledExceptions = true; public static boolean didServerCrash = false; private static NGECore instance; private Config config = null; + private Config options = null; private String motd = ""; private volatile boolean isShuttingDown = false; private long galacticTime = System.currentTimeMillis(); + private int galaxyStatus = -1; private ConcurrentHashMap clients = new ConcurrentHashMap(); @@ -198,6 +192,7 @@ public class NGECore { public SpawnService spawnService; public AIService aiService; public MissionService missionService; + public QuestService questService; public InstanceService instanceService; public SurveyService surveyService; public ResourceService resourceService; @@ -212,6 +207,8 @@ public class NGECore { public PetService petService; public BrowserService browserService; //public BattlefieldService battlefieldService; + public InvasionService invasionService; + public AdminService adminService; // Login Server public NetworkDispatch loginDispatch; @@ -269,11 +266,14 @@ public class NGECore { config = DefaultConfig.getConfig(); } - Config options = new Config(); + options = new Config(); options.setFilePath("options.cfg"); - boolean optionsConfigLoaded = options.loadConfigFile(); - - if (optionsConfigLoaded && options.getInt("CLEAN.ODB.FOLDERS") > 0 || getExcludedDevelopers().contains(System.getProperty("user.name"))){ + if (!(options.loadConfigFile())) { + System.err.println("Failed to load options.cfg!"); + options = DefaultConfig.getConfig(); + } + + if (options.getInt("CLEAN.ODB.FOLDERS") > 0){ File baseFolder = new File("./odb"); if (baseFolder.isDirectory()) { @@ -285,6 +285,8 @@ public class NGECore { } } } + + System.out.println("Cleaned ODB Folders."); } @@ -307,6 +309,13 @@ public class NGECore { } setGalaxyStatus(GalaxyStatus.Loading); + + if (options.getInt("CLEAN.CHARACTERS.TABLE") > 0) { + try { databaseConnection.preparedStatement("DELETE FROM characters").execute(); } + catch (SQLException e) {e.printStackTrace(); } + System.out.println("Cleared characters table."); + } + swgObjectODB = new ObjectDatabase("swgobjects", true, true, true, SWGObject.class); mailODB = new ObjectDatabase("mails", true, true, true, Mail.class); guildODB = new ObjectDatabase("guild", true, true, true, GuildObject.class); @@ -354,7 +363,7 @@ public class NGECore { reverseEngineeringService = new ReverseEngineeringService(this); petService = new PetService(this); - if (optionsConfigLoaded && options.getInt("LOAD.RESOURCE.SYSTEM") == 1) { + if (options.getInt("LOAD.RESOURCE.SYSTEM") == 1) { surveyService = new SurveyService(this); resourceService = new ResourceService(this); } @@ -373,6 +382,8 @@ public class NGECore { spawnService = new SpawnService(this); aiService = new AIService(this); missionService = new MissionService(this); + questService = new QuestService(this); + invasionService = new InvasionService(this); // Ping Server @@ -419,6 +430,7 @@ public class NGECore { zoneDispatch.addService(buffService); zoneDispatch.addService(entertainmentService); zoneDispatch.addService(missionService); + zoneDispatch.addService(questService); zoneDispatch.addService(bazaarService); zoneDispatch.addService(lootService); zoneDispatch.addService(mountService); @@ -427,8 +439,9 @@ public class NGECore { zoneDispatch.addService(staticService); zoneDispatch.addService(reverseEngineeringService); zoneDispatch.addService(petService); + zoneDispatch.addService(invasionService); - if (optionsConfigLoaded && options.getInt("LOAD.RESOURCE.SYSTEM") == 1) { + if (options.getInt("LOAD.RESOURCE.SYSTEM") == 1) { zoneDispatch.addService(surveyService); zoneDispatch.addService(resourceService); } @@ -458,14 +471,18 @@ public class NGECore { terrainService.addPlanet(12, "kashyyyk_main", "terrain/kashyyyk_main.trn", true); //Dungeon Terrains // TODO: Fix BufferUnderFlow Errors on loaded of dungeon instances. - terrainService.addPlanet(13, "kashyyyk_dead_forest", "terrain/kashyyyk_dead_forest.trn", true); - terrainService.addPlanet(14, "kashyyyk_hunting", "terrain/kashyyyk_hunting.trn", true); - terrainService.addPlanet(15, "kashyyyk_north_dungeons", "terrain/kashyyyk_north_dungeons.trn", true); - terrainService.addPlanet(16, "kashyyyk_rryatt_trail", "terrain/kashyyyk_rryatt_trail.trn", true); - terrainService.addPlanet(17, "kashyyyk_south_dungeons", "terrain/kashyyyk_south_dungeons.trn", true); - terrainService.addPlanet(18, "adventure1", "terrain/adventure1.trn", true); - terrainService.addPlanet(19, "adventure2", "terrain/adventure2.trn", true); + terrainService.addPlanet(13, "kashyyyk_dead_forest", "terrain/kashyyyk_dead_forest.trn", false); + terrainService.addPlanet(14, "kashyyyk_hunting", "terrain/kashyyyk_hunting.trn", false); + terrainService.addPlanet(15, "kashyyyk_north_dungeons", "terrain/kashyyyk_north_dungeons.trn", false); + terrainService.addPlanet(16, "kashyyyk_rryatt_trail", "terrain/kashyyyk_rryatt_trail.trn", false); + terrainService.addPlanet(17, "kashyyyk_south_dungeons", "terrain/kashyyyk_south_dungeons.trn", false); + terrainService.addPlanet(18, "adventure1", "terrain/adventure1.trn", false); + terrainService.addPlanet(19, "adventure2", "terrain/adventure2.trn", false); + // Tutorial Terrains terrainService.addPlanet(20, "dungeon1", "terrain/dungeon1.trn", true); + terrainService.addPlanet(21, "tutorial", "terrain/tutorial.trn", false); // 21B droid scene + //terrainService.addPlanet(22, "space_npe_falcon_3", "terrain/space_npe_falcon_3.trn", false); + //Space Zones // NOTE: Commented out for now until space is implemented. No need to be loaded into memory when space is not implemented. /*terrainService.addPlanet(21, "space_corellia", "terrain/space_corellia.trn", true); @@ -482,8 +499,8 @@ public class NGECore { terrainService.addPlanet(32, "space_naboo", "terrain/space_naboo.trn", true); terrainService.addPlanet(33, "space_naboo_2", "terrain/space_naboo_2.trn", true); terrainService.addPlanet(34, "space_nova_orion", "terrain/space_nova_orion.trn", true); - terrainService.addPlanet(35, "space_npe_falcon", "terrain/space_npe_falcon.trn", true); // TODO: New Player Tutorial - terrainService.addPlanet(36, "space_npe_falcon_2", "terrain/space_npe_falcon_2.trn", true); // TODO: New Player Tutorial + terrainService.addPlanet(35, "space_npe_falcon", "terrain/space_npe_falcon.trn", true); // Only space_npe_falce_3 is used + terrainService.addPlanet(36, "space_npe_falcon_2", "terrain/space_npe_falcon_2.trn", true); // Only space_npe_falce_3 is used terrainService.addPlanet(37, "space_ord_mantell", "terrain/space_ord_mantell.trn", true); terrainService.addPlanet(38, "space_ord_mantell_2", "terrain/space_ord_mantell_2.trn", true); terrainService.addPlanet(39, "space_ord_mantell_3", "terrain/space_ord_mantell_3.trn", true); @@ -493,13 +510,10 @@ public class NGECore { terrainService.addPlanet(43, "space_tatooine", "terrain/space_tatooine.trn", true); terrainService.addPlanet(44, "space_tatooine_2", "terrain/space_tatooine_2.trn", true); terrainService.addPlanet(45, "space_yavin4", "terrain/space_yavin4.trn", true);*/ - //PSWG New Content Terrains (WARNING Keep commented out unless you have the current build of kaas!) - - //terrainService.addPlanet(46, "kaas", "terrain/kaas.trn", true); - + //end terrainList - if (optionsConfigLoaded && options.getInt("LOAD.RESOURCE.SYSTEM") > 0) { + if (options.getInt("LOAD.RESOURCE.SYSTEM") > 0) { resourceService.loadResources(); } @@ -557,6 +571,7 @@ public class NGECore { browserService = new BrowserService(this); //battlefieldService = new BattlefieldService(this); + adminService = new AdminService(this); DevLogQueuer devLogQueuer = new DevLogQueuer(); @@ -644,6 +659,7 @@ public class NGECore { public void setGalaxyStatus(int statusId) { + galaxyStatus = statusId; int galaxyId = config.getInt("GALAXY_ID"); try { @@ -657,6 +673,10 @@ public class NGECore { } + public int getGalaxyStatus() { + return galaxyStatus; + } + /* * ---------- Getter methods for NGECore ---------- */ @@ -852,10 +872,14 @@ public class NGECore { public Vector getExcludedDevelopers(){ Vector excludedDevelopers = new Vector(); - excludedDevelopers.add("Charon"); + //excludedDevelopers.add("Charon"); // Feel free to add your OS user account name here to exclude yourself from loading buildouts and snapshots // without having to change options.cfg all the time return excludedDevelopers; } + + public Config getOptions() { + return options; + } } diff --git a/src/protocol/swg/UnknownAbilityPacket.java b/src/protocol/swg/GrantCommand.java similarity index 82% rename from src/protocol/swg/UnknownAbilityPacket.java rename to src/protocol/swg/GrantCommand.java index 6c8047a8..1011f162 100644 --- a/src/protocol/swg/UnknownAbilityPacket.java +++ b/src/protocol/swg/GrantCommand.java @@ -25,12 +25,12 @@ import java.nio.ByteOrder; import org.apache.mina.core.buffer.IoBuffer; -public class UnknownAbilityPacket extends SWGMessage { +public class GrantCommand extends SWGMessage { - private String ability; + private String command; - public UnknownAbilityPacket(String ability) { - this.ability = ability; + public GrantCommand(String command) { + this.command = command; } @Override @@ -40,10 +40,10 @@ public class UnknownAbilityPacket extends SWGMessage { @Override public IoBuffer serialize() { - IoBuffer buffer = IoBuffer.allocate(8 + ability.length()).order(ByteOrder.LITTLE_ENDIAN); + IoBuffer buffer = IoBuffer.allocate(8 + command.length()).order(ByteOrder.LITTLE_ENDIAN); buffer.putShort((short) 2); buffer.putInt(0xE67E3875); - buffer.put(getAsciiString(ability)); + buffer.put(getAsciiString(command)); return buffer.flip(); } diff --git a/src/protocol/swg/LoginClusterStatus.java b/src/protocol/swg/LoginClusterStatus.java index 725a8c8b..05e0a0c0 100644 --- a/src/protocol/swg/LoginClusterStatus.java +++ b/src/protocol/swg/LoginClusterStatus.java @@ -22,8 +22,13 @@ package protocol.swg; import java.nio.ByteOrder; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.TimeZone; +import main.NGECore; + import org.apache.mina.core.buffer.IoBuffer; import engine.clients.Client; @@ -50,8 +55,8 @@ public class LoginClusterStatus extends SWGMessage { } public void addServer(int galaxyID, String serverIP, int serverPort, int pingPort, int maxCharacters, int status, int recommended, int population, Client client) { IoBuffer result = IoBuffer.allocate(39 + serverIP.length()).order(ByteOrder.LITTLE_ENDIAN); - int populationStatus = 0; + result.putInt(galaxyID); result.put(getAsciiString(serverIP)); result.putShort((short)serverPort); @@ -66,11 +71,10 @@ public class LoginClusterStatus extends SWGMessage { populationStatus = 6; status = 3; } - if(status == 3 && client.isGM()) + if(status == 3 && !(NGECore.getInstance().adminService.getAccessLevelFromDB(client.getAccountId()) == null) ) // Ziggy - admins can enter Locked galaxies status = 2; result.putInt(populationStatus); // 0 = very light, 1 = light, 2 = medium , 3 = heavy, 4 = very heavy, 5 = extremely heavy, 6 = full result.putInt(maxCharacters); - //result.putInt(0xFFFF8F80); // Distance? result.putInt(timeZone.getRawOffset() / 3600000); result.putInt(status); result.put((byte)recommended); diff --git a/src/protocol/swg/ObjControllerMessage.java b/src/protocol/swg/ObjControllerMessage.java index ff025def..58da57eb 100644 --- a/src/protocol/swg/ObjControllerMessage.java +++ b/src/protocol/swg/ObjControllerMessage.java @@ -78,7 +78,9 @@ public class ObjControllerMessage extends SWGMessage { public static final int RESOURCE_WEIGHTS = 0x0207; public static final int MISSION_ACCEPT_RESPONSE = 0x00FA; public static final int MISSION_ABORT_RESPONSE = 0x0142; - + public static final int QUEST_TASK_TIMER_MESSAGE = 0x0441; + public static final int FORCE_ACTIVATE_QUEST = 0x04BE; + public ObjControllerMessage() { } diff --git a/src/protocol/swg/ResourceListForSurveyMessage.java b/src/protocol/swg/ResourceListForSurveyMessage.java index a7dd2b68..1b95f623 100644 --- a/src/protocol/swg/ResourceListForSurveyMessage.java +++ b/src/protocol/swg/ResourceListForSurveyMessage.java @@ -25,7 +25,6 @@ import java.io.UnsupportedEncodingException; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; -import java.util.Vector; import main.NGECore; diff --git a/src/protocol/swg/SUICreateTimerBar.java b/src/protocol/swg/SUICreateTimerBar.java new file mode 100644 index 00000000..456f18ab --- /dev/null +++ b/src/protocol/swg/SUICreateTimerBar.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * 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 protocol.swg; + +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; + +import org.apache.mina.core.buffer.IoBuffer; + +@SuppressWarnings("unused") +public class SUICreateTimerBar extends SWGMessage{ + + private String script; + private int windowId; + private int startCount; + private int digitCount; + private List digits = new ArrayList(); + String prompt; + + public SUICreateTimerBar(String script, int windowId, String prompt, int startCount) { + + this.script = script; + this.windowId = windowId; + this.startCount = startCount; + this.prompt = prompt; + + digitCount = 3; + if (startCount>9) + digitCount = 4; + + while (startCount > 0) { + int d = startCount / 10; + int k = startCount - d * 10; + startCount = d; + digits.add((int)(Integer.toString(k).charAt(0))); + //System.out.println("digit: "+Integer.toHexString((int)(Integer.toString(k).charAt(0)))); + } +// digits.add(0x39); +// digits.add(0x31); + } + + public void deserialize(IoBuffer data) { + + } + + public IoBuffer serialize() { + + IoBuffer result = IoBuffer.allocate(100).order(ByteOrder.LITTLE_ENDIAN); + result.setAutoExpand(true); + + result.putShort((short) 2); + result.putInt(0xD44B7259); + + result.putInt(windowId); + result.put(getAsciiString(script)); + result.putInt(5); + result.putInt(5); + result.put((byte)0); + result.putInt(3); + result.putShort((short)0); + result.putShort((short)1); + result.put((byte)9); + + result.put(getAsciiString("modifySlot")); + result.putInt(5); + result.put((byte)0); + result.putInt(3); + result.putShort((short)0); + result.putShort((short)1); + result.put((byte)0xA); + result.put(getAsciiString("modifySlot")); + result.put((byte)3); + result.putInt(1); + + result.put(getUnicodeString(prompt)); + + result.putInt(2); + + result.put(getAsciiString("comp.text")); + result.put(getAsciiString("Text")); + + result.put((byte)3); + result.putInt(1); + + result.put(getUnicodeString("quest_countdown_timer")); + + result.putInt(2); + + result.put(getAsciiString("bg.caption.lblTitle")); + result.put(getAsciiString("Text")); + + + result.put((byte)3); + result.putInt(1); + result.putInt(digitCount); + + result.putShort((short)0x30); + result.putShort((short)0x2C); + for (int i=digits.size()-1;i>=0;i--) + result.putShort((short)((int)digits.get(i))); + + result.putInt(2); + result.put(getAsciiString("this")); + result.put(getAsciiString("countdownTimerTimeValue")); + + result.putLong(0); + result.putInt(0x7F7FFFFF); + result.putInt(0x7F7FFFFF); + result.putInt(0x7F7FFFFF); + result.putInt(0); + + int size = result.position(); + result = IoBuffer.allocate(size).put(result.array(), 0, size); + + return result.flip(); + } +} diff --git a/src/protocol/swg/objectControllerObjects/DataTransform.java b/src/protocol/swg/objectControllerObjects/DataTransform.java index 3b8381e5..62b698b3 100644 --- a/src/protocol/swg/objectControllerObjects/DataTransform.java +++ b/src/protocol/swg/objectControllerObjects/DataTransform.java @@ -21,15 +21,14 @@ ******************************************************************************/ package protocol.swg.objectControllerObjects; +import java.nio.BufferUnderflowException; import java.nio.ByteOrder; - import java.lang.Math; import org.apache.mina.core.buffer.IoBuffer; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; - import protocol.swg.ObjControllerMessage; public class DataTransform extends ObjControllerObject { @@ -93,21 +92,23 @@ public class DataTransform extends ObjControllerObject { } public void deserialize(IoBuffer buffer) { - objectId = buffer.getLong(); - buffer.getInt(); - - movementStamp = buffer.getInt(); - movementIndex = buffer.getInt(); - - xOrientation = buffer.getFloat(); - yOrientation = buffer.getFloat(); - zOrientation = buffer.getFloat(); - wOrientation = buffer.getFloat(); - - xPosition = buffer.getFloat(); - yPosition = buffer.getFloat(); - zPosition = buffer.getFloat(); - speed = buffer.getFloat(); + try{ + objectId = buffer.getLong(); + buffer.getInt(); + + movementStamp = buffer.getInt(); + movementIndex = buffer.getInt(); + + xOrientation = buffer.getFloat(); + yOrientation = buffer.getFloat(); + zOrientation = buffer.getFloat(); + wOrientation = buffer.getFloat(); + + xPosition = buffer.getFloat(); + yPosition = buffer.getFloat(); + zPosition = buffer.getFloat(); + speed = buffer.getFloat(); + } catch (BufferUnderflowException ex){System.err.println("BufferUnderflowException during Datatransform deserialization");} } public IoBuffer serialize() { diff --git a/src/protocol/swg/objectControllerObjects/ForceActivateQuest.java b/src/protocol/swg/objectControllerObjects/ForceActivateQuest.java new file mode 100644 index 00000000..a4da1ae5 --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ForceActivateQuest.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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 protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; + +public class ForceActivateQuest extends ObjControllerObject { + + private long objectId; + private int questCRC; + + public ForceActivateQuest(long objectId, int questCRC) { + this.objectId = objectId; + this.questCRC = questCRC; + } + + @Override + public void deserialize(IoBuffer data) { } + + @Override + public IoBuffer serialize() { + IoBuffer result = IoBuffer.allocate(20).order(ByteOrder.LITTLE_ENDIAN); + + result.putInt(ObjControllerMessage.FORCE_ACTIVATE_QUEST); + result.putLong(objectId); + result.putInt(0); + + result.putInt(questCRC); + result.flip(); + + return result; + } + +} diff --git a/src/protocol/swg/objectControllerObjects/ObjController_0250.java b/src/protocol/swg/objectControllerObjects/ObjController_0250.java new file mode 100644 index 00000000..35a7a1e1 --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ObjController_0250.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; +import resources.datatables.HitType; + +@SuppressWarnings("unused") +public class ObjController_0250 extends ObjControllerObject{ + + private long creatureId; + + public ObjController_0250(long creatureId) { + this.creatureId = creatureId; + } + + public void deserialize(IoBuffer data) { + + } + + public IoBuffer serialize() { + + IoBuffer result = IoBuffer.allocate(100).order(ByteOrder.LITTLE_ENDIAN); + result.setAutoExpand(true); + result.putInt((int)(System.currentTimeMillis()/1000)); + int packetSize = result.position(); + result = IoBuffer.allocate(packetSize).put(result.array(), 0, packetSize); + + return result.flip(); + + } + +} diff --git a/src/protocol/swg/objectControllerObjects/QuestTaskTimerMessage.java b/src/protocol/swg/objectControllerObjects/QuestTaskTimerMessage.java new file mode 100644 index 00000000..1d4b2a8c --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/QuestTaskTimerMessage.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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 protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; + +@SuppressWarnings("unused") +public class QuestTaskTimerMessage extends ObjControllerObject { + + private long objectId; + private String questName; + + public QuestTaskTimerMessage(long objectId, String questName) { + this.objectId = objectId; + this.questName = questName; + } + + @Override + public void deserialize(IoBuffer data) { + + } + + @Override + public IoBuffer serialize() { + + IoBuffer buffer = IoBuffer.allocate(16).order(ByteOrder.LITTLE_ENDIAN); + buffer.setAutoExpand(true); + buffer.putInt(ObjControllerMessage.QUEST_TASK_TIMER_MESSAGE); + buffer.putLong(objectId); + buffer.putInt(0); + buffer.put(getAsciiString("quest/ep3_trando_hssissk_zssik_10")); + buffer.putInt(1); + buffer.put(getUnicodeString("quest/groundquests:destroy_counter")); + buffer.putInt(0); + buffer.putInt(1); + + int size = buffer.position(); + buffer = IoBuffer.allocate(size).put(buffer.array(), 0, size); + + return buffer.flip(); + } + +} diff --git a/src/resources/common/Forager.java b/src/resources/common/Forager.java index 48a26ca5..5f693253 100644 --- a/src/resources/common/Forager.java +++ b/src/resources/common/Forager.java @@ -180,7 +180,7 @@ public class Forager { } // chosenObject = 5; // To test TMs - if(forager.getClient().isGM()) // Always yield a TM for testing + if(!(NGECore.getInstance().adminService.getAccessLevelFromDB(forager.getClient().getAccountId()) == null)) // Always yield a TM for testing chosenObject = 5; //forager.sendSystemMessage("chosenObject " + chosenObject,(byte) 0); diff --git a/src/resources/common/ObjControllerOpcodes.java b/src/resources/common/ObjControllerOpcodes.java index c38a6071..b4ed90e7 100644 --- a/src/resources/common/ObjControllerOpcodes.java +++ b/src/resources/common/ObjControllerOpcodes.java @@ -55,6 +55,6 @@ public class ObjControllerOpcodes { public static final int NEXT_CRAFTING_STAGE_RESULT = 0x01BE; public static final int DRAFT_SLOTS_QUERY_RESPONSE = 0x01BF; public static final int RESOURCE_WEIGHTS = 0x0207; - + public static final int QUEST_CHANGE_ACTIVE = 0x43020000; } diff --git a/src/resources/datatables/AdminTag.java b/src/resources/datatables/AdminTag.java new file mode 100644 index 00000000..a583a653 --- /dev/null +++ b/src/resources/datatables/AdminTag.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.datatables; + +public class AdminTag { + public static final byte NONE = 0; // Default + public static final byte CSR = 1; // (CSR) + public static final byte DEVELOPER = 2; // (Developer) + public static final byte WARDEN = 3; // (Warden) + public static final byte QA = 4; // (QA) + +} diff --git a/src/resources/datatables/DisplayType.java b/src/resources/datatables/DisplayType.java index 437a0df4..8003e36c 100644 --- a/src/resources/datatables/DisplayType.java +++ b/src/resources/datatables/DisplayType.java @@ -28,7 +28,7 @@ public class DisplayType { public static byte Screen = 1; // Screen? XP gain public static byte Chat = 2; //public static byte Overhead = 3; // Flytext? Seen on ent duration - //public static byte Combat = 4; // CombatSpam? + public static byte Quest = 4; //public static byte Combat = 5; // Seen in combat flytext //public static byte Combat = 11; // Seen when blocking diff --git a/src/resources/objectives/BountyMissionObjective.java b/src/resources/objectives/BountyMissionObjective.java index 5ed1b0c0..688e1397 100644 --- a/src/resources/objectives/BountyMissionObjective.java +++ b/src/resources/objectives/BountyMissionObjective.java @@ -304,12 +304,12 @@ public class BountyMissionObjective extends MissionObjective { WaypointObject missionWp = mission.getWaypoint(); - if (missionWp == null || missionWp.getPlanetCRC() != CRC.StringtoCRC(target.getPlanet().name)) { + if (missionWp == null || missionWp.getPlanetCrc() != CRC.StringtoCRC(target.getPlanet().name)) { WaypointObject waypoint = (WaypointObject) getMissionObject().getWaypoint(); waypoint.setActive(true); waypoint.setColor(WaypointObject.ORANGE); waypoint.setName(getMissionObject().getTargetName()); - waypoint.setPlanetCRC(CRC.StringtoCRC(target.getPlanet().getName())); + waypoint.setPlanetCrc(CRC.StringtoCRC(target.getPlanet().getName())); waypoint.setStringAttribute("", ""); waypoint.setPosition(target.getWorldPosition()); mission.setWaypoint(waypoint); @@ -352,12 +352,12 @@ public class BountyMissionObjective extends MissionObjective { WaypointObject missionWp = mission.getWaypoint(); - if (missionWp == null || missionWp.getPlanetCRC() != CRC.StringtoCRC(target.getPlanet().name)) { + if (missionWp == null || missionWp.getPlanetCrc() != CRC.StringtoCRC(target.getPlanet().name)) { WaypointObject waypoint = (WaypointObject) getMissionObject().getWaypoint(); waypoint.setActive(true); waypoint.setColor(WaypointObject.ORANGE); waypoint.setName(getMissionObject().getTargetName()); - waypoint.setPlanetCRC(CRC.StringtoCRC(target.getPlanet().getName())); + waypoint.setPlanetCrc(CRC.StringtoCRC(target.getPlanet().getName())); waypoint.setStringAttribute("", ""); waypoint.setPosition(target.getWorldPosition()); mission.setWaypoint(waypoint); @@ -388,7 +388,7 @@ public class BountyMissionObjective extends MissionObjective { waypoint.setActive(true); waypoint.setColor(WaypointObject.ORANGE); waypoint.setName(getMissionObject().getTargetName()); - waypoint.setPlanetCRC(CRC.StringtoCRC(target.getPlanet().getName())); + waypoint.setPlanetCrc(CRC.StringtoCRC(target.getPlanet().getName())); waypoint.setStringAttribute("", ""); getMissionObject().setWaypoint(waypoint); diff --git a/src/resources/objectives/DeliveryMissionObjective.java b/src/resources/objectives/DeliveryMissionObjective.java index c4eef253..a4645c0f 100644 --- a/src/resources/objectives/DeliveryMissionObjective.java +++ b/src/resources/objectives/DeliveryMissionObjective.java @@ -54,7 +54,7 @@ public class DeliveryMissionObjective extends MissionObjective { if (getObjectivePhase() == 0) { WaypointObject waypoint = getMissionObject().getWaypoint(); - waypoint.setPlanetCRC(CRC.StringtoCRC(player.getPlanet().name)); + waypoint.setPlanetCrc(CRC.StringtoCRC(player.getPlanet().name)); waypoint.setPosition(parent.getStartLocation().getLocation()); waypoint.setName("@" + parent.getTitle().getStfFilename() + ":" + "m" + parent.getMissionId() + "t"); waypoint.setColor(WaypointObject.ORANGE); @@ -63,7 +63,7 @@ public class DeliveryMissionObjective extends MissionObjective { } else if (getObjectivePhase() == 1) { WaypointObject waypoint = getMissionObject().getWaypoint(); - waypoint.setPlanetCRC(CRC.StringtoCRC(player.getPlanet().name)); + waypoint.setPlanetCrc(CRC.StringtoCRC(player.getPlanet().name)); waypoint.setPosition(parent.getDestinationLocation().getLocation()); waypoint.setName("@" + parent.getTitle().getStfFilename() + ":" + "m" + parent.getMissionId() + "t"); waypoint.setColor(WaypointObject.ORANGE); @@ -103,7 +103,7 @@ public class DeliveryMissionObjective extends MissionObjective { waypoint.setName("@" + parent.getTitle().getStfFilename() + ":" + "m" + parent.getMissionId() + "t"); waypoint.setColor(WaypointObject.ORANGE); waypoint.setActive(true); - waypoint.setPlanetCRC(CRC.StringtoCRC(player.getPlanet().name)); + waypoint.setPlanetCrc(CRC.StringtoCRC(player.getPlanet().name)); getMissionObject().setTargetName("Dropoff Location"); getMissionObject().setWaypoint(waypoint); break; @@ -113,7 +113,7 @@ public class DeliveryMissionObjective extends MissionObjective { returnWp.setName("@" + parent.getTitle().getStfFilename() + ":" + "m" + parent.getMissionId() + "t"); returnWp.setColor(WaypointObject.ORANGE); returnWp.setActive(true); - returnWp.setPlanetCRC(CRC.StringtoCRC(player.getPlanet().name)); + returnWp.setPlanetCrc(CRC.StringtoCRC(player.getPlanet().name)); getMissionObject().setTargetName("Return"); getMissionObject().setWaypoint(returnWp); break; diff --git a/src/resources/objects/SWGList.java b/src/resources/objects/SWGList.java index 3b13e6cc..9a3a686b 100644 --- a/src/resources/objects/SWGList.java +++ b/src/resources/objects/SWGList.java @@ -54,6 +54,7 @@ public class SWGList implements List, Serializable { private byte viewType; private short updateType; private boolean addByte; + private boolean questMethod; protected transient Object objectMutex = new Object(); private transient SWGObject object; @@ -66,6 +67,14 @@ public class SWGList implements List, Serializable { this.object = object; } + public SWGList(SWGObject object, int viewType, int updateType, boolean addByte, boolean questMethod) { + this.viewType = (byte) viewType; + this.updateType = (short) updateType; + this.addByte = addByte; + this.object = object; + this.questMethod = questMethod; + } + public void init(SWGObject object) { objectMutex = new Object(); updateCounter = 0; @@ -85,7 +94,19 @@ public class SWGList implements List, Serializable { public boolean add(E e) { synchronized(objectMutex) { if (valid(e) && list.add(e)) { - queue(item(1, list.lastIndexOf(e), Baseline.toBytes(e), true, true)); + if (!questMethod) queue(item(1, list.lastIndexOf(e), Baseline.toBytes(e), true, true)); + else { + List buffer = new ArrayList(); + + int index = 0; + for (E element : list) { + buffer.add(item(1, index, Baseline.toBytes(element), true, true)); + index++; + } + queue(buffer); + + return true; + } return true; } @@ -441,6 +462,17 @@ public class SWGList implements List, Serializable { } private byte[] item(int type, int index, byte[] data, boolean useIndex, boolean useData) { + if (questMethod) { + int size = data.length; + + IoBuffer buffer = Delta.createBuffer(size); + buffer.put(data); + buffer.flip(); + updateCounter++; + + return buffer.array(); + } + int size = 1 + ((useIndex) ? 2 : 0) + ((useData) ? data.length : 0); IoBuffer buffer = Delta.createBuffer(size); diff --git a/src/resources/objects/building/BuildingObject.java b/src/resources/objects/building/BuildingObject.java index fa44577f..c0b27ccf 100644 --- a/src/resources/objects/building/BuildingObject.java +++ b/src/resources/objects/building/BuildingObject.java @@ -403,7 +403,7 @@ public class BuildingObject extends TangibleObject implements IPersistent, Seria } public boolean canEnter(SWGObject object) { - return (getPrivacy() == PRIVATE && (entryList.contains(object.getObjectID()) || adminList.contains(object.getObjectID()))) || !banList.contains(object.getObjectID()) || object.getClient().isGM(); + return (getPrivacy() == PRIVATE && (entryList.contains(object.getObjectID()) || adminList.contains(object.getObjectID()))) || !banList.contains(object.getObjectID()) || !(NGECore.getInstance().adminService.getAccessLevelFromDB(object.getClient().getAccountId()) == null); } public void updateCellPermissions(SWGObject obj) { diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 93c58e5e..b069864e 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -307,7 +307,7 @@ public class CreatureMessageBuilder extends TangibleMessageBuilder { SWGObject obj = NGECore.getInstance().objectService.getObject(objId); if(obj == null) { - System.err.println("Cant find obj for obj id in equip list!!!"); + System.err.println("Cant find obj for obj id in equip list!!! (Normal Message for AI wipes)"); continue; } @@ -427,7 +427,7 @@ public class CreatureMessageBuilder extends TangibleMessageBuilder { SWGObject obj = NGECore.getInstance().objectService.getObject(objId); if(obj == null) { - System.err.println("Cant find obj for obj id in equip list!!!"); + System.err.println("Cant find obj for obj id in equip list!!! (Normal Message for AI wipes)"); continue; } diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 1bbe384c..91dd3446 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -188,6 +188,8 @@ public class CreatureObject extends TangibleObject implements Serializable { private transient CreatureObject calledPet; private byte locomotion = 0; + private int GCWFatigue = 0; + private boolean isConstructing = false; public CreatureObject(long objectID, Planet planet, Point3D position, Quaternion orientation, String Template) { super(objectID, planet, position, orientation, Template); @@ -545,6 +547,9 @@ public class CreatureObject extends TangibleObject implements Serializable { if (companion != null) { companion.setFaction(faction); } + + if (this.getCalledPet()!=null) + this.getCalledPet().setFaction(faction); } public void setFactionStatus(int factionStatus) { @@ -555,6 +560,8 @@ public class CreatureObject extends TangibleObject implements Serializable { if (companion != null) { companion.setFactionStatus(factionStatus); } + if (this.getCalledPet()!=null) + this.getCalledPet().setFactionStatus(factionStatus); } public float getHeight() { @@ -1148,7 +1155,7 @@ public class CreatureObject extends TangibleObject implements Serializable { } //destination.getSession().write(messageBuilder.buildBaseline8()); //destination.getSession().write(messageBuilder.buildBaseline9()); - + if(destination != getClient()) { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this), getFaction()); destination.getSession().write(upvpm.serialize()); @@ -1887,4 +1894,34 @@ public class CreatureObject extends TangibleObject implements Serializable { public void setCalledPet(CreatureObject calledPet) { this.calledPet = calledPet; } + + public int getGCWFatigue() { + return GCWFatigue; + } + + public void setGCWFatigue(int gCWFatigue) { + GCWFatigue = gCWFatigue; + } + + public boolean isTrader(){ + if (isPlayer()){ + PlayerObject player = (PlayerObject) this.getSlottedObject("ghost"); + String profession = player.getProfession(); + if (profession.equals("trader_0a") || + profession.equals("trader_0b") || + profession.equals("trader_0c") || + profession.equals("trader_0d")){ + return true; + } + } + return false; + } + + public boolean isConstructing() { + return isConstructing; + } + + public void setConstructing(boolean isConstructing) { + this.isConstructing = isConstructing; + } } diff --git a/src/resources/objects/installation/InstallationMessageBuilder.java b/src/resources/objects/installation/InstallationMessageBuilder.java index d2b1f80c..0ec055fa 100644 --- a/src/resources/objects/installation/InstallationMessageBuilder.java +++ b/src/resources/objects/installation/InstallationMessageBuilder.java @@ -25,7 +25,6 @@ import java.nio.ByteOrder; import java.util.Map; import org.apache.mina.core.buffer.IoBuffer; - import engine.resources.objects.Builder; import resources.objects.tangible.TangibleMessageBuilder; @@ -215,6 +214,27 @@ public class InstallationMessageBuilder extends TangibleMessageBuilder{ // 0010: 4E 49 07 12 00 00 00 02 00 09 00 00 00 00 00 05 NI.............. // 0020: 00 8A D3 79 16 00 00 0F 00 ...y..... + public IoBuffer buildCustomNameDelta(InstallationObject installation, String customName) { + IoBuffer buffer = IoBuffer.allocate(10).order(ByteOrder.LITTLE_ENDIAN); + buffer.setAutoExpand(true); + int sizeP = 8; + sizeP += 2*customName.length(); + buffer.putShort((short)5); + buffer.putInt(0x12862153); + buffer.putLong(installation.getObjectID()); + buffer.putInt(0x54414E4F); + buffer.put((byte)3); + buffer.putInt(sizeP); + buffer.putShort((short)1); + buffer.putShort((short)2); + buffer.put(getUnicodeString(customName)); + int size = buffer.position(); + buffer.flip(); + tools.CharonPacketUtils.printAnalysis(IoBuffer.allocate(size).put(buffer.array(), 0, size).flip()); + return IoBuffer.allocate(size).put(buffer.array(), 0, size).flip(); + } + + @Override public void buildBaseline3(Map baselineBuilders, Map deltaBuilders) { super.buildBaseline3(deltaBuilders, deltaBuilders); diff --git a/src/resources/objects/installation/InstallationObject.java b/src/resources/objects/installation/InstallationObject.java index b9cc98d6..46cb6a24 100644 --- a/src/resources/objects/installation/InstallationObject.java +++ b/src/resources/objects/installation/InstallationObject.java @@ -24,16 +24,21 @@ package resources.objects.installation; import java.io.Serializable; import java.util.Vector; -import com.sleepycat.persist.model.Entity; +import org.apache.mina.core.buffer.IoBuffer; +import main.NGECore; +import protocol.swg.UpdatePVPStatusMessage; import engine.clients.Client; +import engine.resources.common.CRC; +import engine.resources.objects.Baseline; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; +import resources.datatables.Options; import resources.objects.ObjectMessageBuilder; +import resources.objects.creature.CreatureObject; import resources.objects.tangible.TangibleObject; -@Entity(version=0) public class InstallationObject extends TangibleObject implements Serializable { private static final long serialVersionUID = 1L; @@ -44,20 +49,94 @@ public class InstallationObject extends TangibleObject implements Serializable { messageBuilder = new InstallationMessageBuilder(this); } +// @Override +// public void sendBaselines(Client destination) { +// +// if(destination == null || destination.getSession() == null) { +// //System.out.println("NULL session"); +// return; +// } +// +// destination.getSession().write(messageBuilder.buildBaseline3(this)); +// //destination.getSession().write(messageBuilder.buildBaseline6(this)); +// +// if(destination != getClient()) { +// UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this), getFaction()); +// destination.getSession().write(upvpm.serialize()); +// } +// } + + public Baseline getBaseline3() { + Baseline baseline = super.getBaseline3(); + baseline.put("activeFlag", false); + baseline.put("PowerReserves", 0); + baseline.put("PowerCost", 0); + return baseline; + } + + @Override public void sendBaselines(Client destination) { - + if (destination != null && destination.getSession() != null) { + + // Factional peculiarities + Baseline baseLine3 = getBaseline(3); + if (destination.getParent() instanceof CreatureObject){ + if (((CreatureObject) destination.getParent()).isPlayer() && ((CreatureObject) destination.getParent()).getFaction()!=this.getFaction()){ + int optionsBitMask = getOptionsBitmask(); + if (getOption(Options.QUEST)) + optionsBitMask = optionsBitMask & ~Options.QUEST; + if (!getOption(Options.ATTACKABLE)) + optionsBitMask = optionsBitMask | Options.ATTACKABLE; + + baseLine3.set("optionsBitmask", optionsBitMask); + } + } + + //destination.getSession().write(getBaseline(3).getBaseline()); + destination.getSession().write(baseLine3.getBaseline()); + destination.getSession().write(getBaseline(6).getBaseline()); + + Client parent = ((getGrandparent() == null) ? null : getGrandparent().getClient()); + + if (parent != null && destination == parent) { + destination.getSession().write(getBaseline(8).getBaseline()); + destination.getSession().write(getBaseline(9).getBaseline()); + } + + if (destination.getParent() != this) { + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); + upvpm.setFaction(CRC.StringtoCRC(getFaction())); +// if (this.getTemplate().contains("turret")){ +// System.out.println("TURRET RESULT " + NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this)); +// } + upvpm.setStatus(NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this)); + destination.getSession().write(upvpm.serialize()); + } + } } + @Override + public void notifyClients(IoBuffer buffer, boolean notifySelf) { + notifyObservers(buffer, false); + } + + @Override + public ObjectMessageBuilder getMessageBuilder() { + synchronized(objectMutex) { + if (messageBuilder == null) { + messageBuilder = new InstallationMessageBuilder(this); + } + return messageBuilder; + } + } + + @Override public void initAfterDBLoad() { super.init(); messageBuilder = new InstallationMessageBuilder(this); defendersList = new Vector(); } - - public ObjectMessageBuilder getMessageBuilder() { - return messageBuilder; - } - + } \ No newline at end of file diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index d2f45288..8214635c 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit; import org.apache.mina.core.buffer.IoBuffer; import resources.craft.DraftSchematic; +import resources.datatables.AdminTag; import resources.datatables.Citizenship; import resources.datatables.Professions; import resources.gcw.RegionDefender; @@ -45,6 +46,8 @@ import resources.objects.resource.ResourceContainerObject; import resources.objects.waypoint.WaypointObject; import resources.quest.Quest; import engine.clients.Client; +import engine.resources.common.CRC; +import engine.resources.common.StringUtilities; import engine.resources.objects.Baseline; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -130,7 +133,7 @@ public class PlayerObject extends IntangibleObject implements Serializable { @Override public Baseline getBaseline6() { Baseline baseline = super.getBaseline6(); - baseline.put("godLevel", (byte) 0); + baseline.put("adminTag", (byte) AdminTag.NONE); baseline.put("currentRank", 0); baseline.put("rankProgress", (float) 0); baseline.put("highestRebelRank", 0); @@ -157,8 +160,8 @@ public class PlayerObject extends IntangibleObject implements Serializable { baseline.put("maxForcePower", 100); baseline.put("currentFSQuestList", new SWGList(this, 8, 4, false)); baseline.put("completedFSQuestList", new SWGList(this, 8, 5, false)); - baseline.put("questJournal", new SWGList(this, 8, 6, false)); - baseline.put("7", 0); + baseline.put("activeQuest", 0); + baseline.put("questJournal", new SWGList(this, 8, 7, false, true)); baseline.put("professionWheelPosition", ""); return baseline; } @@ -435,12 +438,12 @@ public class PlayerObject extends IntangibleObject implements Serializable { notifyClients(getBaseline(3).set("showBackpack", showBackpack), true); } - public byte getGodLevel() { - return (byte) getBaseline(6).get("godLevel"); + public byte getAdminTagValue() { + return (byte) getBaseline(6).get("adminTag"); } - public void setGodLevel(int godLevel) { - notifyClients(getBaseline(6).set("godLevel", (byte) godLevel), true); + public void setAdminTagValue(byte adminTag) { + notifyClients(getBaseline(6).set("adminTag", (byte) adminTag), true); } public int getCurrentRank() { @@ -592,6 +595,13 @@ public class PlayerObject extends IntangibleObject implements Serializable { return (SWGList) getBaseline(8).get("questJournal"); } + public int getActiveQuest() { + return (int) getBaseline(8).get("activeQuest"); + } + + public void setActiveQuest(String quest) { + getBaseline(8).set("activeQuest", CRC.StringtoCRC("quest/"+quest)); + } public String getProfessionWheelPosition() { return (String) getBaseline(8).get("professionWheelPosition"); } @@ -1019,6 +1029,7 @@ public class PlayerObject extends IntangibleObject implements Serializable { @Override public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { + switch (viewType) { case 3: case 6: diff --git a/src/resources/objects/resource/GalacticResource.java b/src/resources/objects/resource/GalacticResource.java index b3c6e3e8..33b81bed 100644 --- a/src/resources/objects/resource/GalacticResource.java +++ b/src/resources/objects/resource/GalacticResource.java @@ -441,7 +441,7 @@ public class GalacticResource extends SWGObject implements Serializable { if (lastSurveyWaypoint == null) { surveyWaypoint = (WaypointObject) NGECore.getInstance().objectService.createObject("object/waypoint/shared_world_waypoint_blue.iff", crafter.getPlanet(), smuMsg.getHighestX(), 0, smuMsg.getHighestZ()); surveyWaypoint.setName("Survey location"); - surveyWaypoint.setPlanetCRC(engine.resources.common.CRC.StringtoCRC(crafter.getPlanet().getName())); + surveyWaypoint.setPlanetCrc(engine.resources.common.CRC.StringtoCRC(crafter.getPlanet().getName())); surveyWaypoint.setPosition(new Point3D(smuMsg.getHighestX(), 0, smuMsg.getHighestZ())); player.waypointAdd(surveyWaypoint); surveyWaypoint.setPosition(new Point3D(smuMsg.getHighestX(), 0, smuMsg.getHighestZ())); @@ -450,7 +450,7 @@ public class GalacticResource extends SWGObject implements Serializable { surveyWaypoint.setStringAttribute("", ""); player.waypointAdd(surveyWaypoint); surveyWaypoint.setName("Survey location"); - surveyWaypoint.setPlanetCRC(engine.resources.common.CRC.StringtoCRC(crafter.getPlanet().getName())); + surveyWaypoint.setPlanetCrc(engine.resources.common.CRC.StringtoCRC(crafter.getPlanet().getName())); player.setLastSurveyWaypoint(surveyWaypoint); } else { surveyWaypoint = lastSurveyWaypoint; diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 328a23cb..0a5c86e0 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -24,6 +24,7 @@ package resources.objects.tangible; import java.io.ByteArrayOutputStream; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -241,6 +242,8 @@ public class TangibleObject extends SWGObject implements Serializable { public void setOptionsBitmask(int optionsBitmask) { notifyClients(getBaseline(3).set("optionsBitmask", optionsBitmask), true); + // This needs to be refactored to be sent to clients with different values depending on their faction + // A quest object for one faction, can't be quest object for opposing faction } public void setOptions(int options, boolean add) { @@ -322,18 +325,30 @@ public class TangibleObject extends SWGObject implements Serializable { // All objects can be in combat (terminal mission flag bases, tutorial target box) public List getDefendersList() { - synchronized(objectMutex) { + synchronized(defendersList) { return defendersList; } } + public List getDefendersListClone() { + synchronized(objectMutex) { + List returnList = new Vector(); + Collections.copy(returnList, defendersList); + return returnList; + } + } + public void addDefender(TangibleObject defender) { - if (((CreatureObject)this).getOwnerId()>0){ - if (((CreatureObject)this).getOwnerId()==defender.getObjectID()){ - return; // fix for now until determined where the tamer is added from + if (this instanceof CreatureObject){ + if (((CreatureObject)this).getOwnerId()>0){ + if (((CreatureObject)this).getOwnerId()==defender.getObjectID()){ + return; // fix for now until determined where the tamer is added from + } } } - defendersList.add(defender); + synchronized(defendersList) { + defendersList.add(defender); + } if (!isInCombat()) { setInCombat(true); @@ -341,13 +356,15 @@ public class TangibleObject extends SWGObject implements Serializable { } public void removeDefender(TangibleObject defender) { - defendersList.remove(defender); - - if (defendersList.isEmpty() && isInCombat()) { - setInCombat(false); + synchronized(defendersList) { + defendersList.remove(defender); + + if (defendersList.isEmpty() && isInCombat()) { + setInCombat(false); + } } } - + public int getPvpBitmask() { synchronized(objectMutex) { return pvpBitmask; @@ -387,10 +404,10 @@ public class TangibleObject extends SWGObject implements Serializable { if (observer.getParent() != null) { observer.getSession().write(new UpdatePVPStatusMessage(this.getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) observer.getParent(), this), getFaction()).serialize()); - if(getClient() != null) - getClient().getSession().write(new UpdatePVPStatusMessage(observer.getParent().getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) this, (CreatureObject) observer.getParent()), getFaction()).serialize()); + if(getClient() != null){ + getClient().getSession().write(new UpdatePVPStatusMessage(observer.getParent().getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) this, (CreatureObject) observer.getParent()), getFaction()).serialize()); + } } - } if (getClient() != null) { @@ -400,16 +417,6 @@ public class TangibleObject extends SWGObject implements Serializable { companion.updatePvpStatus(); } } - - - if (this instanceof CreatureObject){ - if (((CreatureObject)this).isPlayer()){ - // Here a specific CREO delta must be sent to update the faction info in character sheet and symbol in name - // If anyone knows which that would be, please replace it here! - sendBaselines(this.getClient()); - - } - } } public boolean isAttackableBy(CreatureObject attacker) { @@ -602,7 +609,8 @@ public class TangibleObject extends SWGObject implements Serializable { } public void notifyClients(IoBuffer buffer, boolean notifySelf) { - notifyObservers(buffer, false); + // notifyObservers(buffer, false); // ??? Ignores the notifySelf argument. Was this done purposely? Faction Status etc. can't update the client without it + notifyObservers(buffer, notifySelf); } public ObjectMessageBuilder getMessageBuilder() { @@ -615,9 +623,26 @@ public class TangibleObject extends SWGObject implements Serializable { } } + @Override public void sendBaselines(Client destination) { if (destination != null && destination.getSession() != null) { - destination.getSession().write(getBaseline(3).getBaseline()); + + // Factional peculiarities + Baseline baseLine3 = getBaseline(3); + if (destination.getParent() instanceof CreatureObject){ + if (((CreatureObject) destination.getParent()).isPlayer() && ((CreatureObject) destination.getParent()).getFaction()!=this.getFaction()){ + int optionsBitMask = getOptionsBitmask(); + if (getOption(Options.QUEST)) + optionsBitMask = optionsBitMask & ~Options.QUEST; + if (!getOption(Options.ATTACKABLE)) + optionsBitMask = optionsBitMask | Options.ATTACKABLE; + + baseLine3.set("optionsBitmask", optionsBitMask); + } + } + + //destination.getSession().write(getBaseline(3).getBaseline()); + destination.getSession().write(baseLine3.getBaseline()); destination.getSession().write(getBaseline(6).getBaseline()); Client parent = ((getGrandparent() == null) ? null : getGrandparent().getClient()); @@ -630,12 +655,18 @@ public class TangibleObject extends SWGObject implements Serializable { if (destination.getParent() != this) { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); upvpm.setFaction(CRC.StringtoCRC(getFaction())); +// if (this.getTemplate().contains("barricade")){ +// System.out.println("BARTANO RESULT " + NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this)); +// } + upvpm.setStatus(NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this)); destination.getSession().write(upvpm.serialize()); } } } + + public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { switch (viewType) { case 3: diff --git a/src/resources/objects/waypoint/WaypointObject.java b/src/resources/objects/waypoint/WaypointObject.java index fa04db07..8dd5337d 100644 --- a/src/resources/objects/waypoint/WaypointObject.java +++ b/src/resources/objects/waypoint/WaypointObject.java @@ -22,147 +22,162 @@ package resources.objects.waypoint; import java.io.Serializable; -import java.nio.ByteOrder; import org.apache.mina.core.buffer.IoBuffer; -import org.apache.mina.core.buffer.SimpleBufferAllocator; -import resources.objects.intangible.IntangibleObject; -import engine.clients.Client; import engine.resources.common.StringUtilities; +import engine.resources.common.UString; +import engine.resources.objects.Baseline; import engine.resources.objects.IDelta; import engine.resources.objects.SWGObject; +import resources.objects.intangible.IntangibleObject; +import engine.clients.Client; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; -public class WaypointObject extends IntangibleObject implements Serializable, IDelta { +public class WaypointObject extends IntangibleObject implements IDelta, Serializable { private static final long serialVersionUID = 1L; - private int cellId; // ??? - private long locationNetworkId; - private int planetCRC; - private String name = ""; - private byte color; - private boolean isActive; - private transient static SimpleBufferAllocator bufferPool = new SimpleBufferAllocator(); + public static final byte BLUE = 1, GREEN = 2, ORANGE = 3, YELLOW = 4, PURPLE = 5, WHITE = 6, MULTICOLOR = 7; - public static final byte BLUE = 1; - public static final byte GREEN = 2; - public static final byte ORANGE = 3; - public static final byte YELLOW = 4; - public static final byte PURPLE = 5; - public static final byte WHITE = 6; - public static final byte MULTICOLOR = 7; // JTL waypoint - - public WaypointObject() { } - public WaypointObject(long objectID, Planet planet, Point3D position) { - super(objectID, planet, position, new Quaternion(0, 0, 0, 1), "object/waypoint/shared_waypoint.iff"); + super(objectID, planet, new Point3D(0, 0, 0), new Quaternion(0, 0, 0, 1), "object/waypoint/shared_waypoint.iff"); + } + + public WaypointObject() { + super(); } - @Override public void initAfterDBLoad() { super.init(); } - public synchronized int getCellId() { - return cellId; - } - - - public synchronized void setCellId(int cellId) { - this.cellId = cellId; - } - - - public synchronized long getLocationNetworkId() { - return locationNetworkId; - } - - - public synchronized void setLocationNetworkId(long locationNetworkId) { - this.locationNetworkId = locationNetworkId; - } - - - public synchronized int getPlanetCRC() { - return planetCRC; - } - - - public synchronized void setPlanetCRC(int planetCRC) { - this.planetCRC = planetCRC; - } - - - public synchronized String getName() { - return name; - } - - - public synchronized void setName(String name) { - this.name = name; - } - - - public synchronized byte getColor() { - return color; - } - - - public synchronized void setColor(byte color) { - this.color = color; - } - - - public synchronized boolean isActive() { - return isActive; - } - - - public void setActive(boolean isActive) { - this.isActive = isActive; - } - - @Override - public void sendBaselines(Client client) { - // TODO Auto-generated method stub - - } - - @Override - public byte[] getBytes() { - IoBuffer buffer = bufferPool.allocate(42 + name.length() * 2, false).order(ByteOrder.LITTLE_ENDIAN); - - buffer.putInt(getCellId()); - - buffer.putFloat(getPosition().x); - buffer.putFloat(getPosition().y); - buffer.putFloat(getPosition().z); - - buffer.putLong(0); // networklocationId - buffer.putInt(getPlanetCRC()); - - buffer.put(StringUtilities.getUnicodeString(getName())); - buffer.putLong(getObjectID()); - - buffer.put((byte) getColor()); - - if (isActive()) - buffer.put((byte) 1); - else - buffer.put((byte) 0); - - return buffer.flip().array(); - - } - - @Override - public void init(SWGObject arg0) { - // TODO Auto-generated method stub + public void init(SWGObject object) { } + public Baseline getOtherVariables() { + Baseline baseline = super.getOtherVariables(); + return baseline; + } + + public Baseline getBaseline3() { + Baseline baseline = super.getBaseline3(); + baseline.put("cellNumber", 0); + baseline.put("position", new Point3D(0, 0, 0)); + baseline.put("targetId", (long) 0); + baseline.put("planetCrc", 0); + baseline.put("name", new UString("Waypoint")); + baseline.put("color", (byte) 1); + baseline.put("active", false); + return baseline; + } + + public Baseline getBaseline6() { + Baseline baseline = super.getBaseline6(); + return baseline; + } + + @Override + public Baseline getBaseline8() { + Baseline baseline = super.getBaseline8(); + return baseline; + } + + @Override + public Baseline getBaseline9() { + Baseline baseline = super.getBaseline9(); + return baseline; + } + + public int getCellNumber() { + return (int) getBaseline(3).get("cellNumber"); + } + + public void setCellNumber(int cellNumber) { + getBaseline(3).set("cellNumber", cellNumber); + } + + public void setPosition(Point3D position) { + getBaseline(3).set("position", position); + } + + public long getTargetId() { + return (long) getBaseline(3).get("targetId"); + } + + public void setTargetId(long targetId) { + getBaseline(3).set("targetId", targetId); + } + + public int getPlanetCrc() { + return (int) getBaseline(3).get("planetCrc"); + } + + public void setPlanetCrc(int planetCrc) { + getBaseline(3).set("planetCrc", planetCrc); + } + + public String getName() { + return ((UString) getBaseline(3).get("name")).get(); + } + + public void setName(String name) { + getBaseline(3).set("name", new UString(name)); + } + + public byte getColor() { + return (byte) getBaseline(3).get("color"); + } + + public void setColor(byte color) { + getBaseline(3).set("color", color); + } + + public boolean isActive() { + return (boolean) getBaseline(3).get("active"); + } + + public void setActive(boolean active) { + getBaseline(3).set("active", active); + } + + public void toggleActive() { + setActive(!isActive()); + } + + @Override + public void sendBaselines(Client destination) { + + } + + public byte[] getBytes() { + synchronized(objectMutex) { + IoBuffer buffer = Baseline.createBuffer(38 + StringUtilities.getUnicodeString(getName()).length); + buffer.putInt(getCellNumber()); + buffer.put(Baseline.toBytes(getBaseline(3).get("position"))); + buffer.putLong(getTargetId()); + buffer.putInt(getPlanetCrc()); + buffer.put(StringUtilities.getUnicodeString(getName())); + buffer.putLong(getObjectID()); + buffer.put(getColor()); + buffer.put(Baseline.getBoolean(isActive())); + return buffer.flip().array(); + } + } + + @Deprecated public int getCellId() { return getCellNumber(); } + + @Deprecated public void setCellId(int cellId) { setCellNumber(cellId); } + + @Deprecated public long getLocationNetworkId() { return getTargetId(); } + + @Deprecated public void setLocationNetworkId(long locationNetworkId) { setTargetId(locationNetworkId); } + + @Deprecated public int getPlanetCRC() { return getPlanetCrc(); } + + @Deprecated public void setPlanetCRC(int planetCRC) { setPlanetCrc(planetCRC); } + } diff --git a/src/resources/objects/weapon/WeaponObject.java b/src/resources/objects/weapon/WeaponObject.java index 4f7402b6..9f17a8c3 100644 --- a/src/resources/objects/weapon/WeaponObject.java +++ b/src/resources/objects/weapon/WeaponObject.java @@ -82,7 +82,7 @@ public class WeaponObject extends TangibleObject implements Serializable { @Override public Baseline getBaseline6() { Baseline baseline = super.getBaseline6(); - baseline.put("weaponType", 6); + baseline.put("weaponType", WeaponType.UNARMED); return baseline; } diff --git a/src/resources/quest/Quest.java b/src/resources/quest/Quest.java index 80348605..ca2a270f 100644 --- a/src/resources/quest/Quest.java +++ b/src/resources/quest/Quest.java @@ -23,18 +23,98 @@ package resources.quest; import java.io.Serializable; +import org.apache.mina.core.buffer.IoBuffer; + +import engine.resources.common.CRC; import engine.resources.objects.Delta; public class Quest extends Delta implements Serializable { private static final long serialVersionUID = 1L; - public Quest() { - + private long ownerId; + private short activeStep = 1; + private short completedStep; + private boolean isCompleted = false; + private String name; + private int crc; + + public Quest() {} + + public Quest(String name, long ownerId) { + this.ownerId = ownerId; + this.name = name; + + if (name.endsWith(".qst")) + this.crc = CRC.StringtoCRC("quest/"+name.split(".qst")[0]); + else + this.crc = CRC.StringtoCRC("quest/"+name); } + public long getOwnerId() { + return ownerId; + } + + public void setOwnerId(long ownerId) { + this.ownerId = ownerId; + } + + public short getActiveStep() { + return activeStep; + } + + public void setActiveStep(short activeStep) { + this.activeStep = activeStep; + } + + public short getCompletedStep() { + return completedStep; + } + + public void setCompletedStep(short completedStep) { + this.completedStep = completedStep; + } + + public boolean isCompleted() { + return isCompleted; + } + + public void setCompleted(boolean isCompleted) { + this.isCompleted = isCompleted; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + this.crc = CRC.StringtoCRC(name); + } + + public int getCrc() { + return crc; + } + public byte[] getBytes() { - return new byte[] { }; + IoBuffer buffer = createBuffer(23); + + buffer.put((byte) 0); + + buffer.putInt(crc); + + buffer.putLong(ownerId); + + buffer.putShort(activeStep); + buffer.putShort(completedStep); + + buffer.put((byte) ((isCompleted) ? 1 : 0)); // isCompleted + buffer.putInt(0); // questCounter + buffer.put((byte) 0); // ? + + buffer.flip(); + + return buffer.array(); } } diff --git a/src/services/AdminService.java b/src/services/AdminService.java new file mode 100644 index 00000000..3763a874 --- /dev/null +++ b/src/services/AdminService.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.sql.PreparedStatement; + +import main.NGECore; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +public class AdminService implements INetworkDispatch { + + private NGECore core; + + public AdminService(NGECore core) { + this.core = core; + + } + + public String getAccessLevelFromDB(long id) { + String accessLevel = null; + PreparedStatement preparedStatement; + + try { + preparedStatement = NGECore.getInstance().getDatabase1().preparedStatement("SELECT * FROM accounts WHERE id=" + id + ""); + ResultSet resultSet = preparedStatement.executeQuery(); + if(resultSet.next()) + accessLevel = resultSet.getString("accessLevel"); + } catch (SQLException e) { + e.printStackTrace(); + } + + return accessLevel; + } + + @Override + public void insertOpcodes(Map arg0, Map arg1) { + + } + + @Override + public void shutdown() { + + } + +} diff --git a/src/services/BuffService.java b/src/services/BuffService.java index 70a24957..c68b1432 100644 --- a/src/services/BuffService.java +++ b/src/services/BuffService.java @@ -22,8 +22,10 @@ package services; import java.util.Map; +import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -34,6 +36,7 @@ import org.python.core.PyObject; import resources.buffs.Buff; import resources.buffs.DamageOverTime; import resources.common.FileUtilities; +import resources.datatables.Posture; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; import resources.objects.player.PlayerObject; @@ -51,6 +54,22 @@ public class BuffService implements INetworkDispatch { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private ConcurrentHashMap buffMap = new ConcurrentHashMap(); + private static Map bannerBuffMapping = new ConcurrentHashMap(); + static{ + bannerBuffMapping.put("trader_0a", "banner_buff_trader"); + bannerBuffMapping.put("trader_0b", "banner_buff_trader"); + bannerBuffMapping.put("trader_0c", "banner_buff_trader"); + bannerBuffMapping.put("trader_0d", "banner_buff_trader"); + bannerBuffMapping.put("entertainer_1a", "banner_buff_entertainer"); + bannerBuffMapping.put("medic_1a", "banner_buff_medic"); + bannerBuffMapping.put("officer_1a", "banner_buff_officer"); + bannerBuffMapping.put("bounty_hunter_1a", "banner_buff_bounty_hunter"); + bannerBuffMapping.put("smuggler_1a", "banner_buff_smuggler"); + bannerBuffMapping.put("commando_1a", "banner_buff_commando"); + bannerBuffMapping.put("spy_1a", "banner_buff_spy"); + bannerBuffMapping.put("force_sensitive_1a", "banner_buff_force_sensitive"); + } + public BuffService(NGECore core) { this.core = core; core.commandService.registerCommand("removeBuff"); @@ -102,6 +121,10 @@ public class BuffService implements INetworkDispatch { } else { if (! hasBuff(target,buffName)) // QA, prevent infinite "refreshing" of buff by repeated use doAddBuff(target, buffName, buffer); + else { + if (buff.getMaxStacks()>1) + doAddBuff(target, buffName, buffer); + } return true; } } @@ -182,6 +205,12 @@ public class BuffService implements INetworkDispatch { if(buff.getEffect4Name().length() > 0) core.skillModService.addSkillMod(target, buff.getEffect4Name(), (int) buff.getEffect4Value()); if(buff.getEffect5Name().length() > 0) core.skillModService.addSkillMod(target, buff.getEffect5Name(), (int) buff.getEffect5Value()); // } + + if (buffName.equals("gcw_fatigue")){ + if (FileUtilities.doesFileExist("scripts/buffs/" + buffName + ".py")) { + core.scriptService.callScript("scripts/buffs/", buffName, "add", core, buffer, buff); + } + } target.addBuff(buff); @@ -414,6 +443,56 @@ public class BuffService implements INetworkDispatch { } + public void applyGCWBuff(String buffName, String factionName, SWGObject center) { + Vector inRangeObjects = core.simulationService.getAllNearSameFactionCreatures(10, center.getWorldPosition(), center.getPlanet(), factionName); + for(SWGObject obj : inRangeObjects) { + if(!(obj instanceof CreatureObject)) + continue; + if(obj instanceof CreatureObject && (((CreatureObject) obj).getPosture() == Posture.Dead)) + continue; + CreatureObject buffed = (CreatureObject) obj; + if (! buffed.hasBuff(buffName)) + addBuffToCreature(buffed, buffName, buffed); + } + } + + public void initiateBannerBuffProcess(CreatureObject buffer, SWGObject banner){ + + String factionName = buffer.getFaction(); + String professionName = buffer.getPlayerObject().getProfession(); + String buffName = bannerBuffMapping.get(professionName); + applyGCWBuff(buffName, factionName, banner); + + final Future[] fut = {null}; + fut[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().objectService.getObject(banner.getObjectID())==null){ + Thread.yield(); + fut[0].cancel(false); + } + + applyGCWBuff(buffName, factionName, banner); + + if (! buffer.isInQuadtree()){ + NGECore.getInstance().objectService.destroyObject(banner.getObjectID()); + Thread.yield(); + fut[0].cancel(false); + } + + if (buffer.getWorldPosition().getDistance2D(banner.getWorldPosition())>1000 || buffer.getPlanetId()!=banner.getPlanetId()){ + NGECore.getInstance().objectService.destroyObject(banner.getObjectID()); + Thread.yield(); + fut[0].cancel(false); + } + + } catch (Exception e) { + System.err.println("Exception in GCW Banner thread " + e.getMessage()); + } + } + }, 0, 2, TimeUnit.SECONDS); + } + private void loadBuffs() { try { DatatableVisitor visitor = ClientFileManager.loadFile("datatables/buff/buff.iff", DatatableVisitor.class); diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 873b3fa7..a1fff102 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -39,6 +39,7 @@ import engine.clientdata.visitors.DatatableVisitor; import engine.clientdata.visitors.ProfessionTemplateVisitor; import engine.clients.Client; import engine.resources.common.CRC; +import engine.resources.config.Config; import engine.resources.container.CreatureContainerPermissions; import engine.resources.container.CreaturePermissions; import engine.resources.container.Traverser; @@ -265,7 +266,15 @@ public class CharacterService implements INetworkDispatch { object.setCustomName(clientCreateCharacter.getName()); object.setHeight(clientCreateCharacter.getScale()); object.setPersistent(true); - object.setPosition(SpawnPoint.getRandomPosition(new Point3D(3528, 0, -4804), (float) 0.5, 3, core.terrainService.getPlanetByName("tatooine").getID())); + + Config options = NGECore.getInstance().getOptions(); + + if (options != null && options.getInt("DO.ISOLATION.TESTS") > 0){ + object.setPosition(SpawnPoint.getRandomPosition(new Point3D(0, 0, 0), (float) 0.5, 3, core.terrainService.getPlanetByName("tatooine").getID())); + } else { + object.setPosition(SpawnPoint.getRandomPosition(new Point3D(3528, 0, -4804), (float) 0.5, 3, core.terrainService.getPlanetByName("tatooine").getID())); + } + object.setCashCredits(100); object.setBankCredits(1000); object.setIncapTimer(10); @@ -357,7 +366,7 @@ public class CharacterService implements INetworkDispatch { System.out.println("Saving character with name: " + object.getCustomName()); core.getSWGObjectODB().put(object.getObjectID(), object); - PreparedStatement ps = databaseConnection.preparedStatement("INSERT INTO characters (id, \"firstName\", \"lastName\", \"accountId\", \"galaxyId\", \"statusId\", appearance, gmflag) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + PreparedStatement ps = databaseConnection.preparedStatement("INSERT INTO characters (id, \"firstName\", \"lastName\", \"accountId\", \"galaxyId\", \"statusId\", appearance) VALUES (?, ?, ?, ?, ?, ?, ?)"); ps.setLong(1, object.getObjectID()); ps.setString(2, clientCreateCharacter.getFirstName()); ps.setString(3, clientCreateCharacter.getLastName()); @@ -365,7 +374,6 @@ public class CharacterService implements INetworkDispatch { ps.setInt(5, galaxyId); ps.setInt(6, 1); ps.setInt(7, CRC.StringtoCRC(raceTemplate)); - ps.setBoolean(8, false); ps.executeUpdate(); ps.close(); CreateCharacterSuccess success = new CreateCharacterSuccess(object.getObjectID()); diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index 4e8ce362..246501fd 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -137,7 +137,6 @@ public class ConnectionService implements INetworkDispatch { if (resultSet.next()) { client.setAccountId(resultSet.getLong("accountId")); client.setSessionKey(clientIdMsg.getSessionKey()); - client.setGM(core.loginService.checkForGmPermission((int) resultSet.getLong("accountId"))); AccountFeatureBits accountFeatureBits = new AccountFeatureBits(); ClientPermissionsMessage clientPermissionsMessage = new ClientPermissionsMessage(maxNumberOfCharacters - core.characterService.getNumberOfCharacters((int) resultSet.getLong("accountId"))); session.write(new HeartBeatMessage().serialize()); @@ -340,7 +339,6 @@ public class ConnectionService implements INetworkDispatch { } ghost.toggleFlag(PlayerFlags.LD); - object.setPerformanceListenee(null); object.setPerformanceWatchee(null); object.setAttachment("disconnectTask", null); diff --git a/src/services/LoginService.java b/src/services/LoginService.java index 3133269f..6e54624c 100644 --- a/src/services/LoginService.java +++ b/src/services/LoginService.java @@ -105,8 +105,9 @@ public class LoginService implements INetworkDispatch{ String user = clientID.getAccountName(); String pass = clientID.getPassword(); + String version = clientID.getVersion(); int id = LoginProvider.getAccountId(user, pass, session.getRemoteAddress().toString()); - System.out.println("LOGIN: " + user + " login attempt "+session.getRemoteAddress().toString()+" returned " + id); + System.out.println("LOGIN: " + user + " login attempt " + session.getRemoteAddress().toString() + " returned " + id); if (id < 0) { @@ -135,14 +136,21 @@ public class LoginService implements INetworkDispatch{ return; } + if(!version.equals("20111130-15:46")) { + ErrorMessage clientErr = new ErrorMessage("Invalid Client", "The version of your client is invalid."); + session.write(clientErr.serialize()); + + Disconnect disconnect = new Disconnect((Integer)session.getAttribute("connectionId"), 6); + session.write(disconnect); + return; + } + Client client = new Client(session.getRemoteAddress()); client.setAccountName(user); client.setPassword(pass); client.setSessionKey(generateSessionKey()); client.setAccountId(id); - //client.setAccountEmail(email); client.setSession(session); - client.setGM(checkForGmPermission(id)); core.addClient(session, client); @@ -156,9 +164,6 @@ public class LoginService implements INetworkDispatch{ System.out.println(client.getAccountName() + " was not added to active connections map."); return; } - /*if(!checkIfAccountExistInGameDB(id)) { - createAccountForGameDB(id, user, email, encryptPass); - }*/ persistSession(client); @@ -170,6 +175,8 @@ public class LoginService implements INetworkDispatch{ CharacterCreationDisabled charCreationDisabled = new CharacterCreationDisabled(0); StationIdHasJediSlot jediSlot = new StationIdHasJediSlot(false); ServerNowEpochTime time = new ServerNowEpochTime((int) (System.currentTimeMillis() / 1000)); + //System.out.println("ServerNowEpochTime " + (int) (System.currentTimeMillis() / 1000)); + //tools.CharonPacketUtils.printAnalysis(time.serialize(), "ServerNowEpochTime"); if (client.getSession().containsAttribute("tradeSession") == true) { client.getSession().removeAttribute("tradeSession"); @@ -267,29 +274,6 @@ public class LoginService implements INetworkDispatch{ } - public boolean checkForGmPermission(int id) { - try { - if (core.getConfig().getInt("ADMIN") > 0) { - return true; - } - } catch (Exception e) { - - } - - PreparedStatement preparedStatement; - - try { - preparedStatement = databaseConnection1.preparedStatement("SELECT * FROM accounts WHERE id=" + id + ""); - ResultSet resultSet = preparedStatement.executeQuery(); - if(resultSet.next()) - return resultSet.getBoolean("gmflag"); - } catch (SQLException e) { - e.printStackTrace(); - } - - return false; - } - /** * Saves session data to DB so Zone Server can link sessions to accounts. * @param client Client that needs a session save. @@ -396,14 +380,5 @@ public class LoginService implements INetworkDispatch{ return clusterStatus; } - /** - * Checks if User has correct client version. - * @param version Client Version String - */ - private boolean checkVersion(String version) { - System.out.println("Version Received: " + version); - return true; - } - } diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index 04d1b18c..996a2214 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -37,9 +37,11 @@ import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.concurrent.atomic.AtomicBoolean; + import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; + import protocol.swg.CharacterSheetResponseMessage; import protocol.swg.ClientIdMsg; import protocol.swg.ClientMfdStatusUpdateMessage; @@ -67,9 +69,13 @@ import resources.common.OutOfBand; import resources.common.ProsePackage; import resources.common.SpawnPoint; import resources.datatables.DisplayType; +import resources.datatables.FactionStatus; +import resources.datatables.Factions; +import resources.datatables.GcwRank; import resources.datatables.Options; import resources.datatables.PlayerFlags; import resources.datatables.Professions; +import resources.datatables.AdminTag; import resources.guild.Guild; import resources.objects.building.BuildingObject; import resources.objects.cell.CellObject; @@ -136,6 +142,48 @@ public class PlayerService implements INetworkDispatch { player.setTotalPlayTime((int) (player.getTotalPlayTime() + ((System.currentTimeMillis() - player.getLastPlayTimeUpdate()) / 1000))); player.setLastPlayTimeUpdate(System.currentTimeMillis()); core.collectionService.checkExplorationRegions(creature); + + // GCW rank progress + if (creature.getFaction().equals("rebel") || creature.getFaction().equals("imperial")){ + int oldrank = player.getCurrentRank(); + //int oldprogress = (int) ((player.getRankProgress() > 100) ? 100 : player.getRankProgress()); + int oldprogress = 0; + int oldpoints = player.getGcwPoints(); + int newrank = oldrank; + int newprogress = oldprogress; + int oldranktotal = 0; + int oldrankprogress = 0; + int newranktotal = 0; + int newrankprogress = 0; + + oldrankprogress = oldprogress * 50; + oldranktotal = 5000 * (oldrank - 1) + oldrankprogress; + + newprogress = (int) core.gcwService.helper(oldpoints, oldrank); + + if (newprogress < -2000) { + newprogress = -2000; + } + + newranktotal = oldranktotal + newprogress; + + if (oldrank == GcwRank.LIEUTENANT && newprogress < 0 && newranktotal < 30000) { + newranktotal = 29999; + } + + newrank = oldrank; + + if (newrank > GcwRank.GENERAL) { + newrank = GcwRank.GENERAL; + newranktotal = 12 * 5000 - 1; + } + + newrankprogress = newranktotal - (newrank - 1) * 5000; + newprogress = newrankprogress * 100 / 5000; + + player.setRankProgress((float) Math.floor(newprogress)); + } + } catch (Exception e) { e.printStackTrace(); } @@ -143,7 +191,7 @@ public class PlayerService implements INetworkDispatch { scheduleList.add(scheduler.scheduleAtFixedRate(() -> { try { - if (creature.isInStealth() && !creature.getOption(Options.INVULNERABLE) && ((PlayerObject) creature.getSlottedObject("ghost")).getGodLevel() == 0) { + if (creature.isInStealth() && !creature.getOption(Options.INVULNERABLE) && core.adminService.getAccessLevelFromDB(creature.getClient().getAccountId()) == null) { List objects = core.simulationService.get(creature.getPlanet(), creature.getPosition().x, creature.getPosition().z, 64); for (SWGObject object : objects) { @@ -157,7 +205,7 @@ public class PlayerService implements INetworkDispatch { CreatureObject observer = (CreatureObject) object; - int camoflauge = creature.getSkillModBase("camoflauge") - observer.getSkillModBase("detectcamo"); + int camoflauge = creature.getSkillModBase("camouflage") - observer.getSkillModBase("detectcamo"); camoflauge -= (64 - creature.getPosition().getDistance(observer.getPosition())); if (new Random(camoflauge).nextInt() == camoflauge) { @@ -526,10 +574,19 @@ public class PlayerService implements INetworkDispatch { @SuppressWarnings("unchecked") public void sendCloningWindow(CreatureObject creature, final boolean pvpDeath) { - //if(creature.getPosture() != 14) - // return; + if(creature.getPosture() != 14) + return; List cloners = core.staticService.getCloningFacilitiesByPlanet(creature.getPlanet()); + + boolean invasionDeath = core.invasionService.checkInvasionDeath(creature); + + if (invasionDeath){ + if (core.invasionService.getAccordingCloners(creature).size()>0){ + cloners = core.invasionService.getAccordingCloners(creature); + } + } + Map cloneData = new HashMap(); Point3D position = creature.getWorldPosition(); @@ -542,9 +599,20 @@ public class PlayerService implements INetworkDispatch { } final long preDesignatedObjectId = (preDesignatedCloner != null) ? preDesignatedCloner.getObjectID() : 0; cloners.stream().filter(c -> c.getObjectID() != preDesignatedObjectId).forEach(c -> cloneData.put(c.getObjectID(), core.mapService.getClosestCityName(c))); + + Map listedCloneData = cloneData; + if (invasionDeath){ + if (core.invasionService.getAccordingCloners(creature).size()>0){ + listedCloneData = new HashMap(); + for (SWGObject cloner : core.invasionService.getAccordingCloners(creature)){ + listedCloneData.put(cloner.getObjectID(), cloner.getCustomName()); + } + } + } + final SUIWindow window = core.suiService.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, "@base_player:revive_title", "@base_player:clone_prompt_header", - cloneData, creature, null, 0); + listedCloneData, creature, null, 0); Vector returnList = new Vector(); returnList.add("List.lstList:SelectedRow"); @@ -577,10 +645,10 @@ public class PlayerService implements INetworkDispatch { } public void handleCloneRequest(CreatureObject creature, BuildingObject cloner, SpawnPoint spawnPoint, boolean pvpDeath) { - + CellObject cell = cloner.getCellByCellNumber(spawnPoint.getCellNumber()); - if(cell == null) + if(cell == null && !cloner.getTemplate().contains("shared_invisible_cloner")) return; creature.setPosture((byte) 0); @@ -599,7 +667,9 @@ public class PlayerService implements INetworkDispatch { creature.updateAllBuffs(); } - creature.setFactionStatus(0); + creature.setFactionStatus(FactionStatus.OnLeave); + creature.updatePvpStatus(); + core.buffService.addBuffToCreature(creature, "cloning_sickness", creature); } @@ -681,35 +751,36 @@ public class PlayerService implements INetworkDispatch { /* * Resets to level 1 */ - public void resetLevel(CreatureObject creature) { + public void resetLevel(CreatureObject creature, boolean unequipItems) { PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); SWGObject inventory = creature.getSlottedObject("inventory"); - - try { - for (Long equipmentId : new ArrayList(creature.getEquipmentList())) { - - SWGObject equipment = core.objectService.getObject(equipmentId); - - if (equipment == null || equipment.getTemplate().startsWith("object/tangible/hair/")) { - continue; - } - - switch (equipment.getTemplate()) { - case "object/tangible/inventory/shared_character_inventory.iff": - case "object/tangible/inventory/shared_appearance_inventory.iff": - case "object/tangible/datapad/shared_character_datapad.iff": - case "object/tangible/bank/shared_character_bank.iff": - case "object/tangible/mission_bag/shared_mission_bag.iff": - case "object/weapon/creature/shared_creature_default_weapon.iff": - continue; - default: - creature.transferTo(creature, inventory, equipment); - } - } - } catch (Exception e) { - e.printStackTrace(); + + if (unequipItems) { + try { + for (Long equipmentId : new ArrayList(creature.getEquipmentList())) { + + SWGObject equipment = core.objectService.getObject(equipmentId); + + if (equipment == null || equipment.getTemplate().startsWith("object/tangible/hair/")) { + continue; + } + + switch (equipment.getTemplate()) { + case "object/tangible/inventory/shared_character_inventory.iff": + case "object/tangible/inventory/shared_appearance_inventory.iff": + case "object/tangible/datapad/shared_character_datapad.iff": + case "object/tangible/bank/shared_character_bank.iff": + case "object/tangible/mission_bag/shared_mission_bag.iff": + case "object/weapon/creature/shared_creature_default_weapon.iff": + continue; + default: + creature.transferTo(creature, inventory, equipment); + } + } + } catch (Exception e) { + e.printStackTrace(); + } } - //for (SWGObject equipment : creature.getAppearanceEquipmentList()) { //core.equipmentService.unequip(creature, equipment); //} @@ -793,7 +864,8 @@ public class PlayerService implements INetworkDispatch { if(level == 0) return; - resetLevel(creature); + if (!(creature.getLevel() <= (short) 1)) resetLevel(creature, true); + else resetLevel(creature, false); try { experienceTable = ClientFileManager.loadFile("datatables/player/player_level.iff", DatatableVisitor.class); diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index dd1c6171..874ac673 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -80,7 +80,9 @@ import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; import resources.objects.harvester.HarvesterObject; +import resources.objects.installation.InstallationObject; import resources.objects.player.PlayerObject; +import resources.objects.staticobject.StaticObject; import resources.objects.tangible.TangibleObject; import resources.common.*; import resources.common.collidables.AbstractCollidable; @@ -281,12 +283,172 @@ public class SimulationService implements INetworkDispatch { public Vector getAllNearNPCs(int distance, SWGObject value ){ Vector foundCreatures = new Vector(); core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> { - if (objecta instanceof CreatureObject) + if (objecta instanceof CreatureObject && objecta!=value) foundCreatures.add((CreatureObject)objecta); } ); return foundCreatures; } + + public Vector getAllNearPlayers(int distance, SWGObject value ){ + Vector foundCreatures = new Vector(); + core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> { + if (objecta instanceof CreatureObject && objecta!=value) + if (((CreatureObject)objecta).isPlayer()) + foundCreatures.add((CreatureObject)objecta); + } + ); + return foundCreatures; + } + + public Vector getAllNearPlayers(int distance, Planet planet, Point3D pos ){ + Vector foundCreatures = new Vector(); + core.simulationService.get(planet, pos.x, pos.z, distance).stream().forEach((objecta) -> { + if (objecta instanceof CreatureObject) + if (((CreatureObject)objecta).isPlayer()) + foundCreatures.add((CreatureObject)objecta); + } + ); + return foundCreatures; + } + + public Vector getAllNearNonSameFactionTargets(int distance, SWGObject center ){ + Vector foundTargets = new Vector(); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + if (center.getObjectID()!=objecta.getObjectID()){ + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && !(objecta instanceof StaticObject)){ + if (objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject) objecta,(TangibleObject) center)) + foundTargets.add((TangibleObject)objecta); + } + } + }); + return foundTargets; + } + + public Vector getAllNearNonSameFactionNPCs(int distance, SWGObject center ){ + Vector foundCreatures = new Vector(); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + if (center.getObjectID()!=objecta.getObjectID()){ + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof CreatureObject){ + if (objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionEnemy((CreatureObject) objecta,(TangibleObject) center)) + foundCreatures.add((CreatureObject)objecta); + } + } + }); + return foundCreatures; + } + + public Vector getAllNearNonSameFactionPlayers(int distance, SWGObject center ){ + Vector foundCreatures = new Vector(); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + if (center.getObjectID()!=objecta.getObjectID()){ + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof CreatureObject){ + if (((CreatureObject)objecta).isPlayer() && objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionEnemy((CreatureObject) objecta,(TangibleObject) center)) + foundCreatures.add((CreatureObject)objecta); + } + } + }); + return foundCreatures; + } + + public Vector getAllNearSameFactionNPCs(int distance, SWGObject center ){ + Vector foundCreatures = new Vector(); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof CreatureObject){ + if (objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionAlly((TangibleObject) objecta,(TangibleObject) center)) + foundCreatures.add((CreatureObject)objecta); + } + }); + return foundCreatures; + } + + public Vector getAllNearSameFactionPlayers(int distance, Point3D centerPos, Planet planet, String factionName){ + Vector foundCreatures = new Vector(); + core.simulationService.get(planet, centerPos.x, centerPos.z, distance).stream().forEach((objecta) -> { + + if (factionName.length()>0 && objecta instanceof CreatureObject){ + if (((CreatureObject)objecta).isPlayer() && NGECore.getInstance().factionService.isFactionAlly(((CreatureObject) objecta).getFaction(),factionName)) + foundCreatures.add((CreatureObject)objecta); + } + }); + return foundCreatures; + } + + public Vector getAllNearSameFactionCreatures(int distance, Point3D centerPos, Planet planet, String factionName){ + Vector foundCreatures = new Vector(); + core.simulationService.get(planet, centerPos.x, centerPos.z, distance).stream().forEach((objecta) -> { + if (factionName.length()>0 && objecta instanceof CreatureObject){ + if (NGECore.getInstance().factionService.isFactionAlly(((CreatureObject) objecta).getFaction(),factionName)) + foundCreatures.add((CreatureObject)objecta); + } + }); + return foundCreatures; + } + + public Vector getAllNearTANOs(int distance, SWGObject value ){ + Vector foundTANOs = new Vector(); + core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> { + if (objecta instanceof TangibleObject && objecta!=value) + foundTANOs.add((TangibleObject)objecta); + } + ); + return foundTANOs; + } + + public Vector getAllNearNonSameFactionTANOs(int distance, SWGObject center ){ + Vector foundTANOs = new Vector(); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + + //if (objecta.getTemplate().contains("shared_adv_turret_dish_sm_heat")){ + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof TangibleObject && !(objecta instanceof CreatureObject)){ + if (objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject) objecta,(TangibleObject) center)) + foundTANOs.add((TangibleObject)objecta); + } + + }); + return foundTANOs; + } public boolean move(SWGObject object, int oldX, int oldZ, int newX, int newZ) { if(quadTrees.get(object.getPlanet().getName()).remove(oldX, oldZ, object)) { @@ -705,6 +867,15 @@ public class SimulationService implements INetworkDispatch { add(object, newPosition.x, newPosition.z); } + if (object.getPlanet().getName().equals("talus") && object.getTemplate().contains("stormtrooper")){ +// float xx = object.getWorldPosition().x - newPosition.x; +// float zz = object.getWorldPosition().z - newPosition.z; +// float diff = (float) Math.sqrt(xx*xx+zz*zz); +// System.out.println(" ((CreatureObject)object).getSpeedMultiplierBase());: " + ((CreatureObject)object).getSpeedMultiplierBase()); +// System.out.println(" ((CreatureObject)object).getSpeedMultiplierMod());: " + ((CreatureObject)object).getSpeedMultiplierMod()); +// + } + UpdateTransformMessage utm = new UpdateTransformMessage(object.getObjectID(), (short) (newPosition.x * 4 + 0.5), (short) (newPosition.y * 4 + 0.5), (short) (newPosition.z * 4 + 0.5), movementCounter + 1, getSpecialDirection(newOrientation), speed); List newAwareObjects = get(object.getPlanet(), newPosition.x, newPosition.z, 512); @@ -838,8 +1009,18 @@ public class SimulationService implements INetworkDispatch { float cos = (float) Math.cos(radians); WB_M44 rotationMatrix = new WB_M44(cos, 0, sin, 0, 0, 1, 0, 0, -sin, 0, cos, 0, 0, 0, 0, 1); - - WB_M44 modelSpace = translateMatrix.mult(rotationMatrix).inverse(); + + WB_M44 modelSpace = null; + try { + modelSpace = translateMatrix.mult(rotationMatrix).inverse(); + } catch (Exception ex){ + // It's usually a bank terminal causing this + //System.out.println("The object " + object.getTemplate() + " at x:" + object.getWorldPosition().x + " z:" + object.getWorldPosition().z + " causes a problem during modelspaceconversion. Can be safely ignored."); + if (modelSpace==null) + return new Ray(origin, new Vector3D(0,0,0)); + } + + float originX = (float) (modelSpace.m11 * origin.x + modelSpace.m12 * origin.y + modelSpace.m13 * origin.z + modelSpace.m14); float originY = (float) (modelSpace.m21 * origin.x + modelSpace.m22 * origin.y + modelSpace.m23 * origin.z + modelSpace.m24); @@ -1185,8 +1366,8 @@ public class SimulationService implements INetworkDispatch { public boolean checkLineOfSight(SWGObject object, Point3D position2) { long startTime = System.nanoTime(); - float heightOrigin = 1.f; - float heightDirection = 1.f; + float heightOrigin = 1.75f; + float heightDirection = 1.75f; if (object instanceof CreatureObject) { heightOrigin = getHeightOrigin((CreatureObject) object); @@ -1205,6 +1386,9 @@ public class SimulationService implements INetworkDispatch { continue; } + if (object.getTemplate().contains("_barricade") || object.getTemplate().contains("shared_dejarik_table_base")) + continue; + if (object.getTemplateData() != null && object.getTemplateData().getAttribute("collisionActionBlockFlags") != null) { int bit = (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags") & 255; @@ -1237,6 +1421,83 @@ public class SimulationService implements INetworkDispatch { return true; } + + public boolean checkLineOfSight2(SWGObject obj1, Point3D obj2) { + long startTime = System.nanoTime(); + + float heightOrigin = 1.75f; + float heightDirection = 1.75f; + + if(obj1 instanceof CreatureObject) + heightOrigin = getHeightOrigin((CreatureObject) obj1); + + Point3D position1 = obj1.getWorldPosition(); + Point3D position2 = obj2; + + Point3D origin = new Point3D(position1.x, position1.y + heightOrigin, position1.z); + Point3D end = new Point3D(position2.x, position2.y + heightDirection, position2.z); + float distance = position1.getDistance2D(position2); + + List inRangeObjects = get(obj1.getPlanet(), position1.x, position1.z, (int) (distance + 10)); + + for(SWGObject object : inRangeObjects) { + + if(object == obj1) + continue; + + if (object.getTemplate().contains("_barricade") || object.getTemplate().contains("shared_dejarik_table_base")) + continue; + + if(object.getTemplateData() != null && object.getTemplateData().getAttribute("collisionActionBlockFlags") != null) { + int bit = (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags") & 255; + if(bit == (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags")) + continue; + } + + Ray ray = convertRayToModelSpace(origin, end, object); + + MeshVisitor visitor = object.getMeshVisitor(); + + if(visitor == null) + continue; + + List tris = visitor.getTriangles(); + + if(tris.isEmpty()) + continue; + + for(Mesh3DTriangle tri : tris) { + + if(ray.intersectsTriangle(tri, distance) != null) { + //System.out.println("Collision took: " + (System.nanoTime() - startTime) + " ns (collided)"); + // System.out.println("Collided with " + object.getTemplate() + " X: " + object.getPosition().x + " Y: " + object.getPosition().y + " Z: " + object.getPosition().z); + return false; + } + + } + + } + + List segments = new ArrayList(); + Line3D.splitIntoSegments(new Vec3D(position1.x, position1.y + 1, position1.z), new Vec3D(position2.x, position2.y + 1, position2.z), (float) 1, segments, true); + + for(Vec3D segment : segments) { + float y = segment.y; + + int height = (int) core.terrainService.getHeight(obj1.getPlanetId(), segment.x, segment.z); // round down to int + + if(height > y) { + //System.out.println("Collision took: " + (System.nanoTime() - startTime) + " ns (terrain collision)"); + return false; + } + } + //System.out.println("Collision took: " + (System.nanoTime() - startTime) + " ns (did not collide)"); + + return true; + + } + + public boolean checkLineOfSight(SWGObject obj1, SWGObject obj2) { long startTime = System.nanoTime(); if(obj1.getPlanet() != obj2.getPlanet()) @@ -1256,8 +1517,10 @@ public class SimulationService implements INetworkDispatch { } - float heightOrigin = 1.f; - float heightDirection = 1.f; +// float heightOrigin = 1.f; +// float heightDirection = 1.f; + float heightOrigin = 1.75f; + float heightDirection = 1.75f; if (obj2.getTemplate().equals("object/tangible/inventory/shared_character_inventory.iff")){ obj2 = obj2.getContainer(); // LOS message fix on corpse @@ -1283,6 +1546,9 @@ public class SimulationService implements INetworkDispatch { if(object == obj1 || object == obj2) continue; + if (object.getTemplate().contains("_barricade") || object.getTemplate().contains("shared_dejarik_table_base")) + continue; + if(object.getTemplateData() != null && object.getTemplateData().getAttribute("collisionActionBlockFlags") != null) { int bit = (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags") & 255; if(bit == (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags")) diff --git a/src/services/StaticService.java b/src/services/StaticService.java index 97be0a13..62b0ad61 100644 --- a/src/services/StaticService.java +++ b/src/services/StaticService.java @@ -59,9 +59,9 @@ public class StaticService implements INetworkDispatch { } public void spawnStatics() { - Config options = new Config(); - options.setFilePath("options.cfg"); - final boolean buildoutsDisabled = ((options.loadConfigFile() && options.getInt("LOAD.BUILDOUT_OBJECTS") == 0) ? true : false); + Config options = core.getOptions(); + + final boolean buildoutsDisabled = ((options != null && options.getInt("LOAD.BUILDOUT_OBJECTS") == 0) ? true : false); for (Planet planet : core.terrainService.getPlanetList()) { if (FileUtilities.doesFileExist("scripts/static_spawns/" + planet.getName())) { @@ -240,14 +240,13 @@ public class StaticService implements INetworkDispatch { public List getCloningFacilitiesByPlanet(Planet planet) { List objects = core.simulationService.get(planet, 0, 0, 8300); List cloners = new ArrayList(); - for (SWGObject obj : objects) { if(obj instanceof BuildingObject && (obj.getTemplate().contains("cloning_facility") || obj.getTemplate().contains("cloning_tatooine") || obj.getTemplate().contains("cloning_naboo") || obj.getTemplate().contains("cloning_corellia"))) { if(!obj.getTemplate().equals("object/building/general/shared_cloning_facility_general.iff")) cloners.add(obj); } } - + return cloners; } diff --git a/src/services/SurveyService.java b/src/services/SurveyService.java index 539af893..5bf32584 100644 --- a/src/services/SurveyService.java +++ b/src/services/SurveyService.java @@ -37,7 +37,6 @@ import resources.harvest.SurveyTool; import resources.objects.creature.CreatureObject; import resources.objects.player.PlayerObject; import resources.objects.resource.GalacticResource; -import resources.objects.resource.ResourceConcentration; import resources.objects.resource.ResourceContainerObject; import resources.objects.resource.ResourceRoot; import resources.objects.tangible.TangibleObject; diff --git a/src/services/TerrainService.java b/src/services/TerrainService.java index 8bea9b00..32a71dbf 100644 --- a/src/services/TerrainService.java +++ b/src/services/TerrainService.java @@ -34,6 +34,7 @@ import resources.datatables.ClientPOIRadius; import services.playercities.ClientRegion; import engine.clientdata.ClientFileManager; import engine.clientdata.visitors.DatatableVisitor; +import engine.resources.common.CRC; import engine.resources.config.Config; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; @@ -168,6 +169,16 @@ public class TerrainService { return null; } + public Planet getPlanetByCrc(int crc) { + for (int i = 0; i < planets.size(); i++) { + if (CRC.StringtoCRC(planets.get(i).getName().toLowerCase()) == crc) { + return planets.get(i); + } + } + + return null; + } + public Planet getPlanetByPath(String path) { for (int i = 0; i < planets.size(); i++) { if (planets.get(i).getPath().equals(path)) { @@ -197,11 +208,9 @@ public class TerrainService { if(planet.getSnapshotVisitor() != null) { Thread thread = new Thread(() -> { - Config config = new Config(); - config.setFilePath("options.cfg"); - boolean loaded = config.loadConfigFile(); - - if (loaded && config.getInt("LOAD.SNAPSHOT_OBJECTS") > 0) { + Config options = core.getOptions(); + + if (options != null && options.getInt("LOAD.SNAPSHOT_OBJECTS") > 0) { if (!core.getExcludedDevelopers().contains(System.getProperty("user.name"))){ try { core.objectService.loadSnapshotObjects(planet); @@ -211,18 +220,22 @@ public class TerrainService { } } - if (loaded && config.getInt("LOAD.BUILDOUT_OBJECTS") > 0) { - if (!core.getExcludedDevelopers().contains(System.getProperty("user.name"))){ - if (! config.keyExists("LOAD.BUILDOUT_ONLY_FOR")){ - try { + if (options != null && options.getInt("LOAD.BUILDOUT_OBJECTS") > 0) { + if (!core.getExcludedDevelopers().contains(System.getProperty("user.name"))){ + if (! options.keyExists("LOAD.BUILDOUT_ONLY_FOR")){ + try { + System.out.println("Loading buildout objects for: " + planet.getName()); core.objectService.loadBuildoutObjects(planet); + System.out.println("Finished loading buildout objects for: " + planet.getName()); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } else { - if (planet.getName().equals(config.getString("LOAD.BUILDOUT_ONLY_FOR"))){ - try { + if (planet.getName().trim().equals(options.getString("LOAD.BUILDOUT_ONLY_FOR").trim())){ + try { + System.out.println("Loading buildout objects for: " + planet.getName()); core.objectService.loadBuildoutObjects(planet); + System.out.println("Finished loading buildout objects for " + planet.getName()); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index f17a7741..20bc635b 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -59,7 +59,7 @@ public class AIActor { private CreatureObject creature; private Point3D spawnPosition; private volatile AIState currentState; - private CreatureObject followObject; + private TangibleObject followObject; private Vector movementPoints = new Vector(); private MobileTemplate mobileTemplate; private ScheduledExecutorService scheduler; @@ -86,14 +86,41 @@ public class AIActor { private ScheduledFuture movementFuture; private ScheduledFuture recoveryFuture; private ScheduledFuture despawnFuture; + private boolean patrolLoop = true; // default + private TangibleObject lastTarget = null; + private Point3D repositionLocation; + private long repositionStartTime = 0L; + private long actorID = 0L; + private static long autoActorID = 0L; + private boolean actorAlive = true; + private int progressionMarker = 0; + private boolean AIactive = true; public AIActor(CreatureObject creature, Point3D spawnPosition, ScheduledExecutorService scheduler) { + actorID = autoActorID++; this.creature = creature; this.spawnPosition = spawnPosition; setLastPositionBeforeStateChange(spawnPosition); // just to make sure it's initialized this.scheduler = scheduler; creature.getEventBus().subscribe(this); this.currentState = new IdleState(); + initiateSchedules(); + } + + public AIActor(CreatureObject creature, Point3D spawnPosition, ScheduledExecutorService scheduler, boolean aiactive) { + actorID = autoActorID++; + this.creature = creature; + this.spawnPosition = spawnPosition; + setLastPositionBeforeStateChange(spawnPosition); // just to make sure it's initialized + this.scheduler = scheduler; + creature.getEventBus().subscribe(this); + this.currentState = new IdleState(); + this.AIactive = aiactive; + initiateSchedules(); + } + + private void initiateSchedules(){ + setIntendedPrimaryAIState(this.currentState); // to switch back to after aggro regenTask = scheduler.scheduleAtFixedRate(() -> { try { @@ -112,41 +139,42 @@ public class AIActor { if(creature.getOption(Options.AGGRESSIVE)) { aggroCheckTask = scheduler.scheduleAtFixedRate(() -> { try { - - if(creature == null || creature.getObservers().isEmpty() || creature.isInCombat() || isStalking) - return; - if (creature.getAttachment("tamed")!=null){ - DevLog.debugout("Charon", "Pet AI", "aggroCheckTask tamed==1"); - return; - } - - if (creature.getCustomName().contains("baby")) - DevLog.debugout("Charon", "Pet AI", "baby aggroCheckTask should not be here " +creature.getAttachment("tamed")); - - creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 15)).forEach((obj) -> { - if(new Random().nextFloat() <= 0.5 || creature.isInCombat() || isStalking) { - /*if(mobileTemplate.isStalker()) { - setFollowObject((CreatureObject) obj); - setCurrentState(new StalkState()); - } else */ - - if (creature.getAttachment("IsBeingTamed")!=null) - return; - - if (obj instanceof CreatureObject){ - CreatureObject addedObject = (CreatureObject) obj; - if (addedObject.getCalledPet()!=null){ - CreatureObject calledPet = addedObject.getCalledPet(); - if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){ - addDefender(calledPet); + if (AIactive){ + if(creature == null || creature.getObservers().isEmpty() || creature.isInCombat() || isStalking) + return; + if (creature.getAttachment("tamed")!=null){ + DevLog.debugoutai(this, "Charon", "Pet AI", "aggroCheckTask tamed==1"); + return; + } + + if (creature.getCustomName().contains("baby")) + DevLog.debugoutai(this, "Charon", "Pet AI", "baby aggroCheckTask should not be here " +creature.getAttachment("tamed")); + + creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 15)).forEach((obj) -> { + if(new Random().nextFloat() <= 0.5 || creature.isInCombat() || isStalking) { + /*if(mobileTemplate.isStalker()) { + setFollowObject((CreatureObject) obj); + setCurrentState(new StalkState()); + } else */ + + if (creature.getAttachment("IsBeingTamed")!=null) + return; + + if (obj instanceof CreatureObject){ + CreatureObject addedObject = (CreatureObject) obj; + if (addedObject.getCalledPet()!=null){ + CreatureObject calledPet = addedObject.getCalledPet(); + if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){ + addDefender(calledPet); + } + } + if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14){ + addDefender(addedObject); } } - if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14){ - addDefender(addedObject); - } } - } - }); + }); + } } catch (Exception e) { e.printStackTrace(); } @@ -155,61 +183,66 @@ public class AIActor { if(creature.getFaction().length()>0 || !creature.getOption(Options.AGGRESSIVE)) { factionCheckTask = scheduler.scheduleAtFixedRate(() -> { try { - - if(creature == null || creature.getFactionStatus()!=FactionStatus.Combatant || creature.getObservers().isEmpty() || creature.isInCombat()) - return; - - creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 15)).forEach((obj) -> { - if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { - DevLog.debugout("Charon", "CHECK faction creature ", "added " + creature.getFaction()); - DevLog.debugout("Charon", "CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "CHECK factionCheckTask", "added " + obj.getCustomName()); - DevLog.debugout("Charon", "CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); - if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){ - CreatureObject addedObject = (CreatureObject) obj; - if (addedObject.getCalledPet()!=null){ - CreatureObject calledPet = addedObject.getCalledPet(); - if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){ - addDefender(calledPet); - } - } - if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14){ - addDefender(addedObject); - DevLog.debugout("Charon", "faction creature ", "added " + creature.getFaction()); - DevLog.debugout("Charon", "faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "factionCheckTask", "added " + obj.getCustomName()); - } + if (AIactive){ + // this is difficult, should NPC not fight when no player is near? || creature.getObservers().isEmpty() + if(creature == null || creature.getFactionStatus()!=FactionStatus.Combatant || creature.isInCombat()) + return; + if(this.getFollowObject() != null){ // Don't search if actor has valid target + CreatureObject addedCreature = null; + TangibleObject addedObject = null; + if (this.getFollowObject() instanceof TangibleObject){ + addedObject = (TangibleObject) this.getFollowObject(); + if (addedObject.getConditionDamage()>=addedObject.getMaximumCondition()) + return; + } + if (this.getFollowObject() instanceof CreatureObject){ + addedCreature = (CreatureObject) this.getFollowObject(); + if (addedCreature.getPosture() != 13 && addedCreature.getPosture() != 14) + return; } } - }); - - NGECore.getInstance().simulationService.getAllNearNPCs(15, creature).forEach((obj) -> { - if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { - DevLog.debugout("Charon", "CHECK faction creature ", "added " + creature.getFaction()); - DevLog.debugout("Charon", "CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "CHECK factionCheckTask", "added " + obj.getCustomName()); - DevLog.debugout("Charon", "CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); - if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){ - CreatureObject addedObject = (CreatureObject) obj; - if (addedObject.getCalledPet()!=null){ - CreatureObject calledPet = addedObject.getCalledPet(); - if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){ - addDefender(calledPet); + + // Check for near targets + float[] closestDist = {9999F}; + TangibleObject[] closestCreature = {null}; + + NGECore.getInstance().simulationService.getAllNearNonSameFactionTargets(15, creature).forEach((obj) -> { + if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { + if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (CreatureObject)obj)){ + CreatureObject addedObject = (CreatureObject) obj; + if (addedObject.getCalledPet()!=null){ + CreatureObject calledPet = addedObject.getCalledPet(); + if (NGECore.getInstance().aiService.distanceSquared2D(creature.getWorldPosition(), obj.getWorldPosition()) @@ -250,9 +287,18 @@ public class AIActor { } } - public void removeDefender(CreatureObject defender) { + public void removeDefender(TangibleObject defender) { + if (defender==null){ +// damageMap.keySet().remove(null); +// damageMap.values().remove(null); + //ToDo: Remove those empty defenders somehow +// if (damageMap.containsKey(null)) +// damageMap.remove(null); + return; + } creature.removeDefender(defender); - damageMap.remove(defender); + if (damageMap.containsKey(defender)) + damageMap.remove(defender); defender.removeDefender(creature); if(followObject == defender) { setFollowObject(getHighestDamageDealer()); @@ -285,17 +331,18 @@ public class AIActor { if(this.currentState != null) doStateAction(this.currentState.onExit(this)); this.currentState = currentState; + DevLog.debugoutai(this,"Charon", "AI Actor setCurrentState", "setCurrentState " + currentState.getClass().getName()); doStateAction(currentState.onEnter(this)); } catch (Exception e) { e.printStackTrace(); } } - public CreatureObject getFollowObject() { + public TangibleObject getFollowObject() { return followObject; } - public void setFollowObject(CreatureObject followObject) { + public void setFollowObject(TangibleObject followObject) { this.followObject = followObject; } @@ -316,23 +363,39 @@ public class AIActor { } public void scheduleMovement() { + // Catch current state BEFORE waiting 500ms for execution, + // as the state could have changed in that time resulting in + // undesired additional movement loops + AIState caughtAIState = currentState; + if (currentState==null) + return; + if (!actorAlive) + return; movementFuture = scheduler.schedule(() -> { try { if (creature==null){ destroyActor(); return; } - doStateAction(currentState.move(AIActor.this)); + if (caughtAIState!=null && currentState!=null){ + if (caughtAIState.getClass().equals(currentState.getClass())) + doStateAction(caughtAIState.move(AIActor.this)); + } } catch (Exception e) { + //System.out.println("Exception in scheduleMovement"); e.printStackTrace(); } }, 500, TimeUnit.MILLISECONDS); } public void scheduleRecovery() { + AIState caughtAIState = currentState; + if (!actorAlive) + return; recoveryFuture = scheduler.schedule(() -> { try { - doStateAction(currentState.recover(AIActor.this)); + if (caughtAIState.getClass().equals(currentState.getClass())) + doStateAction(caughtAIState.recover(AIActor.this)); } catch (Exception e) { e.printStackTrace(); } @@ -345,11 +408,18 @@ public class AIActor { @Handler public void handleDamage(DamageTaken event) { - CreatureObject attacker = event.attacker; + CreatureObject attacker = (CreatureObject)event.attacker; if(damageMap.containsKey(attacker)) damageMap.put(attacker, damageMap.get(attacker) + event.damage); else damageMap.put(attacker, event.damage); + + // Put AI into combat state if it is not yet and damaged + if (!creature.isInCombat()){ + creature.setInCombat(true); + if (this.getHighestDamageDealer()!=null) + addDefender(this.getHighestDamageDealer()); + } } public Map getDamageMap() { @@ -408,7 +478,8 @@ public class AIActor { } switch(result) { - + + case StateResult.DEAD: setCurrentState(new DeathState()); break; @@ -459,17 +530,24 @@ public class AIActor { try { damageMap.clear(); followObject = null; - creature.setAttachment("AI", null); - NGECore.getInstance().objectService.destroyObject(creature); + NGECore.getInstance().objectService.destroyObject(creature); } catch (Exception e) { e.printStackTrace(); } } - }, 2, TimeUnit.MINUTES); + //}, 2, TimeUnit.MINUTES); + }, 10, TimeUnit.SECONDS); } public void destroyActor(){ creature.getEventBus().unsubscribe(this); + if (creature!=null){ + if (despawnFuture!=null){ + despawnFuture.cancel(true); + despawnFuture = null; + } + } + // Make sure to kill all AI helper threads if (aggroCheckTask!=null) aggroCheckTask.cancel(true); @@ -484,11 +562,7 @@ public class AIActor { if (movementFuture!=null){ recoveryFuture.cancel(true); recoveryFuture = null; - } - if (despawnFuture!=null){ - despawnFuture.cancel(true); - despawnFuture = null; - } + } } public void cancelAggro(){ @@ -627,5 +701,100 @@ public class AIActor { Point3D lastPositionBeforeStateChange) { this.lastPositionBeforeStateChange = lastPositionBeforeStateChange; } + + public boolean isPatrolLoop() { + return patrolLoop; + } + + public void setPatrolLoop(boolean patrolLoop) { + this.patrolLoop = patrolLoop; + } + + public TangibleObject getLastTarget() { + return lastTarget; + } + + public void setLastTarget(TangibleObject lastTarget) { + this.lastTarget = lastTarget; + } + + public Point3D getRepositionLocation() { + return repositionLocation; + } + + public void setRepositionLocation(Point3D repositionLocation) { + this.repositionLocation = repositionLocation; + } + + public long getRepositionStartTime() { + return repositionStartTime; + } + + public void setRepositionStartTime(long repositionStartTime) { + this.repositionStartTime = repositionStartTime; + } + + public long getActorID() { + return actorID; + } + + public boolean isActorAlive() { + return actorAlive; + } + + public void setActorAlive(boolean actorAlive) { + this.actorAlive = actorAlive; + } + + public int getProgressionMarker() { + return progressionMarker; + } + + public void setProgressionMarker(int progressionMarker) { + this.progressionMarker = progressionMarker; + } + + public boolean isAIactive() { + return AIactive; + } + + public void setAIactive(boolean aIactive) { + AIactive = aIactive; + } + public void prepareDeletion() { + if(this.creature!=null){ + lastPositionBeforeStateChange = this.creature.getWorldPosition(); + this.creature.getDefendersList().clear(); + this.setFollowObject(null); + } + this.setIntendedPrimaryAIState(new IdleState()); + patrolPoints.clear(); + movementPoints.clear(); + actorAlive = false; // stop moving + AIactive = false; // stop reacting to attacks + } + + public void cloneActor(AIActor oldActor) { + AIactive = oldActor.isAIactive(); + isStalking = oldActor.isStalking(); + patrolPoints = oldActor.getPatrolPoints(); + loiterDestType = oldActor.getLoiterDestType(); + loiterDestination = oldActor.getLoiterDestination(); + minLoiterDist = oldActor.getMinLoiterDist(); + maxLoiterDist = oldActor.getMaxLoiterDist(); + waitState = oldActor.getWaitState(); + waitStartTime = oldActor.getWaitStartTime(); + patrolLoop =oldActor.isPatrolLoop(); + intendedPrimaryAIState = oldActor.getIntendedPrimaryAIState(); + try { + setCurrentState(intendedPrimaryAIState.getClass().newInstance()); + } catch (InstantiationException e) { + System.out.println("Aiactor cloning failed InstantiationException"); + e.printStackTrace(); + } catch (IllegalAccessException e) { + System.out.println("Aiactor cloning failed IllegalAccessException"); + e.printStackTrace(); + } + } } diff --git a/src/services/ai/AIService.java b/src/services/ai/AIService.java index 45ad9279..162b09b1 100644 --- a/src/services/ai/AIService.java +++ b/src/services/ai/AIService.java @@ -21,8 +21,13 @@ ******************************************************************************/ package services.ai; +import java.lang.reflect.Method; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.Random; import java.util.Vector; @@ -33,18 +38,21 @@ import resources.datatables.GcwType; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; import services.ai.states.AIState; import services.ai.states.IdleState; import services.ai.states.LoiterState; import services.ai.states.PatrolState; import engine.resources.objects.SWGObject; import engine.resources.scene.Point3D; +import engine.resources.service.INetworkDispatch; import main.NGECore; public class AIService { @SuppressWarnings("unused") private Vector aiActors = new Vector(); private NGECore core; + private TangibleObject checkerAI = null; public AIService(NGECore core) { this.core = core; @@ -54,6 +62,8 @@ public class AIService { // TODO: implement cell pathfinding, returning straight line for now Vector path = new Vector(); + if (pointA==null || pointB==null) + return path; path.add(pointA); float x = pointB.x - 1 + new Random().nextFloat(); float z = pointB.z - 1 + new Random().nextFloat(); @@ -169,6 +179,13 @@ public class AIService { } } + public void setPatrolLoop(CreatureObject creature, boolean value){ + AIActor actor = (AIActor) creature.getAttachment("AI"); + if (actor==null) + return; + actor.setPatrolLoop(value); + } + public void setPatrol(CreatureObject creature, Vector patrolpoints){ AIActor actor = (AIActor) creature.getAttachment("AI"); if (actor==null) @@ -178,6 +195,8 @@ public class AIService { AIState intendedPrimaryAIState = new PatrolState(); actor.setIntendedPrimaryAIState(intendedPrimaryAIState); actor.setCurrentState(intendedPrimaryAIState); + actor.setCurrentState(intendedPrimaryAIState); + actor.setCurrentState(intendedPrimaryAIState); } public void setPatrol(CreatureObject creature, boolean active){ @@ -209,6 +228,95 @@ public class AIService { actor.setCurrentState(intendedPrimaryAIState); } + public void setCheckAI(TangibleObject checker){ + checkerAI = checker; + } + + public TangibleObject getCheckAI(){ + return this.checkerAI; + } + + public float distanceSquared2D(Point3D p2, Point3D p1){ + return (p2.x - p1.x) * (p2.x - p1.x) + (p2.z - p1.z) * (p2.z - p1.z); + } + + public float distanceSquared(Point3D p2, Point3D p1){ + return (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y) + (p2.z - p1.z) * (p2.z - p1.z); + } + + public void waitForEvent(AIActor actor, INetworkDispatch service, String serviceMethodName, boolean expectedValue, Class nextStateClass){ + + final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + final Future[] wfe = {null}; + wfe[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + Class noParams[] = {}; + Method m = service.getClass().getMethod(serviceMethodName, noParams); + boolean value = (boolean) m.invoke(service); + if (value==expectedValue){ + actor.setCurrentState((AIState)nextStateClass.newInstance()); + System.out.println("condition true waitForEvent! " + nextStateClass.getName()); + Thread.yield(); + wfe[0].cancel(false); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }, 10, 3000, TimeUnit.MILLISECONDS); + } + + public void waitForEvent(AIActor actor, INetworkDispatch service, String serviceMethodName, int expectedValue, Class nextStateClass){ + final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + final Future[] wfe = {null}; + wfe[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + Class noParams[] = {}; + Method m = service.getClass().getMethod(serviceMethodName, noParams); + int number = (int) m.invoke(service); + if (number==expectedValue){ + actor.setCurrentState((AIState)nextStateClass.newInstance()); + Thread.yield(); + wfe[0].cancel(false); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }, 10, 3000, TimeUnit.MILLISECONDS); + } + + // ToDo: Make an overloaded method with params + public void waitForEvent(INetworkDispatch service, String serviceMethodName, Object[] params){ + final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + final Future[] wfe = {null}; + wfe[0] = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + boolean condition = true; + Class noParams[] = {}; + Method m = service.getClass().getMethod(serviceMethodName, noParams); + m.invoke(service); + + if (condition){ + Thread.yield(); + wfe[0].cancel(false); + } + // do something + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 10, 2000, TimeUnit.MILLISECONDS); + } + public void logAI(String logMsg){ if (checkDeveloperIdentity()){ System.err.println("AI-LOG: " + logMsg); diff --git a/src/services/ai/LairActor.java b/src/services/ai/LairActor.java index 1bb1e4b8..ef263b2d 100644 --- a/src/services/ai/LairActor.java +++ b/src/services/ai/LairActor.java @@ -33,6 +33,7 @@ import resources.objects.tangible.TangibleObject; import services.combat.CombatEvents.DamageTaken; import tools.DevLog; +@SuppressWarnings("unused") public class LairActor { private Vector creatures = new Vector(); @@ -86,8 +87,8 @@ public class LairActor { spawnNewCreatures(); for(AIActor ai : creatures) { - ai.addDefender(event.attacker); - event.attacker.addDefender(ai.getCreature()); + ai.addDefender((CreatureObject)event.attacker); + ((CreatureObject)event.attacker).addDefender(ai.getCreature()); } @@ -163,7 +164,6 @@ public class LairActor { } - @SuppressWarnings("unused") private void healLair() { if(lairObject.getConditionDamage() == 0 || creatures.isEmpty()) diff --git a/src/services/ai/TurretAIActor.java b/src/services/ai/TurretAIActor.java new file mode 100644 index 00000000..4773ec34 --- /dev/null +++ b/src/services/ai/TurretAIActor.java @@ -0,0 +1,599 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai; + +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import main.NGECore; +import net.engio.mbassy.listener.Handler; +import engine.clients.Client; +import engine.resources.objects.SWGObject; +import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; +import resources.datatables.Options; +import resources.objects.cell.CellObject; +import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationObject; +import resources.objects.tangible.TangibleObject; +import services.ai.states.TurretAIState; +import services.ai.states.TurretAIState.StateResult; +import services.ai.states.AIState; +import services.ai.states.TurretAttackState; +import services.ai.states.TurretIdleState; +import services.combat.CombatEvents.DamageTaken; +import services.spawn.MobileTemplate; +import tools.DevLog; +import resources.datatables.FactionStatus; + +import java.util.Random; + +@SuppressWarnings("unused") +public class TurretAIActor { + + private TangibleObject creature; + private Point3D spawnPosition; + private volatile TurretAIState currentState; + private TangibleObject followObject; + private Vector movementPoints = new Vector(); + private MobileTemplate mobileTemplate; + private ScheduledExecutorService scheduler; + private Map damageMap = new ConcurrentHashMap(); + private volatile boolean hasReachedPosition; + private long lastAttackTimestamp; + private ScheduledFuture regenTask; + private ScheduledFuture aggroCheckTask; + private ScheduledFuture factionCheckTask; + private boolean isStalking = false; + private byte milkState = 0; + private boolean hasBeenHarvested = false; + private Vector patrolPoints = new Vector(); + private int patrolPointIndex = 0; + private String loiterDestType = "LOITER"; + private Point3D loiterDestination; + private Point3D originPosition; + private float minLoiterDist; + private float maxLoiterDist; + private String waitState = "NO"; + private long waitStartTime = 0L; + private TurretAIState intendedPrimaryTurretAIState; + private Point3D lastPositionBeforeStateChange; + private boolean patrolLoop = true; // default + private ScheduledFuture recoveryFuture; + + + public TurretAIActor(TangibleObject creature, Point3D spawnPosition, ScheduledExecutorService scheduler) { + this.creature = creature; + this.spawnPosition = spawnPosition; + setLastPositionBeforeStateChange(spawnPosition); // just to make sure it's initialized + this.scheduler = scheduler; + creature.getEventBus().subscribe(this); + this.currentState = new TurretIdleState(); + setIntendedPrimaryTurretAIState(this.currentState); // to switch back to after aggro + + if(creature.getOption(Options.AGGRESSIVE)) { + aggroCheckTask = scheduler.scheduleAtFixedRate(() -> { + try { + + if(creature == null || creature.getObservers().isEmpty() || creature.isInCombat() || isStalking) + return; + if (creature.getAttachment("tamed")!=null){ + DevLog.debugoutai(this, "Charon", "Pet AI", "aggroCheckTask tamed==1"); + return; + } + + if (creature.getCustomName().contains("baby")) + DevLog.debugoutai(this, "Charon", "Pet AI", "baby aggroCheckTask should not be here " +creature.getAttachment("tamed")); + + creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 60)).forEach((obj) -> { + if(new Random().nextFloat() <= 0.5 || creature.isInCombat() || isStalking) { + /*if(mobileTemplate.isStalker()) { + setFollowObject((CreatureObject) obj); + setCurrentState(new StalkState()); + } else */ + + if (creature.getAttachment("IsBeingTamed")!=null) + return; + + if (obj instanceof CreatureObject){ + CreatureObject addedObject = (CreatureObject) obj; + if (addedObject.getCalledPet()!=null){ + CreatureObject calledPet = addedObject.getCalledPet(); + if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){ + addDefender(calledPet); + } + } + if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14){ + addDefender(addedObject); + } + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + }, 0, 2000, TimeUnit.MILLISECONDS); + } + if(creature.getFaction().length()>0 || !creature.getOption(Options.AGGRESSIVE)) { + factionCheckTask = scheduler.scheduleAtFixedRate(() -> { + //System.out.println("Turret faction thread"); + try { + + if(creature == null || creature.getFactionStatus()!=FactionStatus.Combatant || creature.getObservers().isEmpty() || creature.isInCombat()) + return; + + creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 60)).forEach((obj) -> { + if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { +// DevLog.debugout("Charon", "TURRET CHECK faction creature ", "added " + creature.getFaction()); +// DevLog.debugout("Charon", "TURRET CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); +// DevLog.debugout("Charon", "TURRET CHECK factionCheckTask", "added " + obj.getCustomName()); +// DevLog.debugout("Charon", "TURRET CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); + if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){ + CreatureObject addedObject = (CreatureObject) obj; + if (addedObject.getCalledPet()!=null){ + CreatureObject calledPet = addedObject.getCalledPet(); + if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){ + addDefender(calledPet); + } + } + if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14 && ! addedObject.getOption(Options.INVULNERABLE)){ + addDefender(addedObject); +// DevLog.debugout("Charon", "TURRET faction creature ", "added " + creature.getFaction()); +// DevLog.debugout("Charon", "TURRET faction obj", "added " + ((TangibleObject)obj).getFaction()); +// DevLog.debugout("Charon", "TURRET factionCheckTask", "added " + obj.getCustomName()); + } + + } + } + }); + + NGECore.getInstance().simulationService.getAllNearNonSameFactionNPCs(60, creature).forEach((obj) -> { + if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { +// DevLog.debugout("Charon", "TURRET CHECK faction creature ", "added " + creature.getFaction()); +// DevLog.debugout("Charon", "TURRET CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); +// DevLog.debugout("Charon", "TURRET CHECK factionCheckTask", "added " + obj.getCustomName()); +// DevLog.debugout("Charon", "TURRET CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); + if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){ + CreatureObject addedObject = (CreatureObject) obj; + if (addedObject.getCalledPet()!=null){ + CreatureObject calledPet = addedObject.getCalledPet(); + if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14 & ! calledPet.getOption(Options.INVULNERABLE)){ + addDefender(calledPet); + } + } + if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14 & ! addedObject.getOption(Options.INVULNERABLE)){ + addDefender(addedObject); +// DevLog.debugout("Charon", "TURRET faction creature ", "added " + creature.getFaction()); +// DevLog.debugout("Charon", "TURRET faction obj", "added " + ((TangibleObject)obj).getFaction()); +// DevLog.debugout("Charon", "TURRET factionCheckTask", "added " + obj.getCustomName()); + } + } + } + }); + + NGECore.getInstance().simulationService.getAllNearNonSameFactionTANOs(60, creature).forEach((obj) -> { + if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { +// DevLog.debugout("Charon", "TANO CHECK faction creature ", "added " + creature.getFaction()); +// DevLog.debugout("Charon", "TANO CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); +// DevLog.debugout("Charon", "TANO CHECK factionCheckTask", "added " + obj.getCustomName()); +// DevLog.debugout("Charon", "TANO CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); + if (obj instanceof TangibleObject && !(obj instanceof CreatureObject) && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){ + TangibleObject addedObject = (TangibleObject) obj; + addDefender(addedObject); + DevLog.debugoutai(this, "Charon", "TANO faction creature ", "added " + creature.getFaction()); + DevLog.debugoutai(this, "Charon", "TANO faction obj", "added " + ((TangibleObject)obj).getFaction()); + DevLog.debugoutai(this, "Charon", "TANO factionCheckTask", "added " + obj.getCustomName()); + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + }, 0, 1000, TimeUnit.MILLISECONDS); + + } + } + + public TangibleObject getCreature() { + return creature; + } + + public void setCreature(CreatureObject creature) { + this.creature = creature; + } + + public Point3D getSpawnPosition() { + return spawnPosition; + } + + public void setSpawnPosition(Point3D spawnPosition) { + this.spawnPosition = spawnPosition; + } + +// public void addDefender(CreatureObject defender) { +// addDefender(defender, false); +// } + public void addDefender(TangibleObject defender) { + addDefender(defender, false); + } + + + public void addDefender(TangibleObject defender, boolean isAssisting) { + creature.addDefender(defender); + if(followObject == null) + setFollowObject(defender); + setCurrentState(new TurretAttackState()); +// if(!isAssisting) { +// NGECore.getInstance().simulationService.get(creature.getPlanet(), creature.getWorldPosition().x, creature.getWorldPosition().z, 38).stream().filter((obj) -> +// obj instanceof CreatureObject && +// obj.getAttachment("AI") != null && +// ((TurretAIActor) obj.getAttachment("AI")).getMobileTemplate().getSocialGroup().equals(getMobileTemplate().getSocialGroup()) && +// obj.inRange(creature.getWorldPosition(), ((TurretAIActor) obj.getAttachment("AI")).getMobileTemplate().getAssistRange()) +// ).forEach((obj) -> ((TurretAIActor) obj.getAttachment("AI")).addDefender(defender, true)); +// } + } + + public void removeDefender(TangibleObject defender) { + creature.removeDefender(defender); + damageMap.remove(defender); + defender.removeDefender(creature); + if(followObject == defender) { + setFollowObject(getHighestDamageDealer()); + if(creature.getDefendersList().size() == 0) + setCurrentState(new TurretIdleState()); + } + } + + public CreatureObject getHighestDamageDealer() { + CreatureObject highestDamageDealer = null; + highestDamageDealer = damageMap.keySet().stream().max((c1, c2) -> damageMap.get(c1) - damageMap.get(c2)).orElse(null); + // return first defender if no damage has been dealt + if(highestDamageDealer == null) { + for(TangibleObject tangible : creature.getDefendersList().toArray(new TangibleObject[]{})) { + if(tangible instanceof CreatureObject) + return (CreatureObject) tangible; + } + } + return highestDamageDealer; + } + + public TurretAIState getCurrentState() { + return currentState; + } + + public void setCurrentState(TurretAIState currentState) { + try { + if(currentState.getClass() == this.currentState.getClass()) + return; + if(this.currentState != null) + doStateAction(this.currentState.onExit(this)); + this.currentState = currentState; + doStateAction(currentState.onEnter(this)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public TangibleObject getFollowObject() { + return followObject; + } + + public void setFollowObject(TangibleObject followObject) { + this.followObject = followObject; + } + + public Vector getMovementPoints() { + return movementPoints; + } + + public void setMovementPoints(Vector movementPoints) { + this.movementPoints = movementPoints; + } + + public MobileTemplate getMobileTemplate() { + return mobileTemplate; + } + + public void setMobileTemplate(MobileTemplate mobileTemplate) { + this.mobileTemplate = mobileTemplate; + } + + public void scheduleRecovery() { + TurretAIState caughtAIState = currentState; + recoveryFuture = scheduler.schedule(() -> { + try { + if (caughtAIState.getClass().equals(currentState.getClass())) + doStateAction(currentState.recover(TurretAIActor.this)); + } catch (Exception e) { + e.printStackTrace(); + } + }, 2000, TimeUnit.MILLISECONDS); + } + + public void setNextPosition(Point3D position) { + movementPoints.add(0, position); + } + + @Handler + public void handleDamage(DamageTaken event) { + CreatureObject attacker = (CreatureObject)event.attacker; + if(damageMap.containsKey(attacker)) + damageMap.put(attacker, damageMap.get(attacker) + event.damage); + else + damageMap.put(attacker, event.damage); + } + + public Map getDamageMap() { + return damageMap; + } + + public boolean hasReachedPosition() { + return hasReachedPosition; + } + + public void setHasReachedPosition(boolean hasReachedPosition) { + this.hasReachedPosition = hasReachedPosition; + } + + public void faceObject(SWGObject object) { + // Null checks due to a null error at: float direction = + if (object == null) DevLog.debugout("Charon", "AI Actor", "faceObject object is NULL"); + if (creature == null) DevLog.debugout("Charon", "AI Actor", "faceObject creature is NULL"); + if (object.getWorldPosition() == null) DevLog.debugout("Charon", "AI Actor", "faceObject object's position is NULL"); + if (creature.getWorldPosition() == null) DevLog.debugout("Charon", "AI Actor", "faceObject creature's position is NULL"); + + float direction = (float) Math.atan2(object.getWorldPosition().x - creature.getWorldPosition().x, object.getWorldPosition().z - creature.getWorldPosition().z); + if(direction < 0) + direction = (float) (2 * Math.PI + direction); + if(Math.abs(direction - creature.getRadians()) < 0.05) + return; + Quaternion quaternion = new Quaternion((float) Math.cos(direction / 2), 0, (float) Math.sin(direction / 2), 0); + if (quaternion.y < 0.0f && quaternion.w > 0.0f) { + quaternion.y *= -1; + quaternion.w *= -1; + } + if(creature.getContainer() instanceof CellObject) + NGECore.getInstance().simulationService.moveObject(creature, creature.getPosition(), quaternion, creature.getMovementCounter(), 0, (CellObject) creature.getContainer()); + else + NGECore.getInstance().simulationService.moveObject(creature, creature.getPosition(), quaternion, creature.getMovementCounter(), 0, null); + + } + + public long getLastAttackTimestamp() { + return lastAttackTimestamp; + } + + public void setLastAttackTimestamp(long lastAttackTimestamp) { + this.lastAttackTimestamp = lastAttackTimestamp; + } + + public long getTimeSinceLastAttack() { + return System.currentTimeMillis() - getLastAttackTimestamp(); + } + + public void doStateAction(byte result) { + + if (creature==null){ + destroyActor(); + return; + } + + switch(result) { + + case StateResult.DEAD: + destroyActor(); + break; + case StateResult.FINISHED: + case StateResult.UNFINISHED: + return; + case StateResult.IDLE: + setCurrentState(new TurretIdleState()); + return; + + //case StateResult.NONE: + // System.out.println("State action returned error result"); + + } + + } + + public void scheduleDespawn() { + // Sometimes these tasks are null? + + try { + if (aggroCheckTask!=null) + aggroCheckTask.cancel(true); + if (factionCheckTask!=null) + factionCheckTask.cancel(true); + } catch(Exception e) { + + } + + try { + regenTask.cancel(true); + } catch(Exception e) { + + } + + } + + public void destroyActor(){ + creature.getEventBus().unsubscribe(this); + // Make sure to kill all AI helper threads + if (aggroCheckTask!=null) + aggroCheckTask.cancel(true); + if (factionCheckTask!=null) + factionCheckTask.cancel(true); + if (regenTask!=null) + regenTask.cancel(true); + } + + public void cancelAggro(){ + try { + aggroCheckTask.cancel(true); + } catch(Exception e) { + } + } + + public ScheduledFuture getRegenTask() { + return regenTask; + } + + public void setRegenTask(ScheduledFuture regenTask) { + this.regenTask = regenTask; + } + + public boolean isStalking() { + return isStalking; + } + + public void setStalking(boolean isStalking) { + this.isStalking = isStalking; + } + + public byte getMilkState() { + synchronized(creature.getMutex()) { + return milkState; + } + } + + public void setMilkState(byte milkState) { + synchronized(creature.getMutex()) { + this.milkState = milkState; + } + } + + public boolean hasBeenHarvested() { + synchronized(creature.getMutex()) { + return hasBeenHarvested; + } + } + + public void setHasBeenHarvested(boolean hasBeenHarvested) { + synchronized(creature.getMutex()) { + this.hasBeenHarvested = hasBeenHarvested; + } + } + + public void setPatrolPoints(Vector patrolPoints){ + this.patrolPoints = patrolPoints; + //setMovementPoints(patrolPoints); + } + + public int getPatrolPointIndex() { + return patrolPointIndex; + } + + public void setPatrolPointIndex(int patrolPointIndex) { + this.patrolPointIndex = patrolPointIndex; + } + + public Point3D getLoiterDestination() { + return loiterDestination; + } + + public void setLoiterDestination(Point3D loiterDestination) { + this.loiterDestination = loiterDestination; + } + + public Point3D getOriginPosition() { + return originPosition; + } + + public void setOriginPosition(Point3D originPosition) { + this.originPosition = originPosition; + } + + public String getLoiterDestType() { + return loiterDestType; + } + + public void setLoiterDestType(String loiterDestType) { + this.loiterDestType = loiterDestType; + } + + public float getMinLoiterDist() { + return minLoiterDist; + } + + public void setMinLoiterDist(float minLoiterDist) { + this.minLoiterDist = minLoiterDist; + } + + public float getMaxLoiterDist() { + return maxLoiterDist; + } + + public void setMaxLoiterDist(float maxLoiterDist) { + this.maxLoiterDist = maxLoiterDist; + } + + public String getWaitState() { + return waitState; + } + + public void setWaitState(String waitState) { + this.waitState = waitState; + } + + public long getWaitStartTime() { + return waitStartTime; + } + + public void setWaitStartTime(long waitStartTime) { + this.waitStartTime = waitStartTime; + } + + public Vector getPatrolPoints() { + return patrolPoints; + } + + public TurretAIState getIntendedPrimaryTurretAIState() { + return intendedPrimaryTurretAIState; + } + + public void setIntendedPrimaryTurretAIState(TurretAIState intendedPrimaryTurretAIState) { + this.intendedPrimaryTurretAIState = intendedPrimaryTurretAIState; + } + + public Point3D getLastPositionBeforeStateChange() { + return lastPositionBeforeStateChange; + } + + public void setLastPositionBeforeStateChange( + Point3D lastPositionBeforeStateChange) { + this.lastPositionBeforeStateChange = lastPositionBeforeStateChange; + } + + public boolean isPatrolLoop() { + return patrolLoop; + } + + public void setPatrolLoop(boolean patrolLoop) { + this.patrolLoop = patrolLoop; + } + +} diff --git a/src/services/ai/states/AIState.java b/src/services/ai/states/AIState.java index ac25ae37..b1f4a93c 100644 --- a/src/services/ai/states/AIState.java +++ b/src/services/ai/states/AIState.java @@ -27,12 +27,16 @@ import java.util.Vector; import main.NGECore; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; +import engine.resources.service.INetworkDispatch; import resources.common.SpawnPoint; import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; +import tools.DevLog; +@SuppressWarnings("unused") public abstract class AIState { public abstract byte onEnter(AIActor actor) throws Exception; @@ -40,6 +44,11 @@ public abstract class AIState { public abstract byte move(AIActor actor) throws Exception; public abstract byte recover(AIActor actor) throws Exception; + public static long lastExecutionTime = 0L; + public static long stateID = 0L; + public static long autoStateID = 0L; + + public enum StateResult {; // default error state result @@ -54,11 +63,187 @@ public abstract class AIState { public static final byte PATROL = 5; public static final byte LOITER = 6; public static final byte FOLLOW = 7; + public static final byte ATTACK = 8; } public boolean findNewPosition(AIActor actor, float speed, float stopDistance, Point3D newPosition) { + speed *= 0.5; // 2 updates per second + CreatureObject creature = actor.getCreature(); + if (!actor.isActorAlive()) + return false; // Suppress any further movement when actor is destroyed to prevent reappearing + NGECore core = NGECore.getInstance(); + Point3D currentPosition = creature.getPosition(); + Point3D targetPosition = null; + float maxDistance = stopDistance; + boolean finished = false; + float dx, dz, newX = 0, newY = 0, newZ = 0; + Vector movementPoints = actor.getMovementPoints(); + Vector patrolPoints = actor.getPatrolPoints(); + CellObject cell = null; + //while(!finished && movementPoints.size() != 0) { + + if ((!(actor.getCurrentState() instanceof FollowState)) && movementPoints.size() == 0 && patrolPoints.size() == 0) { + DevLog.debugoutai(actor, "Charon", "AI State findnewpos", "Breakout1"); + return false; + } + + if (movementPoints.size() != 0){ + try{ + targetPosition = movementPoints.firstElement(); + } catch (NoSuchElementException e) { + targetPosition = currentPosition; + } + } + + if (actor.getCurrentState().getClass().equals(PatrolState.class)){ + targetPosition = patrolPoints.get(actor.getPatrolPointIndex()); + } + + if (actor.getCurrentState().getClass().equals(WithdrawalState.class)){ + targetPosition = patrolPoints.get(actor.getPatrolPointIndex()); + } + + if (actor.getCurrentState().getClass().equals(FollowState.class)){ + targetPosition = actor.getFollowObject().getWorldPosition(); + } + + Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); + + if (targetPosition==null){ + DevLog.debugoutai(actor, "Charon", "AI State findnewpos", "Breakout2"); + return false; + } + float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition()); + + if(distanceToTarget > stopDistance) { + maxDistance = Math.min(speed, distanceToTarget - stopDistance); + } else { + /* + DevLog.debugoutai(actor, "Charon", "AI State findnewpos", "Breakout3"); + if (actor.getCurrentState().getClass().equals(RetreatState.class)){ + if(actor.getIntendedPrimaryAIState().equals(PatrolState.class)){ + actor.setCurrentState(new PatrolState()); + } + if(actor.getIntendedPrimaryAIState().equals(FollowState.class)){ + actor.setCurrentState(new FollowState()); + } + if(actor.getIntendedPrimaryAIState().equals(LoiterState.class)){ + actor.setCurrentState(new LoiterState()); + } + } + */ + return false; + } + + Point3D oldPosition = null; + float pathDistance = 0; + + + + for(int i = 1; i < path.size() && !finished; i++) { + + Point3D currentPathPosition = path.get(i); + cell = currentPathPosition.getCell(); + + if(oldPosition == null) + oldPosition = path.get(0); + Point3D oldWorldPos = oldPosition.getWorldPosition(); + + pathDistance += oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + if(pathDistance >= maxDistance || i == path.size() - 1 || currentPathPosition.getCell() != creature.getContainer()) { + + finished = true; + + if(movementPoints.size() != 0 && currentPosition.getWorldPosition().getDistance(currentPathPosition.getWorldPosition()) <= stopDistance && cell == creature.getContainer()) { + if(i == path.size() - 1 && movementPoints.size()>0){ + try { + movementPoints.remove(0); + } catch (ArrayIndexOutOfBoundsException ex){} // No idea why a vector with size>0 throws this sometimes + } + finished = false; + } else { + + if(cell == null) + oldPosition = oldPosition.getWorldPosition(); + else { + if(oldPosition.getCell() == null) + oldPosition = core.simulationService.convertPointToModelSpace(oldPosition, cell.getContainer()); + } + + if(pathDistance > maxDistance) { + + //float distance = oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + float distance = NGECore.getInstance().aiService.distanceSquared(oldWorldPos, currentPathPosition.getWorldPosition()); // Ok to use, as distance is not directly used later + float travelDistance = distance - (pathDistance - maxDistance); + // temp fix for melee npcs + travelDistance *= 1.3; + if(travelDistance <= 0) { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } else { + + if(distance > 0) { + dx = currentPathPosition.x - oldPosition.x; + dz = currentPathPosition.z - oldPosition.z; + //float deltaDist = (float) Math.sqrt((dx * dx) + (dz * dz)); + int fullong=0; // Approximation->faster + int halfshort=0; + float tempdx = dx; + float tempdz = dz; + if (tempdx<0) + tempdx*=-1; + if (tempdz<0) + tempdz*=-1; + if(tempdx > tempdz) { + fullong = (int)(tempdx*100); + halfshort = ((int)(tempdz*100)) >> 1; + } else { + fullong = (int)(tempdz*100); + halfshort = ((int)(tempdx*100)) >> 1; + } + float deltaDist = (fullong + halfshort)/100; + + newX = (float) (oldPosition.x + (speed * (dx / deltaDist))); + newZ = (float) (oldPosition.z + (speed * (dz / deltaDist))); + + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } + + } + + if(cell == null) { + float height = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + newY = height; + } else { + newY = currentPathPosition.y; + } + } + } + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + newY = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + } + oldPosition = currentPathPosition; + } + //} + newPosition.x = newX; + newPosition.y = newY; + newPosition.z = newZ; + newPosition.setCell(cell); + + return true; + } + + + public boolean findNewLOSPosition(AIActor actor, float speed, float stopDistance, Point3D newPosition) { + speed *= 0.5; // 2 updates per second CreatureObject creature = actor.getCreature(); NGECore core = NGECore.getInstance(); @@ -94,6 +279,41 @@ public abstract class AIState { Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); + if (targetPosition==null) + return false; + if (actor.getFollowObject()==null) + return false; + + int attempts = 0; + float LOSdistance = targetPosition.getWorldPosition().getDistance(actor.getFollowObject().getWorldPosition()); + Point3D LOSorigin = actor.getFollowObject().getWorldPosition(); + float deltaX = actor.getFollowObject().getWorldPosition().x-targetPosition.getWorldPosition().x; + float deltaZ = actor.getFollowObject().getWorldPosition().z-targetPosition.getWorldPosition().z; + float originAngle = (float) (Math.atan2(deltaX,deltaZ)); + int sign = 0; + while (!core.simulationService.checkLineOfSight(actor.getFollowObject(),targetPosition) && attempts<160){ + + float angle = 0; + if (sign==0){ + angle = originAngle + attempts; + sign = 1; + } else { + angle = originAngle - attempts; + sign = 0; + } + if (actor.getFollowObject() instanceof CreatureObject){ + if (((CreatureObject)actor.getFollowObject()).isPlayer()){ + System.out.println("CORRECTING LOS"); + } + } + + + targetPosition = new Point3D((float) (LOSorigin.x + LOSdistance * Math.cos(angle)), 0, (float) (LOSorigin.z + LOSdistance * Math.sin(angle))); + attempts++; + } + + + float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition()); if(distanceToTarget > stopDistance) { @@ -195,7 +415,7 @@ public abstract class AIState { float maxDistance = stopDistance; boolean finished = false; float dx, dz, newX = 0, newY = 0, newZ = 0; - @SuppressWarnings("unused") Vector movementPoints = actor.getMovementPoints(); + Vector movementPoints = actor.getMovementPoints(); CellObject cell = null; targetPosition = actor.getLoiterDestination(); @@ -421,8 +641,11 @@ public abstract class AIState { actor.setFollowObject(null); return; } - CreatureObject target = actor.getFollowObject(); + TangibleObject target = actor.getFollowObject(); float speed = (float) creature.getRunSpeed(); + if (creature.getAttachment("IsSlowVehicle")!=null){ + speed = (float) creature.getWalkSpeed(); + } float maxDistance = 6; if(creature.getWeaponId() != 0) { WeaponObject weapon = (WeaponObject) core.objectService.getObject(creature.getWeaponId()); @@ -439,7 +662,9 @@ public abstract class AIState { maxDistance = 1; Point3D newPosition = new Point3D(); - boolean foundNewPos = findNewPosition(actor, speed, maxDistance, newPosition); + + boolean foundNewPos = false; + foundNewPos = findNewPosition(actor, speed, maxDistance, newPosition); if(!foundNewPos || (newPosition.x == 0 && newPosition.z == 0)) return; @@ -454,20 +679,72 @@ public abstract class AIState { quaternion.w *= -1; } + core.simulationService.moveObject(creature, newPosition, quaternion, creature.getMovementCounter(), speed, newPosition.getCell()); + } + + public void doReposition(AIActor actor){ + + NGECore core = NGECore.getInstance(); + + CreatureObject creature = actor.getCreature(); + if(creature.getPosture() == 14 || creature.getPosture() == 13) { + actor.setFollowObject(null); + return; + } + TangibleObject target = actor.getLastTarget(); + float speed = (float) creature.getRunSpeed(); + float maxDistance = 6; + if(creature.getWeaponId() != 0) { + WeaponObject weapon = (WeaponObject) core.objectService.getObject(creature.getWeaponId()); + if(weapon != null) + maxDistance = weapon.getMaxRange() - 1; + } else if(creature.getSlottedObject("default_weapon") != null) { + WeaponObject weapon = (WeaponObject) creature.getSlottedObject("default_weapon"); + if(weapon != null) + maxDistance = weapon.getMaxRange() - 1; + } + Point3D currentPosition = creature.getWorldPosition(); + + if(target != null && !core.simulationService.checkLineOfSight(creature, target)) + maxDistance = 1; + + Point3D newPosition = actor.getRepositionLocation(); + + if(newPosition.x == 0 && newPosition.z == 0) + return; + + Point3D newWorldPos = newPosition.getWorldPosition(); + float direction = (float) Math.atan2(newWorldPos.x - currentPosition.x, newWorldPos.z - currentPosition.z); + if(direction < 0) + direction = (float) (2 * Math.PI + direction); + Quaternion quaternion = new Quaternion((float) Math.cos(direction / 2), 0, (float) Math.sin(direction / 2), 0); + if (quaternion.y < 0.0f && quaternion.w > 0.0f) { + quaternion.y *= -1; + quaternion.w *= -1; + } + core.simulationService.moveObject(creature, newPosition, quaternion, creature.getMovementCounter(), speed, newPosition.getCell()); } public void doPatrol(AIActor actor) { //NGECore.getInstance().aiService.logAI("AI STATE doPatrol"); + NGECore core = NGECore.getInstance(); CreatureObject creature = actor.getCreature(); + if(creature.getPosture() == 14 || creature.getPosture() == 13) { actor.setFollowObject(null); return; } - CreatureObject target = actor.getFollowObject(); + + if (creature.isInCombat()){ + return; + } + + + TangibleObject target = actor.getFollowObject(); float speed = (float) creature.getWalkSpeed(); float maxDistance = 6; if(creature.getWeaponId() != 0) { @@ -481,24 +758,162 @@ public abstract class AIState { } Point3D currentPosition = creature.getWorldPosition(); - if(target != null && !core.simulationService.checkLineOfSight(creature, target)) - maxDistance = 1; +// if(target != null && !core.simulationService.checkLineOfSight(creature, target)) +// maxDistance = 1; // Manage Patrol points maxDistance = 1; + if (actor.getPatrolPoints().size()==0) + return; Point3D currentDestination = actor.getPatrolPoints().get(actor.getPatrolPointIndex()); - //System.out.println("currentPosition.getDistance2D(currentDestination)<1) " + currentPosition.getDistance2D(currentDestination)); - if (currentPosition.getDistance2D(currentDestination)<2){ + //System.out.println("currentPosition.getDistance2D(currentDestination) " + currentPosition.getDistance2D(currentDestination)); + if (NGECore.getInstance().aiService.distanceSquared2D(currentPosition, currentDestination)<4){ + //if (currentPosition.getDistance2D(currentDestination)<4){ if (actor.getPatrolPointIndex()=4 && NGECore.getInstance().invasionService.getInvasionPhase()!=3){ + actor.setAIactive(false); // switch off auto-target-recognition to counter lag + actor.setCurrentState(new IdleState()); + //System.out.println("AI switched off!"); + return; + } + + //actor.setCurrentState(new IdleState()); + // Wait state() Since this state does not require move,recover and all that its simple task + + //NGECore.getInstance().aiService.waitForEvent(actor, NGECore.getInstance().invasionService, "isDefendingGeneralAlive", false, WithdrawalState.class); + + return; // Last Patrol point reached and no loop + } } } Point3D newPosition = new Point3D(); boolean foundNewPos = findNewPosition(actor, speed, maxDistance, newPosition); - + + + + + if(!foundNewPos || (newPosition.x == 0 && newPosition.z == 0)) + return; + + Point3D newWorldPos = newPosition.getWorldPosition(); + float direction = (float) Math.atan2(newWorldPos.x - currentPosition.x, newWorldPos.z - currentPosition.z); + if(direction < 0) + direction = (float) (2 * Math.PI + direction); + Quaternion quaternion = new Quaternion((float) Math.cos(direction / 2), 0, (float) Math.sin(direction / 2), 0); + if (quaternion.y < 0.0f && quaternion.w > 0.0f) { + quaternion.y *= -1; + quaternion.w *= -1; + } + +// if (newPosition.getCell()==null) +// System.out.println("newPosition.getCell() is NULL"); + try{ + core.simulationService.moveObject(creature, newPosition, quaternion, creature.getMovementCounter(), speed, newPosition.getCell()); + } catch (NullPointerException e) { + // Just to identify what exactly is null here +// if (creature==null) +// System.out.print("creature==null" ); +// if (newPosition==null) +// System.out.print("newPosition==null" ); +// if (quaternion==null) +// System.out.print("quaternion==null" ); +// if (newPosition.getCell()==null) +// System.out.print("newPosition.getCell()==null" ); +// +// System.out.print("creature.getMovementCounter() " + creature.getMovementCounter()); + } + + } + + public void doWithdrawal(AIActor actor) { + //NGECore.getInstance().aiService.logAI("AI STATE doPatrol"); + + NGECore core = NGECore.getInstance(); + + if(actor==null) + return; + CreatureObject creature = actor.getCreature(); + if(creature==null) + return; + +// if (creature.getPlanet().getName().equals("talus") && creature.getTemplate().contains("stormtrooper")){ +// System.out.println("actor " + actor.getActorID() + " stateID " + stateID + " creatureID"+ creature.getObjectID()+ " TIMEDIFF: " + (System.currentTimeMillis()-lastExecutionTime)); +// lastExecutionTime = System.currentTimeMillis(); +// } + if(creature.getPosture() == 14 || creature.getPosture() == 13) { + actor.setFollowObject(null); + return; + } + +// if (creature.isInCombat()){ +// return; +// } + + + TangibleObject target = actor.getFollowObject(); + float speed = (float) creature.getWalkSpeed(); + float maxDistance = 6; + if(creature.getWeaponId() != 0) { + WeaponObject weapon = (WeaponObject) core.objectService.getObject(creature.getWeaponId()); + if(weapon != null) + maxDistance = weapon.getMaxRange() - 1; + } else if(creature.getSlottedObject("default_weapon") != null) { + WeaponObject weapon = (WeaponObject) creature.getSlottedObject("default_weapon"); + if(weapon != null) + maxDistance = weapon.getMaxRange() - 1; + } + Point3D currentPosition = creature.getWorldPosition(); + +// if(target != null && !core.simulationService.checkLineOfSight(creature, target)) +// maxDistance = 1; + + // Manage Patrol points + maxDistance = 1; + if (actor.getPatrolPoints().size()==0) + return; + if (actor.getPatrolPointIndex()<=0) + actor.setPatrolPointIndex(0); + Point3D currentDestination = actor.getPatrolPoints().get(actor.getPatrolPointIndex()); + //System.out.println("currentPosition.getDistance2D(currentDestination) " + currentPosition.getDistance2D(currentDestination)); + if (NGECore.getInstance().aiService.distanceSquared2D(currentPosition, currentDestination)<4){ + //if (currentPosition.getDistance2D(currentDestination)<4){ + if (actor.getPatrolPointIndex()>0){ + actor.setPatrolPointIndex(actor.getPatrolPointIndex()-1); + } else { + if (actor!=null) + actor.destroyActor(); + if (creature!=null){ + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + core.objectService.destroyObject(creature.getObjectID()); + } + return; // First Patrol point reached + } + } + + Point3D newPosition = new Point3D(); + boolean foundNewPos = findNewPosition(actor, speed, maxDistance, newPosition); + + + + if(!foundNewPos || (newPosition.x == 0 && newPosition.z == 0)) return; @@ -541,7 +956,7 @@ public abstract class AIState { actor.setFollowObject(null); return; } - CreatureObject target = actor.getFollowObject(); + TangibleObject target = actor.getFollowObject(); float speed = (float) creature.getWalkSpeed(); float maxDistance = 6; if(creature.getWeaponId() != 0) { @@ -654,7 +1069,6 @@ public abstract class AIState { } - @SuppressWarnings("unused") public void doFollow(AIActor actor) { //NGECore.getInstance().aiService.logAI("AI STATE doPatrol"); NGECore core = NGECore.getInstance(); @@ -664,7 +1078,7 @@ public abstract class AIState { actor.setFollowObject(null); return; } - CreatureObject target = actor.getFollowObject(); + TangibleObject target = actor.getFollowObject(); float speed = (float) creature.getRunSpeed(); float maxDistance = 6; if(creature.getWeaponId() != 0) { diff --git a/src/services/ai/states/AttackState.java b/src/services/ai/states/AttackState.java index 98dc5b7c..203b490b 100644 --- a/src/services/ai/states/AttackState.java +++ b/src/services/ai/states/AttackState.java @@ -24,8 +24,10 @@ package services.ai.states; import java.util.Random; import java.util.Vector; +import engine.resources.scene.Point3D; import main.NGECore; import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; import tools.DevLog; @@ -34,12 +36,20 @@ public class AttackState extends AIState { @Override public byte onEnter(AIActor actor) { - DevLog.debugout("Charon", "AI Attack State", "onEnter"); + DevLog.debugoutai(actor, "Charon", "AI Attack State", "onEnter"); + CreatureObject creature = actor.getCreature(); + if (creature == null || actor==null) + return StateResult.DEAD; + DevLog.debugoutai(actor, "Charon", "AI Attack State", "creature.isInCombat() " + creature.isInCombat()); + DevLog.debugoutai(actor, "Charon", "AI Attack State", "creature.getDefendersList().size() == 0 " + (creature.getDefendersList().size() == 0)); + DevLog.debugoutai(actor, "Charon", "AI Attack State", "actor.getFollowObject() == null " + (actor.getFollowObject() == null)); if(creature.getPosture() == 14) return StateResult.DEAD; if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) return StateResult.FINISHED; + creature.setLookAtTarget(actor.getFollowObject().getObjectID()); + creature.setIntendedTarget(actor.getFollowObject().getObjectID()); actor.scheduleMovement(); actor.scheduleRecovery(); return StateResult.UNFINISHED; @@ -52,22 +62,35 @@ public class AttackState extends AIState { actor.getCreature().setLookAtTarget(0); actor.getCreature().setIntendedTarget(0); actor.setFollowObject(null); - DevLog.debugout("Charon", "AI Attack State", "onExit"); + DevLog.debugoutai(actor, "Charon", "AI Attack State", "onExit"); return StateResult.FINISHED; } @Override public byte move(AIActor actor) { CreatureObject creature = actor.getCreature(); + if (creature==null) + return StateResult.FINISHED; + if(creature.getPosture() == 14) return StateResult.DEAD; actor.getMovementPoints().clear(); if(actor.getFollowObject() != null) { - if(actor.getSpawnPosition().getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), actor.getFollowObject().getWorldPosition())) { - actor.removeDefender(actor.getFollowObject()); - //actor.scheduleMovement(); - return StateResult.UNFINISHED; - } + Point3D checkPosition = actor.getSpawnPosition().getWorldPosition(); // IdleState default + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + checkPosition = creature.getWorldPosition(); + if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) + checkPosition = creature.getWorldPosition(); + + try { + if(checkPosition.getDistance(creature.getWorldPosition()) > 128 || NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), actor.getFollowObject().getWorldPosition())) { + actor.removeDefender(actor.getFollowObject()); + //actor.scheduleMovement(); + //return StateResult.UNFINISHED; + return StateResult.FINISHED; + } + } catch (Exception ex){} // When the followobject turns becomes null inside the if scope an npe can occur + float maxDistance = 0; if(creature.getWeaponId() != 0) { WeaponObject weapon = (WeaponObject) NGECore.getInstance().objectService.getObject(creature.getWeaponId()); @@ -79,19 +102,24 @@ public class AttackState extends AIState { maxDistance = weapon.getMaxRange() - 1; } try{ - if(actor.getFollowObject().getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) + if(actor.getFollowObject().getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance){ actor.setNextPosition(actor.getFollowObject().getPosition()); - else { + // find los pos + } else { //recover(actor); actor.faceObject(actor.getFollowObject()); actor.scheduleMovement(); return StateResult.UNFINISHED; } } catch (Exception e){ - DevLog.debugout("Charon", "AI Attack State Exception move method", "actor " + actor); - DevLog.debugout("Charon", "AI Attack State Exception move method", "actor.getFollowObject() " + actor.getFollowObject()); - DevLog.debugout("Charon", "AI Attack State Exception move method", "actor.getFollowObject().getWorldPosition() " + actor.getFollowObject().getWorldPosition()); - DevLog.debugout("Charon", "AI Attack State Exception move method", "creature.getWorldPosition() " + creature.getWorldPosition()); + if (actor!=null) + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "actor " + actor); + if (actor.getFollowObject()!=null) + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "actor.getFollowObject() " + actor.getFollowObject()); + if (actor.getFollowObject()!=null) + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "actor.getFollowObject().getWorldPosition() " + actor.getFollowObject().getWorldPosition()); + if (creature!=null) + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "creature.getWorldPosition() " + creature.getWorldPosition()); } } @@ -105,6 +133,7 @@ public class AttackState extends AIState { @Override public byte recover(AIActor actor) { CreatureObject creature = actor.getCreature(); + DevLog.debugoutai(actor, "Charon", "AI Attack Recover State", creature.getTemplate()); float maxDistance = 0; WeaponObject weapon = null; if(creature.getWeaponId() != 0) { @@ -119,55 +148,102 @@ public class AttackState extends AIState { if(weapon == null) return StateResult.FINISHED; if(actor.getTimeSinceLastAttack() < weapon.getAttackSpeed() * 1000) { - //actor.scheduleRecovery(); + actor.scheduleRecovery(); return StateResult.UNFINISHED; } NGECore core = NGECore.getInstance(); if(creature.getPosture() == 14) return StateResult.DEAD; - if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) - { - if (creature.getLookAtTarget() != 0) - creature.setLookAtTarget(0); - if (creature.getIntendedTarget() != 0) - creature.setIntendedTarget(0); - actor.setFollowObject(null); - actor.setCurrentState(new RetreatState()); - return StateResult.FINISHED; - } - CreatureObject target = actor.getFollowObject(); + + + TangibleObject target = actor.getFollowObject(); if(target != actor.getHighestDamageDealer() && actor.getHighestDamageDealer() != null) { actor.setFollowObject(actor.getHighestDamageDealer()); target = actor.getFollowObject(); } if(target == null) { - DevLog.debugout("Charon", "AI Attack State", "null target"); + DevLog.debugoutai(actor, "Charon", "AI Attack State", "null target"); actor.scheduleRecovery(); return StateResult.UNFINISHED; } - if(target.getPosture() == 13 || target.getPosture() == 14 || target.isInStealth()) { - - actor.setFollowObject(actor.getHighestDamageDealer()); - target = actor.getFollowObject(); - if(target == null) - { - if (creature.getLookAtTarget() != 0) - creature.setLookAtTarget(0); - if (creature.getIntendedTarget() != 0) - creature.setIntendedTarget(0); - - } - actor.setFollowObject(null); - actor.removeDefender(target); - - actor.setCurrentState(new RetreatState()); + + // If AI has no LOS to target, reposition it + if (!core.simulationService.checkLineOfSight(target,creature)){ + actor.setLastTarget(target); + actor.setCurrentState(new RepositionState()); return StateResult.FINISHED; } - if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || target.getPosture() == 13 || target.getPosture() == 14) { - actor.removeDefender(target); - actor.scheduleRecovery(); - return StateResult.UNFINISHED; + + + if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) + { + +// System.out.println("creature.isInCombat() " + creature.isInCombat()); +// System.out.println("creature.getDefendersList().size() " + creature.getDefendersList().size()); +// System.out.println("actor.getFollowObject() " + actor.getFollowObject()); + creature.setLookAtTarget(0); + creature.setIntendedTarget(0); + actor.setFollowObject(null); + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); + else { + actor.setCurrentState(new RetreatState()); + } + return StateResult.FINISHED; } + + + if (target instanceof CreatureObject){ + CreatureObject targetCreature = (CreatureObject) target; + if(targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14 || targetCreature.isInStealth()) { + + actor.setFollowObject(actor.getHighestDamageDealer()); + target = (CreatureObject) actor.getFollowObject(); + if(target == null) + { + creature.setLookAtTarget(0); + creature.setIntendedTarget(0); + + } + actor.setFollowObject(null); + actor.removeDefender(target); + + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); + else { + actor.setCurrentState(new RetreatState()); + } + return StateResult.FINISHED; + } + if(targetCreature.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14) { + actor.removeDefender(target); + actor.scheduleRecovery(); + return StateResult.UNFINISHED; + } + } else { + TangibleObject targetObject = (TangibleObject) target; + if((targetObject.getConditionDamage()>=targetObject.getMaximumCondition())) { + + actor.setFollowObject(actor.getHighestDamageDealer()); + target = (CreatureObject) actor.getFollowObject(); + if(target == null) + { + creature.setLookAtTarget(0); + creature.setIntendedTarget(0); + + } + actor.setFollowObject(null); + actor.removeDefender(target); + + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); + else { + actor.setCurrentState(new RetreatState()); + } + return StateResult.FINISHED; + } + } + if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) { actor.scheduleRecovery(); return StateResult.UNFINISHED; @@ -179,17 +255,18 @@ public class AttackState extends AIState { // Pet // if (creature.getOwnerId()>0) // attacks = creature.getSpecialAttacks(); - if (creature.getLookAtTarget() != target.getObjectId()) - creature.setLookAtTarget(target.getObjectId()); - if (creature.getIntendedTarget() != target.getObjectId()) - creature.setIntendedTarget(target.getObjectId()); - if(attacks.size() == 0) { + creature.setLookAtTarget(target.getObjectId()); + creature.setIntendedTarget(target.getObjectId()); + + if (attacks==null) { + //if(attacks.size() == 0) { core.commandService.callCommand(creature, actor.getMobileTemplate().getDefaultAttack(), target, ""); } else { Random rand = new Random(); if(rand.nextFloat() <= 0.33f) { - core.commandService.callCommand(creature, attacks.get(rand.nextInt(attacks.size())), target, ""); + if(attacks.size() > 0) + core.commandService.callCommand(creature, attacks.get(rand.nextInt(attacks.size())), target, ""); } else { core.commandService.callCommand(creature, actor.getMobileTemplate().getDefaultAttack(), target, ""); } diff --git a/src/services/ai/states/DeathState.java b/src/services/ai/states/DeathState.java index ed38449f..bb49a07e 100644 --- a/src/services/ai/states/DeathState.java +++ b/src/services/ai/states/DeathState.java @@ -33,16 +33,20 @@ public class DeathState extends AIState { public byte onEnter(AIActor actor) { NGECore.getInstance().aiService.awardExperience(actor); NGECore.getInstance().aiService.awardGcw(actor); + actor.setActorAlive(false); actor.getCreature().setAttachment("radial_filename", "npc/corpse"); //NGECore.getInstance().scriptService.callScript("scripts/radial/npc/corpse", "", "createRadial", NGECore.getInstance(), actor.getCreature().getKiller(), actor.getCreature(), new Vector()); actor.scheduleDespawn(); - CreatureObject killer = (CreatureObject)actor.getCreature().getKiller(); - if (killer==null) - killer = actor.getHighestDamageDealer(); - actor.getCreature().setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); - NGECore.getInstance().lootService.DropLoot(killer,(TangibleObject)(actor.getCreature())); - actor.destroyActor(); // to prevent standing up right after death + if (actor.getCreature().getKiller() instanceof CreatureObject){ + CreatureObject killer = (CreatureObject)actor.getCreature().getKiller(); + if (killer==null) + killer = actor.getHighestDamageDealer(); + actor.getCreature().setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); + if (killer.isPlayer()) // No point to do this for NPCs + NGECore.getInstance().lootService.DropLoot(killer,(TangibleObject)(actor.getCreature())); + } + //actor.destroyActor(); // to prevent standing up right after death return 0; } diff --git a/src/services/ai/states/PatrolState.java b/src/services/ai/states/PatrolState.java index 2a571391..72cb9b27 100644 --- a/src/services/ai/states/PatrolState.java +++ b/src/services/ai/states/PatrolState.java @@ -21,16 +21,22 @@ ******************************************************************************/ package services.ai.states; -import main.NGECore; import resources.objects.creature.CreatureObject; import services.ai.AIActor; +import tools.DevLog; public class PatrolState extends AIState { - + + private boolean locked = false; + + public PatrolState(){ + stateID = autoStateID++; + } + @Override public byte onEnter(AIActor actor) { - // TODO Auto-generated method stub - NGECore.getInstance().aiService.logAI("PATROL ENTERED!"); + + DevLog.debugoutai(actor, "Charon", "AI PatrolState", "PATROL ENTERED!"); CreatureObject creature = actor.getCreature(); if(creature.getPosture() == 14) return StateResult.DEAD; @@ -41,27 +47,37 @@ public class PatrolState extends AIState { @Override public byte onExit(AIActor actor) { - // TODO Auto-generated method stub - NGECore.getInstance().aiService.logAI("EXITING PATROL STATE"); + DevLog.debugoutai(actor, "Charon", "AI PatrolState", "EXITING PATROL STATE!"); actor.setLastPositionBeforeStateChange(actor.getCreature().getWorldPosition()); - return 0; + locked = true; + return StateResult.FINISHED; } @Override public byte move(AIActor actor) { - // TODO Auto-generated method stub - //System.out.println("move in patrolState"); + DevLog.debugoutai(actor, "Charon", "AI PatrolState", "PATROL MOVE!"); + if (locked){ + System.out.println("PatrolState locked!"); + return StateResult.FINISHED; + } + CreatureObject creature = actor.getCreature(); + if(creature.isInCombat()){ + //System.out.println("PatrolState locking!"); + locked = true; + return StateResult.FINISHED; + } doPatrol(actor); -// if (actor.getCreature().getPlanet().getName().equals("dathomir")) -// NGECore.getInstance().aiService.logAI("WalkingSpeed " + actor.getCreature().getWalkSpeed()); actor.scheduleMovement(); return StateResult.UNFINISHED; } @Override public byte recover(AIActor actor) { - // TODO Auto-generated method stub - return 0; + if (actor.getFollowObject()!=null) + System.out.println("recover follow object is not null"); + if (actor.getFollowObject()!=null) + System.out.println("recover follow object is not null"); + return StateResult.UNFINISHED; } } diff --git a/src/services/ai/states/RepositionState.java b/src/services/ai/states/RepositionState.java new file mode 100644 index 00000000..f2452abc --- /dev/null +++ b/src/services/ai/states/RepositionState.java @@ -0,0 +1,163 @@ +package services.ai.states; + +import main.NGECore; +import engine.resources.scene.Point3D; +import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; +import services.ai.AIActor; +import tools.DevLog; + +/** + * @author Charon + */ + +public class RepositionState extends AIState{ + + int prog = 10; + + @Override + public byte onEnter(AIActor actor) { + DevLog.debugoutai(actor, "Charon", "AI RepositionState", "onEnter"); + CreatureObject creature = actor.getCreature(); + Point3D creaturePosition = creature.getWorldPosition(); + + TangibleObject target = actor.getLastTarget(); +// Point3D LOSorigin = targetPosition; +// float deltaX = LOSorigin.x-creaturePosition.x; +// float deltaZ = LOSorigin.z-creaturePosition.z; +// float originAngle = (float) (Math.atan2(deltaX,deltaZ)); + Point3D scanPosition = creaturePosition; + TangibleObject tempObject = new TangibleObject(); // LOS overload for pos and creature does not work correctly + tempObject.setPosition(scanPosition); + boolean breakout = false; + boolean foundPos = false; + actor.setProgressionMarker(1); + long repositionCalculationStart = System.currentTimeMillis(); // Limit time this is calculated to prevent deadloops + while (!NGECore.getInstance().simulationService.checkLineOfSight(target,scanPosition) && !breakout || System.currentTimeMillis()>repositionCalculationStart+2000){ + // Quick, light-weight way to get the AI into a firing LOS position + // ToDo: Check if the Quadnode at the LOS position contains a structure + // Required: Add according method to Quadtree.java + + boolean abortCondition = false; + for (int x=1;x<50 && !abortCondition;x=x+1){ + if (NGECore.getInstance().simulationService.checkLineOfSight(target,new Point3D(creaturePosition.x+x,creaturePosition.y,creaturePosition.z)) && !NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), creaturePosition.x+x, creaturePosition.z)){ + scanPosition = new Point3D(creaturePosition.x+x,creaturePosition.y,creaturePosition.z); + abortCondition = true; + } + } + for (int x=-1;x>-50 && !abortCondition;x=x-1){ + if (NGECore.getInstance().simulationService.checkLineOfSight(target,new Point3D(creaturePosition.x+x,creaturePosition.y,creaturePosition.z)) && !NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), creaturePosition.x+x, creaturePosition.z)){ + scanPosition = new Point3D(creaturePosition.x+x,creaturePosition.y,creaturePosition.z); + abortCondition = true; + } + } + for (int z=1;z<50 && !abortCondition;z=z+1){ + if (NGECore.getInstance().simulationService.checkLineOfSight(target,new Point3D(creaturePosition.x,creaturePosition.y,creaturePosition.z+z)) && !NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), creaturePosition.x, creaturePosition.z+z)){ + scanPosition = new Point3D(creaturePosition.x,creaturePosition.y,creaturePosition.z+z); + abortCondition = true; + } + } + for (int z=-1;z>-50 && !abortCondition;z=z-1){ + if (NGECore.getInstance().simulationService.checkLineOfSight(target,new Point3D(creaturePosition.x,creaturePosition.y,creaturePosition.z+z)) && !NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), creaturePosition.x, creaturePosition.z+z)){ + scanPosition = new Point3D(creaturePosition.x,creaturePosition.y,creaturePosition.z+z); + abortCondition = true; + } + } + actor.setProgressionMarker(2); + + if (!NGECore.getInstance().simulationService.checkLineOfSight(target,scanPosition)){ + foundPos=true; + } + +// else +// System.out.println("LOS found"); +// + breakout=true; + } + actor.setProgressionMarker(3); + if (foundPos){ + actor.setRepositionLocation(scanPosition); + actor.setRepositionStartTime(System.currentTimeMillis()); + } else { + float positionY = NGECore.getInstance().terrainService.getHeight(target.getPlanetId(), target.getPosition().x, target.getPosition().z); + actor.setRepositionLocation(new Point3D(target.getWorldPosition().x,positionY,target.getWorldPosition().z)); + actor.setRepositionStartTime(System.currentTimeMillis()+5000); // give it more time + } + + actor.scheduleMovement(); + return StateResult.UNFINISHED; + } + + @Override + public byte onExit(AIActor actor) { + // TODO Auto-generated method stub + actor.setProgressionMarker(9); + TangibleObject followObject = actor.getFollowObject(); + if (followObject==null) + return StateResult.FINISHED; + + if (followObject instanceof CreatureObject) + if (((CreatureObject) followObject).getPosture()==14 || ((CreatureObject) followObject).getPosture()==13) + actor.setFollowObject(null); + + if (! (followObject instanceof CreatureObject)) + if(followObject.getConditionDamage()>=followObject.getMaximumCondition()) + actor.setFollowObject(null); + + DevLog.debugoutai(actor, "Charon", "AI RepositionState", "exit"); + + return StateResult.FINISHED; + } + + @Override + public byte move(AIActor actor) { + DevLog.debugoutai(actor, "Charon", "AI RepositionState", "move"); + actor.setProgressionMarker(prog++); + Point3D newPosition = actor.getRepositionLocation(); + TangibleObject target = actor.getLastTarget(); + if (target==null){ + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); + else { + actor.setCurrentState(new RetreatState()); + } + return StateResult.FINISHED; + } + + if (target instanceof CreatureObject) + if (((CreatureObject) target).getPosture()==14 || ((CreatureObject) target).getPosture()==13){ + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); + else { + actor.setCurrentState(new RetreatState()); + } + return StateResult.FINISHED; + } + + if (! (target instanceof CreatureObject)) + if(target.getConditionDamage()>=target.getMaximumCondition()){ + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); + else { + actor.setCurrentState(new RetreatState()); + } + return StateResult.FINISHED; + } + + if (newPosition.getDistance2D(target.getWorldPosition())<0.5 || System.currentTimeMillis()>actor.getRepositionStartTime()+5000){ + actor.addDefender(target); + actor.setCurrentState(new AttackState()); + return StateResult.FINISHED; + } + + doReposition(actor); + actor.scheduleMovement(); + return StateResult.UNFINISHED; + } + + @Override + public byte recover(AIActor actor) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/src/services/ai/states/RetreatState.java b/src/services/ai/states/RetreatState.java index b94684fe..f2515724 100644 --- a/src/services/ai/states/RetreatState.java +++ b/src/services/ai/states/RetreatState.java @@ -25,9 +25,13 @@ import main.NGECore; import engine.resources.scene.Point3D; import resources.objects.creature.CreatureObject; import services.ai.AIActor; +import tools.DevLog; public class RetreatState extends AIState { - + + private long retreatStartTime = 0L; + private Point3D retreatStartPos = null; + @Override public byte onEnter(AIActor actor) { /*synchronized(actor.getDamageMap()) { @@ -35,8 +39,11 @@ public class RetreatState extends AIState { actor.removeDefender(defender); } }*/ - NGECore.getInstance().aiService.logAI("RetreatState ENTER "); - + DevLog.debugoutai(actor, "Charon", "AI RetreatState", "RetreatState ENTER!"); + CreatureObject creature = actor.getCreature(); + if (creature.getPosture()==13 || creature.getPosture()==14) + return StateResult.FINISHED; + creature.setInCombat(false); if (actor.getCreature().getOwnerId()>0){ CreatureObject owner = (CreatureObject) NGECore.getInstance().objectService.getObject(actor.getCreature().getOwnerId()); actor.setFollowObject(owner); @@ -44,6 +51,9 @@ public class RetreatState extends AIState { return StateResult.FINISHED; } else actor.setFollowObject(null); + + retreatStartTime = System.currentTimeMillis(); + retreatStartPos = creature.getWorldPosition(); actor.scheduleMovement(); return StateResult.UNFINISHED; } @@ -52,16 +62,20 @@ public class RetreatState extends AIState { public byte onExit(AIActor actor) { // TODO Auto-generated method stub //actor.setCurrentState(actor.getIntendedPrimaryAIState()); + DevLog.debugoutai(actor, "Charon", "AI RetreatState", "RetreatState EXIT!"); return StateResult.FINISHED; } @Override public byte move(AIActor actor) { - + DevLog.debugoutai(actor, "Charon", "AI RetreatState", "RetreatState MOVE!"); Point3D retreatPosition = actor.getSpawnPosition(); if (actor.getIntendedPrimaryAIState() instanceof PatrolState) retreatPosition = actor.getLastPositionBeforeStateChange(); + CreatureObject creature = actor.getCreature(); + if (creature.getPosture()==13 || creature.getPosture()==14) + return StateResult.FINISHED; actor.setNextPosition(retreatPosition); actor.getMovementPoints().clear(); actor.getMovementPoints().add(retreatPosition); @@ -71,19 +85,49 @@ public class RetreatState extends AIState { return StateResult.FOLLOW; if(actor.getCreature().getWorldPosition().getDistance(retreatPosition) > 5) { - //NGECore.getInstance().aiService.logAI("RetreatState ENTER move if case dist " + actor.getCreature().getWorldPosition().getDistance(retreatPosition)); actor.scheduleMovement(); } else { - //NGECore.getInstance().aiService.logAI("RetreatState ENTER move else case"); + if (actor.getIntendedPrimaryAIState().getClass().equals(IdleState.class)) - return StateResult.IDLE; + actor.setCurrentState(new IdleState()); if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) - return StateResult.PATROL; + actor.setCurrentState(new PatrolState()); if (actor.getIntendedPrimaryAIState().getClass().equals(LoiterState.class)) - return StateResult.LOITER; + actor.setCurrentState(new LoiterState()); if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) - return StateResult.FOLLOW; + actor.setCurrentState(new FollowState()); + + return StateResult.FINISHED; } + + if(System.currentTimeMillis()> retreatStartTime + 5000 && creature.getWorldPosition().getDistance2D(retreatStartPos)<1.5){ + // Actor is locked in retreat state, get back to intended state + if (actor.getIntendedPrimaryAIState().getClass().equals(IdleState.class)) + actor.setCurrentState(new IdleState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new PatrolState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(LoiterState.class)) + actor.setCurrentState(new LoiterState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) + actor.setCurrentState(new FollowState()); + + return StateResult.FINISHED; + } + + if(System.currentTimeMillis()> retreatStartTime + 40000){ + // Actor is locked in retreat state, get back to intended state after 40s, no matter what + if (actor.getIntendedPrimaryAIState().getClass().equals(IdleState.class)) + actor.setCurrentState(new IdleState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new PatrolState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(LoiterState.class)) + actor.setCurrentState(new LoiterState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) + actor.setCurrentState(new FollowState()); + + return StateResult.FINISHED; + } + return StateResult.UNFINISHED; } diff --git a/src/services/ai/states/TurretAIState.java b/src/services/ai/states/TurretAIState.java new file mode 100644 index 00000000..2c6e89c7 --- /dev/null +++ b/src/services/ai/states/TurretAIState.java @@ -0,0 +1,415 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +import java.util.NoSuchElementException; +import java.util.Vector; +import main.NGECore; +import engine.resources.scene.Point3D; +import resources.objects.cell.CellObject; +import resources.objects.tangible.TangibleObject; +import services.ai.TurretAIActor; + +public abstract class TurretAIState { + + public abstract byte onEnter(TurretAIActor actor) throws Exception; + public abstract byte onExit(TurretAIActor actor) throws Exception; + public abstract byte move(TurretAIActor actor) throws Exception; + public abstract byte recover(TurretAIActor actor) throws Exception; + + public enum StateResult {; + + // default error state result + public static final byte NONE = 0; + // finished with state + public static final byte FINISHED = 1; + // unfinished with state, call recover() + public static final byte UNFINISHED = 2; + public static final byte DEAD = 3; + // for deaggro or idling + public static final byte IDLE = 4; + public static final byte PATROL = 5; + public static final byte LOITER = 6; + public static final byte FOLLOW = 7; + + } + + public boolean findNewPosition(TurretAIActor actor, float speed, float stopDistance, Point3D newPosition) { + + speed *= 0.5; // 2 updates per second + TangibleObject creature = actor.getCreature(); + NGECore core = NGECore.getInstance(); + Point3D currentPosition = creature.getPosition(); + Point3D targetPosition = null; + float maxDistance = stopDistance; + boolean finished = false; + float dx, dz, newX = 0, newY = 0, newZ = 0; + Vector movementPoints = actor.getMovementPoints(); + //Vector patrolPoints = actor.getPatrolPoints(); + CellObject cell = null; + //while(!finished && movementPoints.size() != 0) { + + + + if (movementPoints.size() != 0){ + try{ + targetPosition = movementPoints.firstElement(); + } catch (NoSuchElementException e) { + targetPosition = currentPosition; + } + } + + + Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); + + float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition()); + + if(distanceToTarget > stopDistance) { + maxDistance = Math.min(speed, distanceToTarget - stopDistance); + } else { + return false; + } + + Point3D oldPosition = null; + float pathDistance = 0; + + + + for(int i = 1; i < path.size() && !finished; i++) { + + Point3D currentPathPosition = path.get(i); + cell = currentPathPosition.getCell(); + + if(oldPosition == null) + oldPosition = path.get(0); + Point3D oldWorldPos = oldPosition.getWorldPosition(); + + pathDistance += oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + if(pathDistance >= maxDistance || i == path.size() - 1 || currentPathPosition.getCell() != creature.getContainer()) { + + finished = true; + + if(movementPoints.size() != 0 && currentPosition.getWorldPosition().getDistance(currentPathPosition.getWorldPosition()) <= stopDistance && cell == creature.getContainer()) { + if(i == path.size() - 1) + movementPoints.remove(0); + finished = false; + } else { + + if(cell == null) + oldPosition = oldPosition.getWorldPosition(); + else { + if(oldPosition.getCell() == null) + oldPosition = core.simulationService.convertPointToModelSpace(oldPosition, cell.getContainer()); + } + + if(pathDistance > maxDistance) { + + float distance = oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + float travelDistance = distance - (pathDistance - maxDistance); + // temp fix for melee npcs + travelDistance *= 1.3; + if(travelDistance <= 0) { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } else { + + if(distance > 0) { + dx = currentPathPosition.x - oldPosition.x; + dz = currentPathPosition.z - oldPosition.z; + float deltaDist = (float) Math.sqrt((dx * dx) + (dz * dz)); + newX = (float) (oldPosition.x + (speed * (dx / deltaDist))); + newZ = (float) (oldPosition.z + (speed * (dz / deltaDist))); + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } + + } + + if(cell == null) { + float height = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + newY = height; + } else { + newY = currentPathPosition.y; + } + } + } + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + newY = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + } + oldPosition = currentPathPosition; + } + //} + newPosition.x = newX; + newPosition.y = newY; + newPosition.z = newZ; + newPosition.setCell(cell); + + return true; + } + + + public boolean findNewLoiterPosition(TurretAIActor actor, float speed, float stopDistance, Point3D newPosition) { + + speed *= 0.5; // 2 updates per second + TangibleObject creature = actor.getCreature(); + NGECore core = NGECore.getInstance(); + Point3D currentPosition = creature.getPosition(); + Point3D targetPosition = null; + float maxDistance = stopDistance; + boolean finished = false; + float dx, dz, newX = 0, newY = 0, newZ = 0; + //Vector movementPoints = actor.getMovementPoints(); + CellObject cell = null; + + targetPosition = actor.getLoiterDestination(); + + Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); + + float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition()); + + if(distanceToTarget > stopDistance) { + maxDistance = Math.min(speed, distanceToTarget - stopDistance); + } else { + return false; + } + + Point3D oldPosition = null; + float pathDistance = 0; + + for(int i = 1; i < path.size() && !finished; i++) { + + Point3D currentPathPosition = path.get(i); + cell = currentPathPosition.getCell(); + + if(oldPosition == null) + oldPosition = path.get(0); + Point3D oldWorldPos = oldPosition.getWorldPosition(); + + pathDistance += oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + if(pathDistance >= maxDistance || i == path.size() - 1 || currentPathPosition.getCell() != creature.getContainer()) { + + finished = true; + + if(currentPosition.getWorldPosition().getDistance(currentPathPosition.getWorldPosition()) <= stopDistance && cell == creature.getContainer()) { +// if(i == path.size() - 1) +// movementPoints.remove(0); + finished = false; + } else { + + if(cell == null) + oldPosition = oldPosition.getWorldPosition(); + else { + if(oldPosition.getCell() == null) + oldPosition = core.simulationService.convertPointToModelSpace(oldPosition, cell.getContainer()); + } + + if(pathDistance > maxDistance) { + + float distance = oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + float travelDistance = distance - (pathDistance - maxDistance); + // temp fix for melee npcs + travelDistance *= 1.3; + if(travelDistance <= 0) { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } else { + + if(distance > 0) { + dx = currentPathPosition.x - oldPosition.x; + dz = currentPathPosition.z - oldPosition.z; + float deltaDist = (float) Math.sqrt((dx * dx) + (dz * dz)); + newX = (float) (oldPosition.x + (speed * (dx / deltaDist))); + newZ = (float) (oldPosition.z + (speed * (dz / deltaDist))); + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } + + } + + if(cell == null) { + float height = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + newY = height; + } else { + newY = currentPathPosition.y; + } + } + } + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + newY = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + } + oldPosition = currentPathPosition; + } + + newPosition.x = newX; + newPosition.y = newY; + newPosition.z = newZ; + newPosition.setCell(cell); + + return true; + } + + public boolean findNewFollowPosition(TurretAIActor actor, float speed, float stopDistance, Point3D newPosition) { + + speed *= 0.5; // 2 updates per second + TangibleObject creature = actor.getCreature(); + NGECore core = NGECore.getInstance(); + Point3D currentPosition = creature.getPosition(); + Point3D targetPosition = null; + float maxDistance = stopDistance; + boolean finished = false; + float dx, dz, newX = 0, newY = 0, newZ = 0; + Vector movementPoints = actor.getMovementPoints(); + Vector patrolPoints = actor.getPatrolPoints(); + CellObject cell = null; + //while(!finished && movementPoints.size() != 0) { + + + if (movementPoints.size() != 0) + targetPosition = movementPoints.firstElement(); + + if (actor.getCurrentState().getClass().equals(PatrolState.class)){ + targetPosition = patrolPoints.get(actor.getPatrolPointIndex()); + } + + if (actor.getCurrentState().getClass().equals(FollowState.class)){ + targetPosition = actor.getFollowObject().getWorldPosition(); + } + + Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); + + float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition()); + + if(distanceToTarget > stopDistance) { + maxDistance = Math.min(speed, distanceToTarget - stopDistance); + } else { + return false; + } + + Point3D oldPosition = null; + float pathDistance = 0; + + + + for(int i = 1; i < path.size() && !finished; i++) { + + Point3D currentPathPosition = path.get(i); + cell = currentPathPosition.getCell(); + + if(oldPosition == null) + oldPosition = path.get(0); + Point3D oldWorldPos = oldPosition.getWorldPosition(); + + pathDistance += oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + if(pathDistance >= maxDistance || i == path.size() - 1 || currentPathPosition.getCell() != creature.getContainer()) { + + finished = true; + + if(movementPoints.size() != 0 && currentPosition.getWorldPosition().getDistance(currentPathPosition.getWorldPosition()) <= stopDistance && cell == creature.getContainer()) { + if(i == path.size() - 1) + movementPoints.remove(0); + finished = false; + } else { + + if(cell == null) + oldPosition = oldPosition.getWorldPosition(); + else { + if(oldPosition.getCell() == null) + oldPosition = core.simulationService.convertPointToModelSpace(oldPosition, cell.getContainer()); + } + + if(pathDistance > maxDistance) { + + float distance = oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + float travelDistance = distance - (pathDistance - maxDistance); + // temp fix for melee npcs + travelDistance *= 1.3; + if(travelDistance <= 0) { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } else { + + if(distance > 0) { + dx = currentPathPosition.x - oldPosition.x; + dz = currentPathPosition.z - oldPosition.z; + float deltaDist = (float) Math.sqrt((dx * dx) + (dz * dz)); + newX = (float) (oldPosition.x + (speed * (dx / deltaDist))); + newZ = (float) (oldPosition.z + (speed * (dz / deltaDist))); + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } + + } + + if(cell == null) { + float height = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + newY = height; + } else { + newY = currentPathPosition.y; + } + } + } + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + newY = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + } + oldPosition = currentPathPosition; + } + //} + newPosition.x = newX; + newPosition.y = newY; + newPosition.z = newZ; + newPosition.setCell(cell); + + return true; + } + + public void doMove(TurretAIActor actor) { + + } + + public void doPatrol(TurretAIActor actor) { + + } + + public void doLoiter(TurretAIActor actor) { + + } + + public void doFollow(TurretAIActor actor) { + + } + +} diff --git a/src/services/ai/states/TurretAttackState.java b/src/services/ai/states/TurretAttackState.java new file mode 100644 index 00000000..29ac49ca --- /dev/null +++ b/src/services/ai/states/TurretAttackState.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +import main.NGECore; +import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; +import resources.objects.weapon.WeaponObject; +import services.ai.TurretAIActor; +import tools.DevLog; + +public class TurretAttackState extends TurretAIState { + + @Override + public byte onEnter(TurretAIActor actor) { + DevLog.debugoutai(actor, "Charon", "Turret AI Attack State", "onEnter"); + TangibleObject creature = actor.getCreature(); + +// DevLog.debugout("Charon", "Turret AI Attack State", "onEnter creature.getConditionDamage() " + creature.getConditionDamage()); +// DevLog.debugout("Charon", "Turret AI Attack State", "onEnter creature.getMaximumCondition() " + creature.getMaximumCondition()); + + if(creature.getConditionDamage()>=creature.getMaximumCondition()){ + return StateResult.DEAD; + } + if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) + return StateResult.FINISHED; + +// DevLog.debugout("Charon", "Turret AI Attack State", "onEnter creature.getDefendersList().size() " + creature.getDefendersList().size()); +// DevLog.debugout("Charon", "Turret AI Attack State", "onEnter actor.getFollowObject() " + actor.getFollowObject()); + if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) + return StateResult.FINISHED; + + actor.scheduleRecovery(); + return StateResult.UNFINISHED; + } + + @Override + public byte onExit(TurretAIActor actor) { + // TODO Auto-generated method stub + DevLog.debugoutai(actor, "Charon", "Turret AI Attack State", "onExit"); + + TangibleObject creature = actor.getCreature(); + creature.setInCombat(false); +// actor.getCreature().setLookAtTarget(0); +// actor.getCreature().setIntendedTarget(0); + actor.setFollowObject(null); +// DevLog.debugout("Charon", "AI Attack State", "onExit"); + return StateResult.FINISHED; + } + + @Override + public byte move(TurretAIActor actor) { + + return StateResult.FINISHED; + + } + + @Override + public byte recover(TurretAIActor actor) { + DevLog.debugoutai(actor, "Charon", "TurretAI Attack State", "recover "); + TangibleObject creature = actor.getCreature(); + if (creature==null) + return StateResult.FINISHED; + + float maxDistance = 0; + WeaponObject weapon = null; + //weapon = (WeaponObject) creature.getSlottedObject("default_weapon"); + + long weaponID = (long) creature.getAttachment("TurretWeapon"); + weapon = (WeaponObject) NGECore.getInstance().objectService.getObject(weaponID); + //DevLog.debugout("Charon", "AI Attack State", "weapontype " + weapon.getTemplate()); + if(weapon == null) + return StateResult.FINISHED; + + + maxDistance = weapon.getMaxRange() - 1; + + + // Here is place for turret cooldown + if(actor.getTimeSinceLastAttack() < weapon.getAttackSpeed() * 1000) { + actor.scheduleRecovery(); + return StateResult.UNFINISHED; + } + NGECore core = NGECore.getInstance(); + + if (core.aiService.getCheckAI()!=null){ +// if (core.aiService.getCheckAI().getObjectID()==creature.getObjectID()) +// System.out.println("creature.getConditionDamage() " + creature.getConditionDamage() + " creature.getMaximumCondition() " + creature.getMaximumCondition()); + } + + if(creature.getConditionDamage()>=creature.getMaximumCondition()){ +// String effectFile = "clienteffect/npe_explosion_02.cef"; +// Vector allPlayers = core.simulationService.getAllNearPlayers(300, creature.getPlanet(), creature.getPosition()); +// for (CreatureObject player : allPlayers){ +// PlayClientEffectLocMessage cEffMsg = new PlayClientEffectLocMessage(effectFile, creature.getPlanet().getName(), creature.getPosition()); +// player.getClient().getSession().write(cEffMsg.serialize()); +// } + return StateResult.DEAD; + } + + if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) + { +// creature.setLookAtTarget(0); +// creature.setIntendedTarget(0); + actor.setFollowObject(null); + actor.setCurrentState(new TurretIdleState()); + return StateResult.FINISHED; + } + + TangibleObject target = actor.getFollowObject(); + if(target != actor.getHighestDamageDealer() && actor.getHighestDamageDealer() != null) { + actor.setFollowObject(actor.getHighestDamageDealer()); + target = actor.getFollowObject(); + } + if(target == null) { + DevLog.debugoutai(actor, "Charon", "AI Attack State", "null target"); + actor.scheduleRecovery(); + return StateResult.UNFINISHED; + } + + if (target instanceof CreatureObject){ + CreatureObject targetCreature = (CreatureObject) target; + if(targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14 || targetCreature.isInStealth()) { + + actor.setFollowObject(actor.getHighestDamageDealer()); + target = (CreatureObject) actor.getFollowObject(); + if(target == null) + { +// creature.setLookAtTarget(0); //Is only accessible from CreatureObject, not TANO +// creature.setIntendedTarget(0); + + } + actor.setFollowObject(null); + actor.removeDefender(target); + + actor.setCurrentState(new TurretIdleState()); + return StateResult.FINISHED; + } + if(targetCreature.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance || targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14) { + actor.removeDefender(target); +// actor.scheduleRecovery(); +// return StateResult.UNFINISHED; +// String effectFile = "clienteffect/npe_explosion_02.cef"; +// Vector allPlayers = core.simulationService.getAllNearPlayers(300, creature.getPlanet(), creature.getPosition()); +// for (CreatureObject player : allPlayers){ +// PlayClientEffectLocMessage cEffMsg = new PlayClientEffectLocMessage(effectFile, creature.getPlanet().getName(), creature.getPosition()); +// player.getClient().getSession().write(cEffMsg.serialize()); +// } + return StateResult.FINISHED; + } + } + +// DevLog.debugout("Charon", "AI Attack State", "prior to attacks dist " + target.getWorldPosition().getDistance(creature.getWorldPosition())); +// DevLog.debugout("Charon", "AI Attack State", "prior to attacks maxDistance " + maxDistance); + + if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) { + actor.removeDefender(target); +// actor.scheduleRecovery(); +// return StateResult.UNFINISHED; + + return StateResult.FINISHED; + } + //actor.faceObject(target); + core.commandService.callCommand(creature, "rangedShot", target, ""); + + actor.setLastAttackTimestamp(System.currentTimeMillis()); + actor.scheduleRecovery(); + return StateResult.UNFINISHED; + } + +} diff --git a/src/services/ai/states/TurretIdleState.java b/src/services/ai/states/TurretIdleState.java new file mode 100644 index 00000000..e6543a66 --- /dev/null +++ b/src/services/ai/states/TurretIdleState.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.ai.states; + +import services.ai.TurretAIActor; +import tools.DevLog; + +public class TurretIdleState extends TurretAIState { + + @Override + public byte onEnter(TurretAIActor actor) { + // TODO Auto-generated method stub + DevLog.debugoutai(actor,"Charon", "Turret AI Idle State", "onEnter"); + //return 0; + return StateResult.UNFINISHED; + } + + @Override + public byte onExit(TurretAIActor actor) { + // TODO Auto-generated method stub + DevLog.debugoutai(actor,"Charon", "Turret AI Idle State", "onExit"); + //return 0; + return StateResult.FINISHED; + } + + @Override + public byte move(TurretAIActor actor) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public byte recover(TurretAIActor actor) { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/services/ai/states/WithdrawalState.java b/src/services/ai/states/WithdrawalState.java new file mode 100644 index 00000000..2f343107 --- /dev/null +++ b/src/services/ai/states/WithdrawalState.java @@ -0,0 +1,66 @@ +package services.ai.states; + +import resources.datatables.Options; +import resources.objects.creature.CreatureObject; +import services.ai.AIActor; +import tools.DevLog; + +public class WithdrawalState extends AIState { +private boolean locked = false; + + + @Override + public byte onEnter(AIActor actor) { + + DevLog.debugoutai(actor, "Charon", "AI WithdrawalState", "WITHDRAWAL ENTERED!"); + CreatureObject creature = actor.getCreature(); + if (creature==null) + return 0; + creature.setOptions(Options.INVULNERABLE, true); + if(creature.getPosture() == 14) + return StateResult.DEAD; + actor.setPatrolPointIndex(actor.getPatrolPointIndex()-1); + actor.scheduleMovement(); + actor.scheduleRecovery(); + return StateResult.UNFINISHED; + } + + @Override + public byte onExit(AIActor actor) { + DevLog.debugoutai(actor, "Charon", "AI WithdrawalState", "EXITING WITHDRAWAL STATE!"); + + return StateResult.FINISHED; + } + + @Override + public byte move(AIActor actor) { + DevLog.debugoutai(actor, "Charon", "AI WithdrawalState", "WITHDRAWAL MOVE!"); + if (locked){ + System.out.println("WITHDRAWAL locked!"); + return StateResult.FINISHED; + } + if (actor==null) + return StateResult.FINISHED; + CreatureObject creature = actor.getCreature(); + if (creature==null) + return StateResult.FINISHED; + +// if(creature.isInCombat()){ +// //System.out.println("PatrolState locking!"); +// locked = true; +// return StateResult.FINISHED; +// } + doWithdrawal(actor); + actor.scheduleMovement(); + return StateResult.UNFINISHED; + } + + @Override + public byte recover(AIActor actor) { + if (actor.getFollowObject()!=null) + System.out.println("recover follow object is not null"); + if (actor.getFollowObject()!=null) + System.out.println("recover follow object is not null"); + return StateResult.UNFINISHED; + } +} diff --git a/src/services/combat/CombatEvents.java b/src/services/combat/CombatEvents.java index 3dc20ee0..e0e1bbf9 100644 --- a/src/services/combat/CombatEvents.java +++ b/src/services/combat/CombatEvents.java @@ -21,14 +21,14 @@ ******************************************************************************/ package services.combat; -import resources.objects.creature.CreatureObject; import engine.resources.common.Event; +import engine.resources.objects.SWGObject; public class CombatEvents implements Event { public class DamageTaken implements Event { - public CreatureObject attacker; + public SWGObject attacker; public int damage; } diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index 21eec82c..beb6d6c0 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -54,12 +54,14 @@ import resources.datatables.Elemental; import resources.datatables.Posture; import resources.datatables.WeaponType; import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationObject; import resources.objects.mission.MissionObject; import resources.objects.player.PlayerObject; import resources.objects.tangible.TangibleObject; import resources.objects.waypoint.WaypointObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; +import services.ai.TurretAIActor; import services.combat.CombatEvents.DamageTaken; import services.command.CombatCommand; import services.sui.SUIService.MessageBoxType; @@ -240,6 +242,148 @@ public class CombatService implements INetworkDispatch { } } } + + public void doCombatForInstallation(final InstallationObject attacker, final TangibleObject target, final WeaponObject weapon, final CombatCommand command, final int actionCounter) { + if(target instanceof CreatureObject) if(((CreatureObject) target).getPosture() == Posture.Incapacitated || ((CreatureObject) target).getPosture() == Posture.Dead) return; + + boolean success = true; + +// if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptCombat(attacker, target)) +// success = false; + +// if(success && !applySpecialCost(attacker, weapon, command)) +// success = false; + + if(!success) { + IoSession session = attacker.getClient().getSession(); + CommandEnqueueRemove commandRemove = new CommandEnqueueRemove(attacker.getObjectId(), actionCounter); + session.write(new ObjControllerMessage(0x0B, commandRemove).serialize()); + StartTask startTask = new StartTask(actionCounter, attacker.getObjectID(), command.getCommandCRC(), CRC.StringtoCRC(command.getCooldownGroup()), -1); + session.write(new ObjControllerMessage(0x0B, startTask).serialize()); + return; + } + + //final Point3D targetPos = target.getPosition(); + //final SWGObject targetParent = target.getContainer(); + + if(command.getDelayAttackParticle().length() > 0 || command.getInitialAttackDelay() > -1) { + + if(command.getInitialAttackDelay() > 0) { + + if(command.getDelayAttackParticle().length() > 0) + target.notifyObservers(new PlayClientEffectLocMessage(command.getDelayAttackParticle(), target.getPlanet().getName(), target.getWorldPosition()), true); + + try { + Thread.sleep((long) command.getInitialAttackDelay() * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + + } else if(command.getInitialAttackDelay() <= 0 && command.getDelayAttackInterval() > 0 && command.getDelayAttackLoops() <= 1) { + + try { + Thread.sleep((long) command.getDelayAttackInterval() * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if(command.getDelayAttackParticle().length() > 0) + target.notifyObservers(new PlayClientEffectLocMessage(command.getDelayAttackParticle(), target.getPlanet().getName(), target.getWorldPosition()), true); + + } + + if(command.getDelayAttackLoops() > 1) { + final ScheduledFuture task = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + if(command.getDelayAttackParticle().length() > 0) + target.notifyObservers(new PlayClientEffectLocMessage(command.getDelayAttackParticle(), target.getPlanet().getName(), target.getWorldPosition()), true); + + if(command.getAttackType() == 1) + doSingleTargetCombatForInstallation(attacker, target, weapon, command, actionCounter); + //else if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3) + //doAreaCombat(attacker, targetPos, weapon, command, actionCounter, targetParent); + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 0, (long) (command.getDelayAttackInterval() * 1000), TimeUnit.MILLISECONDS); + + scheduler.schedule(new Runnable() { + + @Override + public void run() { + try { + task.cancel(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, (long) ((command.getDelayAttackInterval() * 1000) * command.getDelayAttackLoops()), TimeUnit.MILLISECONDS); + + return; + + } else { + if(command.getAttackType() == 1) + doSingleTargetCombatForInstallation(attacker, target, weapon, command, actionCounter); + //else if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3) + //doAreaCombat(attacker, targetPos, weapon, command, actionCounter, targetParent); + } + + } else { + + if(command.getAttackType() == 1) + doSingleTargetCombatForInstallation(attacker, target, weapon, command, actionCounter); + //else if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3) + //doAreaCombat(attacker, target, weapon, command, actionCounter); + + } + + if(target instanceof CreatureObject) + { + CreatureObject creature = (CreatureObject)target; + if(creature.getPosture() == Posture.Incapacitated || creature.getPosture() == Posture.Dead) + { + for (TangibleObject defender : new ArrayList(creature.getDefendersList())) + { + defender.removeDefender(creature); + creature.removeDefender(defender); + } + + if(((CreatureObject) target).getPlayerObject() == null) + { + target.setKiller(attacker); + + scheduler.schedule(new Runnable() + { + @Override + public void run() + { + try { + core.objectService.destroyObject(target); + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 2, TimeUnit.MINUTES); + } + } + } + else if(target instanceof TangibleObject) + { + if(target.getConditionDamage() == target.getMaximumCondition()) + { + for(TangibleObject defender : target.getDefendersList()) defender.removeDefender(target); + core.objectService.destroyObject(target); + } + } + } private void doAreaCombat(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { if(target instanceof CreatureObject) { @@ -313,6 +457,24 @@ public class CombatService implements INetworkDispatch { } + private void doSingleTargetCombatForInstallation(InstallationObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { + if(target instanceof CreatureObject) { + doSingleTargetCombatForInstallation(attacker, (CreatureObject) target, weapon, command, actionCounter); + return; + } + + float damage = calculateDamageForInstallation(attacker, target, weapon, command); + + if(damage > 0) + applyDamageForInstallation(attacker, target, (int) damage); + + sendCombatPacketsForInstallation(attacker, target, weapon, command, actionCounter, damage, 0, HitType.HIT); + + if(FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py")) + core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "run", core, attacker, target, damage); + + } + private void applyDamage(CreatureObject attacker, TangibleObject target, int damage) { target.setConditionDamage(target.getConditionDamage() + damage); @@ -321,6 +483,39 @@ public class CombatService implements INetworkDispatch { core.mountService.damage((CreatureObject) target); } + if (target instanceof CreatureObject){ + CreatureObject targetCreature = (CreatureObject)target; + if (targetCreature.getCalledPet()!=null) { + AIActor petActor = (AIActor) targetCreature.getCalledPet().getAttachment("AI"); + if (petActor!=null){ + petActor.addDefender(attacker); + DevLog.debugoutai(petActor, "Charon", "Pet AI", "applyDamage addDefender"); + } + } + + if (!targetCreature.isInCombat()){ + //targetCreature.setInCombat(true); + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugoutai(targetActor, "Charon", "CombatService AI", "applyDamage addDefender 2"); + } + } + + DamageTaken event = events.new DamageTaken(); + event.attacker = attacker; + event.damage = damage; + target.getEventBus().publish(event); + attacker.setTefTime(300000); + } + + private void applyDamageForInstallation(InstallationObject attacker, TangibleObject target, int damage) { + + target.setConditionDamage(target.getConditionDamage() + damage); + + if (target.getOption(Options.MOUNT)) { + core.mountService.damage((CreatureObject) target); + } + if (target instanceof CreatureObject){ CreatureObject targetCreature = (CreatureObject)target; if (targetCreature.getCalledPet()!=null) { @@ -330,15 +525,133 @@ public class CombatService implements INetworkDispatch { DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); } } + + if (!targetCreature.isInCombat()){ + //targetCreature.setInCombat(true); + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugout("Charon", "CombatService AI", "applyDamage addDefender 2"); + } } DamageTaken event = events.new DamageTaken(); event.attacker = attacker; event.damage = damage; target.getEventBus().publish(event); - System.out.println("APPLY DAMAGE2"); - attacker.setTefTime(300000); + //attacker.setTefTime(300000); } + + private void applyDamageForInstallation(InstallationObject attacker, CreatureObject target, int damage) { + + if(target.getHealth() - damage <= 0 && target.getSlottedObject("ghost") != null) { + + if(target.hasBuff("incapWeaken")) { + + //AIActor aiActor = (AIActor)attacker.getAttachment("AI"); + + deathblowPlayerFromInstallation(attacker, target); + return; + } + + + + if (attacker.getAttachment("AI") instanceof AIActor){ + AIActor aiActor = (AIActor)attacker.getAttachment("AI"); + if (aiActor.getMobileTemplate().isDeathblow()){ + deathblowPlayerFromInstallation(attacker, target); + return; + } + } + if (attacker.getAttachment("AI") instanceof TurretAIActor){ + deathblowPlayerFromInstallation(attacker, target); // turrets always db + return; + + } + + synchronized(target.getMutex()) { + if (core.mountService.isMounted(target)) { + core.mountService.dismount(target, (CreatureObject) target.getContainer()); + } + + target.setHealth(1); + target.setPosture(Posture.Incapacitated); + target.setTurnRadius(0); + target.setSpeedMultiplierBase(0); + + } + + ScheduledFuture incapTask = scheduler.schedule(() -> { + + synchronized(target.getMutex()) { + try { + if(target.getPosture() != 13) + return; + + target.setPosture(Posture.Upright); + target.setTurnRadius(1); + target.setSpeedMultiplierBase(1); + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, target.getIncapTimer(), TimeUnit.SECONDS); + target.setIncapTask(incapTask); + core.buffService.addBuffToCreature(target, "incapWeaken", target); + if(target.getSlottedObject("ghost") != null && attacker.getSlottedObject("ghost") != null) { + target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_incap", "TT", attacker.getCustomName()), DisplayType.Broadcast); + //attacker.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_target_incap", "TT", target.getCustomName()), DisplayType.Broadcast); + } else {target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_incap", "TT", "@" + attacker.getStfFilename() + ":" + attacker.getStfName()), DisplayType.Broadcast); } + return; + } else if(target.getHealth() - damage <= 0 && target.getAttachment("AI") != null) { + synchronized(target.getMutex()) { + target.setHealth(0); + target.setPosture(Posture.Dead); + } + attacker.removeDefender(target); + target.removeDefender(attacker); + return; + } + synchronized(target.getMutex()) { + target.setHealth(target.getHealth() - damage); + } + + + if (target instanceof CreatureObject){ + CreatureObject targetCreature = (CreatureObject)target; + if (targetCreature.getCalledPet()!=null) { + AIActor petActor = (AIActor) targetCreature.getCalledPet().getAttachment("AI"); + if (petActor!=null){ + petActor.addDefender(attacker); + DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); + } + } + + if (!targetCreature.isInCombat()){ + //targetCreature.setInCombat(true); + if (targetCreature.getAttachment("AI") instanceof AIActor){ + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugoutai(targetActor, "Charon", "CombatService AI", "applyDamage addDefender 2"); + } + if (targetCreature.getAttachment("AI") instanceof TurretAIActor){ + TurretAIActor targetActor = (TurretAIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugoutai(targetActor, "Charon", "CombatService AI", "applyDamage addDefender 2"); + } + } + } + + + if (target.getPosture()!=13){ + DamageTaken event = events.new DamageTaken(); + event.attacker = attacker; + event.damage = damage; + target.getEventBus().publish(event); + } + } + + private void doAreaCombat(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { @@ -455,11 +768,39 @@ public class CombatService implements INetworkDispatch { sendCombatPackets(attacker, target, weapon, command, actionCounter, damage, 0, HitType.HIT); } + + private void doSingleTargetCombatForInstallation(InstallationObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { + + float damage = calculateDamageForInstallation(attacker, target, weapon, command); + if(damage > 0) { + damage *= 1.5f; + int damageBeforeArmor = (int) damage; + damage *= 0.99; + int armorAbsorbed = (int) (damageBeforeArmor - damage); + + if(damage > 0) + applyDamageForInstallation(attacker, target, (int) damage); + + sendCombatPacketsForInstallation(attacker, target, weapon, command, actionCounter, damage, armorAbsorbed, HitType.CRITICAL); + + if(FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py")) + core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "run", core, attacker, target, damage); + + return; + } + } private void sendCombatPackets(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter, float damage, int armorAbsorbed, int hitType) { - String animationStr = command.getRandomAnimation(weapon); + String animationStr = command.getRandomAnimation(weapon); // choosing turretShot as default attack, results in a zero length string + if (weapon.getTemplate().contains("atst_ranged")) + animationStr="fire_1_single_light"; + CombatAction combatAction = new CombatAction(CRC.StringtoCRC(animationStr), attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); + +// int turret_fire = 0xD334C0B8; // 0xA7595B4E +// CombatAction combatAction = new CombatAction(turret_fire, attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); +// ObjControllerMessage objController = new ObjControllerMessage(0x1B, combatAction); attacker.notifyObserversInRange(objController, true, 125); CombatSpam combatSpam = new CombatSpam(attacker.getObjectID(), target.getObjectID(), weapon.getObjectID(), (int) damage, armorAbsorbed, hitType); @@ -485,6 +826,21 @@ public class CombatService implements INetworkDispatch { } + private void sendCombatPacketsForInstallation(InstallationObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter, float damage, int armorAbsorbed, int hitType) { + + //String animationStr = command.getRandomAnimation(weapon); + int turret_fire = 0xD334C0B8; // 0xA7595B4E + //CombatAction combatAction = new CombatAction(CRC.StringtoCRC(animationStr), attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); + CombatAction combatAction = new CombatAction(turret_fire, attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); + ObjControllerMessage objController = new ObjControllerMessage(0x1B, combatAction); + attacker.notifyObserversInRange(objController, true, 125); + CombatSpam combatSpam = new CombatSpam(attacker.getObjectID(), target.getObjectID(), weapon.getObjectID(), (int) damage, armorAbsorbed, hitType); + ObjControllerMessage objController4 = new ObjControllerMessage(0x1B, combatSpam); + IoBuffer spam = objController4.serialize(); + if(target.getClient() != null) + target.getClient().getSession().write(spam); + } + private void sendHealPackets(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { CombatAction combatAction = new CombatAction(CRC.StringtoCRC(command.getDefaultAnimations()[0]), attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); @@ -682,6 +1038,23 @@ public class CombatService implements INetworkDispatch { return rawDamage; } + + private float calculateDamageForInstallation(InstallationObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command) { + + float rawDamage = command.getAddedDamage(); + if(command.getPercentFromWeapon() > 0) { + + float weaponMinDmg = weapon.getMinDamage(); + float weaponMaxDmg = weapon.getMaxDamage(); + + + float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg; + weaponDmg *= command.getPercentFromWeapon(); + rawDamage += weaponDmg; + + } + return rawDamage; + } private float calculateDamage(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command) { @@ -717,6 +1090,28 @@ public class CombatService implements INetworkDispatch { } + if (!attacker.isPlayer()){ + if (attacker.hasBuff("expertise_damage_npc")){ + rawDamage *=2; // tower_defense buff + } + } + } + + return rawDamage; + } + + private float calculateDamageForInstallation(InstallationObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command) { + + float rawDamage = command.getAddedDamage(); + + if(command.getPercentFromWeapon() > 0 && weapon != attacker.getSlottedObject("default_weapon")) { + + float weaponMinDmg = weapon.getMinDamage(); + float weaponMaxDmg = weapon.getMaxDamage(); + + float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg; + weaponDmg *= command.getPercentFromWeapon(); + rawDamage += weaponDmg; } return rawDamage; @@ -916,9 +1311,15 @@ public class CombatService implements INetworkDispatch { AIActor petActor = (AIActor) targetCreature.getCalledPet().getAttachment("AI"); if (petActor!=null){ petActor.addDefender(attacker); - DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); + //DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); } } + + if (!targetCreature.isInCombat()){ + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + //DevLog.debugout("Charon", "CombatService AI", "applyDamage addDefender 2"); + } } @@ -1148,6 +1549,26 @@ public class CombatService implements INetworkDispatch { core.playerService.sendCloningWindow(target, attacker.getSlottedObject("ghost") != null); } + + public void deathblowPlayerFromInstallation(InstallationObject attacker, CreatureObject target) { + target.stopIncapTask(); + target.setIncapTask(null); + target.setPosture(Posture.Dead); + + + attacker.removeDefender(target); + target.removeDefender(attacker); + target.setSpeedMultiplierBase(0); + target.setTurnRadius(0); + + if (attacker.getSlottedObject("ghost") != null) + target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_dead", "TT", attacker.getCustomName()), DisplayType.Broadcast); + else + target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_dead", "TT", "@" + attacker.getStfFilename() + ":" + attacker.getStfName()), DisplayType.Broadcast); + + core.playerService.sendCloningWindow(target, attacker.getSlottedObject("ghost") != null); + } + public boolean areInDuel(CreatureObject creature1, CreatureObject creature2) { if(creature1.getDuelList().contains(creature2) && creature2.getDuelList().contains(creature1)) @@ -1385,7 +1806,7 @@ public class CombatService implements INetworkDispatch { if(creature.getClient() == null) { if (creature.getAttachment("AI")!=null){ AIActor aiActor = (AIActor) creature.getAttachment("AI"); - CreatureObject target = aiActor.getFollowObject(); + TangibleObject target = aiActor.getFollowObject(); if (target.getClient()!=null) client = target.getClient(); // Use player's client reference that is in combat with that NPC } diff --git a/src/services/command/BaseSWGCommand.java b/src/services/command/BaseSWGCommand.java index 5025939d..87dff513 100644 --- a/src/services/command/BaseSWGCommand.java +++ b/src/services/command/BaseSWGCommand.java @@ -76,7 +76,10 @@ public class BaseSWGCommand implements Cloneable { if (((String) visitor2.getObject(i, 0)).equalsIgnoreCase(commandName)) { int sub = 0; // Subtract due to command table structures being different - characterAbility = (String) visitor2.getObject(i, 7); + if(((String) visitor2.getObject(i, 7)).equals("admin")) + characterAbility = ""; + else + characterAbility = (String) visitor2.getObject(i, 7); for (int l = (8 - sub); l <= (29 - sub); l++) { if (!((Boolean) visitor2.getObject(i, l))) { diff --git a/src/services/command/CombatCommand.java b/src/services/command/CombatCommand.java index dd761b02..931e41a9 100644 --- a/src/services/command/CombatCommand.java +++ b/src/services/command/CombatCommand.java @@ -62,6 +62,7 @@ public class CombatCommand extends BaseSWGCommand { private float vigorCost; // for commando kill meter and bm specials private float criticalChance; private int attack_rolls; + private String specialLine; private String[] defaultAnimations = new String[]{}; private String[] oneHandedAnimations = new String[]{}; @@ -153,6 +154,7 @@ public class CombatCommand extends BaseSWGCommand { damageType = ((Integer) visitor.getObject(i, 82)).byteValue(); elementalType = ((Integer) visitor.getObject(i, 83)); elementalValue = (Integer) visitor.getObject(i, 84); + setSpecialLine((String) visitor.getObject(i, 87)); performanceSpam = (String) visitor.getObject(i, 89); hitSpam = ((Integer) visitor.getObject(i, 90)).byteValue(); attack_rolls = (Integer) visitor.getObject(i, 93); @@ -672,5 +674,13 @@ public class CombatCommand extends BaseSWGCommand { return animations[new Random().nextInt(animations.length)]; } + + public String getSpecialLine() { + return specialLine; + } + + public void setSpecialLine(String specialLine) { + this.specialLine = specialLine; + } } diff --git a/src/services/command/CommandService.java b/src/services/command/CommandService.java index ab02d15f..6842c5e3 100644 --- a/src/services/command/CommandService.java +++ b/src/services/command/CommandService.java @@ -21,9 +21,14 @@ ******************************************************************************/ package services.command; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.ByteOrder; import java.util.Map; +import java.util.Scanner; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; @@ -31,6 +36,7 @@ import java.util.concurrent.ScheduledExecutorService; import main.NGECore; +import org.apache.commons.io.FileUtils; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; @@ -50,6 +56,7 @@ import protocol.swg.objectControllerObjects.CommandEnqueueRemove; import protocol.swg.objectControllerObjects.StartTask; import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationObject; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; @@ -70,29 +77,23 @@ public class CommandService implements INetworkDispatch { public boolean callCommand(CreatureObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { - if (actor == null) { + if (actor == null) return false; - } - if (command == null) { + if (actor.getClient() == null) return false; - } - if (command.getCharacterAbility().length() > 0 && !actor.hasAbility(command.getCharacterAbility()) && actor.getClient() != null) { + if (command == null) return false; - } - if (command.isDisabled()) { + if (command.getCharacterAbility().length() > 0 && !actor.hasAbility(command.getCharacterAbility())) return false; - } - if (actor.getClient() != null && command.getGodLevel() > actor.getPlayerObject().getGodLevel()) { + if (command.isDisabled()) return false; - } - if (actor.hasCooldown(command.getCooldownGroup()) || actor.hasCooldown(command.getCommandName())) { + if (actor.hasCooldown(command.getCooldownGroup()) || actor.hasCooldown(command.getCommandName())) return false; - } // Causes this service method to return with false after equipping a rifle, not allowing to unequip it anymore // because the client seems to consider rifles invalidweapons for an unkown reason @@ -152,6 +153,7 @@ public class CommandService implements INetworkDispatch { if (!core.simulationService.checkLineOfSight(actor, target)) { actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true); + // If this is AI consider side steps to get LOS return false; } @@ -331,8 +333,255 @@ public class CommandService implements INetworkDispatch { return true; } + public boolean callCommandForInstallation(InstallationObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { + + if (actor == null) { + return false; + } + + if (command == null) { + return false; + } + + if (command.isDisabled()) { + return false; + } + +// if (actor.hasCooldown(command.getCooldownGroup()) || actor.hasCooldown(command.getCommandName())) { +// return false; +// } + + //TangibleObject weapon = (TangibleObject) core.objectService.getObject(actor.getWeaponId()); + TangibleObject weapon = (TangibleObject) core.objectService.getObject((long)actor.getAttachment("TurretWeapon")); + + if (weapon != null && weapon instanceof WeaponObject && ((WeaponObject) weapon).getWeaponType() == command.getInvalidWeapon()) { + System.out.println("Invalid WEAPON!"); + return false; + } + + + + switch (command.getTargetType()) { + case 0: // Target Not Used For This Command + break; + case 1: // Other Only (objectId/targetName) + if (target == null || target == actor) { + if (commandArgs != null && !commandArgs.equals("")) { + String name = commandArgs.split(" ")[0]; + + target = core.objectService.getObjectByFirstName(name); + + if (target == actor) { + target = null; + } + } + + break; + } + + if (target == actor) { + return false; + } + + if (target.getContainer() == actor || target.getGrandparent() == actor) { + break; + } + + if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(target.getPosition()) > command.getMaxRangeToTarget()) { + return false; + } + + + if (!target.isInQuadtree() && (target.getContainer() == null || !(target.getContainer() instanceof CellObject))) { + break; + } + + if (!core.simulationService.checkLineOfSight(actor, target)) { + actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true); + // If this is AI consider side steps to get LOS + return false; + } + + break; + case 2: // Anyone (objectId/targetName) + if (target == null) { + if (commandArgs != null && !commandArgs.equals("")) { + String name = commandArgs.split(" ")[0]; + + target = core.objectService.getObjectByFirstName(name); + + if (target == actor) { + target = null; + } + + // It's possible they use c cmdString to indicate if it should always be on self + if (name.contains("c")) { + //target = actor; + } + } + + break; + } + + if (target.getContainer() == actor || target.getGrandparent() == actor) { + break; + } + + if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(target.getPosition()) > command.getMaxRangeToTarget()) { + return false; + } + + if (!target.isInQuadtree() && (target.getContainer() == null || !(target.getContainer() instanceof CellObject))) { + break; + } + + if (!core.simulationService.checkLineOfSight(actor, target)) { + actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true); + return false; + } + + break; + case 3: // Free Target Mode (rally points, group waypoints) + target = null; + + if (commandArgs == null) { + break; + } + + String[] args = commandArgs.split(" "); + + float x = 0, y = 0, z = 0; + + try { + if (args.length == 2) { + x = Integer.valueOf(args[0]); + z = Integer.valueOf(args[1]); + } else if (args.length > 2) { + x = Integer.valueOf(args[0]); + y = Integer.valueOf(args[1]); + z = Integer.valueOf(args[2]); + } else { + return false; + } + } catch (NumberFormatException e) { + return false; + } + + Point3D position = new Point3D(x, y, z); + + if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(position) > command.getMaxRangeToTarget()) { + return false; + } + + break; + case 4: // Any object + if (target == null) { + break; + } + + if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(target.getPosition()) > command.getMaxRangeToTarget()) { + return false; + } + + if (!target.isInQuadtree() && (target.getContainer() == null || !(target.getContainer() instanceof CellObject))) { + break; + } + + if (!core.simulationService.checkLineOfSight(actor, target)) { + actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true); + return false; + } + + break; + default: + break; + } + switch (command.getTarget()) { + case 0: // Ally Only + if (target == null) { + target = actor; + } + + if (!(target instanceof TangibleObject)) { + return false; + } + + TangibleObject object = (TangibleObject) target; + + if (!object.getFaction().equals("") && !object.getFaction().equals(actor.getFaction())) { + return false; + } + + if (actor.getFactionStatus() < object.getFactionStatus()) { + return false; + } + +// if (object.isAttackableBy(actor)) { +// return false; +// } + + // Without this we could be buffing ally NPCs and such + // Think this is checked later on + if (actor.getSlottedObject("ghost") != null && object.getSlottedObject("ghost") == null) { + return false; + } + + break; + case 1: // Enemy Only + if (target == null || !(target instanceof TangibleObject)) { + return false; + } + + TangibleObject targetObject = (TangibleObject) target; + +// if (!targetObject.isAttackableBy(actor)) { +// return false; +// } + + break; + case 2: // Indifferent + break; + default: + break; + } + +// if (command.shouldCallOnTarget()) { +// if (target == null || !(target instanceof CreatureObject)) { +// return false; +// } +// +// actor = (CreatureObject) target; +// } + + long warmupTime = (long) (command.getWarmupTime() * 1000f); + + if(warmupTime > 0) { + try { + Thread.sleep(warmupTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if(command instanceof CombatCommand) { + try { + processCommandForInstallation(actor, target, (BaseSWGCommand) command.clone(), actionCounter, commandArgs); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } + else + processCommandForInstallation(actor, target, command, actionCounter, commandArgs); + + + return true; + } + public void callCommand(SWGObject actor, String commandName, SWGObject target, String commandArgs) { - callCommand((CreatureObject) actor, target, getCommandByName(commandName), 0, commandArgs); + if (actor instanceof CreatureObject) + callCommand((CreatureObject) actor, target, getCommandByName(commandName), 0, commandArgs); + if (actor instanceof InstallationObject) + callCommandForInstallation((InstallationObject) actor, target, getCommandByName(commandName), 0, commandArgs); } public BaseSWGCommand getCommandByCRC(int commandCRC) { @@ -438,12 +687,61 @@ public class CommandService implements INetworkDispatch { } public void processCommand(CreatureObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { + + if (command.getGodLevel() > 0 || command.getCommandName().equals("setgodmode")) { + String accessLevel = core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()); + String filePath = "accesslevels/" + accessLevel + ".txt"; + System.out.println(command.getCommandName() + " was just used by an admin with accessLevel: " + accessLevel + "."); + if(FileUtilities.doesFileExist(filePath)) { + Scanner scanner; + try { + scanner = new Scanner(new File(filePath)); + boolean levelHasCommand = false; + + while(scanner.hasNextLine()) { + String commandName = scanner.nextLine(); + if(command.getCommandName().equals(commandName)) { + levelHasCommand = true; + break; + } + } + + if (!levelHasCommand) { + actor.sendSystemMessage(" \\#FE2EF7 [GM] \\#FFFFFF " + command.getCommandName() + ": You do not have permission to use this command.", (byte) 0); + return; + } + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else + return; + } + if (command.getCooldown() > 0f) { actor.addCooldown(command.getCooldownGroup(), command.getCooldown()); } if (command instanceof CombatCommand) { processCombatCommand(actor, target, (CombatCommand) command, actionCounter, commandArgs); + } else + if (FileUtilities.doesFileExist("scripts/commands/" + command.getCommandName().toLowerCase() + ".py")) { + core.scriptService.callScript("scripts/commands/", command.getCommandName().toLowerCase(), "run", core, actor, target, commandArgs); + } else if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName().toLowerCase() + ".py")) { + core.scriptService.callScript("scripts/commands/combat/", command.getCommandName().toLowerCase(), "run", core, actor, target, commandArgs); + } + + + } + + public void processCommandForInstallation(InstallationObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { +// if (command.getCooldown() > 0f) { +// actor.addCooldown(command.getCooldownGroup(), command.getCooldown()); +// } + + if (command instanceof CombatCommand) { + processCombatCommandForInstallation(actor, target, (CombatCommand) command, actionCounter, commandArgs); } else { if (FileUtilities.doesFileExist("scripts/commands/" + command.getCommandName().toLowerCase() + ".py")) { core.scriptService.callScript("scripts/commands/", command.getCommandName().toLowerCase(), "run", core, actor, target, commandArgs); @@ -454,9 +752,12 @@ public class CommandService implements INetworkDispatch { } public void processCombatCommand(CreatureObject attacker, SWGObject target, CombatCommand command, int actionCounter, String commandArgs) { - if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName().toLowerCase() + ".py")) { + if (FileUtilities.doesFileExist("scripts/commands/combat/specialline/" + command.getSpecialLine().toLowerCase() + ".py")) + core.scriptService.callScript("scripts/commands/combat/specialline/", command.getSpecialLine().toLowerCase(), "setup", core, attacker, target, command); + + if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName().toLowerCase() + ".py")) core.scriptService.callScript("scripts/commands/combat/", command.getCommandName().toLowerCase(), "setup", core, attacker, target, command); - } else { + else { if (FileUtilities.doesFileExist("scripts/commands/" + command.getCommandName().toLowerCase() + ".py")) { System.err.print("Command " + command.getCommandName() + " is considered a combat command by the client but has a regular command script!"); core.scriptService.callScript("scripts/commands/", command.getCommandName().toLowerCase(), "run", core, attacker, target, ""); @@ -557,6 +858,100 @@ public class CommandService implements INetworkDispatch { } + public void processCombatCommandForInstallation(InstallationObject attacker, SWGObject target, CombatCommand command, int actionCounter, String commandArgs) { + if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py")) { + core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "setup", core, attacker, target, command); + } + + boolean success = true; + + //if((command.getHitType() == 5 || command.getHitType() == 7) && !(target instanceof CreatureObject)) + // success = false; + + if(!(command.getAttackType() == 2) && !(command.getHitType() == 5) && !(command.getHitType() == 0)) { + if(target == null || !(target instanceof TangibleObject) || target == attacker) + success = false; + } else { + if(target == null) + target = attacker; + else if(!(target instanceof TangibleObject)) + return; + } + + if(target instanceof CreatureObject) { + if(!(command.getHitType() == 5)) + if(((CreatureObject) target).getPosture() == 13) + success = false; + if(!(command.getHitType() == 7)) + if(((CreatureObject) target).getPosture() == 14) + success = false; + } + + if(command.getHitType() == 7 && target.getClient() == null) + success = false; + + WeaponObject weapon; + + + weapon = (WeaponObject) core.objectService.getObject((long)attacker.getAttachment("TurretWeapon")); + + if(weapon == null) + return; + + float maxRange = 0; + + if(command.getMaxRange() == 0) + maxRange = weapon.getMaxRange(); + else + maxRange = command.getMaxRange(); + + Point3D attackerPos = attacker.getWorldPosition(); + Point3D defenderPos = attacker.getWorldPosition(); + + if(attackerPos.getDistance(defenderPos) > maxRange && maxRange != 0) + success = false; + + if(command.getMinRange() > 0) { + if(attackerPos.getDistance(defenderPos) < command.getMinRange()) + success = false; + } + + + if(target != attacker && success && !core.simulationService.checkLineOfSight(attacker, target)) { + attacker.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true); + success = false; + } + + if(!success && attacker.getClient() != null) { + IoSession session = attacker.getClient().getSession(); + CommandEnqueueRemove commandRemove = new CommandEnqueueRemove(attacker.getObjectId(), actionCounter); + session.write(new ObjControllerMessage(0x0B, commandRemove).serialize()); + StartTask startTask = new StartTask(actionCounter, attacker.getObjectID(), command.getCommandCRC(), CRC.StringtoCRC(command.getCooldownGroup()), -1); + session.write(new ObjControllerMessage(0x0B, startTask).serialize()); + } else { + +// if(command.getHitType() == 5) { +// core.combatService.doHeal(attacker, (CreatureObject) target, weapon, command, actionCounter); +// return; +// } +// +// if(command.getHitType() == 7) { +// core.combatService.doRevive(attacker, (CreatureObject) target, weapon, command, actionCounter); +// return; +// } +// +// if(command.getHitType() == 0 && command.getBuffNameSelf() != null && command.getBuffNameSelf().length() > 0) { +// core.combatService.doSelfBuff(attacker, weapon, command, actionCounter); +// return; +// } + for(int i = 0 ; i < command.getAttack_rolls(); i++) { + core.combatService.doCombatForInstallation(attacker, (TangibleObject) target, weapon, command, actionCounter); + } + + } + + } + public void removeCommand(CreatureObject actor, int actionCounter, BaseSWGCommand command) { if (actor == null || actor.getClient() == null || command == null) { return; diff --git a/src/services/gcw/FactionService.java b/src/services/gcw/FactionService.java index df74bf0c..2ba2a347 100644 --- a/src/services/gcw/FactionService.java +++ b/src/services/gcw/FactionService.java @@ -21,6 +21,7 @@ ******************************************************************************/ package services.gcw; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; @@ -37,6 +38,7 @@ import org.python.core.Py; import org.python.core.PyObject; import protocol.swg.FactionResponseMessage; +import protocol.swg.UpdatePVPStatusMessage; import resources.common.FileUtilities; import resources.common.Opcodes; import resources.datatables.DisplayType; @@ -44,6 +46,7 @@ import resources.datatables.FactionStatus; import resources.datatables.Options; import resources.datatables.PvpStatus; import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationObject; import resources.objects.mission.MissionObject; import resources.objects.player.PlayerObject; import resources.objects.tangible.TangibleObject; @@ -52,6 +55,7 @@ import engine.clientdata.StfTable; import engine.clientdata.visitors.DatatableVisitor; import engine.clients.Client; import engine.resources.common.CRC; +import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; @@ -169,6 +173,7 @@ public class FactionService implements INetworkDispatch { * Will be useful for NPC AI, so they know who to help and who to be indifferent to. */ public boolean isFactionAlly(TangibleObject object, TangibleObject target) { + if (object == null || target == null) { return false; } @@ -180,10 +185,10 @@ public class FactionService implements INetworkDispatch { return false; } + if (FileUtilities.doesFileExist("scripts/faction/" + objectFaction + ".py")) { - PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isAlly"); - - if (method != null && method.isCallable()) { + PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isAlly"); + if (method != null && method.isCallable()) { return ((method.__call__(Py.java2py(targetFaction)).asInt() == 1) ? true : false); } } @@ -191,6 +196,29 @@ public class FactionService implements INetworkDispatch { return false; } + public boolean isFactionAlly(String objectFaction, String targetFaction) { + + if (objectFaction == null || targetFaction == null) { + return false; + } + + if (!isFaction(objectFaction) || !isFaction(targetFaction)) { + return false; + } + + + if (FileUtilities.doesFileExist("scripts/faction/" + objectFaction + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isAlly"); + if (method != null && method.isCallable()) { + return ((method.__call__(Py.java2py(targetFaction)).asInt() == 1) ? true : false); + } + } + + return false; + } + + + /* * Returns true if target is an enemy of object * @@ -212,13 +240,22 @@ public class FactionService implements INetworkDispatch { PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isEnemy"); if (method != null && method.isCallable()) { - return ((method.__call__(Py.java2py(targetFaction)).asInt() == 1) ? true : false); + int checkResult = method.__call__(Py.java2py(targetFaction)).asInt(); + if (objectFaction.equals("rebel") || objectFaction.equals("imperial")){ + if (object.getFactionStatus()==FactionStatus.OnLeave) + checkResult=0; + } + if (targetFaction.equals("rebel") || targetFaction.equals("imperial")){ + if (target.getFactionStatus()==FactionStatus.OnLeave) + checkResult=0; + } + return ((checkResult == 1) ? true : false); } } return false; } - + /* * Calculates the target's pvp bitmask based on the person's * faction standing and the enemy's options bitmask. @@ -239,6 +276,10 @@ public class FactionService implements INetworkDispatch { PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); int pvpBitmask = 0; + + if (target==null) + return 0; // Avoids infinite loading screen when another player character has been deleted, + // but is still referenced by some collections being null if (object == target) { pvpBitmask |= PvpStatus.Self; @@ -263,7 +304,7 @@ public class FactionService implements INetworkDispatch { if (target.getFactionStatus() == FactionStatus.SpecialForces) { pvpBitmask |= PvpStatus.Overt; } - + // Everything below assumes target is potentially attackable. if (!target.getOption(Options.ATTACKABLE) || target.getOption(Options.INVULNERABLE)) { return pvpBitmask; @@ -355,6 +396,7 @@ public class FactionService implements INetworkDispatch { } } + return pvpBitmask; } @@ -525,6 +567,54 @@ public class FactionService implements INetworkDispatch { return factionMap; } + // This is to make nearby NPCs transmit updatepvp, + // so the player sees the faction change represented in the clientside NPC representation + public void updatePVPFromNearbyNPCs(CreatureObject creature, Client destination){ + List awareObjects = core.simulationService.get(creature.getPlanet(), creature.getWorldPosition().x, creature.getWorldPosition().z, 512); + for(int i = 0; i < awareObjects.size(); i++) { + SWGObject obj = awareObjects.get(i); + if(obj != creature && obj.getContainer() != creature && obj.isInQuadtree()) { + if (obj instanceof CreatureObject){ + CreatureObject creo = (CreatureObject) obj; + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(creo.getObjectID()); + upvpm.setFaction(CRC.StringtoCRC(creo.getFaction())); + upvpm.setStatus(NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), creo)); + destination.getSession().write(upvpm.serialize()); + } + if (obj instanceof TangibleObject && !(obj instanceof CreatureObject)){ + TangibleObject tano = (TangibleObject) obj; + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(tano.getObjectID()); + upvpm.setFaction(CRC.StringtoCRC(tano.getFaction())); + upvpm.setStatus(NGECore.getInstance().factionService.calculatePvpStatus((TangibleObject) destination.getParent(), tano)); + destination.getSession().write(upvpm.serialize()); + + // Crashes client and more importantly should be done selectively with different destinations +// if (destination.getParent() instanceof CreatureObject){ +// //System.out.println("IN updatePVPFromNearbyNPCs!!!!!!!" + destination.getParent().getCustomName()); +// if (((CreatureObject) destination.getParent()).isPlayer() && ((CreatureObject) destination.getParent()).getFaction()!=tano.getFaction()){ +// int optionsBitMask = tano.getOptionsBitmask(); +// if (tano.getOption(Options.QUEST)) +// optionsBitMask = optionsBitMask & ~Options.QUEST; +// if (!tano.getOption(Options.ATTACKABLE)) +// optionsBitMask = optionsBitMask | Options.ATTACKABLE; +// +// tano.setOptionsBitmask(optionsBitMask); +// } +// } + + } + if (obj instanceof InstallationObject && !(obj instanceof TangibleObject)){ + InstallationObject inso = (InstallationObject) obj; + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(inso.getObjectID()); + upvpm.setFaction(CRC.StringtoCRC(inso.getFaction())); + upvpm.setStatus(NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), inso)); + //System.out.println("MakeAwareNearbyNPCs " + NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), inso)); + destination.getSession().write(upvpm.serialize()); + } + } + } + } + @Override public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { diff --git a/src/services/gcw/GCWPylon.java b/src/services/gcw/GCWPylon.java new file mode 100644 index 00000000..60ef29f0 --- /dev/null +++ b/src/services/gcw/GCWPylon.java @@ -0,0 +1,398 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.gcw; + +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import main.NGECore; +import protocol.swg.PlayClientEffectObjectTransformMessage; +import engine.clients.Client; +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; +import resources.datatables.FactionStatus; +import resources.datatables.Factions; +import resources.datatables.Options; +import resources.datatables.WeaponType; +import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationObject; +import resources.objects.tangible.TangibleObject; +import resources.objects.weapon.WeaponObject; +import services.ai.TurretAIActor; + +/** + * @author Charon + */ + +public class GCWPylon extends TangibleObject{ + + private static final long serialVersionUID = 1L; + private int pylonType = 0; + private int pylonFaction = 0; + private int spawnLevel = 0; + private int patrolRoute = 0; + private int resourceFilling = 0; + private int delay = 0; + + private static Map typeStfMapping = new ConcurrentHashMap(); + static{ + typeStfMapping.put(PylonType.SoldierPatrol, "Soldier Patrol Pylon"); + typeStfMapping.put(PylonType.SoldierDefense, "Soldier Patrol Pylon"); + typeStfMapping.put(PylonType.VehiclePatrol, "Soldier Patrol Pylon"); + typeStfMapping.put(PylonType.SiegeVehiclePatrol, "Soldier Patrol Pylon"); + typeStfMapping.put(PylonType.Barricade, "Soldier Patrol Pylon"); + typeStfMapping.put(PylonType.Turret, "Soldier Patrol Pylon"); + typeStfMapping.put(PylonType.Tower, "Soldier Patrol Pylon"); + } + + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + public GCWPylon() { + super(); + } + + public GCWPylon(long objectID, Planet planet, Point3D position, Quaternion orientation, String template){ + super(objectID, planet, position, orientation, template); + this.setAttachment("Filling",0); + this.setResourceFilling(0); + } + + public int getPylonType() { + return pylonType; + } + + public void setPylonType(int pylonType) { + this.pylonType = pylonType; + + String pylonName = ""; + switch (pylonType){ + case PylonType.Barricade: pylonName="Barricade Construction Site"; + break; + case PylonType.SoldierDefense: pylonName="Soldier Construction Site"; + break; + case PylonType.SoldierPatrol: pylonName="Patrol Construction Site"; + break; + case PylonType.VehiclePatrol: pylonName="Vehicle Construction Site"; + break; + case PylonType.SiegeVehiclePatrol: pylonName="Siege Vehicle Construction Site"; + break; + case PylonType.Tower: pylonName="Tower Construction Site"; + break; + case PylonType.Turret: pylonName="Turret Construction Site"; + break; + } + + this.setCustomName(pylonName + " 0/100"); + this.setAttachment("Name", pylonName); + + } + + public int getPylonFaction() { + return pylonFaction; + } + + public void setPylonFaction(int pylonFaction) { + this.pylonFaction = pylonFaction; + } + + public int getSpawnLevel() { + return spawnLevel; + } + + public void setSpawnLevel(int spawnLevel) { + this.spawnLevel = spawnLevel; + } + + public void setPatrolRoute(int route){ + this.patrolRoute = route; + } + + public int getPatrolRoute(){ + return this.patrolRoute; + } + + public void convertToPhase2Object(){ + + //if (determinePylonLevel()==0) + //return; + + resourceFilling = 100; + spawnLevel = 3; +// resourceFilling = 10; +// spawnLevel = 1; + + switch (pylonType){ + case PylonType.Barricade: createBarricade(); + break; + case PylonType.SoldierDefense: createSpawner(); + break; + case PylonType.SoldierPatrol: createSpawner(); + break; + case PylonType.VehiclePatrol: createSpawner(); + break; + case PylonType.SiegeVehiclePatrol: createSpawner(); + break; + case PylonType.Tower: createTower(); + break; + case PylonType.Turret: createTurret(); + break; + } + } + + public int determinePylonLevel(){ + if (resourceFilling==0) spawnLevel = 0; + if (resourceFilling>0 && resourceFilling<50) spawnLevel = 1; + if (resourceFilling>=50 && resourceFilling<100) spawnLevel = 2; + if (resourceFilling==100) spawnLevel = 3; + return spawnLevel; + } + + + public void createSpawner(){ + GCWSpawner spawner = (GCWSpawner) NGECore.getInstance().objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, this.getPlanet(), this.getWorldPosition(), this.getOrientation()); + NGECore.getInstance().simulationService.add(spawner, spawner.getPosition().x, spawner.getPosition().z, true); + spawner.setCustomName(""); + spawner.setStfFilename("battlefield"); + spawner.setStfName("battlefield_marker_name"); + spawner.setPatrolRoute(getPatrolRoute()); + spawner.setDelay(getDelay()); + spawner.setSpawnLevel(3); + spawner.setSpawnerFaction(getPylonFaction()); + spawner.setSpawnerType(getPylonType()); + NGECore.getInstance().invasionService.registerPhase2Objects(spawner); + } + + public void createTurret(){ + String turretTemplate="object/installation/turret/gcw/shared_adv_turret_dish_sm_heat.iff"; + //String turretTemplate="object/installation/turret/gcw/shared_adv_turret_dish_large_heat.iff"; + if (spawnLevel==2) turretTemplate="object/installation/turret/gcw/shared_adv_turret_dish_large_heat.iff"; + if (spawnLevel==3) turretTemplate="object/installation/turret/gcw/shared_adv_turret_block_med_heat.iff"; + Planet spawnPlanet = this.getPlanet(); + Point3D spawnPos = this.getWorldPosition(); + Quaternion quat = this.getOrientation(); + NGECore.getInstance().objectService.destroyObject(this.getObjectID()); + InstallationObject turret = (InstallationObject) NGECore.getInstance().objectService.createObject(turretTemplate, 0, spawnPlanet, spawnPos, quat); + NGECore.getInstance().simulationService.add(turret, turret.getPosition().x, turret.getPosition().z, true); + float positionY = NGECore.getInstance().terrainService.getHeight(turret.getPlanetId(), turret.getPosition().x, turret.getPosition().z); + if (turret.getWorldPosition().getDistance2D(new Point3D(1779.27F, 12, 2517.37F))<5 || turret.getWorldPosition().getDistance2D(new Point3D(1797.00F, 12, 2518.32F))<5){ + positionY +=4; // The terrainService delivers incorrect heights on that bridge near the general in Keren + } + turret.setPosition(new Point3D(turret.getPosition().x,positionY, turret.getPosition().z)); + String customName = "Rebel Turret"; + String factionString = "rebel"; + if (getPylonFaction()==Factions.Imperial){ + customName = "Imperial Turret"; + factionString = "imperial"; + } + turret.setCustomName(customName); + + turret.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST); + //turret.setOptionsBitmask(Options.QUEST); + turret.setFaction(factionString); + turret.setFactionStatus(FactionStatus.Combatant); + turret.setMaximumCondition(50000); + TurretAIActor actor = new TurretAIActor(turret, turret.getPosition(), scheduler); + turret.setAttachment("AI", actor); + NGECore.getInstance().invasionService.registerPhase2Objects(turret); + + WeaponObject turretWeapon = (WeaponObject) NGECore.getInstance().objectService.createObject("object/weapon/ranged/turret/shared_turret_heat.iff", turret.getPlanet()); + turretWeapon.setAttackSpeed(5.0F); + //turretWeapon.setAttackSpeed(0.50F); + turretWeapon.setWeaponType(WeaponType.RIFLE); + turretWeapon.setMaxRange(60.0F); + turretWeapon.setDamageType("energy"); + + int minDamage = 1500; int maxDamage = 2000; + if (spawnLevel==2) {minDamage=2500; maxDamage=3500;} + if (spawnLevel==3) {minDamage=4000; maxDamage=5000;} + + turretWeapon.setMinDamage(minDamage); + turretWeapon.setMaxDamage(maxDamage); + //turret.add(turretWeapon); // Does not have to be added explicitly, would cause engine slot arrangement error message + turret.setAttachment("TurretWeapon",turretWeapon.getObjectID()); + } + + public void createBarricade(){ + String barricadeTemplate = "object/tangible/destructible/shared_gcw_rebel_barricade.iff"; + TangibleObject barricade = (TangibleObject) NGECore.getInstance().objectService.createObject(barricadeTemplate, 0, this.getPlanet(), this.getWorldPosition(), this.getOrientation()); + NGECore.getInstance().simulationService.add(barricade, barricade.getPosition().x, barricade.getPosition().z, true); + String customName = "Rebel Barricade"; + String factionString = "rebel"; + if (getPylonFaction()==Factions.Imperial){ + customName = "Imperial Barricade"; + factionString = "imperial"; + } + barricade.setCustomName(customName); + barricade.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST); + //barricade.setOptionsBitmask(Options.QUEST); + barricade.setFaction(factionString); + barricade.setFactionStatus(FactionStatus.Combatant); + int maxCondition = 50000; + maxCondition += 5000 * resourceFilling; + + barricade.setMaximumCondition(maxCondition); + NGECore.getInstance().invasionService.registerPhase2Objects(barricade); + + final Future[] fut = {null}; + fut[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().objectService.getObject(barricade.getObjectID())==null){ + Thread.yield(); + fut[0].cancel(false); + } + + Vector nearAllies = NGECore.getInstance().simulationService.getAllNearSameFactionCreatures(7,barricade.getWorldPosition(),barricade.getPlanet(),NGECore.getInstance().invasionService.getFactionName(getPylonFaction())); + for (CreatureObject ally : nearAllies){ + if (! ally.hasBuff("barricade_defender")){ + NGECore.getInstance().buffService.addBuffToCreature(ally, "barricade_defender", ally); + } else { + + } + } // towFacGuardDefenseItem + Thread.currentThread().interrupt(); + } catch (Exception e) { + System.err.println("Exception in Barricade thread " + e.getMessage()); + } + } + }, 5, 2, TimeUnit.SECONDS); + } + + public void createTower(){ + String towerTemplate = "object/tangible/destructible/shared_gcw_rebel_tower.iff"; + String factionString = "rebel"; + String towerString = "Rebel Tower"; + if (getPylonFaction()==Factions.Imperial){ + towerTemplate = "object/tangible/destructible/shared_gcw_imperial_tower.iff"; + factionString = "imperial"; + towerString = "Imperial Tower"; + } + TangibleObject tower = (TangibleObject) NGECore.getInstance().objectService.createObject(towerTemplate, 0, this.getPlanet(), this.getWorldPosition(), this.getOrientation()); + NGECore.getInstance().simulationService.add(tower, tower.getPosition().x, tower.getPosition().z, true); + tower.setCustomName(towerString); + tower.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST); + //tower.setOptionsBitmask(Options.QUEST); + tower.setFaction(factionString); + tower.setFactionStatus(FactionStatus.Combatant); + int maxCondition = 50000; + maxCondition += 5000 * resourceFilling; + + tower.setMaximumCondition(maxCondition); + NGECore.getInstance().invasionService.registerPhase2Objects(tower); + + final Future[] fut = {null}; + fut[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().objectService.getObject(tower.getObjectID())==null){ + Thread.yield(); + fut[0].cancel(false); + } + + Vector nearAllies = NGECore.getInstance().simulationService.getAllNearSameFactionNPCs(500, tower); + for (CreatureObject ally : nearAllies){ + if (!ally.isPlayer()){ + if (! ally.hasBuff("tower_defender")){ + NGECore.getInstance().buffService.addBuffToCreature(ally, "tower_defender", ally); + } + } + } + Thread.currentThread().interrupt(); + } catch (Exception e) { + System.err.println("Exception in Tower thread " + e.getMessage()); + } + } + }, 5, 2, TimeUnit.SECONDS); + } + + public int getResourceFilling() { + return resourceFilling; + } + + public void setResourceFilling(int resourceFilling) { + this.resourceFilling = resourceFilling; + } + + public int getDelay() { + return delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } + + public class PylonType { + + public static final int SoldierPatrol = 0; + public static final int SoldierDefense = 1; + public static final int VehiclePatrol = 2; + public static final int SiegeVehiclePatrol = 3; + public static final int Barricade = 4; + public static final int Turret = 5; + public static final int Tower = 6; + + } + /* + Soldier Patrol Pylons - Spawns a continuous stream of NPCs to aid in the battle - shown with a Helmet icon. + Vehicle Patrol Pylons - Spawns vehicles that are considerably more lethal than the Soldiers - shown with a Terminal icon. + Siege Vehicle Patrol Pylon - Spawns Rebel Hailfire Driods or Imperial AT-ATs (only spawn at a Level 3 Pylon) - shown with the same Terminal icon. + Barricade Pylon - Spawns a barricade that defends units behind it by giving them a defensive buff - shown with a Barricade icon. + Turret Pylon - Spawns an AI controlled turret that fires on enemy units - shown with a Gun Barrel or Turret Dish icon. + Tower Pylon - Spawns a watch tower that grants intelligence to nearby NPCs and offers combat missions to players - shown with a Tower icon. + */ + + public void sendBaselines(Client destination) { + if (destination != null && destination.getSession() != null) { + destination.getSession().write(getBaseline(3).getBaseline()); + destination.getSession().write(getBaseline(6).getBaseline()); + + Client parent = ((getGrandparent() == null) ? null : getGrandparent().getClient()); + + if (parent != null && destination == parent) { + destination.getSession().write(getBaseline(8).getBaseline()); + destination.getSession().write(getBaseline(9).getBaseline()); + } + + if (destination.getParent() != this) { + // The icon disappears after a few seconds, no idea why. Must be the commandString requirement + float y = -0.1F; + //float qz= 1.06535322E9F; + float qz= 99999; + //String animName = "pt_gcw_quest_rebel_barricade.prt"; + String animName = "pt_gcw_quest_imperial_patrol_2.prt"; + //String animName = "pt_reb_insignia_02.prt"; // pt_gcw_quest_imperial_patrol_2.prt + Point3D effectorPosition = new Point3D(0,y,0); + Quaternion effectorOrientation = new Quaternion(0,0,0,qz); + PlayClientEffectObjectTransformMessage lmsg = new PlayClientEffectObjectTransformMessage("appearance/" + animName,this.getObjectID(),"",effectorPosition,effectorOrientation); + //PlayClientEffectObjectMessage lmsg = new PlayClientEffectObjectMessage("appearance/" + animName, this.getObjectID(), ""); + destination.getSession().write(lmsg.serialize()); + } + } + } +} diff --git a/src/services/gcw/GCWService.java b/src/services/gcw/GCWService.java index 6a47d4cd..b82b9ac9 100644 --- a/src/services/gcw/GCWService.java +++ b/src/services/gcw/GCWService.java @@ -46,6 +46,7 @@ import org.python.google.common.collect.Multimap; import protocol.swg.GcwGroupsRsp; import protocol.swg.GcwRegionsReq; import protocol.swg.GcwRegionsRsp; +import protocol.swg.ServerNowEpochTime; import resources.common.Opcodes; import resources.common.OutOfBand; import resources.common.collidables.CollidableCircle; @@ -492,7 +493,7 @@ public class GCWService implements INetworkDispatch { /* Ported from javascript. * Written for us by Hendrik of http://swg.activeframe.de. */ - private double helper(int points, int rank) { + public double helper(int points, int rank) { int faktor = points / (MOD2[rank-1] - 250 * rank); int rt = points / (1 + faktor) - DECAY1[rank-1]; @@ -636,9 +637,22 @@ public class GCWService implements INetworkDispatch { c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); - return (int) ((c.getTimeInMillis() - now.getTime()) / 1000L); + // Theory:Due to the client refusing the ServerNowEpochTime packet, the client assumes an epoch time of 0 for GCW! + // An alternative theory would be that the GCWTime is independent from the ServerNowEpochTime + // 2nd theory more likely, because manually sending ServerNowEpochTime (confirmed by sniff) does nothing to the GCW time + // Conclusion: GCW epoch time is set independently somehow + + // The return value must be relative to epoch of 0, the client assumes 25.12.2011 current time/date + //return (int) ((c.getTimeInMillis() - now.getTime()) / 1000L); + return (int) (1324047960 + ((c.getTimeInMillis() - now.getTime()) / 1000L)); } + public void sendServerNowEpochTime(CreatureObject player){ + + ServerNowEpochTime time = new ServerNowEpochTime((int) (System.currentTimeMillis() / 1000)); + player.getClient().getSession().write(time.serialize()); + } + public void updateNextUpdateTime() { ODBCursor cursor = core.getSWGObjectODB().getCursor(); diff --git a/src/services/gcw/GCWSpawner.java b/src/services/gcw/GCWSpawner.java new file mode 100644 index 00000000..42d4c8d8 --- /dev/null +++ b/src/services/gcw/GCWSpawner.java @@ -0,0 +1,852 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.gcw; + +import java.util.Random; +import java.util.Vector; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; +import main.NGECore; +import resources.datatables.Factions; +import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; + +/** + * @author Charon + */ + +@SuppressWarnings("unused") +public class GCWSpawner extends TangibleObject{ + + private static final long serialVersionUID = 1L; + private int spawnerType = 0; + private int spawnerFaction = 0; + private int spawnLevel = 0; + private int totalSpawnedUnits = 0; + private String[] soldierTemplates = new String[]{""}; + private String[] rebelSoldierTemplates1 = new String[]{""}; + private String[] rebelSoldierTemplates2 = new String[]{""}; + private String[] rebelSoldierTemplates3 = new String[]{"gcw_city_rebel_soldier"}; + private String[] imperialSoldierTemplates1 = new String[]{""}; + private String[] imperialSoldierTemplates2 = new String[]{""}; + private String[] imperialSoldierTemplates3 = new String[]{"elite_imperial_stormtrooper_90"}; + + private String[] vehicleTemplates = new String[]{""}; + private String[] rebelVehicleTemplates1 = new String[]{"rebel_invasion_at_xt"}; + private String[] rebelVehicleTemplates2 = new String[]{"rebel_invasion_at_xt"}; + private String[] rebelVehicleTemplates3 = new String[]{"rebel_invasion_at_xt"}; + private String[] imperialVehicleTemplates1 = new String[]{"imp_invasion_at_st"}; + private String[] imperialVehicleTemplates2 = new String[]{"imp_invasion_at_st"}; + private String[] imperialVehicleTemplates3 = new String[]{"imp_invasion_at_st"}; + + + private String[] siegeVehicleTemplates = new String[]{""}; + private String[] rebelSiegeVehicleTemplates1 = new String[]{"rebel_invasion_hailfire_droid"}; + private String[] rebelSiegeVehicleTemplates2 = new String[]{"rebel_invasion_hailfire_droid"}; + private String[] rebelSiegeVehicleTemplates3 = new String[]{"rebel_invasion_hailfire_droid"}; + private String[] imperialSiegeVehicleTemplates1 = new String[]{"imp_invasion_at_at"}; + private String[] imperialSiegeVehicleTemplates2 = new String[]{"imp_invasion_at_at"}; + private String[] imperialSiegeVehicleTemplates3 = new String[]{"imp_invasion_at_at"}; + + private String barricadeTemplate = ""; + private String rebelBarricadeTemplate = "object/tangible/destructible/shared_gcw_rebel_barricade.iff"; + private String imperialBarricadeTemplate = "object/tangible/destructible/shared_gcw_imperial_barricade.iff"; + + + private String turretTemplates = ""; + private String[] rebelTurretTemplates1 = new String[]{""}; + private String[] rebelTurretTemplates2 = new String[]{""}; + private String[] rebelTurretTemplates3 = new String[]{"object/tangible/destructible/shared_gcw_rebel_turret.iff"}; + private String[] imperialTurretTemplates1 = new String[]{""}; + private String[] imperialTurretTemplates2 = new String[]{""}; + private String[] imperialTurretTemplates3 = new String[]{"object/tangible/destructible/shared_gcw_imperial_turret.iff"}; + + private String towerTemplate = ""; + private String rebelTowerTemplate = "object/tangible/destructible/shared_gcw_rebel_tower.iff"; + private String imperialTowerTemplate = "object/tangible/destructible/shared_gcw_imperial_tower.iff"; + + private Vector patrolRoute = new Vector(); + private CreatureObject lastDefender = null; + private int delay = 0; + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + public GCWSpawner() { + super(); + } + + public GCWSpawner(long objectID, Planet planet, Point3D position, Quaternion orientation, String template){ + super(objectID, planet, position, orientation, template); + } + + public int getSpawnerType() { + return spawnerType; + } + + public void setSpawnerType(int spawnerType) { + this.spawnerType = spawnerType; + this.setCustomName(""); + if (spawnerType==SpawnerType.SoldierPatrol){ + final Future[] fut1 = {null}; + fut1[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().invasionService.getInvasionPhase()>2){ + Thread.yield(); + fut1[0].cancel(false); + } + spawnSoldier(); + } catch (Exception e) { + System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, getDelay(), 240, TimeUnit.SECONDS); //120 + } + + if (spawnerType==SpawnerType.SoldierDefense){ + final Future[] fut2 = {null}; + fut2[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().invasionService.getInvasionPhase()>2){ + Thread.yield(); + fut2[0].cancel(false); + } + spawnSoldierDefender(); + } catch (Exception e) { + System.err.println("Exception in SoldierDefensePylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, 5, 90, TimeUnit.SECONDS); + } + + if (spawnerType==SpawnerType.VehiclePatrol){ + final Future[] fut3 = {null}; + fut3[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().invasionService.getInvasionPhase()>2){ + Thread.yield(); + fut3[0].cancel(false); + } + spawnVehicle(); + } catch (Exception e) { + System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnVehicle() " + e.getMessage()); + } + } + }, getDelay(), 240, TimeUnit.SECONDS); //240 + } + + if (spawnerType==SpawnerType.SiegeVehiclePatrol){ + final Future[] fut4 = {null}; + fut4[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().invasionService.getInvasionPhase()>2){ + Thread.yield(); + fut4[0].cancel(false); + } + spawnSiegeVehicle(); + } catch (Exception e) { + System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, getDelay(), 600, TimeUnit.SECONDS); + } + + } + + public int getSpawnerFaction() { + return spawnerFaction; + } + + public void setSpawnerFaction(int spawnerFaction) { + this.spawnerFaction = spawnerFaction; + } + + public int getSpawnLevel() { + return spawnLevel; + } + + public void setSpawnLevel(int spawnLevel) { + this.spawnLevel = spawnLevel; + } + + public void spawnSoldier(){ + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + String stfName = "gcw_city_rebel_specforce_defense"; + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: soldierTemplates = rebelSoldierTemplates1; + stfName = "gcw_city_rebel_grunt_assault"; + break; + case 2: soldierTemplates = rebelSoldierTemplates2; + stfName = "gcw_city_rebel_grunt_assault"; + break; + case 3: soldierTemplates = rebelSoldierTemplates3; + stfName = "gcw_city_rebel_specforce_assault"; + break; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: soldierTemplates = imperialSoldierTemplates1; + break; + case 2: soldierTemplates = imperialSoldierTemplates2; + break; + case 3: soldierTemplates = imperialSoldierTemplates3; + break; + } + } + String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)]; + //if (totalSpawnedUnits==0){ + CreatureObject soldier = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + if (spawnerFaction==Factions.Rebel) + soldier.setStfName(stfName); + if (spawnerFaction==Factions.Imperial){ + String[] Prefices = new String[]{"GK-","TK-"}; + int suffix = 300 + new Random().nextInt(700); + String stormtrooperID = Prefices[new Random().nextInt(Prefices.length)]+suffix; + soldier.setCustomName(stormtrooperID); + } + NGECore.getInstance().invasionService.registerInvader(soldier); + totalSpawnedUnits++; + soldier.setAttachment("IsInvader","yes"); + NGECore.getInstance().aiService.setPatrol(soldier, patrolRoute); + NGECore.getInstance().aiService.setPatrolLoop(soldier,false); + + //} + } + } + + public void spawnSoldierDefender(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + String stfName = "gcw_city_rebel_specforce_defense"; + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: soldierTemplates = rebelSoldierTemplates1; + stfName = "gcw_city_rebel_grunt_defense"; + break; + case 2: soldierTemplates = rebelSoldierTemplates2; + stfName = "gcw_city_rebel_grunt_defense"; + break; + case 3: soldierTemplates = rebelSoldierTemplates3; + stfName = "gcw_city_rebel_specforce_defense"; + break; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: soldierTemplates = imperialSoldierTemplates1; + break; + case 2: soldierTemplates = imperialSoldierTemplates2; + break; + case 3: soldierTemplates = imperialSoldierTemplates3; + break; + } + } + if (lastDefender!=null) + if (lastDefender.getPosture()!=13 && lastDefender.getPosture()!=13) + return; + String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)]; + lastDefender = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + if (spawnerFaction==Factions.Rebel) + lastDefender.setStfName(stfName); + if (spawnerFaction==Factions.Imperial){ + String[] Prefices = new String[]{"GK-","TK-"}; + int suffix = 300 + new Random().nextInt(700); + String stormtrooperID = Prefices[new Random().nextInt(Prefices.length)]+suffix; + lastDefender.setCustomName(stormtrooperID); + } + NGECore.getInstance().invasionService.registerDefender(lastDefender); + totalSpawnedUnits++; + } + } + + public void spawnVehicle(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: vehicleTemplates = rebelVehicleTemplates1; + case 2: vehicleTemplates = rebelVehicleTemplates2; + case 3: vehicleTemplates = rebelVehicleTemplates3; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: vehicleTemplates = imperialVehicleTemplates1; + case 2: vehicleTemplates = imperialVehicleTemplates2; + case 3: vehicleTemplates = imperialVehicleTemplates3; + } + } + String vehicleTemplate = vehicleTemplates[new Random().nextInt(vehicleTemplates.length)]; + CreatureObject vehicle = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(vehicleTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + NGECore.getInstance().invasionService.registerInvader(vehicle); + totalSpawnedUnits++; + vehicle.setAttachment("IsInvader","yes"); + NGECore.getInstance().aiService.setPatrol(vehicle, patrolRoute); + NGECore.getInstance().aiService.setPatrolLoop(vehicle,false); + } + } + + public void spawnSiegeVehicle(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: vehicleTemplates = rebelSiegeVehicleTemplates1; + case 2: vehicleTemplates = rebelSiegeVehicleTemplates2; + case 3: vehicleTemplates = rebelSiegeVehicleTemplates3; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: vehicleTemplates = imperialSiegeVehicleTemplates1; + case 2: vehicleTemplates = imperialSiegeVehicleTemplates2; + case 3: vehicleTemplates = imperialSiegeVehicleTemplates3; + } + } + String vehicleTemplate = vehicleTemplates[new Random().nextInt(vehicleTemplates.length)]; + CreatureObject vehicle = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(vehicleTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + vehicle.setAttachment("IsSlowVehicle",true); + NGECore.getInstance().invasionService.registerInvader(vehicle); + totalSpawnedUnits++; + vehicle.setAttachment("IsInvader","yes"); + + NGECore.getInstance().aiService.setPatrol(vehicle, patrolRoute); + NGECore.getInstance().aiService.setPatrolLoop(vehicle,false); + } + } + + public void setPatrolRoute(int route){ + switch(route){ + case PatrolRoute.Dearic1: patrolRoute = get_Dearic_Route_1(); + break; + case PatrolRoute.Dearic2: patrolRoute = get_Dearic_Route_2(); + break; + case PatrolRoute.Dearic3: patrolRoute = get_Dearic_Route_3(); + break; + case PatrolRoute.Dearic4: patrolRoute = get_Dearic_Route_4(); + break; + case PatrolRoute.Dearic5: patrolRoute = get_Dearic_Route_5(); + break; + case PatrolRoute.Dearic6: patrolRoute = get_Dearic_Route_6(); + break; + case PatrolRoute.Dearic7: patrolRoute = get_Dearic_Route_7(); + break; + case PatrolRoute.Dearic8: patrolRoute = get_Dearic_Route_8(); + break; + case PatrolRoute.Dearic9: patrolRoute = get_Dearic_Route_9(); + break; + case PatrolRoute.Dearic10: patrolRoute = get_Dearic_Route_10(); + break; + case PatrolRoute.Dearic11: patrolRoute = get_Dearic_Route_11(); + break; + + case PatrolRoute.Keren1: patrolRoute = get_Keren_Route_1(); + break; + case PatrolRoute.Keren2: patrolRoute = get_Keren_Route_2(); + break; + case PatrolRoute.Keren3: patrolRoute = get_Keren_Route_3(); + break; + case PatrolRoute.Keren4: patrolRoute = get_Keren_Route_4(); + break; + case PatrolRoute.Keren5: patrolRoute = get_Keren_Route_5(); + break; + case PatrolRoute.Keren6: patrolRoute = get_Keren_Route_6(); + break; + case PatrolRoute.Keren7: patrolRoute = get_Keren_Route_7(); + break; + + case PatrolRoute.Bestine1: patrolRoute = get_Bestine_Route_1(); + break; + case PatrolRoute.Bestine2: patrolRoute = get_Bestine_Route_2(); + break; + case PatrolRoute.Bestine3: patrolRoute = get_Bestine_Route_3(); + break; + case PatrolRoute.Bestine4: patrolRoute = get_Bestine_Route_4(); + break; + case PatrolRoute.Bestine5: patrolRoute = get_Bestine_Route_5(); + break; + case PatrolRoute.Bestine6: patrolRoute = get_Bestine_Route_6(); + break; + case PatrolRoute.Bestine7: patrolRoute = get_Bestine_Route_7(); + break; + case PatrolRoute.Bestine8: patrolRoute = get_Bestine_Route_8(); + break; + } + } + + public Vector get_Dearic_Route_1(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(68.0F, 6.00F, -2959F)); + patrolpoints.add(new Point3D(151.93F,6.00F, -2961.66F)); + patrolpoints.add(new Point3D(170.18F, 6.00F, -2992.99F)); + patrolpoints.add(new Point3D(262.76F, 6.00F, -2999.76F)); + patrolpoints.add(new Point3D(275.87F, 6.00F, -3008.44F)); + patrolpoints.add(new Point3D(303.41F, 6.00F, -3005.19F)); + patrolpoints.add(new Point3D(343.31F, 6.00F, -2961.06F)); + patrolpoints.add(new Point3D(379.98F, 6.00F, -2963.31F)); + patrolpoints.add(new Point3D(404.70F, 6.00F, -2980.57F)); + patrolpoints.add(new Point3D(412.54F, 6.00F, -3039.39F)); + patrolpoints.add(new Point3D(423.06F, 6.00F, -3050.75F)); + patrolpoints.add(new Point3D(446.92F, 6.00F, -3046.32F)); + patrolpoints.add(new Point3D(470.48F, 6.00F, -3023.43F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_2(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(76.0F, 6.00F, -2893F)); + patrolpoints.add(new Point3D(153.0F, 6.00F, -2898F)); + patrolpoints.add(new Point3D(162.89F, 6.00F, -2836.9F)); + patrolpoints.add(new Point3D(291.44F, 6.00F, -2844.6F)); + patrolpoints.add(new Point3D(333.19F, 6.00F, -2878.0F)); + patrolpoints.add(new Point3D(337.00F, 6.00F, -2954.0F)); + patrolpoints.add(new Point3D(378.00F, 6.00F, -2959.0F)); + patrolpoints.add(new Point3D(407.00F, 6.00F, -2978.0F)); + patrolpoints.add(new Point3D(414.00F, 6.00F, -3041.0F)); + patrolpoints.add(new Point3D(448.00F, 6.00F, -3043.0F)); + patrolpoints.add(new Point3D(464.00F, 6.00F, -3017.0F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_3(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(199.0F, 6.00F, -2790F)); + patrolpoints.add(new Point3D(200.0F, 6.00F, -2838F)); + patrolpoints.add(new Point3D(294.0F, 6.00F, -2841F)); + patrolpoints.add(new Point3D(335.0F, 6.00F, -2882F)); + patrolpoints.add(new Point3D(341.0F, 6.00F, -2950F)); + patrolpoints.add(new Point3D(378.0F, 6.00F, -2958F)); + patrolpoints.add(new Point3D(405.0F, 6.00F, -2981F)); + patrolpoints.add(new Point3D(414.00F, 6.00F, -3041.0F)); + patrolpoints.add(new Point3D(448.00F, 6.00F, -3043.0F)); + patrolpoints.add(new Point3D(473.0F, 6.00F, -3024F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_4(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(332.0F, 6.00F, -2715F)); + patrolpoints.add(new Point3D(324.0F, 6.00F, -2817F)); + patrolpoints.add(new Point3D(302.0F, 6.00F, -2835F)); + patrolpoints.add(new Point3D(338.0F, 6.00F, -2888F)); + patrolpoints.add(new Point3D(342.0F, 6.00F, -2949F)); + patrolpoints.add(new Point3D(407.0F, 6.00F, -2972F)); + patrolpoints.add(new Point3D(415.0F, 6.00F, -3055F)); + patrolpoints.add(new Point3D(451.0F, 6.00F, -3044F)); + patrolpoints.add(new Point3D(460.0F, 6.00F, -3011F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_5(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(384.0F, 6.00F, -2720F)); + patrolpoints.add(new Point3D(404.0F, 6.00F, -2817F)); + patrolpoints.add(new Point3D(417.0F, 6.00F, -2827F)); + patrolpoints.add(new Point3D(414.0F, 6.00F, -2854F)); + patrolpoints.add(new Point3D(384.0F, 6.00F, -2888F)); + patrolpoints.add(new Point3D(384.0F, 6.00F, -2959F)); + patrolpoints.add(new Point3D(407.0F, 6.00F, -2975F)); + patrolpoints.add(new Point3D(416.0F, 6.00F, -3049F)); + patrolpoints.add(new Point3D(450.0F, 6.00F, -3043F)); + patrolpoints.add(new Point3D(474.0F, 6.00F, -3025F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_6(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(590.0F, 6.00F, -2825F)); + patrolpoints.add(new Point3D(567.0F, 6.00F, -2860F)); + patrolpoints.add(new Point3D(563.0F, 6.00F, -2943F)); + patrolpoints.add(new Point3D(563.0F, 6.00F, -2943F)); + patrolpoints.add(new Point3D(507.0F, 6.00F, -2955F)); + patrolpoints.add(new Point3D(500.0F, 6.00F, -3011F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_7(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(723.0F, 6.00F, -2995F)); + patrolpoints.add(new Point3D(720.0F, 6.00F, -2964F)); + patrolpoints.add(new Point3D(623.0F, 6.00F, -2961F)); + patrolpoints.add(new Point3D(614.0F, 6.00F, -3010F)); + patrolpoints.add(new Point3D(510.0F, 6.00F, -3032F)); + patrolpoints.add(new Point3D(484.0F, 6.00F, -3021F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_8(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(733.0F, 6.00F, -3004F)); + patrolpoints.add(new Point3D(701.0F, 6.00F, -3004F)); + patrolpoints.add(new Point3D(699.0F, 6.00F, -3039F)); + patrolpoints.add(new Point3D(627.0F, 6.00F, -3041F)); + patrolpoints.add(new Point3D(605.0F, 6.00F, -3018F)); + patrolpoints.add(new Point3D(509.0F, 6.00F, -3033F)); + patrolpoints.add(new Point3D(495.0F, 6.00F, -3017F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_9(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(330.0F, 23.00F, -3402F)); + patrolpoints.add(new Point3D(360.0F, 6.00F, -3357F)); + patrolpoints.add(new Point3D(415.0F, 6.00F, -3273F)); + patrolpoints.add(new Point3D(464.0F, 6.00F, -3256F)); + patrolpoints.add(new Point3D(467.0F, 6.00F, -3236F)); + patrolpoints.add(new Point3D(498.0F, 6.00F, -3230F)); + patrolpoints.add(new Point3D(501.0F, 6.00F, -3205F)); + patrolpoints.add(new Point3D(481.0F, 6.00F, -3174F)); + patrolpoints.add(new Point3D(482.0F, 6.00F, -3126F)); + patrolpoints.add(new Point3D(437.0F, 6.00F, -3065F)); + patrolpoints.add(new Point3D(465.0F, 6.00F, -3019F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_10(){// just for tests + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(618.0F, 6.00F, -2972F)); + patrolpoints.add(new Point3D(617.0F, 6.00F, -2980F)); + patrolpoints.add(new Point3D(616.0F, 6.00F, -2990F)); + patrolpoints.add(new Point3D(615.0F, 6.00F, -3010F)); + patrolpoints.add(new Point3D(500.0F, 6.00F, -3035F)); + + return patrolpoints; + } + + public Vector get_Dearic_Route_11(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(332.0F, 6.00F, -2715F)); + return patrolpoints; + } + + + public Vector get_Keren_Route_1(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(1342.0F, 13.00F, 2917F)); + patrolpoints.add(new Point3D(1447.0F, 13.00F, 2825F)); + patrolpoints.add(new Point3D(1463.0F, 14.00F, 2781F)); + patrolpoints.add(new Point3D(1530.0F, 25.00F, 2760F)); + patrolpoints.add(new Point3D(1523.0F, 25.00F, 2731F)); + patrolpoints.add(new Point3D(1555.0F, 29.00F, 2721F)); + patrolpoints.add(new Point3D(1607.0F, 25.00F, 2706F)); + patrolpoints.add(new Point3D(1607.0F, 25.00F, 2706F)); + patrolpoints.add(new Point3D(1601.0F, 25.00F, 2676F)); + patrolpoints.add(new Point3D(1652.0F, 12.00F, 2652F)); + patrolpoints.add(new Point3D(1674.0F, 12.00F, 2637F)); + patrolpoints.add(new Point3D(1674.0F, 12.00F, 2586F)); + patrolpoints.add(new Point3D(1725.0F, 12.00F, 2584F)); + patrolpoints.add(new Point3D(1727.0F, 12.00F, 2559F)); + patrolpoints.add(new Point3D(1758.0F, 12.00F, 2555F)); + patrolpoints.add(new Point3D(1766.0F, 12.00F, 2528F)); + patrolpoints.add(new Point3D(1780.0F, 12.00F, 2520F)); + return patrolpoints; + } + + public Vector get_Keren_Route_2(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(1994.03F, 12.00F, 2769.94F)); + patrolpoints.add(new Point3D(1981.79F, 13.89F, 2736.23F)); + patrolpoints.add(new Point3D(1911.87F, 12F, 2737.51F)); + patrolpoints.add(new Point3D(1892.03F, 12F, 2718.64F)); + patrolpoints.add(new Point3D(1883.43F, 12F, 2727.32F)); + patrolpoints.add(new Point3D(1863.00F, 12F, 2707.36F)); + patrolpoints.add(new Point3D(1883.67F, 12F, 2694.01F)); + patrolpoints.add(new Point3D(1899.48F, 12F, 2661.86F)); + patrolpoints.add(new Point3D(1901.68F, 12F, 2638.95F)); + patrolpoints.add(new Point3D(1897.24F, 12F, 2603.49F)); + patrolpoints.add(new Point3D(1879.39F, 12F, 2563.75F)); + patrolpoints.add(new Point3D(1841.89F, 12F, 2527.75F)); + patrolpoints.add(new Point3D(1824.33F, 12F, 2521.45F)); + patrolpoints.add(new Point3D(1789.56F, 12F, 2518.26F)); + + return patrolpoints; + } + + public Vector get_Keren_Route_3(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(2063.0F, 49.00F, 2794F)); + patrolpoints.add(new Point3D(2020.0F, 49.00F, 2796F)); + patrolpoints.add(new Point3D(1817.0F, 40.00F, 2808F)); + patrolpoints.add(new Point3D(1753.0F, 40.00F, 2808F)); + patrolpoints.add(new Point3D(1715.0F, 40.00F, 2780F)); + patrolpoints.add(new Point3D(1717.0F, 12.00F, 2741F)); + patrolpoints.add(new Point3D(1713.0F, 12.00F, 2639F)); + patrolpoints.add(new Point3D(1695.0F, 12.00F, 2635F)); + patrolpoints.add(new Point3D(1696.0F, 12.00F, 2589F)); + patrolpoints.add(new Point3D(1725.0F, 12.00F, 2585F)); + patrolpoints.add(new Point3D(1727.0F, 12.00F, 2560F)); + patrolpoints.add(new Point3D(1758.0F, 12.00F, 2555F)); + patrolpoints.add(new Point3D(1766.0F, 12.00F, 2527F)); + patrolpoints.add(new Point3D(1781.0F, 12.00F, 2516F)); + + return patrolpoints; + } + + public Vector get_Keren_Route_4(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(1990.0F, 30.00F, 2715F)); + patrolpoints.add(new Point3D(1990.0F, 30.00F, 2682F)); + patrolpoints.add(new Point3D(1988.0F, 12.00F, 2624F)); + patrolpoints.add(new Point3D(1983.0F, 12.00F, 2560F)); + patrolpoints.add(new Point3D(1931.0F, 12.00F, 2535F)); + patrolpoints.add(new Point3D(1902.0F, 12.00F, 2554F)); + patrolpoints.add(new Point3D(1879.0F, 12.00F, 2525F)); + patrolpoints.add(new Point3D(1846.0F, 12.00F, 2504F)); + patrolpoints.add(new Point3D(1806.0F, 12.00F, 2492F)); + patrolpoints.add(new Point3D(1806.0F, 12.00F, 2520F)); + patrolpoints.add(new Point3D(1794.0F, 12.00F, 2519F)); + + return patrolpoints; + } + + public Vector get_Keren_Route_5(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(1342.0F, 13.00F, 2917F)); + patrolpoints.add(new Point3D(1447.0F, 13.00F, 2825F)); + patrolpoints.add(new Point3D(1463.0F, 14.00F, 2781F)); + patrolpoints.add(new Point3D(1530.0F, 25.00F, 2760F)); + patrolpoints.add(new Point3D(1523.0F, 25.00F, 2731F)); + patrolpoints.add(new Point3D(1555.0F, 29.00F, 2721F)); + patrolpoints.add(new Point3D(1607.0F, 25.00F, 2706F)); + patrolpoints.add(new Point3D(1607.0F, 25.00F, 2706F)); + patrolpoints.add(new Point3D(1601.0F, 25.00F, 2676F)); + patrolpoints.add(new Point3D(1652.0F, 12.00F, 2652F)); + patrolpoints.add(new Point3D(1674.0F, 12.00F, 2637F)); + patrolpoints.add(new Point3D(1674.0F, 12.00F, 2586F)); + patrolpoints.add(new Point3D(1725.0F, 12.00F, 2584F)); + patrolpoints.add(new Point3D(1758.0F, 12.00F, 2555F)); + patrolpoints.add(new Point3D(1766.0F, 12.00F, 2528F)); + patrolpoints.add(new Point3D(1780.0F, 12.00F, 2520F)); + return patrolpoints; + } + + public Vector get_Keren_Route_6(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(1980.0F, 10.00F, 2179F)); + patrolpoints.add(new Point3D(1957.0F, 11.00F, 2259F)); + patrolpoints.add(new Point3D(1934.0F, 12.00F, 2341F)); + patrolpoints.add(new Point3D(1947.0F, 12.00F, 2387F)); + patrolpoints.add(new Point3D(1945.0F, 12.00F, 2414F)); + patrolpoints.add(new Point3D(1879.0F, 12.00F, 2419F)); + patrolpoints.add(new Point3D(1847.0F, 12.00F, 2458F)); + patrolpoints.add(new Point3D(1789.0F, 12.00F, 2459F)); + patrolpoints.add(new Point3D(1743.0F, 12.00F, 2458F)); + patrolpoints.add(new Point3D(1728.0F, 12.00F, 2468F)); + patrolpoints.add(new Point3D(1729.0F, 12.00F, 2495F)); + patrolpoints.add(new Point3D(1761.0F, 12.00F, 2495F)); + patrolpoints.add(new Point3D(1764.0F, 12.00F, 2516F)); + patrolpoints.add(new Point3D(1776.0F, 12.00F, 2517F)); + return patrolpoints; + } + + public Vector get_Keren_Route_7(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(1342.0F, 13.00F, 2917F)); + patrolpoints.add(new Point3D(1487.0F, 20.00F, 2808F)); + + return patrolpoints; + } + + public Vector get_Bestine_Route_1(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-978.75F, 12.00F, -3747.46F)); + patrolpoints.add(new Point3D(-996.37F, 12.00F, -3731.11F)); + patrolpoints.add(new Point3D(-1004.13F, 12.00F, -3708.60F)); + patrolpoints.add(new Point3D(-1042.40F, 12.00F, -3672.19F)); + patrolpoints.add(new Point3D(-1067.11F, 12.00F, -3665.97F)); + patrolpoints.add(new Point3D(-1107.36F, 12.00F, -3633.51F)); + patrolpoints.add(new Point3D(-1126.32F, 12.00F, -3650.40F)); + patrolpoints.add(new Point3D(-1144.03F, 12.00F, -3652.36F)); + patrolpoints.add(new Point3D(-1175.46F, 12.00F, -3631.40F)); + patrolpoints.add(new Point3D(-1204.07F, 12.00F, -3627.40F)); + return patrolpoints; + } + + public Vector get_Bestine_Route_2(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-1002.90F, 19.15F, -3593.77F)); + patrolpoints.add(new Point3D(-1053.93F, 12F, -3576.39F)); + patrolpoints.add(new Point3D(-1064.00F, 12F, -3586.90F)); + patrolpoints.add(new Point3D(-1084.30F, 12F, -3583.85F)); + patrolpoints.add(new Point3D(-1100.69F, 12F, -3622.65F)); + patrolpoints.add(new Point3D(-1129.25F, 12F, -3653.48F)); + patrolpoints.add(new Point3D(-1158.12F, 12F, -3654.10F)); + patrolpoints.add(new Point3D(-1191.37F, 12F, -3628.60F)); + patrolpoints.add(new Point3D(-1214.79F, 12F, -3633.39F)); + return patrolpoints; + } + + public Vector get_Bestine_Route_3(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-1104F, 20.00F, -3467F)); + patrolpoints.add(new Point3D(-1084.21F, 12.00F, -3513.44F)); + patrolpoints.add(new Point3D(-1107.65F, 12.00F, -3570.01F)); + patrolpoints.add(new Point3D(-1166.30F, 12.00F, -3527.04F)); + patrolpoints.add(new Point3D(-1182.49F, 12.00F, -3543.62F)); + patrolpoints.add(new Point3D(-1195.03F, 12.00F, -3534.84F)); + patrolpoints.add(new Point3D(-1222.08F, 12.00F, -3567.95F)); + patrolpoints.add(new Point3D(-1245.74F, 12.00F, -3550.56F)); + patrolpoints.add(new Point3D(-1284.93F, 12.00F, -3596.65F)); + patrolpoints.add(new Point3D(-1255.27F, 12.00F, -3620.79F)); + patrolpoints.add(new Point3D(-1223.85F, 12.00F, -3625.50F)); + return patrolpoints; + } + + public Vector get_Bestine_Route_4(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-1224.17F, 14.92F, -3477.66F)); + patrolpoints.add(new Point3D(-1214.17F, 12F, -3520.83F)); + patrolpoints.add(new Point3D(-1239.38F, 12F, -3552.16F)); + patrolpoints.add(new Point3D(-1251.67F, 12F, -3554.41F)); + patrolpoints.add(new Point3D(-1288.84F, 12F, -3605.51F)); + patrolpoints.add(new Point3D(-1253.18F, 12F, -3620.50F)); + patrolpoints.add(new Point3D(-1224.78F, 12F, -3627.92F)); + return patrolpoints; + } + + public Vector get_Bestine_Route_5(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-1289.09F, 10.77F, -3451.00F)); + patrolpoints.add(new Point3D(-1287.35F, 12F, -3499.91F)); + patrolpoints.add(new Point3D(-1293.84F, 12F, -3516.75F)); + patrolpoints.add(new Point3D(-1293.84F, 12F, -3516.75F)); + patrolpoints.add(new Point3D(-1282.01F, 12F, -3531.76F)); + patrolpoints.add(new Point3D(-1286.69F, 12F, -3604.70F)); + patrolpoints.add(new Point3D(-1247.24F, 12F, -3622.33F)); + patrolpoints.add(new Point3D(-1221.27F, 12F, -3616.53F)); + return patrolpoints; + } + + public Vector get_Bestine_Route_6(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-1399.33F, 18.02F, -3842.45F)); + patrolpoints.add(new Point3D(-1378.02F, 10.02F, -3803.54F)); + patrolpoints.add(new Point3D(-1355.98F, 12.25F, -3741.07F)); + patrolpoints.add(new Point3D(-1351.22F, 12.0F, -3703.81F)); + patrolpoints.add(new Point3D(-1301.95F, 12.0F, -3626.74F)); + patrolpoints.add(new Point3D(-1261.14F, 12.0F, -3624.71F)); + patrolpoints.add(new Point3D(-1224.89F, 12.0F, -3631.51F)); + return patrolpoints; + } + + public Vector get_Bestine_Route_7(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-1319.14F, 21.54F, -3854.52F)); + patrolpoints.add(new Point3D(-1327.96F, 24.39F, -3791.74F)); + patrolpoints.add(new Point3D(-1325.62F, 12.0F, -3694.68F)); + patrolpoints.add(new Point3D(-1325.62F, 12.0F, -3694.68F)); + patrolpoints.add(new Point3D(-1313.86F, 12.0F, -3632.90F)); + patrolpoints.add(new Point3D(-1261.17F, 12.0F, -3623.71F)); + patrolpoints.add(new Point3D(-1225.88F, 12.0F, -3631.15F)); + return patrolpoints; + } + + public Vector get_Bestine_Route_8(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(-1143.05F, 14.43F, -3756.47F)); + patrolpoints.add(new Point3D(-1126.50F, 12F, -3691.73F)); + patrolpoints.add(new Point3D(-1188.91F, 12F, -3627.55F)); + patrolpoints.add(new Point3D(-1203.55F, 12F, -3624.19F)); + return patrolpoints; + } + + + public int getTotalSpawnedUnits() { + return totalSpawnedUnits; + } + + public void setTotalSpawnedUnits(int totalSpawnedUnits) { + this.totalSpawnedUnits = totalSpawnedUnits; + } + + public int getDelay() { + return delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } + + public class SpawnerType { + + public static final int SoldierPatrol = 0; + public static final int SoldierDefense = 1; + public static final int VehiclePatrol = 2; + public static final int SiegeVehiclePatrol = 3; + public static final int Barricade = 4; + public static final int Turret = 5; + public static final int Tower = 6; + + } + /* + Soldier Patrol Pylons - Spawns a continuous stream of NPCs to aid in the battle - shown with a Helmet icon. + Vehicle Patrol Pylons - Spawns vehicles that are considerably more lethal than the Soldiers - shown with a Terminal icon. + Siege Vehicle Patrol Pylon - Spawns Rebel Hailfire Driods or Imperial AT-ATs (only spawn at a Level 3 Pylon) - shown with the same Terminal icon. + Barricade Pylon - Spawns a barricade that defends units behind it by giving them a defensive buff - shown with a Barricade icon. + Turret Pylon - Spawns an AI controlled turret that fires on enemy units - shown with a Gun Barrel or Turret Dish icon. + Tower Pylon - Spawns a watch tower that grants intelligence to nearby NPCs and offers combat missions to players - shown with a Tower icon. + */ + + public class PatrolRoute { + + public static final int Dearic1 = 0; + public static final int Dearic2 = 1; + public static final int Dearic3 = 2; + public static final int Dearic4 = 3; + public static final int Dearic5 = 4; + public static final int Dearic6 = 5; + public static final int Dearic7 = 6; + public static final int Dearic8 = 7; + public static final int Dearic9 = 8; + public static final int Dearic10 = 9; + public static final int Dearic11 = 10; + + public static final int Keren1 = 11; + public static final int Keren2 = 12; + public static final int Keren3 = 13; + public static final int Keren4 = 14; + public static final int Keren5 = 15; + public static final int Keren6 = 16; + public static final int Keren7 = 17; + + public static final int Bestine1 = 18; + public static final int Bestine2 = 19; + public static final int Bestine3 = 20; + public static final int Bestine4 = 21; + public static final int Bestine5 = 22; + public static final int Bestine6 = 23; + public static final int Bestine7 = 24; + public static final int Bestine8 = 25; + public static final int Bestine9 = 26; + } +} diff --git a/src/services/gcw/InvasionService.java b/src/services/gcw/InvasionService.java new file mode 100644 index 00000000..8f61c15d --- /dev/null +++ b/src/services/gcw/InvasionService.java @@ -0,0 +1,2438 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.gcw; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.Set; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.apache.mina.core.session.IoSession; + +import protocol.swg.CommPlayerMessage; +import protocol.swg.ObjControllerMessage; +import protocol.swg.PlayClientEffectObjectTransformMessage; +import protocol.swg.objectControllerObjects.NpcConversationMessage; +import protocol.swg.objectControllerObjects.QuestTaskTimerMessage; +import resources.common.OutOfBand; +import resources.common.SpawnPoint; +import resources.datatables.FactionStatus; +import resources.datatables.Factions; +import resources.datatables.GalaxyStatus; +import resources.datatables.GcwType; +import resources.datatables.Options; +import resources.datatables.Posture; +import resources.objects.building.BuildingObject; +import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; +import services.ai.AIActor; +import services.ai.states.AIState; +import services.ai.states.DeathState; +import services.ai.states.WithdrawalState; +import services.gcw.GCWSpawner.PatrolRoute; +import services.gcw.GCWPylon.PylonType; +import services.sui.SUIWindow; +import services.sui.SUIService.ListBoxType; +import services.sui.SUIWindow.SUICallback; +import services.sui.SUIWindow.Trigger; +import main.NGECore; +import engine.clients.Client; +import engine.resources.common.CRC; +import engine.resources.config.Config; +import engine.resources.container.Traverser; +import engine.resources.objects.SWGObject; +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +/** + * @author Charon + */ + +@SuppressWarnings("unused") +public class InvasionService implements INetworkDispatch { + + private NGECore core; + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + protected final Object objectMutex = new Object(); + + private boolean invasionScheduled = false; + + private CreatureObject invasionGeneral = null; + private CreatureObject defendingGeneral = null; + private CreatureObject defendingQuestOfficer = null; + private Vector offensiveQuestOfficers = new Vector(); + private boolean defendingGeneralAlive = true; + + private int invasionLocation=-1; + private String invasionPlanet="tatooine"; + + private Point3D invasionLocationCenter; + private int invadingFaction=Factions.Imperial; + private int defendingFaction=Factions.Rebel; + + private int invasionPhase=1; // Test phase 1 + + private Vector pylonList = new Vector(); + private Vector offensiveSupplyTerminals = new Vector(); + + private long temptimestartreference = 0L; + private boolean ph1_message1sent = false; + private boolean ph1_message2sent = false; + private boolean ph2_message1sent = false; + private boolean ph2_message2sent = false; + private boolean ph2_message3sent = false; + private boolean ph2_message4sent = false; + private boolean ph2_message5sent = false; + private boolean ph2_message6sent = false; + private boolean ph2_message7sent = false; + + private ScheduledFuture defendingGeneralTask = null; + private Map generalWarningLevelMap = new ConcurrentHashMap(); + + private Map invadingCreatures = new ConcurrentHashMap(); + private int invaderRegistryCounter = 0; + private Map defendingCreatures = new ConcurrentHashMap(); + private int defenderRegistryCounter = 0; + private Map demoralizedSoldiers = new ConcurrentHashMap(); + private int demoralizedSoldierRegistryCounter = 0; + private Map disabledVehicles = new ConcurrentHashMap(); + private int disabledVehicleRegistryCounter = 0; + private Map phase2Objects = new ConcurrentHashMap(); + private int phase2ObjectRegistryCounter = 0; + private Vector defensiveBanners = new Vector(); + private Vector defensiveSupplyTerminals = new Vector(); + private TangibleObject defensiveTable; + private Vector offensiveCamps = new Vector(); + + private List offensiveClonerList = new Vector(); + + public InvasionService(final NGECore core) { + this.core = core; + + Config options = core.getOptions(); + if (options != null && options.getInt("ENABLE.INVASIONS") == 0){ + return; + } + + + // Utility code +// Executors.newSingleThreadScheduledExecutor().schedule(() -> { +// arrangePylons(new Point3D(-1238.13F, 56, -3812.84F),100); +// }, 20, TimeUnit.SECONDS); + + + + // Local code to schedule a 20-30 minutes long phase2 invasion + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + + //testPylons(); + // temp time reference, will be server time later + while (NGECore.getInstance().getGalaxyStatus()!=GalaxyStatus.Online){ + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + } + + temptimestartreference = System.currentTimeMillis(); + scheduleInvasionManager(); + invasionScheduled=true; + scheduleInvasionEventManager(); + }, 60, TimeUnit.SECONDS); + // Local code to schedule a 20 minutes long phase2 invasion + + + // Server code to schedule invasions hourly + /* + for (;;){ + while (!invasionScheduled) { + Calendar now = Calendar.getInstance(); + // wait for the next full hour + if (now.get(Calendar.MINUTE)==0 && ! invasionScheduled){ + temptimestartreference = System.currentTimeMillis(); + scheduleInvasionManager(); + scheduleInvasionEventManager(); + invasionScheduled=true; + try { + if (!invasionScheduled) + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + try { + if (invasionScheduled) + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + */ + } + + public void scheduleInvasionManager(){ + + invasionLocation++; // Change Location of invasion + if (invasionLocation>2) + invasionLocation=0; // Rotate + + // Random for now + invasionLocation = new Random().nextInt(2); + + invasionPlanet = getInvasionPlanet(invasionLocation).getName(); + +// invasionLocation=InvasionLocation.Dearic; +// invasionPlanet="talus"; + +// invasionLocation=InvasionLocation.Keren; +// invasionPlanet="naboo"; + +// invasionLocation=InvasionLocation.Bestine; +// invasionPlanet="tatooine"; + + // Make sides random for now. + // Later GCWService will determine the sides + if (new Random().nextFloat()<0.5){ + invadingFaction=Factions.Rebel; + defendingFaction=Factions.Imperial; + } + + if (invasionLocation==InvasionLocation.Keren){ + spawnPylonsKeren(); + } + if (invasionLocation==InvasionLocation.Bestine){ + spawnPylonsBestine(); + } + if (invasionLocation==InvasionLocation.Dearic){ + spawnPylonsDearic(); + } + + spawnDefensiveAssets(); + spawnOffensiveAssets(); + + setInvasionLocationCenter(); + } + + public void scheduleInvasionEventManager(){ + + final Future[] evm = {null}; + evm[0] = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + if (!invasionScheduled){ + Thread.yield(); + evm[0].cancel(false); + } + invasionEventManager(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 10, 2000, TimeUnit.MILLISECONDS); + } + + public void invasionEventManager(){ + + // First message at 0:00 + if (invasionPhase==1 && System.currentTimeMillis()>temptimestartreference + 10 && ! ph1_message1sent){ + send_Phase1_InvaderMessage1(); + send_Phase1_DefenderMessage1(); + ph1_message1sent = true; + //System.out.println("Phase 1 msg1 sent "); + } + + // Message at 15:00 -> 900000 seconds + if (invasionPhase==1 && System.currentTimeMillis()>temptimestartreference + 50000 && ! ph1_message2sent){ + send_Phase1_InvaderMessage2(); + send_Phase1_DefenderMessage2(); + ph1_message2sent = true; + //System.out.println("Phase 1 msg2 sent "); + } + + // Message at 30:00 -> 1800000 seconds + if (invasionPhase==1 && System.currentTimeMillis()>temptimestartreference + 60000 && ! ph2_message1sent){ + invasionPhase=2; + preparePhase2(); + //System.out.println("PHASE 2"); + send_Phase2_InvaderMessage1(); + send_Phase2_DefenderMessage1(); + ph2_message1sent = true; + //System.out.println("Defender msg1 sent "); + } + + // Message at 45:00 -> 2700000 seconds + if (invasionPhase==2 && System.currentTimeMillis()>temptimestartreference + 900000 && ! ph2_message2sent){ // 1200000 + send_Phase2_InvaderMessage2(); + send_Phase2_DefenderMessage2(); + ph2_message2sent = true; + invasionPhase=3; + AIActor actor = (AIActor)defendingGeneral.getAttachment("AI"); + actor.setAIactive(true); + defendingGeneral.setOptionsBitmask(Options.ATTACKABLE); + + defendingGeneral.updatePvpStatus(); + + makeDefensiveGeneralDefenderForNPCs(); + //System.out.println("Defender msg2 sent "); // Local server gives only 30 mins time, so its ~15 mins for this phase + } + + if (defendingGeneral!=null){ + + if (invasionPhase==3 && defendingGeneral.getHealth()temptimestartreference + 1500000 && ! ph2_message3sent){ + sendDefenderWonMessage(); + sendInvaderLostMessage(); + ph2_message3sent = true; + invasionPhase=4; + + // Take care of GCW points + grantGCWPoints(invadingFaction,100); + grantGCWPoints(defendingFaction,1000); + + grantGCWTokens(invadingFaction,10); + grantGCWTokens(defendingFaction,130); + + playVictoryMusic(defendingFaction); + + // set up delayed tasks + //Clone Maps + Map invadingCreaturesClone = new ConcurrentHashMap(); + Map defendingCreaturesClone = new ConcurrentHashMap(); + for (Map.Entry entry : getInvadingCreaturesEntrySet()) { + invadingCreaturesClone.put(entry.getKey(), entry.getValue()); + } + for (Map.Entry entry : getDefendingCreaturesEntrySet()) { + defendingCreaturesClone.put(entry.getKey(), entry.getValue()); + } + + withdrawInvaders(); + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + wipeInvaders(invadingCreaturesClone); + wipeDefenders(defendingCreaturesClone); // Make sure all are deleted + }, 360, TimeUnit.SECONDS); + + + + for (BuildingObject camp : offensiveCamps){ + core.simulationService.remove(camp, camp.getWorldPosition().x, camp.getWorldPosition().z, true); + core.objectService.destroyObject(camp.getObjectID()); + } + + for (CreatureObject officer : offensiveQuestOfficers){ + core.simulationService.remove(officer, officer.getWorldPosition().x, officer.getWorldPosition().z, true); + core.objectService.destroyObject(officer.getObjectID()); + } + for (TangibleObject banner : defensiveBanners){ + core.objectService.destroyObject(banner.getObjectID()); + } + + if (defensiveTable!=null) + core.objectService.destroyObject(defensiveTable.getObjectID()); + if (defendingGeneral!=null) + core.objectService.destroyObject(defendingGeneral.getObjectID()); + if (defendingQuestOfficer!=null) + core.objectService.destroyObject(defendingQuestOfficer.getObjectID()); + if (invasionGeneral!=null) + core.objectService.destroyObject(invasionGeneral.getObjectID()); + + deletePhase2Objects(); + generalWarningLevelMap.clear(); + offensiveSupplyTerminals = new Vector(); + invaderRegistryCounter = 0; + defenderRegistryCounter = 0; + defensiveBanners.clear(); + defensiveSupplyTerminals.clear(); + defensiveTable = null; + defendingGeneralTask.cancel(true); + defendingGeneralTask = null; + + invasionScheduled = false; // free Service + } + + // General defeated + if (invasionPhase==3 && (defendingGeneral.getPosture()==13 || defendingGeneral.getPosture()==14) && ! ph2_message4sent){ + sendInvaderWonMessage(); + sendDefenderLostMessage(); + ph2_message4sent = true; + invasionPhase=4; // Post-Invasion phase + //System.out.println("Defender msg4 sent "); + + // Take care of GCW points + grantGCWPoints(invadingFaction,1000); + grantGCWPoints(defendingFaction,100); + + grantGCWTokens(invadingFaction,130); + grantGCWTokens(defendingFaction,10); + + playVictoryMusic(invadingFaction); + + // Clean Up +// wipeInvaders(); +// wipeDefenders(); + + // set up delayed tasks + //Clone Maps + Map invadingCreaturesClone = new ConcurrentHashMap(); + Map defendingCreaturesClone = new ConcurrentHashMap(); + for (Map.Entry entry : getInvadingCreaturesEntrySet()) { + invadingCreaturesClone.put(entry.getKey(), entry.getValue()); + } + for (Map.Entry entry : getDefendingCreaturesEntrySet()) { + defendingCreaturesClone.put(entry.getKey(), entry.getValue()); + } + + withdrawInvaders(); + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + wipeInvaders(invadingCreaturesClone); + wipeDefenders(defendingCreaturesClone); // Make sure all are deleted + }, 360, TimeUnit.SECONDS); + + + + for (BuildingObject camp : offensiveCamps){ + core.simulationService.remove(camp, camp.getWorldPosition().x, camp.getWorldPosition().z, true); + core.objectService.destroyObject(camp.getObjectID()); + } + + for (CreatureObject officer : offensiveQuestOfficers){ + core.simulationService.remove(officer, officer.getWorldPosition().x, officer.getWorldPosition().z, true); + core.objectService.destroyObject(officer.getObjectID()); + } + for (TangibleObject banner : defensiveBanners){ + core.objectService.destroyObject(banner.getObjectID()); + } + + if (defensiveTable!=null) + core.objectService.destroyObject(defensiveTable.getObjectID()); + if (defendingGeneral!=null) + core.objectService.destroyObject(defendingGeneral.getObjectID()); + if (defendingQuestOfficer!=null) + core.objectService.destroyObject(defendingQuestOfficer.getObjectID()); + if (invasionGeneral!=null) + core.objectService.destroyObject(invasionGeneral.getObjectID()); + + deletePhase2Objects(); + generalWarningLevelMap.clear(); + offensiveSupplyTerminals = new Vector(); + invaderRegistryCounter = 0; + defenderRegistryCounter = 0; + defensiveBanners.clear(); + defensiveSupplyTerminals.clear(); + defensiveTable = null; + defendingGeneralTask.cancel(true); + defendingGeneralTask = null; + + invasionScheduled = false; // free Service + } + + // General at half health + if (invasionPhase==3 && defendingGeneral.getHealth()<0.5*defendingGeneral.getMaxHealth() &&(defendingGeneral.getPosture()!=13 || defendingGeneral.getPosture()!=14) && ! ph2_message5sent){ + //sendInvaderGeneralHalfMessage(); + sendDefenderGeneralHalfMessage(); + ph2_message5sent = true; + } + } + } + + public void withdrawInvaders(){ + for (Map.Entry entry : getInvadingCreaturesEntrySet()) { + CreatureObject creature = entry.getValue(); + if (creature!=null){ + if (creature.getAttachment("AI")!=null){ + AIActor actor = (AIActor)creature.getAttachment("AI"); + if (actor!=null){ + actor.setActorAlive(true); + actor.setAIactive(true); + actor.setIntendedPrimaryAIState(new WithdrawalState()); + actor.setCurrentState(new WithdrawalState()); + creature.setAttachment("isWithdrawn",1); + } + } + } + } + } + + public void grantGCWPoints(int faction, int gcwPoints){ + String factionName = getFactionName(faction); + Vector allPlayers = core.simulationService.getAllNearSameFactionPlayers(500,invasionLocationCenter, getInvasionPlanet(invasionLocation), factionName); + for (CreatureObject player : allPlayers) { + if (player.getFaction().length() > 0 && player.getFactionStatus() > FactionStatus.OnLeave) { + core.gcwService.addGcwPoints(player, gcwPoints, GcwType.Enemy); + } + } + } + + public void grantGCWTokens(int faction, int tokenamount){ + String factionName = getFactionName(faction); + Vector allPlayers = core.simulationService.getAllNearSameFactionPlayers(500,invasionLocationCenter, getInvasionPlanet(invasionLocation), factionName); + for (CreatureObject player : allPlayers) { + if (player.getFaction().length() > 0 && player.getFactionStatus() > FactionStatus.OnLeave) { + + String tokenTemplate = "object/tangible/gcw/shared_gcw_rebel_token.iff"; + String name = "item_gcw_rebel_token"; + String description = "item_gcw_rebel_token"; + if (player.getFaction().equals(Factions.Imperial)){ + tokenTemplate = "object/tangible/gcw/shared_gcw_imperial_token.iff"; + name = "item_gcw_imperial_token"; + description = "item_gcw_imperial_token"; + } + TangibleObject token = (TangibleObject) core.objectService.createObject(tokenTemplate, player.getPlanet()); + + token.setStfFilename("static_item_n"); + token.setStfName(name); + token.setDetailFilename("static_item_d"); + token.setDetailName(description); + + token.setUses(tokenamount); + + player.sendSystemMessage("@static_item_n:"+name+" \\#32CD32 x" + tokenamount +" have been placed in your inventory \\#FFFFFF", (byte)0); + core.playerService.giveItem(player, token); + } + } + + } + + public void registerInvader(CreatureObject registrant){ + synchronized(invadingCreatures) { + // System.out.println("Registered! " + invaderRegistryCounter); + invadingCreatures.put(invaderRegistryCounter++, registrant); + } + } + + public void registerDefender(CreatureObject registrant){ + synchronized(defendingCreatures) { + defendingCreatures.put(defenderRegistryCounter++, registrant); + } + } + + public void registerDemoralizedSoldier(CreatureObject registrant){ + synchronized(demoralizedSoldiers) { + // System.out.println("Registered! " + invaderRegistryCounter); + demoralizedSoldiers.put(demoralizedSoldierRegistryCounter++, registrant); + } + } + + public void registerDisabledVehicle(CreatureObject registrant){ + synchronized(disabledVehicles) { + // System.out.println("Registered! " + invaderRegistryCounter); + disabledVehicles.put(disabledVehicleRegistryCounter++, registrant); + } + } + + public void wipeInvaders(Map invaderMap){ + + for (BuildingObject camp : offensiveCamps){ + core.simulationService.remove(camp, camp.getWorldPosition().x, camp.getWorldPosition().z, true); + core.objectService.destroyObject(camp.getObjectID()); + } + + for (CreatureObject officer : offensiveQuestOfficers){ + core.simulationService.remove(officer, officer.getWorldPosition().x, officer.getWorldPosition().z, true); + core.objectService.destroyObject(officer.getObjectID()); + } + + for (SWGObject cloner : offensiveClonerList){ + core.simulationService.remove(cloner, cloner.getWorldPosition().x, cloner.getWorldPosition().z, true); + core.objectService.destroyObject(cloner.getObjectID()); + } + + + for (Map.Entry entry : invaderMap.entrySet()) { + CreatureObject creature = entry.getValue(); + if (creature!=null){ + if (creature.getAttachment("AI")!=null){ + AIActor actor = (AIActor)creature.getAttachment("AI"); + if (actor!=null){ + //System.out.println("Preparing deletion " + creature.getObjectID()); + actor.prepareDeletion(); + } + } + } + } + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + //System.out.println("Started schedule to destroy " + invaderMap.entrySet().size()); + for (Map.Entry entry : invaderMap.entrySet()) { + CreatureObject creature = entry.getValue(); + if (creature!=null){ + if (creature.getAttachment("AI")!=null){ + AIActor actor = (AIActor)creature.getAttachment("AI"); + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + //System.out.println("destroying Actor " + creature.getObjectID()); + actor.destroyActor(); + } + } + } + }, 5, TimeUnit.SECONDS); + + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + for (Map.Entry entry : invaderMap.entrySet()) { + CreatureObject creature = entry.getValue(); + if (creature!=null){ + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + core.objectService.destroyObject(creature.getObjectID()); + } + } + invaderMap.clear(); + //System.out.println("Destroyed all invaders."); + }, 15, TimeUnit.SECONDS); // Make sure remaining AI is finished with moves that might make them re-appear + } + + public void wipeDefenders(Map defenderMap){ + + for (TangibleObject banner : defensiveBanners){ + core.objectService.destroyObject(banner.getObjectID()); + } + + if (defensiveTable!=null) + core.objectService.destroyObject(defensiveTable.getObjectID()); + if (defendingGeneral!=null) + core.objectService.destroyObject(defendingGeneral.getObjectID()); + if (defendingQuestOfficer!=null) + core.objectService.destroyObject(defendingQuestOfficer.getObjectID()); + + for (Map.Entry entry : defenderMap.entrySet()) { + CreatureObject creature = entry.getValue(); + if (creature!=null){ + if (creature.getAttachment("AI")!=null){ + AIActor actor = (AIActor)creature.getAttachment("AI"); + actor.prepareDeletion(); + } + } + } + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + for (Map.Entry entry : defenderMap.entrySet()) { + CreatureObject creature = entry.getValue(); + if (creature!=null){ + if (creature.getAttachment("AI")!=null){ + AIActor actor = (AIActor)creature.getAttachment("AI"); + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + actor.destroyActor(); + } + } + } + }, 5, TimeUnit.SECONDS); + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + for (Map.Entry entry : defenderMap.entrySet()) { + CreatureObject creature = entry.getValue(); + if (creature!=null){ + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + core.objectService.destroyObject(creature.getObjectID()); + } + } + defenderMap.clear(); + //System.out.println("Destroyed all defenders."); + }, 15, TimeUnit.SECONDS); // Make sure remaining AI is finished with moves that might make them re-appear + + } + + + public void registerPhase2Objects(TangibleObject registrant){ + synchronized(phase2Objects){ + phase2Objects.put(phase2ObjectRegistryCounter++, registrant); + } + } + + public void deletePhase2Objects(){ + for (Map.Entry entry : phase2Objects.entrySet()) { + TangibleObject tano = entry.getValue(); + if (tano!=null){ + core.simulationService.remove(tano, tano.getWorldPosition().x, tano.getWorldPosition().z, true); // Make sure + core.objectService.destroyObject(tano.getObjectID()); + } + } + defendingCreatures.clear(); + } + + + public void spawnOffensiveAssets(){ + spawnOffensiveCamps(); + spawnOffensiveCloners(); + } + + public void spawnDefensiveAssets(){ + spawnDefendingGeneral(); + spawnDefensiveQuestOfficer(); + spawnBanners(); + spawnSupplyTerminals(); + spawnDefensivePlanningTable(); + } + + public void spawnDefensivePlanningTable(){ + if (invasionLocation==InvasionLocation.Keren){ + String template = "object/tangible/terminal/shared_planning_table_keren_reb.iff"; + if (defendingFaction==Factions.Imperial) + template = "object/tangible/terminal/shared_planning_table_keren_imp.iff"; + spawnDefensiveTable(new Point3D(1789.07F, 12, 2530.95F),new Quaternion(1,0F,0,0F),template); + } + if (invasionLocation==InvasionLocation.Bestine){ + String template = "object/tangible/terminal/shared_planning_table_bestine_reb.iff"; + if (defendingFaction==Factions.Imperial) + template = "object/tangible/terminal/shared_planning_table_bestine_imp.iff"; + spawnDefensiveTable(new Point3D(-1196.37F, 12, -3615.20F),new Quaternion(1,0F,0,0F),template); + } + if (invasionLocation==InvasionLocation.Dearic){ + String template = "object/tangible/terminal/shared_planning_table_dearic_reb.iff"; + if (defendingFaction==Factions.Imperial) + template = "object/tangible/terminal/shared_planning_table_dearic_imp.iff"; + spawnDefensiveTable(new Point3D(476.19F, 6, -3026.57F),new Quaternion(-0.37F,0F,0.92F,0F),template); + } + } + + public void spawnDefensiveTable(Point3D position, Quaternion quaternion, String template){ + + defensiveTable = (TangibleObject) core.objectService.createObject(template, 0, getInvasionPlanet(invasionLocation), position, quaternion); + core.simulationService.add(defensiveTable, defensiveTable.getPosition().x, defensiveTable.getPosition().z, true); + + String name = "gcw_reb_defense_table_n"; + String description = "gcw_reb_defense_table_d"; + if (defendingFaction==Factions.Imperial){ + name = "gcw_imp_defense_table_n"; + description = "gcw_imp_defense_table_d"; + } + + defensiveTable.setStfFilename("gcw"); + defensiveTable.setStfName(name); + defensiveTable.setDetailFilename("gcw"); + defensiveTable.setDetailName(description); + } + + public void spawnSupplyTerminals(){ + + if (invasionLocation==InvasionLocation.Keren){ + spawnDefensiveSupplyTerminal(new Point3D(1787.41F, 12, 2521.47F),new Quaternion(0,0F,1,0F)); + } + if (invasionLocation==InvasionLocation.Bestine){ + spawnDefensiveSupplyTerminal(new Point3D(-1212.58F, 12, -3614.57F),new Quaternion(0,0F,1,0F)); + } + if (invasionLocation==InvasionLocation.Dearic){ + spawnDefensiveSupplyTerminal(new Point3D(465.68F, 6, -3006.34F),new Quaternion(0,0F,1,0F)); + } + } + + public void spawnDefensiveSupplyTerminal(Point3D position, Quaternion quaternion){ + + // "object/tangible/terminal/shared_terminal_gcw_build_resource.iff" + String supplyTerminalTemplate = "object/tangible/terminal/shared_terminal_gcw_reb_def.iff"; // shared_terminal_gcw_reb_def.iff + if (defendingFaction==Factions.Imperial) + supplyTerminalTemplate = "object/tangible/terminal/shared_terminal_gcw_imp_def.iff"; + + TangibleObject supplyTerminal1 = (TangibleObject) core.objectService.createObject(supplyTerminalTemplate, 0, getInvasionPlanet(invasionLocation), position, quaternion); + core.simulationService.add(supplyTerminal1, supplyTerminal1.getPosition().x, supplyTerminal1.getPosition().z, true); + supplyTerminal1.setStfFilename("gcw"); + supplyTerminal1.setStfName("terminal_gcw_reb_def_n"); + supplyTerminal1.setDetailFilename("gcw"); + supplyTerminal1.setDetailName("terminal_gcw_reb_def_d"); + if (defendingFaction==Factions.Imperial){ + supplyTerminalTemplate = "object/tangible/terminal/shared_terminal_gcw_imp_def.iff"; + supplyTerminal1.setStfFilename("gcw"); + supplyTerminal1.setStfName("terminal_gcw_reb_def_n"); + supplyTerminal1.setDetailFilename("gcw"); + supplyTerminal1.setDetailName("terminal_gcw_reb_def_d"); + } + defensiveSupplyTerminals.add(supplyTerminal1); + } + + public void supplyTerminalSUI(CreatureObject user, int childMenu){ + if (invasionPhase!=1) + return; // prevent exploit + String terminalName = "@gcw:terminal_gcw_reb_def_n"; + if (defendingFaction==Factions.Imperial) + terminalName = "@gcw:terminal_gcw_imp_def_n"; + + Map suiOptions = new HashMap(); + suiOptions.put((long) 1, "@gcw:gcw_barricade_tool_n"); + suiOptions.put((long) 2, "@gcw:gcw_spawner_tool_n"); + suiOptions.put((long) 3, "@gcw:gcw_turret_tool_n"); + suiOptions.put((long) 4, "@gcw:gcw_tower_tool_n"); + final SUIWindow window = core.suiService.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, terminalName, "For now the tools are directly available.", suiOptions, user, null, 10); + Vector returnList = new Vector(); + + returnList.add("List.lstList:SelectedRow"); + window.addHandler(0, "", Trigger.TRIGGER_OK, returnList, new SUICallback() + { + public void process(SWGObject owner, int eventType, Vector returnList) + { + if (invasionPhase!=1) + return; // prevent exploit + int index = Integer.parseInt(returnList.get(0)); + int childIndex = (int) window.getObjectIdByIndex(index); + + CreatureObject player = (CreatureObject) owner; + SWGObject inventory = player.getSlottedObject("inventory"); + Planet planet = player.getPlanet(); + + switch(childIndex) + { + case 1: + TangibleObject barricadeTool = (TangibleObject) core.objectService.createObject("object/tangible/gcw/crafting_quest/shared_gcw_barricade_tool.iff", planet); + barricadeTool.setStfFilename("gcw"); + barricadeTool.setStfName("gcw_barricade_tool_n"); + barricadeTool.setDetailFilename("gcw"); + barricadeTool.setDetailName("gcw_barricade_tool_d"); + barricadeTool.setUses(10); + inventory.add(barricadeTool); + break; + + case 2: + TangibleObject spawnerTool = (TangibleObject) core.objectService.createObject("object/tangible/gcw/crafting_quest/shared_gcw_spawner_tool.iff", planet); + spawnerTool.setStfFilename("gcw"); + spawnerTool.setStfName("gcw_spawner_tool_n"); + spawnerTool.setDetailFilename("gcw"); + spawnerTool.setDetailName("gcw_spawner_tool_d"); + spawnerTool.setUses(10); + inventory.add(spawnerTool); + break; + + case 3: + TangibleObject turretTool = (TangibleObject) core.objectService.createObject("object/tangible/gcw/crafting_quest/shared_gcw_turret_tool.iff", planet); + turretTool.setStfFilename("gcw"); + turretTool.setStfName("gcw_turret_tool_n"); + turretTool.setDetailFilename("gcw"); + turretTool.setDetailName("gcw_turret_tool_d"); + turretTool.setUses(10); + inventory.add(turretTool); + break; + + case 4: + TangibleObject towerTool = (TangibleObject) core.objectService.createObject("object/tangible/gcw/crafting_quest/shared_gcw_tower_tool.iff", planet); + towerTool.setStfFilename("gcw"); + towerTool.setStfName("gcw_tower_tool_n"); + towerTool.setDetailFilename("gcw"); + towerTool.setDetailName("gcw_tower_tool_d"); + towerTool.setUses(10); + inventory.add(towerTool); + break; + } + } + }); + + core.suiService.openSUIWindow(window); + + } + + public void supplyOffensiveTerminalSUI(CreatureObject user, int childMenu){ + if (invasionPhase!=1) + return; // prevent exploit + String terminalName = "@gcw:terminal_gcw_reb_offensiv_n"; + if (defendingFaction==Factions.Imperial) + terminalName = "@gcw:terminal_gcw_imp_offensiv_n"; + Map suiOptions = new HashMap(); + suiOptions.put((long) 1, "@gcw:gcw_patrol_tool_n"); + suiOptions.put((long) 2, "@gcw:gcw_vehicle_tool_n"); + final SUIWindow window = core.suiService.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, terminalName, "For now the tools are directly available", suiOptions, user, null, 10); + Vector returnList = new Vector(); + + returnList.add("List.lstList:SelectedRow"); + window.addHandler(0, "", Trigger.TRIGGER_OK, returnList, new SUICallback() + { + public void process(SWGObject owner, int eventType, Vector returnList) + { + if (invasionPhase!=1) + return; // prevent exploit + int index = Integer.parseInt(returnList.get(0)); + int childIndex = (int) window.getObjectIdByIndex(index); + + CreatureObject player = (CreatureObject) owner; + SWGObject inventory = player.getSlottedObject("inventory"); + Planet planet = player.getPlanet(); + + switch(childIndex) + { + case 1: + TangibleObject barricadeTool = (TangibleObject) core.objectService.createObject("object/tangible/gcw/crafting_quest/shared_gcw_patrol_tool.iff", planet); + barricadeTool.setStfFilename("gcw"); + barricadeTool.setStfName("gcw_patrol_tool_n"); + barricadeTool.setDetailFilename("gcw"); + barricadeTool.setDetailName("gcw_patrol_tool_d"); + barricadeTool.setUses(10); + inventory.add(barricadeTool); + break; + + case 2: + TangibleObject spawnerTool = (TangibleObject) core.objectService.createObject("object/tangible/gcw/crafting_quest/shared_gcw_vehicle_tool.iff", planet); + spawnerTool.setStfFilename("gcw"); + spawnerTool.setStfName("gcw_vehicle_tool_n"); + spawnerTool.setDetailFilename("gcw"); + spawnerTool.setDetailName("gcw_vehicle_tool_d"); + spawnerTool.setUses(10); + inventory.add(spawnerTool); + break; + } + } + }); + + core.suiService.openSUIWindow(window); + } + + public void usePylon(CreatureObject user, GCWPylon pylon){ + + // check pylon filling status + if (pylon.getAttachment("Filling")==null) + return; + + if (user.getWorldPosition().getDistance2D(pylon.getWorldPosition())>7){ + user.sendSystemMessage("@gcw:pylon_too_far",(byte) 0); + return; + } + + int pylonFilling = (int) pylon.getAttachment("Filling"); + if (pylonFilling>=100){ + user.sendSystemMessage("@gcw:pylon_construction_complete",(byte) 0); + return; + } + + if (!(CRC.StringtoCRC(user.getFaction())==pylon.getPylonFaction())){ + user.sendSystemMessage("@gcw:pylon_construction_cannot_use",(byte) 0); + return; + } + + if (!user.getFaction().equals(getFactionName(pylon.getPylonFaction()))){ + return; + } + // ToDo: Consider Factional Helpers + if (user.getFaction().equals(getFactionName(pylon.getPylonFaction())) && user.getFactionStatus() tools = new Vector(); + user.getSlottedObject("inventory").viewChildren(user, true, false, new Traverser() { + @Override + public void process(SWGObject item) { + if (item.getTemplate().equals(foundToolTemplate)) { + if (tools.size()==0) + tools.add((TangibleObject)item); + else { + TangibleObject itemTANO = (TangibleObject)item; + if (itemTANO.getUses()[] fut = {null}; + fut[0] = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + //user.sendSystemMessage(""+countdown[0], (byte)0); + countdown[0]--; + // check if user has moved + if (userpos.getDistance2D(user.getWorldPosition())>0.2){ + // cancel count-down + fut[0].cancel(true); + cancelled[0] = true; + user.setConstructing(false); + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + user.sendSystemMessage("@gcw:pylon_construction_moved",(byte) 0); + } + if (user.isInCombat()){ + fut[0].cancel(true); + cancelled[0] = true; + user.setConstructing(false); + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + user.sendSystemMessage("@gcw:pylon_construction_entered_combat",(byte) 0); + } + if (user.getPosture()==13 & user.getPosture()==14){ + fut[0].cancel(true); + cancelled[0] = true; + user.setConstructing(false); + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + user.sendSystemMessage("@gcw:pylon_construction_incapacitated",(byte) 0); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 0, 1, TimeUnit.SECONDS); + + scheduler.schedule(new Runnable() { + @Override + public void run() { + try { + fut[0].cancel(true); + if (! cancelled[0]){ + TangibleObject tool = tools.get(0); + updatePylonFilling(pylon, tool); + user.setConstructing(false); + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + core.buffService.addBuffToCreature(user, "gcw_fatigue", user); + // increase fatigue + user.setGCWFatigue(user.getGCWFatigue()+1); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, constructiontimeagain, TimeUnit.SECONDS); + + } + + public void updatePylonFilling(GCWPylon pylon, TangibleObject tool){ + + int pylonFilling = (int)pylon.getAttachment("Filling"); + String pylonName = (String)pylon.getAttachment("Name"); + // determine power of tool + int power = 15; // assume 15 for now + + pylonFilling += power; + if (pylonFilling>100) + pylonFilling=100; + + String newPylonName = pylonName + " " + pylonFilling +"/100"; + pylon.setCustomName(newPylonName); + pylon.setAttachment("Filling",pylonFilling); + pylon.setResourceFilling(pylonFilling); + + + tool.setUses(tool.getUses()-1); + if (tool.getUses()==0){ + core.objectService.destroyObject(tool.getObjectID()); + } + } + + public void useBarricade(CreatureObject user, TangibleObject structure){ + + if (!user.getFaction().equals(getFactionName(defendingFaction))){ + return; + } + // ToDo: Consider Factional Helpers + if (user.getFaction().equals(getFactionName(defendingFaction)) && user.getFactionStatus()=structure.getMaximumCondition()){ + return; + } + if (user.isConstructing()) + return; + if (structureCondition<10000){ + user.sendSystemMessage("@gcw:gcw_object_doesnt_need_repair",(byte) 0); + return; + } + + + SUIWindow window = core.suiService.createSUIWindow("Script.countdownTimerBar", user, null, 5); + core.suiService.openTimerSUIWindow(window, "@gcw:reparing_gcw_object", 10); // also influenced by fatigue? + + user.setConstructing(true); + int repairtimeagain = 10; + int[] countdown = {repairtimeagain}; + final Point3D userpos = user.getWorldPosition(); + boolean[] cancelled = {false}; + final Future[] fut = {null}; + fut[0] = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + countdown[0]--; + // check if user has moved + if (userpos.getDistance2D(user.getWorldPosition())>0.2){ + // cancel count-down + fut[0].cancel(true); + cancelled[0] = true; + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + user.setConstructing(false); + user.sendSystemMessage("@gcw:pylon_construction_moved",(byte) 0); + } + if (user.isInCombat()){ + fut[0].cancel(true); + cancelled[0] = true; + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + user.setConstructing(false); + user.sendSystemMessage("@gcw:pylon_construction_entered_combat",(byte) 0); + } + if (user.getPosture()==13 & user.getPosture()==14){ + fut[0].cancel(true); + cancelled[0] = true; + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + user.setConstructing(false); + user.sendSystemMessage("@gcw:pylon_construction_incapacitated",(byte) 0); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 0, 1, TimeUnit.SECONDS); + + scheduler.schedule(new Runnable() { + @Override + public void run() { + try { + fut[0].cancel(true); + if (! cancelled[0]){ + int repairAmount = 5000; + int newCondition = structureCondition-repairAmount; + if (newCondition<0) + newCondition=0; + + structure.setConditionDamage(newCondition); + user.setConstructing(false); + tool.setUses(tool.getUses()-1); + if (tool.getUses()==0){ + core.objectService.destroyObject(tool.getObjectID()); + } + core.suiService.closeSUIWindow(window.getOwner(),window.getWindowId()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, repairtimeagain, TimeUnit.SECONDS); + + } + + public TangibleObject retrieveToolFromInventory(CreatureObject user, String toolTemplate){ + + if (toolTemplate.length()==0) + return null; + + // Find the according tool with the lowest uses in user's inventory + final String foundToolTemplate = toolTemplate; + Vector tools = new Vector(); + user.getSlottedObject("inventory").viewChildren(user, true, false, new Traverser() { + @Override + public void process(SWGObject item) { + if (item.getTemplate().equals(foundToolTemplate)) { + if (tools.size()==0) + tools.add((TangibleObject)item); + else { + TangibleObject itemTANO = (TangibleObject)item; + if (itemTANO.getUses()General is null"); + e.printStackTrace(); + } + } + defendingGeneralAlive = true; + + final Future[] dgt = {null}; + dgt[0] = defendingGeneralTask = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + AIActor actor = (AIActor)defendingGeneral.getAttachment("AI"); + if (actor.getCurrentState().getClass().equals(DeathState.class)){ + defendingGeneralAlive = false; + Thread.yield(); + dgt[0].cancel(false); + } + for (CreatureObject damager : actor.getDamageMap().keySet()){ + if (damager.getOwnerId()>0){ // For pets doing damage + damager = (CreatureObject)core.objectService.getObject(damager.getOwnerId()); + } + if (!damager.isPlayer()) + continue; + int warningLevel = 0; + + if (generalWarningLevelMap.get(damager)!=null) + warningLevel = generalWarningLevelMap.get(damager); + + if (actor.getDamageMap().get(damager)>3000 && warningLevel==0){ + // Warning 1 + generalWarningLevelMap.put(damager,1); + damager.sendSystemMessage("Attacking the general puts you at risk to become attackable by other players!", (byte) 0); + } + + if (actor.getDamageMap().get(damager)>10000 && warningLevel==1){ + // Warning 2 + generalWarningLevelMap.put(damager,2); + damager.sendSystemMessage("Continuing your attacks on the general will turn you special forces!", (byte) 0); + } + + if (actor.getDamageMap().get(damager)>15000 && warningLevel==2){ + // Warning 3 -> turn overt + generalWarningLevelMap.put(damager,3); + damager.sendSystemMessage("Your faction status is now special forces!", (byte) 0); + damager.setFactionStatus(FactionStatus.SpecialForces); + damager.updatePvpStatus(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 10, 5000, TimeUnit.MILLISECONDS); + + } + + public void spawnDefensiveQuestOfficer(){ + + String questOfficerTemplate = ""; + if (invadingFaction==Factions.Imperial){ + questOfficerTemplate = "rebel_defensive_quest_officer"; + } + if (invadingFaction==Factions.Rebel){ + questOfficerTemplate = "imp_defensive_quest_officer"; + } + + if (invasionLocation==InvasionLocation.Keren){ + defendingQuestOfficer = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "naboo", 0L, 1787, 12, 2531, 1, 0); + } + if (invasionLocation==InvasionLocation.Bestine){ + defendingQuestOfficer = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "tatooine", 0L, -1195, 12, -3620, 1, 0); + } + if (invasionLocation==InvasionLocation.Dearic){ + defendingQuestOfficer = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "talus", 0L, 478, 6, -3023, 0, 1); + } + } + + public void spawnOffensiveGeneral(){ + + String generalTemplate = "rebel_offensive_invasion_general"; + if (invadingFaction==Factions.Imperial){ + generalTemplate = "imp_offensive_invasion_general"; + } + + if (invasionLocation==InvasionLocation.Keren){ + invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "naboo", 0L, 1206.99F, 7.33F, 3057.06F, 0.85F, 0.51F); + } + if (invasionLocation==InvasionLocation.Bestine){ + invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "tatooine", 0L, -900, 12, -3782, 1, 0); + } + if (invasionLocation==InvasionLocation.Dearic){ + invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "talus", 0L, -894.90F, 9.93F, -2993.29F, 0.96F, 0.26F); + } + + } + + public void spawnOffensiveCamps(){ + String campTemplate = "object/building/poi/shared_scout_camp_s5.iff"; + if (invadingFaction==Factions.Imperial){ + campTemplate = "object/building/poi/shared_scout_camp_s5.iff"; + } + if (invasionLocation==InvasionLocation.Keren){ + spawnOffensiveCamp(new Point3D(1820, 17, 2192),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + spawnOffensiveCamp(new Point3D(2131, 60, 2766),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + spawnOffensiveCamp(new Point3D(1212, 7, 3054),new Quaternion(1.00F,0F,0.00F,0F),campTemplate); + + spawnOffensiveQuestOfficer(new Point3D(1820, 17, 2192), new Quaternion(0.81F,0F,-0.58F,0F)); + spawnOffensiveQuestOfficer(new Point3D(2135.60F,60.0F,2769.78F), new Quaternion(-0.58F,0F,0.81F,0F)); + spawnOffensiveQuestOfficer(new Point3D(1212, 7, 3054), new Quaternion(0.51F,0F,0.85F,0F)); + + spawnOffensiveGeneral(); + + spawnOffensiveSupplyTerminal(new Point3D(1204.51F,7.33F,3054.27F), new Quaternion(0.28F,0F,0.95F,0F)); + spawnOffensiveSupplyTerminal(new Point3D(2139.16F,60.0F,2765.92F), new Quaternion(0.98F,0F,-0.14F,0F)); + spawnOffensiveSupplyTerminal(new Point3D(1828.02F,17.34F,2192.75F), new Quaternion(0.96F,0F,-0.26F,0F)); + } + if (invasionLocation==InvasionLocation.Bestine){ + spawnOffensiveCamp(new Point3D(-900,24, -3782),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + spawnOffensiveCamp(new Point3D(-1253,44.77F, -3348),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + spawnOffensiveCamp(new Point3D(-1184,62.95F, -3821),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + + spawnOffensiveQuestOfficer(new Point3D(-900,24, -3782), new Quaternion(0.81F,0F,-0.58F,0F)); + spawnOffensiveQuestOfficer(new Point3D(-1253,44, -3348), new Quaternion(-0.58F,0F,0.81F,0F)); + spawnOffensiveQuestOfficer(new Point3D(-1184,62, -3821), new Quaternion(0.51F,0F,0.85F,0F)); + + spawnOffensiveGeneral(); + + spawnOffensiveSupplyTerminal(new Point3D(-903,24, -3782), new Quaternion(0.28F,0F,0.95F,0F)); + spawnOffensiveSupplyTerminal(new Point3D(-1256,44, -3348), new Quaternion(0.98F,0F,-0.14F,0F)); + spawnOffensiveSupplyTerminal(new Point3D(-1188,62, -3821), new Quaternion(0.96F,0F,-0.26F,0F)); + } + if (invasionLocation==InvasionLocation.Dearic){ + + spawnOffensiveCamp(new Point3D(-890,9.93F, -2994),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + spawnOffensiveCamp(new Point3D(-2,6, -2805),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + spawnOffensiveCamp(new Point3D(352.85F,6F, -2606.14F),new Quaternion(0.00F,0F,1.00F,0F),campTemplate); + + spawnOffensiveGeneral(); + + spawnOffensiveQuestOfficer(new Point3D(-890,9, -2994), new Quaternion(0.81F,0F,-0.58F,0F)); + spawnOffensiveQuestOfficer(new Point3D(-1.70F,6, -2802.84F), new Quaternion(0.52F,0F,0.85F,0F)); + spawnOffensiveQuestOfficer(new Point3D(355,6, -2605), new Quaternion(0.00F,0F,1.00F,0F)); + + spawnOffensiveSupplyTerminal(new Point3D(-882.80F,9.93F, -2994.76F), new Quaternion(1.00F,0F,0.00F,0F)); + spawnOffensiveSupplyTerminal(new Point3D(-1.33F,6, -2807.17F), new Quaternion(0.87F,0F,0.48F,0F)); + spawnOffensiveSupplyTerminal(new Point3D(347.56F,6, -2604.86F), new Quaternion(0.24F,0F,0.97F,0F)); + + } + } + + public void spawnOffensiveCamp(Point3D position, Quaternion quaternion, String campTemplate){ + // object/building/poi/shared_gcw_camp_rebel_recruiter.iff This IS the right template, but the client doesn't spawn it! + // This works at least object/building/poi/shared_scout_camp_s5.iff + BuildingObject camp = (BuildingObject) core.objectService.createObject(campTemplate, 0, getInvasionPlanet(invasionLocation), position, quaternion); + //TangibleObject camp = (TangibleObject) core.objectService.createObject(campTemplate, 0, core.terrainService.getPlanetByName("talus"), new Point3D(-890,9, -2994), quaternion); + core.simulationService.add(camp, camp.getPosition().x, camp.getPosition().z, true); + offensiveCamps.add(camp); + } + + + public void spawnOffensiveQuestOfficer(Point3D position, Quaternion quaternion){ + + String questOfficerTemplate = "rebel_invasion_captain"; + if (invadingFaction==Factions.Imperial) + questOfficerTemplate = "imp_invasion_captain"; + CreatureObject offensiveQuestOfficer = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(questOfficerTemplate, getInvasionPlanet(invasionLocation).getName(), 0L, position.x, position.y, position.z, quaternion.w, quaternion.x, quaternion.y,quaternion.z,-1); + offensiveQuestOfficers.add(offensiveQuestOfficer); + } + + public void spawnOffensiveSupplyTerminal(Point3D position, Quaternion quaternion){ + + // "object/tangible/terminal/shared_terminal_gcw_build_resource.iff" + String supplyTerminalTemplate = "object/tangible/terminal/shared_terminal_gcw_reb_offensiv.iff"; + if (invadingFaction==Factions.Imperial) + supplyTerminalTemplate = "object/tangible/terminal/shared_terminal_gcw_imp_offensiv.iff"; + + TangibleObject supplyTerminal1 = (TangibleObject) core.objectService.createObject(supplyTerminalTemplate, 0, getInvasionPlanet(invasionLocation), position, quaternion); + core.simulationService.add(supplyTerminal1, supplyTerminal1.getPosition().x, supplyTerminal1.getPosition().z, true); + supplyTerminal1.setStfFilename("gcw"); + supplyTerminal1.setStfName("terminal_gcw_reb_offensiv_n"); + supplyTerminal1.setDetailFilename("gcw"); + supplyTerminal1.setDetailName("terminal_gcw_reb_offensiv_d"); + if (invadingFaction==Factions.Imperial){ + supplyTerminalTemplate = "object/tangible/terminal/shared_terminal_gcw_imp_offensiv.iff"; + supplyTerminal1.setStfFilename("gcw"); + supplyTerminal1.setStfName("terminal_gcw_imp_offensiv_n"); + supplyTerminal1.setDetailFilename("gcw"); + supplyTerminal1.setDetailName("terminal_gcw_imp_offensiv_d"); + } + offensiveSupplyTerminals.add(supplyTerminal1); + } + + public void preparePhase2(){ + for (GCWPylon pylon : pylonList){ + pylon.convertToPhase2Object(); + core.objectService.destroyObject(pylon.getObjectID()); + } + pylonList.clear(); + pylonList = null; + for (TangibleObject defensiveSupplyTerminal : defensiveSupplyTerminals){ + core.objectService.destroyObject(defensiveSupplyTerminal.getObjectID()); + } + for (TangibleObject offensiveSupplyTerminal : offensiveSupplyTerminals){ + core.objectService.destroyObject(offensiveSupplyTerminal.getObjectID()); + } + + + } + + public void spawnBanners(){ + if (invasionLocation==InvasionLocation.Keren){ + spawnKerenBanners(); + } + if (invasionLocation==InvasionLocation.Bestine){ + spawnBestineBanners(); + } + if (invasionLocation==InvasionLocation.Dearic){ + spawnDearicBanners(); + } + } + + public void spawnDearicBanners(){ + + // Starport + createBanner(329.34F, 6, -2936.67F, 0.71F, 0.7F); + createBanner(329.34F, 6, -2925.15F, 0.71F, 0.7F); + + createBanner(414.98F, 6, -3027.86F, 0.71F, -0.7F); + createBanner(414.98F, 6, -2988.05F, 0.71F, -0.7F); + createBanner(448.98F, 6, -3028.05F, 0.68F, -0.73F); + createBanner(448.98F, 6, -2987.95F, 0.70F, 0.71F); + + createBanner(369.96F, 6, -2944.02F, 1.00F, 0.0F); + + createBanner(537.96F, 6, -3038.97F, 0.00F, 1.0F); + + createBanner(569.96F, 6, -2940.37F, 0.71F, -0.69F); + + createBanner(476.09F, 6, -2955.1F, 0.71F, 0.69F); + + createBanner(471.56F, 6, -3004.66F, 1.0F, 0.00F); + createBanner(488.40F, 6, -3004.66F, 1.0F, 0.00F); + + createBanner(524.88F, 6.51F, -3004.96F, 0.927F, 0.374F); + createBanner(525.03F, 6.51F, -2974.90F, 0.91F, -0.41F); + createBanner(555.13F, 6.51F, -2975.05F, 0.93F, 0.37F); + createBanner(555.15F, 6.51F, -3004.96F, 0.39F, 0.922F); + + } + + public void spawnKerenBanners(){ + + // Starport + createBanner(1436.87F, 13, 2764.41F, 0.71F, 0.7F); + createBanner(1436.46F, 13, 2777.70F, 0.71F, 0.7F); + + } + + public void spawnBestineBanners(){ + + // Starport + } + + public void createBanner(float x, float y, float z, float qy, float qw){ + Quaternion quaternion = new Quaternion(qy,0F,qw,0F); //object/installation/battlefield/destructible shared_banner_rebel_style_01.iff + String bannerTemplate = "object/tangible/gcw/shared_flip_banner_onpole_rebel.iff"; //object/tangible/event_perk/shared_banner_rebel_style_01.iff + String factionString = "rebel_banner"; + if (defendingFaction==Factions.Imperial){ + bannerTemplate = "object/tangible/gcw/shared_flip_banner_onpole_imperial.iff"; + factionString = "imperial_banner"; + } + TangibleObject banner = (TangibleObject) core.objectService.createObject(bannerTemplate, 0, getInvasionPlanet(invasionLocation), new Point3D(x, y, z), quaternion); + core.simulationService.add(banner, banner.getPosition().x, banner.getPosition().z, true); + banner.setStfFilename("obj_n"); + banner.setStfName(factionString); + banner.setDetailFilename("obj_d"); + banner.setDetailName(factionString); + defensiveBanners.add(banner); + } + + public int getInvasionPhase() { + return invasionPhase; + } + + public void setInvasionPhase(int invasionPhase) { + this.invasionPhase = invasionPhase; + } + + // Phase 1 messages + + public void send_Phase1_InvaderMessage1(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_call_to_arms_imperial_" + getInvasionLocationName(); + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_call_to_arms_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void send_Phase1_DefenderMessage1(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_construct_defenses_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_construct_defenses_rebel_" + getInvasionLocationName(); + sendMessageToClients(defendingFaction, message); + } + + public void send_Phase1_InvaderMessage2(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_rally_for_invasion_imperial_" + getInvasionLocationName(); + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_rally_for_invasion_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void send_Phase1_DefenderMessage2(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_building_almost_complete_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_building_almost_complete_rebel_" + getInvasionLocationName(); + sendMessageToClients(defendingFaction, message); + } + + + + // Phase 2 messages + + public void send_Phase2_InvaderMessage1(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_attack_city_imperial_" + getInvasionLocationName(); + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_attack_city_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void send_Phase2_DefenderMessage1(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_man_defenses_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_man_defenses_rebel_" + getInvasionLocationName(); + sendMessageToClients(defendingFaction, message); + } + + public void send_Phase2_InvaderMessage2(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_attack_half_done_imperial_" + getInvasionLocationName(); + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_attack_city_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void send_Phase2_DefenderMessage2(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_defense_half_done_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_defense_half_done_rebel_" + getInvasionLocationName(); + sendMessageToClients(defendingFaction, message); + } + + public void sendInvaderWonMessage(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_won_imperial_" + getInvasionLocationName(); + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_won_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void sendDefenderWonMessage(){ + String message = ""; + if (getInvasionLocationName().equals("talus_dearic")){ + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_won_attack_imeprial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_won_attack_rebel_" + getInvasionLocationName(); + } else { + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_safe_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_safe_rebel_" + getInvasionLocationName(); + } + sendMessageToClients(defendingFaction, message); + } + + public void sendInvaderLostMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_lost_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_lost_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void sendCitySafeMessage(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_end_safe_imperial_" + getInvasionLocationName(); + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_end_safe_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void sendDefenderLostMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_lost_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_lost_rebel_" + getInvasionLocationName(); + sendMessageToClients(defendingFaction, message); + } + + public void sendInvaderGeneralAttackMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_attack_half_done_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_attack_half_done_rebel_" + getInvasionLocationName(); + sendMessageToClients(invadingFaction, message); + } + + public void sendDefenderGeneralAttackMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_general_under_attack_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_general_under_attack_rebel_" + getInvasionLocationName(); + sendMessageToClients(defendingFaction, message); + } + + public void sendInvaderGeneralHalfMessage(){ // Is there any? +// String message = ""; +// if (defendingFaction==Factions.Imperial) +// message = "@gcw:gcw_announcement_city_lost_imperial_" + getInvasionLocationName(); +// if (defendingFaction==Factions.Rebel) +// message = "@gcw:gcw_announcement_city_lost_rebel_" + getInvasionLocationName(); +// sendMessageToClients(invadingFaction, message); + } + + public void sendDefenderGeneralHalfMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_invasion_almost_defeated_imperial_" + getInvasionLocationName(); + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_invasion_almost_defeated_rebel_" + getInvasionLocationName(); + sendMessageToClients(defendingFaction, message); + } + + public void sendMessageToClients(int tofaction, String message){ + String modelTemplate = defendingGeneral.getTemplate(); + if (invadingFaction==tofaction) + modelTemplate = invasionGeneral.getTemplate(); + + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + String faction = ((CreatureObject)client.getParent()).getFaction(); + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation)) && faction.equals(getFactionName(tofaction))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel(modelTemplate); + client.getSession().write(comm.serialize()); + } + } + } + } + + + + public Planet getInvasionPlanet(int location){ + Planet planet = null; + switch (location){ + case InvasionLocation.Dearic : planet = core.terrainService.getPlanetByName("talus"); + break; + case InvasionLocation.Keren : planet = core.terrainService.getPlanetByName("naboo"); + break; + case InvasionLocation.Bestine : planet = core.terrainService.getPlanetByName("tatooine"); + break; + } + return planet; + } + + public void makeDefensiveGeneralDefenderForNPCs(){ + Vector enemies = core.simulationService.getAllNearNonSameFactionNPCs(50, defendingGeneral); + if (defendingGeneral==null) + return; + for (CreatureObject enemy : enemies) { + AIActor actor = (AIActor)enemy.getAttachment("AI"); + if (actor==null) + return; + actor.setLastPositionBeforeStateChange(enemy.getWorldPosition()); + actor.addDefender(defendingGeneral); + } + } + + public float getDistanceToDefensiveGeneral(CreatureObject checker){ + //float dist = checker.getWorldPosition().getDistance2D(defendingGeneral.getWorldPosition()); + //return dist; + return NGECore.getInstance().aiService.distanceSquared2D(defendingGeneral.getWorldPosition(), checker.getWorldPosition()); + } + + public CreatureObject getDefensiveGeneral(){ + return defendingGeneral; + } + + public boolean checkInvasionDeath(CreatureObject dead){ + boolean value = false; + if (invasionScheduled){ + String funeralSite = dead.getPlanet().getName(); + if (funeralSite.equals(invasionPlanet)){ + if (invasionLocationCenter.getDistance2D(dead.getWorldPosition())<500){ + value = true; + } + } + } + return value; + } + + public List getAccordingCloners(CreatureObject dead){ + List clonerList = new Vector(); + if (invasionScheduled){ + String funeralSite = dead.getPlanet().getName(); + if (funeralSite.equals(invasionPlanet)){ + if (invasionLocationCenter.getDistance2D(dead.getWorldPosition())<500){ + if (isInvadingFaction(dead)){ + clonerList = getInvaderClonersForPlanet(); + } + } + } + } + return clonerList; + } + + public List getInvaderClonersForPlanet(){ + return offensiveClonerList; + } + + public boolean isInvadingFaction(CreatureObject checker){ + if (checker.getFaction().equals(getFactionName(invadingFaction))) + return true; + return false; + } + + public boolean isdefendingFaction(CreatureObject checker){ + if (checker.getFaction().equals(getFactionName(defendingFaction))) + return true; + return false; + } + + private void spawnOffensiveCloners(){ + String clonerTemplate = "object/tangible/gcw/static_base/shared_invisible_cloner_rebel.iff"; + if (invadingFaction==Factions.Imperial){ + clonerTemplate = "object/tangible/gcw/static_base/shared_invisible_cloner_imperial.iff"; + } + + Point3D cloner1Pos = null; + Point3D cloner2Pos = null; + Point3D cloner3Pos = null; + switch (invasionPlanet) { + case "naboo": cloner1Pos = new Point3D(1814.81F, 17.34F, 2183.17F); + cloner2Pos = new Point3D(2125.71F, 60, 2756.94F); + cloner3Pos = new Point3D(1217.18F, 7.33F, 3062.95F); + break; + case "tatooine": cloner1Pos = new Point3D(-905.35F,24, -3791.04F); + cloner2Pos = new Point3D(-1258.13F,44.77F, -3357.66F); + cloner3Pos = new Point3D(-1189.65F,62.95F, -3830.22F); + break; + case "talus": cloner1Pos = new Point3D(-895.30F,9.93F, -3003.25F); + cloner2Pos = new Point3D(-7.27F,6, -2813.55F); + cloner3Pos = new Point3D(347.51F,6F, -2614.82F); + break; + } + + BuildingObject cloner1 = (BuildingObject) NGECore.getInstance().objectService.createObject(clonerTemplate, 0, core.terrainService.getPlanetByName(invasionPlanet), cloner1Pos, new Quaternion(0.00F,0F,1.00F,0F)); + NGECore.getInstance().simulationService.add(cloner1, cloner1.getPosition().x, cloner1.getPosition().z, true); + cloner1.setCustomName("Attack camp #1"); + Vector spawnPoints = new Vector(); + spawnPoints.add(new SpawnPoint(cloner1Pos,0F,1F)); + cloner1.setAttachment("spawnPoints", spawnPoints); + core.mapService.addLocation(cloner1.getPlanet(), "Attack camp #1", cloner1.getPosition().x, cloner1.getPosition().z, (byte)5, (byte)0, (byte)0); + + BuildingObject cloner2 = (BuildingObject) NGECore.getInstance().objectService.createObject(clonerTemplate, 0, core.terrainService.getPlanetByName(invasionPlanet), cloner2Pos, new Quaternion(0.00F,0F,1.00F,0F)); + NGECore.getInstance().simulationService.add(cloner2, cloner2.getPosition().x, cloner2.getPosition().z, true); + cloner2.setCustomName("Attack camp #2"); + spawnPoints = new Vector(); + spawnPoints.add(new SpawnPoint(cloner2Pos,0F,1F)); + cloner2.setAttachment("spawnPoints", spawnPoints); + core.mapService.addLocation(cloner2.getPlanet(), "Attack camp #2", cloner2.getPosition().x, cloner2.getPosition().z, (byte)5, (byte)0, (byte)0); + + BuildingObject cloner3 = (BuildingObject) NGECore.getInstance().objectService.createObject(clonerTemplate, 0, core.terrainService.getPlanetByName(invasionPlanet), cloner3Pos, new Quaternion(0.00F,0F,1.00F,0F)); + NGECore.getInstance().simulationService.add(cloner3, cloner3.getPosition().x, cloner3.getPosition().z, true); + cloner3.setCustomName("Attack camp #3"); + spawnPoints = new Vector(); + spawnPoints.add(new SpawnPoint(cloner3Pos,0F,1F)); + cloner3.setAttachment("spawnPoints", spawnPoints); + core.mapService.addLocation(cloner3.getPlanet(), "Attack camp #3", cloner3.getPosition().x, cloner3.getPosition().z, (byte)5, (byte)0, (byte)0); + + offensiveClonerList.add(cloner1); + offensiveClonerList.add(cloner2); + offensiveClonerList.add(cloner3); + } + + private void spawnDemoralizedSoldier(int faction, Point3D pos, float qw, float qy){ + String soldierTemplate = "rebel_invasion_demoralized_soldier"; + if (faction==Factions.Imperial){ + soldierTemplate = "imp_invasion_demoralized_soldier"; + } + + CreatureObject soldier = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, getInvasionPlanet(invasionLocation).getName(), 0L, pos.x, pos.y, pos.z, qw,0F,qy,0F,-1); + NGECore.getInstance().invasionService.registerDemoralizedSoldier(soldier); + } + + private void spawnDisabledVehicle(int faction, Point3D pos, float qw, float qy){ + String vehicleTemplate = "rebel_invasion_disabled_atxt"; + if (faction==Factions.Imperial){ + vehicleTemplate = "imp_invasion_disabled_atst"; + } + + CreatureObject vehicle = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(vehicleTemplate, getInvasionPlanet(invasionLocation).getName(), 0L, pos.x, pos.y, pos.z, qw,0F,qy,0F,-1); + vehicle.setPosture((byte) Posture.Incapacitated); + NGECore.getInstance().invasionService.registerDisabledVehicle(vehicle); + } + + private void playVictoryMusic(int winnerFaction){ + String audioTemplate = "sound/music_themequest_victory_rebel.snd"; + if (winnerFaction==Factions.Imperial) + audioTemplate = "sound/music_themequest_victory_imperial.snd"; + +// Vector allPlayers = core.simulationService.getAllNearSameFactionPlayers(500,invasionLocationCenter, getInvasionPlanet(invasionLocation), getFactionName(winnerFaction)); +// for (CreatureObject player : allPlayers) { +// if (player.getFaction().length() > 0 && player.getFactionStatus() > FactionStatus.OnLeave) { +// player.playMusic(audioTemplate); +// } +// } + Vector allPlayers = core.simulationService.getAllNearPlayers(500, getInvasionPlanet(invasionLocation), invasionLocationCenter); + for (CreatureObject player : allPlayers) { + player.playMusic(audioTemplate); + } + } + + // Utility method + public void arrangePylons(Point3D center, int angle){ + + int pylondistance= 4; + + Point3D pylonRefPos1 = new Point3D(-2*pylondistance,0,-pylondistance); + Point3D pylonRefPos2 = new Point3D(-pylondistance,0,pylondistance); + Point3D pylonRefPos3 = new Point3D(0,0,-pylondistance); + Point3D pylonRefPos4 = new Point3D(pylondistance,0,pylondistance); + Point3D pylonRefPos5 = new Point3D(2*pylondistance,0,-pylondistance); + + Point3D pylonTurnedPos1 = turnPoint(pylonRefPos1, angle); + Point3D pylonTurnedPos2 = turnPoint(pylonRefPos2, angle); + Point3D pylonTurnedPos3 = turnPoint(pylonRefPos3, angle); + Point3D pylonTurnedPos4 = turnPoint(pylonRefPos4, angle); + Point3D pylonTurnedPos5 = turnPoint(pylonRefPos5, angle); + + + float positionY1 = core.terrainService.getHeight(getInvasionPlanet(invasionLocation).getID(), center.x + pylonTurnedPos1.x, center.z + pylonTurnedPos1.z); + float positionY2 = core.terrainService.getHeight(getInvasionPlanet(invasionLocation).getID(), center.x + pylonTurnedPos2.x, center.z + pylonTurnedPos2.z); + float positionY3 = core.terrainService.getHeight(getInvasionPlanet(invasionLocation).getID(), center.x + pylonTurnedPos3.x, center.z + pylonTurnedPos3.z); + float positionY4 = core.terrainService.getHeight(getInvasionPlanet(invasionLocation).getID(), center.x + pylonTurnedPos4.x, center.z + pylonTurnedPos4.z); + float positionY5 = core.terrainService.getHeight(getInvasionPlanet(invasionLocation).getID(), center.x + pylonTurnedPos5.x, center.z + pylonTurnedPos5.z); + + Point3D pylonWorldPos1 = new Point3D(center.x + pylonTurnedPos1.x,positionY1,center.z + pylonTurnedPos1.z); + Point3D pylonWorldPos2 = new Point3D(center.x + pylonTurnedPos2.x,positionY2,center.z + pylonTurnedPos2.z); + Point3D pylonWorldPos3 = new Point3D(center.x + pylonTurnedPos3.x,positionY3,center.z + pylonTurnedPos3.z); + Point3D pylonWorldPos4 = new Point3D(center.x + pylonTurnedPos4.x,positionY4,center.z + pylonTurnedPos4.z); + Point3D pylonWorldPos5 = new Point3D(center.x + pylonTurnedPos5.x,positionY5,center.z + pylonTurnedPos5.z); + + System.out.println("new Point3D(" + pylonWorldPos1.x + "F, " + pylonWorldPos1.y + "F, " + pylonWorldPos1.z + "F)"); + System.out.println("new Point3D(" + pylonWorldPos2.x + "F, " + pylonWorldPos2.y + "F, " + pylonWorldPos2.z + "F)"); + System.out.println("new Point3D(" + pylonWorldPos3.x + "F, " + pylonWorldPos3.y + "F, " + pylonWorldPos3.z + "F)"); + System.out.println("new Point3D(" + pylonWorldPos4.x + "F, " + pylonWorldPos4.y + "F, " + pylonWorldPos4.z + "F)"); + System.out.println("new Point3D(" + pylonWorldPos5.x + "F, " + pylonWorldPos5.y + "F, " + pylonWorldPos5.z + "F)"); + } + + private Point3D turnPoint(Point3D orig, int angle){ + double origangle = Math.toDegrees(Math.atan2(orig.x, orig.z)); + double hypo = Math.sqrt(orig.x*orig.x+orig.z*orig.z); + double newAngle = origangle + angle; + float newX = (float)(hypo * Math.sin(Math.toRadians(newAngle))); + float newZ = (float)(hypo * Math.cos(Math.toRadians(newAngle))); + Point3D result = new Point3D(newX,0,newZ); + return result; + } + + private Set> getInvadingCreaturesEntrySet(){ + synchronized(invadingCreatures){ + return invadingCreatures.entrySet(); + } + } + + private Set> getDefendingCreaturesEntrySet(){ + synchronized(defendingCreatures){ + return defendingCreatures.entrySet(); + } + } + + + public void setInvasionLocationCenter(){ + switch (invasionLocation){ + case InvasionLocation.Dearic : invasionLocationCenter = new Point3D(452,6,-3002); + break; + case InvasionLocation.Keren : invasionLocationCenter = new Point3D(1840,12,2635); + break; + case InvasionLocation.Bestine : invasionLocationCenter = new Point3D(-1192,12,-3606); + break; + } + } + + public String getInvasionLocationName(){ + switch (invasionLocation){ + case InvasionLocation.Dearic : return "talus_dearic"; + case InvasionLocation.Keren : return "naboo_keren"; + case InvasionLocation.Bestine : return "tatooine_bestine"; + } + return ""; + } + + public String getFactionName(int faction){ + if (faction==Factions.Rebel) + return "rebel"; + if (faction==Factions.Imperial) + return "imperial"; + return "neutral"; + } + + + public boolean isDefendingGeneralAlive() { + return defendingGeneralAlive; + } + + @Override + public void shutdown() { + + } + @Override + public void insertOpcodes(Map arg0, + Map arg1) { + } + + public class InvasionLocation { + + public static final int Keren = 0; + public static final int Bestine = 1; + public static final int Dearic = 2; + + } + + public int getInvasionLocation() { + return invasionLocation; + } + + public String getInvasionPlanetName() { + return getInvasionPlanet(invasionLocation).getName(); + } + + public void setInvasionLocation(int invasionLocation) { + this.invasionLocation = invasionLocation; + } +} diff --git a/src/services/gcw/VehiclePatrolPylon.java b/src/services/gcw/VehiclePatrolPylon.java new file mode 100644 index 00000000..68bd68a1 --- /dev/null +++ b/src/services/gcw/VehiclePatrolPylon.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.gcw; + +import java.util.Random; +import java.util.Vector; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; +import main.NGECore; +import resources.datatables.Factions; +import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; + +/** + * @author Charon + */ + +@SuppressWarnings("unused") +public class VehiclePatrolPylon extends TangibleObject{ + + private static final long serialVersionUID = 1L; + private int pylonFaction = 0; + private int spawnLevel = 0; + private int totalSpawnedVehicles = 0; + private String[] vehicleTemplates = new String[]{""}; + private String[] rebelTemplates1 = new String[]{""}; + private String[] rebelTemplates2 = new String[]{""}; + private String[] rebelTemplates3 = new String[]{""}; + private String[] imperialTemplates1 = new String[]{""}; + private String[] imperialTemplates2 = new String[]{""}; + private String[] imperialTemplates3 = new String[]{"elite_imperial_stormtrooper_90"}; + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + public VehiclePatrolPylon() { + super(); + } + + public VehiclePatrolPylon(long objectID, Planet planet, Point3D position, Quaternion orientation, String template){ + super(objectID, planet, position, orientation, template); + + scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + spawnVehicle(); + } catch (Exception e) { + System.err.println("Exception in VehiclePatrolPylon->scheduleAtFixedRate->spawnVehicle() " + e.getMessage()); + } + } + }, 5, 20, TimeUnit.SECONDS); + + } + + public int getPylonFaction() { + return pylonFaction; + } + + public void setPylonFaction(int pylonFaction) { + this.pylonFaction = pylonFaction; + } + + public int getSpawnLevel() { + return spawnLevel; + } + + public void setSpawnLevel(int spawnLevel) { + this.spawnLevel = spawnLevel; + } + + public void spawnVehicle(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (pylonFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: vehicleTemplates = rebelTemplates1; + case 2: vehicleTemplates = rebelTemplates2; + case 3: vehicleTemplates = rebelTemplates3; + } + } + if (pylonFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: vehicleTemplates = imperialTemplates1; + case 2: vehicleTemplates = imperialTemplates2; + case 3: vehicleTemplates = imperialTemplates3; + } + } + String vehicleTemplate = vehicleTemplates[new Random().nextInt(vehicleTemplates.length)]; + CreatureObject vehicle = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(vehicleTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + + NGECore.getInstance().aiService.setPatrol(vehicle, get_Dearic_Route_1()); + NGECore.getInstance().aiService.setPatrolLoop(vehicle,false); + totalSpawnedVehicles++; + } + } + + public Vector get_Dearic_Route_1(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(68.0F, 6.00F, -2959F)); + patrolpoints.add(new Point3D(151.93F,6.00F, -2961.66F)); + patrolpoints.add(new Point3D(170.18F, 6.00F, -2992.99F)); + patrolpoints.add(new Point3D(262.76F, 6.00F, -2999.76F)); + patrolpoints.add(new Point3D(275.87F, 6.00F, -3008.44F)); + patrolpoints.add(new Point3D(303.41F, 6.00F, -3005.19F)); + patrolpoints.add(new Point3D(343.31F, 6.00F, -2961.06F)); + patrolpoints.add(new Point3D(379.98F, 6.00F, -2963.31F)); + patrolpoints.add(new Point3D(404.70F, 6.00F, -2980.57F)); + patrolpoints.add(new Point3D(412.54F, 6.00F, -3039.39F)); + patrolpoints.add(new Point3D(423.06F, 6.00F, -3050.75F)); + patrolpoints.add(new Point3D(446.92F, 6.00F, -3046.32F)); + patrolpoints.add(new Point3D(470.48F, 6.00F, -3023.43F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_2(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + public Vector get_Dearic_Route_3(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + public Vector get_Dearic_Route_4(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + public Vector get_Dearic_Route_5(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + public Vector get_Dearic_Route_6(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + public Vector get_Dearic_Route_7(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + public Vector get_Dearic_Route_8(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + public Vector get_Dearic_Route_9(){ + Vector patrolpoints = new Vector(); + return patrolpoints; + } + + + +} diff --git a/src/services/housing/HousingService.java b/src/services/housing/HousingService.java index 3d897d43..89fbf577 100644 --- a/src/services/housing/HousingService.java +++ b/src/services/housing/HousingService.java @@ -92,7 +92,7 @@ public class HousingService implements INetworkDispatch { public void enterStructureMode(CreatureObject actor, TangibleObject deed) { PlayerCity city = core.playerCityService.getCityObjectIsIn(actor); - if (!actor.getClient().isGM() && !core.terrainService.canBuildAtPosition(actor, actor.getWorldPosition().x, actor.getWorldPosition().z)) { + if (core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()) == null && !core.terrainService.canBuildAtPosition(actor, actor.getWorldPosition().x, actor.getWorldPosition().z)) { actor.sendSystemMessage("You may not place a structure here.", (byte) 0); // should probably load this from an stf return; } @@ -122,7 +122,7 @@ public class HousingService implements INetworkDispatch { return null; } - if(!actor.getClient().isGM() && !core.terrainService.canBuildAtPosition(actor, positionX, positionZ)) { + if(core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()) == (null) && !core.terrainService.canBuildAtPosition(actor, positionX, positionZ)) { actor.sendSystemMessage("You may not place a structure here.", (byte) 0); // should probably load this from an stf return null; } diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 7ede2796..9bd27972 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -132,6 +132,9 @@ import services.command.CombatCommand; import services.bazaar.AuctionItem; import services.chat.ChatRoom; import services.equipment.EquipmentService; +import services.gcw.GCWPylon; +import services.gcw.GCWSpawner; +import services.spawn.MobileTemplate; import services.sui.SUIWindow; import services.sui.SUIWindow.SUICallback; import services.sui.SUIWindow.Trigger; @@ -303,6 +306,39 @@ public class ObjectService implements INetworkDispatch { object = new SurveyTool(objectID, planet, position, orientation, Template); + } else if(Template.startsWith("object/tangible/destructible/shared_gcw_city_construction_beacon")) { + + float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z)-1.5f; + Point3D newpoint = new Point3D(position.x,positionY,position.z); + object = new GCWPylon(objectID, planet, position, orientation, Template); + + } else if(Template.startsWith("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base")) { + + float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z)+0.3f; + Point3D newpoint = new Point3D(position.x,positionY,position.z); + object = new GCWSpawner(objectID, planet, position, orientation, Template); + + } else if(Template.startsWith("object/tangible/destructible/")) { + +// float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z)-1f; +// Point3D newpoint = new Point3D(position.x,positionY,position.z); +// object = new InstallationObject(objectID, planet, newpoint, orientation, Template); + + object = new TangibleObject(objectID, planet, position, orientation, Template); + + //object = new BuildingObject(objectID, planet, position, orientation, Template); + + } else if(Template.startsWith("object/tangible/gcw/static_base/shared_invisible_cloner")) { + + object = new BuildingObject(objectID, planet, position, orientation, Template); + if(!isSnapshot && !overrideSnapshot && object.getPortalVisitor() != null) { + int cellCount = object.getPortalVisitor().cells.size() - 1; // -1 for index 0 cell which is outside the building and used for ai pathfinding + for (int i = 0; i < cellCount; i++) { + CellObject cell = (CellObject) createObject("object/cell/shared_cell.iff", planet); + cell.setCellNumber(i+1); + object.add(cell); + } + } } else if(Template.startsWith("object/tangible")) { object = new TangibleObject(objectID, planet, position, orientation, Template); @@ -393,6 +429,12 @@ public class ObjectService implements INetworkDispatch { Point3D newpoint = new Point3D(position.x,positionY,position.z); object = new HarvesterObject(objectID, planet, newpoint, orientation, Template); + } else if(Template.startsWith("object/installation/turret")) { + + float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z); + Point3D newpoint = new Point3D(position.x,positionY,position.z); + object = new InstallationObject(objectID, planet, newpoint, orientation, Template); + } else { return null; } @@ -549,19 +591,25 @@ public class ObjectService implements INetworkDispatch { if (object.getAttachment("AI") != null && object.getAttachment("AI") instanceof AIActor && ((AIActor) object.getAttachment("AI")).getMobileTemplate().getRespawnTime() > 0) { final long objectId = object.getObjectID(); - final String Template = object.getTemplate(); + final MobileTemplate Template = ((AIActor) object.getAttachment("AI")).getMobileTemplate(); final Planet planet = object.getPlanet(); final Point3D position = object.getPosition(); + final Point3D spawnPosition = ((AIActor) object.getAttachment("AI")).getSpawnPosition(); final Quaternion orientation = object.getOrientation(); - final long cellId = ((object.getContainer() == null) ? 0L : object.getContainer().getObjectID()); + // final long cellId = ((object.getContainer() == null) ? 0L : object.getContainer().getObjectID()); + CellObject cellO = spawnPosition.getCell(); + final long cellId = ((cellO == null) ? 0L : cellO.getObjectID()); final short level = ((object instanceof CreatureObject) ? ((CreatureObject) object).getLevel() : (short) 0); - scheduler.schedule(new Runnable() { @Override public void run() { try { - NGECore.getInstance().spawnService.spawnCreature(Template, objectId, planet.getName(), cellId, position.x, position.y, position.z, orientation.w, orientation.x, orientation.y, orientation.z, level); + // Commented for now until found where the respawn is always set to 60 for any NPC +// CreatureObject newObject = NGECore.getInstance().spawnService.spawnCreature(Template, 0, planet.getName(), cellId, spawnPosition.x, spawnPosition.y, spawnPosition.z, orientation.w, orientation.x, orientation.y, orientation.z, level); +// AIActor newAIActor = (AIActor)newObject.getAttachment("AI"); +// newAIActor.cloneActor(((AIActor) object.getAttachment("AI"))); + //object.setAttachment("AI", null); } catch (Exception e) { e.printStackTrace(); } @@ -569,7 +617,7 @@ public class ObjectService implements INetworkDispatch { }, ((AIActor) object.getAttachment("AI")).getMobileTemplate().getRespawnTime(), TimeUnit.SECONDS); } - + String filePath = "scripts/" + object.getTemplate().split("shared_" , 2)[0].replace("shared_", "") + object.getTemplate().split("shared_" , 2)[1].replace(".iff", "") + ".py"; if (FileUtilities.doesFileExist(filePath)) { @@ -1279,7 +1327,6 @@ public class ObjectService implements INetworkDispatch { } public void loadBuildoutObjects(Planet planet) throws InstantiationException, IllegalAccessException { - DatatableVisitor buildoutTable = ClientFileManager.loadFile("datatables/buildout/areas_" + planet.getName() + ".iff", DatatableVisitor.class); for (int i = 0; i < buildoutTable.getRowCount(); i++) { @@ -1287,7 +1334,6 @@ public class ObjectService implements INetworkDispatch { String areaName = (String) buildoutTable.getObject(i, 0); float x1 = (Float) buildoutTable.getObject(i, 1); float z1 = (Float) buildoutTable.getObject(i, 2); - readBuildoutDatatable(ClientFileManager.loadFile("datatables/buildout/" + planet.getName() + "/" + areaName + ".iff", DatatableVisitor.class), planet, x1, z1); } diff --git a/src/services/quest/QuestData.java b/src/services/quest/QuestData.java new file mode 100644 index 00000000..cccc2dfe --- /dev/null +++ b/src/services/quest/QuestData.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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.quest; + +import java.util.Vector; + +public class QuestData { + + private String name; + private String fileName; + + private Vector tasks; + private int tasksAvailableId; + + public QuestData() { } + + public QuestData(String questName) { + + if (questName.endsWith(".qst")) { + this.fileName = questName; + + if (questName.contains("/")) { + String[] split = questName.split("/"); + questName = split[split.length - 1]; + } + + questName = questName.split(".qst")[0]; + } + + this.name = questName; + this.tasks = new Vector(); + } + + public String getName() { + return name; + } + + public String getFileName() { + return fileName; + } + + public Vector getTasks() { + return tasks; + } + + public int getTasksAvailableId() { + return tasksAvailableId; + } + + public void setTasksAvailableId(int tasksAvailableId) { + this.tasksAvailableId = tasksAvailableId; + } + +} diff --git a/src/services/quest/QuestService.java b/src/services/quest/QuestService.java new file mode 100644 index 00000000..60461eae --- /dev/null +++ b/src/services/quest/QuestService.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * 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.quest; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.apache.mina.core.buffer.IoBuffer; +import org.apache.mina.core.session.IoSession; +import org.xml.sax.SAXException; + +import protocol.swg.ObjControllerMessage; +import protocol.swg.PlayMusicMessage; +import protocol.swg.objectControllerObjects.ForceActivateQuest; +import resources.common.ObjControllerOpcodes; +import resources.common.OutOfBand; +import resources.common.ProsePackage; +import resources.datatables.DisplayType; +import resources.objects.SWGList; +import resources.objects.creature.CreatureObject; +import resources.objects.player.PlayerObject; +import resources.quest.Quest; +import main.NGECore; +import engine.clients.Client; +import engine.resources.common.CRC; +import engine.resources.common.StringUtilities; +import engine.resources.objects.SWGObject; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +@SuppressWarnings("unused") +public class QuestService implements INetworkDispatch { + + private NGECore core; + private Map questMap = new ConcurrentHashMap(); + + public QuestService(NGECore core) { + this.core = core; + } + + @Override + public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { + objControllerOpcodes.put(ObjControllerOpcodes.QUEST_CHANGE_ACTIVE, new INetworkRemoteEvent() { + + @Override + public void handlePacket(IoSession session, IoBuffer data) throws Exception { + // This packet seems to not expect a response from the server. It's sent to server whenever changing active quest. + } + + }); + } + + @Override + public void shutdown() { } + + public boolean doesPlayerHaveQuest(CreatureObject creo, String questName) { + PlayerObject ghost = creo.getPlayerObject(); + + if (ghost == null) { + try { throw new Exception("Ghost is null! Cannot determine if player has quest or not."); } + catch (Exception e) {e.printStackTrace();} + } + + SWGList questJournal = ghost.getQuestJournal(); + + if (questJournal.size() == 0) + return false; + + for (Quest quest : questJournal) { + if (quest.getName().equals(questName)) + return true; + } + + return false; + } + + public boolean isQuestCompleted(CreatureObject creo, String questName) { + PlayerObject ghost = creo.getPlayerObject(); + + if (ghost == null) { + try { throw new Exception("Ghost is null! Cannot determine if player completed quest or not."); } + catch (Exception e) {e.printStackTrace();} + } + + SWGList questJournal = ghost.getQuestJournal(); + + if (questJournal.size() == 0) + return false; + + for (Quest quest : questJournal) { + if (quest.getName().equals(questName)) + return quest.isCompleted(); + } + + return false; + } + + public boolean adminActivateQuest(CreatureObject creo, String questName) { + + PlayerObject ghost = creo.getPlayerObject(); + + if (ghost == null) + return false; + + Quest quest = new Quest(questName, creo.getObjectID()); + + try { + if (!parseQuestData(questName)) + return false; + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } + + if (questName.endsWith(".qst")) + questName = questName.split(".qst")[0]; + + ProsePackage prose = new ProsePackage("@quest/ground/system_message:quest_received"); + + // Format for stf string if quest resides in multiple folders beyond base one + if (questName.contains("/")) { + String[] split = questName.split("/"); + questName = split[split.length - 1]; + } + + prose.setToCustomString("@quest/ground/" + questName + ":journal_entry_title"); + creo.sendSystemMessage(new OutOfBand(prose), DisplayType.Quest); + + PlayMusicMessage music = new PlayMusicMessage("sound/ui_npe2_quest_received.snd", creo.getObjectID(), 0, true); + creo.getClient().getSession().write(music.serialize()); + + ghost.getQuestJournal().add(quest); + ghost.setActiveQuest(quest.getName()); + + return true; + } + + public void sendQuestWindow(CreatureObject reciever, String questName) { + if (questName.endsWith(".qst")) + questName = questName.split(".qst")[0]; + + if (!questName.startsWith("quest/")) + questName = "quest/" + questName; + + ObjControllerMessage objMsg = new ObjControllerMessage(11, new ForceActivateQuest(reciever.getObjectID(), CRC.StringtoCRC(questName))); + reciever.getClient().getSession().write(objMsg.serialize()); + } + + public QuestData getQuestData(String questFile) { + if (!questFile.endsWith(".qst")) + questFile = questFile + ".qst"; + + if (questMap.containsKey(questFile)) + return questMap.get(questFile); + + else return null; + } + + private boolean parseQuestData(String questFile) throws ParserConfigurationException, SAXException, IOException { + + if (!questFile.endsWith(".qst")) + questFile = questFile + ".qst"; + + if (questMap.containsKey(questFile)) return true; + + File questXml = new File("clientdata/quest/" + questFile); + if (!questXml.exists()) return false; + + SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParser parser = factory.newSAXParser(); + + QuestData dataObj = new QuestData(questFile); + SWGQuestDataHandler questHandler = new SWGQuestDataHandler(dataObj); + parser.parse(questXml, questHandler); + + questMap.put(questFile, dataObj); + + System.out.println("Loaded quest file " + questFile); + return true; + } +} diff --git a/src/services/quest/QuestTask.java b/src/services/quest/QuestTask.java new file mode 100644 index 00000000..6d885fee --- /dev/null +++ b/src/services/quest/QuestTask.java @@ -0,0 +1,373 @@ +/******************************************************************************* + * 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.quest; + +public class QuestTask { + private String type; // Tells the server what to do when they get the task + private String name; + private String journalEntryTitle; + private String journalEntryDescription; + private String planet; + // private String prerequisiteTasks; // TODO: Figure out format for multiple + // pre-req tasks + // private String exclusionTasks; // TODO: Figure out format for multiple + // exclusion tasks + private String musicOnActivate; + private String musicOnComplete; + private String musicOnFail; + private String target; + private String parameter; // TODO: What does this do? + private String grantQuestOnComplete; + private String grantQuestOnFail; + private String interiorWaypointAppearance; + private String buildingCellName; + private String waypointName; + private String signalName; + private String signalsOnFail; + private String signalsOnComplete; + private String waitMarkerTemplate; + private String waitMarkerPlanetName; + private String waitMarkerCellName; + + private boolean taskOnFail; + private boolean visible; + private boolean grantQuestOnCompleteShowSystemMessage; + private boolean grantQuestOnFailShowSystemMessage; + private boolean allowRepeats; + + private int id; + private int showSystemMessages; // TODO: Possibly change to boolean + private int createWaypoint; + private int waitMarkerCreate; + private int timeToComplete; + + private long waitMarkerBuilding; + + private float LocationX; + private float LocationY; + private float LocationZ; + private float waitMarkerX; + private float waitMarkerY; + private float waitMarkerZ; + + public QuestTask() {} + + public QuestTask(String type, int id, boolean taskOnFail) { + this.type = type; + this.id = id; + this.taskOnFail = taskOnFail; + } + + public String getType() { + return type; + } + + public String getJournalEntryTitle() { + return journalEntryTitle; + } + + public void setJournalEntryTitle(String journalEntryTitle) { + this.journalEntryTitle = journalEntryTitle; + } + + public String getJournalEntryDescription() { + return journalEntryDescription; + } + + public void setJournalEntryDescription(String journalEntryDescription) { + this.journalEntryDescription = journalEntryDescription; + } + + public boolean isTaskOnFail() { + return taskOnFail; + } + + public int getId() { + return id; + } + + public String getPlanet() { + return planet; + } + + public void setPlanet(String planet) { + this.planet = planet; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMusicOnActivate() { + return musicOnActivate; + } + + public void setMusicOnActivate(String musicOnActivate) { + this.musicOnActivate = musicOnActivate; + } + + public String getMusicOnComplete() { + return musicOnComplete; + } + + public void setMusicOnComplete(String musicOnComplete) { + this.musicOnComplete = musicOnComplete; + } + + public String getMusicOnFail() { + return musicOnFail; + } + + public void setMusicOnFail(String musicOnFail) { + this.musicOnFail = musicOnFail; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getParameter() { + return parameter; + } + + public void setParameter(String parameter) { + this.parameter = parameter; + } + + public String getGrantQuestOnComplete() { + return grantQuestOnComplete; + } + + public void setGrantQuestOnComplete(String grantQuestOnComplete) { + this.grantQuestOnComplete = grantQuestOnComplete; + } + + public String getGrantQuestOnFail() { + return grantQuestOnFail; + } + + public void setGrantQuestOnFail(String grantQuestOnFail) { + this.grantQuestOnFail = grantQuestOnFail; + } + + public String getInteriorWaypointAppearance() { + return interiorWaypointAppearance; + } + + public void setInteriorWaypointAppearance(String interiorWaypointAppearance) { + this.interiorWaypointAppearance = interiorWaypointAppearance; + } + + public String getBuildingCellName() { + return buildingCellName; + } + + public void setBuildingCellName(String buildingCellName) { + this.buildingCellName = buildingCellName; + } + + public String getWaypointName() { + return waypointName; + } + + public void setWaypointName(String waypointName) { + this.waypointName = waypointName; + } + + public String getSignalName() { + return signalName; + } + + public void setSignalName(String signalName) { + this.signalName = signalName; + } + + public String getSignalsOnFail() { + return signalsOnFail; + } + + public void setSignalsOnFail(String signalsOnFail) { + this.signalsOnFail = signalsOnFail; + } + + public String getSignalsOnComplete() { + return signalsOnComplete; + } + + public void setSignalsOnComplete(String signalsOnComplete) { + this.signalsOnComplete = signalsOnComplete; + } + + public String getWaitMarkerTemplate() { + return waitMarkerTemplate; + } + + public void setWaitMarkerTemplate(String waitMarkerTemplate) { + this.waitMarkerTemplate = waitMarkerTemplate; + } + + public String getWaitMarkerPlanetName() { + return waitMarkerPlanetName; + } + + public void setWaitMarkerPlanetName(String waitMarkerPlanetName) { + this.waitMarkerPlanetName = waitMarkerPlanetName; + } + + public String getWaitMarkerCellName() { + return waitMarkerCellName; + } + + public void setWaitMarkerCellName(String waitMarkerCellName) { + this.waitMarkerCellName = waitMarkerCellName; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public boolean isGrantQuestOnCompleteShowSystemMessage() { + return grantQuestOnCompleteShowSystemMessage; + } + + public void setGrantQuestOnCompleteShowSystemMessage( + boolean grantQuestOnCompleteShowSystemMessage) { + this.grantQuestOnCompleteShowSystemMessage = grantQuestOnCompleteShowSystemMessage; + } + + public boolean isGrantQuestOnFailShowSystemMessage() { + return grantQuestOnFailShowSystemMessage; + } + + public void setGrantQuestOnFailShowSystemMessage( + boolean grantQuestOnFailShowSystemMessage) { + this.grantQuestOnFailShowSystemMessage = grantQuestOnFailShowSystemMessage; + } + + public boolean getAllowRepeats() { + return allowRepeats; + } + + public void setAllowRepeats(boolean allowRepeats) { + this.allowRepeats = allowRepeats; + } + + public int getShowSystemMessages() { + return showSystemMessages; + } + + public void setShowSystemMessages(int showSystemMessages) { + this.showSystemMessages = showSystemMessages; + } + + public int getCreateWaypoint() { + return createWaypoint; + } + + public void setCreateWaypoint(int createWaypoint) { + this.createWaypoint = createWaypoint; + } + + public int getWaitMarkerCreate() { + return waitMarkerCreate; + } + + public void setWaitMarkerCreate(int waitMarkerCreate) { + this.waitMarkerCreate = waitMarkerCreate; + } + + public int getTimeToComplete() { + return timeToComplete; + } + + public void setTimeToComplete(int timeToComplete) { + this.timeToComplete = timeToComplete; + } + + public long getWaitMarkerBuilding() { + return waitMarkerBuilding; + } + + public void setWaitMarkerBuilding(long waitMarkerBuilding) { + this.waitMarkerBuilding = waitMarkerBuilding; + } + + public float getLocationX() { + return LocationX; + } + + public void setLocationX(float locationX) { + LocationX = locationX; + } + + public float getLocationY() { + return LocationY; + } + + public void setLocationY(float locationY) { + LocationY = locationY; + } + + public float getLocationZ() { + return LocationZ; + } + + public void setLocationZ(float locationZ) { + LocationZ = locationZ; + } + + public float getWaitMarkerX() { + return waitMarkerX; + } + + public void setWaitMarkerX(float waitMarkerX) { + this.waitMarkerX = waitMarkerX; + } + + public float getWaitMarkerY() { + return waitMarkerY; + } + + public void setWaitMarkerY(float waitMarkerY) { + this.waitMarkerY = waitMarkerY; + } + + public float getWaitMarkerZ() { + return waitMarkerZ; + } + + public void setWaitMarkerZ(float waitMarkerZ) { + this.waitMarkerZ = waitMarkerZ; + } +} diff --git a/src/services/quest/SWGQuestDataHandler.java b/src/services/quest/SWGQuestDataHandler.java new file mode 100644 index 00000000..46d5447b --- /dev/null +++ b/src/services/quest/SWGQuestDataHandler.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * 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.quest; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + +import org.xml.sax.Attributes; +import org.xml.sax.helpers.DefaultHandler; + +public class SWGQuestDataHandler extends DefaultHandler { + + private QuestData dataObj; + + public SWGQuestDataHandler(QuestData dataObj) { + this.dataObj = dataObj; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) { + // These are all the currently known elements in the Quest. + switch (qName) { + + case "tasks": + dataObj.setTasksAvailableId(Integer.parseInt(attributes.getValue("availableId"))); + break; + + case "task": + dataObj.getTasks().add(new QuestTask(attributes.getValue("type"), Integer.parseInt(attributes.getValue("id")), Boolean.parseBoolean(attributes.getValue("taskOnFail")))); + break; + + case "data": + parseTaskData(qName, attributes); + break; + + case "list": + parseListData(qName, attributes); + break; + + case "quest": + // TODO: Find out if there are more than 1 versions of quest (Right now just know 1.0) + break; + + default: + System.out.println("Couldn't find what to do with element " + qName); + writeLog("No case found for elment: " + qName); + break; + } + + } + + private void parseListData(String qName, Attributes attributes) { + // TODO: Parse list data + } + + private void parseTaskData(String qName, Attributes attributes) { + QuestTask task = dataObj.getTasks().get(dataObj.getTasks().size() - 1); // get newest task + + // This is by no means the full list of data. To add more task data, put in the value for "name" from .qst file as the case and set appropriate variable. + switch (attributes.getValue("name")) { + + case "journalEntryTitle": + task.setJournalEntryTitle(attributes.getValue("value")); + break; + + case "journalEntryDescription": + task.setJournalEntryDescription(attributes.getValue("value")); + break; + + case "isVisible": + task.setVisible(Boolean.parseBoolean(attributes.getValue("value"))); + break; + + case "allowRepeats": + task.setAllowRepeats(Boolean.parseBoolean(attributes.getValue("value"))); + break; + + case "taskName": + task.setName(attributes.getValue("value")); + break; + + case "showSystemMessages": + task.setShowSystemMessages(Integer.parseInt(attributes.getValue("value"))); + break; + + case "grantQuestOnComplete": + task.setGrantQuestOnComplete(attributes.getValue("value")); + break; + + case "grantQuestOnCompleteShowSystemMessage": + task.setGrantQuestOnCompleteShowSystemMessage(Boolean.parseBoolean(attributes.getValue("value"))); + break; + + case "grantQuestOnFail": + task.setGrantQuestOnFail(attributes.getValue("value")); + break; + + case "grantQuestOnFailShowSystemMessage": + task.setGrantQuestOnFailShowSystemMessage(Boolean.parseBoolean(attributes.getValue("value"))); + break; + + case "createWaypoint": + task.setCreateWaypoint(Integer.parseInt(attributes.getValue("value"))); + break; + + case "Planet": + task.setPlanet(attributes.getValue("value")); + break; + + case "LocationX(m)": + task.setLocationX(Float.parseFloat(attributes.getValue("value"))); + break; + + case "LocationY(m)": + task.setLocationY(Float.parseFloat(attributes.getValue("value"))); + break; + + case "LocationZ(m)": + task.setLocationZ(Float.parseFloat(attributes.getValue("value"))); + break; + + case "interiorWaypointAppearance": + task.setInteriorWaypointAppearance(attributes.getValue("value")); + break; + + case "buildingCellName": + task.setBuildingCellName(attributes.getValue("value")); + break; + + case "waypointName": + task.setWaypointName(attributes.getValue("value")); + break; + + case "Signal Name": + task.setSignalName(attributes.getValue("value")); + break; + + case "signalsOnFail": + task.setSignalsOnFail(attributes.getValue("value")); + break; + + case "signalsOnComplete": + task.setSignalsOnComplete(attributes.getValue("value")); + break; + + default: + break; + } + } + + private void writeLog(String message) { + BufferedWriter writer; + try { + writer = Files.newBufferedWriter(Paths.get("./logs/Quest" + ".txt"), StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE); + PrintWriter out = new PrintWriter(writer); + out.println(message); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/services/resources/HarvesterService.java b/src/services/resources/HarvesterService.java index 96b68aad..7b729f64 100644 --- a/src/services/resources/HarvesterService.java +++ b/src/services/resources/HarvesterService.java @@ -1063,7 +1063,7 @@ public class HarvesterService implements INetworkDispatch { WaypointObject constructionWaypoint = (WaypointObject)NGECore.getInstance().objectService.createObject("object/waypoint/shared_world_waypoint_blue.iff", actor.getPlanet(), harvester.getPosition().x, 0 ,harvester.getPosition().z); String displayname = "@installation_n:"+harvester.getStfName(); constructionWaypoint.setName(displayname); - constructionWaypoint.setPlanetCRC(engine.resources.common.CRC.StringtoCRC(actor.getPlanet().getName())); + constructionWaypoint.setPlanetCrc(CRC.StringtoCRC(actor.getPlanet().getName())); constructionWaypoint.setPosition(new Point3D(object.getPosition().x,0, object.getPosition().z)); player.waypointAdd(constructionWaypoint); constructionWaypoint.setPosition(new Point3D(object.getPosition().x,0, object.getPosition().z)); @@ -1072,13 +1072,13 @@ public class HarvesterService implements INetworkDispatch { constructionWaypoint.setStringAttribute("", ""); player.waypointAdd(constructionWaypoint); constructionWaypoint.setName(displayname); - constructionWaypoint.setPlanetCRC(engine.resources.common.CRC.StringtoCRC(actor.getPlanet().getName())); + constructionWaypoint.setPlanetCrc(CRC.StringtoCRC(actor.getPlanet().getName())); player.setLastSurveyWaypoint(constructionWaypoint); List attachments = new ArrayList(); WaypointAttachment attachment = new WaypointAttachment(); attachment.active = true; - attachment.cellID = constructionWaypoint.getCellId(); + attachment.cellID = constructionWaypoint.getCellNumber(); attachment.color = (byte)1; attachment.name = displayname; attachment.planetCRC = engine.resources.common.CRC.StringtoCRC(actor.getPlanet().getName()); @@ -1111,7 +1111,7 @@ public class HarvesterService implements INetworkDispatch { public void enterStructurePlacementMode(CreatureObject actor, SWGObject object){ - if (!actor.getClient().isGM() && !core.terrainService.canBuildAtPosition(actor,actor.getPosition().x,actor.getPosition().z)){ + if (core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()) == null && !core.terrainService.canBuildAtPosition(actor,actor.getPosition().x,actor.getPosition().z)){ actor.sendSystemMessage("@player_structure:not_permitted", (byte) 0); return; } @@ -1240,7 +1240,7 @@ public class HarvesterService implements INetworkDispatch { WaypointObject constructionWaypoint = (WaypointObject)core.objectService.createObject("object/waypoint/shared_world_waypoint_blue.iff", actor.getPlanet(), harvester.getPosition().x, 0 ,harvester.getPosition().z); String displayname = "@installation_n:"+harvester.getStfName() + " " + counter; constructionWaypoint.setName(displayname); - constructionWaypoint.setPlanetCRC(engine.resources.common.CRC.StringtoCRC(actor.getPlanet().getName())); + constructionWaypoint.setPlanetCrc(CRC.StringtoCRC(actor.getPlanet().getName())); constructionWaypoint.setPosition(new Point3D(spawnCoordsX,0, spawnCoordsZ)); player.waypointAdd(constructionWaypoint); constructionWaypoint.setPosition(new Point3D(spawnCoordsX,0, spawnCoordsZ)); @@ -1249,7 +1249,7 @@ public class HarvesterService implements INetworkDispatch { constructionWaypoint.setStringAttribute("", ""); player.waypointAdd(constructionWaypoint); constructionWaypoint.setName(displayname); - constructionWaypoint.setPlanetCRC(engine.resources.common.CRC.StringtoCRC(actor.getPlanet().getName())); + constructionWaypoint.setPlanetCrc(CRC.StringtoCRC(actor.getPlanet().getName())); player.setLastSurveyWaypoint(constructionWaypoint); } diff --git a/src/services/spawn/DynamicSpawnArea.java b/src/services/spawn/DynamicSpawnArea.java index 6ff91997..db06d1ad 100644 --- a/src/services/spawn/DynamicSpawnArea.java +++ b/src/services/spawn/DynamicSpawnArea.java @@ -36,6 +36,7 @@ import resources.objects.creature.CreatureObject; import services.TerrainService; import services.SimulationService.MoveEvent; import tools.DevLog; +import engine.resources.config.Config; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -59,6 +60,12 @@ public class DynamicSpawnArea extends SpawnArea { @Override @Handler public void onEnter(EnterEvent event) { + + Config options = NGECore.getInstance().getOptions(); + + if (options != null && options.getInt("DO.ISOLATION.TESTS") > 0){ + return; + } SWGObject object = event.object; // ToDo: Mounted players must be handled too diff --git a/src/services/spawn/LairSpawnArea.java b/src/services/spawn/LairSpawnArea.java index 165c53b8..b41222f1 100644 --- a/src/services/spawn/LairSpawnArea.java +++ b/src/services/spawn/LairSpawnArea.java @@ -34,6 +34,7 @@ import resources.objects.creature.CreatureObject; import services.SimulationService.MoveEvent; import services.TerrainService; import services.ai.LairActor; +import engine.resources.config.Config; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -109,6 +110,12 @@ public class LairSpawnArea extends SpawnArea { @Handler public void onEnter(EnterEvent event) { + Config options = NGECore.getInstance().getOptions(); + + if (options != null && options.getInt("DO.ISOLATION.TESTS") > 0){ + return; + } + SWGObject object = event.object; if(object == null || !(object instanceof CreatureObject)) diff --git a/src/services/spawn/MixedSpawnArea.java b/src/services/spawn/MixedSpawnArea.java index e0b0a68b..8a4a5d43 100644 --- a/src/services/spawn/MixedSpawnArea.java +++ b/src/services/spawn/MixedSpawnArea.java @@ -36,6 +36,7 @@ import resources.objects.creature.CreatureObject; import services.TerrainService; import services.SimulationService.MoveEvent; import services.ai.LairActor; +import engine.resources.config.Config; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -61,7 +62,14 @@ public class MixedSpawnArea extends SpawnArea { @Override @Handler public void onEnter(EnterEvent event) { + + Config options = NGECore.getInstance().getOptions(); + if (options != null && options.getInt("DO.ISOLATION.TESTS") > 0){ + return; + } + + SWGObject object = event.object; // ToDo: Mounted players must be handled too //System.out.println("Entering object " + object.getClass().getName()); diff --git a/src/services/spawn/MobileTemplate.java b/src/services/spawn/MobileTemplate.java index 7060a877..efbf7844 100644 --- a/src/services/spawn/MobileTemplate.java +++ b/src/services/spawn/MobileTemplate.java @@ -62,6 +62,8 @@ public class MobileTemplate implements Cloneable { private List lootGroups = new ArrayList(); private String PCDTemplate=""; private String conversationFileName=""; + private boolean AIEnabled = true; + private boolean noAI = false; public Vector getTemplates() { @@ -369,5 +371,21 @@ public class MobileTemplate implements Cloneable { public void setConversationFileName(String conversationFileName) { this.conversationFileName = conversationFileName; } + + public boolean isAIEnabled() { + return AIEnabled; + } + + public void setAIEnabled(boolean aIEnabled) { + AIEnabled = aIEnabled; + } + + public boolean isNoAI() { + return noAI; + } + + public void setNoAI(boolean noAI) { + this.noAI = noAI; + } } diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java index 0fc22032..f5d5aceb 100644 --- a/src/services/spawn/SpawnService.java +++ b/src/services/spawn/SpawnService.java @@ -32,12 +32,12 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Random; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; - import resources.common.collidables.CollidableBox; import resources.common.collidables.CollidableCircle; import resources.datatables.Options; @@ -75,8 +75,14 @@ public class SpawnService { public CreatureObject spawnCreature(String template, long objectId, String planetName, long cellId, float x, float y, float z, float qW, float qX, float qY, float qZ, short level) { - Planet planet = core.terrainService.getPlanetByName(planetName); MobileTemplate mobileTemplate = mobileTemplates.get(template); + return spawnCreature(mobileTemplate, objectId, planetName, cellId, x, y, z, qW, qX, qY, qZ, level); + } + + public CreatureObject spawnCreature(MobileTemplate mobileTemplate, long objectId, String planetName, long cellId, float x, float y, float z, float qW, float qX, float qY, float qZ, short level) { + + Planet planet = core.terrainService.getPlanetByName(planetName); + if(planet == null || mobileTemplate == null) return null; @@ -111,6 +117,9 @@ public class SpawnService { creature.setFaction(mobileTemplate.getFaction()); creature.setFactionStatus(mobileTemplate.getFactionStatus()); creature.setPvpBitmask(mobileTemplate.getPvpBitmask()); + + creature.updatePvpStatus(); + if (mobileTemplate.getCustomName()==null){ creature.setStfFilename("mob/creature_names"); // TODO: set other STFs for NPCs other than creatures -> DONE if (mobileTemplate.getStfFilename()!=null) @@ -159,6 +168,10 @@ public class SpawnService { defaultWeapon.setWeaponType(weaponTemplates.get(rnd).getWeaponType()); defaultWeapon.setMaxRange(weaponTemplates.get(rnd).getMaxRange()); defaultWeapon.setDamageType(weaponTemplates.get(rnd).getDamageType()); + if (defaultWeapon.getTemplate().contains("atst_ranged")){ + defaultWeapon.setStfFilename("theme_park_name"); + defaultWeapon.setStfName("at_st"); + } } if (weaponTemplates.get(rnd).getMinDamage() != 0 && weaponTemplates.get(rnd).getMaxDamage() != 0) { @@ -207,16 +220,26 @@ public class SpawnService { core.skillModService.addSkillMod(creature, "expertise_innate_protection_all", armor); } - AIActor actor = new AIActor(creature, creature.getPosition(), scheduler); - creature.setAttachment("AI", actor); + if (mobileTemplate.isAIEnabled()){ + if (!mobileTemplate.isNoAI()){ // NoAI is for QuestGivers that don't fight to save resources + AIActor actor = new AIActor(creature, creature.getPosition(), scheduler); + creature.setAttachment("AI", actor); + actor.setMobileTemplate(mobileTemplate); + } + } else { // AIEnabled is to dynamically switch the AI on later + AIActor actor = new AIActor(creature, creature.getPosition(), scheduler, false); + creature.setAttachment("AI", actor); + actor.setMobileTemplate(mobileTemplate); + } + + creature.setAttachment("radial_filename", "npc/mobile"); + if (mobileTemplate.getConversationFileName().length()>0){ creature.setAttachment("radial_filename", "object/conversation"); creature.setAttachment("conversationFile", mobileTemplate.getConversationFileName()); } else creature.setAttachment("radial_filename", "npc/mobile"); - actor.setMobileTemplate(mobileTemplate); - - + if(cell == null) { core.simulationService.add(creature, x, z, true); @@ -727,4 +750,13 @@ public class SpawnService { return mobileTemplates.get(template); } + public String getMobileTemplateName(MobileTemplate mobileTemplate) { + for (Entry entry : mobileTemplates.entrySet()) { + if (mobileTemplate.equals(entry.getValue())) { + return entry.getKey(); + } + } + return null; + } + } diff --git a/src/services/sui/SUIService.java b/src/services/sui/SUIService.java index 6b7a6fce..0165c5d1 100644 --- a/src/services/sui/SUIService.java +++ b/src/services/sui/SUIService.java @@ -37,6 +37,7 @@ import org.python.core.PyObject; import protocol.swg.ObjControllerMessage; import protocol.swg.ObjectMenuSelectMessage; import protocol.swg.SUICreatePageMessage; +import protocol.swg.SUICreateTimerBar; import protocol.swg.SUIEventNotification; import protocol.swg.SUIForceClosePageMessage; import protocol.swg.SUIUpdatePageMessage; @@ -490,10 +491,26 @@ public class SUIService implements INetworkDispatch { } SUICreatePageMessage create = new SUICreatePageMessage(window.getScript(), window.getWindowId(), window.getComponents(), rangeObjectId, range); + tools.CharonPacketUtils.printAnalysis(create.serialize(), "SUICreatePageMessage"); owner.getClient().getSession().write(create.serialize()); } + public void openTimerSUIWindow(SUIWindow window, String prompt, int startCount) { + + SWGObject owner = window.getOwner(); + + if(owner == null) + return; + + if(owner.getClient() == null || owner.getClient().getSession() == null) + return; + + SUICreateTimerBar create = new SUICreateTimerBar(window.getScript(), window.getWindowId(), prompt, startCount); + tools.CharonPacketUtils.printAnalysis(create.serialize(), "SUICreateTimerBar"); + owner.getClient().getSession().write(create.serialize()); + } + public void updateSUIWindow(SUIWindow window) { SWGObject owner = window.getOwner(); diff --git a/src/tools/DevLog.java b/src/tools/DevLog.java index c12a3aa5..e639083d 100644 --- a/src/tools/DevLog.java +++ b/src/tools/DevLog.java @@ -35,6 +35,10 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; +import services.ai.AIActor; +import services.ai.TurretAIActor; +import main.NGECore; + /** * @author Charon */ @@ -111,25 +115,109 @@ public class DevLog { if (debugEnable.get(developer)==1){ logMessage = "Devlog->"+developer+"->"+testarea+"-> "+message; DevLogQueuer logger = DevLogQueuer.getInstance(); - logger.log(logMessage); + if (logger!=null) + logger.log(logMessage); } } if (isFileLoggingEnabled(debugRequester)){ if (loggingSessionID>0){ DevLogQueuer logger = DevLogQueuer.getInstance(); - logger.log(logMessage,newFile); + if (logger!=null) + logger.log(logMessage,newFile); } else { createLog(); - DevLogQueuer logger = DevLogQueuer.getInstance(); - logger.log(logMessage,newFile); - loggingSessionID++; + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null){ + logger.log(logMessage,newFile); + loggingSessionID++; + } } } } + public static void debugoutai(AIActor actor, String debugRequester, String testarea, String message){ + if (NGECore.getInstance().aiService.getCheckAI()!=null && actor!=null){ + if (!(NGECore.getInstance().aiService.getCheckAI().getAttachment("AI") instanceof AIActor)) + return; + AIActor checkActor = (AIActor) NGECore.getInstance().aiService.getCheckAI().getAttachment("AI"); + if (checkActor==actor){ + String developer = System.getProperty("user.name"); + String logMessage = ""; + if (!debugRequester.equals(developer)) + return; + if (debugEnable.keySet().contains(developer)){ + + if (debugEnable.get(developer)==1){ + logMessage = "Devlog->"+developer+"->"+testarea+"-> "+message; + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage); + } + } + + if (isFileLoggingEnabled(debugRequester)){ + if (loggingSessionID>0){ + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage,newFile); + + } else { + createLog(); + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null){ + logger.log(logMessage,newFile); + loggingSessionID++; + } + } + } + } + } + } + + public static void debugoutai(TurretAIActor actor, String debugRequester, String testarea, String message){ + if (NGECore.getInstance().aiService.getCheckAI()!=null && actor!=null){ + if (!(NGECore.getInstance().aiService.getCheckAI().getAttachment("AI") instanceof TurretAIActor)) + return; + + TurretAIActor checkActor = (TurretAIActor) NGECore.getInstance().aiService.getCheckAI().getAttachment("AI"); + + if (checkActor==actor){ + String developer = System.getProperty("user.name"); + String logMessage = ""; + if (!debugRequester.equals(developer)) + return; + if (debugEnable.keySet().contains(developer)){ + + if (debugEnable.get(developer)==1){ + logMessage = "Devlog->"+developer+"->"+testarea+"-> "+message; + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage); + } + } + + if (isFileLoggingEnabled(debugRequester)){ + if (loggingSessionID>0){ + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage,newFile); + + } else { + createLog(); + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null){ + logger.log(logMessage,newFile); + loggingSessionID++; + } + } + } + } + } + } + public static void createLog(){ try { @@ -145,7 +233,7 @@ public class DevLog { newFile = Files.createFile(newFile); createHeader(newFile); } catch (IOException ex) { - System.out.println("Error creating file"); + System.out.println("Error creating file " + ex.getMessage()); } } diff --git a/src/tools/DevLogQueuer.java b/src/tools/DevLogQueuer.java index 205eb8cc..58a08f18 100644 --- a/src/tools/DevLogQueuer.java +++ b/src/tools/DevLogQueuer.java @@ -84,7 +84,7 @@ public class DevLogQueuer extends Thread { DevLog.appendToLog(str, path); } catch (Exception iex) { Thread.currentThread().interrupt(); - throw new RuntimeException("Unexpected interruption"); + throw new RuntimeException("Unexpected interruption -> Don't worry about it"); } }