ID:268730
 
step_to allows diagonal access.
EX:
XXXXXX
XXXXPX
XXXMXX
XXXXXX
X = Ground, M = Mob, P = Player
I mean just pure straight... like...
XXXXX
QTQXX
TMTXX
QTQXX
XXXXX

T = Possible positions
Q = non valid

And, if you disallow a mob's NE,NW,SE,SW with step_to, they don't move unless you're RIGHT infront of them.
So, how would you go about doing this?
Anyways, thanks for reading!
Hell Ramen wrote:
step_to allows diagonal access.
EX:
XXXXXX
XXXXPX
XXXMXX
XXXXXX
X = Ground, M = Mob, P = Player
I mean just pure straight... like...
XXXXX
QTQXX
TMTXX
QTQXX
XXXXX

T = Possible positions
Q = non valid

And, if you disallow a mob's NE,NW,SE,SW with step_to, they don't move unless you're RIGHT infront of them.
So, how would you go about doing this?
Anyways, thanks for reading!

So you want a mob to follow a player, without making any diagonal moves, and choosing an orthogonal move that closes the distance instead of standing still when the direction to the player is not orthogonal. The following (pun not intended) mob does that:

/mob/follower

var/mob/leader

New(loc)

spawn(10)
HeartBeat()

verb/followme()

set name = "follow me"
set src in oview()

leader = usr

usr << "[src] is now following you."

proc/HeartBeat()

var/dx // x distance
var/mdx // magnitude of x distance
var/sdx // sign of x distance
var/dy // y distance
var/mdy // magnitude of y distance
var/sdy // sign of y distance
var/xdir // x direction
var/ydir // y direction
var/turf/xturf = null // turf in x direction
var/turf/yturf = null // turf in y direction
var/dir = null // direction to move

// Only consider moving if we have a leader.

if (leader)

// Find the distances to the leader in the x and y directions.

dx = leader.x - x
dy = leader.y - y

// Find the sign, magnitude, and direction of the x distance.

if (dx)
mdx = abs(dx)
if (dx > 0)
sdx = 1
xdir = EAST
else if (dx < 0)
sdx = -1
xdir = WEST

// Find the sign, magnitude, and direction of the y distance.

if (dy)
mdy = abs(dy)
if (dy > 0)
sdy = 1
ydir = NORTH
else if (dy < 0)
sdy = -1
ydir = SOUTH

// If we are not at the same x co-ordinate as the leader, find the
// turf in the x direction ...

if (dx)

xturf = locate(x + sdx, y, z)

// ... but don't consider moving in that direction if we would
// not be allowed to enter the turf.

if (!xturf.Enter(src))
xturf = null

// If we are not at the same y co-ordinate as the leader, find the
// turf in the y direction ...

if (dy)

yturf = locate(x, y + sdy, z)

// ... but don't consider moving in that direction if we would
// not be allowed to enter the turf.

if (!yturf.Enter(src))
yturf = null

// We now have a choice of 0, 1, or 2 turfs.

if (xturf && yturf)

// We could move in either the x direction or the y direction so
// let's close the greater distance.

if (mdx > mdy)
dir = xdir
else
dir = ydir

else if (xturf)

// We can only move in the x direction.

dir = xdir

else if (yturf)

// We can only move in the y direction.

dir = ydir

// Move in the chosen direction, if any.

if (dir)
step(src, dir)

spawn(10)
HeartBeat()
In response to Pmikell
o.o
It's a lot simpler, Dragon Lord showed me a short way, but it gives a few errorrs:
<DN> Move()
var/oldloc = src.loc
. = ..()
var/mob/monster/M = src.monsters[1] //Error
if(M)
M.Move(oldloc) </DM>
:o
<font color = red>Hell Ramen (/mob): Move(the grass (64,103,1) (/turf/ground/grass), 2)
runtime error: list index out of bounds
proc name: Move (/mob/Move)
source file: Dragon Warrior Monsters.dm,343
usr: Hell Ramen (/mob)
src: Hell Ramen (/mob)
call stack:
Hell Ramen (/mob): Move(the grass (64,102,1) (/turf/ground/grass), 2)</font>

It works for him, yet not for me. ;9
Well, I knew I should've posted this first...
But, thanks for posting that method.
In response to Hell Ramen
Hell Ramen wrote:
o.o
It's a lot simpler, Dragon Lord showed me a short way, but it gives a few errorrs:
<DN> Move()
var/oldloc = src.loc
. = ..()
var/mob/monster/M = src.monsters[1] //Error
if(M)
M.Move(oldloc) </DM>
:o
<font color = red>Hell Ramen (/mob): Move(the grass (64,103,1) (/turf/ground/grass), 2)
runtime error: list index out of bounds
proc name: Move (/mob/Move)
source file: Dragon Warrior Monsters.dm,343
usr: Hell Ramen (/mob)
src: Hell Ramen (/mob)
call stack:
Hell Ramen (/mob): Move(the grass (64,102,1) (/turf/ground/grass), 2)</font>

It works for him, yet not for me. ;9
Well, I knew I should've posted this first...
But, thanks for posting that method.

The error is caused by referring to item 1 of src.monsters when the length of src.monsters is 0, which would be expected when there are no mobs following the player. You need to check the length of the list:

    Move()
var/oldloc = src.loc
. = ..()
var/mob/monster/M

if (src.monsters.len)
M = src.monsters[1]
if(M)
M.Move(oldloc)


Another problem is that although src.monsters is a list, only one mob may follow the player because only item 1 of the list is moved. Even if you added a loop to move every mob in src.monsters, it wouldn't work because the mobs are moved to the old location of the player, which only one mob can occupy (I'm assuming that your mobs have density 1 here).

Also, you would have to make sure that a mob can only start following a player when the two are orthogonally adjacent. If they were diagonally adjacent, the mob's first move would be diagonal, and if they were not adjacent at all, the mob's first move would be a jump of multiple turfs.
In response to Pmikell
Pmikell wrote:
Hell Ramen wrote:
o.o
It's a lot simpler, Dragon Lord showed me a short way, but it gives a few errorrs:
<DN> Move()
var/oldloc = src.loc
. = ..()
var/mob/monster/M = src.monsters[1] //Error
if(M)
M.Move(oldloc) </DM>
:o
<font color = red>Hell Ramen (/mob): Move(the grass (64,103,1) (/turf/ground/grass), 2)
runtime error: list index out of bounds
proc name: Move (/mob/Move)
source file: Dragon Warrior Monsters.dm,343
usr: Hell Ramen (/mob)
src: Hell Ramen (/mob)
call stack:
Hell Ramen (/mob): Move(the grass (64,102,1) (/turf/ground/grass), 2)</font>

It works for him, yet not for me. ;9
Well, I knew I should've posted this first...
But, thanks for posting that method.

The error is caused by referring to item 1 of src.monsters when the length of src.monsters is 0, which would be expected when there are no mobs following the player. You need to check the length of the list:

>   Move()
> var/oldloc = src.loc
> . = ..()
> var/mob/monster/M
>
> if (src.monsters.len)
> M = src.monsters[1]
> if(M)
> M.Move(oldloc)
>

Another problem is that although src.monsters is a list, only one mob may follow the player because only item 1 of the list is moved. Even if you added a loop to move every mob in src.monsters, it wouldn't work because the mobs are moved to the old location of the player, which only one mob can occupy (I'm assuming that your mobs have density 1 here).

Also, you would have to make sure that a mob can only start following a player when the two are orthogonally adjacent. If they were diagonally adjacent, the mob's first move would be diagonal, and if they were not adjacent at all, the mob's first move would be a jump of multiple turfs.



Shouldnt it be...


    Move()
var/oldloc = src.loc
. = ..()
var/mob/monster/M

if(src.monsters.len) //This line here edited
M = src.monsters[1]
if(M)
M.Move(oldloc)
In response to XxDohxX
:o
Thanks!
The monster's not dense, and I only want one.
But, thanks. :D
In response to Pmikell
ok i did this and the skeleon wont follow me
/mob/skeleton_4
icon = 'person.dmi'
icon_state = "skeleton_4"
var/mob/leader
New(loc)
spawn(10)
followme()
HeartBeat()
proc/followme()
set name = "follow me"
leader = usr
usr << "[src] is now following you."
proc/HeartBeat()
var/dx
var/mdx
var/sdx
var/dy
var/mdy
var/sdy
var/xdir
var/ydir
var/turf/xturf = null
var/turf/yturf = null
var/dir = null

if (leader)
dx = leader.x - x
dy = leader.y - y
if (dx)
mdx = abs(dx)
if (dx > 0)
sdx = 1
xdir = EAST
else if (dx < 0)
sdx = -1
xdir = WEST
if (dy)
mdy = abs(dy)
if (dy > 0)
sdy = 1
ydir = NORTH
else if (dy < 0)
sdy = -1
ydir = SOUTH
if(dx)
xturf = locate(x + sdx, y, z)
if (!xturf.Enter(src))
xturf = null
if (dy)
yturf = locate(x, y + sdy, z)
if (!yturf.Enter(src))
yturf = null
if (xturf && yturf)
if (mdx > mdy)
dir = xdir
else
dir = ydir
else if (xturf)
dir = xdir
else if (yturf)
dir = (yturf)
if (dir)
step(src, dir)
spawn(10)
HeartBeat()
It doesn't work for me do i have to make it area for it to work? because i have been making turf/ground and mabye thats why...
In response to Bugboy79
Way to bump a five-year-old post...

Anyway, the code is a mess. For something like this, I'd suggest just fixing it at Move() so that they cannot move diagonally. Like so:

mob
var/diagaffinity = 0
Move(atom/newLoc, Dir)
//Don't concern ourselves with anything but movement between adjacent turfs
if(!isturf(newLoc) || !isturf(loc) || get_dist(newLoc, loc) != 1)
return ..()
//first, get the direction
var/d = get_dir(loc, newLoc)
//if d is diagonal:
if(d & (d-1))
//get one component of d
var/nd = d & (diagaffinity?(NORTH|SOUTH):(EAST|WEST))
//switch whether we pick NORTH|SOUTH or EAST|WEST each step.
diagaffinity = !diagaffinity
var/turf/T = get_step(src,nd)
//move in that direction if we can
if(T.Enter(src))
return Move(T)
else
//move in the direction we didn't try
//get the other component of d
nd = d & (diagaffinity?(NORTH|SOUTH):(EAST|WEST))
diagaffinity = !diagaffinity
T = get_step(src,nd)
//attempt to make this move even if we can't, so that we Bump()
return Move(T)
else
return ..()


This will convert any diagonal movements to an appropriate cardinal direction, including that done by players and those produced by using walk_to(), step(), etc., so it's well-suited to just dropping in where you want it and working. However, there's a possibility this isn't what you want, for example, the path followed from A to B will look something like this:

A#
 ##
  ###B


when you may want something like:

A#####
     #
     B


But, if that's a major issue, just say so.
In response to Garthor
mob
icon = 'person.dmi'
var
hp=0
str=5
def=2
turf
spike
icon = 'person.dmi'
icon_state = "spike"
opacity = 1
Entered(var/mob/M)
if(ismob(M))
flick('bloodpour.dmi', src)
sleep(6)
usr << "You are teleported."
M.loc = locate(108,74,1)
mob
verb
Suicide(var/mob/M)
M.loc = locate(108,74,1)
turf
teler
icon = 'person.dmi'
icon_state = "teler"
Entered(var/mob/M)
if(ismob(M))
sleep(6)
usr << "You are teleported."
M.loc = locate(180,14,1)
turf
teler1
icon = 'person.dmi'
icon_state = "teler1"
Entered(var/mob/M)
if(ismob(M))
sleep(6)
usr << "You are teleported."
M.loc = locate(1,180,1)
turf
none_see
icon = 'person.dmi'
icon_state = "none-see"
opacity = 1
turf
grass
icon = 'person.dmi'
icon_state = "grass"
turf
hill
icon = 'person.dmi'
icon_state = "hill"
opacity = 1
density = 1
turf/walls
name = "weak_wall"
turf/walls/open
icon = 'wallsbroke.dmi'
turf/walls/closed
icon = 'wallsok.dmi'
opacity = 1 // Can't see things on the other side of the door.
density = 1 // The door is solid -- you can't move through it.

Click()
if (get_dist(usr, src) < 2)
Break()
verb
Break()
set src in view(1)
flick('wallsbreaking.dmi',src)
new /turf/walls/open(src)
turf/door
name = "door"
turf/door/open
icon = 'open.dmi'
turf/door/closed
icon = 'closed_door.dmi'
opacity = 1 // Can't see things on the other side of the door.
density = 1 // The door is solid -- you can't move through it.

Click()
if (get_dist(usr, src) < 2)
open()
verb
open()
set src in view(1)
flick('opening_door.dmi', src)
new /turf/door/open(src)
turf
skeleton
icon = 'person.dmi'
icon_state = "skeleton"
Entered(var/mob/M)
if(ismob(M))
flick('skeleton-hit.dmi', src)
sleep(6)
usr << "The monster jumped up and popped you in the face!"
M.loc = locate(159,126,1)
turf
skeleton1
icon = 'person.dmi'
icon_state = "skeleton1"
Entered(var/mob/M)
if(ismob(M))
flick('tele.dmi', src)
M.loc = locate(159,126,1)
turf
fire
icon = 'person.dmi'
icon_state = "fire"
luminosity = 4
Entered(var/mob/M)
if(ismob(M))
flick('fire.dmi', src)
sleep(3)
usr << "It burns!!!"
M.loc = locate(159,126,1)
turf
chair_fire
icon = 'person.dmi'
icon_state = "fire_chair"
Entered(var/mob/M)
if(ismob(M))
usr << "It burns!!!"
M.loc = locate(159,126,1)
turf
fire_chair1
icon = 'person.dmi'
icon_state = "fire_chair1"
Entered(var/mob/M)
if(ismob(M))
usr << "It burns!!!"
M.loc = locate(159,126,1)
turf
ground
icon = 'person.dmi'
icon_state = "ground"
turf
mud
icon = 'person.dmi'
icon_state = "mud"
turf
wall
icon = 'person.dmi'
icon_state = "wall"
density = 1
opacity = 1
turf
end_state
icon = 'person.dmi'
icon_state = "end_state"
density = 1
turf
you_won
icon = 'person.dmi'
icon_state = "you_won"
turf
water
icon = 'person.dmi'
icon_state = "water"
density = 1
luminosity = 1
turf
water_1
icon = 'person.dmi'
icon_state = "water_1"
density = 1
luminosity = 1
turf
water3
icon = 'person.dmi'
icon_state = "water3"
turf
start
icon = 'person.dmi'
icon_state = "start"
turf
end
icon = 'person.dmi'
icon_state = "end"
turf
dead_end
icon = 'person.dmi'
icon_state = "dead_end"
turf
magic1
icon = 'person.dmi'
icon_state = "magic1"
luminosity = 1
turf
devil
icon = 'person.dmi'
icon_state = "devil"
Entered(var/mob/M)
if(ismob(M))
usr << "Before you know it, he stabbed you with his sharp, decay-full claws :O "
M.loc = locate(159,126,1)
sleep(10)
usr << "Even after your death, the decay remains poisoning you. The thousands of deseases will kill you fast. "
sleep(200)
M.loc = locate(159,126,1)
turf
magic_skeleton
icon = 'person.dmi'
icon_state = "magic_skeleton"
Entered(var/mob/M)
if(ismob(M))
usr << "A magical sense... seems to teleport you "
flick('tele.dmi', src)
M.loc = locate(159,126,1)
turf
shiny_wall
icon = 'person.dmi'
icon_state = "shiny_wall"
luminosity = 1
density = 1
turf
blood
icon = 'person.dmi'
icon_state = "blood"
turf
blood2
icon = 'person.dmi'
icon_state = "blood2"
turf
wall_blood
icon = 'person.dmi'
icon_state = "wall_blood"
density = 1
opacity = 1
turf
chair
icon = 'person.dmi'
icon_state = "chair"
turf
bed
icon = 'person.dmi'
icon_state = "bed"
turf
candle
icon = 'person.dmi'
icon_state = "candle"
density = 1
luminosity = 1

torch
icon = 'person.dmi'
icon_state = "torch"
density = 1
luminosity = 2
turf
web
icon = 'person.dmi'
icon_state = "web"
turf
invisi
icon = 'person.dmi'
icon_state = "invisi"
density = 1
turf
heaven
icon = 'person.dmi'
icon_state = "heaven"
Entered(var/mob/M)
if(ismob(M))
desc << "Its... Its beautiful "
M.loc = locate(144,93,1)
turf
hole
icon = 'person.dmi'
icon_state = "hole"
Entered(var/mob/M)
if(ismob(M))
usr << "You fall down a dark deep hole... "
M.loc = locate(108,74,1)
turf
magic
icon = 'person.dmi'
icon_state = "magic"
Entered(var/mob/M)
if(ismob(M))
usr << "You have been teleported"
M.loc = locate(155,15,1)
turf
treeb
icon = 'person.dmi'
icon_state = "treeb"
density = 1
treet
icon = 'person.dmi'
icon_state = "treet"
density = 1
turf
firework
icon = 'person.dmi'
icon_state = "firework"
density = 1
turf
the_dark
icon = 'person.dmi'
icon_state = "the_dark"
density = 1
turf
demon
icon = 'person.dmi'
icon_state = "demon"
density = 1
turf
ghost
icon = 'person.dmi'
icon_state = "ghost"
world
name = "Survive the Maze"
turf = /turf/ground
mob
Login()

mob
Login()
world << "You have been teleported to a magical underground maze in which there are much to see. Untill you get to the end, you will be continually teleported to the start, which is your heaven. Your death is your pride. You have nothing to lose except for your life, in which every time you die you will suffer the pain..."
usr.icon_state = input("What gender?") in list ("guy","girl","classic")
usr.Move(locate(1,180,1))

mob
verb
say(msg as text) //what the usr says is passed into "msg" as text
world << "[usr]: [msg]" //the world sees chatroom-like output
/mob/skeleton_4
icon = 'person.dmi'
icon_state = "skeleton_4"
var/mob/leader
New(loc)
spawn(10)
followme()
HeartBeat()
proc/followme()
set name = "follow me"
leader = usr
usr << "[src] is now following you."
proc/HeartBeat()
var/dx
var/mdx
var/sdx
var/dy
var/mdy
var/sdy
var/xdir
var/ydir
var/turf/xturf = null
var/turf/yturf = null
var/dir = null

if (leader)
dx = leader.x - x
dy = leader.y - y
if (dx)
mdx = abs(dx)
if (dx > 0)
sdx = 1
xdir = EAST
else if (dx < 0)
sdx = -1
xdir = WEST
if (dy)
mdy = abs(dy)
if (dy > 0)
sdy = 1
ydir = NORTH
else if (dy < 0)
sdy = -1
ydir = SOUTH
if(dx)
xturf = locate(x + sdx, y, z)
if (!xturf.Enter(src))
xturf = null
if (dy)
yturf = locate(x, y + sdy, z)
if (!yturf.Enter(src))
yturf = null
if (xturf && yturf)
if (mdx > mdy)
dir = xdir
else
dir = ydir
else if (xturf)
dir = xdir
else if (yturf)
dir = (yturf)
if (dir)
step(src, dir)
spawn(10)
HeartBeat()
mob
var/diagaffinity = 0
Move(atom/newLoc, Dir)
//Don't concern ourselves with anything but movement between adjacent turfs
if(!isturf(newLoc) || !isturf(loc) || get_dist(newLoc, loc) != 1)
return ..()
//first, get the direction
var/d = get_dir(loc, newLoc)
//if d is diagonal:
if(d & (d-1))
//get one component of d
var/nd = d & (diagaffinity?(NORTH|SOUTH):(EAST|WEST))
//switch whether we pick NORTH|SOUTH or EAST|WEST each step.
diagaffinity = !diagaffinity
var/turf/T = get_step(src,nd)
//move in that direction if we can
if(T.Enter(src))
return Move(T)
else
//move in the direction we didn't try
//get the other component of d
nd = d & (diagaffinity?(NORTH|SOUTH):(EAST|WEST))
diagaffinity = !diagaffinity
T = get_step(src,nd)
//attempt to make this move even if we can't, so that we Bump()
return Move(T)
else
return ..()

Ok this is my coding and my skeleton is still not following me something is wrong.... I dont know why
In response to Bugboy79
What I posted will not make it follow you, simply prevent it from moving diagonally. You'd need to use walk_to() or step_to() to make it follow.