Jump to content
Sign in to follow this  
JediMindTrix

Area Script Behavior in EE

Recommended Posts

I am investigating this bug report and after several hours of testing have determined that for some reason, the conditions in the following codeblock(s) are only being checked a single time: (Pardon the commenting)

 

 

IF
  StateCheck("finiren",4032)  // finiren      //Irenicus is dead
  OR(2)                                      
  StateCheck("finbodh",4032)  // finbodh      //And Bodhi is dead
  Global("BodhiFights","GLOBAL",1)            //OR Bodhi is fighting
  StateCheck("finsolar",4032)  // finsolar    //And Solar is dead
  !Exists([ENEMY])                            //And no enemies exist
  Global("SetForceWalkwayTimer","AR6200",0)   //Timer not set
  Global("FinalFight","AR6200",3)             //FinalFight 3
THEN                                           
  RESPONSE #100
    SetGlobal("SetForceWalkwayTimer","AR6200",1) //ForceWalkway
    SetGlobalTimer("ForceWalkway","AR6200",30)   //Forcebridges timer
END
IF
  GlobalTimerExpired("ForceWalkway","AR6200")   //Failsafe measure timer set
  Global("FinalFight","AR6200",3)
THEN
  RESPONSE #100
    SetGlobal("FinalFight","AR6200",5)          //Forces bridges to appear
END
IF
  Delay(3)                                        //Wait 3 seconds
  StateCheck("finiren",4032)  // finiren          //Irenicus died
  OR(2)                                          
  StateCheck("finbodh",4032)  // finbodh          //And Bodhi died
  Global("BodhiFights","GLOBAL",1)                //OR sided with player
  StateCheck("finsolar",4032)  // finsolar        //And Solar is dead
  !Exists([ENEMY])                                //And no more enemies exist (Imoen/summons check?)
  Global("BalthazarFights","GLOBAL",1)            //And Balthazar is fighting with player
  !StateCheck("balth2",4032)  // balth2           //And Balthazar is not dead or stunned etc
  !StateCheck("balth2",STATE_STUNNED)  // balth2
  !StateCheck("balth2",STATE_SLEEPING)  // balth2
  !StateCheck("balth2",STATE_SILENCED)  // balth2
  !StateCheck("balth2",STATE_CONFUSED)  // balth2
  OR(2)                                           //
  Global("ImoenBackToHuman","GLOBAL",2)           //And Imoen Back
  StateCheck("Imoen2",4032)  // Imoen2            //OR Imoen Died
  Global("FinalFight","AR6200",3)                 //AND finalfight is 3
THEN
  RESPONSE #100
    SetGlobal("FinalFight","AR6200",4)
    ActionOverride("balth2",Dialog(Player1))
END
IF
  Delay(3)                                  //Wait 3 seconds
  StateCheck("finiren",4032)  // finiren    //Check Irenicus death
  OR(2)                                     //OR next 2
  StateCheck("finbodh",4032)  // finbodh    //Bodhi is dead
  Global("BodhiFights","GLOBAL",1)          //Bodhi fought by players side
  StateCheck("finsolar",4032)  // finsolar  //and Solar is dead
  !Exists([ENEMY])                          //and There are no enemies in AR6200
  OR(6)                                     //OR
  Global("BalthazarFights","GLOBAL",0)      //Balthazar did not fight by players side
  StateCheck("balth2",4032)  // balth2      //Balathazar is dead
  StateCheck("balth2",STATE_STUNNED)  // balth2  //Various balthazar states
  StateCheck("balth2",STATE_SLEEPING)  // balth2
  StateCheck("balth2",STATE_SILENCED)  // balth2
  StateCheck("balth2",STATE_CONFUSED)  // balth2
  OR(2)                                          //OR
  Global("ImoenBackToHuman","GLOBAL",2)          //Imoen made it back to Human
  StateCheck("Imoen2",4032)  // Imoen2           //But she died
  Global("FinalFight","AR6200",3)                //And global is 3
THEN
  RESPONSE #100
    SetGlobal("FinalFight","AR6200",4)           //
    ActionOverride(Player1,StartDialogue("player1",Player1))
END

 

My test procedure and results:

 

 

 

I did a speedrun to the end (only took me an hour and a half o.O) and was able to replicate the bug. Imoen went through her transformation, I ctrl-y'd bodhi, irenicus, and the solar, imoen transformed back, and nothing happened.
This is with only Ascension and our new components installed.

 

I had forgotten to check the globals the first time and went back to repeat the process, though instead of letting Imoen ride out her slayer transformation, I ctrl-y'd her as well. This time, the bridges appeared and Ascension proceeded as normal.

 

I went back and again let Imoen ride out her transformation while Irenicus and Bodhi and the Solar were ctrl-y'd. This time, the bridges did not appear, and the global FinalFight was set to 3 instead of 5 like it should be.

 

The fourth time I tested the fight, I killed off everyone but Bodhi and Slayer-Imoen. Then I waited about 60 seconds before resolving the situation. Again, nothing triggered.

So what this tells us is: the block that checks to see if the opponents are still alive is only firing once, and unless you are pausing the game and instantly ctrl-y'ing everyone, a player will not be able to kill everyone quick enough to progress.

 

Were this Neverwinter Nights, I would simply move these checks to the OnDeath scripts of the creatures, however I'm not sure there is anything comparable in BGEE.

 

Frankly, I am at a loss on what could cause this. I do not believe any code blocks in AR6200 are returning true and causing the script to start over before it reaches the relevant code that is responsible for creating the bridges that allow progression in Ascension, by virtue of my 2nd tests success. Instead, it feels like AR6200 is only firing a single time.

My knowledge on how the area scripts function, how often they are called, etc - is very limited, and I was hoping for any insights into solving this confounding problem?

Share this post


Link to post

tldr;

is 4032 the state for dead folk or the "just died" one? I thought they were a bitfield, so this one would match many states.

Share this post


Link to post

4032 (hasSpell something) is supposed to be 15(state_really_dead). Changing this did not fix the issue.

 

Can you put a check at the top of a creature's override or default script that goes something like...

 

 

IF
  StateCheck(Myself, 15) //STATE_REALLY_DEAD
THEN
  RESPONSE #100
   IncrementGlobal("JMT#WV1","AR6200",1)
   ActionOverride(DisplayStringHead(Myself,49766),Player1))
   Continue()
END

 

and have the codeblock fire when a creature dies?

Edited by JediMindTrix

Share this post


Link to post

Can you put a check at the top of a creature's override or default script that goes something like...

(...)

and have the codeblock fire when a creature dies?

check this topic: https://forums.beamdog.com/discussion/43353/state-really-dead-in-udmpswn-bcs-is-not-reliable

From my experience running death check in CRE Override script is not reliable at all, at least in BG2:EE. I used "not always" words in that topic, but the last time I've checked similar script it failed like 10 times in a row, so my guess is it doesn't work. Although try yourself and let us know the results of your tests.

Edited by K4thos

Share this post


Link to post

I opted to restructure the way those variables are applied by moving them into creature override scripts. Each one looks like this, except for Imoen's which I haven't fully realized yet as it will involve messing with a dialog file.

IF                              //Everybody, including Bodhi and Balthazar is dead
  Global("JMT#WV1","AR6200",4)
  Global("SetForceWalkwayTimer","AR6200",0)
  OR(2)
  Global("BalthazarFights","GLOBAL",0)     
  StateCheck("balth2",15)
  !Exists([ENEMY])
THEN
  RESPONSE #100
   ActionOverride(Player1, DisplayStringHead(Myself,49764))
   SetGlobal("FinalFight","AR6200",4)
   ActionOverride(Player1,StartDialogOverride("player1",Player1))
END
IF                              //Every enemy is dead and Bodhi is ally, assumes balthazar and bodhi can't both fight with you
  Global("JMT#WV1","AR6200",3)
  Global("BodhiFights","GLOBAL",1)
  !Exists([ENEMY])
THEN
  RESPONSE #100
   ActionOverride(Player1, DisplayStringHead(Myself,49764))
   SetGlobal("FinalFight","AR6200",4)
   ActionOverride(Player1,StartDialogOverride("player1",Player1))
END
IF                            //Everybody is dead, Balthazar is ally
  Global("JMT#WV1","AR6200",4)
  Global("BalthazarFights","Global",1)
  !Exists([ENEMY])
THEN
  RESPONSE #100
   ActionOverride(Player1, DisplayStringHead(Myself,49764))
   SetGlobal("FinalFight","AR6200",4) 
   ActionOverride("balth2",StartDialogOverride("balth2",Player1))
END
 
IF
  Die() //STATE_REALLY_DEAD
THEN
  RESPONSE #100
   IncrementGlobal("JMT#WV1","AR6200",1)
END

I also tried a version with IF Die at the top with a Continue() command.

 

The global JMT#WV1 is incremented successfully on creature death 95% of the time.

However, the other three code blocks are not triggering.

 

EDIT: Likely this is because the dead creature's script stops parsing after the Die function.

Edited by JediMindTrix

Share this post


Link to post

UPDATE:

IF                                        //All enemies are dead, Imoen resolved, Balthazar Dead
  Die()
  Global("JMT#WV1","AR6200",2)            //Current first wave count
  OR(2)
  Global("BalthazarFights","GLOBAL",0)    //Balthazar did not fight with you
  StateCheck("balth2",15)                 //Balthazar died
  OR(2)
  Global("ImoenBackToHuman","GLOBAL",2)   //Imoen Survived
  Global("JMT#IMD","AR6200",1)            //Imoen's dead!
  !Exists([ENEMY])                        //No summons around
THEN
  RESPONSE #100
   IncrementGlobal("JMT#WV1","AR6200",1)  //Final increment
   SetGlobal("FinalFight","AR6200",4)     //Set to pre-bridge dialog
END

IF                                     //All enemies are dead, Imoen resolved, Balthazar is ally
  DIE()
  Global("JMT#WV1","AR6200",2)        
  Global("BalthazarFights","Global",1)
  OR(2)
  Global("ImoenBackToHuman","GLOBAL",2)   //Imoen Survived
  Global("JMT#IMD","AR6200",1)            //Imoen's dead!
  !Exists([ENEMY])                    
THEN
  RESPONSE #100
   IncrementGlobal("JMT#WV1","AR6200",1)
   SetGlobal("FinalFight","AR6200",4)  
   ActionOverride("balth2",StartDialogueNoSet(Player1))
END

IF                                     //All enemies are dead, Imoen resolved, Bodhi is ally (no balthazar)
  Die()
  Global("JMT#WV1","AR6200",2)
  Global("BodhiFights","GLOBAL",1)
  OR(2)
  Global("ImoenBackToHuman","GLOBAL",2)   //Imoen Survived
  Global("JMT#IMD","AR6200",1)            //Imoen's dead!
  !Exists([ENEMY])
THEN
  RESPONSE #100
   IncrementGlobal("JMT#WV1","AR6200",1)
   SetGlobal("FinalFight","AR6200",4)
END

IF                                     //If none of the above are true, increment death count by 1
  Die() //STATE_REALLY_DEAD
THEN
  RESPONSE #100
   IncrementGlobal("JMT#WV1","AR6200",1)
END

EDIT: Solved! Player dialog is forced from the area script, which triggers whenever a variable is set. :)

 

 

IF
  Global("FinalFight","AR6200",4)
  OR(2)
  Global("BalthazarFights","Global",0)
  Global("JMT#BD","AR6200",1)
THEN
  RESPONSE #100
   ClearAllActions()
   Wait(1)
   ActionOverride(Player1,StartDialog("player1",Player1)) //Start dialog
END
Edited by JediMindTrix

Share this post


Link to post

From the first post it read like you were using the area script the whole time. :dry:

Share this post


Link to post

From the first post it read like you were using the area script the whole time. :dry:

I'm sorry. Until I posted the 'I opted to restructure the code into creature override scripts' you were correct.

Share this post


Link to post
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.

Sign in to follow this  

×
×
  • Create New...