Jump to content

kjeron

Members
  • Posts

    485
  • Joined

  • Last visited

Everything posted by kjeron

  1. It had no standards - spell descriptions were copied straight from their source material. In game it ranged from 3.57 units per foot, to 28.57 units per foot, but most often around 8.5 units per foot, which was still wrong. The descriptions have mostly been fixed in the EE's, albeit with some rounding. 16 horizontal pixels = 1 foot 12 vertical pixels = 1 foot Projectile trap/explosion size is based on horizontal distance, 16 = 16h pixels = 1 foot radius 80 = 5' radius 256 = 16' radius 448 = 28' radius (max engine can handle for repeating AoE's) 480 = 30' radius Visual/Script Range = 448h/336v pixels (28 feet) (I don't know why it's often listed as 30') Spellcasting Range = 16h/12v pixels (1 foot) per unit Opcode 262 (Visual Range) = 32h/24v pixels (2 feet) per unit The one thing that is 30' (480h/360v pixels) is PC movement rate per round, at least in original BG1, BG2 bumped it up by 50% to 45' per round.
  2. In that case: You can get more slots per stat if you store the slots as an integer rather than actual bits, using 4 bits you can get 15 spell slots (should be enough per level I think), so your first one would be best, using relation #7 (binary more or equal - contains all bits of value) Repeated spell: (level 1) 172 - remove innate ability Z 326 - if stat bit more or equal (1 << 8) then cast subspell A 326 - if stat bit more or equal (2 << 8) then cast subspell A 326 - if stat bit more or equal (3 << 8) then cast subspell A 326 - if stat bit more or equal (4 << 8) then cast subspell A 326 - if stat bit more or equal (5 << 8) then cast subspell A 326 - if stat bit more or equal (6 << 8) then cast subspell A 326 - if stat bit more or equal (7 << 8) then cast subspell A 326 - if stat bit more or equal (8 << 8) then cast subspell A 326 - if stat bit more or equal (9 << 8) then cast subspell A 326 - if stat bit more or equal (10 << 8) then cast subspell A 326 - if stat bit more or equal (11 << 8) then cast subspell A 326 - if stat bit more or equal (12 << 8) then cast subspell A 326 - if stat bit more or equal (13 << 8) then cast subspell A 326 - if stat bit more or equal (14 << 8) then cast subspell A 326 - if stat bit more or equal (15 << 8) then cast subspell A Subspell A: 171 - give innate ability Z Repeated spell: (level 2) 172 - remove innate ability Z2 326 - if stat bit more or equal (1 << 12) then cast subspell A2 326 - if stat bit more or equal (2 << 12) then cast subspell A2 326 - if stat bit more or equal (3 << 12) then cast subspell A2 326 - if stat bit more or equal (4 << 12) then cast subspell A2 326 - if stat bit more or equal (5 << 12) then cast subspell A2 326 - if stat bit more or equal (6 << 12) then cast subspell A2 326 - if stat bit more or equal (7 << 12) then cast subspell A2 326 - if stat bit more or equal (8 << 12) then cast subspell A2 326 - if stat bit more or equal (9 << 12) then cast subspell A2 326 - if stat bit more or equal (10 << 12) then cast subspell A2 326 - if stat bit more or equal (11 << 12) then cast subspell A2 326 - if stat bit more or equal (12 << 12) then cast subspell A2 326 - if stat bit more or equal (13 << 12) then cast subspell A2 326 - if stat bit more or equal (14 << 12) then cast subspell A2 326 - if stat bit more or equal (15 << 12) then cast subspell A2 Subspell A2: 171 - give innate ability Z2
  3. More or less yes. Another way around this would be to run all such increments through the same "parent" resource, and just have the "morning reset" remove all effects of that resource, while retaining the base increment for total slots. CLAB applies Increment (1 << 8) or appropriate bit for each level, for each new spell "slot". Each spell does casting-effect bitwise check (any one of): "row stat 0xfffff1ff 10" = Can still cast after this spell (contains bit not in value) "row stat 0xfffff1ff 6" = Cannot cast more after this spell, remove selection ability (doesn't contain bit not in value) Casting spell applies (resource) to decrement (1 << 8), or appropriate bit for it's level. Morning Reset removes effects by (resource), restores all selection abilities. One thing about the "Set"/"Increment": Some opcodes (such as modify proficiency) do not apply their "Increment" mode effects until all other effects in the stack have processed their checks, which is why the above bitwise check if the value is greater than "1", not "0" - decrementing the proficiency before the check would not make any difference. (This behavior is dependent on the opcode used, but I believe it is exclusive to "Increment" modes, and that any "Set" modes are always instant).
  4. Well, the corresponding SPIN###/SPCL### might already be in use. The new spell would get checked in dialogues that were written with labels, but not indexes, and scripts would continue to check/cast the old spell unless you updated them as well. But why do you need an SPIN/SPCL prefix for the EE? Every relevant action/trigger except "HaveSpellParty()" has a RES variant, and it can be replicated with 6x "HaveSpellRES()".
  5. There are also Bows, Daggers, and Darts, which naturally grant 2-3 APR, but would be overridden by the spell.
  6. Instantaneous 206/318/321/324 need altering to new filename on the new spell. Durational 206/318/321/324 need cloning to new filename on the new and old spell. Entries in 7eyes.2da need to be cloned for the new filename.
  7. SPWI[LEVEL][01-50].spl All spells that follow that naming format are picked up by the engine to be selected by mages/sorcerers, minus those listed as IS_HIDDEN in "HIDESPL.2da". Spell type doesn't even matter - the game will let you pick priest/innate spells if they are named as such (they won't work, but it still lets you).
  8. It's still best to stick to 7-character filenames for most spells, reserving 8-character names for those generated by hard-coded suffixes, both so they can exist, and so they do not overlap. Opcode 257 still requires a 7-character filename in order to grant it's activation abilities, suffixed -D and -P.
  9. The Thief Skill multipliers (Scripting States) are no longer used. The extra proficiency stats are still used, despite almost all of them now applying Spellstates as well.
  10. Are you sure you weren't taking the delayed damage from a previous un-evaded arrow? If I set the characters Breath Save to 0/1, it becomes 100% consistent for both spells.
  11. The cap is not present in EE patch 2.5. Tested with See() trigger and visual range set to 100 with this opcode. There is still a limit applied to fog of war exposure by this opcode (0-23).
  12. Immunity to SPELLA is applied regardless of current mana. The very first time it triggers will be instant, but afterwards it would only occur if the timer (2400 / ((2+CHA)*level)) had already expired. In that case having it cast SPELLA is probably correct. Also a correction on SPELLB## these lines should be specifying SPELLC: Cast Spell #146 (value: (2+CHA modifier), type: instantly at level) => (SPELL D) -> Cast Spell #146 (value: (2+CHA modifier), type: instantly at level) => (SPELL C)
  13. Yes, splitting it into separate spells would be better than hundreds/thousands of splprot entries, and should work, one way or another. SPELLA: As is but without: Protection From Spell #206 => (SPELL D) // This is taken care of in SPELLB## For SPELLB##: (all minlvls) Cast Spell #146 (instantly) => (SPELL D)(min lvl: 1) Immunity Spell #318 (value: 0, type: 0) (duration 2400/(2+CHA modifier)-1) => (SPELL A) Immunity Spell #318 (value: (2+CHA modifier), type: STAT 116 < -1 splprot row) => (SPELLB##) Cast Spell #146 (value: (2+CHA modifier), type: instantly at level) => (SPELL D) (min lvl: 2) Immunity Spell #318 (value: 0, type: 0) (duration 2400/(2+CHA modifier)*2-1) => (SPELL A) Immunity Spell #318 (value: (2+CHA modifier)*2, type: STAT 116 < -1 splprot row) => (SPELLB##) Cast Spell #146 (value: (2+CHA modifier)*2, type: instantly at level) => (SPELL D) (min lvl: 3) Immunity Spell #318 (value: 0, type: 0) (duration 2400/(2+CHA modifier)*3-1) => (SPELL A) Immunity Spell #318 (value: (2+CHA modifier)*3, type: STAT 116 < -1 splprot row) => (SPELLB##) Cast Spell #146 (value: (2+CHA modifier)*3, type: instantly at level) => (SPELL D) (...) SPELLC: (If we are or would go over maximum mana, remove all modifiers and reset current = maximum, cleans up accumulating effects) (for all min lvls) Remove Effects by Resource #321: => (SPELLC) // Remove Increments (over time) Remove Effects by Resource #321: => (SPELLD) // Remove Reset (this one) Remove Effects by Resource #321: => (SPELLE) // Remove Decrements (from casting) (SPELL6 in my first post) Proficiency Modifier #233 (value: min lvl, type: 116, Increment) // FYI minlvl is not capped at either 50 or 255 when set using the "Cast at Level" opcodes, if you need higher values. SPELLD: Don't need the Cast SpellA, it will already be cast every round. Use opcode 318 instead of 324 - the latter will flood the combat log with feedback messages about "Unaffected by effects from <RESOURCE>".
  14. Only if the projectile used by the subspell's effects is instant-hit (uses projectile 0, 1, or a similar custom projectile).
  15. Yes Hence "hijack". Everyone one of those stats can be better represented by a Spellstate in the EE's, and some already are. Continuing to use them for spell detection in the EE is nothing but wasteful. You could also use the upper bytes of actual proficiency stats, though it makes the splprot lines a bit more complicated. It's a complex mix of "use two rows of splprot.2da", except it's really a "NOT(rowX or rowY)", so both would actually check the opposite of what's intended, in that particular example: RowX = charisma > 15 RowY = Stat116 < level*14+1 RowZ = NOT (RowX or RowY)
  16. Multiply Mana Points per spell/level/charisma x8, so the 12.5% can work without rounding issues. No need for separate Sorcerer versions, effects can be filtered to sorcerers through opcode 177/326. If you want to avoid scripting, hijack a proficiency stat. In theory: (SPELL1) Use EFF (EFF2) Use EFF (EFF1) (EFF2) Cast spell on Condition (hp>102%) (SPELL3) (EFF1) Cast spell on Condition (hp>102%) (SPELL2) (SPELL2) (SPELL3) (SPELL4) (SPELL5) Global Effects for each wizard spell: Apply Effects List (CLASS=SORCERER) (SPELL6%spelllevel%) (SPELL6) Modify Proficiency (-level*8, 116, Increment) Cast Spell (SPELL2) (SPELL61)Cast spell at level (1) (SPELL6)(SPELL62)Cast spell at level (2) (SPELL6)(SPELL63)Cast spell at level (3) (SPELL6)etc...
  17. That looks like IWD2 - it's damage opcode is setup differently from every other game. I think the closest you'll get there is: Opcode 17: -XX% Opcode 12: 1 damage - to properly "kill" targets. Any valid type will do, damage reduction will not block the death.
  18. Area of Effect is defined by the projectile. The projectile in SPWI507 (HOLD.pro) hits every (enemy) creature within (vanilla is 4 feet, don't know SR's value). The effects of SPWI507 (Cast Spell) is applied to every creature hit by the projectile, casting SPWI507D on each target individually. This particular spell has no primary/secondary targets, everyone is equal. For the purpose of Spell Deflection, if the save were on the parent spell, the target would get to save against the spell before spell deflection was checked, saving them deflection charges if they were successful, which would be inconsistent with how single target spells work.
  19. Every vanilla spell is setup this way, it is the only way to have multiple effects offer differing save bonuses/types. All effects, regardless of source, use the same savingthrow roll, for any given moment. As long as the effects are applied at the same time, they will use the same save roll. Delayed effects are saved against when they are initially applied, not when their delay expires. It's identical to seeing only a single instance of Magic Resistance against 5x Magic Missiles(occasionally, they don't always hit at the same time), or a single save against a 3x of the same spell in a chain contingency. Auto-pause can disrupt this and other internal game mechanics, so it's best to never use the "Hit", "Injured", "Death", or "Spell Cast" auto-pause options.
  20. All Objects and Triggers are in relevance to the effect target of opcode 232. For parameter1: // Cast Resource on Object: 0 : Myself 1 : LastHitter 2 : NearestEnemyOf 3 : NearestNotSelf For Parameter2: // Trigger: 0 : HitBy([ANYONE]) Every time 1 : See(NearestEnemyOf(Myself)) Once per Round 2 : HPPercentLT(Myself, 50) Once per Round 3 : HPPercentLT(Myself, 25) Once per Round 4 : HPPercentLT(Myself, 10) Once per Round 5 : StateCheck(Myself,STATE_HELPLESS) Once per Round 6 : StateCheck(Myself,STATE_POISONED) Once per Round 7 : AttackedBy([ANYONE]) Every time 8 : Range([ANYONE],4) Once per Round 9 : Range([ANYONE],10) Once per Round 11 : TookDamage() Every time 12 : Killed([ANYONE]) Every time 13 : TimeOfDay('Special') Once per Round 14 : Range([ANYONE],'Special') Once per Round 15 : StateCheck(Myself,'Special') Once per Round 16 : Died(Myself) Every time 17 : Died([ANYONE]) Every time 18 : TurnedBy([ANYONE]) Every time 19 : HPLT(Myself,'Special') Once per Round 20 : HPPercentLT(Myself,'Special') Once per Round 21 : CheckSpellState(Myself,'Special') Once per Round The triggers and objects are still limited to their normal detection range, i.e. "Died([ANYONE])" won't see someone dying on the other side of the map. "NearestEnemyOf", and "LastHitter" must be currently valid objects in order to trigger. Excluding the Range() checks, [ANYONE] includes "Myself". The [Resource] is cast using a similar structure to opcode 146[P2=1]: "Self" affects the creature with opcode 232. "Preset" affects the [Object] that [Resource] is cast on. "Original Caster" affects the creature with opcode 232. However, that [Object] must be within range of the [Resource] or the whole spell will fail. edit - this forum butchers formatting.
  21. If I'm understanding you correctly, no, some of them do not function that way. For all: Player A casts SpellA targeting player B SpellA: Ability Target: Living Actor -Effect: Opcode 146, target = (1 or 9), parameter2 = (0 or 1), resource = SpellB SpellB: -Effect: Opcode 12, target = 1(Self) = affects Player A -Effect: Opcode 12, target = 2(Preset) = affects Player A -Effect: Opcode 12, target = 9(Original) = affects Player A SpellA: Ability Target: Living Actor -Effect: Opcode 146, target = 2(Preset), parameter2 = (0 or 1), resource = SpellB SpellB: -Effect: Opcode 12, target = 1(Self) = affects Player A -Effect: Opcode 12, target = 2(Preset) = affects Player B -Effect: Opcode 12, target = 9(Original) = affects Player A While here it does: SpellA: Ability Target: Living Actor -Effect: Opcode 146, target = (1, 2, or 9), parameter2 = 2, resource = SpellB SpellB: -Effect: Opcode 12, target = 1(Self) = affects Player B -Effect: Opcode 12, target = 2(Preset) = affects Player B -Effect: Opcode 12, target = 9(Original) = affects Player A More importantly, for Opcode 146(P2=0/1), Opcode 148(P2=0), regardless of target, the spells are cast at the level of player A(or specified level), and their effects bypasses player A's magic resistance, not Player B's. Targeting playerB with Opcode 148(P2=1), Opcode 258, or Opcode 260, will have the spells cast at the level of player B(or specified level), and their effects bypass player B's magic resistance. Targeting playerB with Opcode 146(P2=2) or Opcode 326, the spells are cast at the level of PlayerA(or specified level), and their effects bypass both players magic resistance. The targeting quirks of AoE's(i.e Sunfire) still take precedence over the above to determine bypassing MR. Opcode 326 also casts spells using the caster level of the calling spell, not the called spell, as other opcodes do. If spellA is innate and spellB is wizard, opcode 326 would cast spellB using character level, not wizard caster level. If spellA is cleric and spellB is wizard, opcode 326 would cast spellB using cleric caster level, not wizard caster level. If spellA is innate and spellB is wizard, opcode 146 would cast spellB using wizard caster level, not character level. If spellA is cleric and spellB is wizard, opcode 146 would cast spellB using wizard caster level, not cleric caster level.
  22. Items that recharge will restore any charges less than that amount. Either by resting, for x per day items, or by selling/re-buying from shops that recharge magical items.
  23. All items have 1 charge by default. Any more must be specified in the CRE/STO/ARE file that contains or the EFF/SPL/BCS/DLG that creates the item.
  24. I've always gotten different results from that: Opcode 146: The source always does the casting. If p2=2 and target=(1 or 9), Source casts spell at "Preset Target" and this effect bypasses targets deflection/reflection effects (though its subspell's effects are still subject). Otherwise, Source casts spell at any/all specified target(s). Opcode 148: The source always does the casting when p2=0, and the spell is cast once for each effect target. The target(s) always does the casting when p2=1. With either p2 value, the spell is always cast at the ability target(point). To compare: Opcode 258 (activate sequencer) The target is always the caster, and is who must have the spells sequenced. Opcode 260 (activate sequencer at point) The target is always the caster, and is who must have the spells sequenced. Opcode 326 (apply effects list) The source always does the casting. Unless target = 2, this effect bypasses targets deflection/reflection effects (though its subspell's effects are still subject). When target=(1 or 9), Source casts spell at "Preset Target". Otherwise, Source casts spell at any/all specified target(s). Delaying the effects can further complicates the identify of "Source" and "target", as they revert to defaults if you save&reload before the delay expires. Using them further in Subspells also complicates the identity of "Source" and "target".
×
×
  • Create New...