The spawn in conditions are still in use, there is a master variable the ai uses and checks related to that. It is probably one of the most important components of the current AI system.
It is controlled by the functions inside "x0_i0_spawncond.nss"
SetSpawnInCondition and GetSpawnInCondition
and to cause fast buffing you just use
SetSpawnInCondition(NW_FLAG_FAST_BUFF_ENEMY) ( generally in the on spawned script )
but those just set a bit on the variable "NW_GENERIC_MASTER" which you can set in the toolset bypassing all scripts. I am actually fixing some things developed by the community to actually use those variables, Akavit did a feature to make creatures properly flee, and other major flags, like things related to team type AI's and the like.
The following bits are what you can set to the variable, all expressed as hex values:
const int NW_FLAG_SPECIAL_CONVERSATION = 0x00000001;
const int NW_FLAG_SHOUT_ATTACK_MY_TARGET = 0x00000002;
const int NW_FLAG_STEALTH = 0x00000004;
const int NW_FLAG_SEARCH = 0x00000008;
const int NW_FLAG_SET_WARNINGS = 0x00000010;
const int NW_FLAG_ESCAPE_RETURN = 0x00000020; //Failed
const int NW_FLAG_ESCAPE_LEAVE = 0x00000040;
const int NW_FLAG_TELEPORT_RETURN = 0x00000080; //Failed
const int NW_FLAG_TELEPORT_LEAVE = 0x00000100;
const int NW_FLAG_PERCIEVE_EVENT = 0x00000200;
const int NW_FLAG_ATTACK_EVENT = 0x00000400;
const int NW_FLAG_DAMAGED_EVENT = 0x00000800;
const int NW_FLAG_SPELL_CAST_AT_EVENT = 0x00001000;
const int NW_FLAG_DISTURBED_EVENT = 0x00002000;
const int NW_FLAG_END_COMBAT_ROUND_EVENT = 0x00004000;
const int NW_FLAG_ON_DIALOGUE_EVENT = 0x00008000;
const int NW_FLAG_RESTED_EVENT = 0x00010000;
const int NW_FLAG_DEATH_EVENT = 0x00020000;
const int NW_FLAG_SPECIAL_COMBAT_CONVERSATION = 0x00040000;
const int NW_FLAG_AMBIENT_ANIMATIONS = 0x00080000;
const int NW_FLAG_HEARTBEAT_EVENT = 0x00100000;
const int NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS = 0x00200000;
const int NW_FLAG_DAY_NIGHT_POSTING = 0x00400000;
const int NW_FLAG_AMBIENT_ANIMATIONS_AVIAN = 0x00800000;
const int NW_FLAG_APPEAR_SPAWN_IN_ANIMATION = 0x01000000;
const int NW_FLAG_SLEEPING_AT_NIGHT = 0x02000000;
const int NW_FLAG_FAST_BUFF_ENEMY = 0x04000000;
( the above values are in the same number system called hex that metamagic and spell targets use, or that websites write their colors in where it's numbered from 0-F instead of from 1 to 9, you can easily find an online calculator to turn a hex number to an integer, each one of those above actually is a single bit )
The language related to the operators you asked about like & and |, in which you illustrated the following line:
gbSpellInfoCastMask = HENCH_SPELL_INFO_UNLIMITED_FLAG | HENCH_SPELL_INFO_HEAL_OR_CURE;
Uses those bits, and those are bitwise operators. Please read this on
Bitwise math operators where i described it all. The above merges two variables, and later on after you do a |, you can then use a & inside an if to see if those constants are inside the single variable. It's just a way to store a boolean true false into a integer - if you think of the following binary string 0011, that is the number 3, but it's also FALSE, FALSE, TRUE, TRUE. If i take the following psedo code which i will write the number in binary...
int iMask1 = 1; // binary 0001 - this squares up each number
int iMask2 = 2; // binary 0010;
int iMask3 = 4; // binary 0100;
int iMask4 = iMask1 | iMask2; // this is an "or", which makes 0001 and 0010 into 0011;
if ( iMask4 & iMask2 ) // this uses a bitwise "and" which evaluates to be true since iMask2 was put into iMask4 and 0010 is kind of a special mask allowing you to see if just that bit is true or false in the first number.
{
// do stuff
}
if ( iMask4 & iMask3 ) // this evaluates to be false since iMask3 was not put into iMask4
{
// do stuff
}
You really need to study this though, as it's pretty in depth.
gbSpellInfoCastMask is a global variable, which means its defined outside of main which means it's always in effect. This is done like crazy in the AI and it makes it very hard to keep track of the variables.
To answer questions about the flow of the AI, well i added SendMessageToPC each time any function is used, and i can say each script uses almost EVERY function in the ai at least once, and it causes a TMI due to the sheer quantity it's trying to echo and noticeable lag as it tries to catch up, i am talking about it scrolling quickly past on the screen. The only term for it is spagetti,and unlike other code, it uses those global vars to affect things completely unrelated to what is inside the current function. I have read and traced the code line by line throughout the entire process, and after about the 20th function deep my brain dumps where it was before.
I have removed a LOT of the garbage involved though, in the code i linked to.
The issues are not really in the code, the issue is one of fixing the caches the AI uses. One of the core pieces in henchspells.2da which describes a spell for the AI, so it knows how each spell or ability works. The other 2da's provided do class abilities. Fixing these ( and these happen to be full of bitwise packed integers ) is really a key issue to getting it working better. As such once my editor is finished, it should allow you to really correct a LOT of the issues without needing a computer science degree.
The other thing that ( i think ) needs to be done, is to have a 2da which correlates resrefs to spell abilities, which uses some sort of toolset plugin to export those. This is something which is dependent on another project using Grinning Fools creature creator, which has a tool for saving resref to a database. This would provide a "cache" for looking up those special abilties, spells and feats, and for you to set what those are quickly especially if a toolset plugin lets you bypass the engine limitation of not allowing us access to those. This is basically something i am designing at this moment for my revamp of the AI system, not something required but it would really solve a lot of issues.
The functions most people edit to put their fixes in, tend to just make it all much more complicated, even the AI itself has multiple redundant functions that work the exact same way since the dev's just did not realize that a certain feature was already implemented. The spawn conditions master variable, the caching of items, feats and spells each round, and the lookup 2da's are all core foundations upon which the AI rests - and why it's using up so much CPU as it trys to brute force guess what abilities a creature has from round to round. Quite of the other stuff is just making how it works overly complicated.