ID:1870641
 
Context: The following code is a recursive gravity proc for a 2D Side Scrolling Non-Traditional Platformer
turf
Ground
icon_state="1";
density=1;
mob/var
jumping=0;
mob
proc
Gravity() {
if(src.jumping==2) {
var/oldDir=src.dir;
step2(SOUTH);
src.dir=oldDir;
for(var/turf/Ground/G in view(2)) {
if(G.x==src.x&&G.y==src.y-1&&src.step_y==0) {
src.jumping=0;
src.icon_state="";
}
}
}
else if(src.jumping==0) {
world << "They are not jumping"
for(var/turf/Ground/Gr in view(2)) {
world << "Check"
if(!Gr) { src.jumping=2; world << "Now They Are Jumping" }
if(Gr.y!=src.y-1&&Gr.x==src.x) { src.jumping=2; world << "Now They Are Jumping[src.jumping]" }
}
}
sleep(0.5);
Gravity();
}
step2(var/direction) {
step(src,direction);
step(src,direction);
}


Whenever the player's "jumping" var is set to 2 the code has no problem entering the for() loop to find turf/Ground/G in view, but for some reason it's not doing the same for my else if block immediately after that.

Whenever I run the game, my output consistently posts "They are not jumping", but it doesn't mention "Check" or "Now They Are Jumping[src.jumping]" even when I remove the statement that claims they are not jumping.
An even stranger thing that is happening is that whenever the player is positioned directly above an instance of turf/Ground the code outputs Now They Are Jumping0 instead of outputting Now They Are Jumping2. This means that the code is not setting src.jumping to 2, but still outputting "Now They Are Jumping" message at the same time; which is weird because the code should set src.jumping=2 right before that output message.

Any help is appreciated, thank you for taking the time to read my code and the summary of what happened when said code was executed!
This would be because there are no turfs matching that path type in view(2). Try if(locate() in view())
In response to NNAAAAHH
NNAAAAHH wrote:
This would be because there are no turfs matching that path type in view(2). Try if(locate() in view())

Tried inserting if(locate(var/turf/Ground/G) in view()) and it gave me errors. Then I defined the variable outside of the if block and referenced it in the locate() proc which caused it not to enter the if() block.
Also, this time it doesn't go inside of the if block even if you're spawned right above the ground.

Some other variations I tried were if(locate(G in view())), if(locate(G) in view(2)), and if(locate(G in view(2))).

TL:DR;
var/turf/Ground/G; if(locate(G) in view()) world << "Check"
doesn't call the output to world.


Would it be a good idea if I used the bump proc and had the turf push the player back a pixel for every pixel the player goes into it?
locate(/turf/Ground). It doesn't make sense to declare a variable in there, and locate(G) is obviously locate(null) since G is null.
In response to Kaiochao
Kaiochao wrote:
locate(/turf/Ground). It doesn't make sense to declare a variable in there, and locate(G) is obviously locate(null) since G is null.

Would I instead create an instance of /turf/Ground (Using the new keyword) and check for world instead of view, then compare variables such as it's position via x/y/z?
In response to GameAnalysis
If you're trying to check if something is around, you shouldn't start by creating what you're looking for.
In response to Kaiochao
Kaiochao wrote:
If you're trying to check if something is around, you shouldn't start by creating what you're looking for.

I'm not sure if this context changes anything, but I'm checking for an object that has a position of (src.x, src.y-1, src.z) inside of the block (whether it be a for loop or an if block). If I were to create this object, change it's "appearance" to have no icon, and spawn it above the user before using locate(), would that fix the problem or would it still be an issue?
You can either do var/turf/Ground/G=locate() in view(2) then if(G) or if(locate(/turf/Ground) in view(2))

You don't need to create anything here. Only reason to define the turf as a variable is if you need to check/change a variable assigned to that turf.
You could just use get_step() to check the turf south of the mob, instead of defining the location that way.
#DEFINE NOT_JUMPING 0
#DEFINE JUMPING 1
#DEFINE JUMPING_2 2

/turf/ground
icon_state= "1"
density = 1
/mob
var/jumping = 0
/mob/proc/gravity()
if(jumping == JUMPING_2)
var/oldDir = src.dir
step2(SOUTH)
dir = oldDir
for(var/turf/Ground/G in view(2))
if(G.x == src.x && G.y == (src.y-1) && src.step_y == 0)
jumping = NOT_JUMPING
icon_state = ""
else if(jumping == JUMPING)
world << "They are not jumping"
for(var/turf/ground/Gr in view(2))
world << "Check"
if(!Gr)
src.jumping = JUMPING_2
world << "Now They Are Jumping"
if(Gr.y != (src.y-1) && Gr.x == src.x)
jumping = JUMPING_2
world << "Now They Are Jumping[jumping]"
sleep(0.5)
gravity()
/mob/proc/step2(var/direction) // this is terrible just use a while() loop
step(src,direction)
step(src,direction)


Work off of this. It's less terrible to read and removes all the un-needed colons, curly brackets, and un-needed "src."s. It also absolute paths it, so it's modern and stuff.

ps. this stupid text box thingy butchered some of it so you'll need to fix a bit
In response to Iamgoofball
A couple of problems there:

1) It's not at all clear what JUMPING_2 is for. Basically there should only be walking, jumping up, and either falling or returning from a jump (both falling, but maybe with different animations).

2) You have gravity() calling itself without spawning, so it'll create an infinite recursion and blow the stack. A loop would be more sensible. (That's a problem you carried over from the original code, but it still needs fixing.)
GameAnalysis wrote:
Context: The following code is a recursive gravity proc for a 2D Side Scrolling Non-Traditional Platformer
turf
> Ground
> icon_state="1";
> density=1;
> mob/var
> jumping=0;
> mob
> proc
> Gravity() {
> if(src.jumping==2) {
> var/oldDir=src.dir;
> step2(SOUTH);
> src.dir=oldDir;
> for(var/turf/Ground/G in view(2)) {
> if(G.x==src.x&&G.y==src.y-1&&src.step_y==0) {
> src.jumping=0;
> src.icon_state="";
> }
> }
> }
> else if(src.jumping==0) {
> world << "They are not jumping"
> for(var/turf/Ground/Gr in view(2)) {
> world << "Check"
> if(!Gr) { src.jumping=2; world << "Now They Are Jumping" }
> if(Gr.y!=src.y-1&&Gr.x==src.x) { src.jumping=2; world << "Now They Are Jumping[src.jumping]" }
> }
> }
> sleep(0.5);
> Gravity();
> }
> step2(var/direction) {
> step(src,direction);
> step(src,direction);
> }

Whenever the player's "jumping" var is set to 2 the code has no problem entering the for() loop to find turf/Ground/G in view, but for some reason it's not doing the same for my else if block immediately after that.

Whenever I run the game, my output consistently posts "They are not jumping", but it doesn't mention "Check" or "Now They Are Jumping[src.jumping]" even when I remove the statement that claims they are not jumping.
An even stranger thing that is happening is that whenever the player is positioned directly above an instance of turf/Ground the code outputs Now They Are Jumping0 instead of outputting Now They Are Jumping2. This means that the code is not setting src.jumping to 2, but still outputting "Now They Are Jumping" message at the same time; which is weird because the code should set src.jumping=2 right before that output message.

Any help is appreciated, thank you for taking the time to read my code and the summary of what happened when said code was executed!

http://puu.sh/il95o/2f88de3775.zip < super marioz i was bored one day.
In response to NNAAAAHH
Sorry for the late response! I was away for a long while.

NNAAAAHH wrote:
You can either do var/turf/Ground/G=locate() in view(2) then if(G) or if(locate(/turf/Ground) in view(2))

You don't need to create anything here. Only reason to define the turf as a variable is if you need to check/change a variable assigned to that turf.

You could just use get_step() to check the turf south of the mob, instead of defining the location that way.

Okay, I'll try these methods right away. Thanks!

Lummox JR wrote:
A couple of problems there:
2) You have gravity() calling itself without spawning, so it'll create an infinite recursion and blow the stack. A loop would be more sensible. (That's a problem you carried over from the original code, but it still needs fixing.)

Hm, okay. That makes more sense to do. Just to be sure and double check, should I use a while() or a do-while()?
Edit: Nevermind, I wasn't thinking properly. I should probably use a while loop since I'm not just executing one statement and it'd be a lot simpler IMO.


Iamgoofball wrote:
... removes all the un-needed colons, curly brackets, and un-needed "src."s...

Aren't semi-colons after statements and curly braces around functions good programming practices? Or am I just crazy?


Edit: Something I'm doing here is really wrong, but I can't put my finger on it.
mob/var
jumping=0;
hspd=8;
vspd=16;
mob
proc
Gravity() {
while(!(locate(/turf/Ground) in get_step(src,SOUTH))) {
world << "Check";
if(jumping==2) {
world << "2";
var/oldDir=dir; move(SOUTH,vspd); dir=oldDir;
return;
}
else if(jumping==0) { jumping=2; flick("run",src); world << "Falling"; }
sleep(0.5);
}
if(step_y==0) { jumping=0; icon_state=""; world << "Hit Ground" }
}
move(direction, speed) {
step_size=speed;
step(src,direction);
}

Output when Gravity() is called when jumping=0:
Check
Falling
Check
2

Whenever I remove the return statement though, it seems to work a bit too well. This meaning that even when turf/Ground is below src, it still continues the loop.
In response to GameAnalysis
GameAnalysis wrote:
Aren't semi-colons after statements and curly braces around functions good programming practices? Or am I just crazy?

They're only good programming practices if they're appropriate to the language. BYOND allows for them, but its core syntax doesn't really use them. Readability is actually better without them.

Same for the src.var stuff; unless you're using that to resolve the scope for two vars with the same name, it's just dead weight. (Doesn't hurt the proc any, since it compiles as src.var either way.)


Edit: Something I'm doing here is really wrong, but I can't put my finger on it.

You're trying to locate() a turf inside of a turf, which will always return null. What you want instead is istype().
In response to Lummox JR
Lummox JR wrote:
You're trying to locate() a turf inside of a turf, which will always return null. What you want instead is istype().

I don't completely understand what you mean. The locate proc is inside of a mob proc.
Or are you referring to:
get_step(src,SOUTH)
and saying that src in this instance is /turf/Ground and not the user? If this is the case, would I instead use "usr" instead of "src"?
This is your problem:

while(!(locate(/turf/Ground) in get_step(src,SOUTH)))

get_step() returns a turf. Therefore, you're trying to locate() a turf inside of another turf.

What you want instead is istype(get_step(...), /turf/Ground).
In response to Lummox JR
Thank you all so much for your help on this issue! I got it fixed and picked up on some good programming habits as well along the way!
In response to GameAnalysis
Glad you learned something, we all hope you continue this process and aren't ever afraid to ask for help to continue this process!

I got put off of helping and developing in general on BYOND, because no one ever does anything. I hope you're one of those few exceptions, not many people that come here for help continue to learn and grow into something here. It's disappointing, really.
In response to NNAAAAHH
NNAAAAHH wrote:
Glad you learned something, we all hope you continue this process and aren't ever afraid to ask for help to continue this process!

I got put off of helping and developing in general on BYOND, because no one ever does anything. I hope you're one of those few exceptions, not many people that come here for help continue to learn and grow into something here. It's disappointing, really.

I know what you mean. I used to be one of those people, but I grew and matured as the years go on. Granted, I'm still not fully mature, but my main obsession is definitely knowledge/research.
It seems that the attitude you mentioned isn't just BYOND, but also programming in general. Everyone says they want to be a programmer when they really just want to be a coder, and a coder isn't what game design is about.
Another reason I came up with is because people imagine it being less work than it is and get overwhelmed by it.