Skyrim Special Edition
0 of 0

File information

Last updated

Original upload

Created by

Quad2Core originally - updated and extended by Kalivore

Uploaded by

Kalivore

Virus scan

Safe to use

About this mod

Inventory Functions plugin for SKSE to allow filtering of inventory by Keyword.Originally by Quad2Core, now updated for SKSE-64 (including functions supporting Poisoning, and for getting filtered lists of spells/shouts an actor has)

Requirements
Permissions and credits
Changelogs
This is an update of the excellent 'Inventory Functions' SKSE plugin, originally written by Quad2Core for 32-bit Skyrim, and found here.

AE Compatible
Works on newest AE build (SKSE 2.2.6 for AE build 1.6.1170)
MIGHT work on GOG version 1.6.1170 too - and there's also a version that should work with GOG 1.6.659 on the Files page..

I'm not intending to do releases for AE builds before 1.6.640, btw;
there are just far too many old versions for me to go through and force-update my Skyrim folder to!




I first updated this for the final 32-bit SKSE (thankfully Q2C included a source file, and also gave permission for the plugin to be re-used - I contacted a Nexus admin, and they confirmed it would be considered acceptable for me to host the updated version). With the (alpha) release of SKSE64, I've updated and recompiled this again, and on the assumption the original permission still holds, am hosting it here for 64-bit users.

Here's what is currently in the script:



Container Inventory Functions



; Q2C's original functions, updated for SKSE64
int Function  GetNumItemsWithKeyword(ObjectReference akObjRef, Keyword akKeyword)
Form Function GetNthFormWithKeyword(ObjectReference akObjRef, Keyword akKeyword, int aiItemIndex)

; added by Kalivore - type is the SKSE itemType (eg 26 for armour, or 46 for potion)
; full list at http://www.creationkit.com/index.php?title=GetType_-_Form

int Function  GetNumItemsOfType(ObjectReference akObjRef, int aiType)
Form Function GetNthFormOfType(ObjectReference akObjRef, int aiType, int aiItemIndex)

; get total of the base gold values of items in container
; 'base' means the extra value of enchantments/improvements on items is ignored

int Function  GetTotalBaseGoldValue(ObjectReference akObjRef)




Poison Functions



; Q2C's original poison functions, updated for SKSE64
; Note a slight change in format from Q2C's original 32-bit plugin:
; Worn_PoisonWeapon has become WornObjectSetPoison,
; Worn_GetPoison has become WornObjectGetPoisonCharges etc

; Valid Hand Slot:
; 0 - Left
; 1 - Right


; this is already done by SKSE, so just forward on to that version
Potion Function WornObjectGetPoison(Actor akActor, int aiHandSlot, int aiSlotMask)

int Function WornObjectSetPoison(Actor akActor, int aiHandSlot, int aiSlotMask, Potion akPoison, int aiCharges = 1)
{
Applies akPoison to weapon in aiHandSlot. Note the item MUST be a weapon, or the function will fail and return -1
Returns: The number of poison charges the weapon now has (which should be the same as aiCharges)
or -1 if unsuccessful
}


Function WornObjectRemovePoison(Actor akActor, int aiHandSlot, int aiSlotMask)
{
Remove the poison from the weapon in aiHandSlot
}


int Function WornObjectGetPoisonCharges(Actor akActor, int aiHandSlot, int aiSlotMask)
{
Get the number of poison charges on the weapon in aiHandSlot
Returns: The number of charges, or -1 if unsuccessful for any reason
(eg the item is not a weapon, or no poison applied)
}


int FunctionWornObjectSetPoisonCharges(Actor akActor, int aiHandSlot, int aiSlotMask, int aiCharges = 1)
{
Set the number of poison charges on the weapon in aiHandSlot
Returns: The number of poison charges now on the weapon in aiHandSlot (which should be the same as aiCharges)
or -1 if unsuccessful for any reason (eg the item is not a weapon, or no poison applied)
}


; this is already done by SKSE, so just forward on to that version
Potion Function GetPoison(ObjectReference akObjRef)

int Function SetPoison(ObjectReference akObjRef, Potion akPoison, int aiCharges = 1)
{
Applies akPoison to akObjRef. Note the item MUST be a weapon, or the function will fail and return -1
Returns: The number of poison charges the weapon now has (which should be the same as aiCharges)
or -1 if unsuccessful
}


Function RemovePoison(ObjectReference akObjRef)
{
Remove the poison from the weapon akObjRef
}


int Function GetPoisonCharges(ObjectReference akObjRef)
{
Get the number of poison charges on akObjRef
Returns: The number of charges, or -1 if unsuccessful for any reason
(eg the item is not a weapon, or no poison applied)
}


int FunctionSetPoisonCharges(ObjectReference akObjRef, int aiCharges = 1)
{
Set the number of poison charges on akObjRef
Returns: The number of poison charges now on the weapon in aiHandSlot (which should be the same as aiCharges)
or -1 if unsuccessful for any reason (eg the item is not a weapon, or no poison applied)
}



; These are all just shortcuts to the full WornObject versions above, sending aiSlotMask as 0
Potion FunctionWornGetPoison(Actor akActor, int aiHandSlot)
int Function WornSetPoison(Actor akActor, int aiHandSlot, Potion poison, int aiCharges = 1)
FunctionWornRemovePoison(Actor akActor, int aiHandSlot)
int Function WornGetPoisonCharges(Actor akActor, int aiHandSlot)
int Function WornSetPoisonCharges(Actor akActor, int aiHandSlot, int aiCharges = 1)





Ammo Functions



; OK, not really specifically to do with Inventories, but I needed these for another mod of mine and they don't exist in current SKSE
Function SetIsBolt(Ammo akAmmo, bool abIsBolt)
{
Sets whether this ammo is a bolt
}


Function SetProjectile(Ammo akAmmo, Projectile akProjectile)
{
Sets the projectile associated with this ammo
--WARNING!!-- Highly untested! >:$
}


Function SetDamage(Ammo akAmmo, float afDamage)
{
Sets the base damage of this ammo
}





Spell inventory Functions


The Spell-related functions in here will only list explicit Spells (ie items which have a Spell Type of "Spell" in the Creation Kit).  This means they will ignore magic marked as Abilities, like those added by Perks.
(Many thanks to user irswat for helping me to investigate and realise the difference between these).  As a result, if you call them with no specific criteria, these will return a full list of Spells.


; Some spell-related Constants for use with these functions (all Global, so you can call them as _Q2C_Functions.SpellSchoolAny() )

; Valid spell School values
string Function SpellSchoolAny()
{returns an empty string ""}
string Function SpellSchoolAlteration()
{returns "Alteration"}
string Function SpellSchoolConjuration()
{returns "Conjuration"}
string Function SpellSchoolDestruction()
{returns "Destruction"}
string Function SpellSchoolIllusion()
{returns "Illusion"}
string Function SpellSchoolRestoration()
{returns "Restoration"}

; useful preset spell Level values
int Function SpellLevelAny()
{returns -1}
int Function SpellLevelNovice()
{returns 0 (all Novice spells I found were level 0)}
int Function SpellLevelApprentice()
{returns 25}
int Function SpellLevelAdept()
{returns 50}
int Function SpellLevelExpert()
{returns 75}
int Function SpellLevelMaster()
{returns 100}

; Valid Level Comparison values (only applied if aiLevel >= 0):
int Function SpellLevelComparisonLt()
{returns -2. Means spell level must be lower than specified aiLevel to be counted}
int Function SpellLevelComparisonLtEq()
{returns -1. Means spell level must be less than or equal to specified aiLevel to be counted}
int Function SpellLevelComparisonEq()
{returns 0. Means spell level must be equal to specified aiLevel to be counted}
int Function SpellLevelComparisonGtEq()
{returns 1. Means spell level must be equal to or greater than specified aiLevel to be counted}
int Function SpellLevelComparisonGt()
{returns 2. Means spell level must be greater than specified aiLevel to be counted}



Spell[] Function ActorGetSpells(Actor akActor, Keyword akKeyword = None, string asSchool = "", int aiLevel = -1, int aiLevelComparison = 1, bool abSearchBase = true)
{
Scans the MagicEffects of the Actor's spells, adding the Spell to the returned array if the MagicEffect matches the criteria.
Use the default values to ignore that condition (eg sending asSchool as "" means 'of any School')
NOTE: sending just the akActor (or sending all additional arguments as their default values) will return ALL spells the Actor knows
Optionally will also check through the relevant ActorBase (which is more likely to be the one with the spells)
}


Spell[] Function ActorBaseGetSpells(ActorBase akActorBase, Keyword akKeyword = None, string asSchool = "", int aiLevel = -1, int aiLevelComparison = 1)
{
Scans the MagicEffects of the Actor's spells, adding the Spell to the returned array if the MagicEffect matches the criteria.
Use the default values to ignore that condition (eg sending asSchool as "" means 'of any School')
NOTE: sending just the akActorBase (or sending all additional arguments as their default values) will return ALL spells set on the ActorBase
}


Shout[] Function ActorBaseGetShouts(ActorBase akActorBase, Keyword akKeyword = None)
{
Returns an array of Shouts that match the specified Keyword.
}



; Additional spell-checking Functions
; These are included for convenience. They use the same criteria as the spell-listing functions above
; (and actually, all they do is just call the corresponding function, and return true if the resulting array has at least one entry)


bool Function ActorHasSpell(Actor akActor, Keyword akKeyword = None, string asSchool = "", int aiLevel = -1, int aiLevelComparison = 1, bool abSearchBase = true)
{
Scans the MagicEffects of the Actor's spells, returning true at the first one that matches any of the supplied criteria.
NOTE: sending just the akActor (or sending all additional arguments as their default values) will return TRUE if the actor has any spell at all
Optionally will also check through the relevant ActorBase (which is more likely to be the one with the spells)
}


bool Function ActorBaseHasSpell(ActorBase akActorBase, Keyword akKeyword = None, string asSchool = "", int aiLevel = -1, int aiLevelComparison = 1)
{
Scans the MagicEffects of the ActorBase's spells, returning true at the first one that matches any of the supplied criteria.
NOTE: sending just the akActorBase (or sending all additional arguments as their default values) will return TRUE if the ActorBase has any spell at all
}


bool Function ActorBaseHasShout(ActorBase akActorBase, Keyword akKeyword)
{
Scans the ActorBase's shouts, returning true at the first one that matches the specified Keyword.
}




A Note about checking Spell Levels

If you supply a Level argument to the functions (eg 25 for Apprentice-level spells), the plugin will only check the FIRST Magic Effect on each spell for this. Additionally, if testing for level 0 (Novice), the Magic Effect must have a School assigned to it to be counted.

Explanation:
Spoiler:  
Show

This is because spells can have many Effects assigned to them. The additional effects are usually enabled by perks: eg the Intense Flames effect on the Adept-level Fireball spell. Since you need the Perk to unlock it, the Intense Flames effect actually has a level of 0 - which would cause trouble if you were looking for "spells of Apprentice level or less", and you got the Fireball spell back because its second effect is level 0.

Furthermore (and regrettably), the vanilla game actually assigns Novice spells (eg Flames) a level of 0 - which is the default level, and used by a lot of 'maintenance effect'-type spells (ie, the sort of Magic Effect you apply with a Cloak spell to nearby NPCs). Thankfully, these effects are also unlikely to have a Magic School assigned to them, so by testing the the effect does have a school, it means we should only get 'proper' spells returned by the functions.



Some example code for usage - the first function is taken directly from the original mod page:


import _Q2C_Functions

ObjectReference Property PlayerRef Auto
Keyword Property VendorItemPotion Auto

Function ReWeightPotions()
  int PotionIndex = GetNumItemsWithKeyword(PlayerRef, VendorItemPotion)
  While(PotionIndex > 0)
    PotionIndex -= 1
    Form potion = GetNthFormWithKeyword(PlayerRef, VendorItemPotion, PotionIndex)
    potion.SetWeight(0.0)
  endWhile
endFunction



Actor Property SomeEnemy Auto
Keyword Property MagicDamageFire Auto

Function CheckEnemyHasFireSpell()
  ; just send the Keyword argument, and leave all others at default
  bool hasFire = ActorHasSpell(SomeEnemy, MagicDamageFire)
  if (hasFire)
    Debug.Trace("The enemy has at least one Fire spell")
  else
    Debug.Trace("Well at least they won't set us on fire...")
  endIf
endFunction



Actor Property SomeAlly Auto

Function CheckAllyHasRestorationSpell()
  ; set Keyword argument to None (meaning 'don't match Keywords'), specify the School, and leave all others at default
  bool hasRestorationSpell = ActorHasSpell(SomeAlly, None, "Restoration")
  if (hasRestorationSpell)
    Debug.Trace("Restoration IS a perfectly valid school of magic")
  else
    Debug.Trace("Guess our ally won't be doing any healing...")
  endIf
endFunction



Actor Property PlayerRef Auto

Function ListPlayerSpells()
  ; just send the Actor argument, and leave all others at defaults, to get a full list of spells the actor knows
  Spell[] actorAllSpells = ActorGetSpells(PlayerRef)
  int spellIndex = 0
  Report("Player has " + actorAllSpells.Length + " spells of any sort")
  while (spellIndex < actorAllSpells.Length)
    Spell currentSpell = actorAllSpells[spellIndex]
    Debug.Trace("Spell " + spellIndex + ": " + currentSpell.GetName())
    spellIndex += 1
  endWhile
endFunction



I am just the updater of the original work - all credit for the original functions (and my inspiration) is due to Quad2Core.

As per their original wishes:
Feel free to package this plugin with your own mods and use it for your own projects.
Please just mention me (ie Quad2Core) in a footnote somewhere.

All Credits are going to the SKSE Team!


I hope other people can find as much excellent use for these as I have!  Oh - and go give Quad2Core some kudos! :)


Source code here, btw (cos I hadn't noticed I'd left the link out!!): https://github.com/kalivore/inventory-functions-se