Research:Magic

Comments
The cast chance calculation is used in multiple places, some where magicka use may not be important, so there is a, which is normally true for casting/AI use and the inventory spell list, and false for all other UI uses of spell chance. The function returns the weakest school used out of all the effects, which is the skill that will gain progress when the spell is cast. Note that spells that are marked "always succeed" do not seem to contribute to skill progress.

Cast cost
Casting cost is an independent variable in the spell data. For spellmaker generated spells, refer to Spell merchant. Failed casts still incur all costs.

Casting incurs a fatigue hit. which is how Morrowind behaves but is clearly incorrect; a fixed formula is

The GMST fFatigueSpellCostMult is unused.

Comments
Note that this punishes casting difficult (low cast chance) spells versus high willpower enemies. The castChance scaling will go almost guarantee resists if castChance < 25%.

Has an interesting situation, where spells with magnitude _do_ take resistance from willpower but at a very low rate (0.01x due to lack of rescaling) than would be expected, making willpower resistance almost useless for that class of spells.

The way resistance affects the final attribute, is that magnitude is stored untouched, resistance is stored with the active effect, and resistance is applied every time the spell has an application tick. The outward effect is that spell effect tooltips list the original magnitude, without factoring resistance.

Using enchanted items
This makes items last 10 times longer at 100 enchant compared to 10 enchant, making it scale a little too well. MCP uses x = 0.025 * (400 - pcEnchant).

Natural recharge
Every item in the player's inventory charges by tickTime * fMagicItemRechargePerSecond. Items anywhere else do not charge.

Soulgem charging
Refer to Player Craft Skills.

Magic effects
Spells are combinations of one or more effects, which have associated code specific to the effect, and properties which cover cast ranges, resistances and other generalized behaviours that may be shared by a small set of effects.

Effect attributes
All actors have "hidden" attributes that effects apply to, to allow effects to stack, have resistance applied and counteract each other. These attributes are saved with actors, appearing in the actor data in the same order. All effect attributes are applied and stored as integers. Resists and weaknesses are unified under the Resist- attributes, with resistances being positive and weaknesses being negative. Non-magnitude spells have an effective attribute of 1 when active.

Some attributes provide resistance values vs magic effects when calculating magic mitigation. These resistances only apply in certain cases, check magic resistance.

Effect flags
These are fixed properties of magic effects. Obtained from the code, these are not affected by mods.

Flags for all effects:

int effectFlags[] = { 0x11c8, 0x11c0, 0x11c8, 0x11e0, 0x11e0, 0x11e0, 0x11e0, 0x11d0, 0x11c0, 0x11c0, 0x11e0, 0x11c0, 0x11184, 0x11184, 0x1f0, 0x1f0, 0x1f0, 0x11d2, 0x11f0, 0x11d0, 0x11d0, 0x11d1, 0x1d2, 0x1f0, 0x1d0, 0x1d0, 0x1d1, 0x1f0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x1d0, 0x1d0, 0x11c8, 0x31c0, 0x11c0, 0x11c0, 0x11c0, 0x1180, 0x11d8, 0x11d8, 0x11d0, 0x11d0, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11c4, 0x111b8, 0x1040, 0x104c, 0x104c, 0x104c, 0x104c, 0x1040, 0x1040, 0x1040, 0x11c0, 0x11c0, 0x1cc, 0x1cc, 0x1cc, 0x1cc, 0x1cc, 0x1c2, 0x1c0, 0x1c0, 0x1c0, 0x1c1, 0x11c2, 0x11c0, 0x11c0, 0x11c0, 0x11c1, 0x11c0, 0x21192, 0x20190, 0x20190, 0x20190, 0x21191, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x1c0, 0x11190, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x11c0, 0x1180, 0x1180, 0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x1188, 0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x1048, 0x104c, 0x1048, 0x40, 0x11c8, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048 };