ID:149589
 
Ok I have this as my bump code and I can't get it to reconize the hull var of the item its hitting. Can anyone help me out here?

LJR


Bump(O)
if(ismob(O))
if(O.hull > 0)
world << "[who]'s [name] hits [O] for [damage] damage!"
O.hull -= damage
if(O.hull < 1)
If hull is a object var it would be Bump(obj/O) for mobs Bump(mob/M) etc..
LordJR wrote:
Ok I have this as my bump code and I can't get it to reconize the hull var of the item its hitting. Can anyone help me out here?

LJR
You know that O is a mob because it passed ismob(O), but the program still thinks of it as a generic variable, without any of the extras a mob has. You can create a variable that the program knows is a mob and assign it to O.


Bump(O)
if(ismob(O))
<font color=#FFFFA0>var/mob/M = O // create a mob alias for O</font>
if(<font color=#FFFFA0>M</font>.hull > 0)
world << "<font color=red>[who]'s [name] hits [<font color=#FFFFA0>M</font>] for [damage] damage!</font>"
<font color=#FFFFA0>M</font>.hull -= damage
if(<font color=#FFFFA0>M</font>.hull < 1)
In response to Nadrew
Nadrew wrote:
If hull is a object var it would be Bump(obj/O) for mobs Bump(mob/M) etc..

That is a bit misleading. Bump is called by the internal procs with an argument that can be any class of atom. (Maybe even non-atoms, but you'd have to create special cases to bump into something non-atomic.)

Declaring your own Bump(obj/O) proc will not filter out objs. Instead it stores whatever is passed to Bump as an obj. If you bump a turf, it will be treated as a obj and as soon as your proc accesses an obj var that turfs don't have, you will get an error. You should make sure that O is actually an obj first.
In response to Shadowdarke
I've tested this and it works:

mob
Bump(obj/O)
if(isobj(O))
src << "[O] is an object."
else
src << "[O] isn't an object."


It seems passing obj/O into the argument doesn't effect when it's called. Adding the isobj() check takes care of what you just pointed out. You could use istype() for more specfic types:

mob
Bump(obj/O)
if(istype(O,/obj/someobj))
src << "[O]'s type is someobj."
else
src << "[O]'s type isn't someobj."


Both work fine.
In response to Nadrew
Both work fine.

Yes, they do. However, try the following.

mob
Bump(obj/O)
O.Move(get_step(O,WEST))

and run into a dense turf.
In response to Spuzzum
The way Nadrew did it eliminates the need to create a new variable. Just include the isobj() as he did and it's fine. Byond seems to have a very loose system of type conversions where virtually any type of information can be stored in almost any variable. You can store mobs in object variables during runtime without much problem, it's just that the compiler won't catch errors that can be caused by this (such as trying to access variables or verbs that it doesn't have) so you need to have checks like isobj().

I'm speaking purely from experience (which I suppose most of you have more of :p) so I could be wrong in some aspects of what I'm saying, I've never actually read anything official on how it handles type conversions.
In response to English
English is correct. I added isobj() to get rid of the possible errors when bumping into a turf with obj passed into the argument. I know what it's like forgetting to check if something is a certain type when using Bump() and getting a slew of runtime errors when I do.
In response to Nadrew
Nadrew wrote:
English is correct. I added isobj() to get rid of the possible errors when bumping into a turf with obj passed into the argument. I know what it's like forgetting to check if something is a certain type when using Bump() and getting a slew of runtime errors when I do.

Sigh. That wasn't my point, though.

It's much wiser to make sure you type all of your variables based on EVERYTHING they could possible be.

For example, if the proc

proc/Sporknife()

were supposed to take one argument that could either be a mob or an obj, never EVER should you put:

proc/Sporknife(mob/M)
if(isobj(M))
//do this
else //it's a mob!
//do that

Rather, it should be

proc/Sporknife(atom/movable/O)
if(isobj(O))
//do this
else
//do that

It might not matter to you one way or the other, but when other people read your code, it will be very confusing: when you're typing something as "mob/M" in your proc definition, people are going to assume that it will only accept mob arguments.
In response to Spuzzum
It might not matter to you one way or the other, but when other people read your code, it will be very confusing: when you're typing something as "mob/M" in your proc definition, people are going to assume that it will only accept mob arguments.

Well, it basically will ONLY utilize mob arguments (with proper tests in place). If you send it a turf, obj, or any other type then it won't do anything.

In byond every proc will accept every argument, it just might not utilize it.

If I skimmed over a proc called Destroy_Thing(var/atom/A) I would assume it will destroy any atom I send it. The way your suggesting it would only destroy mobs but appear to be accepting all atoms. With a proc called Destroy_Thing(var/mob/M) it would be much clearer that it is intended to destroy a mob.
In response to English
English wrote:
It might not matter to you one way or the other, but when other people read your code, it will be very confusing: when you're typing something as "mob/M" in your proc definition, people are going to assume that it will only accept mob arguments.

Well, it basically will ONLY except mob arguments. If you send it a turf, obj, or any other type then it won't do anything.

The example I gave accepted both mob and obj arguments, and still would have caused problems if it was provided a turf or area argument and the user assumed that the else meant it was a mob. The "mob/M" was illustrating a point in that it could accept objs which would be stuck into a var/mob/ variable. This means that it would assume that that obj was a mob when it wasn't. You should always try to make variables general and then make them more specific once you've verified their types.

Eg.

area/creepy_zone/Entered(atom/movable/O) //make variable general
if(ismob(O)) //verify type
var/mob/M = O //make variable specific
M << "You enter an area that makes the hair on the nape of your neck stand on end."

It *will* work just to say:

area/creepy_zone/Entered(mob/M)
M << "You enter an area that makes the hair on the nape of your neck stand on end."

but you will not be guaranteed that M is indeed a mob. Thankfully, BYOND ignores non-mob output for you.


In byond every proc will accept every argument, it just might not utilize it.

mob/Bump(obj/O) will gladly accept and utilize a mob or turf argument unless steps are taken to prevent that. I can understand that you aren't really disagreeing there, but to illustrate the point better, simply saying var/obj/O is not enough to tell BYOND that O will be an obj. BYOND will simply assume that O is an obj.

The key is to make people aware of what the code will do, not to just get away with a hacky "well, it works anyway" solution. You'll be thankful you did because in 15 months, if a new BYOND release somehow makes your proc not work right, you'll be confused as to why it is trying to modify an obj when the parameter is clearly a mob.
In response to Spuzzum
Oops, I didn't see that part about either mob or obj. Sorry about that. I was speaking purely about wanting one specific type. If multiple types are wanted then the most general case should be the type of the variable (which I think is basically what you said). Meaning, if you want an obj or a mob you should use atom/movable. If you want an obj, mob, or turf you should use an atom.

In this particular case you know you want an obj so I think it would be just fine to use var/obj/O in conjunction with the proper testing statements. If an obj or a mob was wanted (for example) then var/atom/A should be used.