ID:169864
 
How would I go about making "Force Push", and "Force Pull", commands to where if you use Push, you'll push any mob or obj thats density = 1 thats in your direction (like straight ahead of you) move one space that direction.


If anyone can help i'd appreciate it.


~C
is that possible?
In response to Earth_kai (#1)
Yes, Rcet implaments this in his game Star Wars: Jedi Arena, but once again can someone help me plz..



~C
Would it be something like:

mob
verb
Force_Push()
for(var/obj/O in usr.dir)
if(O.density == 1)
if(usr.dir == NORTH)
step(O,NORTH)


I don't think that will work though..
Chwgt wrote:
How would I go about making "Force Push", and "Force Pull", commands to where if you use Push, you'll push any mob or obj thats density = 1 thats in your direction (like straight ahead of you) move one space that direction.

mob/player/proc
push(atom/movable/A)
var/atom/new_object_loc = get_step(A,src.dir)
var/atom/old_object_loc = A.loc
if(isloc(new_object_loc) && A.Move(new_object_loc))
src.Move(old_object_loc)

pull(atom/movable/A)
var/atom/new_player_loc = get_step(get_step(A,get_dir(A,src)),get_dir(A,src))
var/atom/old_player_loc = src.loc
if(isloc(new_player_loc) && src.Move(new_player_loc))
A.Move(old_player_loc)


The push() proc pushes both the player and the object ahead one tile each, while the pull() proc moves them behind.
In response to Wizkidd0123 (#4)
Another player or the usr?
In response to Chwgt (#2)
mob
verb
push(atom/m in get_step(src,src.dir))
if(m.density != 0)
if(istype(m,/mob) || istype(m,/obj))
// its a mob or a obj and we can grab it
step(m,src.dir) // pushed it
step(src,src.dir)
else
return
pull(atom/m in get_step(src,src.dir))
if(m.density != 0)
if(istype(m,/mob) || istype(m,/obj))
// its a mob or a obj and we can grab it
var/newdir = "dont"
switch(src.dir)
if(1)
newdir = 2
if(4)
newdir = 8
if(2)
newdir = 1
if(8)
newdir = 4
if(newdir != "dont")
step(src,newdir)
step(m,newdir) // pulled it
else
return

this will also stop people getting traped in walls and stuff
In response to Wizkidd0123 (#4)
And how would I go about putting this into a verb? (Never did anything like this before so i'm trying to learn).
In response to Zmadpeter (#6)
Actually I need it almost identical to the one in this game:

http://www.byond.com/hub/Rcet/StarWarsJediArena
In response to Chwgt (#5)
Chwgt wrote:
Another player or the usr?

src. Please don't say "the usr". usr is a variable; not an object.
In response to Chwgt (#7)
Chwgt wrote:
And how would I go about putting this into a verb? (Never did anything like this before so i'm trying to learn).

mob/player/verb
Push(atom/movable/A in oview(1,src))
if(A.density)
src.push(A)

Pull(atom/movable/A in oview(1,src))
if(A.density)
src.pull(A)
In response to Chwgt (#3)
Nope, it won't work, but it's close.

mob
verb
Force_Push()
for(var/atom/movable/A in get_step(src,dir))
if(A.density)
step(A,dir)


First, look for all of the atom/movables instead of objs or mobs, because an atom/movable can be either a mob or an object, since they are both movable types of atoms.

Then, in the for() loop, you were looking for all the objects in usr.dir, which means "For each object in NORTH", which makes no sense. The get_step() proc gets a turf one space away from the Reference in the Dir. This is what you want, the turf one tile away from the player, in the direction they are facing. Since get_step() returns a turf, we can stick it right in the for() loop, which now reads: "For every movable atom in the turf in front of the player", which is exactly what you want.

Next, I removed the == 1 part from your if() statement, since density can only be true or false, it alone can qualify as a conditional statement, meaning, you don't need anything except the variable in your if() statement to see if it is true or not. The == 1 part is redundant here.

Finally, instead of writting 8 different if() statements to check the direction of the player, just step() the object the direction the player is facing, which will always be a step away from the player. Since this is the effect you want, it's perfect, and completes the verb.

~X
In response to Xooxer (#11)
Question, what would you do to make it do the same thing if its at least 1-4 spaces away.
In response to Xooxer (#11)
How would I make it 1: Work as a pull verb, and how would I make the verb work if A is 1-4 spaces away?
In response to Chwgt (#13)
mob
verb
Force_Push()
var/turf/T // to store the current turf
for(var/dist=1, dist<=4, dist++) // From there to here
T = get_force_step(src, dir, 5-dist) // get the turf dist tiles away
for(var/atom/movable/A in T) // for everything movable in that
if(A.density == 1) // if it is dense
step(A,dir) // step it in our dir

Force_Pull()
var/turf/T // to store the current turf
for(var/dist=1, dist<=4, dist++) // From here to there
T = get_force_step(src, dir, dist) // get the turf dist tiles away
for(var/atom/movable/A in T) // for everything movable in that
if(A.density == 1) // if it is dense
step(A,rev_dir(dir)) // step it the opposite of our dir

/* Dirs is a list of directions stored as text numbers.
Each direction is associated with its opposite direction.
Pass a direction in as the index of the list and the
list will return the opposite direction, like so:

var/Dir = NORTH
var/Opposite_Dir = Dir["[Dir]"]

Because we are storing the directions as text, you need to
change your direction to text before it can be used. This is
easily done by placing the variable within quotes and brackets.
*/

var/list/Dirs = list("1" = "2", "2" = "1", // NORTH - SOUTH
"4" = "8", "8" = "4", // EAST - WEST
"5" = "10", "10" = "5", // NORTHEAST - SOUTHWEST
"6" = "9", "9" = "6") // NORTHWEST - SOUTHEAST

proc
rev_dir(var/Dir) // returns the opposite direction of Dir
if("[Dir]" in Dirs) // if Dir is a direction
return text2num(Dirs["[Dir]"]) // Return the associated opposite

// get_force_step() returns the turf Dist tiles away from Ref in the Dir
// Only Ref and Dir are required. Dist can be from 0 to world.maxx or
// world.maxy, whichever is larger.
get_force_step(var/atom/Ref, var/Dir, var/Dist)
if(!Ref) return // If no Reference, return
if(!("[Dir]" in Dirs)) return // If Dir is not valid, return
Dist = min(max(world.maxx,world.maxy),max(1,Dist)) // crop the Dist
var/turf/T // to store our turf
switch(Dir) // locates the turf based on Dir and Dist from the Ref
if(NORTH) T = locate(Ref.x, Ref.y+Dist, Ref.z)
if(SOUTH) T = locate(Ref.x, Ref.y-Dist, Ref.z)
if(EAST) T = locate(Ref.x+Dist, Ref.y, Ref.z)
if(WEST) T = locate(Ref.x-Dist, Ref.y, Ref.z)
if(NORTHEAST) T = locate(Ref.x+Dist, Ref.y+Dist, Ref.z)
if(SOUTHEAST) T = locate(Ref.x+Dist, Ref.y-Dist, Ref.z)
if(NORTHWEST) T = locate(Ref.x-Dist, Ref.y+Dist, Ref.z)
if(SOUTHWEST) T = locate(Ref.x-Dist, Ref.y-Dist, Ref.z)
return T // return the turf T


That's how I would do it. >.>

~X
In response to Xooxer (#14)
Instead of a get_opposite_dir() proc, it's probably better to use get_dir instead:

If atoms A and B are both on the map, then get_dir(A,B) will return the opposite direction of what get_dir(B,A) returns.

You could actually avoid the whole issue by using step_towards() anyway, now that I think about it.

Also, why are you checking for if(density == 1)? You should be checking for if(density)!
In response to Wizkidd0123 (#15)
Wizkidd0123 wrote:
Instead of a get_opposite_dir() proc, it's probably better to use get_dir instead:

If atoms A and B are both on the map, then get_dir(A,B) will return the opposite direction of what get_dir(B,A) returns.

Oh, yeah... duh. I knew there was a simpler way.

You could actually avoid the whole issue by using step_towards() anyway, now that I think about it.

Meh... >.>

Also, why are you checking for if(density == 1)? You should be checking for if(density)!

I had his original proc saved in a junk project I use to help people diagnose their code problems. I did mention the if(density) check in my first reply, and corrected it, but I guess it slipped my mind when I went back and rewrote it.

Thanks for the tips, Wiz.

~X
Here's my theory. Untested, so take it or leave it!

mob/verb/push()
var
turf/curTurf
atom/A

curTurf = usr.loc
for(var/i in 1 to world.view)
curTurf = get_step(curTurf, usr.dir)
if(curTurf)
for(A in curTurf.contents)
if(A.density) A.Move(get_step(curTurf, usr.dir)
In response to Xooxer (#14)
rev_dir(var/Dir) // returns the opposite direction of Dir

Xoox, a bit of constructive criticism -- you might find it easier to use turn(dir, 180).
In response to Gughunter (#17)
Gughunter wrote:
for(var/i in 1 to world.view)

Just want to mention that this will cause problems unless world.view is equal to a numerical value (as opposed to a text value) =P.