Author Topic: Line of sight  (Read 1710 times)

Manuel345

  • Newbie
  • *
  • Posts: 6
    • View Profile
Line of sight
« on: August 23, 2016, 10:45:00 am »
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:

Code: [Select]
function enemy:on_update()
  if self:get_line_of_sight(hero) then
    self.hasLOS = true
  else
    self.hasLOS = false
  end
end

Christopho

  • Administrator
  • Hero Member
  • *****
  • Posts: 1176
    • View Profile
Re: Line of sight
« Reply #1 on: August 23, 2016, 11:21:54 am »
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.

Manuel345

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Line of sight
« Reply #2 on: August 23, 2016, 11:29:18 am »
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...

Christopho

  • Administrator
  • Hero Member
  • *****
  • Posts: 1176
    • View Profile
Re: Line of sight
« Reply #3 on: August 23, 2016, 11:39:10 am »
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.

Manuel345

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Line of sight
« Reply #4 on: August 23, 2016, 11:52:14 am »
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:

Code: [Select]
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
      break
    end
  end

  return hasLOS
end

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.
« Last Edit: August 23, 2016, 12:39:23 pm by Manuel345 »

Christopho

  • Administrator
  • Hero Member
  • *****
  • Posts: 1176
    • View Profile
Re: Line of sight
« Reply #5 on: August 23, 2016, 02:03:35 pm »
Nice!
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).