Line of sight

Started by Manuel345, August 23, 2016, 10:45:00 AM

Previous topic - Next topic
I am trying to get a line-of-sight working for enemies to detect the hero.

I tried using an invisible custom entity going in a strait line towards the hero and stopping at any wall or impassable surface.
This unfortunately didn't go as planned.

I'm wondering if it would be possible to add a line-of-sight function, probably in sol.main alongside get_distance or maybe directly as a map entity method.

Here's a mockup of how I would use it:

function enemy:on_update()
  if self:get_line_of_sight(hero) then
    self.hasLOS = true
    self.hasLOS = false

Using an invisible custom entity like you suggest should work. There is no such function in the API because every game would need different sights.

Okay, thank you.

I'll try the invisible entity again, can't hurt to try a different approach.

One problem I had the first time is that the entity would sometimes pass through walls...
But the biggest problem is that I can't test for it on each update because the movement needs to move the entity...

Use custom_entity:set_can_traverse_ground() and custom_entity:set_can_traverse_ground() to define what it can traverse or not.

Instead of a movement, you can make a loop that tries different positions of your entity, with entity:test_obstacles(dx, dy).
For example, to test if the entity can move 200 pixels to the right, try dx = 0 to 200.
Or use a movement with a high speed.

August 23, 2016, 11:52:14 AM #4 Last Edit: August 23, 2016, 12:39:23 PM by Manuel345
Awesome, thanks a lot, I'll do a loop iterating through all positions from the enemy to the hero using test_obstacle!

Here's a mockup:

function line_of_sight(entity)
  local hasLOS = true
  local heroDistance = entity:get_distance(hero)
  local heroAngle = entity:get_angle(hero)

  for i=0, heroDistance do
    local dx, dy = math.cos(heroAngle)*i, -math.sin(heroAngle)*i
    if entity:test_obstacles(dx, dy) then
      hasLOS = false

  return hasLOS

Edit It works, thank you so much!!! Also had to invert the Y for some reason, I guess Lua does its math in Cartesian coordinates (negative y towards the bottom)...

Included is the final script for anyone interested.

Y increases towards the bottom, yes, not because of Lua but because this is the usual standard to represent screen coordinates. So it is normal that you need to invert the Y coordinate (math.cos() and math.sin() use the math standard).