On this page 13 sections
- Words used on this page
- Inventory
- blse.inventory
- blse.item_added, blse.item_removed
- blse.item_equipped, blse.item_unequipped
- Item information and changing items
- blse.item_info
- blse.item_classes, blse.item_files, blse.item_loaded
- blse.set_item
- blse.reset_item
- New items and weapons
- blse.add_item_class
- blse.item_class_template, blse.added_item_classes
This page is about items: knowing what the player and NPCs carry and when that changes, reading an item's data (name, price, weight), changing it for a session, and adding new items and weapons to the game. Come here for a shop mod, a loot mod, a mod that reacts when the player picks something up, or a new weapon.
Giving, removing, counting, dropping, equipping and moving items are on the world page: Spawning, teleporting and inventories.
A minimal working example: tell the player when they pick up a blood pack, and show its price.
import blse
def on_added(topic, data):
owner_class, owner_name, item_class, item_name = data.split('\0')
if owner_class == 'player' and item_class == 'item_g_bloodpack':
info = blse.item_info(item_class)
if info:
blse.show_text('A blood pack (worth $%d)' % info[3], 'top')
blse.subscribe('blse.item_added', on_added)Important, before you start:
- The inventory events and
blse.inventory()need a recognized game build (blse.build_id()is notNone). - Item data is loaded when the game first needs it (a level's items, a merchant's goods when the trade screen opens). Before that,
item_classes()does not list an item, butitem_info()reads it from its file, andset_itemremembers your change until it loads. - Changes made with
set_itemare not saved: they last for this session. Set them again at startup. - A save holding an item a mod added cannot be loaded without that mod (the game crashes). See New items and weapons.
Words used on this page#
| Word | Meaning |
|---|---|
| Item class, classname | The kind of an item, such as item_g_bloodpack (a blood pack) or item_w_thirtyeight (a revolver). By convention item_w_ are weapons, item_g_ general items, item_a_ armour |
| Item file | vdata/items/<classname>.txt, the game's data for one item: names, prices, models, damage |
| Owner | The character or container holding an item |
| Equip | Take an item in hand (a weapon). Unequip: put it away |
| Template | An existing item class whose behaviour a new class copies |
| Merchant, vendor | A character the player trades with; their stock is in vdata/system/vendors.txt |
| Merge file | A file in a mod folder that adds to a game data file instead of replacing it (see mod folders) |
Inventory#
On recognized game builds (b0.5.12):
| Function / topic | |
|---|---|
blse.inventory([name]) |
List of the item classnames the player carries (or the first character with that targetname; other entities with the same name, such as a cop's car, are skipped), in slot order, e.g. ['item_w_fists', 'item_w_tire_iron', ..., 'item_g_wallet']. Raises ValueError if there is no such character or no level is running |
blse.item_added, blse.item_removed |
owner_class, owner_name, item_class, item_name = data.split('\0'): an item entered or left a character's inventory (picked up, given, bought, sold, used up, removed by a script) |
blse.item_equipped, blse.item_unequipped |
Same fields: a weapon or other item was taken in hand or put away. A weapon switch gives item_unequipped (old) then item_equipped (new) |
Delivered at the end of the frame, for the player (owner_class == 'player') and NPCs. Nothing is reported while a level loads or shuts down (the game then restores the player's items after a load or a level transition and hands out NPCs' gear). The game's own HasItem, GiveItem and RemoveItem remain the way to check and change items.
blse.inventory#
blse.inventory([name]) # -> ['item_w_fists', ...](b0.5.12) The item classnames a character carries, in the order of its inventory slots.
name: a character's targetname; left out (or''): the player. The first character with that name is used; other entities with the same name (a cop's car) are skipped.- Returns a list of strings.
- Errors:
ValueErrorif there is no such character or no level is running;RuntimeErroron a game build where inventories are not available.
if 'item_w_tire_iron' in blse.inventory():
blse.log('the player has a tire iron')For counting stacks (how many blood packs), use blse.item_count.
blse.item_added, blse.item_removed#
An item entered or left a character's inventory: picked up, given, bought, sold, used up, removed by a script. Fields: owner_class, owner_name, item_class, item_name = data.split('\0'): the owner's classname ('player' for the player) and name, the item's classname and name. Sent for the player and NPCs, at the end of the frame; not while a level loads or shuts down.
When to use them: a pickup message, a quest that waits for an item, a weight limit of your own.
blse.item_equipped, blse.item_unequipped#
The same fields: an item was taken in hand or put away. A weapon switch sends item_unequipped (the old one) then item_equipped (the new one).
def on_equip(topic, data):
owner_class, owner_name, item_class, item_name = data.split('\0')
if owner_class == 'player' and item_class.startswith('item_w_'):
blse.log('weapon in hand: ' + item_class)
blse.subscribe('blse.item_equipped', on_equip)Item information and changing items#
blse.item_files() (b0.5.35) lists every item there is a file for, loaded or not, and blse.item_info() also answers for items the game has not loaded, read from their file (vdata/items/<class>.txt) the way the game reads it. Files whose names a class cannot have (copies such as item_a_body_armor - hunter.txt) are left out.
blse.item_loaded (b0.5.34): the game loaded an item's data (payload: the classname). Items are read when first needed: a level's, a merchant's goods when the trade screen opens. Items loaded before are listed by blse.item_classes(), so a mod that changes every item calls item_classes() once and then handles item_loaded.
| Function | |
|---|---|
blse.set_item(classname, field, value) |
Changes an item for the rest of the session (not saved): 'name' (up to 127 characters), 'description', 'price' (buying), 'sell_price', 'weight', and a weapon's ammunition: 'ammo_name', 'ammo_description', 'ammo_price' (ammunition is not an item of its own: it is part of the weapon's data). value is a string or a whole number (0..1000000000). Returns 1, or 0 if the game has not loaded the item yet: it gets the value when the game loads it (merchants' goods load when their screen opens). A script can call it in its first lines: BLSE finds the game's items a moment after scripts run, so it returns 0 then and the change is applied as soon as it does. ValueError for an unknown field or a bad value. Both of the game's copies are changed: the server's and the client's, which the barter screen prices from (shown prices still include the game's haggling adjustment) |
blse.reset_item(classname) |
The game's own values again for every field changed from Python; 1, or 0 if none. A Python restart resets them too |
blse.item_info(classname) returns (name, description, type, price, sell_price, weight, flags, model) from the game's item data (vdata/items), or None; blse.item_classes() lists the items the game has loaded so far (items are loaded as levels and inventories need them). For example item_w_thirtyeight gives ('Colt Police Positive Special', "This 'Thirty-Eight' is ...", 'weapon_firearm', 70, 15, 3, 0, 'models/weapons/ThirtyEight/info/i_ThirtyEight.mdl').
blse.item_info#
blse.item_info(classname) # -> tuple or NoneAn item's data, from the game's records or, for an item the game has not loaded, from its file (b0.5.35). Returns None for an unknown class.
| Position | Field | Meaning |
|---|---|---|
| 0 | name |
The name the game shows (may be a # translation key) |
| 1 | description |
The description text |
| 2 | type |
The item type: 'weapon_firearm', 'armor', ... |
| 3 | price |
What it costs to buy |
| 4 | sell_price |
What a merchant pays for it |
| 5 | weight |
Its weight |
| 6 | flags |
The item's flags number |
| 7 | model |
Its inventory model |
name, desc, kind, price, sell, weight, flags, model = blse.item_info('item_g_bloodpack')blse.item_classes, blse.item_files, blse.item_loaded#
blse.item_classes() # -> ['item_g_bloodpack', ...] loaded so far
blse.item_files() # -> every item with a file, loaded or not (b0.5.35)item_classes() lists the items the game has loaded so far; item_files() every item there is a file for. The event blse.item_loaded (b0.5.34) sends a classname whenever the game loads an item's data. A mod that changes every item calls item_classes() once and then handles item_loaded:
def cheaper(classname):
info = blse.item_info(classname)
if info and info[3] > 0:
blse.set_item(classname, 'price', info[3] / 2)
for c in blse.item_classes():
cheaper(c)
blse.subscribe('blse.item_loaded', lambda topic, data: cheaper(data))blse.set_item#
blse.set_item(classname, field, value) # -> 1 or 0Changes one field of an item for the rest of the session (not saved). When to use it: a shop mod with its own prices, a mod that renames or rebalances items.
field:'name'(up to 127 characters),'description'(up to 8191),'price','sell_price','weight', or a weapon's ammunition'ammo_name','ammo_description','ammo_price'.value: a string or a whole number; numbers 0 to 1000000000.- Returns 1 if changed now, 0 if the item is not loaded yet: it gets the value when the game loads it.
- Errors:
ValueErrorfor an unknown field, a bad value (another type, too long, out of range), or when items are not available on this game build. - Both of the game's copies are changed (the server's, and the client's that the barter screen prices from). Shown prices still include the game's haggling adjustment.
blse.reset_item#
blse.reset_item(classname) # -> 1 or 0The game's own values again for every field changed from Python on that item. Returns 1, or 0 if Python changed none. A Python restart resets them too.
New items and weapons#
(b0.5.49) A mod can add items beside the game's own, without replacing any. No code is needed: Start here walks through a new sword, step by step, from the item file to a merchant selling it.
Important: a save that holds an item a mod added cannot be loaded without that mod (the game crashes). Tell players to keep the mod while they play a game they started with it. Details under Limits below.
Each of the game's items is a class in vampire.dll; BLSE lets a mod name a new class that behaves like one of them (the template) and reads its own data from vdata/items/<new class>.txt:
| From the template (its C++ class) | From the new item's file |
|---|---|
| What kind of item it is and what its code does: a melee weapon, a gun with a magazine, a thrown weapon, what using a blood pack does, a key | Names, description, prices, weight, stacking, item type and flags; the view, world, wielded and inventory models; animation prefix, camera class and sounds; each attack's damage, rate, range, spread, recoil and crosshairs; the magazine (ammunition names, prices, size, reload); HUD and inventory pictures |
So a new sword can be a katana with its own model, damage and sounds, and a new gun a Glock with its own model, magazine and stats. A completely new behavior (a new projectile, a new fire mode) is not data: a native plugin can hook the template's functions and check the classname (see the plugin reference).
| Function | |
|---|---|
blse.add_item_class(classname, template) |
classname (item_<name>, 6-63 characters of a-z 0-9 _) becomes an item class the game can create everywhere it creates items: maps, the console's give, GiveItem, merchants' stock, blse.spawn_entity, blse.give_item, loading saves. 1, or 0 if not available on this game build. ValueError with the reason if refused: a bad name, a class the game has already (new classes only), a template BLSE cannot copy. The same class again: the later registration wins (logged). Registrations last until the next Python start (scripts run again then) |
blse.item_class_template(classname) |
The template of an added class, or None |
blse.added_item_classes() |
[(classname, template, who, created), ...]; who is 'python', 'mod <folder>' or a plugin's name; created: entities made this session |
The console command item_classes lists them too.
blse.add_item_class#
blse.add_item_class(classname, template) # -> 1 or 0Makes a new item class that behaves like template and reads its data from vdata/items/<classname>.txt (b0.5.49).
classname:item_<name>, 6-63 characters ofa-z 0-9 _, not a class the game already has.template: one of the game's item classes that can be templates (see Templates below), or a class added before.- Returns 1, or 0 if new item classes are not available on this game build.
- Errors:
ValueErrorwith the reason if refused (a bad name, an existing game class, a template BLSE cannot copy). - Call it in your script's first lines (scripts run before any save loads). Registrations last until the next Python start; the script registers again when it runs again.
blse.add_item_class('item_w_mymod_sword', 'item_w_katana')blse.item_class_template, blse.added_item_classes#
blse.item_class_template(classname) # -> 'item_w_katana' or None
blse.added_item_classes() # -> [(classname, template, who, created), ...]item_class_template returns the template of a class added with add_item_class (or blse/items.txt), None for others. added_item_classes lists every added class: who is 'python', 'mod <folder>' or a plugin's name; created how many entities of it were made this session.
Without code: a mod folder's blse/items.txt, read at startup in load order, one class per line: <new class> <template>; # or // start a comment.
# my_mod/blse/items.txt
item_w_mymod_sword item_w_katana
item_w_mymod_pistol item_w_glock_17cand the item files beside it, as the game's own (copy the template's file and change it):
my_mod/vdata/items/item_w_mymod_sword.txt
my_mod/models/weapons/mymod_sword/... (models, if the item has its own)
my_mod/materials/... (textures and inventory pictures)
my_mod/sound/...Merchants: their stock is vdata/system/vendors.txt; a mod adds an item with a merge file (blse/merge/vdata/system/vendors.txt, see mod folders):
VendorData
{
Vendor
{
"@match" "Name=Mercurio"
+VendorItem { "Name" "item_w_mymod_sword" "InternalName" "item_w_mymod_sword" "AmmoOnly" "0" "MinStage" "0" }
}
}"@match" "Name=Mercurio" picks the merchant (the game's vendors.txt has one Vendor block per merchant, by Name), and +VendorItem adds an entry to his list. In the entry, Name and InternalName are the item's class; AmmoOnly 1 sells only ammunition for a gun instead of the gun; MinStage is the point in the story from which the item is sold (0: from the start; the game's own entries use higher numbers for later items).
Templates: 184 of the game's 202 item classes, those whose create function has the common form. Not usable as templates: the containers (item_container, item_container_animated, item_container_lock, item_container_one_item_filtered), item_g_keyring, item_g_astrolite, item_p_occult_regen, item_i_written, item_d_holy_light, item_w_remington_m_700 (use item_w_steyr_aug for a rifle with a scope), item_w_unarmed, item_w_flamethrower, item_w_torch and the boss weapons item_w_chang_energy_ball, item_w_chang_ghost, item_w_mingxiao_melee, item_w_mingxiao_tentacle, item_w_tzimisce_melee. An added class can be named as a template, also one registered later (another line or mod): its own template is used.
Limits:
- Saves need the mod. A save holding a mod's item loads only while the class is registered. With the mod (or BLSE) removed, the game itself crashes loading that save: it creates each saved entity by its classname and does not check for a failure (vampire.dll 0x101a2ec5). Register in
blse/items.txtor a script, which run before any save loads. A class in a mod'sblse/items.txtstays registered even if a script registers it again and later fails (the script's template is used while it runs). - The game's code that checks for one item by name (a quest asking for
item_w_katana, special cases in a few weapons) does not see a new class as that item. - The item file must exist: a registered class whose
vdata/items/<class>.txtis missing is not created (logged once). A save holding such an item crashes the game on load, as for a missing mod. - Keep a class's template once saves hold its items: a save stores the item's fields as its template's class has them.