WizWom Posted September 23, 2006 Share Posted September 23, 2006 For My Tutu NPC, I've made a fairly sophisticated threat calculator, mainly for Mages. generally, it decides how dangerous to th mage the nearest enemy closer than 8 (a distance which should take 2 seconds to cross) is and how dangerous the furthest spellcaster is (priority goes Mage, cleric, druid, bard, if I'm scripting right). It takes into account the mages resilience and the spellcaster's power. It then chooses between these two if both are present. And since I keep the threat calculation, I can then have the script use different spells for differeing levels of danger - of course, I like putting out a magic missile or acid arrow to disrupt preferentially. Clerics, of course, should open with a disrupting insect swarm. Anyway, it also can be extended to fighters, in that they can just choose to attack the target if they are ranging, or the nearest non-trivial if they are meleeing. I'm basing it off the TAZQ series of scripts, but I'm ending up chopping stuff out because it will never be seen in tutu, and recoding almost all the tests :-) Link to comment
cirerrek Posted September 23, 2006 Share Posted September 23, 2006 WizWorm, Threat assessment is pretty tricky, cool that you've worked something out that is effective. Ideally you would be able to have a 'global' threat level = the amount of trouble the whole part is in e.g., Red = 1 Tarasque or 2 summoned demons + 2 mages + 2 Fighters + 2 Clerics Yellow = 5 Fire Giants or 8 10th+ lvl creatures Green = 10 Kobolds or 3 Carrion Crawlers And then have an individual threat level based on who/what is currently attacking a particular party memember. Then you would figure out some way to mesh the two systems to react appropriately e.g., the mage realizing that he is in serious trouble runs off towards your fighters to get some help with the Iron Golem that is trying to maul him/her. Care to post some snippets with an explanation or is the code proprietary? Does your threat assessment scale well? Tutu vs. BG2? TAZQ series of scripts? ...Never heard of this system Thanks, Link to comment
WizWom Posted September 23, 2006 Author Share Posted September 23, 2006 Well, the whole point was to make a scaling threat assessment, for Tutu. since what's really dangerous as 1st level isn't going to phase you when you've make 5th or 6th. So, you need to use your magic/items to battle a wolf at first level, but you probably won't break a sweat fighting a Dire wolf at 4th. The scripts were an extension on someone's q-series scripts, off of sorcerer's place. BG2 aiscripts by Tapio Kivikkola <zap@mad.scientist.com> It included upgraded summons AI & somewhat better Similiar to orginal Blucher's scripts, but usage of scrolls, some items and most of area spells are removed (in my game, however, Aerie still casts Fireball).Also alchemy is removed. Link to comment
WizWom Posted September 23, 2006 Author Share Posted September 23, 2006 As for the teamwork, have you looked at http://www.citilink.com/~jch/bg/ He seems to have spent some time working on his scripts. I grabbed them, to see if he's got anything interesting in there. Link to comment
Gimble Posted September 26, 2006 Share Posted September 26, 2006 Just to chime in, I'm now testing my own threat level system in IWD2. My brief experience seems to indicate that at least the following factors should be considered: Number of non-disabled enemies Number of nearby allies Health (and status) of party Presence of enemy spellcasters Checks for (a few) particularly nasty enemy types and, very importantly, Personal health For my own system, I add or subtract from my threat levels based on the above, and then perform some sanity checks to ensure the threat level has not gotten too high or too low. After that, I translate the threat level value into a maximum spell level that I'm willing to use. That made it much more trivial to think appropriately for spell and item usage: I'll gladly cast Mirror Image (spell level 2) or drink a Potion of Aid (spell level 2) if my MaxSpellLevel is 2 or higher. An added bonus is that as I refine the list of threat contributors above, I merely have to adjust the maximum spell level appropriately as I find the threat system too lenient or too strict, and all the items/spells I have coded will "take care of themselves". My testing so far has been pretty limited, but I've been happy with the system. I will admit that IWD2's scripting engine -- and allocation of enemies -- actually makes threat assessment a little easier than the BG2 engine IMO, but that's small consolation for the multitude of bugs that are in the engine overall. As a secondary note, the inclusion of character-specific modifiers to threat level (most notably personal health) meant that a global threat level seemed less appropriate than a personal one. In addition, I found that global threat calculation had to be handled very carefully (to ensure that everyone isn't constantly trying to adjust it), so I've abandoned global threat level for now. Link to comment
WizWom Posted September 26, 2006 Author Share Posted September 26, 2006 well, generally, my script starts with a "fix-up" section, which tests for low HP or poison and tries to remedy. The, if I'm not in combat and see nothing threatening, I break. Combat threat calculation is: IF True() THEN RESPONSE #100 SetGlobal("WxNearDanger","LOCALS",0) SetGlobal("WxMageDanger","LOCALS",0) Continue() END IF Global("Debug","GLOBAL",1) THEN RESPONSE #100 PauseGame() Continue() END IF See(NearestEnemyOf(Myself)) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 SetGlobal("WxNearDanger","LOCALS",3) Continue() END IF HPLT(LastSeenBy(Myself),10) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",-1) Continue() END IF HPLT(LastSeenBy(Myself),5) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",-1) Continue() END IF HPGT(LastSeenBy(Myself),20) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",1) Continue() END IF HPGT(LastSeenBy(Myself),35) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",1) Continue() END IF HPGT(LastSeenBy(Myself),50) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",1) Continue() END IF HPGT(LastSeenBy(Myself),65) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",1) Continue() END IF HPGT(Myself,40) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",-1) Continue() END IF HPGT(Myself,30) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",-1) Continue() END IF HPGT(Myself,15) Range(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxNearDanger","LOCALS",-1) Continue() END IF GlobalLT("WxNearDanger","LOCALS",0) THEN RESPONSE #100 SetGlobal("WxNearDanger","LOCALS",0) ChangeSpecifics(NearestEnemyOf(Myself),WWXJON_TRIVIAL) Continue() END IF GlobalGT("WxNearDanger","LOCALS",3) THEN RESPONSE #100 Shout(124) ChangeSpecifics(NearestEnemyOf(Myself),WXJON_TARGET) Continue() END IF OR(4) See([ENEMY.0.0.CLERIC_ALL]) See([ENEMY.0.0.LONG_BOW]) See([ENEMY.0.0.BARD_ALL]) See([ENEMY.0.0.DRUID_ALL]) THEN RESPONSE #100 SetGlobal("WxMageDanger","LOCALS",3) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) LevelLT(LastSeenBy(Myself),3) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",-1) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) LevelLT(LastSeenBy(Myself),5) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",-1) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) LevelGT(LastSeenBy(Myself),6) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",2) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) LevelGT(LastSeenBy(Myself),8) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",2) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) CheckStatGT(Myself,10,SAVEVSSPELL) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",1) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) CheckStatGT(Myself,13,SAVEVSSPELL) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",1) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) CheckStatGT(Myself,16,SAVEVSSPELL) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",1) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) CheckStatLT(Myself,6,SAVEVSSPELL) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",-1) Continue() END IF HPGT(Myself,40) GlobalGT("WxMagedanger","LOCALS",0) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",-1) Continue() END IF HPGT(Myself,30) GlobalGT("WxMagedanger","LOCALS",0) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",-1) Continue() END IF HPGT(Myself,15) GlobalGT("WxMagedanger","LOCALS",0) THEN RESPONSE #100 IncrementGlobal("WxMageDanger","LOCALS",-1) Continue() END IF GlobalLT("WxMagedanger","LOCALS",0) THEN RESPONSE #100 SetGlobal("WxMageDanger","LOCALS",0) ChangeSpecifics(LastSeenBy(Myself),WWXJON_TRIVIAL) Continue() END IF GlobalGT("WxMagedanger","LOCALS",0) !See([0.0.0.0.WXJON_TARGET]) THEN RESPONSE #100 ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET) Continue() END IF GlobalGT("WxMageDanger","LOCALS",0) See([0.0.0.0.WXJON_TARGET]) OR(4) See([ENEMY.0.0.CLERIC_ALL]) See([ENEMY.0.0.LONG_BOW]) See([ENEMY.0.0.BARD_ALL]) See([ENEMY.0.0.DRUID_ALL]) LocalsGT("WxMageDanger","WxNearDanger") THEN RESPONSE #100 ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET) ChangeSpecifics(NearestEnemyOf(Myself),0) Continue() END So, if I have no enemy with a WXJON_TARGET, then I know I am not threatened. If I see an enemy with WXJON_TARGET, then I can decide whether it is a mage or a melee combatant, if it is a mage, I can use blocks like: IF LocalsGT("WxMageDanger","WxNearDanger") See([0.0.0.0.WXJON_TARGET]) CheckStatLT(Myself,35,SPELLFAILUREMAGE) CheckStatLT(LastSeenBy(Myself),50,RESISTMAGIC) !HasBounceEffects(LastSeenBy(Myself)) !HasItemEquiped("mageamul",LastSeenBy(Myself)) // Necklace !StateCheck(LastSeenBy(Myself),STATE_INVISIBLE) !StateCheck(LastSeenBy(Myself),STATE_IMPROVEDINVISIBILITY) CheckStatLT(LastSeenBy(Myself),25,RESISTACID) HaveSpell(WIZARD_MELF_ACID_ARROW) THEN RESPONSE #100 SetInterrupt(FALSE) SetGlobalTimer("GBHalfAttack","LOCALS",ONE_ROUND) Spell(LastSeenBy(Myself),WIZARD_MELF_ACID_ARROW) END The "GBHalfAttack" bit is to let the next pass through the script use a ranged weapon, so I don't waste the rest of the round. Link to comment
cirerrek Posted September 27, 2006 Share Posted September 27, 2006 Wizworm, Not sure about BG1, but it BG2, you can break the game by changing specifics of a character. That is why I dropped the ChangeSpecifics targeting from the eSeries and went to using Detectable Spells (not that it doesn't have its issues). Link to comment
WizWom Posted September 27, 2006 Author Share Posted September 27, 2006 As far as it goes, I change specifics of NPC, not characters... I'm running this under tutu, so the engine is BG2. I saw the note about multiplayer using specific; I would expect they use it to tell who controlls what sprites. It's a shame, because othewise I can't really make a turing machine, as I have no real way to store data. It's a bit of a hack, but it was seeming to work. Link to comment
cirerrek Posted September 27, 2006 Share Posted September 27, 2006 As far as it goes, I change specifics of NPC, not characters... I'm running this under tutu, so the engine is BG2. I saw the note about multiplayer using specific; I would expect they use it to tell who controlls what sprites. It's a shame, because othewise I can't really make a turing machine, as I have no real way to store data. It's a bit of a hack, but it was seeming to work. --ChangeSpecifics(NearestEnemyOf(Myself),WWXJON_TRIVIAL) I meant NPCs, darn esoteric terminology... Wizworm, ah, TuTu. Is there someway to search as see if any ingame scripts are checking for Specifics to move the plot along? If BG1 (albeit in the BG2 engine) isn't using Specifics to advance quests or the plot line along, then you would still be okay using it. Seems like you are saying that multiplayer definitely does. In that case, it would probably be a bad idea to use the scripts for multiplayer games. Link to comment
WizWom Posted September 27, 2006 Author Share Posted September 27, 2006 Well, BG2 uses specifics for certain NPCs, from what i can see. So, I'm not sure it's wise to do this, anyway. Since I know whether to target the NearestEnemy() or the LastSeen of a mage class, then I suppose I'll have to have the targeting in the blocks :-( Link to comment
Taza Posted August 4, 2009 Share Posted August 4, 2009 This coming extremely late, but those scripts are mainly Blucher's scripts. I just adjusted them, mostly to avoid nuking neutrals. Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.