ID:140167
 
Code:
turf
JailBorder
icon = 'Border.dmi'
RedTop
icon_state = "red"
density = 1
Enter(mob/M)
if(istype(M))
if(M.team == 2)
return
src << output("What are you doing? Trying to release the oponent?!","log")
else if(M.team == 1)
if(Red_Jail_Broken == 0)
if(M.dir == SOUTH||SOUTHEAST||SOUTHWEST)
Red_Jail_Broken = 1
src.density = 0
src.icon_state = ""
view(10,src) << "<font color=red>Quickly, red team, escape!</font>"
sleep(70)
src.density = 1
src.icon_state = "red"
Red_Jail_Broken = 0
else return


Problem description:

So I have 2 teams. The #1 team is red team, #2 team is blue team. So when a blue red guy gets in jail he needs a red guy to attempt to enter one of the turfs from the outside. The only issue is that my code does not check the direction. I can go north with a red guy in the red Jail and the jail will still dissapear, I only want red guys going say, south, which would be from the outside, to be able to "open" the jail. Another issue is that the turfs do not become dense. I am wondering if for some reason I am not allowed to change a turf's density at runtime.

Please Help, And Thank-You.
Darkjohn66 wrote:
Code:
> turf
> JailBorder
> icon = 'Border.dmi'
> RedTop
> icon_state = "red"
> density = 1
> Enter(mob/M)
> if(istype(M))
> if(M.team == 2)
> return
> src << output("What are you doing? Trying to release the oponent?!","log")
> else if(M.team == 1)
> if(Red_Jail_Broken == 0)
> if(M.dir == SOUTH||SOUTHEAST||SOUTHWEST)
> Red_Jail_Broken = 1
> src.density = 0
> src.icon_state = ""
> view(10,src) << "<font color=red>Quickly, red team, escape!</font>"
> sleep(70)
> src.density = 1
> src.icon_state = "red"
> Red_Jail_Broken = 0
> else return


Problem description:

So I have 2 teams. The #1 team is red team, #2 team is blue team. So when a blue red guy gets in jail he needs a red guy to attempt to enter one of the turfs from the outside. The only issue is that my code does not check the direction. I can go north with a red guy in the red Jail and the jail will still dissapear, I only want red guys going say, south, which would be from the outside, to be able to "open" the jail. Another issue is that the turfs do not become dense. I am wondering if for some reason I am not allowed to change a turf's density at runtime.

Please Help, And Thank-You.

Im not sure but you can try this:
<dm>
turf
JailBorder
icon = 'Border.dmi'
RedTop
icon_state = "red"
density = 1
Enter(mob/M)
if(istype(M))
if(M.team == 2)
return
src << output("What are you doing? Trying to release the oponent?!","log")
else if(M.team == 1)
if(Red_Jail_Broken == 0)
if(M.dir == SOUTH||M.dir ==SOUTHEAST||M.dir==SOUTHWEST)
Red_Jail_Broken = 1
src.density = 0
src.icon_state = ""
view(10,src) << "<font color=red>Quickly, red team, escape!</font>"
sleep(70)
src.density = 1
src.icon_state = "red"
Red_Jail_Broken = 0
else return
                        return
src << output("What are you doing? Trying to release the oponent?!","log")


The output is never reached because return stops the procedure.

                            if(M.dir == SOUTH||SOUTHEAST||SOUTHWEST)


This is always true. I assume you want if(M.dir in list(SOUTH, SOUTHEAST, SOUTHWEST)), or even more straightforward, if(M.dir & SOUTH).

                                Red_Jail_Broken = 1
src.density = 0
src.icon_state = ""
view(10,src) << "<font color=red>Quickly, red team, escape!</font>"
sleep(70)
src.density = 1
src.icon_state = "red"
Red_Jail_Broken = 0


Absolutely none of this belongs in Enter(). Replace this whole thing with a "return ..()" to allow entry. Handle whatever happens as a result of entering the turf, then, in Entered().
There are a number of both design flaws and errors in this code. I suggest fixing both, since poor design will only come back to haunt you again.

The first thing you need to change is that this "team jail" turf or area should be generic. An area would make more sense than a turf for this purpose, but you can still use turfs if you prefer. The best way to set this up is to give it a team name like "red" and then check the team var of whoever's trying to get in. Then your teams aren't 1 and 2, but the more sensible "red" or "blue" or what have you. Any object in the game can be given a simple team var that will say who it belongs to.

As an example, consider this code:

atom/var/team

area/jail
var/jailbreak

// Not using Enter() because there is no point in not letting the same team in.
Entered(mob/M)
if(istype(M) && M.team != team)
// Do this so a mob entering after capture won't trigger a jailbreak
if(M.captured)
M.captured = 0
return
if(!jailbreak)
jailbreak = 1
for(var/turf/T in src) T.icon_state = "jailbreak"
for(var/mob/M2 in players[team]) M2 << "<font color=[team]>Jailbreak!</font>"
for(var/mob/M2 in src)
if(M2.team != M.team)
M2.team << "<font color=[M2.team]>Quickly, escape!</font>"
spawn(70)
jailbreak = 0
for(var/turf/T in src) T.icon_state = initial(T.icon_state)

Exit(mob/M)
if(istype(M) && M.team != team && !jailbreak)
return 0
return ..()


This code as you see is much simpler and it can be used for either team, which means you don't have to retype practically the same code to use it on another team. This means less work for you and less chance of something going wrong in the code. Enter() does not restrict players on the same team from entering the jail area. Entered() is the only thing that reacts; if a player of the other team enters, a jailbreak occurs--if they didn't enter because they were captured. Exit() keeps the jailed players in, by returning 0 if the jail is still locked, but it lets anything else through.

As a bonus, this method also doesn't require a bunch of very similar vars like Red_Jail_Broken, Blue_Jail_Broken, etc. Whenever you see vars like that it's usually evidence of a design flaw. Such vars should be organized another way, like by keeping them in a datum or in this case an area.

If you were to stick with your existing code, these are some of the errors or problems you'd need to fix:

1) if(Red_Jail_Broken == 0) is not a good way to handle true/false checks. That should be if(!Red_Jail_Broken) which is more robust.

2) if(M.dir == SOUTH||SOUTHEAST||SOUTHWEST) will always equate to if(1). The reason is that M.dir==SOUTH, SOUTHEAST, and SOUTHWEST are all separate expressions. SOUTHEAST and SOUTHWEST are both true values. What you really wanted was if(M.dir==SOUTH || M.dir==SOUTHEAST || M.dir==SOUTHWEST). But since dirs use bitflags, an even easier approach is if(M.dir & SOUTH).

Lummox JR
In response to Lummox JR (#3)
Thanks for the detailed post lummox. While I will follow everything you said, I feel that, mathematically and logically, everything just makes more sense [to me] if it equals say a 0 for false or 1 for true.
In response to Darkjohn66 (#4)
Darkjohn66 wrote:
Thanks for the detailed post lummox. While I will follow everything you said, I feel that, mathematically and logically, everything just makes more sense [to me] if it equals say a 0 for false or 1 for true.

Well obviously a 1 is true and a 0 is false; I don't mean you should choose different values to mean true and false. I mean you should write your code robustly.

Robust programming requires that you prepare for the unexpected, and a value being null when you expected a 0 is not at all unusual. Doing this the right way is not only safer, but it's shorter and produces cleaner-looking code.

// wrong
if(tf_value == 1)
// right
if(tf_value)

// wrong
if(tf_value == 0)
// right
if(!tf_value)


As long as the value you're using is only used for a true or false test, then you should never ever compare it to 1 and 0 directly, but always use it directly in the if(). Note that in both cases the code is cleaner when it's done the right way. if(!tf_value) will also catch unexpected nulls or empty strings, which can render moot some potential errors that would otherwise mess up the logic in your game. Likewise if(tf_value) will catch true values other than just 1.

So if you meant you wanted to stick with 1 meaning true and 0 meaning false, I agree--that's really the only sensible choice. But if you meant you felt it's better practice to use ==1 and ==0 to test for truth or falsehood, then that's wrong. Robust programming is absolutely paramount; switching to robust techniques will save you and your players many, many headaches, even if it seems unwieldy to you at first. (And it's not unwieldy at all; it's just not what you're used to. You've been making way more work for yourself doing it the wrong way.) The whole point about not using redundant vars and code and redesigning your teams/areas/etc. more flexibily goes hand in hand with that.

Lummox JR