Tes3Mod:AddItem

AddItem
 
 

Use
Adds a given number of items to the callers inventory. The most common use is in dialogue to handle rewards or quest items. It is often used together with RemoveItem to simulate giving something from one actor to another. However, AddItem will always create new items in the given inventory. Keep that in mind when dealing with items that run scripts of their own.

AddItem is not limited by the encumbrance value of a container.

AddItem can not be used on objects that have no reference in the game. Accessing disabled references is no problem.

The implementation of the inventory feature is poor, politely put. There are so many traps to avoid, that the bugs section would be longer than the real explanation. For this reason most of the bugs, traps, and problems are included in the main text.

Caller
Player, Actors, Containers

This function can be called by any actor or container from a script or dialog result. The behavior of the function changes significantly depending on the type of the caller, the time of the call, and sometimes the number of objects present in the game. The scripting language does not provide any means to determine any of these conditions; however, the use on actors in a dialog is generally safe.

At this point we need to remember the two types of uses of functions like AddItem:
  refers to the object 'some object' defined in the CS and can be used anywhere in scripting.
  can only be used in a script attached to 'some object' or in a dialog. Other than the first version it refers to the calling reference.
Read the following section to learn how these function calls not necessarily do what you expect.

How Inventories Work
Every actor and container has in fact two inventories:
The object inventory
:this list is defined in the CS and holds all the items the actors or containers will contain at the beginning. It should be noted, that leveled items are only evaluated coming from THIS list.
The reference inventory
:this is an individual list for actors or containers that keeps track of the changes in the inventory during the game. Containers only get this second inventory list, if the player changes the content, other than just taking everything. Actors get it, when they are loaded for the first time. For all practical purposes the player's inventory works like this.

Containers
Container objects go through three states, which show a different behavior for the AddItem function:
# the container is newly loaded, the player has not changed the content, but he may open the container. When the player leaves the cell and returns later, the container will be newly loaded again. Every call of AddItem, RemoveItem or GetItemCount at this point will refer to the object inventory. Changes will affect every reference of the same container in the game.
# the player opened the container and took everything before closing it. Now the container is marked empty. Any call of AddItem, RemoveItem or GetItemCount at this point will still refer to the object inventory. Changes will affect every reference of the same container in the game, but THIS container will appear empty to the player.
# the player changed the content of a container. He did not take everything at once, or he put something new into it. Now the container gets his individual reference inventory. If the container has a script attached that calls AddItem on itself, the item is added only to this container. A container at state 3 stays that way, even if the player empties it again. Exception: Organic containers that respawn are reset to state 1.

Example 1:
:You have two containers   and you call from a script  
:* If you have not touched the containers, both will contain 100 gold.
:* Any container you have emptied will still be empty.
:* If you have changed a container (state 3), it will contain 100 gold.

Example 2:
:You have two containers   in the same cell with a script attached. This script looks for some game progress and then calls   on itself.
:* If you have not touched the containers, both will contain 200 gold. (Both added 100 gold to the object inventory.)
:* Any container you have emptied will still be empty. If you emptied one and did not touch the second, that one will hold 200 gold. (Both added 100 gold to the object inventory.)
:* If you changed both (state 3) both will hold 100 gold. (they only add to themselves)
:* If you changed one (state 3) the changed one holds 200 gold, the unchanged 100. (the changed container adds gold only to itself, the unchanged adds gold to everyone.
:* If the containers are in different cells, the outcome would be different, as their scripts would run at different times - but you get the picture.

Actors
Actors show a different behavior than containers and they have only two states.
# the actor has never been loaded. Local scripts would not be executed yet, therefore AddItem can only be called in the form  , which would affect the object inventory.
# after an actor has been loaded, it has an individual inventory. Any call of AddItem from the reference - in a dialog or local script - will work as expected and add the item(s) to this reference. This is also true for dead actors.

However, the form   works in a strange way:
If the actor   is unique, a call of   will add the item(s) to that actors inventory.
If the actor   is NOT unique, a call of   will add the item(s) to the object inventory, so the new item will only be given to all references of   that have not been loaded yet.

Examples:
 : if Bob Smith is a unique NPC (as he should be), he now has 100 gold.
 : only imperial archers that have not been loaded yet will have those 100 silver arrows.


The Player
The player's inventory works as expected.

ObjectID
Every portable item defined in CS, Leveled Items

Normal items can be added to any actor or container.

Leveled items can be added to any actor or container, but they may not work as expected. They are only evaluated, if added to the object inventory. Added to the player, or a container in state 3, or an actor that has already been loaded, they appear as some strange and unusable icon.

Items that are created by the player like self-made potions or self enchanted items or filled soul gems can not be handled by AddItem. The same is true for health or number of usages. AddItem will only add items as defined in CS.

Count
short value

In scripts the function only accepts literal values for count. Global variables (not local!) are accepted in dialog result fields, provided their value has been set before the dialog entry is displayed.

The use of the count value requires special care. The actual parameter is a short value (-32768 to 32767). The maximum number of items that can be added with one function call is therefore 32767, but the function will accept any numerical value and wrap. A value of 32768 is really -32768, 65356 is 0, and so on.

AddItem will accept negative values for count, but not 0.

Calling AddItem with a negative value will actually add a positive amount of items to a container or actor, and those items become restockable, if the actor is a merchant. Do not add a negative amount of items to the players inventory! It will mess up the encumbrance value.

Summary
The use of AddItem on the player with normal items and positive numbers is not a problem.
Adding items to any actor from a local script (on the actor) or a dialog works as expected.
If an actor is unique, an AddItem call from other scripts will work as expected.
If you feel the need to add something to an existing container, you are out of luck, if the player has already emptied that container. There is no way to check for this. Find some other way to give the item to the player.
You should not use leveled items unless you know exactly what you are doing.

Notes
The encumbrance value is changed during the execution of AddItem, RemoveItem, when buying or selling, or when you pick up or drop items. This is only done once by adding or subtracting the weight of the items that are handled. If that gets messed up, the encumbrance value will be broken.
The maximum value of 32767 seems to be enough for normal items, but one could think of situations, where you want to add more (gold comes to mind). Split it up into several AddItem calls or write a separate script to deal with this. Buying or selling or picking up or dropping items does not have that limitation.
NPCs will always wear the best clothes and armor they have. If you add better clothes or armor (depending on the armor skills of the NPC) the NPC will wear these. This is also true if you add the better item with a negative count value. If the NPC is a merchant and you want him to sell the stuff, add it to a hidden chest he owns.
If you add a negative amount of leveled items to a merchants container, the randomness is calculated only once. Restocking will always add the same items.
Remember that the combination of RemoveItem and AddItem is the only way in scripting and dialog to transfer items between inventories. If an item has a script attached, this script will be started new for the new item and any data in local variables will be lost. The same is true for individual data like health, number of usage, magical charge. Buying or selling or the normal process of picking up or dropping an item do not have that problem.

Bugs
Calling AddItem with a count of 0 will create an error at runtime. Since scripts only accept literals this is only a problem, if you add items in a dialog using a global variable. Make sure the variable is not 0.
Using a variable for count in a script may even compile, but will result in a runtime error.
Adding a negative amount of items to the players inventory is bad. The player will receive a positive number of items, but the weight is subtracted. Bad, bad, bad... (Makes a nice encumbrance cheat, though...)
Not a Bug, but could lead to one in your mod: leveled items are only calculated before the player manipulates the content a container. Therefore you should add leveled item only to containers that have not been touched by the player. Otherwise the container will hold some unusable item with the name of your leveled list.

Related Functions
RemoveItem, GetItemCount (normal item handling)
AddSoulGem (adding filled soul gems)
Activate (pick up items)
OnActivate, OnPCAdd (react to the process of acquiring an item)