Advanced AI doesn't work properly for Exported characters...(Thank you Bubb and kjeron for the fix!)
islandking
Member Posts: 426
v2.3, heavily modded, there was no problem when beating BG1 final boss and got transferred to SOD, but when I exported my f/m/t to Black Pits, Advanced AI can no longer autocast any spells. Other functions like attack, trap detection etc work fine though.
I also tried SOD>BG2, BG1>BG2 exports, same problem, any ideas?
Thanks!
I also tried SOD>BG2, BG1>BG2 exports, same problem, any ideas?
Thanks!
Post edited by islandking on
0
Comments
Edit: typo.
so for that reason I made my own scripts which work through out the whole series where they work regardless of game im playing
Looks like I'm not the only one, for a moment I thought it was caused by mods.
Really don't want to create anew in BG2, losing original exportable plus SoD items that way...
My character is a f/m/t, can I use your scripts?
https://forums.beamdog.com/discussion/63928/improved-scripts-for-your-bg-bg2-playing-experience#latest
The Advanced AI script is BDDEFAI, and the problem is caused by a timer called BD_CAST. I don't fully understand how timers work, but it seems exporting to a new game resets the game's current tick. It looks as if the timer stores an absolute tick in the LOCALS of the creature, not a relative one. Thus, when you export a character, the timer is now set to a very large, very far in the future time.
Run this console command several times, changing Player1 to Player2, Player3, etc. to fix every character in the party. Your characters should immediately start casting spells again!
C:Eval('ActionOverride(Player1,SetGlobalTimer("BD_CAST","LOCALS",0))')
EDIT: Fixed malformed command.
PS: This is my first post, so sorry for any mistakes!
That sounds like an oversight, I’ll file an issue report on support.baldursgate site.
And well, this is worse than I thought. The BD_CAST timer is not the only timer that goes haywire when a character is exported. In the Advanced AI script alone, there are 15 timers which can become stuck upon export. List:
BD_Blind; Blind
BD_Cast; Controls one-round casting delay
BD_CLTM; Zone Of Sweet Air
BD_Dharm; Defensive Harmony
BD_DInv; Detect Invisibility
BD_Glitter; Glitterdust
BD_Haste; Haste
BD_HIDE; Hide in Shadows ability
BD_Horror; Horror
BD_RParal; Remove Paralysis
BD_SCLAR; Spiritual Clarity
BD_Slow; Slow
BD_Spook; Spook
BD_Support; Controls delay between buffing-spells
BD_Wand; Controls delay between wand usages
If your character has done ANY of these things, at ANY point before exporting, you will have to reset the corresponding timer to zero in order for that function to work again.
I've attached a script that will reset all of your party's Advanced AI. Drop it in the game's base folder, and run it with this console command:
C:Exec("ResetAI.txt")
I’m always open to suggestions. And your method works! RPG perspective: my poor f/m/t must’ve got shockingly confused when transported to the arena at first, but now she finally realized she’s the mighty spellcasting Bhaalspawn and begin to rain terror upon the entire black pits :-D
Anyways, back to topic, I was actually using EEkeeper to do the job, and while I was checking my post-SoD imported f/m/t’s local variables, besides the “BD_CAST” you mentioned, there’re other large numbers as well, listed as follows:
BD_CAST 46616237
BD_GLITTER 46429627
BD_DUEL_BARK_TIMER 46253345
BD_BLIND 1552821
BD_SLOW 46616185
BD_HORROR 45913796
I also do a quick-check on other savefiles, it seems that these “BD_” variables only appear after the first time Advanced AI casts the according spells, like Glitter Dust, Slow, Horror…etc listed above, some spells won’t be listed, but any ability or spell will trigger “BD_CAST” to appear. After that, the values will increase in number as you spend time playing. This behavior explains why a fleshly-made, or never-autocast-a-spell-before character is barely affected after the import.
In my case, not only do I have to reset “BD_CAST”, but also other large number values as well so that she can cast Glitter Dust, Slow and Horror again, hope it helps other players who encounter the same issue.
Thanks Bubb!
By the time I almost finish Baldur’s Gate, my pre-sod savefile values are like this:
BD_CAST 35124047
BD_GLITTER 35123961
BD_BLIND 1552821 (still the same number? hmm this one is strange…maybe I shouldn’t reset this value…)
BD_SLOW 35123909
BD_HORROR 35028147
If you don't mind, I'll use your found value names in Spoiler tag for the issue report.
Thanks for the welcome
I'm not sarevok, but I think I can chime in here.
Anyway, these timer values do indeed update whenever the Advanced AI casts the corresponding spell. It's completely fine to set all of these timers to 0; they will update themselves the next time they are used. The lower number on the blind timer simply means the character hasn't auto-cast blindness in a while.
Also, using the timer names is completely fine. :-)
hmm I still don't get it, if the number only increases with Advanced AI uses of spells and in an imported new game Adv AI won't use spells, then how can sarevok57's tob saves exceed those numbers?
I am a little confused by the question, but I think I might have the idea. You're asking how sarevok57's trigger values are greater than yours, when his should be halted just as yours are? I'll try to detail the process the script takes in using these triggers:
Let's take the example of the BD_Cast trigger. Whenever the script checks if it can cast a spell / use a potion, it checks this trigger:
!GlobalTimerNotExpired("BD_Cast","LOCALS")
Paraphrased, this line is asking "Is this trigger expired? If it is, cast the spell / use the item."
It's important to understand how triggers work to understand the problem, so here is the gist: When a trigger is set to ONE_ROUND (or any value, for the matter), the game stores the absolute tick number that corresponds with the expiration of the trigger in the LOCALS of the character.
I don't know the exact tick value of ONE_ROUND, but let's pretend it takes 100 ticks to wait one round. If the current tick is 1000, the game would store the value 1100 in the LOCALS of the character. When the game checks if the trigger is expired, it checks the current game tick against this stored expiration local. So, if the current game tick is greater than or equal to 1100, the BD_Cast trigger will be expired, and the script will continue as normal.
This stored "ending" value is the key of the problem. Whenever you start a new game (aka exporting), the game resets the current game tick to 0. But wait.. the expiration tick of 1100 is still stored in our LOCALS, isn't it? The script still thinks it has to wait for tick 1100 to cast a spell. The script will now wait 11! rounds after exporting to cast a spell. See the problem? It only gets worse the farther you are into the game at the time of exporting.
Let's generalize this. If you were on, say, day 100 of TotSC, then you exported to SoD, the script would think it had to wait 100 days to cast a spell. sarevok57's ToB saves could exceed your numbers for several reasons.
1. He took more time before exporting, running the script at higher game tick values, and thus the trigger values reflect this fact.
2. He waited long enough in ToB so that the script fixed itself, and continued updating normally.
The way to fix these triggers is to either
a) Have them wiped on export, just like global variables
or
b) Reset them to 0 on export
You could theoretically build in some sort of error-checking into the script, and have it reset the triggers if they are absurdly high; but that is easier said than done.
I know, big wall of text. TLDR; triggers are complicated. Here are some images with the current game tick added, to help demonstrate the triggers in relation to the game tick:
Script casting Stoneskin right after starting new TotSC game:
Resting 24 hours and casting another Stoneskin:
After exporting to SoD immediately after last screenshot:
See how there is a disconnect between the first two screenshots, and the last one? Hopefully this helps.
Thanks for the detailed explanation, sorry I didn’t make myself clear.
I get your meaning of having to exceed precious numbers for Adv AI to autocast. What I didn’t get is:
1.I thought all local variables are wiped out during exportation, looks like it’s not the case.
2.Take my “BD_BLIND 1552821” for example, the number will only change the next time AI casts Blindness right? And time gap in-between the two casts will be added to the number, which would be HUGE in my case. That actually answered my precious question :-)
3.The third one's not important but, why do we need those ticks in first place?
1) I tested this, and local variables are preserved in exports. This is most likely due to them being stored in the creature. Global variables, on the other hand, are most certainly wiped.
2) You are correct, the timer's value will only update when the spells are auto-cast. This upate will jump the timer to the current game tick, skipping everything in between.
3) The ticks are the internal, precise way the game keeps track of time. It's just another layer; a layer that is closer to the internal logic-loop that runs the whole program. This "tick" system is what the round system is built on top of.
This problem is simply an oversight by the developers when making these scrips. I don't necessarily see how they can fix this easily using current methods, but it certainly is fixable. It would require scripting in resets for these timers at export, or at every new game transition. It's up to the developers to fix now, but for now you can just reset the timers manually if they ever get stuck.
I had come up with a similar solution, but it constantly made my characters cancel whatever actions they were doing. This seems like the only way to fix it other than to hard wire resets on export. I just checked your script, and it does indeed cancel any of the characters actions when it sets the globals / timers. Maybe throwing an ActionListEmpty() in the triggers block would fix this?
Note: This patch reads the PARTYAI.2DA file to find the advanced ai scripts. Any mod that adds entries to this file will get their scripts unnecessarily patched, and any mod that changes the existing default values will break this patch.
EDIT: Fixed instance where patch would interrupt thieving abilities.
Sorry, I don't know how to help with mobile.