Author Topic: default AI and offensive spell  (Read 327 times)

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
default AI and offensive spell
« on: July 19, 2012, 01:29:28 pm »


               Im doing another community patch update and considering to implement a quite major change in spellcasting selection and cast order
except many bugs Ive found out (these fixes will be included in next CP release):
- category 1 is substituted for 11 by GetCreatureTalent* functions and vice versa - seems hardcoded
- CountEnemies count dead PCs/henchmans
- DetermineclassToUse returns invalid class in some cases
- GetLastGenericSpellCast returns always -1  after a while (at least if creature is hasted)


Im planning to change the spell selection to GetCreatureTalentRandom instead of Best. But im not sure whether Im going on the right path. First I describe my results with one test subject:

Ive tried sorcerer lvl 20 with following spells:
- meteor swarm
- mantle
- power word kill
- horrid wilting
- sunburst
- premonition
- great thunderclap
- shadow shield
- chain lightning
- true seeing
- great dispelling
- firebrand
- mestills sheat
- isaac's lesser
- ice storm
- ii
- fireball

in 1.69, he is casting true seeing over and over or one particulare best offensive spell over and over until he lost whole spell level, then he choose different spell, plus he will loose the whole 9th level if his target has more than 100hp due to the way how AI works, well pointless to speak about, without my fixes sorcerers are almost unusable

after the fixes from CP and new fixes above, if he decide to cast offensive spell, first he choose meteor swarm as that is the best "discriminant harmful aoe" spell as it has CR 17. Next round, the first he find is again meteors but since he casted it previous round the AI moves to the next step and choose great thunderclap as best "indiscriminant aoe spell". Next round again meteor, again thunderclap unless Im struck by the spell and paralyzed/kded/deafened in that case it will use random discriminant spell (chain, horrid, meteor). After losing 9th level, he choose sunburst as first spell, after losing 7th level he choose Ice storm as best indiscriminant. After losing 8th lvl, he uses chain lighting as best discriminant and after losing 4th level he choose fireball as best indiscriminant.

Problem is that this is quite uneffective. His best spell is horrid wilting and he will use it only rarely (btw in 1.69 with this setup this spell is ignored completely). Imo spells are not comparable only by innate level. Also I dont know why the GetCreatureTalentBest function does return always sunburst when there is horrid with same category and innate level. Hardly best '<img'>

So I tried to use GetCreatureTalentRandom function instead. (btw builder can force this behavior already using variable "X2_SPELL_RANDOM" int 1)
Now he randomly uses those 4 discriminant spells he got: meteor, horrid, sunburst, chain - until he loose them all or the AI choose same spell twice in a row - in that case it moves to the indiscriminant where it randomly chooses thunderclap/ice storm/fireball.

This seems to me much better than default "best" method of choosing spells. It isnt perfect for sure as the ice storm is often better than discriminant spells, but its more random and efficient I think. Problem is that it changes the spell selection of all spellcaster in module, and it wont be in all cases improvement, as Wizards casting well already. It won't be worse but still...

Thougths? Suggestions?
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
default AI and offensive spell
« Reply #1 on: July 19, 2012, 02:16:27 pm »


               Maybe you could add a check to see if they have sorc levels, and use random if they do, best if they don't.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
default AI and offensive spell
« Reply #2 on: July 19, 2012, 02:22:40 pm »


               

Failed.Bard wrote...

 Maybe you could add a check to see if they have sorc levels, and use random if they do, best if they don't.

very good idea, guess i should do this for bards too, although bards need a bit more adjustments - they shouldnt have cast offensive spells at all I think
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
default AI and offensive spell
« Reply #3 on: July 19, 2012, 03:54:34 pm »


               This might go down like a lead balloon, but I like the idea of adaptive AI's where they can adapt their strategy to their opponent.
However, such a system would be a bit of a framework.


The way I envision it
The AI on the Creature, looks at the Player/Opponent, determines their weaknesses, and then tries to exploit them.

eg- Some way of iterating through effects on the target
determine the element they are weakest against
Determine if they have Immunity to Certain level spells (add those spells to a list of Spells to avoid using against that target)
Determine if the target has Warding active etc - can we dispel it - if not, dont waste spell levels on the target - maybe resort to conjuring instead.


Unfortunately, alot of this would require alot of processing.
eg- Picking the target
        Looping through effects
        Looping through Item Properties on armor/skin/weapons/rings etc

The good news is - once the information has been gathered, it could be cached on the player / creature object as a local var.
(Perhaps exploit the onEquiped Event. - When an item is equipped, re-analyze the character, and change any statistics as necessary)


If you had the information on the creature objects, before battle, then the AI only needs to look at local vars on the target itself.


The result could be
Sorcerers that use fire against Fire Vulnerable targets.
Sorcerers that resort to Conjuring when Evokation spells are unlikely to succeed etc

There are so many ways that the Spellcaster AI can be improved, some are more efficient than others.
Things like AOE spells like Ice Storm, would be best targetted against enemies that have allies nearby.

Unfortunately, the methods that are in nwscript, are somewhat processor intensive (they even warn you about that in the comments)
GetDistanceBetween and GetLineOfSight  etc  - anything that calculates distance and vectors are somewhat processor draining, and if were done in AI scripts might bring a server down to a crawl.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
default AI and offensive spell
« Reply #4 on: July 19, 2012, 04:57:48 pm »


               Well if you want such AI you should consider to use Jasperr's or Tony K. What Im doing is on the edge of fixing the default one - the advantage of default AI is that is custom content compatible - if you create a spell, at least offensive one, the default AI will be able to use it. It is also more appropriate for most mobs as you dont want each stinking goblin to taunt you, hips you and i cheat-cast you '<img'>.

I dont care that creature is using evasion-based spells on target with high reflexes and evasion - more important is that the creature should favor generally more powerful spells (ice storm, horrid, igms, ilms).

I wouldnt be against do this for high ai level creatures but as you said its quite complex to do that. Such code would most likely run into TMI limit, the default AI is quite close to it too.

Reason Im not satisfied with the behavior I have now is that the offensive spelsl are divided into 4 categories:
discriminant aoe
indiscriminant aoe
ranged
touch

by that order. Now when sorcerer has spells from all categories, the AI code will force him to cast discriminant in 90% cases, indiscriminant in 9% and ranged in 0.9% and touch in 0.1% cases. Unless he lose all spells in previous category the chance that he use different category is very small (which isnt problem with "best" behavior, but that way has different issues).

One thought that came into my mind is that I could set the last used category and force AI to use different category all the time - which wouldnt be so easy because it would need to rewrite the AI loops to switch(d4()). Anyway even if I would do this, it isnt certain it will be more efficient. Maybe the creature should favor each category in certain cases? But i dont know what would be the conditions for them yet.
               
               

               


                     Modifié par ShaDoOoW, 19 juillet 2012 - 04:00 .
                     
                  


            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
default AI and offensive spell
« Reply #5 on: July 19, 2012, 11:00:05 pm »


               Another option would be to set an override switch in the spellhook if a specific caster class is matched, or certain spells.

 Alternatively, it could be hooked into your spell data collection script, since caster class is likely already checked there.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
default AI and offensive spell
« Reply #6 on: July 21, 2012, 01:28:39 pm »


               

Failed.Bard wrote...

Another option would be to set an override switch in the spellhook if a specific caster class is matched, or certain spells.

 Alternatively, it could be hooked into your spell data collection script, since caster class is likely already checked there.

not really sure what you mean

new topic - what are a thoughts on AI and bards? Just tried to play HotU with Sharwyn and Deekin and the AI is really stupid.

So far Ive got these features:
- AI is able to use curse song
- bards over 35spell failure wont cast spells at all

still, I dont really like the AI spamming balagarn/sound burst on enemy, wasting spelluses for defensive spells that are more helpful to bards