Jump to content

[LE] Making script to fix Dint999 HDT wigs glitch


GentleJack

Recommended Posts

Hello there!


Briefly:

I'm not a newbie in OOP, I know the basics and I want to make a simple script. I need some documentation about Papyrus and Skyrim scripts, because all links I found is broken. For instance, this one: Papyrus Reference Guide. Examples of well documented scripts also suits.

UPD: Solved. I found out documentation on Creation Kit site.


---


Not briefly:


Input:

- Extensible Follower Framework - to have 3 followers with me simultaneously;

- New HDT Physics for KS-SG-HG Hairs - to have beautiful hair with physics as wigs to my followers.


The problem:

I have a party of 3 followers. To each follower a gave a wig from New HDT Physics for KS-SG-HG Hairs. This looks amazing. But sometimes the hair of my followers look glitchy: it is visually anchored in space, causing hilarious graphical artifacts. Funny, but it makes me pissed of. This glithes can be fixed by undressing/redressing wigs, but it is a bit annoying to start save with redressing 3 wigs. You can notice, that there is a good mod to do this named Toggle Options, but I need to redress only wigs (this is essential) placed in 31 armor slot.

UPD: I also desided to expand my fixing script on HDT animal ears and tails from HDT Tail wearable mod.


Possible solution:

Make my own script to redress wigs, of course!



The plan:

1 - I guess that I need a code to put my followers as actor objects to array/list/set, to have a possibility to perform redressing operation on each actor. No idea how to realise it in Papyrus;

UPD: Solved. I use array of actors.


2 - I think it is better to use a pressing a hotkey as start event trigger. I have some guides about it;

UPD: Solved. If object appeares in crosshair and the object is an actor, script places it's reference in variable. Pressing hotkey places this variable in array of actors. Also, there is a check for doubles inside array, and script generate notification about doubles.

Question: when my mode initiates, default hotkey is "ESC". I saw in other mods, that while initiating all default hotkeys have value of "???". How to get it?


3 - I need a variable to store a wig object everytime the script is performing on actor object. I guess this object type should be called "armor" or "pieceOfArmor" or something, dunno. Can someone give me a short description of objects using in scripts?

UPD: Solved. I thought, that I need to undress/redress glithy HDT objects, but I was wrong. Decision: remove HDT object from target's inventory and put it back with RemoveItem() and AddItem() functions.


4 - script body. I think it should look like this:


myArmorVariable = "unknown method"

Function UnequipItemSlot(31)

Function EquipItem(myArmorVariable)


So here I need help with the method of how to define armor variable and with the EquipItem function. As I understood, I should put as argument object ID. I want to make this script a bit flexible and avoid the need of making a solid definition of redressing objects by IDs. How to get it? Like this: Function EquipItem(myArmorVariable.GetItemID())?

UPD: Solved. Thanks IsharaMeradin for help!


5 - what is Alias in Papyrus? Do I need to use Alias to solve this task?

UPD: I still don't have clear inderstanding, what is Alias and what coud be done with it. I used guide and make something with Alias reference in Creation Kit with quest of my mod, but, as I mentioned, don't understand completely what I've done. Anyway, I can see MCM menu of my mod and remap hotkey.


I will appreciate any help and tips. Waiting for comments. Thanks for your attention!

Edited by GentleJack
Link to comment
Share on other sites

  • 2 weeks later...

Sooooooo, I made a script. It, partially, works, but there is one thing, that is worrying me most of all. When I press the mapped button, script runs (mostly, it needs some modification to make all functions properly), but only once. If I press button again - nothing happened. I track it with Debug.Notification. Can someone tell me, WTF is that?

Edited by GentleJack
Link to comment
Share on other sites

From what i suspect, your issue is related to how the 'Wings' mesh is rigid + the hair and the body type your followers use.


For this situation you need to edit / fix the 'Wing' mesh, that from what i can understand, it's not well constructed or it needs to be modify so that it can be use with your followers set up.


If you need / want some help identifying any possible script's malfunction or misfirings, post your script, there are experienced modders / coders here that can lend you a hand, but without the script is like walking in the dark without a candle...
Link to comment
Share on other sites

Two scripts inside: one with logic, second with MCM.

 

I have feeling, that I not properly understand logic of Papyrus. My feeling is, that when my function FixActorHDT try to undress/redress armor slots it executes commands not sequently, but parallel.

 

UPD: i guess i have problems with attachments. I will upload it to cloud and give a link

Edited by GentleJack
Link to comment
Share on other sites

Your OnKeyDown event as posted:

Event OnKeyDown(Int KeyCode)
	;Debug.Notification("HDTFix OnKeyDown entry")
	If KeyCode == HDTArmorFixHotkey.GetValueInt() && objectInFocus == None
		FixAllSelectedActors()
	ElseIf KeyCode == HDTArmorFixHotkey.GetValueInt() && objectInFocus.GetType() == 62  ;gettype() = 62 - kCharacter
		actorInFocus = objectInFocus as Actor
		AddActorToBufer(actorInFocus)			
	EndIf
EndEvent

Your key press will only process if the additional conditions are also true. And then the work will only happen if everything falls in place for the custom functions being called.

I suggest a further break down in order to help you to see what is happening in your game to better troubleshoot your code.

 

 

ObjectReference Ref

Event OnKeyDown(Int KeyCode)
    ;Debug.Notification("HDTFix OnKeyDown entry")
    If KeyCode == HDTArmorFixHotkey.GetValueInt()
        Ref = Game.GetCurrentCrosshairRef()  
        ; OnCrosshairRefChange will run everytime a new object is pointed at
        ; use GetCurrentCrosshairRef at the exact moment needed instead.
        If Ref ; a valid object
            If Ref as Actor ; no need to get the type and if you did need to 43 - kNPC would be the one to use instead of 62 - kCharacter
                Debug.Notification("Valid actor targeted - Storing.")
                AddActorToBufer(Ref as Actor)            
            Else
                Debug.Notification("Valid object but not an actor.")
            EndIf
        Else
            Debug.Notification("No actor targeted - Fixing all stored actors.")
            FixAllSelectedActors()
        EndIf
    EndIf
EndEvent

This adjustment at this point assumes that your custom functions are working properly. You'll know for sure once you get past this hurdle. Also note that for GetCurrentCrosshairRef and OnCrosshairRefChange to work properly, the crosshair target needs to be close enough that if it has a prompt said prompt would be showing.

Link to comment
Share on other sites

 

Your OnKeyDown event as posted:

Event OnKeyDown(Int KeyCode)
	;Debug.Notification("HDTFix OnKeyDown entry")
	If KeyCode == HDTArmorFixHotkey.GetValueInt() && objectInFocus == None
		FixAllSelectedActors()
	ElseIf KeyCode == HDTArmorFixHotkey.GetValueInt() && objectInFocus.GetType() == 62  ;gettype() = 62 - kCharacter
		actorInFocus = objectInFocus as Actor
		AddActorToBufer(actorInFocus)			
	EndIf
EndEvent

Your key press will only process if the additional conditions are also true. And then the work will only happen if everything falls in place for the custom functions being called.

I suggest a further break down in order to help you to see what is happening in your game to better troubleshoot your code.

 

 

ObjectReference Ref

Event OnKeyDown(Int KeyCode)
    ;Debug.Notification("HDTFix OnKeyDown entry")
    If KeyCode == HDTArmorFixHotkey.GetValueInt()
        Ref = Game.GetCurrentCrosshairRef()  
        ; OnCrosshairRefChange will run everytime a new object is pointed at
        ; use GetCurrentCrosshairRef at the exact moment needed instead.
        If Ref ; a valid object
            If Ref as Actor ; no need to get the type and if you did need to 43 - kNPC would be the one to use instead of 62 - kCharacter
                Debug.Notification("Valid actor targeted - Storing.")
                AddActorToBufer(Ref as Actor)            
            Else
                Debug.Notification("Valid object but not an actor.")
            EndIf
        Else
            Debug.Notification("No actor targeted - Fixing all stored actors.")
            FixAllSelectedActors()
        EndIf
    EndIf
EndEvent

This adjustment at this point assumes that your custom functions are working properly. You'll know for sure once you get past this hurdle. Also note that for GetCurrentCrosshairRef and OnCrosshairRefChange to work properly, the crosshair target needs to be close enough that if it has a prompt said prompt would be showing.

 

 

I guess, I fixed the problem: there were incorrect condition of loop break after fixing all stored actors. I still need some testing, but I'm sure everything will be fine. And thanks a lot for your advice and code example! I used it in my actual script revison.

 

Two more things:

1 - how to transfer data from my base script to MCM script. I want to see number of actors stored in array through MCM, but the property value is always equals 0.

2 - on init default hotkey is "ESC". I saw in other mods, that default value could be "???'. How to get it?

Edited by GentleJack
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...