Tactical AI Analyses and Discussion

All development conversation and discussion takes place here

Moderator: Moderator

Message
Author
jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#16 Post by jenx »

I"ve been trying to modify the tactial ai but I can't make head or tail of how it works.

I had thought that tactical.lua was the brains of the operation, but none of its print functions appear in the log, so I don't think it is being used:

Code: Select all

newAI("use_tactical", function(self)
	-- Find available talents
	print("============================== TACTICAL AI", self.name)
	local avail = {}
So where then is the logic for the tactical ai? Or have I misunderstood something?
MADNESS rocks

jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#17 Post by jenx »

I worked it out - and I have misunderstood something.

In the sort of function defined in tactical.lua, which is different from the _M:<<func name>> I see in most other files, the print command doesn't work. Not sure why.

So I've added in game.logSeen and this does print to the log, and to the screen.

So at least now I can see what's happening in tactical.lua.

I'm off to tweak it!
Last edited by jenx on Mon Sep 02, 2013 8:36 am, edited 1 time in total.
MADNESS rocks

jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#18 Post by jenx »

Ok, I've found a simple way to get mindslayer npcs to spike shields and auras. The code is very simple currently:

Code: Select all

elseif t.mode == "sustained" and not t.no_npc_use and not self:isTalentCoolingDown(t) and self:preUseTalent(t, true, true) and not self:isTalentActive(t.id) then
	t_avail = true
end
The issue is the not self:isTalentActive(t.id), because these are sustains that *are* active, but should still be available. If simply change this, then the tactical ai can decide if it wants to deactivate them.

I've tested it and it works.

It doesn't check to see if psi as such that the spiked aura does damage. That would be more complex. But because they start with full psi, and there is a long cd (though perhaps not on nightmare/insane), this is not a problem. So I suggest this simple hack:

Code: Select all

elseif t.mode == "sustained" and not t.no_npc_use and not self:isTalentCoolingDown(t) and self:preUseTalent(t, true, true) then
	if self:isTalentActive(t.id) and (t.name == "Thermal Aura" or t.name == "Kinetic Aura" or t.name == "Charged Aura" or t.name == "Thermal Shield" or t.name == "Kinetic Shield" or t.name == "Charged Shield") then
   		t_avail = true
	elseif not self:isTalentActive(t.id) then
		t_avail = true
	end
end
Attachments
tome-tactical-ai-tough.txt
Try this out. rename to *.teaa and add to addons. It spits out lots of info re tactical ai to screen and log, to assist development.
(6.17 KiB) Downloaded 129 times
MADNESS rocks

jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#19 Post by jenx »

The issue with traps is:

(
Rogues: Fine if you don't see them until they're next to you... otherwise there's a few issues.

Issue 1) Traps. Same problem as Archmages/Wyrmics/Summoners here. They seem to only be able to summon traps right on top of you, which is the absolutely least efficient place they can put them. Have them throw them in front of you while they're wandering up, or basically just anywhere that's not on top of you so that there's some chance you'd step on them.
this is because the range of a trap is small, which is what the tactical ai uses to see if the target (i.e. the player) is within range. So we need to add to the range (I suggest 5) of a trap for the ai, changing the default of:

Code: Select all

within_range = target_dist and target_dist <= (self:getTalentRange(t) + self:getTalentRadius(t))
to

Code: Select all

local add_trap = 0
if t.type[1] == "cunning/traps" then
	add_trap = 5
end
within_range = target_dist and target_dist <= (self:getTalentRange(t) + self:getTalentRadius(t) + add_trap)
MADNESS rocks

Crim, The Red Thunder
Sher'Tul Godslayer
Posts: 2000
Joined: Fri May 07, 2004 8:26 pm
Location: Nahgharash

Re: Tactical AI Analyses and Discussion

#20 Post by Crim, The Red Thunder »

How cruel do we want to be here? Because if a rogue is at critical health and about to die, he could spitefully set a nasty trap on his own tile. That way, when he dies, and you come running up to pick his loot up, you walk right onto his final trap, giving him the last laugh. I mean, if it knows it's going to die anyway.... :twisted:

....Possible? Too cruel?
Currently playing under the name Aura of the Dawn 4 down, 227 to go!
Proud author of Orc Pit Restoration Project, Faction Allies, Dwarven Adventurer addons
SadistSquirrel wrote:DarkGod has two arms, one with an opened hand, one with a closed fist. You got the fist.

jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#21 Post by jenx »

Crim, The Red Thunder wrote:How cruel do we want to be here? Because if a rogue is at critical health and about to die, he could spitefully set a nasty trap on his own tile. That way, when he dies, and you come running up to pick his loot up, you walk right onto his final trap, giving him the last laugh. I mean, if it knows it's going to die anyway.... :twisted:

....Possible? Too cruel?
Yes - in my addon (not released yet), traps are now laid, but then sometimes the npc walks onto them. Bot sure what to do about this. And higher level rares will launch traps at a distance, which won't be such a suicidal moment... :shock:
MADNESS rocks

Hachem_Muche
Uruivellas
Posts: 744
Joined: Thu Nov 18, 2010 6:42 pm

Re: Tactical AI Analyses and Discussion

#22 Post by Hachem_Muche »

Traps are faction specific. An NPC of the same faction as the trap should not set it off.
Author of the Infinite 500 and PlenumTooltip addons, and the joys of Scaling in ToME.

jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#23 Post by jenx »

I've also posted this as a separate bug, but in case Hachem is reading here first .....


This occurs with Talents like Grasping Moss, which have no required target.

For some reason, this code in Tactical.lua

Code: Select all

				-- Project the talent if possible, counting foes and allies hit
				local foes_hit = {}
				local allies_hit = {}
				local self_hit = {}
				local typ = engine.Target:getType(tg or default_tg)
				if tg or self:getTalentRequiresTarget(t) then
					local target_actor = self.ai_target.actor or self
					self:project(typ, ax, ay, function(px, py)
						local act = game.level.map(px, py, engine.Map.ACTOR)
						if act and not act.dead then
							if self:reactionToward(act) < 0 then
								print("[DEBUG] hit a foe!")
								foes_hit[#foes_hit+1] = act
							elseif (typ.selffire) and (act == self) then
								print("[DEBUG] hit self!")
								self_hit[#self_hit+1] = act
							elseif typ.friendlyfire then
								print("[DEBUG] hit an ally!")
								allies_hit[#allies_hit+1] = act
							end
						end
					end)
				end
and the talent code:

Code: Select all

newTalent{
	name = "Grasping Moss",
	type = {"wild-gift/moss", 1},
	require = gifts_req1,
	points = 5,
	cooldown = 16,
	equilibrium = 5,
	no_energy = true,
	tactical = { ATTACKAREA = {NATURE=1}, DISABLE = {pin = 1} },
	getDamage = function(self, t) return self:combatTalentMindDamage(t, 6, 40) end,
	getDuration = function(self, t) return 3 + math.ceil(self:getTalentLevel(t)) end,
	getSlow = function(self, t) return 30 + math.ceil(self:getTalentLevel(t) * 6) end,
	getPin = function(self, t) return 20 + math.ceil(self:getTalentLevel(t) * 5) end,
	range = 0,
	radius = function(self, t)
		return 2 + math.floor(self:getTalentLevelRaw(t)/2)
	end,
	target = function(self, t)
		return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)}
	end,
	action = function(self, t)
		-- Add a lasting map effect
		game.level.map:addEffect(self,
			self.x, self.y, t.getDuration(self, t),
			DamageType.GRASPING_MOSS, {dam=self:mindCrit(t.getDamage(self, t)), pin=t.getPin(self, t), slow=t.getSlow(self, t)},
			self:getTalentRadius(t),
			5, nil,
			{type="moss"},
			nil, false, false
		)
		activate_moss(self, t.id)
		game:playSoundNear(self, "talents/slime")
		return true
	end,
	info = function(self, t)
		local damage = t.getDamage(self, t)
		local duration = t.getDuration(self, t)
		local slow = t.getSlow(self, t)
		local pin = t.getPin(self, t)
		local radius = self:getTalentRadius(t)
		return ([[Instantly grow a moss circle of radius %d at your feet.
		Each turn the moss deals %0.2f nature damage to any foes with in its radius.
		This moss is very thick and sticky, all foes passing through it have their movement speed reduced by %d%% and have %d%% chances to be stuck on the ground for 4 turns.
		The moss lasts %d turns.
		Using a moss talent takes no turn but places all other moss talents on a 3 turns cooldown.
		The damage will increase with your Mindpower.]]):
		format(radius, damDesc(self, DamageType.NATURE, damage), slow, pin, duration)
	end,
}
result in the tactical ai thinking that this talent will hit itself. Hence it never uses it (or similar talents).

I'm hoping someone can help me adjust the checking routine in tactical.lua.

Any help Hachem?
MADNESS rocks

jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#24 Post by jenx »

ok - you can see from my bug posts today that I"ve identified the problems with lots of the talents identified in this post and why they don't work.

Others are due to the actual tactical.lua code, and I'm working on an addon to improve this.
MADNESS rocks

jenx
Sher'Tul Godslayer
Posts: 2263
Joined: Mon Feb 14, 2011 11:16 pm

Re: Tactical AI Analyses and Discussion

#25 Post by jenx »

With the release of my new better tactical ai addon (http://forums.te4.org/viewtopic.php?f=50&t=38820), most the issues in this thread have been addressed. Enjoy!
MADNESS rocks

Post Reply