Jump to content

Quick advice for a scripting-noob?


Recommended Posts

Been trying to change the script of the mod 'Equippable Underwear for NPCs' so it's items don't get distrubuted to certain factions. From what I know, there is a spell distributed to every NPC via SPID which then itself adds the items and some other stuff. From What I understand, SPID's config file should be pretty straight forward by simply adding in a 'NOT 0xFormID' but adding lines for that didn't seem to change anything. I've now tried to modify the script itself with just as little sccess as before. I obviously must have overlooked something but I have no clue what it is. Some advice would be much appreciated <3

The modified script, I've only added the lines around IsInFaction

Scriptname zzzUnderwearMGEFScript extends ActiveMagicEffect

Event OnEffectStart(Actor akTarget, Actor akCaster)
	If akTarget.IsChild()
		akTarget.removeItem(zzzUnderwearFormList, 1000, True)
		Dispel()
		Return
	EndIf
	If akTarget == Game.GetPlayer() || akCaster == Game.GetPlayer() || !GetBaseObject()
		Dispel()
		Return
	EndIf
	If akTarget.GetItemCount(zzzUnderwearFormList) == 0
		akTarget.addItem(zzzUnderwearLItem, 1, True)
	EndIf
	If akTarget.IsInFaction(BanditFaction) == True
		akTarget.removeItem(zzzUnderwearFormList, 1000, True)
		Dispel()
		Return
	EndIf
EndEvent

Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
	Actor target = GetTargetActor()
	If ShouldWearUnderwear(target, akBaseObject)
		Form[] underwearArray = zzzUnderwearFormList.ToArray()
		Int i = underwearArray.Length
		While i
			i -= 1
			Form underwear = underwearArray[i]
			If target.GetItemCount(underwear)
				target.EquipItem(underwear, True, True)
				if !target.IsEquipped(DecapitatedHead)
					target.QueueNiNodeUpdate()
				endIf
				return
			EndIf
		EndWhile
	EndIf
EndEvent

bool Function ShouldWearUnderwear(Actor target, Form akBaseObject)
	If target.GetEquippedArmorInSlot(32) != None
		Return false
	EndIf
	If zzzUnderwearFormList.HasForm(akBaseObject)
		Return false
	EndIf
	If (UI.IsMenuOpen("ContainerMenu") || target.IsDead()) && Game.GetCurrentCrosshairRef() == target
		Return true
	EndIf
	Return false
EndFunction

LeveledItem Property zzzUnderwearLItem Auto
FormList Property zzzUnderwearFormList Auto
Armor Property DecapitatedHead Auto
Faction Property BanditFaction Auto

Link to comment
Share on other sites

There isn't anything technically wrong. Just make sure the script compiles and that you load the mod in the Creation Kit and assign the correct faction to the property that you added. If the property variable is named the same as the faction's EditorID, you can use the Auto-Fill button. If you do not want to mess with editing the plugin, you can use GetFormFromFile

 

The other thing I would do is combine the IsChild condition with the IsInFaction condition because they are doing the same thing. For example:

 

 

Event OnEffectStart(Actor akTarget, Actor akCaster)
  If akTarget.IsChild() || akTarget.IsInFaction(BanditFaction) == True
    akTarget.removeItem(zzzUnderwearFormList, 1000, True)
    Dispel()
    Return
  EndIf
  If akTarget == Game.GetPlayer() || akCaster == Game.GetPlayer() || !GetBaseObject()
    Dispel()
    Return
  EndIf
  If akTarget.GetItemCount(zzzUnderwearFormList) == 0
    akTarget.addItem(zzzUnderwearLItem, 1, True)
  EndIf
EndEvent 

 

 

Link to comment
Share on other sites

Maybe script code like this.

 

zzzUnderwearMGEFScript

 

Scriptname zzzUnderwearMGEFScript extends ActiveMagicEffect
; https://forums.nexusmods.com/index.php?/topic/10429878-quick-advice-for-a-scripting-noob/

; script is from mod "Equippable Underwear for NPCs" (EUN)
; Lutzlisbelt wrote: I want to make sure "its items do not get distributed to certain factions"

  Faction PROPERTY BanditFaction   auto
  Armor   PROPERTY DecapitatedHead auto                 ; auto-fill here

  FormList    PROPERTY zzzUnderwearFormList auto        ; new created by mod
  LeveledItem PROPERTY zzzUnderwearLItem    auto        ; new ..

  Actor target        ; added by ReDragon


; -- EVENTs -- 2

EVENT OnEffectStart(Actor akTarget, Actor akCaster)
IF ( akTarget )
;;    Debug.Trace(" *EUN* - OnEffectStart() - target = " +akTarget+ ", caster = " +akCaster)
    ; now we are sure our target is a valid actor

    IF (akCaster == Game.GetPlayer())
        ; do not allow player as caster of this spell

    ELSEIF myF_IsOK(akTarget)
        target = akTarget                                ; make target persistent for effect runtime
        gotoState("Waiting")        ; ### STATE ###
        RETURN    ; - STOP -    it seems that this spell is an ability
    ENDIF
;    ----------------------
ENDIF

    self.Dispel()
ENDEVENT


EVENT OnEffectFinish(Actor akTarget, Actor akCaster)
;;    Debug.Trace(" *EUN* - OnEffectFinish() - target = " +akTarget+ ", caster = " +akCaster)
    gotoState("")                    ; ### STATE ###
    target = None
ENDEVENT


;===================================
state Waiting
;============
;;;    EVENT OnDeath(Actor akKiller)
;;;    ENDEVENT

EVENT OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
IF ( target )
;;;    IF zzzUnderwearFormList.HasForm(akBaseObject)    ; *** re-equip for this item is blocked, using state switch instead
;;;        RETURN ; - STOP - /1  unequipped item is part of our formlist
;;;    ENDIF
;    ---------------------
    IF (SKSE.GetVersion() > 0)
    ELSE
        RETURN ; - STOP - /0  SKSE not found!
    ENDIF
;    ----------------------
    IF target.GetEquippedArmorInSlot(32)                    ; SKSE!
        RETURN ; - STOP - /2  slot 32 is filled
    ENDIF
;    ---------------------
    IF (target == Game.GetCurrentCrosshairRef())            ; SKSE!
    ELSE
        RETURN ; - STOP - /3  target not crosshair selected
    ENDIF
;    ---------------------
    IF     target.IsDead()
    ELSEIF UI.IsMenuOpen("ContainerMenu")                   ; SKSE!
    ELSE
        RETURN ; - STOP - /4  target alive /OR/ container menu is not open
    ENDIF
;    ---------------------
    myF_ReEquip(target)
ENDIF
ENDEVENT
;=======
endState


; -- FUNCTIONs -- 3

;-----------------------------------
FUNCTION myF_ReEquip(Actor akTarget)  ; last item in formlist, first taken for item check
;-----------------------------------
; keep formlist, do not use converted array
; is waste of script runtime and stack size

    int i = zzzUnderwearFormList.GetSize()
    WHILE (i)                                        ; WHILE (i != 0)
        i = i - 1
        form fm = zzzUnderwearFormList.GetAt(i)      ; fm = underwear

        IF (akTarget.GetItemCount(fm) > 0)
            gotoState("")                ; ### STATE ###

            akTarget.EquipItem(fm, TRUE, TRUE)        ; *** re-equip, make sure OnObjectUnequipped() does not fire for this    
            IF akTarget.IsEquipped(DecapitatedHead)
                ; decapted actor, do not refresh the NiNode mesh
            ELSE
                akTarget.QueueNiNodeUpdate()                ; SKSE!
            ENDIF

            gotoState("Waiting")        ; ### STATE ###
            i = 0        ; break loop here
        ENDIF
    ENDWHILE
ENDFUNCTION


;-------------------------------------
Bool FUNCTION myF_IsOK(Actor akTarget)  ; helper for initial effect conditions
;-------------------------------------
    IF (akTarget == Game.GetPlayer())
        Return False
    ENDIF
;    ----------
    IF akTarget.IsChild() || myF_IsInFaction(akTarget)              ; child or any faction to avoid underwear equipping
        IF (akTarget.GetItemCount(zzzUnderwearFormList) > 0)
            akTarget.RemoveItem(zzzUnderwearFormList, 1000, TRUE)   ; remove any item from inventory, which is part of formlist
        ENDIF
;;;        self.Dispel()        ; will be done in event above
        Return False
    ELSE
        IF (akTarget.GetItemCount(zzzUnderwearFormList) < 1)        ; if target does not have any item from formlist
            akTarget.AddItem(zzzUnderwearLItem, 1, TRUE)            ; then add a single leveledItem to
        ENDIF
        Return TRUE
    ENDIF
ENDFUNCTION


;--------------------------------------------
Bool FUNCTION myF_IsInFaction(Actor akTarget)
;--------------------------------------------
    form[] a = new Form(10)                ; init array for 10
    a[0] = BanditFaction as Form           ; default property

; use TESVEdit (32-bit) or SSEdit (64-bit) to find formIDs for other factions (vanilla used or mod added)
    a[1] = Game.GetForm(0x00123451)        ; fill in the formID of <faction1>
    a[2] = Game.GetForm(0x00123452)        ; fill in the formID of <faction2>
;..
    a[9] = Game.GetFormFromFile("Skyrim.esm", 0x00123459)    ; or use this function like IsharaMeradin suggested for mods or DLCs


    int i = a.Length
    WHILE (i)
        i = i - 1
        faction T = a[i] as Faction
        IF ( T )
            IF akTarget.IsInFaction(T)
                Return TRUE                ; actor is in faction
            ENDIF
        ENDIF
    ENDWHILE

    Return False                           ; no faction match up
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

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