ID:1885652
 
(See the best response by Rotem12.)
Code:
walk_towards(Ref,Trg,Lag=0,Speed=0)


Problem description:
First: Is there a proc similar to walk_towards(Ref,Trg,Lag=0,Speed=0)
where I can tell my object to walk_towards an object's exact pixel location with regards to the tile it is on?

Second: If there isn't one...how would I do this?

Lets say I click a spot on the map and well ..the basics of the map are 32x32 so within each turf tile is 32 pixels in which I could have clicked...

Now that I have clicked tile number 3 at exactly its top right hand pixel point
I want this object to move to that tile but also at it's exact pixel point.

I figured out how to get it to move to the tile and for the click to tell me what pixel position on which tile is being clicked but
not sure what to do from there.

Preferably, I want it to move on a straight path from the client straight to the exact spot click
Best response
Alright, I'll first state there's probably a better method and I'd still want to use built-in walk/step.

You can probably use get_step_to or get_step_towards (depending if you want to consider obstacles) to get to the turf you want to be on and from there use my method to walk inside the turf.

We'll start by defining a point datum that will keep track of pixel position, I'll also define a distance function so that we can tell the precise distance between two points.
point
var
x
y

New(x, y)
src.x = x
src.y = y

proc/dist(point/p)
return sqrt((x - p.x) ** 2 + (y - p.y) ** 2)


Now let's grab the point of the click, we'll define a pixel destination point then tell the player to go there.
(I'm using world.icon_size which in your case is 32)
turf/Click(location,control,params)
..()
var/point/dest = new (x * world.icon_size, y * world.icon_size) // world.icon_size is 32 in your case.

var/paramslist = params2list(params)
var/px = text2num(paramslist["icon-x"])
var/py = text2num(paramslist["icon-y"])

// add click pixel position within the turf
dest.x += px
dest.y += py

usr.move_to(dest)


Now all we have to do is define our move_to proc where we'll check the angle we need to move to and just call Move().
atom/movable/proc/move_to(point/target, minDist = 0)

var/point/source = new (x * world.icon_size + step_x, y * world.icon_size + step_y)

var/dist = source.dist(target)

while(dist > minDist)

var/angle = 90 - get_angle(source, target)

// we need to make sure we're not moving more than the distance is
var/move_size = min(step_size, dist)

var/move_x = move_size * cos(angle)
var/move_y = move_size * sin(angle)

Move(loc, 0, usr.step_x + move_x, usr.step_y + move_y)

// update source point to new position
source.x = x * world.icon_size + step_x
source.y = y * world.icon_size + step_y

// calculate new distance
dist = source.dist(target)

sleep(world.tick_lag)



And here's get_angle()
proc/get_angle(point/a, point/b)
return atan2(b.y - a.y, b.x - a.x)

proc/atan2(x, y)
if(!x && !y) return 0
return y >= 0 ? arccos(x / sqrt(x * x + y * y)) : -arccos(x / sqrt(x * x + y * y))


There's probably things to improve/modify with this, don't just blindly add it in, for example move_to won't cancel with new move_to calls so if you've clicked a second target you have to cancel the previous move_to() but all that should be relatively easy, bump this with questions if you have any.


Alternatively to the whole method I wrote above you can just try creating a temporary target object located at precise x,y,z step_x, step_y of the click on the turf and using walk_towards to that object.

You might even want to attach a nice animated image to it like arrows or a circle similar to how it is in league of legends or RTS games, up to you!



Hey man much thanks for the reply...I'm slowly but surely piecing together what you've shown me into what I wanted...

Questions though...

What is the difference between:

step(Ref, Step_size)
~versus~
simply increasing the step_x or step_y vars?
I'm guessing that if I use step() It handles the tile movement for me though

Also, if I keep increasing the step_x or y vars beyond the world icon size...would it automatically count as a step or a new tile moved to?

Also, what exactly determines what tile my object is on, the amount of his step_x or step_y vars on 1 tile versus that of the others?

*About your last suggestion about creating a temp point with the icon_x and y value of the click location*

Sure it works but It doesn't go toward it in a straight path
In response to Sphinxe1
Sphinxe1 wrote:
What is the difference between:

step(Ref, Step_size)
~versus~
simply increasing the step_x or step_y vars?
I'm guessing that if I use step() It handles the tile movement for me though

Precisely. step() calls Move() for you. This also means it can initiate Bump() and Entered() and such.

Also, if I keep increasing the step_x or y vars beyond the world icon size...would it automatically count as a step or a new tile moved to?

It'll adjust the step_x/y values and the tile location.

Also, what exactly determines what tile my object is on, the amount of his step_x or step_y vars on 1 tile versus that of the others?

The tile your object is on--assuming you're on a turf--is always loc. step_x/y determine how far offset you are from that position. Internally, step_x/y will tend to normalize if they get too far out of range, changing loc for you.
It'd be nice if the pathfinding procs could center you on a point instead of stop after just reaching a tile.

One way you could do this is to repeat step_to() until you're in range, then simply step() in the necessary direction to align the center. Hopefully by the time step_to() returns false, you've reached the target tile, so you can simply slide the short rest of the way.
Thanks for the responses guys, I'll take these thoughts into consideration as well.