Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Dark Dreams of Furiae - a new module for NWN:EE! Buy now
Attention, new and old users! Please read the new rules of conduct for the forums, and we hope you enjoy your stay!

Want to make a custom contingency or sequencer spell? Here's a fix that lets you do that.

OlvynChuruOlvynChuru Member Posts: 2,759
Currently, in BG:EE, BG2:EE, and IWD:EE, if you make a custom contingency or sequencer spell (for example, if you want to be able to store a spell in a Glyph of Warding), when a character casts it, the game will crash when it tries to bring up the spell select menu. The reason is because each contingency/sequencer spell file has a unique description in the menu after you cast it (separate from the normal spell description). These descriptions are hardcoded as far as I know, and if you make a custom contingency/sequencer spell, it won't have a description in the menu, and the game will crash trying to load a description that doesn't exist.

My fix edits UI.menu so that if the game can't find the description of the particular contingency or sequencer your character is casting, it gives it a blank description rather than crashing the game. The fix does not change the unmodded experience of the game at all: if you're casting one of the vanilla contingency/sequencer spells, it will still have the correct description. It simply allows you to create your own contingencies and sequencers without the game crashing.

I have tested my fix in BG:EE, BG2:EE, and IWD:EE, and with both custom sequencers and custom contingencies. In all these cases, without the fix installed, casting a custom contingency/sequencer will cause the game to crash. In all these cases, with the fix installed, casting a custom contingency/sequencer works fine.

The fix is a simple WeiDU program that patches UI.menu rather than overwriting it. You can download it below.

GrammarsaladRavenslight

Comments

  • kjeronkjeron Member Posts: 2,257

    These descriptions are hardcoded as far as I know, and if you make a custom contingency/sequencer spell, it won't have a description in the menu, and the game will crash trying to load a description that doesn't exist.

    Not at all: https://support.baldursgate.com/issues/24579
    All you need is:
    OUTER_SET tip RESOLVE_STR_REF ( "string" ) APPEND ~L_%EE_LANGUAGE%.LUA~ ~uiStrings['%TITLE%'] = "label string"~ APPEND ~L_%EE_LANGUAGE%.LUA~ ~uiStrings['%LABEL%'] = "action string"~ APPEND ~BGEE.LUA~ ~mageBookStrings['%resref%'] = {tip = %tip%, title = '%TITLE%', action = "%LABEL%"} // or // APPEND ~BGEE.LUA~ ~mageBookStrings['%resref%'] = mageBookStrings['SPWI420']~ // or any of the other default sequencer/contingency resrefs, it will share their selection description. Just choose a custom LABEL, TITLE, and resref, and set the variables with custom entries.

    Grammarsalad
  • OlvynChuruOlvynChuru Member Posts: 2,759
    kjeron said:

    These descriptions are hardcoded as far as I know, and if you make a custom contingency/sequencer spell, it won't have a description in the menu, and the game will crash trying to load a description that doesn't exist.

    Not at all: https://support.baldursgate.com/issues/24579
    All you need is:
    OUTER_SET tip RESOLVE_STR_REF ( "string" ) APPEND ~L_%EE_LANGUAGE%.LUA~ ~uiStrings['%TITLE%'] = "label string"~ APPEND ~L_%EE_LANGUAGE%.LUA~ ~uiStrings['%LABEL%'] = "action string"~ APPEND ~BGEE.LUA~ ~mageBookStrings['%resref%'] = {tip = %tip%, title = '%TITLE%', action = "%LABEL%"} // or // APPEND ~BGEE.LUA~ ~mageBookStrings['%resref%'] = mageBookStrings['SPWI420']~ // or any of the other default sequencer/contingency resrefs, it will share their selection description. Just choose a custom LABEL, TITLE, and resref, and set the variables with custom entries.
    Aha! I didn't know that. Though my fix makes it so that you don't have to do that if you don't want it to crash.

  • GrammarsaladGrammarsalad Member Posts: 2,571
    This is awesome! I didn't know something like this was possible...

    Could one of you provide an example, like a glyph of warding that allows you to store a 1st level spell in it?
    *Puppy dog eyes*

  • kjeronkjeron Member Posts: 2,257

    This is awesome! I didn't know something like this was possible...

    Could one of you provide an example, like a glyph of warding that allows you to store a 1st level spell in it?
    *Puppy dog eyes*

    You can get close, but the spells would still originate from the caster, not the location of the glyph, and the caster must still be within range of the targets. You can get around the latter by increasing the range of all spells with a range of at least 28 (visual range) to 32767, as visual range will still cap normal spellcasting range, but not sequencer range. There isn't anything practical you can do about the spell origin - it's tied to the projectile of each spell, not the glyph.
    PROfile:
    Create copy of TRAPGLYP.PRO with explosion projectile set to '1'(None).

    SPLfile1 (Base Spell - name, description, casting time, Icon, etc...):
    Ability Target: Any Point
    Projectile = 1(None)
    Effect List:
    • Opcode 321, target=Self, Resource=(resref), timing/duration=0
    • Opcode 177, target=Self, p1=0, p2=2, resource=EFFfile1, timing/duration=0
    • Opcode 148, target=Self, p1=0, p2=1, resource=SPLfile2, timing/duration=0
    SPLfile2:
    Ability Target: Living Actor
    Projectile = PROfile Index
    Effect List:
    • Opcode 146, target=Preset Caster, p1=0, p2=1, Resource=SPLfile3, timing/duration=0
    SPLfile2:
    Ability Target: Living Actor
    Projectile = 1 (none)
    Effect List:
    • Opcode 256, target=Original Caster, Resource=(resref), timing/duration=0
    EFFfile1:
    Opcode 257, p1=(max level), p2=(number of spells), probability1=100, resourceType = 1, parentResource= (resref)
    APPEND ~BGEE.lua~ ~
    OUTER_SET tip RESOLVE_STR_REF ( "description string for this spell" )
    APPEND	~L_%EE_LANGUAGE%.LUA~	~uiStrings['%resref%_TITLE'] = "label string for this spell"~
    APPEND	~L_%EE_LANGUAGE%.LUA~	~uiStrings['%resref%_LABEL'] = "action string for this spell"~
    APPEND	~BGEE.LUA~	~mageBookStrings['%resref%'] = {tip = %tip%, title = '%resref%_TITLE', action = "%resref%_LABEL"}
    Cast SPLfile1 at target point, upon completion, sequencer menu pops up, select spells, click done and glyph is launched into place, upon triggering the trap/glyph, caster will cast stored spells at all targets.

    If you instead want it to only be able to cast a single, area-effect spell at the glyphs location when triggered, then:
    Replace SPLfile2 with:
    Ability Target: Living Actor
    Projectile = PROfile Index
    Effect List:
    • Opcode 260, target=Original Caster, Resource=(resref), timing/duration=0
    And omit SPLfile3. The caster will still have to be within spell range of the trap/glyph center point when it triggers.

    Grammarsalad
  • GrammarsaladGrammarsalad Member Posts: 2,571
    kjeron said:

    This is awesome! I didn't know something like this was possible...

    Could one of you provide an example, like a glyph of warding that allows you to store a 1st level spell in it?
    *Puppy dog eyes*

    You can get close, but the spells would still originate from the caster, not the location of the glyph, and the caster must still be within range of the targets. You can get around the latter by increasing the range of all spells with a range of at least 28 (visual range) to 32767, as visual range will still cap normal spellcasting range, but not sequencer range. There isn't anything practical you can do about the spell origin - it's tied to the projectile of each spell, not the glyph.
    PROfile:
    Create copy of TRAPGLYP.PRO with explosion projectile set to '1'(None).

    SPLfile1 (Base Spell - name, description, casting time, Icon, etc...):
    Ability Target: Any Point
    Projectile = 1(None)
    Effect List:
    • Opcode 321, target=Self, Resource=(resref), timing/duration=0
    • Opcode 177, target=Self, p1=0, p2=2, resource=EFFfile1, timing/duration=0
    • Opcode 148, target=Self, p1=0, p2=1, resource=SPLfile2, timing/duration=0
    SPLfile2:
    Ability Target: Living Actor
    Projectile = PROfile Index
    Effect List:
    • Opcode 146, target=Preset Caster, p1=0, p2=1, Resource=SPLfile3, timing/duration=0
    SPLfile2:
    Ability Target: Living Actor
    Projectile = 1 (none)
    Effect List:
    • Opcode 256, target=Original Caster, Resource=(resref), timing/duration=0
    EFFfile1:
    Opcode 257, p1=(max level), p2=(number of spells), probability1=100, resourceType = 1, parentResource= (resref)
    APPEND ~BGEE.lua~ ~
    OUTER_SET tip RESOLVE_STR_REF ( "description string for this spell" )
    APPEND	~L_%EE_LANGUAGE%.LUA~	~uiStrings['%resref%_TITLE'] = "label string for this spell"~
    APPEND	~L_%EE_LANGUAGE%.LUA~	~uiStrings['%resref%_LABEL'] = "action string for this spell"~
    APPEND	~BGEE.LUA~	~mageBookStrings['%resref%'] = {tip = %tip%, title = '%resref%_TITLE', action = "%resref%_LABEL"}
    Cast SPLfile1 at target point, upon completion, sequencer menu pops up, select spells, click done and glyph is launched into place, upon triggering the trap/glyph, caster will cast stored spells at all targets.

    If you instead want it to only be able to cast a single, area-effect spell at the glyphs location when triggered, then:
    Replace SPLfile2 with:
    Ability Target: Living Actor
    Projectile = PROfile Index
    Effect List:
    • Opcode 260, target=Original Caster, Resource=(resref), timing/duration=0
    And omit SPLfile3. The caster will still have to be within spell range of the trap/glyph center point when it triggers.
    Hmm...
    @kjeron What if the ward was actually a summoned creature with a ward like animation? Hey, wait, is that already possible?

Sign In or Register to comment.