ID:272713
 
I've used parameters in a program called Alice. They're VERY simple in that program. But I just can't seem to wrap my head around parameters in the DM language. I've used them for savefile features like saving a mob's verbs to a savefile using a parameter, but could anyone explain to me how to use a parameter to do similar lines of coding for multiple verbs?

e.g. 2 verbs use the same lines of coding EXCEPT for the used icons and obj paths. The conditional if statements I figured would be okay to just write out in each verb, unless making a mob proc would make it less typing. I hope yall understand :)
I'll assume a param is an arg. An arg is like a var you define in the parenthises of a proc, and you can set their value when you call the proc.

mob/proc/Throw_Object(path, icon, dest)
var/obj/O = new path(loc)
O.icon = icon
walk_to(O,loc)

mob/verb/Hit_With_Rock()
set src in oview(10)
usr.Throw_Object(/obj/rock,'rock.dmi',src)


mob/verb/Hit_With_Chair()
set src in oview(10)
usr.Throw_Object(/obj/chair/rocking_chair,'rocking chair.dmi',src)

mob/verb/Hit_With_Holy_Hand_Grenade()
set src in oview(10)
usr.Throw_Object(/obj/grenade/jesus,'holy grenade.dmi',src)
In response to Jeff8500
Oh wow. I thought I'd need to use a parameter. Not a proc with named arguments o.O
In response to Mizukouken Ketsu
A param in BYOND is either 1) the "vars" skin controls have or 2) a text string of values (a list can be converted into them with list2params).
In response to Mizukouken Ketsu
There are no named arguments there. I suggest looking up in the Reference 'arguments' (which are parameters), 'named arguments' (which is an optional convenient method to use when supplying arguments in proc calls) and the 'args' list (as extra "credit").
In response to Jeff8500
This works perfectly fine. Anyway to improve upon it?

mob/proc/Wave(path,X,Y,Z)
var/obj/Q
var/obj/R
var/obj/S
if(src.dir==EAST || src.dir==WEST)
Q = new path(locate(X,Y,Z))
R = new path(locate(X,Y+1,Z))
S = new path(locate(X,Y-1,Z))
Q.Owner = src; R.Owner = src; S.Owner = src
if(src.dir==NORTH || src.dir==SOUTH)
Q = new path(locate(X,Y,Z))
R = new path(locate(X+1,Y,Z))
S = new path(locate(X-1,Y,Z))
Q.Owner = src; R.Owner = src; S.Owner = src
walk(Q,src.dir)
walk(R,src.dir)
walk(S,src.dir)
sleep(20)
del(Q); del(R); del(S)

mob/SandManipulator/verb
Sand_Tsunami()
set category = "Ninjutsu"
Wave(/obj/Jutsu/SandManipulator/SandTsunami,usr.x,usr.y,usr.z)
In response to Mizukouken Ketsu
I believe you could simply use get_step() with turn() instead of all that checking of it, as well as turn that repetitive object initialization into a loop.
In response to Mizukouken Ketsu
You could use a line proc to make a list of turfs between two points. Then you could say for(var/X in get_line(x-1,y,x+1,y)) and it would be more efficient. Here's my get line():

proc/Get_line(x1,y1,z1,x2,y2,z2)
var/turf/s = locate(x1,y1,z1)
var/turf/f = locate(x2,y2,z2)
. = list(s)
var/turf/T = s
while(T != f)
T = get_step(T,f)
. += T


It will get a line from all the 1 coords to the 2 coords. I just wrote it up now, so there may be a problem; I don't see any at the moment, though.

for(var/turf/T in get_line(x-1,y,z,x+1,y,z))
new path(loc,dir)

obj/jutsu/whatever
New(loc,dir,delay)
..()
spawn() // you should really spawn this off onto another proc
walk(src,dir)
if(delay)
sleep(delay)
del(src)


You should really call all the movements and stuff in New(), and use inheritance to really cut down your typing.
In response to Jeff8500
It's not making all 3 like my snippet did. It's only making 1 and it's the one at usr.loc

obj/Jutsu/SandManipulator
SandTsunami
name = "Sand Tsunami"
icon = 'Sand Tsunami.dmi'
New(loc,dir,delay)
..()
walk(src,dir)
sleep(delay*10)
del(src)

mob/proc
Wave(path,X,Y,Z)
if(src.dir==EAST || src.dir==WEST)
for(var/turf/T in get_line(usr.x,usr.y-1,usr.z,usr.x,usr.y+1,usr.z))
new path(locate(X,Y,Z),src.dir,2)
if(src.dir==NORTH || src.dir==SOUTH)
for(var/turf/T in get_line(usr.x-1,usr.y,usr.z,usr.x+1,usr.y,usr.z))
new path(locate(X,Y,Z),src.dir,2)

get_line(x1,y1,z1,x2,y2,z2)
var/turf/S = locate(x1,y1,z1)
var/turf/F = locate(x2,y2,z2)
. = list(S)
var/turf/T = S
while(T != S)
T = get_step(T,F)
. += T

mob/SandManipulator/verb
Sand_Tsunami()
set category = "Ninjutsu"
Wave(/obj/Jutsu/SandManipulator/SandTsunami,usr.x,usr.y,usr.z)
In response to Mizukouken Ketsu
Instead of making a "get_line" proc, you could just use the block() prock. I totally forgot about that neat little function :)

    Wave(path)
if(src.dir==NORTH || src.dir==SOUTH)
for(var/turf/T in block(locate(src.x-1,src.y,src.z),locate(src.x+1,src.y,src.z)))
new path(T)
if(src.dir==EAST || src.dir==WEST)
for(var/turf/T in block(locate(src.x,src.y-1,src.z),locate(src.x,src.y+1,src.z)))
new path(T)
In response to Mizukouken Ketsu
A get line would still be better, you're using a formula rather than repetitive directional checks; it's much more versatile in general!
In response to Jeff8500
But block() isn't a "directional" check? >_> It's a location check? Pretty much the same as your "get_line". Besides, your get_line didn't work properly. It put up one obj only. There's 3 that needed to appear simultaneously. block() does the job perfectly fine, and with less coding needed and, in my eyes, more efficient.
In response to Mizukouken Ketsu
But it's bad. A nice quick little formula will do the job for anything. Your's doesn't even work in all directions.

And who says mine won't work? Do you know what spawn() does?
In response to Jeff8500
Oh so I forgot to add in NORTHEAST|NORTHWEST|SOUTHEAST|SOUTHWEST compatibility >_> Whatever. "A quick little formula"? block() does the EXACT same thing as your get_line() function. I won't need to write "a quick little formula" with the built-in function. Tell me, do you use "a quick little formula" in place of get_step()? How about locate()? I would sure hope not... Sorry Jeff, but I'm going to stick with block() on this one.
In response to Mizukouken Ketsu
Uhh, all due respect to remembering and using block() and all, the manual dir checking is still ugly. =P Erm, did you even read my previous post? I already mentioned a nice way to do this. [link]
    for(var/turf/T in list(src.loc,get_step(src,turn(src.dir,90)),get_step(src,turn(src.dir,-90))))
var/obj/O = new path(T)
walk(O,src.dir)
...

Or broken up for clarity,
    var
turf/side_A = get_step(src,turn(src.dir,90))
turf/side_B = get_step(src,turn(src.dir,-90))
list/turfs = list(src.loc,side_A,side_B)
for(var/turf/T in turfs)
var/obj/O = new path(T)
walk(O,src.dir)
...
In response to Kaioken
Would you mind clarifying how block() is "ugly" in comparison to get_step() and turn() please? :)
In response to Mizukouken Ketsu
I didn't say block() was specifically ugly. What's ugly and not too well-maintainable is you manually checking the dir for every possible value, then duplicating code because of it (ugh!), only slightly, and manually altering the coordinates in each 'duplication' (your very code could be recreated by using vars to replace duplicating code, BTW).
Rather, I went about it in a more flexible, functional method that will always automatically calculate the wanted turfs, no matter what value the dir is.
In response to Mizukouken Ketsu
Tell me, do you use "a quick little formula" in place of get_step()?

Yeah, it's called path finding.

EDIT: If you ever wanted to, you could also use a little trig and make get_line() use angles other than multiples of 45, giving it even more functionality.