From d5d3fa49f2e02eabb1326eee0de642a811c711ae Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sun, 2 Nov 2014 14:22:06 -0500 Subject: [PATCH 01/22] Fixed some warnings in ObjectService --- options.cfg | 2 +- src/services/object/ObjectService.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/options.cfg b/options.cfg index 6f466e49..6c88a6b9 100644 --- a/options.cfg +++ b/options.cfg @@ -28,4 +28,4 @@ DO.ISOLATION.TESTS=0 # Toggles GCW Invasions System. # 1 = On, 0 = Off. -ENABLE.INVASIONS=0 +ENABLE.INVASIONS=1 diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index ab0f4eae..857b54ac 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -1288,7 +1288,8 @@ public class ObjectService implements INetworkDispatch { if(! checkIfObjectAlreadyInList(object.getObjectID())) objectList.put(object.getObjectID(), object); } else { - Thread.currentThread().dumpStack(); + Thread.currentThread(); + Thread.dumpStack(); } }); @@ -1731,12 +1732,12 @@ public class ObjectService implements INetworkDispatch { } private void addCellsToBuildings(){ - Iterator it = null; + Iterator it = null; synchronized(buildingMap){ it = buildingMap.entrySet().iterator(); } while (it.hasNext()) { - Map.Entry pairs = (Map.Entry)it.next(); + Map.Entry pairs = (Map.Entry)it.next(); long buildingId = (long) pairs.getKey(); BuildingObject building = (BuildingObject)pairs.getValue(); //System.out.println("We have buildingId " +buildingId); From bfc1653d686187e82fcc8834d70d7a2b8d9046cd Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Tue, 4 Nov 2014 22:22:05 -0600 Subject: [PATCH 02/22] Refactored EntertainmentService to to allow music to function properly Modified startdance script to work with the refactored EntertainmentService --- scripts/commands/startdance.py | 4 +- src/services/EntertainmentService.java | 81 ++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/scripts/commands/startdance.py b/scripts/commands/startdance.py index ce557827..aec96252 100644 --- a/scripts/commands/startdance.py +++ b/scripts/commands/startdance.py @@ -56,7 +56,9 @@ def startDance(core, actor, danceName, visual): entSvc = core.entertainmentService if visual <= 0: - visual = entSvc.getDanceVisualId(danceName) + print("[PYTHON] startdance.visual = " , visual) + visual = entSvc.getDanceVisualId(danceName) + print("[PYTHON] startdance.visual = " , visual) if visual <= 0: actor.sendSystemMessage('@performance:dance_unknown_self',0) diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index 68907056..7af4ba9b 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -4,6 +4,7 @@ import java.nio.ByteOrder; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; @@ -13,6 +14,7 @@ import java.util.concurrent.TimeUnit; import main.NGECore; +import org.apache.commons.collections.iterators.EntrySetMapIterator; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; @@ -52,7 +54,7 @@ public class EntertainmentService implements INetworkDispatch { private Vector buffBuilderSkills = new Vector(); //FIXME: create a wrapper class for double key lookup maps - private ConcurrentHashMap performances = new ConcurrentHashMap(); + private ConcurrentHashMap performances = new ConcurrentHashMap(); private ConcurrentHashMap performancesByIndex = new ConcurrentHashMap(); private ConcurrentHashMap danceMap = new ConcurrentHashMap(); @@ -68,6 +70,9 @@ public class EntertainmentService implements INetworkDispatch { this.core = core; populateSkillCaps(); populatePerformanceTable(); + + System.out.printf("[DEBUG] number_of_performances: %d\n", performances.size()); + populatePerformanceEffects(); registerCommands(); loadCharacterCustomizationData(); @@ -437,13 +442,21 @@ public class EntertainmentService implements INetworkDispatch { if (p.getType() == -1788534963) { danceMap.put(new Integer(p.getDanceVisualId()), p); } - performances.put(p.getPerformanceName(), p); + performances.put(new PerformanceUID(p.getPerformanceName(), p.getInstrumentAudioId()), p); performancesByIndex.put(r, p); } } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } + + //TODO: Remove + Set debugSet = performances.keySet(); + for(PerformanceUID uid : debugSet) + { + System.out.println(uid.toString()); + } + } private void populateSkillCaps() { @@ -608,13 +621,15 @@ public class EntertainmentService implements INetworkDispatch { }*/ } + //FIXME: Refactor using new map --Complete-- public int getDanceVisualId(String danceName) { - Performance p = performances.get(danceName); + Performance p = getPerformance(danceName, 0); //if 0 , then it's no dance. need to handle that in the script. return ((p == null) ? 0 : p.getDanceVisualId()); } + //FIXME: Refactor using new map ?? Perhaps not ?? public Map getAvailableDances(CreatureObject actor) { Map dances = new HashMap(); @@ -627,6 +642,7 @@ public class EntertainmentService implements INetworkDispatch { } + //FIXME: if visualId > 0 then it is a dance... public boolean isDance(int visualId) { return ( danceMap.get(visualId) != null ) ; } @@ -647,8 +663,10 @@ public class EntertainmentService implements INetworkDispatch { return danceMap.get(visualId); } - public Performance getPerformance(String name) { - return performances.get(name); + //FIXME: Refactor using new map -COMPLETE- + //FIXME: Returning null for known combination... + public Performance getPerformance(String name, int instrumentAudioId) { + return performances.get(new PerformanceUID(name, instrumentAudioId)); } public Performance getPerformanceByIndex(int index) { @@ -757,6 +775,7 @@ public class EntertainmentService implements INetworkDispatch { performer.sendSystemMessage("@performance:flourish_wait_self", (byte) 0); return; } + //FIXME: I don't think this will work. Performance performance = getPerformanceByIndex(performer.getPerformanceId()); if(performance == null) @@ -991,5 +1010,57 @@ public class EntertainmentService implements INetworkDispatch { public void shutdown() { } + + /** + * @author Glen + * This class serves as a unique id for performances. + * The performance.iff file is structured very similar to a database, and with that idea in mind + * this helper-class will serve as essentially the primary key of each performance. + */ + private class PerformanceUID + { + private final String performanceName; + private final int instrumentAudioId; + + public PerformanceUID(String performanceName, int instrumentAudioId) + { + this.performanceName = performanceName; + this.instrumentAudioId = instrumentAudioId; + } + + public boolean equals(PerformanceUID other) { + if(other != null) + { + if(this.performanceName == other.performanceName && this.instrumentAudioId == other.instrumentAudioId) + { + return true; + } + } + return false; + } + + @Override + public boolean equals(Object obj) { + if(obj != null && this.getClass() == obj.getClass() && this.performanceName.equals(((PerformanceUID)obj).performanceName) && this.instrumentAudioId == ((PerformanceUID)obj).instrumentAudioId) + { + return true; + } + return false; + } + + @Override + public int hashCode() { + return this.performanceName != null ? performanceName.hashCode() * 37 + instrumentAudioId: instrumentAudioId; +// int hash = performanceName.hashCode() ^ instrumentAudioId; +// return hash; + } + + @Override + public String toString() { + return "PerformanceUID [performanceName=" + performanceName + + ", instrumentAudioId=" + instrumentAudioId + ", hashCode = " + hashCode() + "]"; + } + + } } From d04c8c11cc5d5a3161dd66db2641367412908df1 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Wed, 5 Nov 2014 10:15:26 -0600 Subject: [PATCH 03/22] Added getInstrument method to EntertainmentService --- src/services/EntertainmentService.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index 7af4ba9b..3eba71b2 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -1006,6 +1006,15 @@ public class EntertainmentService implements INetworkDispatch { return 0; } + /** + * @param actor Player + * @return SWGObject equipped in the player's right hand + */ + public SWGObject getInstrument(CreatureObject actor) + { + return actor.getSlottedObject("hold_r"); + } + @Override public void shutdown() { From 1aac844428c34bd0509942e9485a76bd9cef69ed Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Wed, 5 Nov 2014 21:40:58 -0600 Subject: [PATCH 04/22] Added entertainer music (very rough and buggy) Added stopmusic.py in commands (currently does nothing) Modified startdance.py: removed some debugging print statements --- scripts/commands/startdance.py | 1 - scripts/commands/startmusic.py | 98 ++++++++++++++++++++++++++++++++++ scripts/commands/stopmusic.py | 0 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 scripts/commands/startmusic.py create mode 100644 scripts/commands/stopmusic.py diff --git a/scripts/commands/startdance.py b/scripts/commands/startdance.py index aec96252..b24f18df 100644 --- a/scripts/commands/startdance.py +++ b/scripts/commands/startdance.py @@ -56,7 +56,6 @@ def startDance(core, actor, danceName, visual): entSvc = core.entertainmentService if visual <= 0: - print("[PYTHON] startdance.visual = " , visual) visual = entSvc.getDanceVisualId(danceName) print("[PYTHON] startdance.visual = " , visual) diff --git a/scripts/commands/startmusic.py b/scripts/commands/startmusic.py new file mode 100644 index 00000000..47b39291 --- /dev/null +++ b/scripts/commands/startmusic.py @@ -0,0 +1,98 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + #print("Up the Irons!") + entSvc = core.entertainmentService + instrumentObj = entSvc.getInstrument(actor) + #TODO: Determine if player has an instrument + if instrumentObj is not None: + #TODO: If player does have an instrument then determine what type of instrument the player has + instrumentStfName = instrumentObj.getStfName() + instrumentCode = -1 + #TODO: If type is traz then audioID is 1 + if instrumentStfName == "obj_traz_classic": + instrumentCode = 1 + #TODO: Else if type is slitherhorn then audioID is 2 + elif instrumentStfName == "obj_slitherhorn_classic": + instrumentCode = 2 + #TODO: Else if type is fanfar then audioID is 3 + elif instrumentStfName == "obj_fanfar_classic": + instrumentCode = 3 + #TODO: Else if type is flutedroopy then audioID is 4 + #FIXME: I don't know what this is yet, but I suspect it's "obj_chidinkalu_horn_classic" + + #TODO: Else if type is kloohorn then audioID is 5 + elif instrumentStfName == "obj_kloo_horn_classic": + instrumentCode = 5 + #TODO: Else if type is fizz then audioID is 6 + elif instrumentStfName == "obj_fizzz_classic": + instrumentCode = 6 + #TODO: Else if type is bandfill then audioID is 7 + elif instrumentStfName == "obj_bandfill_classic": + instrumentCode = 7 + + #TODO: Else if type is omnibox then audioID is 8 + #FIXME: This instrument isn't equipped when played + + #TODO: Else if type is nalargon then audioID is 9 + #FIXME: This instrument isn't equipped when played + + #TODO: Else if type is mandoviol then audioID is 10 + elif instrumentStfName == "obj_mandoviol_classic": + instrumentCode = 10 + #TODO: Else if type is xantha then audioID is 11 + elif instrumentStfName == "xantha_n": + instrumentCode = 11 + #TODO: Else if type is flangedjessoon then audioID is 12 + elif instrumentStfName == "obj_jessoon": + instrumentCode = 12 + #TODO: Else if type is valahorn then audioID is 13 + elif instrumentStfName == "obj_valahorn": + instrumentCode = 13 + #TODO: Else if type is downeybox then audioID is 14 + #FIXME: This instrument isn't equipped when played + + print("instrumentCode: " , instrumentCode) + if instrumentCode > 0: + #TODO: Parse command string + if len(commandString) > 0: + params = commandString.split(" ") + performance = entSvc.getPerformance(params[0], instrumentCode) + #print(performance.getPerformanceName(), performance.getInstrumentAudioId()) + startMusic(core, actor, performance, entSvc) + + else: + #TODO: In game error message + pass + else: + #TODO: In game error message + pass + ''' + NOTE: animation files are "all_b_dnc_musician__loop.ans" + NOTE: flourish animation files are "all_b_dnc_musician__sp_8.ans" + ''' + pass +def startMusic(core, actor, performance, entSvc): + print (actor.getPosture()) + if performance is None: + #TODO: Client error message + return + #TODO: Handle lack of skill + if actor.getPosture == 0x09: + #TODO: Client error + #return + pass + + '''if not actor.getPerformanceWatchee(): + actor.setPerfomanceWatchee(actor) + actor.addSpectator(actor)''' + + actor.setPosture(0x09) + + + entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, "dance_0", 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 + pass + \ No newline at end of file diff --git a/scripts/commands/stopmusic.py b/scripts/commands/stopmusic.py new file mode 100644 index 00000000..e69de29b From d808fdd48ef13a09b9ec49ea23416128fbdbd207 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Thu, 6 Nov 2014 08:41:52 -0600 Subject: [PATCH 05/22] Refactored startmusic.py a bit --- scripts/commands/startmusic.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/commands/startmusic.py b/scripts/commands/startmusic.py index 47b39291..7abd6f1b 100644 --- a/scripts/commands/startmusic.py +++ b/scripts/commands/startmusic.py @@ -73,6 +73,7 @@ def run(core, actor, target, commandString): ''' NOTE: animation files are "all_b_dnc_musician__loop.ans" NOTE: flourish animation files are "all_b_dnc_musician__sp_8.ans" + This information doesn't seem to be needed... ''' pass def startMusic(core, actor, performance, entSvc): @@ -86,9 +87,10 @@ def startMusic(core, actor, performance, entSvc): #return pass - '''if not actor.getPerformanceWatchee(): - actor.setPerfomanceWatchee(actor) - actor.addSpectator(actor)''' + if not actor.getPerformanceWatchee(): + #this also notifies the client with a delta4 + actor.setPerformanceWatchee(actor) + actor.addSpectator(actor) actor.setPosture(0x09) From d3bd0220dc0f74a4fb008312de16b2532ce3713a Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Thu, 6 Nov 2014 08:44:06 -0600 Subject: [PATCH 06/22] Added xp gain to music performance. --- scripts/commands/startmusic.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/commands/startmusic.py b/scripts/commands/startmusic.py index 7abd6f1b..14ef7367 100644 --- a/scripts/commands/startmusic.py +++ b/scripts/commands/startmusic.py @@ -94,6 +94,10 @@ def startMusic(core, actor, performance, entSvc): actor.setPosture(0x09) + #Turn on XP gain + playerObject = actor.getSlottedObject('ghost') + if playerObject and playerObject.getProfession() == "entertainer_1a" and actor.getLevel() != 90: + entSvc.startPerformanceExperience(actor) entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, "dance_0", 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 pass From 6dab500e42f46d5cffa49fe325150e1cb9e71409 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Thu, 6 Nov 2014 22:26:01 -0600 Subject: [PATCH 07/22] Experimented with startmusic.py Added some client messages to the startmusic command code --- scripts/commands/startmusic.py | 41 ++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/scripts/commands/startmusic.py b/scripts/commands/startmusic.py index 14ef7367..dbad360c 100644 --- a/scripts/commands/startmusic.py +++ b/scripts/commands/startmusic.py @@ -55,20 +55,25 @@ def run(core, actor, target, commandString): #TODO: Else if type is downeybox then audioID is 14 #FIXME: This instrument isn't equipped when played - print("instrumentCode: " , instrumentCode) + #TODO: Handle instruments that are placed on the ground + + print('instrumentCode: ' , instrumentCode) if instrumentCode > 0: #TODO: Parse command string if len(commandString) > 0: params = commandString.split(" ") performance = entSvc.getPerformance(params[0], instrumentCode) + print('line number: ', performance.getLineNumber()) #print(performance.getPerformanceName(), performance.getInstrumentAudioId()) startMusic(core, actor, performance, entSvc) else: - #TODO: In game error message + #Equipped item is not an instrument + actor.sendSystemMessage('@performance:music_no_instrument', 0) pass else: - #TODO: In game error message + #No instrument equipped + actor.sendSystemMessage('@performance:music_no_instrument', 0) pass ''' NOTE: animation files are "all_b_dnc_musician__loop.ans" @@ -77,14 +82,16 @@ def run(core, actor, target, commandString): ''' pass def startMusic(core, actor, performance, entSvc): - print (actor.getPosture()) + if performance is None: - #TODO: Client error message + #Not a proper song + actor.sendSystemMessage('@performance:music_invalid_song', 0) return + #TODO: Handle lack of skill + if actor.getPosture == 0x09: - #TODO: Client error - #return + actor.sendSystemMessage('@performance:music_fail', 0) pass if not actor.getPerformanceWatchee(): @@ -96,9 +103,25 @@ def startMusic(core, actor, performance, entSvc): #Turn on XP gain playerObject = actor.getSlottedObject('ghost') - if playerObject and playerObject.getProfession() == "entertainer_1a" and actor.getLevel() != 90: + if playerObject and playerObject.getProfession() == "entertainer_1a" and actor.getLevel() != 90: entSvc.startPerformanceExperience(actor) - entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, "dance_0", 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 + #FIXME: player plays wrong song + + anim = 'music_'+ str(performance.getLineNumber()) + #entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, "dance_0", 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 + #entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, anim, 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 + entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, 'music_8', 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 + ''' + Bandfill = music_1 + Nargalon = music_2 + (Some flute-ish)[perhaps traz] = music_3 + Omnibox = music_4 + Mandoviol = music_5 + Nil = music_6 + Nargalon = music_8 + + ''' + pass \ No newline at end of file From ea4c8f06f897846664ecd1cdab30e149899b8434 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Fri, 7 Nov 2014 11:16:09 -0600 Subject: [PATCH 08/22] FIXED Incorrect music playing for each instrument ADDED Player Ability check to playing music ADDED Player notification messages for failed music performance checks ADDED 'canPerform' method to EntertainmentService ADDED 'getAvailableSongs' method to EntertainmentService --- scripts/commands/startmusic.py | 91 ++++++++++++++++---------- src/services/EntertainmentService.java | 33 +++++++++- 2 files changed, 90 insertions(+), 34 deletions(-) diff --git a/scripts/commands/startmusic.py b/scripts/commands/startmusic.py index dbad360c..06c82768 100644 --- a/scripts/commands/startmusic.py +++ b/scripts/commands/startmusic.py @@ -1,72 +1,102 @@ import sys +from services.sui import SUIWindow +from services.sui import SUIService +from services.sui.SUIWindow import Trigger +from services.sui.SUIService import ListBoxType +from java.util import Vector +from java.util import HashMap +from resources.datatables import Posture def setup(): return def run(core, actor, target, commandString): - #print("Up the Irons!") + global suiWindow + global actorObject + global entSvc + actorObject = actor entSvc = core.entertainmentService + instrumentObj = entSvc.getInstrument(actor) + #TODO: Determine if player has an instrument if instrumentObj is not None: - #TODO: If player does have an instrument then determine what type of instrument the player has + #If player does have an instrument then determine what type of instrument the player has instrumentStfName = instrumentObj.getStfName() instrumentCode = -1 - #TODO: If type is traz then audioID is 1 + #If type is traz then audioID is 1 if instrumentStfName == "obj_traz_classic": instrumentCode = 1 - #TODO: Else if type is slitherhorn then audioID is 2 + #if type is slitherhorn then audioID is 2 elif instrumentStfName == "obj_slitherhorn_classic": instrumentCode = 2 - #TODO: Else if type is fanfar then audioID is 3 + #if type is fanfar then audioID is 3 elif instrumentStfName == "obj_fanfar_classic": instrumentCode = 3 - #TODO: Else if type is flutedroopy then audioID is 4 + #if type is flutedroopy then audioID is 4 #FIXME: I don't know what this is yet, but I suspect it's "obj_chidinkalu_horn_classic" - #TODO: Else if type is kloohorn then audioID is 5 + #if type is kloohorn then audioID is 5 elif instrumentStfName == "obj_kloo_horn_classic": instrumentCode = 5 - #TODO: Else if type is fizz then audioID is 6 + #if type is fizz then audioID is 6 elif instrumentStfName == "obj_fizzz_classic": instrumentCode = 6 - #TODO: Else if type is bandfill then audioID is 7 + #if type is bandfill then audioID is 7 elif instrumentStfName == "obj_bandfill_classic": instrumentCode = 7 - #TODO: Else if type is omnibox then audioID is 8 + #if type is omnibox then audioID is 8 #FIXME: This instrument isn't equipped when played - #TODO: Else if type is nalargon then audioID is 9 + #if type is nalargon then audioID is 9 #FIXME: This instrument isn't equipped when played - #TODO: Else if type is mandoviol then audioID is 10 + #if type is mandoviol then audioID is 10 elif instrumentStfName == "obj_mandoviol_classic": instrumentCode = 10 - #TODO: Else if type is xantha then audioID is 11 + #if type is xantha then audioID is 11 elif instrumentStfName == "xantha_n": instrumentCode = 11 - #TODO: Else if type is flangedjessoon then audioID is 12 + #if type is flangedjessoon then audioID is 12 elif instrumentStfName == "obj_jessoon": instrumentCode = 12 - #TODO: Else if type is valahorn then audioID is 13 + #if type is valahorn then audioID is 13 elif instrumentStfName == "obj_valahorn": instrumentCode = 13 - #TODO: Else if type is downeybox then audioID is 14 + #if type is downeybox then audioID is 14 #FIXME: This instrument isn't equipped when played #TODO: Handle instruments that are placed on the ground print('instrumentCode: ' , instrumentCode) if instrumentCode > 0: - #TODO: Parse command string + #Parse command string if len(commandString) > 0: params = commandString.split(" ") performance = entSvc.getPerformance(params[0], instrumentCode) print('line number: ', performance.getLineNumber()) - #print(performance.getPerformanceName(), performance.getInstrumentAudioId()) - startMusic(core, actor, performance, entSvc) + if performance is None: + #Not a proper song + actor.sendSystemMessage('@performance:music_invalid_song', 0) + return + + #Handle lack of skill + if not entSvc.canPerform(actor, performance): + actor.sendSystemMessage('@performance:music_lack_skill_self',0) + return + startMusic(core, actor, performance.getLineNumber()) + else: + availableSongs = entSvc.getAvailableSongs(actor, instrumentCode) + suiSvc = core.suiService + suiWindow = suiSvc.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, "@performance:select_song", "@performance:available_songs", availableSongs, actor, None, 10) + + returnList = Vector() + returnList.add("List.lstList:SelectedRow") + suiWindow.addHandler(0, '', Trigger.TRIGGER_OK, returnList, handleStartMusic) + + suiSvc.openSUIWindow(suiWindow) else: #Equipped item is not an instrument actor.sendSystemMessage('@performance:music_no_instrument', 0) @@ -81,17 +111,15 @@ def run(core, actor, target, commandString): This information doesn't seem to be needed... ''' pass -def startMusic(core, actor, performance, entSvc): - - if performance is None: - #Not a proper song - actor.sendSystemMessage('@performance:music_invalid_song', 0) - return - - #TODO: Handle lack of skill +def handleStartMusic(core, owner, eventType, returnList): + item = suiWindow.getMenuItems().get(int(returnList.get(0))) + print(item.getObjectId()) + startMusic(core, actorObject, item.getObjectId()) + pass +def startMusic(core, actor, performanceLineNumber): if actor.getPosture == 0x09: - actor.sendSystemMessage('@performance:music_fail', 0) + actor.sendSystemMessage('@performance:already_performing_self', 0) pass if not actor.getPerformanceWatchee(): @@ -108,19 +136,16 @@ def startMusic(core, actor, performance, entSvc): #FIXME: player plays wrong song - anim = 'music_'+ str(performance.getLineNumber()) + actor.sendSystemMessage('@performance:music_start_self',0) #entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, "dance_0", 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 #entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, anim, 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 - entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, 'music_8', 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 + entSvc.startPerformance(actor, performanceLineNumber+1, -842249156, 'music_2', 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 ''' Bandfill = music_1 Nargalon = music_2 (Some flute-ish)[perhaps traz] = music_3 Omnibox = music_4 Mandoviol = music_5 - Nil = music_6 - Nargalon = music_8 - ''' pass diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index 3eba71b2..e53212e6 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -51,6 +51,9 @@ public class EntertainmentService implements INetworkDispatch { private NGECore core; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + private static final int SONG = 866729052; + private static final int DANCE = -1788534963; private Vector buffBuilderSkills = new Vector(); //FIXME: create a wrapper class for double key lookup maps @@ -642,6 +645,22 @@ public class EntertainmentService implements INetworkDispatch { } + public Map getAvailableSongs(CreatureObject actor, int instrumentCode) + { + Map songs = new HashMap(); + for(Performance performance : performances.values()) + { + if(performance.getInstrumentAudioId() == instrumentCode) + { + if(canPerform(actor, performance)) + { + songs.put(new Long(performance.getLineNumber()), performance.getPerformanceName()); + } + } + } + return songs; + } + //FIXME: if visualId > 0 then it is a dance... public boolean isDance(int visualId) { return ( danceMap.get(visualId) != null ) ; @@ -654,17 +673,29 @@ public class EntertainmentService implements INetworkDispatch { return false; } + public boolean canDance(CreatureObject actor, int visualId) { if (!isDance(visualId)) { return false; } return canDance(actor, danceMap.get(visualId)); } + + public boolean canPerform(CreatureObject actor, Performance performance) + { + if(performance.getRequiredInstrument() != null) + { + boolean hasInstrument = actor.hasAbility(performance.getRequiredInstrument()); + boolean hasSong = actor.hasAbility(performance.getRequiredSong()); + return hasInstrument && hasSong; + } + else return actor.hasAbility(performance.getRequiredDance()); + } public Performance getDance(int visualId) { return danceMap.get(visualId); } //FIXME: Refactor using new map -COMPLETE- - //FIXME: Returning null for known combination... + //FIXME: Returning null for known combination... - fixed? public Performance getPerformance(String name, int instrumentAudioId) { return performances.get(new PerformanceUID(name, instrumentAudioId)); } From de430bd3e56729acd982397b423b9e0f52501650 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Fri, 7 Nov 2014 13:52:50 -0600 Subject: [PATCH 09/22] FIXED animations while playing instruments --- scripts/commands/startmusic.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/commands/startmusic.py b/scripts/commands/startmusic.py index 06c82768..ff1a94e3 100644 --- a/scripts/commands/startmusic.py +++ b/scripts/commands/startmusic.py @@ -117,6 +117,7 @@ def handleStartMusic(core, owner, eventType, returnList): print(item.getObjectId()) startMusic(core, actorObject, item.getObjectId()) pass + def startMusic(core, actor, performanceLineNumber): if actor.getPosture == 0x09: actor.sendSystemMessage('@performance:already_performing_self', 0) @@ -133,13 +134,33 @@ def startMusic(core, actor, performanceLineNumber): playerObject = actor.getSlottedObject('ghost') if playerObject and playerObject.getProfession() == "entertainer_1a" and actor.getLevel() != 90: entSvc.startPerformanceExperience(actor) + + performance = entSvc.getPerformanceByIndex(performanceLineNumber)#TODO: Refactor to not need this + audioId = performance.getInstrumentAudioId() - #FIXME: player plays wrong song + songAnim = "music_0" + if audioId < 7: + songAnim = "music_3" #Horns + elif audioId < 8: + songAnim = "music_1" #Bandfill + elif audioId < 9: + songAnim = "music_4" #Omnibox + elif audioId < 10: + songAnim = "music_2" #Nargalon + elif audioId < 12: + songAnim = "music_5" #String instruments + elif audioId < 14: + songAnim = "music_3" #More horns + elif audioId < 15: + songAnim = "music_4" #downeybox (Don't think this was ever added) + + print(songAnim) + actor.sendSystemMessage('@performance:music_start_self',0) #entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, "dance_0", 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 #entSvc.startPerformance(actor, performance.getLineNumber(), -842249156, anim, 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 - entSvc.startPerformance(actor, performanceLineNumber+1, -842249156, 'music_2', 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 + entSvc.startPerformance(actor, performanceLineNumber+1, -842249156, songAnim, 0)#TODO: Figure out what exactly goes in parameter slots 2 and 3 ''' Bandfill = music_1 Nargalon = music_2 From b4b45951a9847a0a94a464915adb46f529ffba4a Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Fri, 7 Nov 2014 20:37:57 -0600 Subject: [PATCH 10/22] ADDED basic implementation for the stopmusic command MODIFIED stopdance to indicate the use of a deprecated method --- scripts/commands/stopdance.py | 2 +- scripts/commands/stopmusic.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/commands/stopdance.py b/scripts/commands/stopdance.py index 1427496b..b4f59c2d 100644 --- a/scripts/commands/stopdance.py +++ b/scripts/commands/stopdance.py @@ -11,5 +11,5 @@ def run(core, actor, target, commandString): actor.sendSystemMessage('@performance:dance_not_performing', 0) return - actor.stopPerformance() + actor.stopPerformance()#FIXME: Deprecated method return diff --git a/scripts/commands/stopmusic.py b/scripts/commands/stopmusic.py index e69de29b..1e960468 100644 --- a/scripts/commands/stopmusic.py +++ b/scripts/commands/stopmusic.py @@ -0,0 +1,16 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + entSvc = core.entertainmentService + perf = entSvc.getPerformanceByIndex(actor.getPerformanceId()) + + if actor.getPosture() != 0x09 or not perf or perf.getDanceVisualId() < 0: + actor.sendSystemMessage('@performance:music_not_performing', 0) + return + + actor.stopPerformance()#FIXME: Deprecated method + actor.sendSystemMessage('@performance:music_stop_self', 0) + return From 88a027121668e74a373cea21b835fb3de04067c1 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Fri, 7 Nov 2014 21:51:19 -0600 Subject: [PATCH 11/22] MOVED stopPerformance code from CreatureObject to EntertainmentService MOVED stopAudience code from CreatureObject to EntertainmentService MODIFIED stopdance to utilize refactored stopPerformance code MODIFIED stopmusic to utilize refactored stopPerformance code --- scripts/commands/stopdance.py | 2 +- scripts/commands/stopmusic.py | 4 +- .../objects/creature/CreatureObject.java | 23 +++++-- src/services/EntertainmentService.java | 66 +++++++++++++++++++ 4 files changed, 88 insertions(+), 7 deletions(-) diff --git a/scripts/commands/stopdance.py b/scripts/commands/stopdance.py index b4f59c2d..570441ae 100644 --- a/scripts/commands/stopdance.py +++ b/scripts/commands/stopdance.py @@ -11,5 +11,5 @@ def run(core, actor, target, commandString): actor.sendSystemMessage('@performance:dance_not_performing', 0) return - actor.stopPerformance()#FIXME: Deprecated method + entSvc.stopPerformance(actor) return diff --git a/scripts/commands/stopmusic.py b/scripts/commands/stopmusic.py index 1e960468..84cc095f 100644 --- a/scripts/commands/stopmusic.py +++ b/scripts/commands/stopmusic.py @@ -11,6 +11,6 @@ def run(core, actor, target, commandString): actor.sendSystemMessage('@performance:music_not_performing', 0) return - actor.stopPerformance()#FIXME: Deprecated method - actor.sendSystemMessage('@performance:music_stop_self', 0) + entSvc.stopPerformance(actor) + #actor.sendSystemMessage('@performance:music_stop_self', 0) return diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index b116f39b..11977e19 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -367,7 +367,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { } if (getPosture() == resources.datatables.Posture.SkillAnimating) { - stopPerformance(); + stopPerformance();//FIXME: Find a way to do this with EntertainmentService } if (getPosture() == posture) { @@ -1050,6 +1050,16 @@ public class CreatureObject extends TangibleObject implements IPersistent { this.entertainerExperience = entertainerExperience; } + public void cancelEntertainerExperience() + { + synchronized(objectMutex) { + if (entertainerExperience != null) { + entertainerExperience.cancel(true); + entertainerExperience = null; + } + } + } + public ScheduledFuture getInspirationTick() { return inspirationTick; } @@ -1106,6 +1116,11 @@ public class CreatureObject extends TangibleObject implements IPersistent { setListenToId((performanceListenee == null) ? 0L : performanceListenee.getObjectID()); } + public ArrayList getPerformanceAudience() + { + return new ArrayList(performanceAudience); + } + public int getFlourishCount() { synchronized(objectMutex) { return this.flourishCount; @@ -1588,7 +1603,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } - @Deprecated // FIXME Objects aren't meant for functionality + @Deprecated // FIXME Objects aren't meant for functionality. Instead use EntertainmentService.stopPerformance() public void stopPerformance() { setPerformanceId(0); setPerformanceCounter(0); @@ -1601,7 +1616,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } - sendSystemMessage("@performance:" + getPerformanceType() + "_stop_self", (byte)0); + //sendSystemMessage("@performance:" + getPerformanceType() + "_stop_self", (byte)0); stopAudience(); if (isPerforming()) { @@ -1609,7 +1624,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } - @Deprecated // FIXME Objects aren't meant for functionality + @Deprecated // FIXME Objects aren't meant for functionality. Instead use EntertainmentService.stopAudience() public void stopAudience() { synchronized(objectMutex) { if (performanceAudience == null) { diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index e53212e6..bec391e5 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -1,7 +1,9 @@ package services; import java.nio.ByteOrder; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -719,6 +721,27 @@ public class EntertainmentService implements INetworkDispatch { } } + public void stopPerformance(CreatureObject actor) + { + Performance performance = getPerformanceByIndex(actor.getPerformanceId()); + + actor.setPerformanceId(0); + actor.setPerformanceCounter(0); + actor.setCurrentAnimation("");//I think the animation should be some sort of idle animation. + + actor.cancelEntertainerExperience(); + + String performanceType = (performance.getType() == DANCE)? "dance" : "music"; + + // actor.sendSystemMessage(String.format("@performance:%s_stop_self", performanceType), (byte)0);//FIXME: This hasn't been sending the correct message + stopAudience(actor); + + if (actor.isPerforming()) { + actor.setPerforming(false); + } + actor.setPosture((byte) 0x0); + } + public void startPerformanceExperience(final CreatureObject entertainer) { final ScheduledFuture experienceTask = scheduler.scheduleAtFixedRate(() -> { try { @@ -800,6 +823,49 @@ public class EntertainmentService implements INetworkDispatch { } + public void stopAudience(CreatureObject actor) + { + synchronized(actor.getMutex()) { + if (actor.getPerformanceAudience() == null) { + return; + } + + String performanceType = actor.getPerformanceType(); + Iterator it = actor.getPerformanceAudience().iterator(); + + while (it.hasNext()) { + CreatureObject next = it.next(); + + if (((performanceType.equals("dance")) && (next.getPerformanceWatchee() != actor)) + || ((performanceType.equals("music")) && (next.getPerformanceListenee() != actor))) { + continue; + } + + if (performanceType.equals("dance")) { + next.setPerformanceWatchee(null); + } else if (performanceType.equals("musci")) { + next.setPerformanceListenee(null); + } + + //this may be a bit dodgy. + boolean isEntertained = next.getPerformanceListenee() != null && next.getPerformanceWatchee() != null; + + if (!isEntertained) { + next.setMoodAnimation(""); + } + + if (next == actor) { + continue; + } + + + next.sendSystemMessage("@performance:" + performanceType + "_stop_other", (byte)0); + } + + actor.getPerformanceAudience().clear(); + //performanceAudience = new ArrayList(); + } + } public void performFlourish(final CreatureObject performer, int flourish) { // FIXME There wasn't a limit on flourishes; they just queued up. if (performer.getFlourishCount() > 0 || performer.isPerformingFlourish()) { From 92deb583213d268d73b63a3ad3697262da64a663 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Fri, 7 Nov 2014 22:04:37 -0600 Subject: [PATCH 12/22] MODIFIED CreatureObject.setPosture to use refactored stopPerformance method --- src/resources/objects/creature/CreatureObject.java | 3 ++- src/services/EntertainmentService.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 11977e19..6d12b33a 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -367,7 +367,8 @@ public class CreatureObject extends TangibleObject implements IPersistent { } if (getPosture() == resources.datatables.Posture.SkillAnimating) { - stopPerformance();//FIXME: Find a way to do this with EntertainmentService + //stopPerformance(); + NGECore.getInstance().entertainmentService.stopPerformance(this); } if (getPosture() == posture) { diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index bec391e5..5a012745 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -733,7 +733,7 @@ public class EntertainmentService implements INetworkDispatch { String performanceType = (performance.getType() == DANCE)? "dance" : "music"; - // actor.sendSystemMessage(String.format("@performance:%s_stop_self", performanceType), (byte)0);//FIXME: This hasn't been sending the correct message + actor.sendSystemMessage(String.format("@performance:%s_stop_self", performanceType), (byte)0);//FIXME: This hasn't been sending the correct message stopAudience(actor); if (actor.isPerforming()) { From 2d24e8d8ae3215827299eedbaa561a1d6b9b3448 Mon Sep 17 00:00:00 2001 From: wallaceg09 Date: Sat, 8 Nov 2014 09:44:57 -0600 Subject: [PATCH 13/22] FIXED server crash when a player stops performing. --- src/resources/objects/creature/CreatureObject.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 6d12b33a..be310f6f 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -367,8 +367,8 @@ public class CreatureObject extends TangibleObject implements IPersistent { } if (getPosture() == resources.datatables.Posture.SkillAnimating) { - //stopPerformance(); - NGECore.getInstance().entertainmentService.stopPerformance(this); + stopPerformance(); + //NGECore.getInstance().entertainmentService.stopPerformance(this);//FIXME: Maximum recursion. } if (getPosture() == posture) { From d0e22aeed6abbd0933ebf223855598d4a4e7e62b Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 15:15:58 -0500 Subject: [PATCH 14/22] Changed invasions back to 0 --- options.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options.cfg b/options.cfg index 6c88a6b9..6f466e49 100644 --- a/options.cfg +++ b/options.cfg @@ -28,4 +28,4 @@ DO.ISOLATION.TESTS=0 # Toggles GCW Invasions System. # 1 = On, 0 = Off. -ENABLE.INVASIONS=1 +ENABLE.INVASIONS=0 From 842abb6d8789fc7025fba911e0b522350cb4100b Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 15:19:12 -0500 Subject: [PATCH 15/22] Added cooldown to binoculars --- scripts/object/tangible/gcw/gcw_invasion_binoculars_01.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/object/tangible/gcw/gcw_invasion_binoculars_01.py b/scripts/object/tangible/gcw/gcw_invasion_binoculars_01.py index 02df443d..ca6b996e 100644 --- a/scripts/object/tangible/gcw/gcw_invasion_binoculars_01.py +++ b/scripts/object/tangible/gcw/gcw_invasion_binoculars_01.py @@ -2,6 +2,7 @@ import sys def setup(core, object): object.setIntAttribute('no_trade', 1) + object.setIntAttribute('reuse_time', 5) object.setAttachment('radial_filename', 'object/usable') object.setStfFilename('static_item_n') object.setStfName('invasion_gcw_binoculars_01_01') From d90e9a97b8618327d979a641961b49b79fe3f034 Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 15:19:56 -0500 Subject: [PATCH 16/22] Added stats to blackwing crystal --- .../lightsaber/lightsaber_module_blackwing_crystal.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/object/tangible/component/weapon/lightsaber/lightsaber_module_blackwing_crystal.py b/scripts/object/tangible/component/weapon/lightsaber/lightsaber_module_blackwing_crystal.py index ccad8904..77e03485 100644 --- a/scripts/object/tangible/component/weapon/lightsaber/lightsaber_module_blackwing_crystal.py +++ b/scripts/object/tangible/component/weapon/lightsaber/lightsaber_module_blackwing_crystal.py @@ -1,4 +1,9 @@ import sys def setup(core, object): - return \ No newline at end of file + object.setStringAttribute('condition', '100/100') + object.setStringAttribute('@obj_attr_n:color', 'Blackwing Bezoar') + object.setAttachment('radial_filename', 'item/tunable') + object.setStringAttribute('@obj_attr_n:crystal_owner", "\\#D1F56F UNTUNED \\#FFFFFF ') + return + \ No newline at end of file From 30917c1e0e8e27c1a72b417ab59e9fb828752aa1 Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 15:25:41 -0500 Subject: [PATCH 17/22] Removed protection from katarn armor This caused a bug with protection because the protection was already coded as shown here: https://github.com/ProjectSWGCore/NGECore2/tree/master/scripts/object/tangible/wearables/armor/clone_trooper --- scripts/character_builder_terminal.py | 50 +-------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) diff --git a/scripts/character_builder_terminal.py b/scripts/character_builder_terminal.py index 78901ad4..17d09fa7 100644 --- a/scripts/character_builder_terminal.py +++ b/scripts/character_builder_terminal.py @@ -595,6 +595,7 @@ def compositeArmor(owner, inventory): comp_chest.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); comp_boots = core.objectService.createObject("object/tangible/wearables/armor/composite/shared_armor_composite_boots.iff", owner.getPlanet()) comp_gloves = core.objectService.createObject("object/tangible/wearables/armor/composite/shared_armor_composite_gloves.iff", owner.getPlanet()) + inventory.add(comp_bicep_r); inventory.add(comp_bicep_l); inventory.add(comp_bracer_r); @@ -610,60 +611,11 @@ def compositeArmor(owner, inventory): def clonetrooperArmor(owner, inventory): clonetrooper_bicep_r = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_bicep_r.iff", owner.getPlanet()) - clonetrooper_bicep_r.setIntAttribute("cat_armor_standard_protection.armor_eff_kinetic", 7000); - clonetrooper_bicep_r.setIntAttribute("cat_armor_standard_protection.armor_eff_energy", 5000); - clonetrooper_bicep_r.setIntAttribute("cat_armor_special_protection.special_protection_type_heat", 6000); - clonetrooper_bicep_r.setIntAttribute("cat_armor_special_protection.special_protection_type_cold", 6000); - clonetrooper_bicep_r.setIntAttribute("cat_armor_special_protection.special_protection_type_acid", 6000); - clonetrooper_bicep_r.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); - clonetrooper_bicep_l = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_bicep_l.iff", owner.getPlanet()) - clonetrooper_bicep_l.setIntAttribute("cat_armor_standard_protection.armor_eff_kinetic", 7000); - clonetrooper_bicep_l.setIntAttribute("cat_armor_standard_protection.armor_eff_energy", 5000); - clonetrooper_bicep_l.setIntAttribute("cat_armor_special_protection.special_protection_type_heat", 6000); - clonetrooper_bicep_l.setIntAttribute("cat_armor_special_protection.special_protection_type_cold", 6000); - clonetrooper_bicep_l.setIntAttribute("cat_armor_special_protection.special_protection_type_acid", 6000); - clonetrooper_bicep_l.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); - - clonetrooper_bracer_r = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_bracer_r.iff", owner.getPlanet()) - clonetrooper_bracer_r.setIntAttribute("cat_armor_standard_protection.armor_eff_kinetic", 7000); - clonetrooper_bracer_r.setIntAttribute("cat_armor_standard_protection.armor_eff_energy", 5000); - clonetrooper_bracer_r.setIntAttribute("cat_armor_special_protection.special_protection_type_heat", 6000); - clonetrooper_bracer_r.setIntAttribute("cat_armor_special_protection.special_protection_type_cold", 6000); - clonetrooper_bracer_r.setIntAttribute("cat_armor_special_protection.special_protection_type_acid", 6000); - clonetrooper_bracer_r.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); - clonetrooper_bracer_l = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_bracer_l.iff", owner.getPlanet()) - clonetrooper_bracer_l.setIntAttribute("cat_armor_standard_protection.armor_eff_kinetic", 7000); - clonetrooper_bracer_l.setIntAttribute("cat_armor_standard_protection.armor_eff_energy", 5000); - clonetrooper_bracer_l.setIntAttribute("cat_armor_special_protection.special_protection_type_heat", 6000); - clonetrooper_bracer_l.setIntAttribute("cat_armor_special_protection.special_protection_type_cold", 6000); - clonetrooper_bracer_l.setIntAttribute("cat_armor_special_protection.special_protection_type_acid", 6000); - clonetrooper_bracer_l.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); - clonetrooper_leggings = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_leggings.iff", owner.getPlanet()) - clonetrooper_leggings.setIntAttribute("cat_armor_standard_protection.armor_eff_kinetic", 7000); - clonetrooper_leggings.setIntAttribute("cat_armor_standard_protection.armor_eff_energy", 5000); - clonetrooper_leggings.setIntAttribute("cat_armor_special_protection.special_protection_type_heat", 6000); - clonetrooper_leggings.setIntAttribute("cat_armor_special_protection.special_protection_type_cold", 6000); - clonetrooper_leggings.setIntAttribute("cat_armor_special_protection.special_protection_type_acid", 6000); - clonetrooper_leggings.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); - clonetrooper_helmet = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_helmet.iff", owner.getPlanet()) - clonetrooper_helmet.setIntAttribute("cat_armor_standard_protection.armor_eff_kinetic", 7000); - clonetrooper_helmet.setIntAttribute("cat_armor_standard_protection.armor_eff_energy", 5000); - clonetrooper_helmet.setIntAttribute("cat_armor_special_protection.special_protection_type_heat", 6000); - clonetrooper_helmet.setIntAttribute("cat_armor_special_protection.special_protection_type_cold", 6000); - clonetrooper_helmet.setIntAttribute("cat_armor_special_protection.special_protection_type_acid", 6000); - clonetrooper_helmet.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); - clonetrooper_chest = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_chest_plate.iff", owner.getPlanet()) - clonetrooper_chest.setIntAttribute("cat_armor_standard_protection.armor_eff_kinetic", 7000); - clonetrooper_chest.setIntAttribute("cat_armor_standard_protection.armor_eff_energy", 5000); - clonetrooper_chest.setIntAttribute("cat_armor_special_protection.special_protection_type_heat", 6000); - clonetrooper_chest.setIntAttribute("cat_armor_special_protection.special_protection_type_cold", 6000); - clonetrooper_chest.setIntAttribute("cat_armor_special_protection.special_protection_type_acid", 6000); - clonetrooper_chest.setIntAttribute("cat_armor_special_protection.special_protection_type_electricity", 6000); clonetrooper_boots = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_boots.iff", owner.getPlanet()) clonetrooper_gloves = core.objectService.createObject("object/tangible/wearables/armor/clone_trooper/shared_armor_clone_trooper_neutral_s01_gloves.iff", owner.getPlanet()) From 0f296ea96d44506b39913cade85cca84682ef212 Mon Sep 17 00:00:00 2001 From: Undercova Date: Sat, 8 Nov 2014 23:06:18 +0100 Subject: [PATCH 18/22] Update character_builder_terminal.py --- scripts/character_builder_terminal.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/character_builder_terminal.py b/scripts/character_builder_terminal.py index 78901ad4..34fd20c0 100644 --- a/scripts/character_builder_terminal.py +++ b/scripts/character_builder_terminal.py @@ -305,7 +305,7 @@ def miscHandler(owner): returnList = Vector() returnList.add('List.lstList:SelectedRow') window.addHandler(0, '', Trigger.TRIGGER_OK, returnList, miscHandlerCallback) - window.addListBoxMenuItem('Backpack', 0) + window.addListBoxMenuItem('Instrument', 0) window.addListBoxMenuItem('Heroism Jewelry Set', 1) window.addListBoxMenuItem('Belt of Master Bodo Baas', 2) window.addListBoxMenuItem('Starter Equipment Box', 3) @@ -321,7 +321,7 @@ def miscHandlerCallback(owner, window, eventType, returnList): return if returnList.get(0)=='0': - backpack(owner, inventory) + instrument(owner, inventory) return if returnList.get(0)=='1': heroismJewelry(owner, inventory) @@ -1347,8 +1347,8 @@ def jediBelt(owner, inventory): screenOne(core, owner) return -def backpack(owner, inventory): - # inventory.add(core.objectService.createObject("object/tangible/wearables/backpack/shared_backpack_s01.iff", owner.getPlanet())) +def instrument(owner, inventory): + inventory.add(core.objectService.createObject("object/tangible/instrument/shared_slitherhorn.iff", owner.getPlanet())) screenOne(core, owner) return From a7a4f781644520e3ed3ecd4fa7b978219e0e9776 Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 18:48:42 -0500 Subject: [PATCH 19/22] Added level 5 deathtroopers Started work on Quarantine zone NPCs. --- .../mobiles/dathomir/undead_deathtrooper.py | 90 +++++++++++++++++++ .../dynamicgroups/dathomir_quarantine_1.py | 16 ++++ ...ine_entrance.py => dathomir_quarantine.py} | 3 +- .../static_spawns/dathomir/placeholder.txt | 0 4 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 scripts/mobiles/dathomir/undead_deathtrooper.py create mode 100644 scripts/mobiles/dynamicgroups/dathomir_quarantine_1.py rename scripts/mobiles/spawnareas/{dathomir_quarantine_entrance.py => dathomir_quarantine.py} (65%) delete mode 100644 scripts/static_spawns/dathomir/placeholder.txt diff --git a/scripts/mobiles/dathomir/undead_deathtrooper.py b/scripts/mobiles/dathomir/undead_deathtrooper.py new file mode 100644 index 00000000..7db73dd9 --- /dev/null +++ b/scripts/mobiles/dathomir/undead_deathtrooper.py @@ -0,0 +1,90 @@ +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 java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('eow_outbreak_undead_deathtrooper') + mobileTemplate.setLevel(5) + mobileTemplate.setDifficulty(Difficulty.NORMAL) + + mobileTemplate.setMinSpawnDistance(5) + mobileTemplate.setMaxSpawnDistance(10) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup('undead') + mobileTemplate.setAssistRange(12) + mobileTemplate.setRespawnTime(300) + mobileTemplate.setOptionsBitmask(Options.AGGRESSIVE | Options.ATTACKABLE) + + templates = Vector() + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_01_f.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_01_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_02_f.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_03_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_04_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_05_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_06_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_07_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_08_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_09_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_10_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_11_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_12_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_13_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_14_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_15_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_16_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_17_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_18_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_19_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_20_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_21_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_22_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_23_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_24_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_25_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_26_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_27_m.iff') + templates.add('object/mobile/shared_outbreak_undead_deathtrooper_28_m.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/rifle/shared_rifle_e11', WeaponType.RIFLE, 0.8, 0, 'energy') + weaponTemplates.add(weapontemplate) + weapontemplate = WeaponTemplate('object/weapon/melee/unarmed/shared_unarmed_default.iff', WeaponType.ONEHANDEDMELEE, 1.0, 4, 'kinetic') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('creatureRangedShot') + mobileTemplate.setDefaultAttack('creatureMeleeHit') + mobileTemplate.setAttacks(attacks) + + lootPoolNames_1 = ['Junk'] + lootPoolChances_1 = [100] + lootGroupChance_1 = 65 + mobileTemplate.addToLootGroups(lootPoolNames_1,lootPoolChances_1,lootGroupChance_1) + + lootPoolNames_2 = ['jedi_relic_1'] + lootPoolChances_2 = [100] + lootGroupChance_2 = 85 + mobileTemplate.addToLootGroups(lootPoolNames_2,lootPoolChances_2,lootGroupChance_2) + + lootPoolNames_4 = ['random_stat_jewelry'] + lootPoolChances_4 = [100] + lootGroupChance_4 = 8 + mobileTemplate.addToLootGroups(lootPoolNames_4,lootPoolChances_4,lootGroupChance_4) + + lootPoolNames_5 = ['sithholocrons'] + lootPoolChances_5 = [100] + lootGroupChance_5 = 3 + mobileTemplate.addToLootGroups(lootPoolNames_5,lootPoolChances_5,lootGroupChance_5) + + core.spawnService.addMobileTemplate('undead_deathtrooper', mobileTemplate) + + return \ No newline at end of file diff --git a/scripts/mobiles/dynamicgroups/dathomir_quarantine_1.py b/scripts/mobiles/dynamicgroups/dathomir_quarantine_1.py new file mode 100644 index 00000000..12dc55c4 --- /dev/null +++ b/scripts/mobiles/dynamicgroups/dathomir_quarantine_1.py @@ -0,0 +1,16 @@ +import sys +from java.util import Vector +from services.spawn import DynamicSpawnGroup +from services.spawn import MobileTemplate + +def addDynamicGroup(core): + dynamicGroup = DynamicSpawnGroup() + mobileTemplates = Vector() + mobileTemplates.add('undead_deathtrooper') + dynamicGroup.setMobiles(mobileTemplates) + dynamicGroup.setGroupMembersNumber(5) + dynamicGroup.setName('dathomir_deathtroopers_1') + dynamicGroup.setMaxSpawns(-1) + dynamicGroup.setMinSpawnDistance(10) + core.spawnService.addDynamicGroup('dathomir_level_5_deathtroopers', dynamicGroup) + return diff --git a/scripts/mobiles/spawnareas/dathomir_quarantine_entrance.py b/scripts/mobiles/spawnareas/dathomir_quarantine.py similarity index 65% rename from scripts/mobiles/spawnareas/dathomir_quarantine_entrance.py rename to scripts/mobiles/spawnareas/dathomir_quarantine.py index 3660d7b6..1b18ad73 100644 --- a/scripts/mobiles/spawnareas/dathomir_quarantine_entrance.py +++ b/scripts/mobiles/spawnareas/dathomir_quarantine.py @@ -1,9 +1,8 @@ -# Spawn Area file created with PSWG Planetary Spawn Tool import sys from java.util import Vector def addSpawnArea(core): dynamicGroups = Vector() - dynamicGroups.add('dark_jedi_wild_1') + dynamicGroups.add('dathomir_level_5_deathtroopers') core.spawnService.addDynamicSpawnArea(dynamicGroups, -5700, -6478, 100, 'dathomir') return diff --git a/scripts/static_spawns/dathomir/placeholder.txt b/scripts/static_spawns/dathomir/placeholder.txt deleted file mode 100644 index e69de29b..00000000 From 9552da49dbb9706271b99c72cb7ed640235297d2 Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 18:59:05 -0500 Subject: [PATCH 20/22] Fixed invalid weapon --- scripts/mobiles/dathomir/undead_deathtrooper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mobiles/dathomir/undead_deathtrooper.py b/scripts/mobiles/dathomir/undead_deathtrooper.py index 7db73dd9..bf2c3dd8 100644 --- a/scripts/mobiles/dathomir/undead_deathtrooper.py +++ b/scripts/mobiles/dathomir/undead_deathtrooper.py @@ -54,7 +54,7 @@ def addTemplate(core): mobileTemplate.setTemplates(templates) weaponTemplates = Vector() - weapontemplate = WeaponTemplate('object/weapon/ranged/rifle/shared_rifle_e11', WeaponType.RIFLE, 0.8, 0, 'energy') + weapontemplate = WeaponTemplate('object/weapon/ranged/rifle/shared_rifle_e11.iff', WeaponType.RIFLE, 0.8, 0, 'energy') weaponTemplates.add(weapontemplate) weapontemplate = WeaponTemplate('object/weapon/melee/unarmed/shared_unarmed_default.iff', WeaponType.ONEHANDEDMELEE, 1.0, 4, 'kinetic') weaponTemplates.add(weapontemplate) From 360262765822991c8be81e35c2acba2cf6e01fb4 Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 19:18:19 -0500 Subject: [PATCH 21/22] Changed deathtrooper loot, aggro/assist range and attacks --- .../mobiles/dathomir/undead_deathtrooper.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/scripts/mobiles/dathomir/undead_deathtrooper.py b/scripts/mobiles/dathomir/undead_deathtrooper.py index bf2c3dd8..e3ff624f 100644 --- a/scripts/mobiles/dathomir/undead_deathtrooper.py +++ b/scripts/mobiles/dathomir/undead_deathtrooper.py @@ -9,7 +9,7 @@ from java.util import Vector def addTemplate(core): mobileTemplate = MobileTemplate() - mobileTemplate.setCreatureName('eow_outbreak_undead_deathtrooper') + mobileTemplate.setCreatureName('eow_outbreak_undead_deathtrooper') ##TODO: Needs correct stf name mobileTemplate.setLevel(5) mobileTemplate.setDifficulty(Difficulty.NORMAL) @@ -17,7 +17,7 @@ def addTemplate(core): mobileTemplate.setMaxSpawnDistance(10) mobileTemplate.setDeathblow(True) mobileTemplate.setSocialGroup('undead') - mobileTemplate.setAssistRange(12) + mobileTemplate.setAssistRange(15) mobileTemplate.setRespawnTime(300) mobileTemplate.setOptionsBitmask(Options.AGGRESSIVE | Options.ATTACKABLE) @@ -61,8 +61,8 @@ def addTemplate(core): mobileTemplate.setWeaponTemplateVector(weaponTemplates) attacks = Vector() - mobileTemplate.setDefaultAttack('creatureRangedShot') - mobileTemplate.setDefaultAttack('creatureMeleeHit') + mobileTemplate.setDefaultAttack('RangedShot') + mobileTemplate.setDefaultAttack('MeleeHit') mobileTemplate.setAttacks(attacks) lootPoolNames_1 = ['Junk'] @@ -70,20 +70,10 @@ def addTemplate(core): lootGroupChance_1 = 65 mobileTemplate.addToLootGroups(lootPoolNames_1,lootPoolChances_1,lootGroupChance_1) - lootPoolNames_2 = ['jedi_relic_1'] - lootPoolChances_2 = [100] - lootGroupChance_2 = 85 - mobileTemplate.addToLootGroups(lootPoolNames_2,lootPoolChances_2,lootGroupChance_2) - lootPoolNames_4 = ['random_stat_jewelry'] lootPoolChances_4 = [100] lootGroupChance_4 = 8 mobileTemplate.addToLootGroups(lootPoolNames_4,lootPoolChances_4,lootGroupChance_4) - - lootPoolNames_5 = ['sithholocrons'] - lootPoolChances_5 = [100] - lootGroupChance_5 = 3 - mobileTemplate.addToLootGroups(lootPoolNames_5,lootPoolChances_5,lootGroupChance_5) core.spawnService.addMobileTemplate('undead_deathtrooper', mobileTemplate) From bd33445757b4363e43bd3b1231a6ed2748aa8d73 Mon Sep 17 00:00:00 2001 From: Iosnowore Kun Date: Sat, 8 Nov 2014 19:18:31 -0500 Subject: [PATCH 22/22] Added more static spawn areas for deathtroopers --- scripts/mobiles/spawnareas/dathomir_quarantine.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mobiles/spawnareas/dathomir_quarantine.py b/scripts/mobiles/spawnareas/dathomir_quarantine.py index 1b18ad73..5b8f0b6f 100644 --- a/scripts/mobiles/spawnareas/dathomir_quarantine.py +++ b/scripts/mobiles/spawnareas/dathomir_quarantine.py @@ -4,5 +4,9 @@ from java.util import Vector def addSpawnArea(core): dynamicGroups = Vector() dynamicGroups.add('dathomir_level_5_deathtroopers') - core.spawnService.addDynamicSpawnArea(dynamicGroups, -5700, -6478, 100, 'dathomir') + core.spawnService.addDynamicSpawnArea(dynamicGroups, -5700, -6500, 100, 'dathomir') + core.spawnService.addDynamicSpawnArea(dynamicGroups, -5640, -6550, 100, 'dathomir') + core.spawnService.addDynamicSpawnArea(dynamicGroups, -5850, -6400, 100, 'dathomir') + core.spawnService.addDynamicSpawnArea(dynamicGroups, -5800, -6500, 100, 'dathomir') + core.spawnService.addDynamicSpawnArea(dynamicGroups, -5600, -6525, 100, 'dathomir') return