ToME: the Tales of Maj'Eyal

Everything about ToME
It is currently Mon Jul 13, 2020 5:03 pm

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Thu Aug 29, 2013 11:04 am 
Offline
Sher'Tul Godslayer

Joined: Mon Feb 14, 2011 11:16 pm
Posts: 2263
I've been experimenting with the dumb ai, and watching its behavior closely.

I have four major "problems", and with simple coding, I've fixed them. I say "problems" because not everyone might see them as problems. I'm not sure what DG would think.

And because necrotic minions all use dumb ai, even though their equivalent npcs don't all do so, these improvements improve minions quite a lot, but I've only played to early levels.

There might be some unintended consequences to my changes. One thing is clear, the starting zones are much tougher.

So the three changes are:
1. Regen infusions, healing infusions, skeleton reassemble, and conversion (solipsist) are only used if health falls below 60%
2. Archers only use reload if they have no ammo.
3. Any available talents other than plain melee Attack are used before Attack.
4. Any available talents other than shoot for archers, are used before Shoot (i.e. Pinning Shot, Crippling Shot, etc)

How is this different then? Well take the archer using dumb ai. In a non-adjacent position, currently he/she chooses between shoot and reload, at 50/50 chance of each. With my changes, it is always shoot, unless ammo = 0.

But even better, if an archer is adjacent to an enemy, it currently has three available talents, shoot, reload, and attack. changes 2 and 3 combine so that only shoot works.

And a Master Skeleton archer (e.g., one of your minions :)), will use pinning shot and crippling shot before regular shoot !!

Or take for instance a simple orc warrior, as found in Escape from Reknor. He will typically have Crush and Sunder Armour. Both will be used prior to attack. And as soon as they reset, they will be used again. And combined with 1, they are now tougher to beat.

The code is very simple, and someone might even do it better:

Code:
-- Randomly use talents
newAI("dumb_talented", function(self)
   -- Find available talents
   local avail = {}
   local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
   local target_dist = core.fov.distance(self.x, self.y, tx, ty)

-- JENX ADDED - variable to check for Attack and Shoot
   local canAttack = 0
   local canShoot = 0

   for tid, _ in pairs(self.talents) do
      local t = self:getTalentFromId(tid)
--      print(self.name, self.uid, "dumb ai talents can try use", t.name, tid, "::", t.mode, not self:isTalentCoolingDown(t), target_dist <= self:getTalentRange(t), self:preUseTalent(t, true), self:canProject({type="bolt"}, self.ai_target.actor.x, self.ai_target.actor.y))
      -- For dumb AI assume we need range and LOS
      -- No special check for bolts, etc.
      local total_range = self:getTalentRange(t) + self:getTalentRadius(t)
      local tg = {type=util.getval(t.direct_hit, self, t) and "hit" or "bolt", range=total_range}
      if t.mode == "activated" and not t.no_npc_use and
         not self:isTalentCoolingDown(t) and self:preUseTalent(t, true, true) and
         (not self:getTalentRequiresTarget(t) or self:canProject(tg, tx, ty))
         then
-- JENX ADDED: only use regen infusion or healing if life < 60% max life
         if t.name == "Infusion: Regeneration" or t.name == "Infusion: Healing" or t.name == "Skeleton Reassemble" or t.name == "Conversion" then
            local life = 100 * self.life / self.max_life
            if life < 60 then
               avail[#avail+1] = tid
               print(self.name, self.uid, "dumb ai talents can use", t.name, tid)
            end
-- JENX ADDED: only use reload if ammo = 0
         elseif t.name == "Reload" then
--            print(self.name, self.uid, "ammo fix <<<<<<<<<<<<")
            local a = self:hasAmmo()
--            print(self.name, self.uid, a, a.combat.shots_left, a.combat.capacity)
            if a then
               if a.combat.shots_left == 0 then
                  avail[#avail+1] = tid
                  print(self.name, self.uid, "dumb ai talents can use", t.name, tid)
               end
            end
         else
            avail[#avail+1] = tid
            print(self.name, self.uid, "dumb ai talents can use", t.name, tid)
            if t.name == "Attack" then
               canAttack = #avail
               print(self.name, self.uid, "canAttack <<<<<<<<<<<<", #avail)
            end
            if t.name == "Shoot" then
               canShoot = #avail
               print(self.name, self.uid, "canShoot <<<<<<<<<<<<", #avail)
            end
         end
      elseif t.mode == "sustained" and not t.no_npc_use and not self:isTalentCoolingDown(t) and
         not self:isTalentActive(t.id) and
         self:preUseTalent(t, true, true)
         then
         avail[#avail+1] = tid
         print(self.name, self.uid, "dumb ai talents can activate", t.name, tid)
      end
   end

-- JENX ADDED - if more than one talent and attack is available, do the talent rather than attack
   if #avail > 1 and canAttack > 0 then
      table.remove(avail,canAttack)
   end
-- then remove shoot, if other (shooting?) talents available
   if #avail > 1 and canShoot > 0 then
      table.remove(avail,canShoot)
   end
--JENX end

   if #avail > 0 then
      local tid = avail[rng.range(1, #avail)]
      print("dumb ai uses", tid)
      self:useTalent(tid)
      return true
   end
end)

_________________
MADNESS rocks


Top
 Profile  
 
PostPosted: Thu Aug 29, 2013 6:15 pm 
Offline
Uruivellas

Joined: Thu Nov 18, 2010 6:42 pm
Posts: 744
This looks like progress towards a smarter AI for most NPCs. The main reason to use the "dumb_talented" ai over the much more effective tactical ai is for speed. With that in mind, I suggest a couple of tweaks:

Let regen be used whenever life < 80% to allow for preemptive healing.
Let reload be used whenever ammo is low (say 1/4 of capacity) rather than empty.

Note that some heals will still be used at full health. A more general way to fix those would be to check the talent.tactical table for the heal flag and disable those talents when above the healing threshold. Something like:
Code:
if t.tactical and t.tactical.heal then
<code to decide if healing is allowed or not>
...

_________________
Author of the Infinite 500 and PlenumTooltip addons, and the joys of Scaling in ToME.


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 12:39 pm 
Offline
Spiderkin

Joined: Wed Jan 26, 2011 3:47 pm
Posts: 559
Nice, I like smarter AI in general. Might require some rebalancing of the game though.


Top
 Profile  
 
PostPosted: Sat Aug 31, 2013 2:24 am 
Offline
Sher'Tul Godslayer

Joined: Mon Feb 14, 2011 11:16 pm
Posts: 2263
I've been playing a bulwark with this addon, and I think it is a good improvement to the game. And it could be developed further.

Enemies actually do a lot wider range of things, particularly as they can't choose attack or shoot if they have another option.

So for example, little ole mice, now regularly cast Hide in Plain Sight. And so I'm not seeing the mice as much until I bump into them.

I think the big test will be places like elven ruins, dreadfell, etc, with lots of archers pinging me non-stop. Let's see how that goes!

If others have ideas as to how to improve the dumb ai, let me know!

_________________
MADNESS rocks


Top
 Profile  
 
PostPosted: Sun Sep 01, 2013 3:58 am 
Offline
Sher'Tul Godslayer

Joined: Mon Feb 14, 2011 11:16 pm
Posts: 2263
Hachem_Muche wrote:
This looks like progress towards a smarter AI for most NPCs. The main reason to use the "dumb_talented" ai over the much more effective tactical ai is for speed. With that in mind, I suggest a couple of tweaks:

Let regen be used whenever life < 80% to allow for preemptive healing.
Let reload be used whenever ammo is low (say 1/4 of capacity) rather than empty.

Note that some heals will still be used at full health. A more general way to fix those would be to check the talent.tactical table for the heal flag and disable those talents when above the healing threshold. Something like:
Code:
if t.tactical and t.tactical.heal then
<code to decide if healing is allowed or not>
...


I don't understand why some will still heal at full health, as my code prohibits the talent even entering the hash table doesn't it?

_________________
MADNESS rocks


Top
 Profile  
 
PostPosted: Sun Sep 01, 2013 4:03 am 
Offline
Sher'Tul Godslayer

Joined: Mon Feb 14, 2011 11:16 pm
Posts: 2263
Update

I've updated the add-on in several ways.

1. I've introduced a scaling threshold for activation of healing talents. This is based on my own experience. Early in the game, I use heals/regens sooner rather than later. so I've changed the code to make the threshold 80% - maxlife/100. So at 100 life, it is 79% and at 2000 life it is 60%.
2. I've introduced a force heal. That is, if the criteria above is reached, the heal always occurs, regardless of how many talents are available.
3. I've improved the log output.

So here is an example of the new log format, with the forced heal being used by a spitting spider:

Code:
AI took for target   87779   spitting spider   ::   1538   Lekra   4   <   100
AI took for target   87043   thought-forged warrior   ::   87779   spitting spider   4   <   100

[LOG]   #UID:1538:0#Lekra hits spitting spider for #YELLOW#4 mind#LAST#, #GREY#3 darkness#LAST# damage (total 6.62).
[LOG]   #UID:87779:0#Spitting spider hits Lekra for #LIGHT_GREEN#14 nature#LAST# damage.

[LOG]   #UID:87043:0#Thought-forged warrior hits spitting spider for #aaaaaa#45 physical#LAST#, #LIGHT_GREEN#2 nature#LAST# damage (total 46.71).

[LOG]   #UID:1538:0#Lekra hits spitting spider for #YELLOW#4 mind#LAST#, #GREY#3 darkness#LAST# damage (total 6.62).
[LOG]   #UID:87779:0#Spitting spider hits Lekra for #LIGHT_GREEN#13 nature#LAST# damage.

[LOG]   #UID:87043:0#Thought-forged warrior hits spitting spider for #aaaaaa#50 physical#LAST#, #LIGHT_GREEN#2 nature#LAST# damage (total 51.71).

spitting spider   87779   dumb ai talents can use   Infusion: Healing   T_INFUSION:_HEALING_1
spitting spider   87779   dumb ai talents can use   Infusion: Sun   T_INFUSION:_SUN_2
spitting spider   87779   dumb ai talents can use   Attack   T_ATTACK
spitting spider   87779   dumb ai talents can use   Lay Web   T_LAY_WEB
spitting spider   87779   dumb ai talents can use   Spit Poison   T_SPIT_POISON
spitting spider   87779   dumb ai talents can use   Web   T_SPIDER_WEB
dumb ai uses   T_INFUSION:_HEALING_1
spitting spider   87779   Healing talent forced use <<<<<<<<<<<<   1
[LOG]   Spitting spider uses Infusion: Healing.
[HEALING]   87779   spitting spider   for   101.35


See how in this example, the spider has as options healing infusion, sun infusion, attack (which would be forbidden), lay web, spit poison and spider web. This line indicates that the dumb ai has been forced to use the healing infusion:

spitting spider 87779 Healing talent forced use <<<<<<<<<<<< 1

Hence the dumb ai is slightly tougher to beat now!!

Have fun.

_________________
MADNESS rocks


Top
 Profile  
 
PostPosted: Sun Sep 01, 2013 4:46 pm 
Offline
Archmage

Joined: Tue Nov 09, 2010 7:43 pm
Posts: 356
Seems the current update causes the profile to revert to the offline profile.


Top
 Profile  
 
PostPosted: Sun Sep 01, 2013 5:25 pm 
Offline
Uruivellas

Joined: Thu Nov 18, 2010 6:42 pm
Posts: 744
jenx wrote:
I don't understand why some will still heal at full health, as my code prohibits the talent even entering the hash table doesn't it?
Your code only applies the healing check to Healing and Regeneration Infusions and to Skeleton Reassemble. The ai could still use other healing talents (like Nature's Touch or Healing Light) at full health. I'm suggesting a simple way to check if (almost) any talent is a healing talent and act appropriately.

_________________
Author of the Infinite 500 and PlenumTooltip addons, and the joys of Scaling in ToME.


Top
 Profile  
 
PostPosted: Tue Apr 22, 2014 4:05 pm 
Offline
Archmage

Joined: Tue Jun 18, 2013 7:24 pm
Posts: 449
Any chance of getting an update for 1.1.5?

_________________
Working on a T-Engine game
Veins of the Earth

Veins of the Earth ModDB page


Top
 Profile  
 
PostPosted: Thu Apr 24, 2014 11:59 pm 
Offline
Sher'Tul Godslayer

Joined: Mon Feb 14, 2011 11:16 pm
Posts: 2263
Zireael wrote:
Any chance of getting an update for 1.1.5?


not from me. but please feel free to take my code and rework it.

_________________
MADNESS rocks


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group