Page 1 of 1

Seeing if target tiles are within build_distance for placing paths

Posted: Fri Oct 16, 2020 7:57 am
by gotyoke
Working on a mod that will spray tiles (e.g. stone-path) around the player, bounded by the player's reach and what's available in the player's inventory, very similar to placing tiles in the core game, just automated. I got set_tiles working fine, but it doesn't care about the player's reach. How could I determine if the target tiles are within reach? Unlike entities, where there is a can_place_entity function, I don't see something like that for tiles.

I think doing something with find_tiles_filtered and using the player's position and build_distance as the radius is plausible. But it would be horribly inefficient to search the resulting array for the target tiles. Really don't want to go that route if I can avoid it.

Re: Seeing if target tiles are within build_distance for placing paths

Posted: Fri Oct 16, 2020 11:25 am
by Pi-C
gotyoke wrote: Fri Oct 16, 2020 7:57 am How could I determine if the target tiles are within reach? Unlike entities, where there is a can_place_entity function, I don't see something like that for
You know the player's position and the radius. You also know the position where you want to place the new tile. Calculate the area, then check if the tile is in the given area:

Code: Select all

local math2d = require("math2d")
 
 -- The player position and reach
local pos, radius

-- Position of the new tile
local tile_pos

local x = pos.x or pos[1]
local y = pos.y or pos[2]

local area =  { {x - radius, y - radius}, {x + radius, y + radius} }

if math2d.bounding_box.contains_point(area, tile_pos)  then
	-- build tile
end
EDIT: Actually, if you know both player and tile position, you don't even need the area but can just calculate the distance and check if it's less or equal to the player's reach…

Re: Seeing if target tiles are within build_distance for placing paths

Posted: Fri Oct 16, 2020 7:35 pm
by gotyoke
That sounds reasonable, but the edge case is making me hesitate. What happens if the center of a tile is outside the reach but the nearest corner of that tile is inside the reach? If the game rules state that such a tile is within reach, I don't just need to know what tile it is, I also need to know which corner of that tile is closest to the player and use that for my range computation.

And do you know if it would be < reach or <= reach?

Thanks.

Re: Seeing if target tiles are within build_distance for placing paths

Posted: Fri Oct 16, 2020 8:29 pm
by Pi-C
gotyoke wrote: Fri Oct 16, 2020 7:35 pm That sounds reasonable, but the edge case is making me hesitate. What happens if the center of a tile is outside the reach but the nearest corner of that tile is inside the reach? If the game rules state that such a tile is within reach, I don't just need to know what tile it is, I also need to know which corner of that tile is closest to the player and use that for my range computation.
Not sure, but I suppose the tile position would be measured from the center. Yes, that's not an integer value. But I've caught the position of an entity with this wonderful mod:
Screenshot at 2020-10-16 21-56-08.png
Screenshot at 2020-10-16 21-56-08.png (280.08 KiB) Viewed 1401 times
As you can see, y is not an integer either. So,with floating point numbers, in my opinion the tile should be placeable if the difference between the two positions is less than or equal to the player's reach.

Something different: I'm working on a mod where I'm currently having problems with tiles set by script (see here). When a tile is placed, I need to know what player or force caused this, so I can add some hidden entities if one of my tiles has been built. Would you mind using script.raise_script_set_tiles() and adding player_index to the event data?

Re: Seeing if target tiles are within build_distance for placing paths

Posted: Fri Oct 16, 2020 10:08 pm
by eradicator
Best guess pseudocode. If you don't like best guess you just test it in-game yourself ;p.

Code: Select all

if distance(player.position,target.position) <= player.reach + force.reach_bonus + character.reach_bonus then
  --dostuff!
  end
I find it unlikely that vanilla reach uses box detection. It's more expensive to calculate for exactly identical gameplay - players don't see or calculate their reach when playing. But you gotta beware of the different reach bonus types (looks like equipment can't have reach bonus?).