User:JRoush

Revision as of 16:52, 17 July 2010 by imported>JRoush (→‎Encumbrance)

Notes on Scripting

General Scripting

Adding or removing (possibly any modifying of) effects in an enchantment (or, presumably, a spell) that is currently affecting an actor results in CTD. Instead, we must cloneform the enchantment and use that instead. Previous testing gives me hope that the game might garbage collect unused formids.

Modifications to non-cloned forms (e.g. changes to name, etc) do not appear to stick upon reloading the game. Dynamically generated spells must be cloned, or else the base forms modified in script every time the game is reloaded.

Cloned forms are not removed when the mod is deactivated. Since there is no way for the average player to remove cloned spells from spell merchants, a "cleanup" script must be provided to do so. - makes the whole use of cloned spells unattractive -

GetOwner appears to work only on references (not items in a container). There is a stolen flag, I believe, but not sure how to set it.

Moveto and PositionCell don't transfer meshes. the 'usual' workarounds assume transfer to the current cell, and don't work for destination cells that aren't loaded.

Using GetIconPath on an object with no icon causes a CTD.

Menu Scripting

Traits of the form <user#> are parameters set by the game enigne. The visible manifestations (text, slider position, etc.) are usually set to derive from these inputs. As of OBSE v0017 modifying most traits from scripts will destroy derivative relationships; it appears that some values (e.g. quantity slider traits) are safe to modify. Modifying the <user#> traits directly one can "fake" user input; in particular spell/potion names and slider bar positions. Derivative relationships are reloaded when the menu is. Note that the HUD (and possibly the inventory) reloads only after exiting to the main menu; changes to the HUD will persist until then.

The Arrow + Enter keys can normally be used to navigate menus. I haven't found (or seriously looked for) a way to determine which tile is the focus of a keyboard event. It looks like the focus is *either* keyboard or mouse based, and transitions from one to the other are inconsistent or bugged. At any rate, OBSE v0017 GetActiveUIComponent* functions work only for tiles focused on by the mouse. Also, arrow+enter menu navigation is NOT based on mapped controls and cannot be disabled using Disablekey. It CAN be disabled by removing all traits of the form <xbutton>, <xleft>, <xright>, etc. from the menu in question, but not by simply setting them to zero in scripts. This is a problem because an errant keystrokes can apparently derail a ClickMenuButton call, which makes setting up long chains of automated click events unfeasible.

The GetCursorPos function is a bit dodgy. Returned positions are not consistent, and seem to depend on integrated movement history. This, combined with the lack of a function to get screen resolution, makes it impractical for use in menus (specifically, I couldn't use it to script in a custom slider bar).

General Actor Value Mechanics

There are six factors that contribute to an Actor Value:

  • Base - the AV value from the Actor's base form - all instances of the actor share this value (e.g. all guards share the same Base Health). This factor is set by the designer in the CS. It is modified in-game by the SetAV console+script commands, and by 'recoverable' effects on Ability-type spells.
  • Calculated Base - the contribution to an AV from other AVs and game settings. For example, the Calculated Base for the player's Health is fPCBaseHealthMult * Endurance. This factor is nonzero only for the player character - NPC and Creature health, to use the same example, do not depend on their endurance.
  • Calculated Multiplier - a multiplier to the AV from other AVs and game settings. This factor is almost always 1.0; the exception is the Magicka Multiplier for the player character.
  • Max Modifier - for Actors with middle process or higher. This factor is modified by 'recoverable' effects such as Fortify,Drain,Feather,etc on non-Ability-type spells.
  • Offset Modifier - for all Actors. This factor is doesn't seem to be used by the combat or magic systems. It is modified only by the ModAV and ForceAV script commands (not the console versions).
  • Damage Modifier - for Actors with low process or higher. This factor is modified by the ModAV and ForceAV console commands, by direct damage from combat, falling, lava, etc., and by 'nonrecoverable' effects like Damage & Restore. It is intended only for negative values; any change that would increase it above zero sets it to zero instead.

There are three different 'versions' of an Actor Value that play a role in Oblivion:

Calculated Base Value = (Base + Calculated Base) * (Calculated Multiplier)
    Maximum Value     =  Calculated Base Value + Max Modifier
    Current Value     =  Maximum Value + Offset Modifier + Damage Modifier
  • Calculated Base Value - returned by the GetBaseAV console+script commands. This value is used to check mastery level in a skill, and (for Alchemy) to compute player-created potion strength.
  • Maximum Value - the "full health" value shown for the players Health, Magicka, and Fatigue, both in the menu and in the HUD.
  • Current Value - returned by the GetAV console+script commands. This is the value used for the vast majority of AV checks. It is the value shown for the players stats in the menu.

Notes:

  • These formulas do not apply to Fame,Infamy,Bounty,or Encumbrance. These AVs are calculated differently, and stored differently as well.
  • When player stats are displayed in the menu, they are shown as green if the Current value is greater than the Calculated Base value, red if the Current value is less than the CBV, and blue if the two are equal. The exception is the players Health, Magicka, and Fatigue, where the comparison is between the Maximum value and the CBV.
  • Since the Offset modifier is not affected by ordinary damage or magic, changes to it cannot be undone by restoration spells or chapel healing, etc.
  • The Damage modifier is always negative or zero, but the Offset modifier can be positive, so it can be used to make the Current value greater than the Maximum value. This isn't seen in game simply because nothing ever uses the Offset modifier.
  • Recoverable effects on Ability-type spells apply directly to the Base factor, which is a property of the actor's base form. This means that these effects become common to all instances of the actor. So, for example, applying a 'Fortify Health' ability on one guard will give all guards of that type the same health bonus. This isn't often a problem since one doesn't usually "cast" abilities on a specific target.

Encumbrance

Encumbrance is calculated and displayed differently from other actor values.

  • The Base factor is ignored entirely. It is not used in calculation, and cannot be altered by the SetAV command or any magical means. However, it is still included in the return value of the GetBaseAV command, making this command effectively useless.
  • The Calculated Base is the total encumbrance bonus from strength. Unlike most calculated factors, this applies to all actors, not just the player.
  • The Maximum Value and Current Value are calculated differently:
Modifier Sum = (Max Modifier + Offset Modifier + Damage Modifier)

if (Modifier Sum < 0) :

  Maximum Value = Calculated Base - Modifier Sum
  Current Value = Carried Weight

if (Modifier Sum > 0) :

  Maximum Value = Calculated Base
  Current Value = Carried Weight + Modifier Sum

For this reason, the Current encumbrance of an actor will never be less than their total carried weight, and the Maximum encumbrance will never be less than the value calculated from their strength.

  • The GetAV command does not return the Current Value, but rather the sum of carried weight and all modifiers, even if the sum of the modifiers is negative:
 GetAV Return Value = Carried Weight + Modifier Sum

This means that GetAV will return the wrong value if the actor is currently subject to enough effects that reduce encumbrance (e.g. Feather).