Jump to content

[LE] Reversing InventoryEventFilter Function


zede5

Recommended Posts

Hi, so I'm a new modder working on my first mod. When it is finished, the mod will basically link chests and categorize items put into linked chests.The player will then be able to put filters on each chest to set what type of items are in it. The problem I am running into has to do with optimization.

 

The system I'm using in the mod is one where there is one "master chest" which holds all items in the system of linked chests until one of them is opened, at which time items corresponding to the filters put on the opened chest are transferred from the master chest to the open chest. However, the way I am sorting items is using an if/then tree that triggers using an OnItemAdded event attached to the master chest. What I am trying to do is create a filter so that all the items that have already been sorted will skip the OnItemAdded event on the master chest. At first I thought I could use the InventoryEventFilter function to do this, but upon reading exactly what the function did, I found that it actually does the exact opposite of what I need. I have a formlist of all the items I don't want to trigger the OnItemAdded event, whereas the InventoryEventFilter function needs a formlist of what items it does want to trigger the event.

 

The only idea I have had so far is to somehow create a formlist of every item the player encounters, then remove all the items that get sorted, but I haven't been able to make it work , and I also feel like it is not a very good solution. So do any of y'all know of a function or something that will fit what I need?

 

Link to comment
Share on other sites

You didn't post any script or part of that. Maybe next sample code is useful.

 

xyzMasterContainerScript

 

Scriptname xyzMasterContainerScript extends ObjectReference
; https://forums.nexusmods.com/index.php?/topic/8301788-reversing-inventoryeventfilter-function/

  ObjectReference PROPERTY container00 auto        ; any other item
  ObjectReference PROPERTY container01 auto        ; Weapons
  ObjectReference PROPERTY container02 auto        ; Armor
  ObjectReference PROPERTY container03 auto        ; Ingredients
  ObjectReference PROPERTY container04 auto        ; Potions
  ObjectReference PROPERTY container05 auto        ; Books

 ;ObjectReference[] PROPERTY myContainerList auto  ; instead of single objectRef properties you could use an array to hold all of them
   ; myContainerList[0] = container00
   ; myContainerList[1] = container01
   ; ..
   ; myContainerList[?] = container??


; -- EVENTs -- 3

EVENT OnInit()
    Debug.Trace(self+" OnInit() - has been reached..")        ; info only
ENDEVENT


EVENT OnActivate(ObjectReference akActionRef)
IF (akActionRef == Game.GetPlayer() as ObjectReference)
ELSE
    RETURN    ; - STOP -    masterchest not player activated
ENDIF
;---------------------
    ; now player transfers some item to self "the masterchest"
    ; which are immediately transfered to categorized containers

    Utility.Wait(0.25)

    ; transfer menu has been closed by player, time to do other things
    ; like message choice to open a sub container menu
ENDEVENT


;EVENT OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
;ENDEVENT


EVENT OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
IF (akBaseItem as Weapon)
    self.RemoveItem(akBaseItem, aiItemCount, TRUE, container01)        ; myContainerList[1]
    RETURN    ; - STOP -
ENDIF
;---------------------    
IF (akBaseItem as Armor)    
    self.RemoveItem(akBaseItem, aiItemCount, TRUE, container02)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (akBaseItem as Ingredient)
    self.RemoveItem(akBaseItem, aiItemCount, TRUE, container03)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (akBaseItem as Potion)
    self.RemoveItem(akBaseItem, aiItemCount, TRUE, container04)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (akBaseItem as Book)
    self.RemoveItem(akBaseItem, aiItemCount, TRUE, container05)
    RETURN    ; - STOP -
ENDIF
;---------------------
    self.RemoveItem(akBaseItem, aiItemCount, TRUE, container00)        ; myContainerList[0]

; some more item classes
    ;IF (akBaseItem as MiscObject)
    ;IF (akBaseItem as Scroll)
    ;IF (akBaseItem as Key)

; samples for keyword sorting
    ;IF akBaseItem.HasKeyword(VendorItemSoulGem)     ; [KYWD:000937A3]    Soulgems
    ;IF akBaseItem.HasKeyword(VendorItemOreIngot)    ; [KYWD:000914EC]    Ingots
    ;IF akBaseItem.HasKeyword(VendorItemRecipe)      ; [KYWD:000F5CB0]    Receipes
    ;IF akBaseItem.HasKeyword(VendorItemSpellTome)   ; [KYWD:000937A5]    SpellTomes

    ;IF akBaseItem.HasKeyword(WeapMaterialSilver)    ; [KYWD:0010AA1A]    Silver Weapons
    ;IF akBaseItem.HasKeyword(WeapMaterialFalmer)    ; [KYWD:000C5C03]    Falmer Weapons and Shields
ENDEVENT

 

 

 

no formlist required and its avoid using of AddInventoryEventFilter()

Edited by ReDragon2013
Link to comment
Share on other sites

First of all, thank you for the response! I had thought of that approach of storing items in presorted chests at first when I started the mod. The problem is that I have a super specific sorting system- almost 30 options, and I plan to add ones that the player can customize as well. Not all the categories use keywords to categorize items, and there are also cases where an item may be in two or more different categories, such as garlic being both in alchemy ingredients and cooking ingredients. I'll gladly post the script, I think you'll see the problem once I post it. Fair warning, its pretty long :b

 

Scriptname CLC_MasterChest extends ReferenceAlias  
{Script to apply to master chest (chest that items are stored in by default)}


EffectShader Property EnchShockFXShader Auto
Actor Property PlayerREF Auto
Message Property CLC_UnlinkMessage Auto
Quest Property CLC_AliasStorage Auto


FormList Property CLC_1HandedWeaponFormList Auto
FormList Property CLC_2HandedWeaponFormList Auto
FormList Property CLC_AlchIngredientFormList Auto
FormList Property CLC_ArrowFormList Auto
FormList Property CLC_BookFormList Auto
FormList Property CLC_ClothingFormList Auto
FormList Property CLC_ClutterFormList Auto
FormList Property CLC_CookingIngredientsFormList Auto
FormList Property CLC_FoodFormList Auto
FormList Property CLC_GemFormList Auto
FormList Property CLC_HealthPotionFormList Auto
FormList Property CLC_HeavyArmorFormList Auto
FormList Property CLC_IngotFormList Auto
FormList Property CLC_JewelryFormList Auto
FormList Property CLC_KeyFormList Auto
FormList Property CLC_LightArmorFormList Auto
FormList Property CLC_MagickaPotionFormList Auto
FormList Property CLC_MiscPotionFormList Auto
FormList Property CLC_MiscFormList Auto
FormList Property CLC_OreFormList Auto
FormList Property CLC_PoisonFormList Auto
FormList Property CLC_ScrollFormList Auto
FormList Property CLC_SoulGemFormList Auto
FormList Property CLC_SpellTomeFormList Auto
FormList Property CLC_StaffWeaponFormList Auto
FormList Property CLC_StaminaPotionFormList Auto
FormList Property CLC_BowFormList Auto
FormList Property CLC_NoteFormList Auto
FormList Property CLC_UnsortedFormList Auto
FormList Property CLC_ValuablesFormList Auto
FormList Property CLC_SortedFormList Auto
FormList Property CLC_TrueUnsortedFormList Auto


Keyword Property ArmorHeavy Auto
Keyword Property ArmorLight Auto
Keyword Property ArmorJewelry Auto
Keyword Property ArmorClothing Auto
Keyword Property VendorItemAnimalHide Auto
Keyword Property VendorItemAnimalPart Auto
Keyword Property VendorItemArmor Auto
Keyword Property VendorItemArrow Auto
Keyword Property VendorItemBook Auto
Keyword Property VendorItemClothing Auto
Keyword Property VendorItemClutter Auto
Keyword Property VendorItemFood Auto
Keyword Property VendorItemFoodRaw Auto
Keyword Property VendorItemGem Auto
Keyword Property VendorItemIngredient Auto
Keyword Property VendorItemJewelry Auto
Keyword Property VendorItemKey Auto
Keyword Property VendorItemOreIngot Auto
Keyword Property VendorItemPoison Auto
Keyword Property VendorItemPotion Auto
Keyword Property VendorItemScroll Auto
Keyword Property VendorItemSoulGem Auto
Keyword Property VendorItemSpellTome Auto
Keyword Property VendorItemStaff Auto
Keyword Property VendorItemWeapon Auto
Keyword Property WeapTypeBattleaxe Auto
Keyword Property WeapTypeBow Auto
Keyword Property WeapTypeDagger Auto
Keyword Property WeapTypeGreatsword Auto
Keyword Property WeapTypeMace Auto
Keyword Property WeapTypeStaff Auto
Keyword Property WeapTypeSword Auto
Keyword Property WeapTypeWarAxe Auto
Keyword Property WeapTypeWarhammer Auto


MagicEffect Property AlchFortifyHealRate Auto
MagicEffect Property AlchFortifyHealth Auto
MagicEffect Property AlchFortifyMagicka Auto
MagicEffect Property AlchFortifyMagickaRate Auto
MagicEffect Property AlchFortifyStamina Auto
MagicEffect Property AlchFortifyStaminaRate Auto
MagicEffect Property AlchRestoreHealth Auto
MagicEffect Property AlchRestoreMagicka Auto
MagicEffect Property AlchRestoreStamina Auto
MagicEffect Property AlchRestoreHealthAll Auto
MagicEffect Property AlchRestoreMagickaAll Auto
MagicEffect Property AlchRestoreStaminaAll Auto






Event OnActivate(ObjectReference akActionRef)
Debug.Notification("Linked Chest")
EndEvent


Auto State Unlinked
Event OnClose(ObjectReference akActionRef)
EnchShockFXShader.Play(Self.GetRef(), -1)
GoToState("Linked")
EndEvent
EndState


State Linked
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
;;Armor
If akBaseItem.GetType() == 26
If akBaseItem.HasKeyword(ArmorHeavy)
CLC_HeavyArmorFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(ArmorLight)
CLC_LightArmorFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(ArmorClothing)
CLC_ClothingFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(ArmorJewelry)
CLC_JewelryFormList.AddForm(akBaseItem)
EndIf
;;Weapons
ElseIf (akBaseItem.GetType() == 41) || (akBaseItem.GetType() == 42)
If akBaseItem.HasKeyword(WeapTypeBattleaxe) || akBaseItem.HasKeyword(WeapTypeGreatsword) || akBaseItem.HasKeyword(WeapTypeWarhammer)
CLC_2HandedWeaponFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(WeapTypeBow)
CLC_BowFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(WeapTypeDagger) || akBaseItem.HasKeyword(WeapTypeSword) || akBaseItem.HasKeyword(WeapTypeMace) || akBaseItem.HasKeyword(WeapTypeWarAxe)
CLC_1HandedWeaponFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(WeapTypeStaff) || akBaseItem.HasKeyword(VendorItemStaff)
CLC_StaffWeaponFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(VendorItemArrow) || (akBaseItem.GetType() == 42)
CLC_ArrowFormList.AddForm(akBaseItem)
EndIf
;;Ingredients
ElseIf (akBaseItem.GetType() == 30)
CLC_AlchIngredientFormList.AddForm(akBaseItem)
If akBaseItem.HasKeyword(VendorItemFoodRaw)
CLC_CookingIngredientsFormList.AddForm(akBaseItem)
EndIf
;;Books
ElseIf (akBaseItem.GetType() == 27)
If akBaseItem.HasKeyword(VendorItemSpellTome)
CLC_SpellTomeFormList.AddForm(akBaseItem)
ElseIf (akBaseItem.GetWeight() == 0)
CLC_NoteFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(VendorItemBook)
CLC_BookFormList.AddForm(akBaseItem)
EndIf
;;SoulGems
ElseIf (akBaseItem.GetType() == 52)
CLC_SoulGemFormList.AddForm(akBaseItem)
;;Scrolls
ElseIf (akBaseItem.GetType() == 23)
CLC_ScrollFormList.AddForm(akBaseItem)
;;MiscItems
ElseIf (akBaseItem.GetType() == 32)
If akBaseItem.HasKeyword(VendorItemSoulGem)
CLC_SoulGemFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(VendorItemGem)
CLC_GemFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(VendorItemOreIngot)
If StringUtil.Find(akBaseItem.GetName(), "Ore") || StringUtil.Find(akBaseItem.GetName(), "Stalhrim")
CLC_OreFormList.AddForm(akBaseItem)
Else
CLC_IngotFormList.AddForm(akBaseItem)
EndIf
ElseIf (akBaseItem.GetGoldValue() >= 250)
CLC_ValuablesFormList.AddForm(akBaseItem)
ElseIf akBaseItem.HasKeyword(VendorItemClutter)
CLC_ClutterFormList.AddForm(akBaseItem)
Else
CLC_MiscFormList.AddForm(akBaseItem)
EndIf
ElseIf (akBaseItem.GetType() == 45)
CLC_KeyFormList.AddForm(akBaseItem)
;;Potions and food
ElseIf (akBaseItem.GetType() == 46)
If (akBaseItem as Potion).IsFood()
If akBaseItem.HasKeyword(VendorItemFoodRaw)
CLC_CookingIngredientsFormList.AddForm(akBaseItem)
EndIf
If akBaseItem.HasKeyword(VendorItemFood)
CLC_FoodFormList.AddForm(akBaseItem)
EndIf
ElseIf (akBaseItem as Potion).IsPoison() || akBaseItem.HasKeyword(VendorItemPoison)
CLC_PoisonFormList.AddForm(akBaseItem)
Else 
MagicEffect[] PotionEffects
PotionEffects = (akBaseItem as Potion).GetMagicEffects()
If PotionEffects.Find(AlchFortifyHealth) || PotionEffects.Find(AlchFortifyHealRate) || PotionEffects.Find(AlchRestoreHealth) || PotionEffects.Find(AlchRestoreHealthAll)
CLC_HealthPotionFormList.AddForm(akBaseItem)
EndIf
If PotionEffects.Find(AlchFortifyStamina) || PotionEffects.Find(AlchFortifyStaminaRate) || PotionEffects.Find(AlchRestoreStamina) || PotionEffects.Find(AlchRestoreStaminaAll)
CLC_StaminaPotionFormList.AddForm(akBaseItem)
EndIf
If PotionEffects.Find(AlchFortifyMagicka) || PotionEffects.Find(AlchFortifyMagickaRate) || PotionEffects.Find(AlchRestoreMagicka) || PotionEffects.Find(AlchRestoreMagickaAll)
CLC_MagickaPotionFormList.AddForm(akBaseItem)
EndIf
Int p = 0
While p <= ((akBaseItem as Potion).GetNumEffects() - 1)
If !(PotionEffects[p] == AlchFortifyHealth || PotionEffects[p] == (AlchFortifyHealRate) || PotionEffects[p] == (AlchRestoreHealth) || PotionEffects[p] == (AlchRestoreHealthAll) || PotionEffects[p] == (AlchFortifyStamina) || PotionEffects[p] == (AlchFortifyStaminaRate) || PotionEffects[p] == (AlchRestoreStamina) || PotionEffects[p] == (AlchRestoreStaminaAll) || PotionEffects[p] == (AlchFortifyMagicka) || PotionEffects[p] == (AlchFortifyMagickaRate) || PotionEffects[p] == (AlchRestoreMagicka) || PotionEffects[p] == (AlchRestoreMagickaAll))
CLC_MiscPotionFormList.AddForm(akBaseItem)
EndIf
p += 1
EndWhile 
EndIf 
Else
CLC_UnsortedFormList.AddForm(akBaseItem)
EndIf
CLC_SortedFormList.AddForm(akBaseItem)
CLC_TrueUnsortedFormList.RemoveAddedForm(akBaseItem)
;;Self.AddInventoryEventFilter(CLC_TrueUnsortedFormList)
EndEvent




EndState

 

Link to comment
Share on other sites

The script was not long, imho very poor structured. At this moment I do not know what are you really want to do here.

Nevertheless a bit rewritten for better understanding.. compiled not yet

 

CLC_MasterChest

 

Scriptname CLC_MasterChest extends ReferenceAlias  
{Script to apply to master chest}    ; chest that items are stored in by default
; https://forums.nexusmods.com/index.php?/topic/8301788-reversing-inventoryeventfilter-function/

  Quest   PROPERTY CLC_AliasStorage  auto            ; !?
  Message PROPERTY CLC_UnlinkMessage auto            ; !?

  EffectShader PROPERTY EnchShockFXShader  auto        ; effect shader to play while sorting
  FormList     PROPERTY CLC_PlayerItemList auto        ; empty formlist has to be created by CK and filled here


; -- EVENTs -- 4 + "Done"

EVENT OnInit()
    Debug.Trace(" OnInit() - has been reached.. " +self)
ENDEVENT


;==========================================
state Done
;=========
    EVENT OnActivate(ObjectReference akActionRef)
    ENDEVENT

    EVENT OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    ENDEVENT
    
    EVENT OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    ENDEVENT
;=======
endState


;EVENT OnClose(ObjectReference akActionRef)
;ENDEVENT


EVENT OnActivate(ObjectReference akActionRef)
IF (akActionRef == Game.GetPlayer() as ObjectReference)
ELSE
    RETURN    ; - STOP -    not player activated
ENDIF
;---------------------
    Debug.Notification("Activation.. linked chest")
    Utility.Wait(0.25)

    gotoState("Done")                ; ### STATE ###  do not interrupt sorting
    myF_PlayFX(TRUE)

float f = Utility.GetCurrentGameTime()                                          ; for debugging ***
    myF_SortByList()
    f = Utility.GetCurrentGameTime() - f     ; *** edited 13th January ***
    Debug.Trace("Sorting in " +f+ " sec")    ; for debugging ***
    myF_PlayFX(False)
    gotoState("")                    ; ### STATE ###    formlist sorting finished
ENDEVENT


EVENT OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    IF (CLC_PlayerItemList.Find(akBaseItem) < 0)
        CLC_PlayerItemList.AddForm(akBaseItem)
    ENDIF
ENDEVENT


EVENT OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    int i = akSourceContainer.GetItemCount(akBaseItem) - aiItemCount
    IF (i <= 0)
        CLC_PlayerItemList.RemoveAddedForm(akBaseItem)
    ENDIF
ENDEVENT


; -- FUNCTIONs -- 4 + 11 = 15

;----------------------------
FUNCTION myF_PlayFX(Bool bOK)
;----------------------------
; https://www.creationkit.com/index.php?title=Play_-_EffectShader
; wiki tells us: "The effects created by this function stack, so using it
;                 multiple times without stopping may cause frame rate issues."

    objectReference oRef = self.GetReference()
IF ( oRef )
    IF (bOK)
        EnchShockFXShader.Play(oRef, -1)    ; play shader FX (no time out)
    ELSE
        EnchShockFXShader.Stop(oRef)        ; stop shader FX
    ENDIF
ENDIF
ENDFUNCTION


;--------------------------------------
Bool FUNCTION myF_HasKW(Form fm, Int i)  ; internal helper to shrink amount of properties
;--------------------------------------
    RETURN fm.HasKeyword(Game.GetForm(i) as Keyword)
ENDFUNCTION


;----------------------------
FUNCTION myF_RevertAllLists()
;----------------------------
; ???
    CLC_UnknownFormList.Revert()

; weapon
    CLC_BowFormList.Revert()
    CLC_StaffWeaponFormList.Revert()
    CLC_2HandedWeaponFormList.Revert()
    CLC_1HandedWeaponFormList.Revert()

; ammo
    CLC_ArrowFormList.Revert()

; key
    CLC_KeyFormList.Revert()

; Ingredient
    CLC_AlchIngredientFormList.Revert()
    CLC_CookingIngredientsFormList.Revert()

; Potion
    CLC_FoodFormList.Revert()
    CLC_PoisonFormList.Revert()

; Scroll
    CLC_ScrollFormList.Revert()

; Armor
    CLC_ShieldFormList.Revert()
    CLC_HeavyArmorFormList.Revert()
    CLC_LightArmorFormList.Revert()
    CLC_JewelryFormList.Revert()
    CLC_ClothingFormList.Revert()

; Book
    CLC_SpellTomeFormList.Revert()
    CLC_ReceipeFormList.Revert()
    CLC_SkillBookWizardFormList.Revert()
    CLC_NoteFormList.Revert()
    CLC_BookFormList.Revert()

; MiscObject
    CLC_SoulGemFormList.Revert()
    CLC_GemFormList.Revert()
    CLC_OreFormList.Revert()
    CLC_IngotFormList.Revert()
    CLC_ValuablesFormList.Revert()
    CLC_ClutterFormList.Revert()
    CLC_MiscFormList.Revert()

; Potion
    CLC_HealthPotionFormList.Revert()
    CLC_MagickaPotionFormList.Revert()
    CLC_StaminaPotionFormList.Revert()
    CLC_MiscPotionFormList.Revert()
ENDFUNCTION


;------------------------
FUNCTION myF_SortByList()
;------------------------
    myF_RevertAllLists()        ; just an approach, can be handled much better

int i = CLC_PlayerItemList.GetSize()
    WHILE (i)                                ; WHILE (i > 0)
        i = i - 1
        form fm = CLC_PlayerItemList.GetAt(i)
        
        IF     (fm as Weapon)
                                    myF_Add41(fm)
        ELSEIF (fm as Ammo)
                                    myF_Add42(fm)
        ELSEIF (fm as Key)
                                    myF_Add45(fm)
        ELSEIF (fm as Potion)
                                    myF_Add46(fm)    ; potions and food
        ELSEIF (fm as Scroll)
                                    myF_Add23(fm)
        ELSEIF (fm as Armor)
                                    myF_Add26(fm)
        ELSEIF (fm as Book)
                                    myF_Add27(fm)
        ELSEIF (fm as Ingredient)
                                    myF_Add30(fm)
        ELSEIF (fm as MiscObject)
                                    myF_Add32(fm)    ; miscItems and soulgems
        ELSE
                                    myF_Add00(fm)    ; *** edited 13th January ***
        ENDIF
    ENDWHILE
ENDFUNCTION


  FormList PROPERTY CLC_UnknownFormList auto

  Keyword Property VendorItemAnimalHide Auto            ; VendorItemAnimalHide [KYWD:000914EA]
  Keyword Property VendorItemAnimalPart Auto            ; VendorItemAnimalPart [KYWD:000914EB]
  Keyword Property VendorNoSale            Auto         ; VendorNoSale [KYWD:000FF9FB]

;--------------------------
FUNCTION myF_Add00(Form fm)
;--------------------------
;IF fm.HasKeyword(VendorItemClothing)                   ; VendorItemClothing [KYWD:0008F95B]
;    CLC_ClothingFormList.AddForm(fm)
;ELSE
    CLC_UnknownFormList.AddForm(fm)
;ENDIF
ENDFUNCTION


  FormList PROPERTY CLC_BowFormList           auto
  FormList PROPERTY CLC_StaffWeaponFormList   auto
  FormList PROPERTY CLC_2HandedWeaponFormList auto
  FormList PROPERTY CLC_1HandedWeaponFormList auto

;--------------------------
FUNCTION myF_Add41(Form fm)  ; (akBaseItem.GetType() == 41)
;--------------------------
IF myF_HasKW(fm, 0x0001E715)             ; [KYWD:0001E715]  fm.HasKeyword(WeapTypeBow)
    CLC_BowFormList.AddForm(fm)
    RETURN    ; - STOP -    bows and crossbows
ENDIF
;---------------------                                    ; [KYWD:0001E716] fm.HasKeyword(WeapTypeStaff)
IF myF_HasKW(fm, 0x0001E716) ||    myF_HasKW(fm, 000937A4)    ; [KYWD:000937A4] fm.HasKeyword(VendorItemStaff)
    CLC_StaffWeaponFormList.AddForm(fm)
    RETURN    ; - STOP -    any kind of magic staff
ENDIF
;--------------------- fm.HasKeyword(WeapTypeBattleaxe) || fm.HasKeyword(WeapTypeGreatsword) || fm.HasKeyword(WeapTypeWarhammer)
IF myF_HasKW(oRef, 0x0006D932) || myF_HasKW(oRef, 0x0006D931) || myF_HasKW(oRef, 0x0006D930)
    CLC_2HandedWeaponFormList.AddForm(fm)
    RETURN    ; - STOP -    any kind of 2H-Weapon
ENDIF
;---------------------
;IF fm.HasKeyword(WeapTypeDagger) || fm.HasKeyword(WeapTypeSword) || fm.HasKeyword(WeapTypeMace) || fm.HasKeyword(WeapTypeWarAxe)
    CLC_1HandedWeaponFormList.AddForm(akBaseItem)
;ENDIF
ENDFUNCTION


  FormList PROPERTY CLC_ArrowFormList auto

;--------------------------
FUNCTION myF_Add42(Form fm)  ; (akBaseItem.GetType() == 42)
;--------------------------
;IF fm.HasKeyword(VendorItemArrow)                        ; VendorItemArrow [KYWD:000917E7]
    CLC_ArrowFormList.AddForm(fm)
;ENDIF
ENDFUNCTION


  FormList PROPERTY CLC_KeyFormList auto

;--------------------------
FUNCTION myF_Add45(Form fm)  ; (akBaseItem.GetType() == 45)
;--------------------------
    CLC_KeyFormList.AddForm(fm)
ENDFUNCTION


  FormList PROPERTY CLC_AlchIngredientFormList     auto
  FormList PROPERTY CLC_CookingIngredientsFormList auto

;--------------------------
FUNCTION myF_Add30(Form fm)  ; (akBaseItem.GetType() == 30)
;--------------------------
IF myF_HasKW(fm, 0x000A0E56)                            ; [KYWD:000A0E56] fm.HasKeyword(VendorItemFoodRaw)
    CLC_CookingIngredientsFormList.AddForm(fm)
    RETURN    ; - STOP -    for cooking
ENDIF
;---------------------
;IF fm.HasKeyword(VendorItemIngredient)                 ; VendorItemIngredient [KYWD:0008CDEB]
    CLC_AlchIngredientFormList.AddForm(fm)
;ENDIF
ENDFUNCTION


  FormList PROPERTY CLC_FoodFormList   auto
  FormList PROPERTY CLC_PoisonFormList auto

;--------------------------
FUNCTION myF_Add46(Form fm)  ; (akBaseItem.GetType() == 46)
;--------------------------
IF myF_HasKW(fm, 0x000A0E56)                            ; [KYWD:000A0E56] fm.HasKeyword(VendorItemFoodRaw)
    CLC_CookingIngredientsFormList.AddForm(fm)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF myF_HasKW(fm, 0x0008CDEA)                            ; [KYWD:0008CDEA] fm.HasKeyword(VendorItemFood)
    CLC_FoodFormList.AddForm(fm)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF fm.IsFood()                                ; SKSE required !!!
    CLC_FoodFormList.AddForm(fm)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF myF_HasKW(fm, 0x0008CDED)                            ; [KYWD:0008CDED] fm.HasKeyword(VendorItemPoison)
    CLC_PoisonFormList.AddForm(fm)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF fm.IsPoison()                            ; SKSE required !!!
    CLC_PoisonFormList.AddForm(fm)
    RETURN    ; - STOP -
ENDIF
;---------------------
    myF_AddPotion2EffectList(fm)            ; SKSE required !!!
ENDFUNCTION


  FormList PROPERTY CLC_ScrollFormList auto

;--------------------------
FUNCTION myF_Add23(Form fm)  ; (akBaseItem.GetType() == 23)
;--------------------------
    CLC_ScrollFormList.AddForm(fm)
ENDFUNCTION


  FormList PROPERTY CLC_ShieldFormList     auto
  FormList PROPERTY CLC_HeavyArmorFormList auto
  FormList PROPERTY CLC_LightArmorFormList auto
  FormList PROPERTY CLC_JewelryFormList    auto
  FormList PROPERTY CLC_ClothingFormList   auto

;--------------------------
FUNCTION myF_Add26(Form fm)  ; (akBaseItem.GetType() == 26)
;--------------------------
IF myF_HasKW(fm, 0x000965B2)                            ; [KYWD:000965B2] fm.HasKeyword(ArmorShield)
    CLC_ShieldFormList.AddForm(fm)
    RETURN    ; - STOP -    shields
ENDIF
;---------------------
IF myF_HasKW(fm, 0x0006BBD2)                            ; [KYWD:0006BBD2] fm.HasKeyword(ArmorHeavy)
    CLC_HeavyArmorFormList.AddForm(fm)
    RETURN    ; - STOP -    heavy armor
ENDIF
;---------------------
IF myF_HasKW(fm, 0x0006BBD3)                            ; [KYWD:0006BBD3] fm.HasKeyword(ArmorLight)
    CLC_LightArmorFormList.AddForm(fm)
    RETURN    ; - STOP -    light armor
ENDIF
;---------------------
IF myF_HasKW(fm, 0x0006BBE9)                            ; [KYWD:0006BBE9] fm.HasKeyword(ArmorJewelry)
    CLC_JewelryFormList.AddForm(fm)
    RETURN    ; - STOP -    jewelry
ENDIF
;---------------------
;IF fm.HasKeyword(ArmorClothing)                        ; ArmorClothing [KYWD:0006BBE8]
    CLC_ClothingFormList.AddForm(fm)
;ENDIF
ENDFUNCTION


  FormList PROPERTY CLC_SpellTomeFormList auto
  FormList PROPERTY CLC_ReceipeFormList   auto
  FormList PROPERTY CLC_SkillBookWizardFormList auto
  FormList PROPERTY CLC_NoteFormList      auto
  FormList PROPERTY CLC_BookFormList      auto

;--------------------------
FUNCTION myF_Add27(Form fm)  ; (akBaseItem.GetType() == 27)
;--------------------------
IF myF_HasKW(fm, 0x000937A5)                            ; [KYWD:000937A5] fm.HasKeyword(VendorItemSpellTome)
    CLC_SpellTomeFormList.AddForm(fm)
    RETURN    ; - STOP -    spelltome
ENDIF
;---------------------
IF myF_HasKW(fm, 0x000F5CB0)                            ; [KYWD:000F5CB0] fm.HasKeyword(VendorItemRecipe)
    CLC_ReceipeFormList.AddForm(fm)
    RETURN    ; - STOP -    receipe
ENDIF
;---------------------
IF myF_HasKW(fm, 0x000A0E62)                            ; [KYWD:000A0E62] fm.HasKeyword(GiftWizardSpecial)
    CLC_SkillBookWizardFormList.AddForm(fm)
    RETURN    ; - STOP -    wizard skillbook
ENDIF
;---------------------
IF (fm.GetWeight() == 0.0)                ; SKSE required !!!
    CLC_NoteFormList.AddForm(fm)
    RETURN    ; - STOP -    note
ENDIF
;---------------------
;IF fm.HasKeyword(VendorItemBook)                        ; VendorItemBook [KYWD:000937A2]
    CLC_BookFormList.AddForm(fm)
;ENDIF
ENDFUNCTION


  FormList PROPERTY CLC_SoulGemFormList   auto
  FormList PROPERTY CLC_GemFormList       auto
  FormList PROPERTY CLC_OreFormList       auto
  FormList PROPERTY CLC_IngotFormList     auto
  FormList PROPERTY CLC_ValuablesFormList auto
  FormList PROPERTY CLC_ClutterFormList   auto
  FormList PROPERTY CLC_MiscFormList      auto

;--------------------------
FUNCTION myF_Add32(Form fm)  ; (akBaseItem.GetType() == 32) || (akBaseItem.GetType() == 52)
;--------------------------
IF myF_HasKW(fm, 0x000937A3)                            ; [KYWD:000937A3] fm.HasKeyword(VendorItemSoulGem)
    CLC_SoulGemFormList.AddForm(fm)
    RETURN    ; - STOP -    soulgems 52
ENDIF
;---------------------
IF myF_HasKW(fm, 0x000914ED)                            ; [KYWD:000914ED] fm.HasKeyword(VendorItemGem)
    CLC_GemFormList.AddForm(fm)
    RETURN    ; - STOP -    gems
ENDIF
;---------------------
IF myF_HasKW(fm, 0x000914EC)                            ; [KYWD:000914EC] fm.HasKeyword(VendorItemOreIngot)
    IF StringUtil.Find(fm.GetName(), "Ore") || StringUtil.Find(fm.GetName(), "Stahlrim")                        ; SKSE required !!!
        ; it works for the English language only !!!
        CLC_OreFormList.AddForm(fm)
    ELSE
        CLC_IngotFormList.AddForm(fm)
    ENDIF
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (fm.GetGoldValue() >= 250)                ; SKSE required !!!
    CLC_ValuablesFormList.AddForm(fm)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF myF_HasKW(fm, 0x000914E9)                            ; [KYWD:000914E9] fm.HasKeyword(VendorItemClutter)
    CLC_ClutterFormList.AddForm(fm)
    RETURN    ; - STOP -
ENDIF
;---------------------
    CLC_MiscFormList.AddForm(fm)        ; any other miscItem
ENDFUNCTION


  FormList PROPERTY CLC_HealthPotionFormList  auto
  FormList PROPERTY CLC_MagickaPotionFormList auto
  FormList PROPERTY CLC_StaminaPotionFormList auto
  FormList PROPERTY CLC_MiscPotionFormList    auto

;-----------------------------------------
FUNCTION myF_AddPotion2EffectList(Form fm)  ; internal helper
;-----------------------------------------
    magicEffect[] b = fm.GetMagicEffects()                            ; SKSE required !!!
    bool bOK

    IF b.Find(a[0]) || b.Find(a[1]) || b.Find(a[2]) || b.Find(a[3])
        CLC_HealthPotionFormList.AddForm(fm)
        bOK = TRUE
    ENDIF
    
    IF b.Find(a[4]) || b.Find(a[5]) || b.Find(a[6]) || b.Find(a[7])
        CLC_StaminaPotionFormList.AddForm(fm)
        bOK = TRUE
    ENDIF

    IF b.Find(a[8]) || b.Find(a[9]) || b.Find(a[10]) || b.Find(a[11])
        CLC_MagickaPotionFormList.AddForm(fm)
        bOK = TRUE
    ENDIF

    IF ( bOK )
    ELSE
        CLC_MiscPotionFormList.AddForm(fm)
    ENDIF
ENDFUNCTION

  MagicEffect[] PROPERTY a auto        ; fill by CK with next effects

;;;  MagicEffect PROPERTY AlchFortifyHealth      auto    ; a[0]
;;;  MagicEffect PROPERTY AlchFortifyHealRate    auto
;;;  MagicEffect PROPERTY AlchRestoreHealth      auto
;;;  MagicEffect PROPERTY AlchRestoreHealthAll   auto    ; a[3]

;;;  MagicEffect PROPERTY AlchFortifyStamina     auto    ; a[4]
;;;  MagicEffect PROPERTY AlchFortifyStaminaRate auto
;;;  MagicEffect PROPERTY AlchRestoreStamina     auto
;;;  MagicEffect PROPERTY AlchRestoreStaminaAll  auto    ; a[7]

;;;  MagicEffect PROPERTY AlchFortifyMagicka     auto    ; a[8]
;;;  MagicEffect PROPERTY AlchFortifyMagickaRate auto
;;;  MagicEffect PROPERTY AlchRestoreMagicka     auto
;;;  MagicEffect PROPERTY AlchRestoreMagickaAll  auto    ; a[11]

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

The script was not long, imho very poor structured. At this moment I do not know what are you really want to do here.

Nevertheless a bit rewritten for better understanding.. compiled not yet

 

Hey ReDragon,

 

1. I noticed you used Game.GetPlayer() in your script. That function is tied to the frame rates of the game so it can be quite slow. In most cases when it is used it is not noticeable.

 

This function gets you the player and is very fast.

 

Game.GetFormFromFile(0x00000014, "Skyrim.esm") As ObjectReference ; Player

 

https://www.creationkit.com/index.php?title=Category:Non-delayed_Native_Function

 

2. I noticed you used Utility.Wait(0.25) in your script. Using that in a menu can create some very bizarre behaviors. It is best to be avoided if you can. It will not fire in menu so any functions below it will not start until the chest is closed and the player is no longer in menu. It is used for this purpose if you must have your script start after the menu has closed. That may be why you are using it here.

 

There is a trick for working with chests and moving things around. You can BlockActivation() on the chest and then after the scripts have run you use this ( Activate(Game.GetPlayer(), true) ) to active the chest so all of the moved items show up in the menu or don't.

 

Your script is amazing and I hope these suggestions are helpful. It would take me a week to write a script like that.

Link to comment
Share on other sites

To anyone that might be interested...


1) If the "Game.GetPlayer()" will be call only once then there isn't too much of a problem.

If its is going to be call multiple times in the same script (slowing down the script execution), then you can call it once and then store it.


Example:

Event OnActivate(ObjectReference akActionRef)

If akActionRef == Game.GetPlayer()

Actor AC = akActionRef as Actor

AC.DamageActorValue(...)

AC.AddItem(...)

...

EndIf

EndEvent



2) There is an other workaround to this:

Self.setDestroyed(True)

And when it has finish doing its thing

Self.setDestroyed(False)


Objects that have the flag "setDestroyed(True)" cannot be interacted by the Player or anyone else, they appear normal ingame and they will not show the "E Activate" text when near it, setting it to "False" will revert the object to its normal state.

Edited by maxarturo
Link to comment
Share on other sites

 

To anyone that might be interested...
1) If the "Game.GetPlayer()" will be call only once then there isn't too much of a problem.
If its is going to be call multiple times in the same script (slowing down the script execution), then you can call it once and then store it.
Example:
Event OnActivate(ObjectReference akActionRef)
If akActionRef == Game.GetPlayer()
Actor AC = akActionRef as Actor
AC.DamageActorValue(...)
AC.AddItem(...)
...
EndIf
EndEvent
2) There is an other workaround to this:
Self.setDestroyed(True)
And when it has finish doing its thing
Self.setDestroyed(False)
Objects that have the flag "setDestroyed(True)" cannot be interacted by the Player or anyone else, they appear normal ingame and they will not show the "E Activate" text when near it, setting it to "False" will revert the object to its normal state.

 

 

 

That point 2 is interesting! I've been using perks to do that.

Link to comment
Share on other sites

Thank you for interrest and posting background infos.. "SurfsideNaturals"

 

1. Game.GetPlayer() vs. Game.GetForm()
Your approach (as follow) is not really thread safe. I had some strange CTD by using Game.GetForm(0x14).

 

; yours
    IF (akActionRef == Game.GetFormFromFile(0x00000014, "Skyrim.esm") As ObjectReference)
    ELSE
        RETURN    ; - STOP -
    ENDIF

;; same as
    IF (akActionRef == Game.GetForm(0x14) as ObjectReference)
    ELSE
        RETURN    ; - STOP -
    ENDIF

;; same as
    IF (Game.GetForm(0x14) == akActionRef as Form)
    ELSE
        RETURN    ; - STOP -
    ENDIF

;; same as
    IF (akActionRef.GetFormID() == 0x14)
    ELSE
        RETURN    ; - STOP -
    ENDIF

 


My first choice is next code, because it is absolutely thread safe.

    IF (akActionRef == Game.GetGetPlayer() as ObjectReference)
    ELSE
        RETURN    ; - STOP -
    ENDIF

or this

    IF (Game.GetGetPlayer() == akActionRef as Actor)
    ELSE
        RETURN    ; - STOP -
    ENDIF

2. OnClose()
The issue with OnClose() event is that it triggers only when the activated object finishes its closing animation.
But in fact most of the Skyrim containers do not have such animation so OnClose() won't never initiate here.
That is the reason why I am using OnActivate() event with Utility.Wait(0.25) in the script. It never fails.

---
maxarturo, if next is really working.. thank you for sharing this information :smile:
2) "There is an other workaround to this:"

    EVENT OnActivate(ObjectReference akActionRef)
        self.SetDestroyed(TRUE)
        
        Utility.Wait(0.25)            ; and when it has finish doing its thing

        self.SetDestroyed(False)
    ENDEVENT
Edited by ReDragon2013
Link to comment
Share on other sites

 

Thank you for interrest and posting background infos.. "SurfsideNaturals"

 

 

Hey ReDragon,

 

Game.GetForm() is known to be very buggy. We have never had any issues with Game.GetFormFromFile() and we run large array functions with it. Never any CTDs.

 

https://www.creationkit.com/index.php?title=GetFormFromFile_-_Game

 

If you are using it to get NPCs you need to make sure they are flagged persistent or loaded or the function will fail. basically any object ref that you would call a function on needs to be persistent or loaded.

 

Give it a try in some of your scripts and get back to us.

 

2. If you use utility.wait in a menu it will cause some events to fire more than once. If your functions must run on close you have to use it. We know of no other way.

Edited by SurfsideNaturals
Link to comment
Share on other sites

foamyesque & ReDragon2013

And of course anyone else interested in this.


I've been using "SetDestroyed()" to the death in my project, it's very reliable.

I have found only one bug with it, or more like a "malfunction".


Explanation of the issue:

- If the "Activator A" calls on itself

Event OnCellAttach()

Self.SetDestroyed(True)

.....

EndEvent


- And then "Activator B" calls on "Activator A"

Event SomeEvent()

Activator A.SetDestryed(False)

....

EndEvent


It will not work, the "SetDestroyed(True / False)" must be called by the same Object that called the "OnCellAttach()" event on itself.

Other than that, i haven't found any other issues with it.

Edited by maxarturo
Link to comment
Share on other sites

  • Recently Browsing   0 members

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