Skyrim
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 1.7.3 (with new function to get by SKSE FormType, and functions 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 by Quad2Core, and found here.

The original plugin was written for SKSE 1.7.0, and some of the internal SKSE classes have changed slightly between then and the current 1.7.3.  This meant that, sadly, the original plugin would no longer work with the latest SKSE.

The good news is that Q2C included a source file, so I was able to update the relevant sections and get it working again.  The bad news is that I was unable to get in touch with the original author to either submit my changes, or offer to host an updated version (I sent a message, but it looks like they have been absent from the Nexus since late 2015).

However, the original file did give permission for the plugin to be re-used.  After much thought, I contacted a Nexus admin, and asked if it would be considered acceptable for me to host this updated version.  They agreed, and so here is the updated version, free for people to use.

I should point out that the source file on the original page was only the v1 of the plugin, so didn't include any of the more exciting newer functions (for poisoning). With a bit of experimenting, I've figured out how to recreate those, and they're available in v3.02.  I've also added a few new functions of my own along the way - here's what is currently in the script:




Container Inventory Functions



; Q2C's original functions, updated for SKSE 1.7.3
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)




Poison Functions



; Q2C's original poison functions, updated for SKSE 1.7.3
; Note a slight change in format: 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


NOTE - Important Changes in v3!!

As of v3, the Spell-related functions in here will now 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, the default behaviour of ActorGetSpells and ActorBaseGetSpells have changed, and will now return a full list of Spells if you call them with no specific criteria (this makes a lot more sense to me, and was how I wanted to do it originally, but the Abilities were getting in the way).


; 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: as of v3, sending just the akActor (or sending all additional arguments as their default values) will now return ALL spells the Actor knows - rather than an empty list as before
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: as of v3, sending just the akActorBase (or sending all additional arguments as their default values) will now return ALL spells set on the ActorBase - rather than an empty list as before
}


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: as of v3, sending just the akActor (or sending all additional arguments as their default values) will now return TRUE - rather than FALSE as before
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: as of v3, sending just the akActorBase (or sending all additional arguments as their default values) will now return TRUE - rather than FALSE as before
}


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



; Additional, now-DEPRECATED Spell and Keyword Functions
; These are now deprecated, and may be REMOVED in future versions.
; Please switch to using the generic equivalents above (which is all these fuctions do now -
; just call the generic version with correct arguments, and pass back the result)


bool Function ActorHasSpellSchool(Actor akActor, string asSchool, bool abSearchBase)
{
OBSOLETE - now just a pass-through to the main ActorHasSpell, with relevant default vals
}


bool Function ActorBaseHasSpellSchool(ActorBase akActorBase, string asSchool)
{
OBSOLETE - now just a pass-through to the main ActorBaseHasSpell, with relevant default vals
}



bool Function ActorHasSpellKeyword(Actor akActor, Keyword akKeyword, bool abSearchBase)
{
OBSOLETE - now just a pass-through to the main ActorHasSpell, with relevant default vals
}


bool Function ActorBaseHasSpellKeyword(ActorBase akActorBase, Keyword akKeyword)
{
OBSOLETE - now just a pass-through to the main ActorBaseHasSpell, with relevant default vals
}




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 this 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! :)