Tes4Mod:Cobl/Modding/Inventory Tracking

Background
COBL's Inventory Tracking provides an easy way for modders to monitor changes in the player's inventory, essentially creating OnPickup/Drop Item''''' type blocks. This is currently used by the Keychain mod to move any keys the player picks up to the keychain (a remote container). It could also be used to automatically determine whether the loot the player just picked up is worth keeping or should be trashed, automatically equip better armour, or continuously supply arrows as the player runs out.

Requirements
The player will need   (>= v.0012) and   (>= v56) to use the Inventory Tracker.

Specifics
The Inventory Tracker scans the player's inventory every 2 seconds. If the contents have changed since the last scan, the change (item's base reference, count, etc.) is marked on the appropriate list. There are, currently, 5 lists that can be broken down into 2 categories:
Gains
Increased items - Player has more of these items since the last scan. Marks the items' base references and changes in count.
Added items - Items that the player didn't have in the last scan. Marks the items' base references.
New items - Items that the player has never had before (based on BaseID). Marks the items' base references.
Loses
Decreased items - Player has fewer of these items since the last scan. Marks the items' base references and changes in count.
Removed items - Player has lost the entire stack of these items. Marks the items' base references.
Example
The player has 5 Iron Arrows, 1 Iron Cuirass, and 50 Gold. Inventory tracking is initialized, makes the first scan, and the lists are updated:
 Increased - 5 Iron Arrows, 1 Iron Cuirass, 50 Gold
 Added - Iron Arrows, Iron Cuirass, Gold
 New - Iron Arrows, Iron Cuirass, Gold

The player doesn't do anything for the next 2 seconds, IT makes the second scan, and updates the lists:
 No changes

The player picks up 20 Gold, 1 Leather Cuirass, drops the Iron Cuirass and 2 Iron Arrows, IT makes the third scan and updates the lists:
 Increased - 20 Gold, 1 Leather Cuirass
 Added - Leather Cuirass
 New - Leather Cuirass
 Decreased - 2 Iron Arrows, 1 Iron Cuirass
 Added - Iron Cuirass

Finally, the player picks up the Iron Cuirass again, IT makes the fourth scan and updates the lists:
 Increased - 1 Iron Cuirass
 Added - Iron Cuirass

Taking requests
If you'd like the Inventory Tracking to do something else, post it in this section and I'll see what I can do.
Eat/Drink list
A list of ingredients and potions that the player has eaten or drunk. As of now, the Remove list is indiscriminate about how the item was removed and all of the various methods (via script, dropping the item, selling the item, or eating the item, etc.) are treated the same way.

As of now, I'm thinking this would be a single list and you'd need to use IsFood, IsIngredient, and IsAlchemyItem to determine whether it's food or drink.

Quick Guide
Initialize the system
 
 Write down an EditorID from your mod - anything except Globals will work
 
 
 Create this quest script (replace the ---s with the name of your quest)
  
 
 
 
 
 
   
Using the lists
I suggest using a quest as it will run all the time. You can use an object, but to be safe make sure it's always running (use the "Set" trick - set a variable on itself in GameMode and MenuMode).

 
 
 
 Create this script: (where you see ---s, replace them with the appropriate name of the list - New, Add, Remove, Inc, or Dec)
 scn YourQuestScript

float fQuestDelayTime
long  ScanNumber
long  iChange
ref   rItem

begin GameMode
	set fQuestDelayTime to 1.5
	if (cobInvTracker.iScan != ScanNumber)
		set iChange to 0
		Label
		if (iChange   
 

Example from Keychain
Initialization script
 
Keychain script (The tracking is split across this and the following Hooking script)
 
Hooking script
 scn P1DkeyHookScript

long  UseIT ;Use the inventory tracker
long  iInv
ref   rItem
long  KeyCount
long  StopSpam ;Used to stop message spam as the keys are taken from the player

begin onActivate
	set iInv to 0
	set StopSpam to 1
	Label
	if UseIT
		if (iInv  

Advanced
Pluggy
Pluggy is fairly unique, and I would suggest you read the   and keep the   available as you read this.
Initializing the system
Use the script as in the Quick Guide. Here's a description of the various parts and options:
Registration System
Inventory Tracking uses a registration system so it can shut itself down if the player de-activates your mod. Before you activate the Initializer, make sure to set its rInUse variable to a reference from your mod. The reference can be anything new in your mod: base object of an item, specific reference of an object or item that your mod places in the world, a quest, etc. (A specific example that ''won't'' work - if you edit a vanilla item, i.e., reduce the weight of a Silver Shortsword, the item is still from "Oblivion.esm" and won't work. If you make a new Silver Shortsword base object, that will work.)
Running in Combat
By default, Inventory Tracking will stop while the player is in combat. If you need to track items in combat (i.e., lost arrows) then set the RunInCombat variable to 1 before activating the Initializer.
Version Number
cobInvTrackingInit can be thought of as a version number. Use the following guide to determine which version you need.


Some Background info
Variables
All of the variables that you'll be using are on the quest "cobInvTracker". They're on the script "cobInvTrackerQS" under the ";Global" section. You will need to refer to them as any other external quest variable and prefix the variable with "cobInvTracker.".
When does it run?
Inventory Tracking runs during most of GameMode and MenuMode. It won't run while the player is in combat (unless it's been set to run during combat) and won't run during the Options menus or Messageboxes.
Using the lists
Scan Index (cobInvTracker.iScan)
The scan index is changed after every new scan. Note that it's changed, not necessarily increased. So the check should be
 
If this is on a quest, you can set "fQuestTimeDelay" to 1 or 1.5.
You should also add a special part to the top of the MenuMode block to make sure it won't run during the Main Menu
 
List Updates
After every scan a "Changes" variable is updated for each list (AddChanges, RemoveChanges, etc.). This is the number of changes that occurred for each list. For the examples above

Scan 1


Scan 2


Scan 3


Scan 1

This number is very important! The arrays will not be "shrunk" after each scan. For instance, on the second scan (inventory doesn't change) the lists actually look like the first:
 Increased - 5 Iron Arrows, 1 Iron Cuirass, 50 Gold
 Added - Iron Arrows, Iron Cuirass, Gold
 New - Iron Arrows, Iron Cuirass, Gold
However, the Changes variables will all be 0 so you should know that the lists should be ignored.

Use a check, such as
 if (iInv < cobInvTracker.AddChanges)
to make sure you don't use information from old scans.

The lists
The lists themselves are arrays. For instance, on the first scan they will look like this

Increased List


Added List


New List

Use the function GetInArray to retrieve the information.