Help in understanding a script function

Post » Thu Aug 27, 2015 9:46 pm

I'm trying to figure out how to give an NPC a shout via scripting, NOT already within the spell list. In my research, I've come across a code that does this but I'm not experienced enough to know what it's doing. The limit of my papyrus knowledge is if x then apply(y). As such I don't know if the whole script is necessary, this is the particular function that I think adds the shout but if the whole thing is necessary then I can provide it.

Spoiler
Int Function ApplyCharacterShouts(String sCharacterName){Apply shouts to named character. Return -1 for failure, or number of shouts applied for success. Needed because AddShout causes savegame corruption. }    If _bApplyShoutsBusy        Return -1    EndIf    _bApplyShoutsBusy = True    Int iConfigShoutHandling = GetConfigInt("SHOUTS_HANDLING")    vMYC_Shoutlist.Revert()    Int jCharacterShouts = GetCharacterObj(sCharacterName,"Shouts")    Int i = JArray.Count(jCharacterShouts)    Int iMissingCount = 0    While i > 0        i -= 1        Shout kShout = JArray.getForm(jCharacterShouts,i) as Shout        If !kShout            iMissingCount += 1        Else            Shout kStormCallShout = GetFormFromFile(0x0007097D,"Skyrim.esm") as Shout            Shout kDragonAspectShout            If GetModByName("Dragonborn.esm")                kDragonAspectShout = GetFormFromFile(0x0201DF92,"DragonBorn.esm") as Shout            EndIf            If kShout == kStormCallShout && (iConfigShoutHandling == 1 || iConfigShoutHandling == 3)                ;Don't add it            ElseIf kShout == kDragonAspectShout && (iConfigShoutHandling == 2 || iConfigShoutHandling == 3)                ;Don't add it            ElseIf GetConfigBool("SHOUTS_BLOCK_UNLEARNED")                If PlayerREF.HasSpell(kShout)                    vMYC_ShoutList.AddForm(kShout)                EndIf            Else                vMYC_ShoutList.AddForm(kShout)                    EndIf        EndIf        ;Debug.Trace("MYC/CM/" + sCharacterName + ": Adding Shout " + kShout + " (" + kShout.GetName() + ") to list...")    EndWhile    ;Debug.Trace("MYC/CM/" + sCharacterName + ": Loading " + vMYC_ShoutList.GetSize() + " Shouts to Actorbase...")    If vMYC_ShoutList.GetSize() == 0        ;Debug.Trace("MYC/CM/" + sCharacterName + ": ShoutList size is 0. Won't attempt to apply this.")        _bApplyShoutsBusy = False        Return 0    EndIf    If iMissingCount        Debug.Trace("MYC/CM/" + sCharacterName + ": Loading " + vMYC_ShoutList.GetSize() + " Shouts with " + iMissingCount + " skipped.",1)    Else        ;Debug.Trace("MYC/CM/" + sCharacterName + ": Loaded " + vMYC_ShoutList.GetSize() + " Shouts.")    EndIf    FFUtils.LoadCharacterShouts(GetCharacterDummy(sCharacterName),vMYC_Shoutlist)    WaitMenuMode(0.1)    _bApplyShoutsBusy = False    Return vMYC_ShoutList.GetSize()EndFunction

I'd like to simplify this to just add a single shout from property to an NPC, I just have no idea what the script is doing and why.

Any help or advice is appreciated.

User avatar
DAVId MArtInez
 
Posts: 3410
Joined: Fri Aug 10, 2007 1:16 am

Post » Thu Aug 27, 2015 1:54 pm

Can you explain what you mean by "not already within the spell list", please?

Which spell list, specifically?

User avatar
Ebony Lawson
 
Posts: 3504
Joined: Fri Feb 16, 2007 11:00 am

Post » Thu Aug 27, 2015 8:17 am

What I mean is, in order for NPC to be able to use shouts they must already have it pre set in their spell list in the creation kit. I'd like an NPC to learn shouts through leveling, so them having access to all of them from the beginning isn't helpful.

User avatar
Becky Cox
 
Posts: 3389
Joined: Thu Jun 22, 2006 8:38 am

Post » Thu Aug 27, 2015 2:06 pm

Well, what your code appears to be doing is using JContainers to iterate over a list of shouts that have been somehow associated with that character name.

It loops over them, and builds a formList of all the shouts in the JContainers list, filtering for Dragon Aspect, possibly Storm Call and possibly shouts the player doesn't know depending on config settings.

The it (presumably) gets the actor with GetCharacterDummy and adds them to that actor them using FFUtils.LoadCharacterShouts about which I know nothing.

From a comment at the top the FFUtils call is needed because AddShout corrupts savegames. Looking at the wiki page, that only applies if you're adding them to NPCs, so if you want to change player leveling, just go head and use a property and call AddShout

User avatar
Gemma Woods Illustration
 
Posts: 3356
Joined: Sun Jun 18, 2006 8:48 pm

Post » Thu Aug 27, 2015 9:41 pm

@Doc,

I think that's the problem OP has? They want to add the shout to an NPC as they level, but AddShout will break their Save?

How do NPCs choose which Shout to use? It might be easier to just make a copy of the Shouts, add them to the NPC via the CK, and find a way to modify the conditions which cause the NPC to pick a given shout...

User avatar
Kelly Tomlinson
 
Posts: 3503
Joined: Sat Jul 08, 2006 11:57 pm

Post » Thu Aug 27, 2015 3:59 pm

Whoops. Misread that (I mean it's only mentioned twice!). In that case they seem to be building a formlist of shouts and passing it off to ffutils.

I don't know whether FFUtils replaces the current shout list in its entirety or just adds new ones. I'm guessing it does a full replace and the JContainers code is to store shouts already added. I don't know how hard it is to get a list of an NPC's current shouts.

Am I right in thinking this is from the Familiar Faces mod on Nexus?

User avatar
Shae Munro
 
Posts: 3443
Joined: Fri Feb 23, 2007 11:32 am

Post » Thu Aug 27, 2015 10:08 pm

Yes that's right, it's Familiar Faces and it's the only lead I have that has a way to add shouts to an NPC without the AddShout command which, as mentioned, corrupts save games. I've tried contacting the author but have yet to hear back.

Spoiler
Scriptname FFutils Hidden{Thanks to Brendan for this plugin}; Replaces the actorbase's perks with the perks listed in the FormListFunction LoadCharacterPerks(ActorBase akActorbase, FormList perkList) native global; Replaces the actorbase's shouts with the shouts listed in the FormListFunction LoadCharacterShouts(ActorBase akActorbase, FormList shoutList) native global; Removes .nif and .dds from the respective directories. ;  Returns;  -1 = Bad ActorBase;   0 = success;   Bitmask:;    1:kReturnDeletedNif;    2:kReturnDeletedDDSInt Function DeleteFaceGenData(ActorBase akActorbase) native globalFunction TraceConsole(String asTrace) native globalString Function UUID() native global

It just sounds terribly complicated for such a simple task and way out of my league. I'm not sure where I'd begin to condense these 2 functions to just, if npc getlevel >= 10.applycharactershouts()

I've actually also tried that as well, one of the first things I tried was replicating the shouts and giving the NPC the AllowShout perk but as far as I can tell the NPC do not care about conditions on shouts. I tried it on the spells themselves and on the MGEFs, don't use it unless you have AllowShout perk but they still use it. So that was a dead end.

User avatar
Sherry Speakman
 
Posts: 3487
Joined: Fri Oct 20, 2006 1:00 pm

Post » Thu Aug 27, 2015 10:26 am

Well, first thing to do is create a formlist in the CK object window. Set a property to that list. Then in your script rever it to empty it from any previous run and then add the shouts you want to the list and call FFUtils.LoadCharacterShouts on your NPC ref.

Then see if the FFUtils function is additive or if it just replaces the shoult list with the list supplied. If the latter then you still have work to do, but you'll be further forward.
User avatar
Laura-Jayne Lee
 
Posts: 3474
Joined: Sun Jul 02, 2006 4:35 pm


Return to V - Skyrim