Difference between revisions of "Unplayable Items"
Clean up, new info., re-write/simplification
imported>Elder |
imported>GuidoBot (Clean up, new info., re-write/simplification) |
||
Line 1: | Line 1: | ||
UNPLAYABLE ITEMS - AKA TOKENS | ==<font size=4>'''UNPLAYABLE ITEMS - AKA TOKENS'''</font>== | ||
By [[User:GuidoBot|GuidoBot]] | |||
===Introduction=== | |||
Ok, so you've probably heard about tokens all over the forums by now and are wondering "what are they" or "what's all the fuss about". | |||
Well they are basically unplayable items that allow you to effectively re-program any actor or even the player. | |||
In fact, despite their modest name, tokens are perhaps the most powerful tool that scripters have in the unextended CS. Tokens themselves are really almost that - i.e. they are an object that exists just to get the attached script to run on a target. What is actually important is the 'token effect'. | |||
===Properties of unplayable items=== | |||
How unplayable items are actually intended to be used in the CS is unclear. They could be used to prevent the player taking items off of bodies but it is unclear whether any actors actually have such items in the standard game(?). Certainly a base object marked unplayable cannot be placed in game for the player (or actor) to pickup. | |||
The only real point of unplayable items is that they are not seen by the player, either in an actor's or player's inventory. Some other points about using an unplayable item on the player will be noted later. However, beyond this unplayable items behave pretty much like any other [non-persistant] item. | |||
From here on unplayable items will be referred to as tokens. Here's a list of important token properties with respect to scripting: | |||
# Tokens are always specific to the actor they are applied to, even if that actor was created by PlaceAtMe. In contrast, spells and abilities are added to the base model. (All [new] actor references of the same base model inherit these effects when they respawn.) | |||
# Local variables are persistant. Scripted spell effects and abilities reset when the actor comes into scope (same cell) as the player, meaning any local variables are re-instantiated (to 0). | |||
# You can add a token remotely - i.e. to an actor not even in your cell, so long as it is a persistant ref. | |||
# Token effect scripts are always active and the OnActivate block can be called when the actor is out-of-scope. This is not true of scripts on actors themselves. | |||
# When [the marked actor is] in scope the GameMode block activates every frame. When out of scope the GameMode block triggers about every 30 seconds (?). Additionally it will always fire when the token is first added - meaning that you have an effective OnAdd method. | |||
# Unlike standard items, the token is never seen in the target's/player's inventory. (This essentially makes up for the fact that inventory items cannot be disabled.) | |||
# Like spells, tokens can remove themselves or be removed from a calling script (very handy for instant or 1-time effects). | |||
===Creating an unplayable item=== | |||
# Choose any item in the game that has the Playable switch. These are essentially clothing and weapons. Most favored choice seems to be a 0-value ring. It is unclear whether actors can equip an unplayable item but if you use a ring it probably will not matter and making it worth 0 gold means they will not be inclinded to put it on. | |||
# Copy your choice by saving with a new unique ID. You probably want to use the actual name as a comment as to what the token effect will do, etc. | |||
# Uncheck the Playable option. | |||
# Attach/create your object script - your 'token effect'. | |||
===Adding a token to an actor=== | |||
To deploy a token on a target actor simply do the following command from any active script: | |||
actor.AddItem MyToken 1 | |||
===Token Script Example=== | |||
Here's a very useful example. This token effect allows a merchant to initially have one of a set of items in their inventory for sale the first time you visit. It is attached as the script to the token (you just made), called VendorToken. | |||
scn VendorTokenEffect | |||
scn | |||
ref target | ref target | ||
Line 51: | Line 57: | ||
; wait for player presence | ; wait for player presence | ||
if GetInSameCell player | if GetInSameCell player | ||
; add items (or spells) to inventory and remove effect | |||
set target to GetContainer | set target to GetContainer | ||
target.AddSpell | set type to 0.03*GetRanomdPercent | ||
target.AddSpell | if type == 0 | ||
target.AddSpell | target.AddSpell MyItem01 | ||
elseif type == 1 | |||
target.AddSpell MyItem02 | |||
else | |||
target.AddSpell MySpell01 | |||
endif | |||
RemoveMe | RemoveMe | ||
endif | endif | ||
Line 61: | Line 72: | ||
End | End | ||
To | To deploy this particular token effect I would suggest a quest script. There are other ways to do this but having a startup quest is a good idea for almost any mod involving scripting. Here is a skeleton start up quest script, attached to quest ID MyStartupQuest: | ||
scn MyStartupQuestScript | scn MyStartupQuestScript | ||
Line 76: | Line 87: | ||
; this is a real unique ref in the std game (must be persistant and unique) | ; this is a real unique ref in the std game (must be persistant and unique) | ||
<InGameVendor1>.AddItem | <InGameVendor1>.AddItem VendorToken 1 | ||
; another real unique ref to a second vendor | ; another real unique ref to a second vendor | ||
<InGameVendor2>.AddItem | <InGameVendor2>.AddItem VendorToken 1 | ||
End | End | ||
Ok so what have we done here? Basically we've added | Ok so what have we done here? Basically we've added items to a particular vendor (or vendors) without ever modding any of the vanilla world - not even an activator/sensor placed next to the vendor! You could use scripts that don't remove themselves the first time to do more complicated things, like maintain particular items in their inventory. | ||
===Tokens on the player=== | |||
(Very useful for OBSE key programming.) | |||
Firstly a couple of notes: | |||
# Adding a token directly to the player will produce message spam. | |||
# Equipping a token on the player will make it appear that the token is equipped and will unequip an item of the same type, even though the item will not show up rendered or in the player's inventory. This can be useful BUT it will produce the usual item-equipped message spam. | |||
To give a player a token without causing any messages it is necessary to first add this to a container. (See '''Discussion'''.) However, since you cant be sure one exist it is best to use your own persistant actor, or shadow (see [[Remote Activators]]). | |||
scn ImporterScript | |||
; This is a token script to get a token on the player! | |||
; Called by simply doing MyShadow.AddItem ImporterToken 1 | |||
short frame | |||
Begin GameMode | |||
if frame == 1 | |||
; 2nd frame - hide shadow and destroy command token | |||
MyShadow.Disable | |||
RemoveMe | |||
endif | |||
; 1st frame - give stuff to shadow | |||
MyShadow.Enable | |||
MyShadow.AddItem MyToken 1 | |||
MyShadow.MoveTo player 0 0 -5000 | |||
set frame to 1 | |||
End | |||
This is a 1-time token script to add a token to the player using a shadow [actor]. The key thing here is that the shadow (hidden container) has to be in the player cell before you can get scripted items to remove themselves (silently) to the player. The first part of the token script would be: | |||
Begin GameMode | |||
if GetContainer == MyShadow | |||
RemoveMe player | |||
Return | |||
endif | |||
; actual token script goes below... | |||
End | |||
You can also use the shadow to bring in 3D items to the game. In this case the '''Activate''' command would be used in place of the '''AddItem''' command (see [[Remote Activators]]). The important thing with these extended effects to watch for is ''timing''. In this case the commands that have to be handled carefully are MoveTo and RemoveMe. | |||
Token Abuse | ===Token Abuse=== | ||
Because tokens are always active make sure you dont add them repeatedly or to almost very NPC you meet (in-game). Sometimes using a spell, ability or other method to get your active script going is more appropriate. | |||
Token Origin: I wish I could say I invented tokens but I didn't. It appears they started out in thread discussions and were eventually put to use by early adopters such as Scruggs. Through thread discussions, I have only helped solidify our understanding of how and when to use them. | ===Comments=== | ||
'''Token Origin''': I wish I could say I invented tokens but I didn't. It appears they started out in thread discussions and were eventually put to use by early adopters such as Scruggs. Through thread discussions, I have only helped solidify our understanding of how and when to use them. | |||
[[User: JOG|JOG]] may have released the first tokens ever in his proofs-of-concept, [[User:JOG#The_Generous Giant_of_Tamriel|The Generous Giant of Tamriel]] and [[User:JOG#Dagger_Mould|Dagger Mould]]. | [[User: JOG|JOG]] may have released the first tokens ever in his proofs-of-concept, [[User:JOG#The_Generous Giant_of_Tamriel|The Generous Giant of Tamriel]] and [[User:JOG#Dagger_Mould|Dagger Mould]]. |