Trouble with canSee, et al

All development conversation and discussion takes place here

Moderator: Moderator

Post Reply
Message
Author
nate
Wyrmic
Posts: 261
Joined: Fri Jan 18, 2013 8:35 am

Trouble with canSee, et al

#1 Post by nate »

Trying to make a talent that does something when you're targeted by a critter you can't see; running into problems, and my workarounds are ugly.

The problem is I can't figure out how to tell if I see something or not. Checking the can_see_cache is no good (it's always empty). Checking canSee or canSeeNoCache both sometimes return true even when the mob isn't visible (due to Stealth, in the test I'm currently trying).

My workaround is to add a display callback that writes the mob's location to a new set of grids-- then, if I check those grids and find nothing, I know there was nothing drawn on that tile. It requires making a new table and overloading a function.

Isn't there some other way to do this?
Proud father of Fx4fx and Chronometer add-ons; proud mother of Fated add-on

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

Re: Trouble with canSee, et al

#2 Post by Hachem_Muche »

Maybe something like the way the Hightened Reflexes works?

Have you tried actor:hasLOS?
Author of the Infinite 500 and PlenumTooltip addons, and the joys of Scaling in ToME.

nate
Wyrmic
Posts: 261
Joined: Fri Jan 18, 2013 8:35 am

Re: Trouble with canSee, et al

#3 Post by nate »

hasLOS returns LOS to a target map grid-- not to an entity. It returns true or false based entirely on whether the grid is in LOS. Calling actor:hasLOS(banshee.x, banshee.y) doesn't care at all about whether I can see the banshee or not, just whether I have LOS to its location.

Heightened Senses (which is I believe what you meant?) doesn't see through stealth or invisibility.
Proud father of Fx4fx and Chronometer add-ons; proud mother of Fated add-on

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

Re: Trouble with canSee, et al

#4 Post by Hachem_Muche »

Heightened Reflexes (unarmed training talent) triggers a special effect when you become the target of a projectile. However that is obviously not the issue you're having.

I don't understand the problem you're having with the Actor.canSee function, as it checks can_see_cache (to avoid rechecking if the target is seen or not) and should give a consistent result each time. Note that sometimes the map display is not updated immediately (bug?) but if you mouse over the npc it will disappear. Would this explain the inconsistency?
Author of the Infinite 500 and PlenumTooltip addons, and the joys of Scaling in ToME.

nate
Wyrmic
Posts: 261
Joined: Fri Jan 18, 2013 8:35 am

Re: Trouble with canSee, et al

#5 Post by nate »

canSee does cache-- it gives consistent results on any given tick for which its called. The problem is that those results have nothing to do with whether the target's image has been drawn to the screen or not. Calling it on either the player's tick or the potentially invisible target's tick doesn't matter-- the cache is empty to begin with (emptied every tick if I'm not mistaken), and writing to the cache does not cause any invisible or stealthed creatures to be drawn, nor does the display status of the mob have any effect on what canSee returns. I just tested with lots of mousing over a stealthed Banshee that isn't being drawn to the screen, presumably because of its Stealth-- mousing over it repeatedly doesn't make it appear, even though my canSee on it returns true this tick. (Although I know what you're talking about when you get a glimmer of something you shouldn't be able to see-- it seems pretty cool; if it's a bug, it's a nice one).
Proud father of Fx4fx and Chronometer add-ons; proud mother of Fated add-on

tiger_eye
Perspiring Physicist
Posts: 889
Joined: Thu Feb 17, 2011 5:20 am

Re: Trouble with canSee, et al

#6 Post by tiger_eye »

nate, forgive me for not reading this post in detail, but what exactly is it that you want to do?
darkgod wrote:OMFG tiger eye you are my hero!

nate
Wyrmic
Posts: 261
Joined: Fri Jan 18, 2013 8:35 am

Re: Trouble with canSee, et al

#7 Post by nate »

I want to (actually have made, just ugly): when a player is targeted by something they're unaware of, give them a timed effect that, amongst other things, makes them aware of the targeter.

The two parts of this that are hard:
a) figuring out if they're aware of an invisible or stealthed actor
b) displaying the image of an invisible or stealthed actor
Proud father of Fx4fx and Chronometer add-ons; proud mother of Fated add-on

Lynn
Wayist
Posts: 15
Joined: Mon Apr 22, 2013 6:54 pm

Re: Trouble with canSee, et al

#8 Post by Lynn »

mod.class.player.lua has local function spotHostiles(self)

that's the targeting function used for autouse abilities - I'm not sure why it's local and why it's not used anywhere else.

You can use this:

Code: Select all

function spotHostiles()
	local seen = {}
	if not game.player.x then return seen end

	-- Check for visible monsters, only see LOS actors, so telepathy wont prevent resting
	core.fov.calc_circle(game.player.x, game.player.y, game.level.map.w, game.level.map.h, game.player.sight or 10, function(_, x, y) return game.level.map:opaque(x, y) end, function(_, x, y)
		local actor = game.level.map(x, y, game.level.map.ACTOR)
		if actor and game.player:reactionToward(actor) < 0 and game.player:canSee(actor) and game.level.map.seens(x, y) then
			seen[#seen + 1] = actor
		end
	end, nil)
	return seen
end

-- some lines later...

local enemies = spotHostiles()
if enemies then
	if (#enemies > 0) then
		print("existance of enemies, amount below")
		print(#enemies)
		for eid, null in ipairs(enemies) do
			enemy_actor = enemies[eid]
			print(enemy_actor.uid)
I'm still cleaning up, so sorry if its messy. It works though, just tested it.

If anyone can see any optimizations I can make then plz suggest

(this post has been edited 99 times)

nate
Wyrmic
Posts: 261
Joined: Fri Jan 18, 2013 8:35 am

Re: Trouble with canSee, et al

#9 Post by nate »

I just tried this out, then tested it by summoning a banshee, and calling spotHostiles from the console (I just copy/pasted your function to player:spotHostiles). I was getting the banshee in the list of seens even when the banshee was not being drawn to the screen. (Curious, I also enabled auto-attack when enemies are visible and adjacent; this was firing off sometimes when the banshee was not being drawn to the screen. It's probably also related to the fact that auto-explore will interrupt with stealthed or invisible enemies entering your "view".)

Really, the only thing that code relies upon is canSee, which is the problem here-- it doesn't appear to have any relationship to whether an entity's image has been drawn to the screen. Testing of it needs to be done carefully, because it does cache. There can be an apparent relationship that's just coincidental, and you've got to advance the clock to get a new chance at canSee.

I wouldn't be surprised if there was some point in the game code during which canSee could be called with results that corresponded to what's being drawn. I don't know what point that is though.
Proud father of Fx4fx and Chronometer add-ons; proud mother of Fated add-on

Nagyhal
Wyrmic
Posts: 282
Joined: Tue Feb 15, 2011 12:01 am

Re: Trouble with canSee, et al

#10 Post by Nagyhal »

I really need this functionality for the Beholder content I'm working on (they're big, floating eyes crowned by a cluster of smaller eyes—go figure,)

For the meantime I'll have to write my own vision functions.

I'll post back here if I make significant progress.

Post Reply