[1.0.4] Suggested improvements to dumb ai
Posted: Thu Aug 29, 2013 11:04 am
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:
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

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: Select all
-- 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)