ID:1102152
 
A lot of sources I see bridge 2 different places by making 2 different areas for each place. This method is a pain in the neck and completely unnecessary. You shouldn't have to type area/tox_fromy and area/toy_fromx.

area/bridge
var/ID
Enter()
for(var/area/bridge/B in world)
if(B.ID == src.ID)
if(B == src)
return
else
usr.loc = B.loc


Basically, what this does is detects if there is another area out there with the same ID is it when a player walks in to it. If this is the case, then it makes sure that it's not just referring to itself, and makes the player go to the other area.

EDIT: Whoops, I forgot to include 2 ='s. Sorry for any confusion.
A few things:

Firstly, Entered() is more suited for this. Enter() is meant to be the event that determines whether or not you can, well, enter the tile. Entered() is an event fired after Enter() has occured.

Secondly, you shouldn't be using usr within Enter() (or Entered()). If a non-mob were to wander onto the tile, it would generate a runtime error because it wouldn't know what usr is.
What variable should I use to substitute for usr?
In response to BeignetLover
Preferably you would typecast, something along the lines of:

area/bridge
Entered(mob/m)
if(!ismob(m)) return

m.loc = someLoc
area/bridge
var/ID
Entered(atom/A)
for(var/area/bridge/B in world)
if(B.ID == src.ID)
if(B == src)
return
else
A.loc = B.loc


For the sake of immersion, I made it so anything can pass through. If anyone using this code disagrees, see LordAndrew's edit above.
Take note that an area's loc var is null. You'd have to go for A.loc = locate(B.x,B.y,B.z).
You actually want to use Enter() and then write CanEnter()

Otherwise, players can just stand in the area and block it forever.

area/bridge
var/tmp/id = 0

Enter(atom/movable/a)
if(CanEnter(a))
DoAllow(a)
else
DoReject(a)
//or just handle return ..() / return 0 if you'd like
proc/CanEnter(atom/movable/a)
return 1//write logic when you create your own bridge type, this is "abstract"
proc/DoAllow(atom/movable/a)
return //doesn't do anything, this is abstract
proc/DoReject(atom/movable/a)
return //doesn't do anything, this is abstract
area/bridge/basic
CanEnter(atom/movable/a)
if(ismob(a)) return 1
return 0
DoAllow(atom/movable/a)
//i don't agree with the following code, but here it is for completeness sake
for(var/area/bridge/b in world)
if(b.id == src.id)
if(b == src)
return
else
//set a's location some how
DoReject(atom/movable/a)
a << "You can't enter [src]."
In response to FIREking
For that, you can allow your players to Enter the area. For everything else, do the default action.
area/bridge
Enter(atom/movable/atom)
if(ismob(atom))
return 1
return ..()

EDIT: Actually, this should be handled by a turf's Enter proc since it's the one that handles the obstacles.
In response to Jemai1
Jemai1 wrote:
For that, you can allow your players to Enter the area. For everything else, do the default action.
> area/bridge
> Enter(atom/movable/atom)
> if(ismob(atom))
> return 1
> return ..()
>


User can override this as he sees fit. I'm not here to potty train haha. Writing the logic directly in there prevents any expandability without providing basic functionality. You'd have to re-write the entire procedure if you ever want it to function differently. That's why the CanEnter() layer is there, so you can decide what is allowed to enter it.

Suppose you want to make a bridge that bears can't enter. Can be coded in four lines...

area/bridge/nobears
CanEnter(atom/movable/a)
if(istype(a, /mob/bear)) return 0
return 1


Now even if someone is standing in the way of the area, a player can still attempt to enter it and successfully travel through the area bridge, and bears won't be able to enter the bridge.
In response to FIREking
That's what Enter is designed for.. >.>
area/bridge/nobears
Enter(atom/movable/a)
if(istype(a, /mob/bear)) return 0
return ..()

Basically, it determines what can enter and what cannot.
In response to Jemai1
Jemai1 wrote:
That's what Enter is designed for.. >.>
> area/bridge/nobears
> Enter(atom/movable/a)
> if(istype(a, /mob/bear)) return 0
> return ..()
>

Basically, it determines what can enter and what cannot.

And if you want to change something about the overall order of the logic, or something else, you'd have to go edit the code for every area/bridge instead of just changing it in the parent type. Which is why I provided CanEnter(). This is future proofing code and preventing giant refactoring projects.
In response to FIREking
Well, you'll have the same experience with CanEnter.

Having things modular is good and all but what you are doing is duplicating procs (Enter vs CanEnter). Because of this redundancy, people, even you, will get confused on which is which.

Also, you broke the default movement. One will assume that Entered will be called when he successfully moved into that area. If movement wasn't successful, Bump will be called. However, this no longer happens as you always return a false value on Enter.

Long story short, Enter is responsible for determining if a movable object can enter an atom. It returns 1 to permit entrance; 0 to deny. Aside from that it does nothing else. For successful movement, Entered is the one for the job.
If the main concern here is the player blocking the area after entering it, can't you just use step_away?
In response to Jemai1
Jemai1 wrote:
Well, you'll have the same experience with CanEnter.

Having things modular is good and all but what you are doing is duplicating procs (Enter vs CanEnter). Because of this redundancy, people, even you, will get confused on which is which.

Also, you broke the default movement. One will assume that Entered will be called when he successfully moved into that area. If movement wasn't successful, Bump will be called. However, this no longer happens as you always return a false value on Enter.

Long story short, Enter is responsible for determining if a movable object can enter an atom. It returns 1 to permit entrance; 0 to deny. Aside from that it does nothing else. For successful movement, Entered is the one for the job.

Well it doesn't confuse me, I know the difference between what happens by default, and where I've injected behavior. I overrode the default behavior (ignoring bump, etc) on purpose. If I wanted to allow that to happen in the future, I could just change Enter() in area/bridge. That's the point of having a CanEnter(). CanEnter() will still answer the question, What can enter? without changing the basic logic of the abstract class. In area/bridge, we removed the default functionality on purpose. Now you have the opportunity to add it back in later without re-factoring anything.

There is a well defined difference between Enter() and CanEnter(). Enter is not only responsible for determining if a movable object can enter an atom, it provides basic logic of what is supposed to happen if something is allowed or not allowed to enter. On the other hand, CanEnter() only answers a question! (and should only answer a question, nothing more). I know that if I want to keep the way the question is answered the same, yet add default functionality back in, I can change the code like this:

area/bridge
Enter(atom/movable/a)
if(CanEnter(a))
spawn DoAllow(a)//happens after return ..()
return ..()
else
spawn DoReject(a)//happens after return 0
return 0

area/bridge/nobears
CanEnter(atom/movable/a)
if(istype(a, /mob/bear)) return 0
return 1
//still answers our question, but we've changed how all areas work by default now


Resting my case, this makes sense to me, and I'm not an expert programmer, but my code base is easy for me to manage, so maybe the same principles will help someone else. I can't agree that this is a bad way to structure things, so I continue to defend my case.
In response to BeignetLover
BeignetLover wrote:
If the main concern here is the player blocking the area after entering it, can't you just use step_away?

If you want to forcefully move players, sure. If you don't, you can do it my way.
In response to BeignetLover
The recent convo got me confused. Changing the area's Enter proc doesn't really help since the turf's Enter proc will be evaluated before it. Letting players pass though each other (via Cross) on certain locations is what I'll probably do.