Jump to content

The "battle for control" of arcane elemental summons is broken


jmerry

Recommended Posts

It's possible to give orders to an elemental summon while you're still "battling for control". And if you do, things only get worse. The elemental is not very responsive, turning to stare at the summoner after a bit. And if you keep this up, this behavior persists for the entire time the summon is out.

The mage's side of the "battle for control" is handled by the original summoning spell. The elemental's side is handled by the WIZELSUM script, of which I'll reproduce the key block here (BG2EE version):

IF
	Global("Elementalcontrol","LOCALS",0)
THEN
	RESPONSE #15
		ChangeEnemyAlly(Myself,ALLY)
		FaceObject(LastSummonerOf(Myself))
		ApplySpell(Myself,THREE_ROUND_ENCHANTMENT_IMMUNITY)  // SPIN906.SPL (No such index)
		Wait(17)
		PlaySound("EFF_M72D")
		Enemy()
		SetGlobal("Elementalcontrol","LOCALS",2)
	RESPONSE #85
		ChangeEnemyAlly(Myself,ALLY)
		FaceObject(LastSummonerOf(Myself))
		ApplySpell(Myself,THREE_ROUND_ENCHANTMENT_IMMUNITY)  // SPIN906.SPL (No such index)
		Wait(17)
		PlaySound("EFF_M72C")
		Ally()
		SetGlobal("Elementalcontrol","LOCALS",1)
END

What's going wrong? The problem is that Wait(17) command, coupled with the fact that the creature is under your control. Issuing commands during a Wait() breaks the block, causing whatever comes after to not be executed. (This is also the cause of many "missing messenger" bugs)

So you issue the command, then the next time scripts get checked this block starts up again. The elemental stops whatever it's doing to stare at you, and restarts that wait. Repeat indefinitely, or at least until the summoning ends.

What can be done to fix this one? We need to prevent the player from issuing commands to the elemental while the struggle is happening, and preferably without making it helpless. I tried adding a Pause effect to THREE_ROUND_ENCHANTMENT_IMMUNITY ... no, you can still issue commands even if the creature can't move, so that just makes things worse. Feeblemind? That one stops scripts from running, so it kills the block even without player input. The best solution I can find is to replace that ChangeEnemyAlly(Myself,ALLY) command with ChangeEnemyAlly(Myself,NEUTRAL). Or maybe GOODBUTBLUE. If you don't control the creature, you can't issue commands to it.

The BGEE version of this script lacks those ChangeEnemyAlly lines entirely; testing it, that makes no actual difference from the BG2EE version. If an enemy casts the summoning spell, this block never comes into play; the elemental is immediately under their control for good, though the mage is still paused for three rounds.

See also this thread over at Beamdog: https://forums.beamdog.com/discussion/86920/elemental-summons-do-not-work-at-all

Link to comment

I'll try that, since I've already got a testing character set up (create a new sorcerer in ToB with Stoneskin and Conjure Lesser Earth Elemental). Attach that effect to THREE_ROUND_ENCHANTMENT_IMMUNITY and test. As a side note, THREE_ROUND_ENCHANTMENT_IMMUNITY is only used for these control battles; if there's any effect-based solution, attaching it to that spell is the way to go.

Nope. The opcode doesn't seem to respect duration; while you lose control of the creature when it's applied, you can just reselect it after a moment and issue orders.

[Added in edit] The only existing use of opcode 365 I could find was in MAKE_STATUE, which uses timing mode 1. It may be that the opcode just doesn't work properly in any timing mode less permanent than that. Can someone else test this?

Edited by jmerry
Link to comment

Oh thanks, I see it now, in "Non-Spell Revisions changes".

Now that I look a it SR documentation doesn't mention the mental battle, so it should be another mod adding it back 😅

oops

 

EDIT: and I'll end there this topic hijacking, sorry...

EDIT: and that was atweaks PnP elementals. Well, it's in the components name :D

Edited by mickabouille
Link to comment

SR specifically removes the mental battle.

On topic: isn't there a MakeUnselectable script action that prevents you from issuing commands to a creature? Could the script make them unselectable before the Wait() action, and then make them selectable again after it?

Or set the selection circle to zero size for that time, I vaguely recall reading that makes a creature unselectable.

Link to comment

MakeUnselectable() stops local scripts from being executed if engine_mode=1 (BG2EE). It would break the battle even without any outside intervention. That leaves opcode 365, which ... well, I already tried that.

Time to test opcode 287 (selection circle removal).

Opcode 287 does make it impossible to select the creature, but also doesn't interrupt any current control. Since you can easily box-select the elemental while it's warping in, before its script has a chance to run, that's not a full solution. Maybe if we also used 365 ... but there's another problem. You can't attack a creature under opcode 287's influence, or at least can't order such an attack. And there's a notable enemy use of the mental battle - the Boareskyr Bridge event, which uses a different script (bdelefir) but the same THREE_ROUND_ENCHANTMENT_IMMUNITY spell. Attacking the elemental during those three rounds is supposed to be an option.

Link to comment

Anyway, back to the allegiance change attempt. I tried GOODBUTBLUE and GOODBUTRED ... but somehow both of those resulted in controllable elementals despite the blue/red circles? I suppose NEUTRAL is the only reasonable option, then. Figure out the regexp voodoo, code up my test component ... and it still breaks. I can't issue orders to the creature while waiting, but I can click on it with my mage selected, issuing a talk command. That interrupts the wait and restarts the countdown.

Which leaves me wondering - can you cheese the Boareskyr Bridge event with this bug? Enemy mage summons elemental, enters struggle ... so you tell someone to talk to the elemental. By my reading of the script in that case (bdelefir), the wait breaks and doesn't restart. The elemental never goes hostile, and the only threat to the bridge is if people throw around too much AoE damage.

That brings me back to messing with THREE_ROUND_ENCHANTMENT_IMMUNITY. Try both opcodes 287 and 365, each with duration 17 like that spell's other effects ... control is broken when the wait starts, selection circle is gone so I can't click on the elemental, but I can still box-select it and issue orders, interrupting the wait and restarting it a moment later. What, do I have to combine multiple approaches, both eliminating the elemental's selection circle and changing its allegiance to neutral during the wait? That's the only idea I have left.

(By the way, I've been talking about WIZELSUM. WIZELSU2 is essentially identical, and any script-based change would change both of them.)

Does this mechanic exist in Icewind Dale?

Link to comment

OK. Try two new effects on the spell (op365 with effect modes "disable dialogue" and "enable AI" and timing mode 1, op321 with timing mode 4, duration 17, and resource "this spell"). The elemental is properly uncontrollable, but if I tell a character to talk to it, that still interrupts the wait despite the "disable dialogue" effect. You regain control when the spell runs out, but if you interrupted the wait that's just a mirage and it starts again.

At this point, you can't break things by just clicking on the elemental; that has to be a force-talk to do it. Which isn't going to happen accidentally. Good enough?

Link to comment
9 hours ago, jmerry said:

Good enough?

What about removing both the "Wait()" and the "PlaySound()" actions from the script and adding a delayed (timing=4, duration=17) op174 effect to the SPL file...?

However, since the script is supposed to play two different sounds ("EFF_M72C" and "EFF_M72D"), you would need to create a second SPL file...

Edited by Luke
Link to comment

There's no point in moving the sound effects to the spell. The allegiance change also happens at that time, and it's something that definitely can't be done as part of the spell. Since we have to do script stuff anyway at that time, we might as well put the sound in the script.

You can't remove that wait without an adequate replacement. A timer, maybe? Now you're defining a timer in the actions of that block, testing for the timer in the conditions of that block so you don't execute it twice, adding more scripting that tests for the timer so the elemental doesn't just run off and fight your enemies before it's properly on your side, and finally breaking off the ends of those blocks into new blocks that test for the timer being expired. It looks doable to me, but it's a pretty thorough overhaul of the script.

Link to comment

All right. Here's code for adding those two new effects to the spell. Should work in BGEE and BG2EE.

// Psychic struggle for control of wizard elemental summons breaks when elemental is issued order
COPY_EXISTING ~SPIN906.SPL~ ~override~
	LPF CLONE_EFFECT INT_VAR match_opcode=169 match_parameter2=55 opcode=365 parameter1=0 parameter2=1 timing=1 duration=0 STR_VAR insert=first END
	LPF CLONE_EFFECT INT_VAR match_opcode=169 match_parameter2=55 opcode=321 parameter1=0 parameter2=0 timing=4 STR_VAR insert=first resource=%SOURCE_RES% END
BUT_ONLY // Make elemental unselectable during psychic struggle

I went with the "prevent stun icon" effect as the one to clone, because it's the first effect with a duration in the BG2EE version. Nice and simple, not quite unbreakable but close enough. Certainly a major improvement over the vanilla situation in which simply clicking "select all" and issuing a move or attack command to everything you control would reset the elemental's side of the struggle.

Edited by jmerry
Corrected code
Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...