# Throne of Bhaal Extender (TobEx)

Modder Reference

Introduction

Main: Engine · Debugging · Lua · Ruleset

Scripting: Triggers · Actions · Scripting Stats

Audio · Animations and Graphics · Effects · Items · Spells · Stores

## Introduction

This document is intended to be a modmaker's reference that answers the question: "What can TobEx allow me to do as a modder?". It is not intended for players. It is not intended to answer the question: "How can I change the game with TobEx to do X?" This document is purely descriptive, and contains little to no information about how to achieve a certain modding goal.

This document is intended to be used in conjunction with the Infinity Engine Structures Description Project and with ./TobEx_redist/TobEx_ini.txt. Please refer to each of these resources accordingly.

Technically, TobEx functions conceptually by applying a group of hacks to the engine. This is achieved by loading a DLL at game startup. The DLL contains code that modifies the virtual image of the game executable BGMain.exe by:

- directly changing hex code (patch), and
- replacing and/or extending existing game functions (hook).

Hacks may be exclusively patch, exclusively hook, or a combination of both. To enable easier troubleshooting, all hacks can be enabled/disabled by .ini files. Additionally, TobEx allows users to specify their own custom patches in the TobEx_ini/patch directory. Usage of this feature can be learnt from the template.patch file found in that directory.

Overall, TobEx divides hacks into core hacks and tweak hacks. Core hacks are enabled/disabled in TobEx_ini/TobExCore.ini, while tweak hacks are enabled/disabled in TobEx_ini/TobExTweak.ini. In general, modders should not allow players to configure core hacks. Modders and players can configure core debugging hacks manually for their own debugging purposes. In contrast, modders can include components in their modifications that allow players to configure tweak hacks. The standalone package of TobEx allows some, but not all, of these tweak hacks to be configured. In this document, any behaviours that are not enabled by a default installation of the TobEx redistributable package or the core component of the TobEx standalone package are described using the keyword option.

In the .ini files, TobEx hacks are grouped by type. To browse each hack by type, refer to ./TobEx_redist/TobEx_ini.txt. This document groups the features of TobEx differently to allow easier navigation. If any more information is sought beyond these resources, modders can discuss their questions at the TobEx forum.

## Engine

The following core engine changes are discussed:

- Arenas Game Type
- Attacking
- Auto-pause
- Bard Song
- Casting Graphics and Sounds
- Creatures Moving Between Areas
- Dead Static Animations
- Dialogue Bar
- Difficulty
- Effect Saving Throws
- Effect Stacking Behaviour
- Fake Talk Exploit
- Gaining Experience
- Inventory Screen Pausing
- Item Recharge in Bags and Stores
- Kit Support
- Launcher Fixes
- Music Song List
- Player 1 Death
- Race Selection Strings
- Random Treasure
- Rest Spawns
- Spell Turning
- Starting Experience
- Summon Limit Bug
- Talking to Charmed Creatures
- Variables

### Arenas Game Type

The arenas game type is a deathmatch multiplayer game type disabled by BioWare in the release version of Throne of Bhaal. TobEx reactivates this game type, with all its features and bugs. Here is a summary of the game type:

- Games are called scenarios and are loaded as saved games from the ./arenas directory
- Pausing the game is not allowed
- The game does not end when Player1 dies
- LOCALSKickedOut is not set on death
- Only inventory slot items are dropped on death
- The DeathmatchPosition() actions set the DEATHMATCH_RESURRECT<PLAYERNUM> variable
- When the action DeathmatchPosition() is used, a player who dies will immediately Raise Dead and LeaveAreaLua() to the position set by DeathmatchPosition(), with a random orientation
- Gold is not shared by the party but is kept by the player
- Opposing players' health is not shown overhead and tooltips reveal approximate health
- No locator feedback is displayed when opposing players are damaged
- Opposing players' visibility maps are not displayed
- Party effects do not affected opposing players, hostile non-party effects affect opposing players
- Chunk death is disabled
- The default action when clicking on the portrait of an opposing player is to attack when in visibility range, and to move to opposing player when outside visibility range
- Record screen information on opposing players is not accessible

The limitations of the game type are:

- Multiplayer permissions cannot be set correctly when setting up the game
- The host can reform party, kicking out other players
- The party can rest, all party members will heal, and the party cannot rest when the party is scattered (including opposing players)
- Any player can modify the party position of all party members
- Dialogue can be made to pause the game
- One can see the opposing player's kit description
- When outside visibility range, clicking on an opposing player's portrait allows the player to locate their opponents
- Summoned creatures turn enemy when hit by opposing players

### Attacking

TobEx makes the following changes to the standard attack action:

- With X/2 attacks, the attack that occurs once every two rounds now always occurs every two rounds (rather than a random probability of the attack taking place every single round)
- With 3/2 attacks, the attack that occurs once every two rounds now always uses the offhand if an offhand weapon is present (rather than the offhand never being used)

Option: TobEx gives the option of making all attack animations genuine statistical attacks.

### Auto-pause

Option: TobEx gives the option of allowing auto-pause to work on any screen in single player. The behavior mimics that of multiplayer. The original behaviour is that auto-pause only works in the main game screen when in single player.

### Bard Song

TobEx externalises the standard Bard Song effects to bardsong.spl. This allows modders to customise the standard set of Bard Song effects.

### Casting Graphics and Sounds

Normally, female gender uses a female casting sound, other and niether gender use an unvoiced casting sound, and all other genders use a male casting sound. This caused problems with spells like Project Image where illusory female creatures used male casting sounds.

TobEx fixes this bug by modifying the way that the gender of casting sound selection is handled. Specifically, male gender uses a male casting sound, while all other genders check the Sex field (0x237) in the CRE file format. If the Sex field is male (1), a male casting sound is used. If the Sex field is female (2), a female casting sound is used. For any other value in the Sex field, an unvoiced casting sound is used. In order to do this, TobEx also ensures that the Sex field is correctly set during character generation, and patches some characters and creatures (a la BG2 Fixpack) so that their Sex field is correct.

TobEx also fixes a bug where the Mental Speed stat is not considered when determining whether to play a casting sound at all, whether to play a gendered or unvoiced casting sound, and whether to play a casting animation.

### Creatures Moving Between Areas

TobEx fixes a bug whereby creatures moving between areas can get multiple copies saved in the area file in a saved game. This bug was fixed in the Throne of Bhaal 26499 BETA patch, and the fix is re-created by TobEx.

TobEx also fixes a bug where creatures chasing targets through an area transition can be cloned because the creature was not removed from the previous area.

### Dead Static Animations

TobEx fixes a bug where dead static animations are still valid scripting targets. Normally, this causes bugs where a creature in berserk amongst dead static animations will permanently remain in berserk, breaking game transitions.

### Dialogue Bar

TobEx greatly expands the amount of text that can display in the dialogue bar before old text is lost. The number of rows supported is 32767.

### Difficulty

TobEx allows modmakers to modify the damage percentage modifier for each difficulty level by extenalising the values to DIFFMOD.2DA.

DIFFMOD.2DA
DAMAGE_MOD: The percentage to add to base damage
LUCK_MOD: The amount to add to luck of party members
[ROWNAME]: Difficulty level based on DIFFLEV.IDS

### Effect Saving Throws

TobEx makes the following changes to effect saving throws:

- If an effect has multiple saving throw types (e.g. all five), then the best saving throw of the target is used. However, as saving throw types are checked in order, better subsequent saving throw types are all checked, which can create an internal consistency when flagging which saving throw type is used. TobEx fixes this issue. The issue may not have any impact in-game.
- If a target of an effect does not save versus any type, but modifiers result in a successful save (i.e. effect save bonus, save bonus versus same mage school type, and specific save bonus versus object type), then a successful save is not reported in the dialogue bar.
- TobEx fixes an issue where targets with improved invisibility do not get a +4 saving throw bonus against effects from creatures that cannot see invisible.

### Effect Stacking Behaviour

TobEx allows modmakers to configure when effects can stack. This is achieved by implementing bit 25 (Limit Effect Stacking) of the EFF V2.0 Header offset 0x0040 (Save Type), ITM V1.0 Feature Block offset 0x0024 (Save Type), and SPL V1.0 Feature Block offset 0x0024 (Save Type).

When set, TobEx checks EFF V2.0 Header offset 0x0048 (Special), ITM V1.0 Feature Block offset 0x002c (Special), and SPL V1.0 Feature Block offset 0x002c (Special) for a unique stacking ID. If two effects of the same opcode are applied, both have Limit Effect Stacking Set, and both have the same stacking ID, then the latter applied effect is suspended in application until the former effect expires. Regardless of whether it is applied, the latter effect will expire at the same time that it would expire if it was applied. In other words, the total duration of some non-stacking effect opcode is not extended because more than one copy of the effect was applied.

Stacking IDs are unique to the opcode being applied. To maintain uniqueness of stacking IDs between different mods, one recommendation is to use the higher word of Special as the modder's Infinity Engine Community Prefix, then use the lower word as an identifying ID. For example, 0x41360001 ('A6' 0x0001).

TobEx also implements bit 26 (Internal: Suspend Effect Application) of the EFF V2.0 Header offset 0x0040 (Save Type), ITM V1.0 Feature Block offset 0x0024 (Save Type), and SPL V1.0 Feature Block offset 0x0024 (Save Type) to prevent effects with limited stacking from being applied.

### Fake Talk Exploit

TobEx fixes an exploit where players could intend to initiate dialogue with a neutral creature, cancel their action, and then perform a hostile action instead, resulting in the creature wasting up to 10 seconds doing nothing before becoming hostile.

### Gaining Experience

Option: Normally, Throne of Bhaal gives the party 110% of the experience actually coded into creatures and given by the AddExperienceParty() action opcode. However, the amount coded into creatures (100%) is reported in the dialogue bar. TobEx gives the option of fixing this issue and giving the party the coded amount of experience (100%) in these situations.

### Inventory Screen Pausing

Option: TobEx gives the option of disabling a forced game pause when the inventory screen is opened in single player. The behavior mimics that of multiplayer.

### Kit Support

Normally, Throne of Bhaal limits the total number of kits available to 256 before overflow occurs. TobEx expands this limit to 1280. Additionally, TobEx enables scrolling of the kit selection menu, such that each class is no longer limited to 10 kits.

### Item Recharge in Bags and Stores

TobEx fixes an exploit where players could instantly restore the charges of rechargeable items by putting them in a bag and then taking them out again.

From the technical perspective, TobEx modifies usages for non-stackable items with charges such that:

- Items in a store with usages of 0 are no longer loaded with usages of 1
- Putting items in bags no longer recharges the items, unless bit 14 of STO V1.0 Header offset 0x10 (Flags) is set, see below.
- TobEx adds functionality to bit 14 (Toggle Recharge) of STO V1.0 Header offset 0x10 (Flags). For bags, setting this bit will allow items to be recharged when placed in the bag. For stores, setting this bit will prevent items from recharging when sold to the store.
- The buy and sell prices of items that recharge now take into account the fact that they recharge.

### Launchers with No Ammo

TobEx fixes an exploit where launcher weapons grant the damage and strength bonuses of non-launcher (4)-type abilities. This corrects the issue with non-ammo-requiring launcher weapons (using ranged (2) ability) granting extra damage when ammo is equipped. If this is enabled, damage bonuses of launcher abilities are only given for the first launcher (4)-type ability of the launcher weapon.

TobEx also fixes an engine bug where no penalties were applied for having no proficiency points in bows, crossbows, and slings.

### Music Song List

TobEx removes the 100-row limit on SONGLIST.2DA. The script action PlaySong() supports this change, and extended song numbers are recognised in ARE files.

### Player 1 Death

Option: TobEx enables modmakers to disable the game over cutscene when the protagonist dies. In order for the game to be over, modmakers must specify a condition where the new action opcode LoseGame() applies without fail. Also refer to the LoseGame() action opcode section.

### Race Selection Strings

TobEx externalises hard-coded string references in the character generation race selection screen to RACETEXT.2DA. This allows modmakers to translate or modify these strings to other text.

### Random Treasure

TobEx extends the limit of rows in all the random treasure 2DA files from 10 to 99.

### Rest Spawns

Option: TobEx gives the option of advancing a random time up to, but not including, eight hours if resting is interrupted by spawns. All resting times of one hour or greater will display in the dialogue bar. Resting times less than one hour will not display in the dialogue bar.

### Spell Turning

TobEx fixes a bug where on occasions, certain creatures with spell turning absorb spells rather than bouncing them back to the original caster.

### Starting Experience

Option: TobEx gives the option for modmakers to modify the starting experience of Shadows of Amn and Throne of Bhaal.

TobEx allows setting the starting experience to zero without causing problems with character generation. This can be useful for partial and total conversions.

### Summon Limit Bug

TobEx fixes a bug where the number of summons may increment permanently because those not existing in an area remain in the saved game. This bug was fixed in the Throne of Bhaal 26499 BETA patch, and the fix is re-created by TobEx.

### Talking to Charmed Creatures

Option: TobEx gives the option of allowing the player to talk to charmed or dominated creatures and preventing charmed and dominated creatures from losing their soundset.

### Variables

TobEx optimises the code used for setting and finding variables. The variable map hash function uses the djb2 algorithm.

## Debugging

The debugging features of TobEx include:

- A console that logs a variety of internal and TobEx-specific text
- Expansion of the Lua console to enhance real-time debugging. See the Lua section for more details.
- Message boxes of assertion failures will always show when they occur
- Internal logging text, including assertion failures, assertion warnings, network errors, and other internal messages, can be displayed in the TobEx console and logged to TobEx.log
- For assertion failures, TobEx reports a debugging address that is displayed in the console and logged to TobEx.log
- Provision of some information about assertion failures and warnings that previously had no specific message explaining what the problem was
- The dialogue bar can be logged to TobEx_dlg.log
- Missing resources can be logged to TobEx.log
- The function of the 'Restore Extra Combat Info Text' baldur.ini option has been restored

Note that a number of TobEx debugging features are not automatically enabled, and therefore need to be enabled manually by modifying ./TobEx_ini/TobExCore.ini after installation of TobEx. For the greatest amount of debugging information, set all the hacks in the [Debug] section of ./TobEx_ini/TobExCore.ini to 1. Refer to TobEx_redist/TobEx_ini.txt for specific information about each hack.

## Lua

Baldur's Gate II: Throne of Bhaal uses Lua 3.0 in a limited fashion to facilitate debugging. For an introduction to Lua 3.0 and lua programming syntax, read Chapter 4 of the Lua manual. For a brief description of the CLUAConsole commands, refer to the Infinity Engine Structures Description Project website.

TobEx makes changes to the following CLUAConsole functions:

- StartStore(ResRef): TobEx fixes the crash associated with using this function, which starts the store named by ResRef with Player1 as the customer.

TobEx expands on the use of Lua 3.0 for in-game debugging purposes and provides capabilities for modders and users to extend Lua debugging functions. Preset Lua functions imported into Baldur's Gate II: Throne of Bhaal are those described only in Chapter 6.1 of the Lua Reference Manual. New user-defined functions can be defined by extending TobEx_ini/TobEx.lua or included .lua files. TobEx defines the following new functions:

### Global functions (defined internally in C)

- band
- bor
- createobject
- dec2hex
- hex2dec
- getsprite
- mod
- pow
- pushfunction
- pushuserdata
- u2n

### TobExObject tag methods (defined internally in C)

- cdecl
- getaddress
- getbyte
- getdword
- getlist
- getpointer
- getstring
- getword
- print
- stdcall

### Global functions (defined externally in Lua)

- area_getcurrent
- area_listsprites
- creature_getstat
- creature_liststates
- creature_listtriggers
- creature_listactions
- creature_listtriggerobjects
- creature_listscripts
- dump
- dump_table
- p
- sprite_getcurrent
- sprite_gettype

#### area_getcurrent()

- Type: Lua function (area.lua)
- Scope: Global
- Parameters: None
- Returns: TobExObject (type "area")
- Behaviour: Creates a TobExObject referencing the current area.

#### area_listsprites(are)

- Type: Lua function (area.lua)
- Scope: Global
- Parameters: are - TobExObject (type "area")
- Returns: None
- Behaviour: Dumps text of all the sprites in the current area into the dialogue window.

#### band(x,y)

- Type: C function
- Scope: Global
- Parameters: x,y - number of hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Performs a bitwise AND (x & y) operation. There is no operator synonym for this function.

#### bor(x,y)

- Type: C function
- Scope: Global
- Parameters: x,y - number of hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Performs a bitwise OR (x | y) operation. There is no operator synonym for this function.

#### cdecl(f, [args...])

- Type: C function
- Scope: TobExObject tag method
- Parameters: f - cfunction; args... (optional) - any type
- Returns: Number
- Behaviour: Pushes 'args...' onto the C stack, and calls 'f' using the cdecl calling convention. Arguments of type Lua function and table are ignored, and arguments of nil or non-existent arguments terminate the argument list. The TobExObject is placed into the ecx register as per thiscall. The return value in the eax register is pushed onto the Lua stack as a number.

#### createobject(u, [type])

- Type: C function
- Scope: Global
- Parameters: u - userdata; type (optional) - string
- Returns: TobExObject
- Behaviour: Creates a TobExObject referencing userdata of type "notype" or 'type' (if explicitly specified). A TobExObject is a global Lua table set to tag "TobExObject" containing the fields "type"->string and "userdata"->userdata. TobExObjects have access to all functions under the TobExObject tag method scope.

#### creature_getstat(cre, n)

- Type: Lua function (creature.lua)
- Scope: Global
- Parameters: cre - TobExObject (type "creature"); n - number
- Returns: Number
- Behaviour: Gets the value of stat number 'n' of the creature.

#### creature_listactions(cre)

- Type: Lua function (creature.lua)
- Scope: Global
- Parameters: cre - TobExObject (type "creature")
- Returns: None
- Behaviour: Dumps text of all the actions of the creature into the dialogue window.

#### creature_listscripts(cre)

- Type: Lua function (creature.lua)
- Scope: Global
- Parameters: cre - TobExObject (type "creature")
- Returns: None
- Behaviour: Dumps text of the script ResRefs assigned to the creature, and the current script-block-response currently running, into the dialogue window.

#### creature_liststates(cre)

- Type: Lua function (creature.lua)
- Scope: Global
- Parameters: cre - TobExObject (type "creature")
- Returns: None
- Behaviour: Dumps text of all the states that apply to the creature into the dialogue window.

#### creature_listtriggerobjects(_cre)

- Type: Lua function (creature.lua)
- Scope: Global
- Parameters: cre - TobExObject (type "creature")
- Returns: None
- Behaviour: Dumps text of all the trigger objects of the creature into the dialogue window.

#### creature_listtriggers(cre)

- Type: Lua function (creature.lua)
- Scope: Global
- Parameters: cre - TobExObject (type "creature")
- Returns: None
- Behaviour: Dumps text of all the triggers of the creature into the dialogue window.

#### dec2hex(n)

- Type: C function
- Scope: Global
- Parameters: n - number
- Returns: String
- Behaviour: Converts a decimal number into a hexadecimal string beginning with "0x".

#### dump()

- Type: C function
- Scope: Global
- Parameters: None
- Returns: None
- Behaviour: Dumps text of all Lua global variables into the dialogue window.

#### dump_table(t, name)

- Type: C function
- Scope: Global
- Parameters: t - table; name - string
- Returns: None
- Behaviour: Dumps text of a Lua table into the dialogue window. 'name' is displayed as a prefix to every line of the dump.

#### getaddress(address)

- Type: C function
- Scope: TobExObject tag method
- Parameters: address - number or hexadecimal string (beginning with "0x")
- Returns: Userdata
- Behaviour: Gets 'address' relative to the TobExObject reference address.

#### getbyte(address)

- Type: C function
- Scope: TobExObject tag method
- Parameters: address - number or hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Gets the byte (8-bit) value at 'address' relative to the TobExObject reference address.

#### getdword(address)

- Type: C function
- Scope: TobExObject tag method
- Parameters: address - number or hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Gets the dword (32-bit) value at 'address' relative to the TobExObject reference address.

#### getlist(address)

- Type: C function
- Scope: TobExObject tag method
- Parameters: address - number or hexadecimal string (beginning with "0x")
- Returns: Table
- Behaviour: Pushes a table derived from the CPtrList object at 'address' relative to the TobExObject reference address. The index of each table element is the index from the head of a MFC CList object {0,1,2,...}, and the value is its corresponding value.

#### getpointer(address)

- Type: C function
- Scope: TobExObject tag method
- Parameters: address - number or hexadecimal string (beginning with "0x")
- Returns: Userdata
- Behaviour: Gets the value (pointer) at 'address' relative to the TobExObject reference address.

#### getsprite(enum|scriptname)

- Type: C function
- Scope: Global
- Parameters: enum - number or hexadecimal string (beginning with "0x"); scriptname - string
- Returns: Userdata
- Behaviour: Gets a reference to a game sprite by by enum (instance index) or scriptname as type userdata.

#### getstring(address, [length])

- Type: C function
- Scope: TobExObject tag method
- Parameters: address - number or hexadecimal string (beginning with "0x"); length (optional) - number
- Returns: String
- Behaviour: Gets the string (terminating at the first nul character, or of specified length 'length') at 'address' relative to the TobExObject reference address.

#### getword(address)

- Type: C function
- Scope: TobExObject tag method
- Parameters: address - number or hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Gets the word (16-bit) value at 'address' relative to the TobExObject reference address.

#### hex2dec(string)

- Type: C function
- Scope: Global
- Parameters: string - hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Converts a hexadecimal string to a decimal number.

#### mod(x,y)

- Type: C function
- Scope: Global
- Parameters: x,y - number of hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Performs a mod (x mod y) operation.

#### p(text)

- Type: C function
- Scope: Global
- Parameters: text - any type
- Returns: None
- Behaviour: Prints 'text' to the dialogue window. Synonym for CLUAConsole::DisplayText(tostring(text)).

#### pow(x, y)

- Type: C function
- Scope: Global
- Parameters: x,y - number of hexadecimal string (beginning with "0x")
- Returns: Number
- Behaviour: Performs a pow (x ^ y) operation. Operator ^ can be used as a synonym for this function (defined in TobEx.lua).

#### print([to_console])

- Type: C function
- Scope: TobExObject tag method
- Parameters: to_console - boolean
- Returns: String (only when to_console == false)
- Behaviour: Dumps hard-coded type-based information about the TobExObject into a string. If to_console is true, the text is placed into the dialogue window.

#### pushfunction(n)

- Type: C function
- Scope: Global
- Parameters: n - number of hexadecimal string (beginning with "0x")
- Returns: CFunction
- Behaviour: Converts a number to a cfunction.

#### pushuserdata(n)

- Type: C function
- Scope: Global
- Parameters: n - number of hexadecimal string (beginning with "0x")
- Returns: Userdata
- Behaviour: Converts a number to userdata with tag 0.

#### sprite_getcurrent()

- Type: Lua function (sprite.lua)
- Scope: Global
- Parameters: None
- Returns: TobExObject (type variable)
- Behaviour: Creates a TobExObject of the sprite highlighted by the game cursor. The TobExObject type is preset using sprite_gettype().

#### sprite_gettype(obj)

- Type: Lua function (sprite.lua)
- Scope: Global
- Parameters: obj - TobExObject
- Returns: String
- Behaviour: Gets the specific type of the TobExObject as a string.

#### stdcall(f, [args...])

- Type: C function
- Scope: TobExObject tag method
- Parameters: f - cfunction; args... (optional) - any type
- Returns: Number
- Behaviour: Pushes 'args...' onto the C stack and calls 'f' using the stdcall/thiscall calling convention. Arguments of type Lua function and table are ignored, and arguments of nil or non-existent arguments terminate the argument list. The TobExObject is placed into the ecx register as per thiscall. If too many or too few arguments are supplied for the function, the stack pointer is corrected. The return value in the eax register is pushed onto the Lua stack as a number.

#### u2n(u)

- Type: C function
- Scope: Global
- Parameters: u - userdata
- Returns: Number
- Behaviour: Converts a userdata to number.

## Ruleset

The following ruleset changes are discussed:

- Assassin and Bounty Hunter Kits
- Backstabbing
- Casting Spells When Silenced
- Class-Race Restrictions
- Contingency/Trigger/Sequencer and Select Spell
- Critical Hits
- Dual Classing
- Equipping Armor in Combat
- High Level Abilities (HLAs)
- Hit Point Tables
- Item Restrictions
- Mage Spells
- Magical Weapons
- Mirror Images
- Pickpocketing
- Priest Spells
- Proficiencies
- Spell Selection
- Targetting Invisible Creatures
- Weapon Slots
- Weapon Specialisation-associated Number of Attacks
- Weight Allowance

### Assassin and Bounty Hunter Kits

When the unusability flags for Assassin (0x40000) and Bounty Hunter (0x80000) Kits are used for custom thief kits, TobEx applies the 15% (Assassin) or 20% (Bounty Hunter) thieving skill points disadvantage to these kits.

### Backstabbing

Normally, only non-ranged items usable by thieves can be used for backstabbing. TobEx allows modmakers to invert this behaviour to customise what items can be used for backstabbing. TobEx adds functionality to bit 25 (Toggle backstab restrictions) of ITM V1.0 Extended Header offset 0x0026 (Flags). When set, this bit makes items normally unusable for backstabbing usable, and items normally usable for backstabbing unusable. For a ranged attack that hits, both launcher and ammo abilities are checked, and if at least one of the bits is set, backstabbing is toggled.
Example

| Usable by thief? | Ranged | Bit 25 Off | Bit 25 On
Dagger | Yes | No | Backstab | No backstab
Warhammer | No | No | No backstab | Backstab
Arrow | Yes | Yes | No backstab | Backstab | //bit 25 can be set either on Arrow or Bow)
Throwing Axe | No | Yes | No backstab | Backstab

### Casting Spells When Silenced

Normally, spells cannot be cast while silent unless the caster is affected by Vocalize. TobEx allows modmakers to enable specific spells to be cast when silenced, even when Vocalize is not applied. TobEx adds functionality to bit 25 (Can Be Cast When Silenced) of SPL V1.0 Header offset 0x0018 (Flags). When set and the spell is being cast, the spell will be cast but with a silenced casting sound of CHA_S*.WAV. The behaviour of Vocalize (SPWI219), Set Snare (SPCL412), Set Special Snare (SPCL414), and Pocket Plane (SPIN649), which are normally castable when silenced are not changed.

### Class-Race Restrictions

TobEx externalises the restrictions of classes that are available to each race to CLSRCREQ.2DA. Mage school restrictions are externalised to MGSRCREQ.2DA. This allows modmakers to customise what classes are available to each race.
Note that there are no pre-existing animations for halfling mages and non-human monks. Therefore, animation IDs for the former are set to the halfling cleric and the latter to fighter of the same race

### Contingency/Trigger/Sequencer and Select Spell

Normally, spells that use the Select Spell effect opcode such as Spell Immunity are not shown in the spell menu after casting Contingency or similar spells because the contingency behaviour does not work as intended when such a spell is stored in a contingency. TobEx modifies this by allowing players to select the child spells of a Select Spell effect opcode instead of the parent spell. To enable this behaviour for existing Throne of Bhaal spells, CONTINGX.2DA still needs to be modified to allow those spells to be displayed in the contingency menu.

### Critical Hits

Normally, anything equipped in a helmet slot prevents critical hits. TobEx allows modmakers to invert this behaviour to customise what items avert critical hits. TobEx adds functionality to bit 25 (Toggle critical hit aversion) of ITM V1.0 Header offset 0x0018 (Flags). When set, this bit makes items equipped in helmet slots not avert critical hits, and items equipped in other slots avert critical hits.

### Dual Classing

Option: TobEx gives the option of allowing all races to dual class instead of just humans.

### Equipping Armor in Combat

Option: TobEx gives the option of allowing the player to change the armor slot of party members during combat.

### High Level Abilities (HLAs)

TobEx fixes a bug where Cleric-Ranger classes had the cleric and ranger HLA rules swapped around. This was due to internal arrays being set up inconsistently when working out the number of HLAs available at level-up. Therefore, Cleric-Rangers correctly get their first HLA at Ranger level 13 (with cleric HLAs available due to level 7 spells being available), get one HLA for each Ranger level from level 13 and higher, and get one HLA for each Cleric level from level 15 and higher.

### Hit Point Tables

TobEx externalises the usage of hit point tables to a master HPCLASS.2DA file. This specifies the hit point table to use by single class. This allows modmakers to use custom hit point tables by class.

Additionally, TobEx externalises Barbarian from Fighter class hit point tables to HPBARB.2DA.

### Item Restrictions

TobEx externalises creature-specific item restrictions to ITEM_USE.2DA. This allows modmakers to customise specific item restrictions for creatures in the style of Minsc's Boo and Xan's Moonblade.

ITEM_USE.2DA
[ROWNAME]: the resource name of the item that the item-creature restrictions apply to
USER: death variable/script name of creature (not case-sensitive)
STRREF#: the string reference to display in the inventory screen when the restriction indicated by the flag value of # applies
FLAG: bitfield indicating the type/s of restriction to apply
FLAG bits

- bit 0 [1]: the item cannot be picked up from any slot of the creature (this overrides bits 3 and 4)
- bit 1 [2]: the item can only be equipped by the creature (this is 'stackable', so multiple item entries with different creatures mean that each of the listed creatures can equip the item)
- bit 2 [4]: no restrictions (this bit is reserved for GemRB)
- bit 3 [8]: the item cannot be picked up from any equipped slot of the creature
- bit 4 [16]: the item cannot be picked up from any inventory slot of the creature
- bit 5 [32]: the item cannot be dropped into any equipped slot of the creature
- bit 6 [64]: the item cannot be dropped into any inventory slot of the creature

Example

| USER | STRREF | FLAG | STRREF2 | STRREF4 | STRREF8 | STRREF16 | STRREF32 | STRREF64
MISC84 | MINSC | 10218 | 3 | 10218 | -1 | -1 | -1 | -1 | -1

Item MISC84 cannot be picked up from any slot of "Minsc", and can only be equipped by "Minsc".

### Mage Spells

TobEx allows the extension of the limit of possible mage spells selectable for mages and sorcerers by externalising the number of spells selectable to SPELLS.2DA. The cap for level 1-8 spells can be set to 99, while the cap for level 9 spells can be set to 199, for which spells 100-199 refer to SPWI0**.SPL.

If this hack is used, it is recommended you use this hack with Externalize Mage Spell Hiding. Otherwise, unwanted spells will show up on spell selection screens. Also, assuming you provide maximum values for the number of spells in SPELLS.2DA, you should add to HIDESPL.2DA the following vanilla Throne of Bhaal spells:

SPWI298-299
SPWI399
SPWI483-491, 493-499
SPWI590-97
SPWI853, 888, 897-899
SPWI926-965, 979-999
SPWI001-027, 050-056

### Magical Weapons

TobEx allows modmakers to create magical weapons that do not get dispelled in the magical weapon slot. Also refer to the Dispel Magic effect section.

### Mirror Images

TobEx allows modmakers to create effects that bypass mirror images. Also refer to the Damage effect section.

### Pickpocketing

TobEx allows modmakers to customise which item slots are amenable to pickpocketing, and the minimum skill level required to steal an item from each slot. This behaviour is governed by SLTSTEAL.2DA.

SLTSTEAL.2DA
SKILL: The minimum pickpocketing skill with which the item in the item slot can be stolen. If the skill is set to 0, the item slot can never be stolen from. Note that the SLOT_FIST value is ignored.
[ROWNAME]: The name of the item slot. The row numbers are mapped to the item slot, not the name, except for SLOT_EQUIPPED. SLOT_EQUIPPED refers to the currently equipped weapon slot, or the currently equipped ammo slot and its launcher slot.

### Priest Spells

TobEx allow extension of priest spells allowed at each level from 50 to 99 (SPPR*00-SPPR*99). This is still limited by SPELLS.2DA. If this hack is used, the following change should be made to SPELLS.2DA to avoid existing Throne of Bhaal priest spells that should not be included:

PRIEST 99 99 99 99 98 97 99

### Proficiencies

Option: TobEx gives the option of enabling the application of level one proficiency restrictions as dictated by PROFSMAX.2DA.

TobEx allows additive modification of proficiencies by using a modified effect opcode #233. Also refer to the Proficiency Modifier effect section.

### Spell Selection

TobEx makes a number of changes to spell selection.

For character generation and level-up, TobEx externalises spell selection restrictions to HIDESPL.2DA. This allows modmakers to customise what spells can and cannot be displayed in these spell selection screens. Additionally, TobEx adds scrollbars to the spell selection screens to allow players to select from a choice of more than 24 spells. This currently does not apply to high-level ability selection.

For selecting spells to memorize in mage and priest spellbooks, TobEx adds scroll buttons to allow players to select from greater than 20 memorized spells for each level. At the moment, players cannot scroll through already memorized spells if they overflow the allowed space.

### Targetting Invisible Creatures

Spells cannot be cast under normal conditions on creatures affected by invisibility, improved invisibility, and sanctuary. TobEx adds functionality to bit 24 (Can target invisible) of SPL V1.0 Header offset 0x0018 (Flags). When set, a player can target invisible, improved invisible, and sanctuary creatures with that spell.

For items, TobEx adds functionality to bit 26 (Cannot target invisible) of ITM V1.0 Extended Header offset 0x0026 (Flags). When set, a player cannot target invisible, improved invisible, or sanctuary creatures with that item ability.

### Weapon Slots

TobEx enables the option to give all classes the same number of weapon slots as fighters, who have four weapon slots. This currently only changes the inventory display and not the quick bar at the bottom of the screen.

### Weapon Specialisation-associated Number of Attacks

Option: TobEx gives the option of modifying the application of weapon specialisation-associated number of attacks bonuses described by WSPATCK.2DA. Specifically, all non-monk classes receive such a bonus based on their average level. Originally, ranger, paladin, and fighter classes received such a bonus based on their fighter level, while other non-monk classes received no bonus. Calculation of such a bonus for the monk class is unchanged.

### Weight Allowance

TobEx allows modmakers to customise the percentage weight that defines low and high encumbrance through ENCUMBER.2DA. Additionally, TobEx allows additive modification of weight allowance by using a custom scripting stat #400. Also refer to the Scripting Stats section.

ENCUMBER.2DA
THRESHOLD: The percentage weight above which [ROWNAME] applies. If the THRESHOLD is set to 0, [ROWNAME] never applies. If the THRESHOLD is set to a negative number, the value is treated as invalid and the default hard-coded value is applied.
[ROWNAME]: Either LOW_ENCUMBRANCE (slowed) or HIGH_ENCUMBRANCE (cannot move)

## Triggers

TobEx modifies the internal script compiler used for dialogues so that it recognises more trigger parameter constructions. These are:

- (S,I,I)
- (S,I,I,I)
- (S,O,I,I)
- (S,O,I,I,I)
- (S,S,O)

TobEx makes changes to the following script trigger opcodes:

- 0x4042 PartyHasItem(S:Item*)
- 0x4044 CheckStat(O:Object*,I:Value*,I:StatNum*Stats)
- 0x4045 CheckStatGT(O:Object*,I:Value*,I:StatNum*Stats)
- 0x4046 CheckStatLT(O:Object*,I:Value*,I:StatNum*Stats)
- 0x005D PickPocketFailed(O:Object*)
- 0x4061 HasItem(S:ResRef*,O:Object*)
- 0x40A9 PartyHasItemIdentified(S:ResRef*)
- 0x40BB Kit(O:Object*,I:Kit*KIT)

TobEx aldo adds the following new script trigger opcodes:

- 0x4100 NextTriggerObject(O:Object*)
- 0x4101 MovementRate(O:Object*,I:Value*)
- 0x4102 MovementRateGT(O:Object*,I:Value*)
- 0x4103 MovementRateLT(O:Object*,I:Value*)
- 0x4104 NumMirrorImages(O:Object*,I:Value*)
- 0x4105 NumMirrorImagesGT(O:Object*,I:Value*)
- 0x4106 NumMirrorImagesLT(O:Object*,I:Value*)
- 0x4107 BouncingSpellLevel(O:Object*,I:Level*)
- 0x4108 NumBouncingSpellLevel(O:Object*,I:Level*,I:Amount*)
- 0x4109 NumBouncingSpellLevelGT(O:Object*,I:Level*,I:Amount*)
- 0x410A NumBouncingSpellLevelLT(O:Object*,I:Level*,I:Amount*)
- 0x410B ImmuneToSpellLevel(O:Object*,I:Level*)
- 0x410C NumImmuneToSpellLevel(O:Object*,I:Level*,I:Amount*)
- 0x410D NumImmuneToSpellLevelGT(O:Object*,I:Level*,I:Amount*)
- 0x410E NumImmuneToSpellLevelLT(O:Object*,I:Level*,I:Amount*)
- 0x410F TimeStopCounter(I:Number*)
- 0x4110 TimeStopCounterGT(I:Number*)
- 0x4111 TimeStopCounterLT(I:Number*)
- 0x4112 TimeStopObject(O:Object*)
- 0x4113 NumTrappingSpellLevel(O:Object*,I:Level*,I:Amount*)
- 0x4114 NumTrappingSpellLevelGT(O:Object*,I:Level*,I:Amount*)
- 0x4115 NumTrappingSpellLevelLT(O:Object*,I:Level*,I:Amount*)
- 0x4116 OriginalClass(O:Object*,I:Class*Class)
- 0x4117 HPLost(O:Object*,I:Hit Points*)
- 0x4118 HPLostGT(O:Object*,I:Hit Points*)
- 0x4119 HPLostLT(O:Object*,I:Hit Points*)
- 0x411A Assign(S:Statement*,I:Type*ArgType,I:Local*)
- 0x411B Eval(S:Expression*,I:Type*ArgType,I:Loc*)
- 0x411C E(I:Num1*,I:Num2*)
- 0x411D GT(I:Num1*,I:Num2*)
- 0x411E LT(I:Num1*,I:Num2*)
- 0x411F CheckStatBAND(O:Object*,I:Value*,I:StatNum*Stats)

0x4042 PartyHasItem(S:Item*)
TobEx optimises this trigger by greatly reducing the amount of overhead associated with checking bags

0x4044 CheckStat(O:Object*,I:Value*,I:StatNum*Stats)
0x4045 CheckStatGT(O:Object*,I:Value*,I:StatNum*Stats)
0x4046 CheckStatLT(O:Object*,I:Value*,I:StatNum*Stats)
TobEx makes no direct changes to these opcodes. However, TobEx expands STATS.IDS to support a variety of new scripting stats. Also refer to the Scripting Stats section.

0x005D PickPocketFailed(O:Object*)
TobEx restores the function of this trigger such that it is sent when a pickpocket attempt fails. The standard AttackedBy() trigger is also sent as per vanilla behaviour. Also refer to the PickPockets(O:Target*) action.

Option: TobEx gives the option of modifying the PickPockets(O:Target*) action so that upon failure, it sends only the PickPocketFailed() trigger, and not sending the standard AttackedBy() trigger.

0x4061 HasItem(S:ResRef*,O:Object*)
TobEx optimises this trigger by greatly reducing the amount of overhead associated with checking bags

0x40A9 PartyHasItemIdentified(S:ResRef*)
TobEx optimises this trigger by greatly reducing the amount of overhead associated with checking bags. TobEx fixes a bug in single player where this trigger opcode behaved exactly the same as the PartyHasItem() trigger opcode.

0x40BB Kit(O:Object*,I:Kit*KIT)
TobEx fixes this trigger opcode so that the full dword of I:Kit is checked against the creature rather than just the low word. To preserve original behaviour, if an I:Kit value of 0 is used, only the low word is checked against.

0x4100 NextTriggerObject(O:Object*)
New
Defines the object that the next trigger will be evaluated in reference to. This trigger does not evaluate and does not count as a trigger in an OR() block. This trigger ignores the Eval() trigger when finding the next trigger to evaluate the object for. If the object cannot be found, the next trigger will evaluate to false.

0x4101 MovementRate(O:Object*,I:Value*)
0x4102 MovementRateGT(O:Object*,I:Value*)
0x4103 MovementRateLT(O:Object*,I:Value*)
New
Compares the animation movement rate of the target creature specified by Object to Value. This is not affected by slow or haste, but is affected if the Object is entangled, webbed, etc.

0x4104 NumMirrorImages(O:Object*,I:Value*)
0x4105 NumMirrorImagesGT(O:Object*,I:Value*)
0x4106 NumMirrorImagesLT(O:Object*,I:Value*)
New
Compares the number of mirror images present on the target creature specified by Object to Value.

0x4107 BouncingSpellLevel(O:Object*,I:Level*)
New
Returns true if the target creature specified by Object is bouncing spells of power Level.
This returns true for both Bounce Spell Level (199) and Decrementing Bounce Spells (200) effects.

0x4108 NumBouncingSpellLevel(O:Object*,I:Level*,I:Amount*)
0x4109 NumBouncingSpellLevelGT(O:Object*,I:Level*,I:Amount*)
0x410A NumBouncingSpellLevelLT(O:Object*,I:Level*,I:Amount*)
New
Compares the number of spell bounces remaining on the target creature specified by Object at the power Level to Amount. If Object has the Bounce Spell Level (199) opcode, then the number of spell bounces is unsigned 0xFFFFFFFF.

0x410B ImmuneToSpellLevel(O:Object*,I:Level*)
New
Returns true if the target creature specified by Object is protected from spells of power Level. This returns true for both Protection from Spell Levels (102) and Decrementing Spell Immunity (201) effects.

0x410C NumImmuneToSpellLevel(O:Object*,I:Level*,I:Amount*)
0x410D NumImmuneToSpellLevelGT(O:Object*,I:Level*,I:Amount*)
0x410E NumImmuneToSpellLevelLT(O:Object*,I:Level*,I:Amount*)
New
Compares the number of spell protections remaining on the target creature specified by Object at the power Level to Amount. If Object has the Protection from Spell Levels (102) opcode, then the number of spell protections is unsigned 0xFFFFFFFF.

0x410F TimeStopCounter(I:Number*)
0x4110 TimeStopCounterGT(I:Number*)
0x4111 TimeStopCounterLT(I:Number*)
New
Compares the number of ticks left of time stop to Number.

0x4112 TimeStopObject(O:Object*)
New
Returns true if the the target sprite specified by Object is the caster of time stop (and is exempt from the effect).

0x4113 NumTrappingSpellLevel(O:Object*,I:Level*,I:Amount*)
0x4114 NumTrappingSpellLevelGT(O:Object*,I:Level*,I:Amount*)
0x4115 NumTrappingSpellLevelLT(O:Object*,I:Level*,I:Amount*)
New
Compares the number of spell traps remaining on the target creature specified by Object at the power Level to Amount.

0x4116 OriginalClass(O:Object*,I:Class*Class)
New
Returns true if the target creature specified by Object is dual-classed and the original class matches Class.

0x4117 HPLost(O:Object*,I:Hit Points*)
0x4118 HPLostGT(O:Object*,I:Hit Points*)
0x4119 HPLostLT(O:Object*,I:Hit Points*)
New
Compares the absolute number of hit points short of maximum hit points on the target creature specified by Object to Amount.

0x411A Assign(S:Statement*,I:Type*ArgType,I:Local*)
New
Assigns a value determined by Statement of the type Type from ARGTYPE.IDS (INT integer, or STR string) to a local trigger block variable. The general form of Statement is "prefix[params]". This trigger does not evaluate and does not count as a trigger in an OR() block.

- "prefix" can be:

prefix | description | params type | examples
c | assigns a constant value | integer or string | c[1], c[FOO]
e | assigns the value of an expression | expression (see trigger 0x411B Eval() for format) | e[6 + 7]
id | assigns the index of a IDS file value | file.value | id[EA.CHARMED]
s | assigns the value of the stat specified of the current object | STATS.IDS name | s[LEVEL]
sp | assigns the value of the special value specified (of the current object, if applicable) | ASGNSPEC.IDS name | sp[SPRITE_PT_X]
tn | assigns the value of a 2DA file value by coordinates | file.x.y | tn[IMPORT01.0.0]
ts | assigns the value of a 2DA file value by column and row name | file.column.row | tn[IMPORT01.ITEMS.1]
v | assigns the value of a variable | name.scope | v[foo.GLOBAL]

- "params" values containing #<num> and @<num> are replaced by the integer and string values, respectively, stored in local trigger block variables of index "num". Avoid using integer variables in expressions of string type. Avoid using string variables in expressions of integer type. The range of "num" is 0 to 24.

0x411B Eval(S:Expression*,I:Type*ArgType,I:Loc*)
New
Overwrites the (Loc)th argument of type Type from ARGTYPE.IDS (INT integer, or STR string) in the next trigger with the value returned by Expression. This trigger does not evaluate and does not count as a trigger in an OR() block. This trigger does not overwrite values of the Assign(), NextTriggerObject() and OR() triggers. The NextTriggerObject() trigger ignores this trigger.

- Expression is a math expression that can use the following symbols:

= + - * / % ^ ( )

min(x, y), max(x, y), avg(x, y)

ceil(x), floor(x), round(x)

abs(x)

reciprocal(x)

sqrt(x), pow(x, y)

log(x), log10(x)

sin(x), cos(x), tan(x), sinh(x), cosh(x), tanh(x), asin(x), acos(x), atan(x), atan2(x)

Custom: and(x, y), or(x, y), band(x, y), bor(x, y)

- Any text in Expression of form #<num> and @<num> is replaced by the integer and string values, respectively, stored in local trigger block variables of index "num". Avoid using integer variables in expressions of string type. Avoid using string variables in expressions of integer type. The range of "num" is 0 to 24.

0x411C E(I:Num1*,I:Num2*)
0x411D GT(I:Num1*,I:Num2*)
0x411E LT(I:Num1*,I:Num2*)
New
Compares "Num1" to "Num2", where E is equals, GT is greater than, and LT is less than. To make use of these triggers, the 0x411B Eval() trigger should be used prior to this trigger.

0x411F CheckStatBAND(O:Object*,I:Value*,I:StatNum*Stats)
New
Returns true only if the specified object has the statistic in the 3rd parameter produces a non-zero value when executing a bitwise AND with the value of the 2nd parameter.

## Actions

TobEx makes changes to the following script action opcodes:

- 19 JoinParty()
- 25 PickPockets(O:Target*)
- 34 UseItem(S:Object*,O:Target*)
- 97 UseItemPoint(S:Item,P:Target*,I:Ability*)
- 116 TakePartyItem(S:Item*)
- 174 EquipRanged()
- 188 TakePartyItemAll(S:Item*)
- 193 TakePartyItemRange(S:Item*)
- 194 ChangeAnimation(S:ResRef*)
- 204 TakePartyItemNum(S:ResRef*,I:Num*)
- 219 ChangeAnimationNoEffect(S:ResRef*)
- 220 TakeItemListParty(S:ResRef*)
- 226 TakeItemListPartyNum(S:ResRef*,I:Num*)
- 274 AddKit(I:Kit*KIT)
- 289 AddSuperKit(I:Kit*KIT)
- 317 PlaySong(I:Song*)

TobEx adds the following new script action opcodes:

- 352 LoseGame()
- 353 DialogueSetGlobal(S:Name*,S:Area*,I:Value*)
- 354 DialogueIncrementGlobal(S:Name*,S:Area*,I:Value*)
- 355 DialogueSG(S:Name*,I:Num*)
- 356 Assign(S:Statement*,I:Type*ArgType,I:Local*)
- 356 AssignFromObject(S:Statement*,O:Object*,I:Type*ArgType,I:Local*)
- 357 Eval(S:Expression*,I:Type*ArgType,I:Loc*)
- 358 ClearBlockVariables()

19 JoinParty()
TobEx fixes this action opcode to prevent the action restoring all class abilities, which would allow players to re-use class abilities over and over again.

25 PickPockets(O:Target*)

TobEx extends this action opcode by sending the PickPocketFailed() trigger in addition to the standard AttackedBy() trigger when a pickpocket attempt fails. Also refer to the PickPocketFailed() trigger section.

Option: TobEx gives the option of modifying this action so that upon failure, it sends only the PickPocketFailed() trigger, and not sending the standard AttackedBy() trigger.

Option: TobEx gives the option of modifying this action by delaying the end of Stealth mode until the next round, and not terminating invisibility caused by a spell or item, if a successful pickpocket is made.

34 UseItem(S:Object*,O:Target*)
TobEx modifies this action opcode indirectly by allowing custom animation sequences to be played on the creature using the item. This is controlled by ITEMANIM.2DA and is item ability-specific. Also refer to the Animation Sequences when Using Items section.

97 UseItemPoint(S:Item,P:Target*,I:Ability*)
TobEx modifies this action opcode indirectly by allowing custom animation sequences to be played on the creature using the item. This is controlled by ITEMANIM.2DA and is item ability-specific. Also refer to the Animation Sequences when Using Items section.

116 TakePartyItem(S:Item*)
TobEx fixes this action opcode so that non-party characters taking items no longer put them in the magical weapon slot or quick item slots. TobEx also removes a buffer overflow in some cases when putting items into the magical weapon slot.

174 EquipRanged()
TobEx fixes this action opcode so that one-handed ranged weapons are equipped with this action when a shield is currently equipped

188 TakePartyItemAll(S:Item*)
TobEx fixes this action opcode so that non-party characters taking items no longer put them in the magical weapon slot or quick item slots. TobEx also removes a buffer overflow in some cases when putting items into the magical weapon slot.

193 TakePartyItemRange(S:Item*)
TobEx fixes this action opcode so that non-party characters taking items no longer put them in the magical weapon slot or quick item slots. TobEx also removes a buffer overflow in some cases when putting items into the magical weapon slot.

194 ChangeAnimation(S:ResRef*)
TobEx fixes a bug with this action opcode where a creature killed during this action does not die correctly, resulting in an invincible creature with zero hit points.

204 TakePartyItemNum(S:ResRef*,I:Num*)
TobEx fixes this action opcode so that non-party characters taking items no longer put them in the magical weapon slot or quick item slots. TobEx also removes a buffer overflow in some cases when putting items into the magical weapon slot.

220 TakeItemListParty(S:ResRef*)
TobEx fixes this action opcode so that non-party characters taking items no longer put them in the magical weapon slot or quick item slots. TobEx also removes a buffer overflow in some cases when putting items into the magical weapon slot.

226 TakeItemListPartyNum(S:ResRef*,I:Num*)
TobEx fixes this action opcode so that non-party characters taking items no longer put them in the magical weapon slot or quick item slots. TobEx also removes a buffer overflow in some cases when putting items into the magical weapon slot.

219 ChangeAnimationNoEffect(S:ResRef*)
TobEx fixes a bug with this action opcode where a creature killed during this action does not die correctly, resulting in an invincible creature with zero hit points.

274 AddKit(I:Kit*KIT)
Fixed so the full dword of I:Kit is saved into the creature rather than the low word. This specifically allows setting BARBARIAN (0x40000000) and WILDMAGE (0x80000000) kits.

289 AddSuperKit(I:Kit*KIT)
Fixed so the full dword of I:Kit is saved into the creature rather than the low word. This specifically allows setting BARBARIAN (0x40000000) and WILDMAGE (0x80000000) kits.

317 PlaySong(I:Song*)
TobEx modifies this action opcode to allow songs with index greater than 127 to be played, allowing modmakers to fully utilise an extended SONGLIST.2DA. Also refer to the Music Song List section.

352 LoseGame()
New
Plays the ending cutscene as if the protagonist died. If the action is used in a pausing dialogue, the ending cutscene will play after the dialogue ends. This action does nothing in the arenas game type.

353 DialogueSetGlobal(S:Name*,S:Area*,I:Value*)
New
Sets the variable 'Name' in the scope 'Area' to 'Value' immediately instead of being added through the dialogue owner's action queue. This allows variables to be set instantaneously and checked immediately afterwards in the same dialogue. ActionOverride() is supported. If used outside dialogue, this action behaves exactly as SetGlobal().
Limitations: Variables become set asynchronously to the order in which the action is present on the script block. This can cause issues when an action is purposely sandwiched between two modifications of the same variable.

354 DialogueIncrementGlobal(S:Name*,S:Area*,I:Value*)
New
Increments the variable 'Name' in the scope 'Area' by 'Value' immediately instead of being added through the dialogue owner's action queue. This allows variables to be set instantaneously and checked immediately afterwards in the same dialogue. ActionOverride() is supported. If used outside dialogue, this action behaves exactly as IncrementGlobal().
Limitations: Variables become set asynchronously to the order in which the action is present on the script block. This can cause issues when an action is purposely sandwiched between two modifications of the same variable.

355 DialogueSG(S:Name*,I:Num*)
New
Sets the global variable 'Name' to 'Num' immediately instead of being added through the dialogue owner's action queue. This allows variables to be set instantaneously and checked immediately afterwards in the same dialogue. ActionOverride() is supported. If used outside dialogue, this action behaves exactly as SG().
Limitations: Variables become set asynchronously to the order in which the action is present on the script block. This can cause issues when an action is purposely sandwiched between two modifications of the same variable.

356 Assign(S:Statement*,I:Type*ArgType,I:Local*)
356 AssignFromObject(S:Statement*,O:Object*,I:Type*ArgType,I:Local*)
New
Assigns a value determined by Statement of the type Type from ARGTYPE.IDS (INT integer, or STR string) to a local action block variable. The general form of Statement is "prefix[params]". If Object is specified, the value of Statement is determined relative to Object instead of the object that owns the script. This action is ignored by prior Eval() actions.

- "prefix" can be:

prefix | description | params type | examples
c | assigns a constant value | integer or string | c[1], c[FOO]
e | assigns the value of an expression | expression (see action 0x411B Eval() for format) | e[6 + 7]
id | assigns the index of a IDS file value | file.value | id[EA.CHARMED]
s | assigns the value of the stat specified of the current object | STATS.IDS name | s[LEVEL]
sp | assigns the value of the special value specified (of the current object, if applicable) | ASGNSPEC.IDS name | sp[SPRITE_PT_X]
tn | assigns the value of a 2DA file value by coordinates | file.x.y | tn[IMPORT01.0.0]
ts | assigns the value of a 2DA file value by column and row name | file.column.row | tn[IMPORT01.ITEMS.1]
v | assigns the value of a variable | name.scope | v[foo.GLOBAL]

- "params" values containing #<num> and @<num> are replaced by the integer and string values, respectively, stored in local action block variables of index "num". Avoid using integer variables in expressions of string type. Avoid using string variables in expressions of integer type. The range of "num" is 0 to 24.

357 Eval(S:Expression*,I:Type*ArgType,I:Loc*)
New
Overwrites the (Loc)th argument of type Type from ARGTYPE.IDS (INT integer, or STR string) in the next action with the value returned by Expression. To replace point X and point Y, use a Loc value of 4 and 5, respectively. This action skips subsequent Assign() and Eval() actions when determining in which action to overwrite a value. This action does not overwrite values of actions beyond ClearBlockVariables() actions.

- Expression is a math expression that can use the following symbols:

= + - * / % ^ ( )

min(x, y), max(x, y), avg(x, y)

ceil(x), floor(x), round(x)

abs(x)

reciprocal(x)

sqrt(x), pow(x, y)

log(x), log10(x)

sin(x), cos(x), tan(x), sinh(x), cosh(x), tanh(x), asin(x), acos(x), atan(x), atan2(x)

Custom: and(x, y), or(x, y), band(x, y), bor(x, y)

- Any text in Expression of form #<num> and @<num> is replaced by the integer and string values, respectively, stored in local action block variables of index "num". Avoid using integer variables in expressions of string type. Avoid using string variables in expressions of integer type. The range of "num" is 0 to 24.

358 ClearBlockVariables()
New
Sets all action block integer variables to 0 and empties all actions block string variables.

## Scripting Stats

TobEx expands the use of STATS.IDS to support new hard-coded stats and custom stats for modmaker use. The features of new stats are:

- New stats can be set using effect opcode 318 (0x13E) with description below
- New stats 202-400 are reserved for hard-coded stats
- New stats can be checked correctly using CheckStat(), CheckStatLT(), and CheckStatGT() script triggers
- New stats are not permanent, they require an ongoing effect opcode 318 in order to keep their values
- New stats will only be saved in saved games if stored as an effect opcode 318
- Actions cannot directly set the value of new stats (they will not keep); use an action to trigger effect opcode 318 if actions are required
- New stats have no effect on the game unless you specifically script in; for example, use scripts to CheckStat() and apply appropriate actions

New hard-coded stats that cannot be set using effect opcode 318 include:

301 FIGHTERLEVEL | true fighter level (does not include monk)
302 MAGELEVEL | true mage level (does not include sorcerer)
303 CLERICLEVEL | true cleric level
304 THIEFLEVEL | true thief level
305 DRUIDLEVEL | true druid level
306 RANGERLEVEL | true ranger level
307 EFFECTCLERICLEVEL | equivalent cleric casting level (Cleric 1 = Ranger 8 = Paladin 9; Cleric-Rangers use cleric level)
308 BUTTONDISABLESTEALTH | set via Disable/Enable Button effect opcodes
309 BUTTONDISABLETHIEVING | set via Disable/Enable Button effect opcodes
310 BUTTONDISABLECASTSPELL | set via Disable/Enable Button effect opcodes
311 BUTTONDISABLEQUICKSPELL1 | set via Disable/Enable Button effect opcodes
312 BUTTONDISABLEQUICKSPELL2 | set via Disable/Enable Button effect opcodes
313 BUTTONDISABLEQUICKSPELL3 | set via Disable/Enable Button effect opcodes
314 BUTTONDISABLETURNUNDEAD | set via Disable/Enable Button effect opcodes
315 BUTTONDISABLETALK | set via Disable/Enable Button effect opcodes
316 BUTTONDISABLEUSEITEM | set via Disable/Enable Button effect opcodes
317 BUTTONDISABLEQUICKITEM1 | set via Disable/Enable Button effect opcodes
318 BUTTONDISABLEBARDSONG | set via Disable/Enable Button effect opcodes
319 BUTTONDISABLEQUICKITEM2 | set via Disable/Enable Button effect opcodes
320 BUTTONDISABLEQUICKITEM3 | set via Disable/Enable Button effect opcodes
321 BUTTONDISABLEABILITY | set via Disable/Enable Button effect opcodes
322 BUTTONDISABLEFINDTRAPS | set via Disable/Enable Button effect opcodes, disables Find Traps button when set to 1
323 AID | set to param1 of Aid effect
324 BLESS | set to param1 of Bless effect
325 CHANT | set to param1 of Chant effect
326 DRAWUPONHOLYMIGHT | set to param1 of Draw Upon Holy Might effect
327 CHANTBAD | set to param1 of Chant Bad effect
328 DISABLESPELLTYPEWIZARD | set to 1 on Disable Spelltype effect
329 DISABLESPELLTYPEPRIEST | set to 1 on Disable Spelltype effect
330 DISABLESPELLTYPEINNATE | set to 1 on Disable Spelltype effect
331 WINGBUFFET | set to param2 of Wing Buffet effect

New hard-coded stats that can be set using effect opcode 318 include:

387 ACIDDAMAGEBONUS | percentage modifier to acid damage from item/spell ability effects
388 COLDDAMAGEBONUS | percentage modifier to cold damage from item/spell ability effects
389 CRUSHINGDAMAGEBONUS | percentage modifier to crushing damage from normal damage and item/spell ability effects
390 ELECTRICITYDAMAGEBONUS | percentage modifier to electricity damage from item/spell ability effects
391 FIREDAMAGEBONUS | percentage modifier to fire damage from item/spell ability effects
392 PIERCINGDAMAGEBONUS | percentage modifier to piercing damage from normal damage and item/spell ability effects
393 POISONDAMAGEBONUS | percentage modifier to poison damage from item/spell ability effects
394 MAGICDAMAGEBONUS | percentage modifier to magic damage from item/spell ability effects
395 MISSILEDAMAGEBONUS | percentage modifier to missile damage from normal damage and item/spell ability effects
396 SLASHINGDAMAGEBONUS | percentage modifier to slashing damage from normal damage and item/spell ability effects
397 MAGICFIREDAMAGEBONUS | percentage modifier to magic fire damage from item/spell ability effects
398 MAGICCOLDDAMAGEBONUS | percentage modifier to magic colddamage from item/spell ability effects
399 STUNNINGDAMAGEBONUS | percentage modifier to stunning damage from normal damage and item/spell ability effects
400 WEIGHTALLOWANCEMOD | custom stat that modiifies by sum the amount a character is allowed to carry (total weight allowance = StrMod value + StrModEx value + WeightAllowanceMod)

## Audio

The following changes to audio are discussed:

- Animation and Creature Soundsets
- Animation Walking Sounds
- Dialogue Greeting Subtitles
- Soundset Subtitles

### Animation and Creature Soundsets

TobEx fixes a bug that prevented the sounds in the middle of animation soundset 2DA files from playing. TobEx also fixes a bug where PICKED_POCKET sounds were played when EXISTANCE sounds were called for in the creature soundset. This was corrected to EXISTANCE5.

Option: TobEx gives the option to enable the use of SLASH, BACKSLASH, and JAB sounds in animation soundset 2DA files. These sounds play when the appropriate attack animation is played. They are played in addition to the ATTACK sound.

### Animation Walking Sounds

TobEx externalises all animation walking sounds to ANIWKSND.2DA, which allows modmakers to specify custom walking sounds by each animation ID. This is particularly useful for new animations introduced by Infinity Animations.

ANIWKSND.2DA
[ROWNAME]: animation ID
ANIMATION: the name of the animation for your reference (from ANIMATE.IDS)
WALK_SOUND: 6-character string specifying the root name of the walking sound. Longer strings are read truncated. Shorter strings cause havoc! A value of '*' is equivalent to no walking sound.
WALK_NUM: integer specifying the number of walking sounds available for the root name.
As per engine behaviour, a sound file will be loaded with name <WALK_SOUND><random>, where <random> is mapped 0 -> a, 1 -> b, 2 -> c, ..., (WALK_NUM - 1) -> nul.
Example

| WALK_SOUND | WALK_NUM
0x1234 | WAL_20 | 4

Walking sound for animation ID 0x1234 loads one of the following sounds:
WAL_20a [0]
WAL_20b [1]
WAL_20c [2]
WAL_20 [3]
If WALK_SOUND is set to 'TERRAIN' and WALK_NUM is set to '*', ANITNSND.2DA is used to determine the walking sound.

ANITNSND.2DA
[ROWNAME]: terrain code, based on search map pixel
WALK_SOUND: as ANIWKSND.2DA above
WALK_NUM: as per ANIWKSND.2DA above

### Dialogue Greeting Subtitles

Option: TobEx gives the option of displaying the greeting string reference in the dialogue bar when initiating dialogue, similar to Baldur's Gate I behaviour. However, the string is displayed after the first line of dialogue rather than before.

### Soundset Subtitles

TobEx enables the display of subtitles for custom soundsets in the dialogue bar. This is achieved by appending by column to CSOUND.2DA. This is vanilla-compatible: if no column is present in CSOUND.2DA, no subtitles are used. To use this hack, use APPEND_COL on CSOUND.2DA. The column header should contain the prefix of the soundset (e.g. FEMALE1). The values for each sound should point to the string reference to display for the sound with suffix designated by the existing LETTER column. Please note the LETTER values in rows labelled with the numbers 30, 31, 39, 63, and 64 are incorrect in vanilla Throne of Bhaal and should be corrected to "x, y, *, _, *", respectively.

## Animations and Graphics

The following animation changes are discussed:

- Animation Sequences when Using Items
- Icewind Dale-style Animations
- Paper Dolls
- Spell Turning Animations
- Throwing Weapon Animations
- Tooltip Scroll
- Visual Effect Video Cells (VVCs)

### Animation Sequences when Using Items

TobEx expands the use of custom animation sequences when using different abilities of the same item in the setting of the UseItem() and UseItemPoint() actions, or equivalent thereof (i.e. used as quick item). This is achieved by expanding ITEMANIM.2DA. Modmakers can therefore assign custom animation sequences to the use of specific item abilities.

ITEMANIM.2DA
This file lists the character animation sequence to be played when an item ability is used. This only applies to items that are used in UseItem() and UseItemPoint() actions, or equivalent thereof (i.e. used as quick item).
[ROWNAME]: Item ResRef
SEQUENCE: The animation sequence to play for the first ability of the specified item (from seq.ids). If there are no other columns, this is the animation sequence to play for all abilities.
<subsequent columns>: The animation sequence to play for the (n+1)th ability of the specified item (from seq.ids), where n is the name of the column.

Example
WAND05.ITM has two abilities

2DA V1.0
-1
| SEQUENCE | 1
WAND05 | -1 | 12

Using the first ability plays no animation sequence (-1). Using the second ability plays animation sequence 12 (SEQ_ATTACK_BACKSLASH).

### Icewind Dale-style Animations

TobEx fixed Icewind Dale-style animations (of IDs 0xE***) that use the 3rd attack animation (A3). These would otherwise have display the 2nd attack animation in northeast and east orientations if 'Sprite Mirror' is disabled in baldur.ini.

### Paper Dolls

TobEx enables paperdolls to be shown in the inventory and character customisation screens for animation IDs 0x12XX, 0x2XXX, 0x3XXX, and modification-added 0x7XXX (except 0x73XX, which is already shown in vanilla), which would otherwise not show at all. Note that paperdolls for the 0x7XXX group of animation must have to be named <prefix>INV.BAM.

### Spell Turning Animation

TobEx fixes a bug introduced somewhere between builds 22941 and 23037 of Shadows of Amn, whereby SPSTURNI.VVC was no longer played each time a spell is bounced off a creature who had spell turning.

### Throwing Weapon Animations

Option: TobEx gives the option of enabling the use of item ability slash %, backslash %, and jab % fields for ranged weapons equipped in a weapon slot that do not require a launcher. Because this hack makes the creature use of the SEQ_ATTACK_[] animations instead of SEQ_SHOOT, attacks play the SEQ_ATTACK and SEQ_ATTACK_[] animation sounds instead of the SEQ_SHOOT animation sound. These percentages will only affect creatures with animation IDs in the 0x5000-0x53FF group with animation prefix starting with C, and 0x6*** groups to maintain vanilla behaviour and Infinity Animations compatibility.

### Tooltip Scroll

TobEx enlarges the tooltip scroll so that it can fit more text.

### Visual Effect Video Cells (VVCs)

TobEx fixes a few issues with the VVC file format.

The Display Flag (0x0018) bit 2 (Translucent shadow) has been fixed to use the Shadow Animation ResRef (0x0010) instead of duplicating the use of the Primary Animation ResRef (0x0008).

The Alpha Blending Animation ResRef (0x0088) has been fixed to allow its use without summarily causing an assertion failure.

## Effects

TobEx makes the following changes to the EFF V2.0 file format.

### Body

Offset | Description
0x0040 (dword) | Saving throw type bit 24: bypass mirror images bit 25: limit effect stacking bit 26: internal: suspend effect application
0x0048 (dword) | Special Vanilla: Used only for Set Local Variable when the variable is non-existant Stacking ID when bit 25 of 'Saving throw type' is enabled

TobEx makes changes to the following effect opcodes:

- #1 (0x001) Stat: Attacks Per Round Modifier [1]
- #2 (0x002) Cure: Sleep [2]
- #6 (0x006) Stat: Charisma Modifier [6]
- #10 (0x00A) Stat: Constitution Modifier [10]
- #12 (0x00C) HP: Damage [12]
- #13 (0x00D) Death: Instant Death [13]
- #15 (0x00F) Stat: Dexterity Modifier [15]
- #19 (0x013) Stat: Intelligence Modifier [19]
- #20 (0x014) State: Invisibility [20]
- #21 (0x015) Stat: Lore Modifier [21]
- #22 (0x016) Stat: Cumulative Luck Bonus [22]
- #25 (0x019) State: Poison [25]
- #33 (0x021) Stat: Save vs. Death Modifier [33]
- #34 (0x022) Stat: Save vs. Wands Modifier [34]
- #35 (0x023) Stat: Save vs. Petrification/Polymorph Modifier [35]
- #36 (0x024) Stat: Save vs. Breath Weapons Modifier [36]
- #37 (0x025) Stat: Save vs. Spells Modifier [37]
- #42 (0x02A) Spell: Wizard Spell Slots Modifier [42]
- #44 (0x02C) Stat: Strength Modifier [44]
- #49 (0x031) Stat: Wisdom Modifier [49]
- #58 (0x03A) Cure: Dispellable Effects (Dispel Magic) [58]
- #59 (0x03B) Stat: Stealth Modifier [59]
- #62 (0x03E) Spell: Priest Spell Slots Modifier [62]
- #74 (0x04A) State: Blindness [74]
- #78 (0x04E) State: Disease [78]
- #90 (0x05A) Stat: Open Locks Modifier [90]
- #91 (0x05B) Stat: Find Traps Modifier [91]
- #92 (0x05C) Stat: Pick Pockets Modifier [92]
- #93 (0x05D) Stat: Fatigue Modifier [93]
- #94 (0x05E) Stat: Drunkenness Modifier [94]
- #95 (0x05F) Stat: Tracking Skill Modifier [95]
- #96 (0x060) Stat: Level Change [96]
- #97 (0x061) Stat: Strength-Bonus Modifier [97]
- #98 (0x062) HP: Regeneration [98]
- #106 (0x06A) Stat: Morale Break Modifier [106]
- #108 (0x06C) Stat: Reputation [108]
- #119 (0x077) Spell Effect: Mirror Image [119]
- #135 (0x087) Graphics: Polymorph into Specific [135]
- #144 (0x090) Button: Disable Button [144]
- #147 (0x093) Spell: Learn Spell [147]
- #164 (0x0A4) Cure: Drunkeness [164]
- #166 (0x0A6) Stat: Magical Resistance Modifier [166]
- #173 (0x0AD) Stat: Set Poison Resistance [173]
- #177 (0x0B1) Use EFF File [177]
- #181 (0x0B5) Item: Can't Use Itemtype [181]
- #182 (0x0B6) Item: Apply Effect Item [182]
- #183 (0x0B7) Item: Apply Effect Itemtype [183]
- #191 (0x0BF) Spell: Casting Level Modifier [191]
- #218 (0x0DA) Protection: Stoneskin [218]
- #232 (0x0E8) Spell Effect: Cast Spell on Condition [232]
- #233 (0x0E9) Stat: Proficiency Modifier [233]
- #238 (0x0EE) Death: Disintegrate [238]
- #272 (0x110) Spell: Apply Repeating EFF [272]
- #273 (0x111) Remove: Specific Area Effect(Zone of Sweet Air) [273]
- #279 (0x117) Button: Enable Button [279]
- #298 (0x12A) Cutscene 2 [298]
- #303 (0x12F) Spell Effect: Backstab On Condition [303]

TobEx also adds the following new effect opcodes:

- #318 (0x13E) Stat: Set Stat [318]

#1 (0x001) Stat: Attacks Per Round Modifier [1]
TobEx fixes this effect opcode so that stacking this opcode stacks the number of attacks, not the key. The transformation is done internally, so that the key value is still stored in the effect.
Parameter #1: Value
Parameter #2: Type
Description:
Alters a characters Attacks per Round in the style specified by 'Type' field.

Key | Attacks Per Round
0 | 0
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 0.5
7 | 1.5
8 | 2.5
9 | 3.5
10 | 4.5

Known values for 'Type' are:

0 Cumulative Modifier -> Key = Key + Value [Value is of type 'Key' with support for negative keys]
1 Flat Value Modifier -> Key = Value [Value is of type 'Key']
2 Percentage Modifier -> Key = Key * value / 100 [Value is of type 'positive integer', with rounding to the nearest 0.5 attacks]

#2 (0x002) Cure: Sleep [2]
TobEx fixes this effect opcode so that it correctly removes the Sleep effect opcode

#6 (0x006) Stat: Charisma Modifier [6]
TobEx fixes a bug so that a net negative charisma value will limit to 0 rather than wrap to 25. This removes an exploit involving the Rod of Terror and the Ring of Human Influence

#10 (0x00A) Stat: Constitution Modifier [10]
TobEx fixes a bug so that a net negative constitution value will limit to 0 rather than wrap to 25

#12 (0x00C) HP: Damage [12]
TobEx fixes three bugs with this effect opcode:

- killing someone with magic fire damage would cause a WEIRD damage assertion failure, and
- hitting someone with magic cold damage would not play a hit sound
- memory leak when fist damage would make the target unconscious

TobEx allows the scaling of damage type by percentage by using custom scripting stats #387 to #399. Also refer to the Scripting Stats section.

TobEx implements bit 24 (Bypass Mirror Images) of the EFF V2.0 Header offset 0x0040 (Save Type), ITM V1.0 Feature Block offset 0x0024 (Save Type), and SPL V1.0 Feature Block offset 0x0024 (Save Type). When set the mirror image check is skipped on the target creature when checking saving throw.

Option: TobEx gives the option of implementing a concentration check affecting spellcasters being hit. Instead of always being interrupted when hit, spellcasters have a chance of their spells being interrupted. In the current implementation, a spellcaster passes the concentration check if:

(1D20 + luck) > (spell level + damage taken)

Option: TobEx gives the option of not interrupting a creature's spellcasting if a creature takes zero damage (i.e. immune)

Option: TobEx gives the option of causing sleeping creatures to awaken when hit.

#13 (0x00D) Death: Instant Death [13]
Option: TobEx gives the option of making a creature dying of disintegrate, frozen death, and/or stone death drop all non-critical items

#15 (0x00F) Stat: Dexterity Modifier [15]
TobEx fixes a bug so that a net negative dexterity value will limit to 0 rather than wrap to 25. TobEx also adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Dexterity = Dexterity + 'Statistic Modifier' value
1 Flat Value Modifier -> Dexterity = 'Statistic Modifier' value
2 Percentage Modifier -> Dexterity = (Dexterity * 'Statistic Modifier' value) / 100
3 Cats Grace Spell

For a Type of 3 (Cat's Grace Spell), dexterity is modified as per Icewind Dale Cat's Grace spell behaviour, externalised to CLSSPLAB.2DA, in which 1Dx dexterity is gained up to a maximum of 20 depending on the player's class (defaults to 1D6 if class is not present), where x is specified by the DEX column.

#19 (0x013) Stat: Intelligence Modifier [19]
TobEx fixes a bug so that a net negative intelligence value will limit to 0 rather than wrap to 25

#20 (0x014) State: Invisibility [20]
TobEx fixes the application of improved invisibility under permanent until death timing

#21 (0x015) Stat: Lore Modifier [21]
TobEx fixes a bug so that a net negative lore value will limit to 0 rather than wrap to 100

#22 (0x016) Stat: Cumulative Luck Bonus [22]
TobEx adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Luck = Luck + 'Statistic Modifier' value
1 Flat Value Modifier -> Luck = 'Statistic Modifier' value
2 Percentage Modifier -> Luck = (Luck * 'Statistic Modifier' value) / 100
3 Instantaneous Cumulative Modifier -> Luck = Luck + 'Statistic Modifier' value

For a non-permanent timing, the instantaneous cumulative modifier immediately adds the 'Statistic Modifier' value, unlike the cumulative modifier which adds the 'Statistic Modifier' after all effects are applied. The former has the disadvantage that it will be overriden by any subsequent flat value modifiers. Percentage modifiers override all other modifiers.

#25 (0x019) State: Poison [25]
TobEx fixes a bug with the poison effect opcode where a creature with multiple instances of disease, poison, wing buffet, regeneration and/or repeating effect opcodes would only have the highest frequency instance applied

#33 (0x021) Stat: Save vs. Death Modifier [33]
TobEx fixes a bug so that the save value correctly limits to -20 or 20, rather than a net negative save value wrapping to 20. TobEx adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Save = Save + 'Statistic Modifier' value
1 Flat Value Modifier -> Save = 'Statistic Modifier' value
2 Percentage Modifier -> Save = (Save * 'Statistic Modifier' value) / 100
3 Instantaneous Cumulative Modifier -> Save = Save + 'Statistic Modifier' value

'Statistic Modifier' can be positive or negative.
For a non-permanent timing, the instantaneous cumulative modifier immediately adds the 'Statistic Modifier' value, unlike the cumulative modifier which adds the 'Statistic Modifier' after all effects are applied. The former has the disadvantage that it will be overriden by any subsequent flat value modifiers. Percentage modifiers override all other modifiers.

#34 (0x022) Stat: Save vs. Wands Modifier [34]
TobEx fixes a bug so that the save value correctly limits to -20 or 20, rather than a net negative save value wrapping to 20. TobEx adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Save = Save + 'Statistic Modifier' value
1 Flat Value Modifier -> Save = 'Statistic Modifier' value
2 Percentage Modifier -> Save = (Save * 'Statistic Modifier' value) / 100
3 Instantaneous Cumulative Modifier -> Save = Save + 'Statistic Modifier' value

'Statistic Modifier' can be positive or negative.
For a non-permanent timing, the instantaneous cumulative modifier immediately adds the 'Statistic Modifier' value, unlike the cumulative modifier which adds the 'Statistic Modifier' after all effects are applied. The former has the disadvantage that it will be overriden by any subsequent flat value modifiers. Percentage modifiers override all other modifiers.

#35 (0x023) Stat: Save vs. Petrification/Polymorph Modifier [35]
TobEx fixes a bug so that the save value correctly limits to -20 or 20, rather than a net negative save value wrapping to 20. TobEx adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Save = Save + 'Statistic Modifier' value
1 Flat Value Modifier -> Save = 'Statistic Modifier' value
2 Percentage Modifier -> Save = (Save * 'Statistic Modifier' value) / 100
3 Instantaneous Cumulative Modifier -> Save = Save + 'Statistic Modifier' value

'Statistic Modifier' can be positive or negative.
For a non-permanent timing, the instantaneous cumulative modifier immediately adds the 'Statistic Modifier' value, unlike the cumulative modifier which adds the 'Statistic Modifier' after all effects are applied. The former has the disadvantage that it will be overriden by any subsequent flat value modifiers. Percentage modifiers override all other modifiers.

#36 (0x024) Stat: Save vs. Breath Weapons Modifier [36]
TobEx fixes a bug so that the save value correctly limits to -20 or 20, rather than a net negative save value wrapping to 20. TobEx adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Save = Save + 'Statistic Modifier' value
1 Flat Value Modifier -> Save = 'Statistic Modifier' value
2 Percentage Modifier -> Save = (Save * 'Statistic Modifier' value) / 100
3 Instantaneous Cumulative Modifier -> Save = Save + 'Statistic Modifier' value

'Statistic Modifier' can be positive or negative.
For a non-permanent timing, the instantaneous cumulative modifier immediately adds the 'Statistic Modifier' value, unlike the cumulative modifier which adds the 'Statistic Modifier' after all effects are applied. The former has the disadvantage that it will be overriden by any subsequent flat value modifiers. Percentage modifiers override all other modifiers.

#37 (0x025) Stat: Save vs. Spells Modifier [37]
TobEx fixes a bug so that the save value correctly limits to -20 or 20, rather than a net negative save value wrapping to 20. TobEx adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Save = Save + 'Statistic Modifier' value
1 Flat Value Modifier -> Save = 'Statistic Modifier' value
2 Percentage Modifier -> Save = (Save * 'Statistic Modifier' value) / 100
3 Instantaneous Cumulative Modifier -> Save = Save + 'Statistic Modifier' value

'Statistic Modifier' can be positive or negative.
For a non-permanent timing, the instantaneous cumulative modifier immediately adds the 'Statistic Modifier' value, unlike the cumulative modifier which adds the 'Statistic Modifier' after all effects are applied. The former has the disadvantage that it will be overriden by any subsequent flat value modifiers. Percentage modifiers override all other modifiers.

#42 (0x02A) Spell: Wizard Spell Slots Modifier [42]
TobEx adds parameter 2 value 512
Parameter #1: Slot Amount Modifier
Parameter #2: Spell Level
Description:
Alters the number of wizard spell slots available to the targeted creature(s), as specified by the 'Slot Amount Modifier' field, at the level specified by the 'Spell Level' field.
Known values for 'Spell Level' are:

0 Double spells
1 Level 1
2 Level 2
4 Level 3
8 Level 4
16 Level 5
32 Level 6
64 Level 7
128 Level 8
256 Level 9
512 Double spells

For a 'Spell Level' of 0, the amount of spell slots is doubled for the level specified by the 'Slot Amount Modifier' value and all levels below. For a 'Spell Level' of 512, the amount of spell slots is doubled for the level(s) specified by the 'Slot Amount Modifier' field, where a value of 0 is level 1 and a value of 8 is level 9. The target creature(s) must have at least 1 slot at the selected level to have their slot count changed. If the resultant slot count is negative, the creature is given 12 slots.
'Statistic Modifier' can be positive or negative.

#44 (0x02C) Stat: Strength Modifier [44]
TobEx fixes a bug so that a net negative strength value will limit to 0 rather than wrap to 25. TobEx also adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Strength = Strength + 'Statistic Modifier' value
1 Flat Value Modifier -> Strength = 'Statistic Modifier' value
2 Percentage Modifier -> Strength = (Strength * 'Statistic Modifier' value) / 100
3 Strength Spell

For a Type of 3 (Strength Spell), strength is modified as per Icewind Dale Strength spell behaviour, externalised to CLSSPLAB.2DA, in which 1Dx strength is gained up to a maximum of 18/<STREX value> depending on the player's class (defaults to 1D6 if class is not present), where x is specified by the STR column. Unit increments between 18 and 19 depend on differences detected in the STRMODEX.2DA table. The 'Statistic Modifier' value overrides the CLSSPLAB.2DA entry, specifying the die size and allowing a maximum strength of 18/00.
FlameWing's description of Strength Spell: "IWD1/P&P Strength Spell With a slight change, in that param1 != 0 means dice size to roll for all classes and allows exceptional strength bonuses for non-warrior classes. For example, param1 = 4 rolls a d4 for strength increase, similar to P&P Strength of Stone spell. In all cases, strength cannot become 19 or more."

#49 (0x031) Stat: Wisdom Modifier [49]
TobEx fixes a bug so that a net negative wisdom value will limit to 0 rather than wrap to 25

#58 (0x03A) Cure: Dispellable Effects (Dispel Magic) [58]
TobEx adds parameter 2 high and corrects the formula used to determine whether dispel is successful
TobEx implements bit 24 (Not dispellable in magical weapon slot) to the ITM V1.0 Header offset 0x0018 (Flags). Items with this flag set cannot be dispelled by this effect opcode
Parameter #1: Level
Parameter #2 Low: Type
Parameter #2 High: Magical weapon dispel behaviour
Description:
Dispels magic from the targeted creature(s). Depending on the value of the 'Type' field, the 'Level' field can be used to set the level of the effect.
Known values for 'Type' are:

0 Always dispel
1 Use Caster Level
2 Use 'Level' field

Known values for 'Magical weapon dispel behaviour' are:

0 Always dispel
1 Do not dispel
2 Chance of dispel (target level is the higher of the effective mage or cleric level, whichever is higher)

With 'Type' of 1 or 2, the base chance of successfully dispelling is 50%. This chance is modified by the relative levels of the dispeller to the target.
Each level below target gives a -10% chance, each level above target gives a +5% chance. There is always a 1% chance of success or failure.

#59 (0x03B) Stat: Stealth Modifier [59]
TobEx fixes a bug so that an out of bounds move silently skill will limit to 0 or 255 rather than wrap around

#62 (0x03E) Spell: Priest Spell Slots Modifier [62]
Added parameter 2 value 3
Parameter #1: Slot Amount Modifier
Parameter #2: Spell Level
Description:
Alters the number of priest spell slots available to the targeted creature(s), as specified by the 'Slot Amount Modifier' field, at the level specified by the 'Spell Level' field.
Known values for 'Spell Level' are:

0 Double spells
1 Level 1
2 Level 2
4 Level 3
8 Level 4
16 Level 5
32 Level 6
64 Level 7
512 Double spells

For a 'Spell Level' of 0, the amount of spell slots is doubled for the level specified by the 'Slot Amount Modifier' value and all levels below. For a 'Spell Level' of 512, the amount of spell slots is doubled for the level(s) specified by the 'Slot Amount Modifier' field. The target creature(s) must have at least 1 slot at the selected level to have their slot count changed. If the resultant slot count is negative, the creature is given 12 slots.
'Statistic Modifier' can be positive or negative.

#74 (0x04A) State: Blindness [74]
TobEx fixes this effect opcode to prevent stacking of the THAC0 penalty when a creature is affected by multiple copies of this effect opcode

Option: TobEx gives the option of modifying this effect opcode to match the Blindness spell description in the game. If used, Blindness gives a -4 to hit and 4 point armor penalty instead of a -10 to hit penalty.

#78 (0x04E) State: Disease [78]
TobEx fixes a bug with the disease effect opcode for parameter 2 values 0-3 where a creature with multiple instances of disease, poison, wing buffet, regeneration and/or repeating effect opcodes would only have the highest frequency instance applied

#90 (0x05A) Stat: Open Locks Modifier [90]
TobEx fixes a bug so that an out of bounds open locks skill will limit to 0 or 255 rather than wrap around

#91 (0x05B) Stat: Find Traps Modifier [91]
TobEx fixes a bug so that an out of bounds find traps skill will limit to 0 or 255 rather than wrap around

#92 (0x05C) Stat: Pick Pockets Modifier [92]
TobEx fixes a bug so that an out of bounds pick pockets skill will limit to 0 or 255 rather than wrap around

#93 (0x05D) Stat: Fatigue Modifier [93]
TobEx fixes a bug so that a net negative fatigue limit value will limit to 0 rather than wrap to 100

#94 (0x05E) Stat: Drunkenness Modifier [94]
TobEx fixes a bug so that a net negative intoxication value will limit to 0 rather than wrap to 100

#95 (0x05F) Stat: Tracking Skill Modifier [95]
TobEx fixes a bug so that an out of bounds tracking skill will limit to 0 or 255 rather than wrap around

#96 (0x060) Stat: Level Change [96]
TobEx fixes a bug so that a net negative level will limit to 0 rather than wrap to 100

#97 (0x061) Stat: Strength-Bonus Modifier [97]
TobEx fixes a bug so that a net negative strength extra value will limit to 0 rather than wrap to 100

#98 (0x062) HP: Regeneration [98]
TobEx fixes a bug with the regeneration opcode where a creature with multiple instances of disease, poison, wing buffet, regeneration and/or repeating effect opcodes would only have the highest frequency instance applied

#106 (0x06A) Stat: Morale Break Modifier [106]
TobEx fixes a bug so that an out of bounds morale break value will limit to 0 or 255 rather than wrap around

#108 (0x06C) Stat: Reputation [108]
TobEx fixes a bug so that an out of bounds reputation value will limit to 0 or 255 rather than wrap around

#119 (0x077) Spell Effect: Mirror Image [119]
Option: TobEx gives the option of modifying the mirror image effect opcode to keep caster level, so that dispel magic will work on it

#135 (0x087) Graphics: Polymorph into Specific [135]
TobEx fixes a bug with parameter 2 values of 1 (Appearance only) where changes to the character's colour would either not work, or revert back to normal colours on refreshing the character. The Use EFF File opcode is fixed to prevent stuttering associated with using Polymorph opcode as a child effect.

#144 (0x090) Button: Disable Button [144]
TobEx adds parameter 2 values 10 and 14. The button disabled states are tied to new hard-coded STATS.IDS opcodes 308-322, inclusive. Also refer to the Scripting Stats section.
Parameter #1: Irrelevant
Parameter #2: Button
Description:
Disabled the button specified by the 'Button' field.
Known values for 'Button' are:

0 Stealth Button
1 Thieving Skill Button
2 Spell Select Button
3 First Quick Spell Button
4 Second Quick Spell Button
5 Third Quick Spell Button
6 Turn Undead Button
7 Talk Button
8 Use Item Button
9 First Quick Item Button
10 Bard Song Button
11 Second Quick Item Button
12 Third Quick Item Button
13 Innate Ability Button
14 Find Traps Button

#147 (0x093) Spell: Learn Spell [147]
TobEx adds parameter 1 high
Parameter #1 Low: Irrelevant
Parameter #1 High: Flags
Parameter #2: Irrelevant
Description:
The targeted creature(s) tries to learn the spell specified by the resource key.
Learning is successful when 1D100 <= the INT-dependent LEARN_SPELL value in INTBON.2DA.
The LEARN_SPELL value is modified for mage specialists, with +15 for same school spells, and -15 for non-same school spells.
The 'Flags' field modifies the behaviour of the effect in the following manners:

Bit 0: Learning the spell never gives experience (including scrolls from the inventory screen)
Bit 1: No effect (reserved for GemRB)
Bit 2: Learning is always successful (including scrolls from the inventory screen)
Bit 3: No effect (reserved for GemRB)
Bit 4: If the spell is already learnt, no experience is given (excludes inventory screen)
Bit 5: Learning the spell obeys mage school exclusions (excludes inventory screen)
Bit 6: The spell cannot be learnt by sorcerer class (excludes inventory screen)
Bit 7: Learning fails if the target has already learnt the maximum number of spells as per INTMOD.2DA for the spell's level (excludes inventory screen)

#164 (0x0A4) Cure: Drunkeness [164]
TobEx fixes this effect opcode so that it correctly removes the Drunkenness effect opcode

#166 (0x0A6) Stat: Magical Resistance Modifier [166]
TobEx fixes the effect opcode behaviour for permanent until death timing and adds parameter 2 value 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Instantaneous Cumulative Modifier -> Value = Value + 'Statistic Modifier' value
1 Flat Value Modifier -> Value = 'Statistic Modifier' value
2 Percentage Modifier -> Value = (Value * 'Statistic Modifier' value) / 100
3 Cumulative Modifier -> Value = Value + 'Statistic Modifier' value

For a non-permanent timing, the instantaneous cumulative modifier immediately adds the 'Statistic Modifier' value, unlike the cumulative modifier which adds the 'Statistic Modifier' after all effects are applied. The former has the disadvantage that it will be overriden by any subsequent flat value modifiers. Percentage modifiers override all other modifiers.

#173 (0x0AD) Stat: Set Poison Resistance [173]
TobEx adds paramter 2 values 1 to 3
Parameter #1: Statistic Modifier
Parameter #2: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field.
Known values for 'Type' are:

0 Flat Value Modifier -> Value = 'Statistic Modifier' value
1 Cumulative Modifier -> Value = Value + 'Statistic Modifier' value
2 Percentage Modifier -> Value = (Value * 'Statistic Modifier' value) / 100
3 Instantaneous Cumulative Modifier -> Value = Value + 'Statistic Modifier' value

Note that the 'Percentage Modifier' type (2) is applied before the 'Cumulative Modifier' types (1) are applied.

#177 (0x0B1) Use EFF File [177]
TobEx fixes this effect opcode so that adjustments to child effect parameters 1 to 4 are saved in unused internal structures of this opcode and restored to the child effect on next application. This fixes stutter issues associated with the Polymorph (parameter 2 value 1) opcode and is required for the changes to the Dexterity Modifier (parameter 2 value 3), Poison, Strength Modifier (parameter 2 value 3), Disease, Regeneration, and Apply Repeating EFF opcodes to work correctly when used as child effects of this effect.
TobEx also fixes memory deallocation issues associated with containers and doors that use this effect opcode in their trap scripts

#181 (0x0B5) Item: Can't Use Itemtype [181]
TobEx fixes this effect opcode so that it works correctly when parameter 2 is non-zero

#182 (0x0B6) Item: Apply Effect Item [182]
TobEx restores the function of this effect opcode
Parameter #1: Undetermined
Parameter #2: Undetermined
Description:
Applies the effect specified by the resource 2 key to the targeted creature(s) when an item specified by the resource key is equipped. Due to the use of the resource 2 key, this effect must be used in an EFF file.
Limitations: the effect is applied again if an already equipped matching item is used to force-attack a target via the quickbar.

#183 (0x0B7) Item: Apply Effect Itemtype [183]
TobEx restores the function of this effect opcode
Parameter #1: String Reference
Parameter #2: Type
Description:
Applies the effect specified by the resource key to the targeted creature(s) when an item of the item type specified by the 'Type' field is equipped. The 'String Reference' field is currently unused.
Limitations: the effect is applied again if an already equipped matching itemtype is used to force-attack a target via the quickbar.

#191 (0x0BF) Spell: Casting Level Modifier [191]
TobEx made no direct changes to this effect opcode. However, TobEx applies the stats CASTINGLEVELBONUSMAGE and CASTINGLEVELBONUSCLERIC modified by this effects opcode to spells being cast. These stats were previously unused.

#218 (0x0DA) Protection: Stoneskin [218]
Option: TobEx gives the option of removing the grey colour change to a character who applies this effect opcode.

#232 (0x0E8) Spell Effect: Cast Spell on Condition [232]
TobEx adds parameter 2 high
Parameter #1: Target
Parameter #2 Low: Condition
Parameter #2 High: Trigger Check Period
Description:
Casts the spell specified by the resource field on the target specified by the 'Target' field, when the condition from the 'Condition' field is true. The conditions are akin to various triggers.
The trigger check period field specifies how often (in ticks) the condition is checked. If set to 0, the trigger check period is set to the game default of 100 ticks.
Known values for 'Target' are:

0 Effect Target
1 LastHitter
2 NearestEnemyOf
3 Nearest

Known values for 'Condition' are:

0 HitBy()
1 See(NearestEnemyOf())
2 HPPercentLT(Myself 50)
3 HPPercentLT(Myself 25)
4 HPPercentLT(Myself 10)
5 StateCheck(Myself,STATE_HELPLESS) i.e. unconscious
6 StateCheck(Myself,STATE_POISONED) i.e. poisoned
7 AttackedBy('Target')
8 PersonalSpaceDistance('Target',4)
9 PersonalSpaceDistance('Target',10)
10 Unknown - every round
11 TookDamage()

A non-zero Parameter 3 Low value activates the portrait icon, immediately triggers the HitBy() trigger, and prevents purging of the conditional spell after the condition is true.
Parameter 3 High is reserved for internal use (specifies that Parameter 4 has been set).
Parameter 4 is reserved for internal use (set to the game time when the effect is first applied).

#233 (0x0E9) Stat: Proficiency Modifier [233]
TobEx adds parameter 2 high
Parameter #1: Amount
Parameter #2 Low: Type
Parameter #2 High: Behaviour
Description:
Applies 'Behaviour' to the weapon proficiency points for the weapon type specified in the 'Type' field with the value specified by the 'Amount' field, for the targeted creature(s).
Values for 'Behaviour' are:

0 Set proficiency 'Type' to 'Amount' only if 'Amount' is higher than the current proficiency points
1 Proficiency points of 'Type' = Proficiency points of 'Type' + 'Amount' (applied after all of Behaviour 0)

Known values for 'Type' are:

Axe | 92
Bastard Sword | 89
Blackjack | 108
Club | 115
Crossbow | 103
Dagger | 96
Darts | 106
Flail/Morningstar | 100
Gun | 109
Halberd | 99
Katana | 94
Long Bow | 104
Long Sword | 90
Mace | 101
Martial Arts | 110
Quarter Staff | 102
Scimitar/Wakizashi/Ninja-To | 95
Short Bow | 105
Short Sword | 91
Single Weapon Skill | 113
Sling | 107
Spear | 98
Sword and Shield Skill | 112
Two-Handed Sword | 93
Two-Handed Weapon Skill | 111
Two Weapon Skill | 114
War Hammer | 97
Extra Proficiency 2(Unused) | 116
Extra Proficiency 3(Unused) | 117
Extra Proficiency 4(Unused) | 118
Extra Proficiency 5(Unused) | 119
Extra Proficiency 6(Unused) | 120
Extra Proficiency 7(Unused) | 121
Extra Proficiency 8(Unused) | 122
Extra Proficiency 9(Unused) | 123
Extra Proficiency 10(Unused) | 124
Extra Proficiency 11(Unused) | 125
Extra Proficiency 12(Unused) | 126
Extra Proficiency 13(Unused) | 127
Extra Proficiency 14(Unused) | 128
Extra Proficiency 15(Unused) | 129
Extra Proficiency 16(Unused) | 130
Extra Proficiency 17(Unused) | 131
Extra Proficiency 18(Unused) | 132
Extra Proficiency 19(Unused) | 133
Extra Proficiency 20(Unused) | 134

Standard Throne of Bhaal proficiencies are limited to a maximum of 5 stars.

#238 (0x0EE) Death: Disintegrate [238]
TobEx fixes a memory leak associated this effect opcode

#272 (0x110) Spell: Apply Repeating EFF [272]
TobEx fixes a bug with the repeating effect opcode where a creature with multiple instances of disease, poison, wing buffet, regeneration and/or repeating effect opcodes would only have the highest frequency instance applied

#273 (0x111) Remove: Specific Area Effect(Zone of Sweet Air) [273]
TobEx adds parameter 1 value 1
Parameter #1: Mode
Parameter #2: Undetermined
Description:
If Mode is not 1, removes projectiles listed in clearair.2da and smoke of animation ID 0x5*0 (standard behaviour).
If Mode is 1, removes projectiles and smoke animations listed in the 2da resource specified in the Resource field.
If the custom resource is invalid, standard behaviour occurs as if Mode is 0.
The recommended format of the custom 2da resources are as follows:

2DA V1.00
*
| Projectile Number | Smoke Animation
<PROJECTILE_NAME> | 94 | * | //for projectile only
<PROJECTILE_NAME> | * | 0X0500 | //for smoke animation only
<PROJECTILE_NAME> | 186 | 0X0600 | //for projectile and smoke animation

Note that the smoke animation ID must be specified in hexadecimal, with capital X and must be 4 hexadecimal digits.
The third digit of the target smoke animation ID is ignored, e.g. 0X0500 will remove smoke animation IDs 0x05*0.

#279 (0x117) Button: Enable Button [279]
TobEx adds parameter 2 values 10 and 14. The button disabled states are tied to new hard-coded STATS.IDS opcodes 308-322, inclusive. Also refer to the Scripting Stats section.
Parameter #1: Irrelevant
Parameter #2: Button
Description:
Enables the button specified by the 'Button Type' field.
Known values for 'Button' are:

0 Stealth Button
1 Thieving Skill Button
2 Spell Select Button
3 First Quick Spell Button
4 Second Quick Spell Button
5 Third Quick Spell Button
6 Turn Undead Button
7 Talk Button
8 Use Item Button
9 First Quick Item Button
10 Bard Song Button
11 Second Quick Item Button
12 Third Quick Item Button
13 Innate Ability Button
14 Find Traps Button

#298 (0x12A) Cutscene 2 [298]
TobEx adds parameter 1 and parameter 2 value 1
Parameter #1: Store party location behaviour
Parameter #2: Script
Description:
Starts a cutscene.
Values for 'Store party location behaviour':

0 Use list specifically for pocket plane
1 Use list normally used by StorePartyLocations() action - restore with RestorePartyLocations() action
2 Do not store party locations

Values for 'Use custom script':

0 Use cut250a.bcs
1 Use cutscene script specified by the Resource field

#303 (0x12F) Spell Effect: Backstab On Condition [303]
TobEx adds parameter 2 values 2 and 4
Parameter #1: Irrelevant
Parameter #2: Type (bitfield)
Description:
The targeted creature(s) will backstab on the conditions set by the 'Type' field.
Known values for 'Type' are:

0 Normal conditions (attacker must be invisible, attacker must be in 90-degree arc behind victim)
1 Ignore invisible requirement and positioning requirement
2 Ignore invisible requirement only
4 Ignore positioning requirement only

#318 (0x13E) Stat: Set Stat [318]
New
Parameter #1: Statistic Modifier
Parameter #2 low: Stat Opcode
Parameter #2 high: Type
Description:
Applies the modifier value specified by the 'Statistic Modifier' field in the style specified by the 'Type' field to the opcode specified by the 'Stat Opcode' field.
Known values for 'Type' are:

0 Cumulative Modifier -> Value = Value + 'Statistic Modifier' value
1 Flat Value Modifier -> Value = 'Statistic Modifier' value
2 Percentage Modifier -> Value = (Value * 'Statistic Modifier' value) / 100
3 Multiplicative Modifier -> Value = Value * 'Statistic Modifier' value
4 Divisive Modifier -> Value = Value / 'Statistic Modifier' value
5 Modulus Modifier -> Value = Value % 'Statistic Modifier' value
6 Logical AND Modifier -> Value = Value && 'Statistic Modifier' value
7 Logical OR Modifier -> Value = Value || 'Statistic Modifier' value
8 Bitwise AND Modifier -> Value = Value & 'Statistic Modifier' value
9 Bitwise OR Modifier -> Value = Value | 'Statistic Modifier' value
10 Inverse Modifier -> Value = !Value

You cannot set any stats with opcode < 387 with this effect. New stats 202-400 are reserved for new hard-coded stats.
Modmakers can set the damage type percentage modifiers and weight allowance modifiers using this effect opcode. Also refer to the Scripting Stats section.

## Items

TobEx makes the following changes to the ITM V1.0 file format.

### Header

Offset | Description
0x0018 (dword) | Flags bit 24: not dispellable in magical weapon slot bit 25: toggle critical hit aversion

### Extended Header (Ability)

Offset | Description
0x0026 (dword) | Flags bit 25: toggle backstab restrictions bit 26: cannot target invisible

### Feature Block (Effect)

Offset | Description
0x0024 (dword) | Flags bit 24: bypass mirror images bit 25: limit effect stacking bit 26: internal: suspend effect application
0x002c (dword) | Special Vanilla: Used only for Set Local Variable when the variable is non-existant Stacking ID when bit 25 of 'Saving throw type' is enabled

## Spells

TobEx makes the following changes to the SPL V1.0 file format.

### Header

Offset | Description
0x0018 (dword) | Flags bit 24: can target invisible bit 25: can be cast when silenced

### Feature Block (Effect)

Offset | Description
0x0024 (dword) | Flags bit 24: bypass mirror images bit 25: limit effect stacking bit 26: internal: suspend effect application
0x002c (dword) | Special Vanilla: Used only for Set Local Variable when the variable is non-existant Stacking ID when bit 25 of 'Saving throw type' is enabled

## Stores

TobEx makes the following changes to the STO V1.0 file format.

### Header

Offset | Description
0x0010 (dword) | Flags bit 14: toggle recharge