Hyperglyph Posted November 16, 2017 Posted November 16, 2017 I've been trying for several hours to get my first Papyrus script up and running. I came late to the party (stuck with Oblivion for years) and apparently, a lot has changed in how scripts are written. I'm trying to write a simple script that will be attatched to a wig. I'd like to unequip and re-equip the wig when it first loads in a session. This is what I've put together so far: ScriptName WigEquip extends ObjectReference ObjectReference Wig Actor akActor Event OnLoad() Wig = Self akActor = Wig.GetActorRefOwner() akActor.UnequipItem(Wig, false, true) akActor.EquipItem(Wig, false, true) endEvent The CK fails to compile and insists that "GetActorRefOwner is not a function". I've tried GetContainer and other similar things... same issue. I've already unpacked the Skyrim and SKSE scripts into the source directory, and honestly I think the problem is with my code not my install. I don't quite understand the way Papyrus handles references. Used to be I could just stick a token on a NPC and put a GetContainer script on it to return the owner's ref. So, I was hoping someone here could post a simple script or correct mine. (I looked around the forums and read a bunch of other threads... but I'm just not getting it)
Storms of Superior Posted November 16, 2017 Posted November 16, 2017 It seems like that should work with a tweak. Maybe try replacing "Get" with a different term. Don't ask me what term; I can only read scripts, not write or thoroughly understand them.
Andy14 Posted November 16, 2017 Posted November 16, 2017 2 hours ago, Hyperglyph said: GetActorRefOwner This is Fallout 4 only. Use GetActorOwner instead. Link And OnPlayerLoadGame would be better, because OnLoad can happen after cell changes (with wig.Is3DLoaded() ).
Tyrant99 Posted November 16, 2017 Posted November 16, 2017 A simple way would be to create a generic quest in CK, call it AddWig or something. Have your script extend Quest instead of Objectreference. Add a couple properties: Actor Property AkActor auto Armor Property Wig Auto Then all you need for script is the following: You could use OnPlayerLoadGame() if you want per above suggestion. Event OnLoad() akActor.UnequipItem(Wig, false, true) akActor.EquipItem(Wig, false, true) endEvent Now the script works but you have to point the properties to something in CK. So go into the generic blank Quest you created, attach the script to it, click on script and go into properties. Then assign AkActor property to Player, and assign the Wig armor property to whatever wig you want.
Hyperglyph Posted November 16, 2017 Author Posted November 16, 2017 Wow, that's a fast response. Thanks, peeps! 12 hours ago, Andy14 said: OnPlayerLoadGame would be better, because OnLoad can happen after cell changes (with wig.Is3DLoaded() ). In this case, I need to run the script once per wig per game session. Since not all the NPCs are loaded into memory (right?) I need to run the script whenever a new NPC with the wig is loaded. I might be misunderstanding you, apologies if I am. 7 hours ago, Tyrant99 said: A simple way would be to create a generic quest in CK, call it AddWig or something. That would be simpler, but the wig isn't just for the PC. It (and other wigs) are equipped to the NPCs as well. Outside of adding a script to the wigs that triggers when the wig loads, the only way I can think of doing this "mass re-equip" is to use an "always-on" script that scans for any NPCs with the wig equipped. And I REALLY don't want to do that. *************************************************** I've added Andy14's changes, but apparently GetActorOwner() returns an ActorBase and not a reference. That means UnequipItem/EquipItem won't work. Is there another way to get the reference of an armor/wig's wearer? Like the way GetContainer() in Oblivion would return the actor who had the item in their inventory? EDIT: For those curious about the specifics of what I need: I'm working with HDT-SMP wigs using a xEdit script I wrote to assign them to the default outfits. The problem is that when the NPCs change equipment (ANY equipment) HDT locks the wig in place and the hair stretches instead of staying with the NPC when they move. I learned that re-equipping the wigs after loading fixed that problem. So I need a script I can use to quickly re-equip the wigs on every NPC as they load. I've done a lot of testing and I'm still not sure why the stretching happens ONLY in that scenario. It's just a limitation of HDT-SMP, I suppose. I guess it can't handle loading that many objects simultaneously.
Tyrant99 Posted November 17, 2017 Posted November 17, 2017 Effecting every NPC in the game would be taxing to the engine. But you could use a method of dynamically attaching scripts to nearby actors via a cloaktype spell with x radius. That way all actors within x-range to player would get their hair fixed as the player travels around or enters their location cells. You'd set up a magic effect that would have nearby NPCs attach their wigs, and then you could have it trigger when you enter a cell and then maybe send a pulse out on a cooldown. Here's a guide to setting something like that up: https://www.creationkit.com/index.php?title=Dynamically_Attaching_Scripts
Hyperglyph Posted November 19, 2017 Author Posted November 19, 2017 On 11/17/2017 at 12:28 AM, Tyrant99 said: But you could use a method of dynamically attaching scripts to nearby actors via a cloaktype spell with x radius. I'd considered that, but I really wanted to keep this as light as possible. That's partly why I added the wigs to the Default Outfits, rather than using an "auto-equip" type script. Is there really no way to put a "run once and done" script on the wigs themselves? Or are you saying that the cloaktype script would actually be LIGHTER than processing the smaller, individual scripts? Keep in mind that the re-quip only needs to happen once per session. I don't need to requip the wigs on NPCs twice... so there'd be a lot of redundant scanning with a cloaktype spell. I'd have to add tokens to NPCs to mark the "already scanned" ones.
Andy14 Posted November 20, 2017 Posted November 20, 2017 Not tested - but should work. It would have to work with KeyWords in the armor form of the wig. In the OnPlayerLoadGame event make a cell scan to Actors. In a loop check if actor WornHasKeyword(HDTWigKW) is true. HDTWigKW is a property in the script. Keyword Property HDTWigKW auto
Hyperglyph Posted November 30, 2017 Author Posted November 30, 2017 The holidays took me away from this, but I'm back. So I guess everyone agrees that it's impossible to reference an actor within a script on an equipped item. Seems weird as hell to me, but I guess that's what has to be worked with. I thought I'd give Andy's idea a shot. Made an empty quest, added an alias for the player ref, attatched a script to the alias (see below) and added a keyword to the wig. Spoiler ScriptName WigResetScript extends ReferenceAlias Keyword Property HDTWigReset auto Actor kActor Actor kNPC Armor kWig Event OnPlayerLoadGame() kActor = GetReference() as Actor Cell kCell = kActor.GetParentCell() Int iIndex = kCell.GetNumRefs(43) While iIndex iIndex -= 1 kNPC = kCell.GetNthRef(iIndex, 43) as Actor if kNPC.WornHasKeyword(HDTWigReset) kWig = kNPC.GetWornForm(0x00000802) as Armor kNPC.UnequipItem(kWig) kWig = kNPC.GetWornForm(0x00000002) as Armor kNPC.UnequipItem(kWig) endif EndWhile endEvent Nothing happens. The script compiles, but it doesn't seem to be active at all (Debug.Trace() commands aren't printing anything either). I get the feeling I must've made a rookie mistake somewhere. Any further help would be appreciated, but you guys have already been great.
Andy14 Posted November 30, 2017 Posted November 30, 2017 And the Quest is "Start Game Enabled" and not "Rune Once"?
Hyperglyph Posted December 1, 2017 Author Posted December 1, 2017 Update 2: Okay, so the problem is clearly WornHasKeyword and my use of it. This works: if kNPC != kActor This doesn't: if kNPC.WornHasKeyword(ArmorHelmet) && kNPC != kActor ;I used the ArmorHelmet property as a test, since it's vanilla. For the life of me, I don't understand why. Keywords are properly declared, the kNPC is an ObjectReference cast as an Actor... I checked the code in the Auto-Unequip Helmet mod and my syntax is practically identical. Guess I'll keep digging. EDIT: Found an error in the log right after my Debug text that seems related to this: ERROR: Cannot check worn items against a None keyword stack Update 1: Spoiler Update: After reviewing the Auto-Unequip mod, I added stages to the empty quest. I also added the following to my ReferenceAlias script Event OnInit() OnPlayerLoadGame() EndEvent The quest now works and prints debug messages... but the script still doesn't work as intended. if kNPC.WornHasKeyword(HDTWigReset) returns false every time. No other keywords work either, which means the kNPC is being set to invalid actors, I guess. Original Post: Spoiler 13 hours ago, Andy14 said: And the Quest is "Start Game Enabled" and not "Rune Once"? Yup. Double-checked just now to be sure. Priority = 99, Start Game Enabled = true, Run Once = false. I didn't give it a name, type, stages, or any scripts. The WigReset script is attatched to the Quest Alias, not the quest itself. I'll try messing around and see if anything changes, but I'm still flying in the dark. I read somewhere that Quest Aliases can fail to fill properly on first load, so I've been loading multiple times per session just to make sure that isn't the issue. EDIT: I'm going to take another look at that Auto-Unequip Helmet mod. Maybe I can learn something from it.
LazyBoot Posted December 1, 2017 Posted December 1, 2017 Did you fill the keyword property in the creationkit?
Hyperglyph Posted December 1, 2017 Author Posted December 1, 2017 1 hour ago, LazyBoot said: Did you fill the keyword property in the creationkit? That was it. Once I filled in the properties, the script worked with ArmorHelmet as the keyword. It still won't work with my custom keyword, but that's probably a different problem. ... and I suppose it's not the end of the world to requip ALL the headgear instead of just the wigs. Better than nothing, at least. Thanks for the tip, LazyBoot.
Hyperglyph Posted December 2, 2017 Author Posted December 2, 2017 Okay, side problem here. In my ongoing efforts to relearn scripting I've tried to move the re-equip script back onto the wigs. (e.g. an OnLoad event triggers the cell scan) However, the ONLY type of event that works for me is OnInit(). ScriptName WigEquip extends ObjectReference Event OnLoad() Debug.Trace("HelpMe") endEvent That doesn't work at all. And using Self returns a reference to the script itself, not the wig it's attached to... which is correct, apparently, according to the wiki. So, if scripts only read Self as a reference to the script... and only script events like OnInit() work... then how are custom effects/scripts "added" to items in Skyrim?
Tyrant99 Posted December 3, 2017 Posted December 3, 2017 20 hours ago, Hyperglyph said: Okay, side problem here. In my ongoing efforts to relearn scripting I've tried to move the re-equip script back onto the wigs. (e.g. an OnLoad event triggers the cell scan) However, the ONLY type of event that works for me is OnInit(). ScriptName WigEquip extends ObjectReference Event OnLoad() Debug.Trace("HelpMe") endEvent That doesn't work at all. And using Self returns a reference to the script itself, not the wig it's attached to... which is correct, apparently, according to the wiki. So, if scripts only read Self as a reference to the script... and only script events like OnInit() work... then how are custom effects/scripts "added" to items in Skyrim? OnLoad is only for when an Object's 3d is loaded, so it might not fire reliably when you want it to. You may want to check out OnCellLoad and OnCellAttach events. Also, as a sub-note, scripts can be added to items a number of ways, I think just about any kind of object can have scripts added directly, you can do this with armor for instance. You can also set up magic effects that use effect archetype script, there's also at least a couple dozen 'on' events that can be used for triggering things.
Hyperglyph Posted December 3, 2017 Author Posted December 3, 2017 I tried the other OnX events. None of them work, so I think it's just a quirk of the language. The script only seems to recognize itself, and doesn't fire any events that relate to 3D, loading, equipping, cells, or any other "item/world" functions. This was with the script being manually attached. Eventually, I just decided to give up on my plan and made a cloak-type script following the tutorial that Tyrant99 linked to. It's not ideal, but it appears to be up and working. I just wish I knew why none of my custom Keywords are being recognized. i.e. a WornHasKeyword condition in the cloak apply effect will work with "ArmorHelmet == 1.00" but not "HDTWigReset == 1". Even though the keyword is (as far as I can tell) properly added to the items.
Tyrant99 Posted December 3, 2017 Posted December 3, 2017 Hmmm, well Keywords in and of themselves are basically just strings, the main purpose is for grouping things, items, effects, etc. Sometimes its just to categorize, other times its to pass through effects to items. If you attach a keyword to an item in CK, it should be straight-forward to call WornHasKeyword on it. But, keep in mind, properties like this can get baked into a save. So if you run into something straight-forward like this that doesn't work, you may want to launch a new game and test it again.
Hyperglyph Posted December 3, 2017 Author Posted December 3, 2017 I know, it really doesn't make sense how I could mess it up. Just tried again with a new game. Made a new Keyword "WigResetKeyword", added to a KS Hair wig AND a Stormcloak Helmet, changed my magic effect's condition to "WornHasKeyword 'WigResetKeyword' == 1.00". Nothing. It also doesn't work with the "ArmorMaterialKSWigs" keyword from the KS Wigs mod itself. But, as with before, using "ArmorHelmet" as the keyword works just fine. It's not the end of the world, it just means I have to stop sexlab from stripping helmets... since I can't separate helmets from wigs without a keyword. That, plus a lot of unnecessary cloak effects being applied on NPCs who have helmets, not wigs.
LazyBoot Posted December 3, 2017 Posted December 3, 2017 As long as the wigs have a nostrip keyword, sexlab shouldn't strip it (or you can use the sexlab provided keyword). Though at this point I think you may need to provide a screenshot of the creation kit script properties window for the script you're using for testing, and possibly code as well.
Hyperglyph Posted December 4, 2017 Author Posted December 4, 2017 Further testing shows I was actually wrong about my custom Keyword not working on Vanilla items. The StormcloakHelmetFull works fine. However, I'm correct that it doesn't work with the wigs. I've attached some screenshots of the Keyword, the wig I attached it to and the Magic Effect from the cloak tutorial I followed (with the conditional). If anyone has some input, I'd be grateful. Spoiler Spoiler Spoiler
Hyperglyph Posted December 4, 2017 Author Posted December 4, 2017 I've learned that non-Vanilla keywords DO work... but only if they're in the same esp as the wigs. i.e. A merged esp with the wigs and my scripts/quest works fine with "MyCustomKeyword", but a parent-child structure won't. I think the CK is duplicating the wig armors when I edit them in the child .esp, instead of correctly applying the edits to the original armors. I checked it out in xEdit and yea, for some reason editing KSWigsBabydollBandBlack in the CK creates a whole new record that DOESN'T overwrite the wig in the parent .esp. In other words, I wasn't seeing my custom Keywords work on the wigs because my modified wigs were never actually equipped. The NPCs were still wearing the originals. And since the originals already had the Vanilla keywords, the Vanilla Keywords worked fine. So, I guess I'm good as long as I merge my changes into the original mod and use only ONE esp. Or I can try creating an override in xEdit, adding the keywords there, and bypassing the CK altogether. --> On a side note, does anyone know how to hide images in the new LL layout? I tried to drag them into a Spoiler box, but it wouldn't let me.
LazyBoot Posted December 4, 2017 Posted December 4, 2017 3 minutes ago, Hyperglyph said: --> On a side note, does anyone know how to hide images in the new LL layout? I tried to drag them into a Spoiler box, but it wouldn't let me. I think you can press the spoiler button with them selected (the same way you would text), it should put them in a spoiler.
Hyperglyph Posted December 5, 2017 Author Posted December 5, 2017 Yup, that did it. Thanks for all the help, guys, I really appreciate it. With a couple of workarounds and a little legwork, my "Give Every NPC a SMP Wig as a Default Outfit" mod is pretty much complete.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.