ID:4289
 
Many of us have tried to interact between different types of atom and have mostly succeeded. But success doesn’t mean you did it right.

turf/Enter()

Enter() is only called when something moves onto the turf. It is useful because one can decide whether or not to let the thing Enter()ing enter or not. It is no place to be doing any programming in which you’re going to do anything not related to simply allowing entry or not – such as teleportation to other locations or display messages to the thing Enter()ing. Enter() should only be used to decide whether or not to let the thing Enter()ing enter or not. To do this, you must return values. 1 if you want the thing to enter or 0 if you don’t want the thing to enter. One example showing this would be:

Image hosted by Photobucket.com

Enter() can also be used to get past density checks. If you return 1 and if density exists, you would still Enter() the turf.

In no case however must you assume that the thing Enter()ing will be a player, or even a mob for that matter. It is vital that you run checks before doing anything. Here’s an example showing what not to do:

Image hosted by Photobucket.com

Ok sure this’ll run fine when you go and test it, but have you really thought of all possibilities? What happens if a non-client Enter()s? Or what if it’s an obj that is Enter()ing? You’re just assuming that there’s a usr there – and in programming, you don’t assume.

First, we need a way to refer to the thing that is Enter()ing. You can do that easily by defining a variable in turf/Enter(). But you can’t just do turf/Enter(mob/M) because it could easily be an obj that’s Enter()ing. You would get a runtime error like runtime error: undefined variable /obj. We know only something that can Move() will be able to Enter() our turf, therefore we can say that atom/movable will always be safe.

Next we must check to see whether or not the thing Enter()ing is a mob or an obj. A simple ismob() and isobj() test will figure that out. After running one, you should refer to the variable atom/movable/A as var/mob/M or var/obj/O if you plan on accessing mob/obj specific variables and/or procs.

turf/Entered()

This is where you should do programming that happens after the thing has successfully Enter()ed - such as teleportation or displaying messages to the thing that Entered(). It is called only when Enter() returns 1. It won’t be called if Enter() returned 0.


Everything said for Enter() applies to Entered() so there’s no point in repeating what is already written above.

A very useful function of Entered() is that we can know where the thing that Entered() is coming from. To do this, simply put a second argument for turf/Entered() and then you can refer to the old location. Uses include getting the distance between the two locations, checking if they came from the right place and sending them back to the old place too.

Ok so we’ve figured out how to get interaction between turfs and movable atoms, but what about interaction between just movable atoms?

Bump()

This is one of the most misunderstood procs I’ve ever seen. The way it works is that the atom you define Bump() for will be the thing that has to move and collide with something to call Bump() and the thing you define within the Bump() will be the thing collided.

For example:

Image hosted by Photobucket.com

In this, considering something has caused obj/Knife to move, if the Knife collides with a mob or an obj that has density, Bump() for the Knife will be called.

Again you must not assume that the thing you’re Bump()ing is a player/client/mob/obj, you need to know! Similar checks used in turf/Enter() will be necessary here. First define the thing that is getting collided. Next, check if it’s a mob or an obj and then define a variable for it accordingly.

There is no place for usr in Bump()

An example of a strong Bump() system:

Image hosted by Photobucket.com

Bumped()

In some cases, you may not want to Bump() something but rather have that thing be Bumped() instead. There is no Bumped() proc defined in the DM language, but it is simple enough to make your own. Here is an efficient one I’ve found on the forums:

Image hosted by Photobucket.com

Bumped() works exactly like Bump() only instead of defining the thing Bump()ed, we define the thing that’s Bump()ing.

If you do include Bumped() in your projects, be sure to realize that both Bump() and Bumped() won’t be called in a collision between two atoms.

Image hosted by Photobucket.com

In this case, all you’ll ever see is “The knife hit the victim”. You won’t ever see “Victim got hit by the knife” because Bump() takes precedence over Bumped().

In conclusion of all interaction: Always have variables know what are the two things involved in the interaction. Run validity checks. Do relevant-to-the-game programming last. Don’t use usr!
Nice article, I can never remember which way Bump() goes.

"In this case, all you’ll ever see is “The knife hit the victim”. You won’t ever see “Victim got hit by the knife” because Bump() takes precedence over Bumped()."

I don't understand that, could you clarify?
In your code example you didn't call bumped() at all!
In the example shown, the knife can been moved.

If the knife strikes /mob/victim, it'll only ever say "The knife hit the victim" even though we've said under /mob/victim to say "The victim was hit by the knife".

One would think that both Bump() (for the knife) and Bumped() (for the victim) would be called, but they're not - only Bump() for the knife is.

You can override this feature though, the article was pointing out the default action.
Bumped() works exactly like Bump() only instead of defining the thing Bump()ed, we define the thing that’s Bump()ing.
exacly from the article read the def