ID:271679
 
I want to make a statement that if you kill a monster you get it's exp so it would be like

My current Procs
DeathCheck()
LevelUp()

if(DeathCheck(M) == true)
usr.exp += M.exp
if(usr.exp == usr.maxexp)
LevelUp()
return



Believe me i know that isn't correct but if that's even possible to do how would i make something like that work correctly. Please explain in lame mans terms I don't understand all the language words really.
Looks good to me with a few minor issues. I'll go line by line.

Line 1:
 if(DeathCheck(M) == true)


When checking to see if a value is true or or false(null), just do if(value). So replace that with
 if(DeathCheck(M))


For future reference, if you wanted to check if it was false, you would do:
 if(!DeathCheck(M))


Line 2:
     usr.exp += M.exp


At first glance this appears okay, but it all depends on how your DeathCheck() proc looks. Does your DeathCheck() delete the dead monster? If so, M no longer exists, so you've got a runtime error. If not, well then, it's fine. :)

Line 3:
         if(usr.exp == usr.maxexp)


Say I have 99 exp with a maxexp of 100, I kill a monster that gives me 2 exp points. I now have 101 experience points, which is NOT equal to my maxexp. I will never level up. Use greater than or equal to (>=) instead)
         if(usr.exp >= usr.maxexp)


Line 4:
             LevelUp()

If you want to call the LevelUp() proc belonging to the usr, just to be safe, you might want to change that to usr.Levelup(). Either that or learn to use arguments.
             LevelUp(usr)

//elsewhere in your code...
mob/proc/LevelUp(mob/M) //M is the argument, of a mob type.
M << "You leveled up!" //Example of the argument in action.
M.level++


Line 5:
             return

Should be fine. You don't always need to explicitly return stuff unless it would otherwise continue, but it's a good habit to have. I do it myself.
In response to Zagreus
Aside from the fact that his DeathCheck() procedure should probably handle all of this stuff directly, if he wanted to do this he'd have to make his DeathCheck() return a value.

mob/proc/DeathCheck(mob/theKiller)
// Death check stuff here.
return 1
mob/verb/Slay(mob/theTarget as mob in world)
theTarget.healthPoints = 0
if(theTarget.DeathCheck(usr)) world << "[theTarget] has been slain by [usr]!"
else usr << "Err... It didn't work for some reason."





Not sure why you deleted your post, but it WAS full of issues, so you might be interested in what I typed out here:

Okay, now that I'm seeing the whole thing, we have some really big problems.

First, never ever, use usr in a proc. usr is the mob belonging to the client that directly initiated an action like a verb or click() or what not. Using it outside of client-called procs is just asking for errors.


Line 3:
        Damage()

This is where you have to define an argument. before you decide what the argument is, we need to look at two ways that this proc could work:

  1. The proc belongs to the mob taking damage (most probable)
  2. The proc belongs to the mob dealing damage


I'm going to assume it's 1. So we now know that src is the victim. We need to define the attacker. We know the attacker is a mob, so we need to allow the proc to accept an argument of a mob type.

        Damage(mob/attacker)

I always opt for descriptive arguments, but you could just as well do mob/M or whatever.

Now, we need to actually pass the argument to the proc. So find your attack verb, that probably looks something like this:
mob/verb/attack(mob/M as mob in oview(1))
M.Damage()
<dm>

And change it to pass the usr as an argument.
<dm> M.Damage(usr)


Okay, next line!
            if(M.defense > usr.reiatsu)

In your original code, this doesn't work at all, because M doesn't exist and we have no idea what exactly usr is. The proc belongs to the mob taking the damage, and you can use src within procs to reference the source or owner. So lets change it to this:
            if(src.defense > attacker.reiatsu)


next:
                damage = 1

Where is damage defined? is damage a mob var belonging to the mob being attacked, or is it just something used internally within this proc? If it's the latter, then you need to define it as a variable.
                var/damage = 1



Next:
                src<<"[src] hits [M] for [damage] damage!"
> M<<"[src] hits you for [damage] damage!"

To take your original code and clean it up to use our revised method using arguments, it would be:
                attacker<<"[attacker] hits [src] for [damage] damage!"
> src<<"[attacker] hits you for [damage] damage!"


However, this would look kinda funny.
I hit you and see: Zagreus hits Soul Society Productions for 1 damage!
You see: Zagreus hits you for 1 damage!

No one else sees anything.

I propose tweaking the first line, and adding a third.
                attacker<<"You hits [src] for [damage] damage!"
attacker.oview()-src<<"[attacker] hits [src] for [damage] damage!"
> src<<"[attacker] hits you for [damage] damage!"

NOW, I hit you and see: You hit Soul Society Productions for 1 damage!
You see: Zagreus hits you for 1 damage!
People in my view, excluding you see: Zagreus hits Soul Society Productions for 1 damage!

Now for your return, which does have an issue:
                return

You're ending the proc right here. But you're dealing damage. You're never calling deathcheck, so even if I'm only doing 1 damage. Say I you have 1 HP and I hit you. It never checks to see if you're dead.

Second half of your proc: You should be able to figure it out based on the above, so lets skip to the deathcheck part again.

                if(DeathCheck(M))//src NOT M
del M //PROBLEM HERE
usr.exp += M.exp //attacker NOT usr, src NOT M
if(usr.exp >= usr.maxexp)//attacker, not usr
LevelUp(usr)//attacker, not usr
return


See the line that says PROBLEM here? You're deleting the mob, and then trying to assign the mob's experience to the attacker. That'll result in a null.exp runtime error.

But that's not all. Deleting the source of the proc ends the proc.

The solution? Just replace that final return with del src and take your del M out of there.

I would advise the following:
mob
proc
Damage(mob/attacker)
var/damage //Create a new variable called damage for use within this proc only
if(src.defense > attacker.reiatsu)
damage = 1
else //We're checking the opposite of the first IF, so we can just do an ELSE
damage = round(attacker.reiatsu/2.25)
damage -= src.defense / 2
//I moved the chat stuff outside of the ifs so we only need to do it once instead of twice.
attacker.oview()-src<<"[attacker] hits [src] for [damage] damage!"
attacker << "You hit [src] for [damage] damage!"
src<<"[attacker] hits you for [damage] damage!"
//Also moved deathcheck to outside of the ifs, so it happens regardless of if you hit for 1 or not.
if(DeathCheck(src))
attacker.exp += src.exp
if(attacker.exp >= attacker.maxexp)
LevelUp(attacker)
del src
In response to Zagreus
Thank you very much for fixing that. Though i had to edit it, because that damage calculator has the tendency to take the damage below 0 so i had to change it to this:
mob
proc
Damage(mob/attacker)
var/damage
damage = round(attacker.reiatsu/2.25)
damage -= src.defense / 2
if(damage <= 0)
damage = 1
attacker.oview()-src<<"[attacker] hits [src] for [damage] damage!"
attacker << "You hit [src] for [damage] damage!"
src<<"[attacker] hits you for [damage] damage!"
if(DeathCheck(src))
attacker.exp += src.exp
if(attacker.exp >= attacker.maxexp)
LevelUp(attacker)
del src



Procs.dm:58:error:attacker.oview:undefined proc

I do realize I am newbish at coding but im slowly getting better. I really appreciate all the help that your giving me.
In response to Zagreus
LevelUp(attacker) is not correct. A levelup proc should pretty much never take an argument, because it needs only one piece of information: the mob who's leveling up. That mob should be src within that proc, since the action entirely concerns them, so the call should be attacker.LevelUp().

Lummox JR
In response to Lummox JR
Good point. :) I had just used it as an example to show him arguments earlier because I think arguments are ultra cool, but you're definitely right. In this situation arguments are kinda wasteful.

Now, why on earth wouldn't his oview() be recognized? It's a built in atom proc, and attacker is definitely defined as a mob.
In response to Blagh Nabbit
            if(damage <= 0)
damage = 1
attacker.oview()-src<<"[attacker] hits [src] for [damage] damage!"
attacker << "You hit [src] for [damage] damage!"
src<<"[attacker] hits you for [damage] damage!"


If damage is less than or equal to 0, set damage to 1 and output this text.

However, if I were to hit you for 42 damage, there would be absolutely no text output at all because all the text is indented under the above if.

It goes through everything under your if if true, then continues with the rest of the proc. So put your outputs with the rest of the proc by taking one indentation off the last three lines there, and it'll display either way.


By the way, not necessary at all, and some people actually don't like doing it, totally personal preference and stuff. But when you have a single line of code after an if(), you can just put it on the same line as it.

if(damage <= 0) damage = 1
//output stuff here


I would advise against this for more complex things(can make debugging errors by line number harder), but for simple assignments and returns, it's usually fine.
In response to Zagreus
Zagreus wrote:
Now, why on earth wouldn't his oview() be recognized? It's a built in atom proc, and attacker is definitely defined as a mob.

Close. oview() is a global proc, and one of the arguments would be the atom you're referring to. Instead of attacker.oview(), he should be calling oview(attacker).

Hiead
In response to Zagreus
Zagreus wrote:
Good point. :) I had just used it as an example to show him arguments earlier because I think arguments are ultra cool, but you're definitely right. In this situation arguments are kinda wasteful.

Now, why on earth wouldn't his oview() be recognized? It's a built in atom proc, and attacker is definitely defined as a mob.

oview() isn't an atom proc; it's a global proc. It takes an atom and a range as an argument. If you leave out the atom it defaults to usr, and if you leave out the range it defaults to world.view. So he actually needs to change attacker.oview() to oview(attacker).

Lummox JR
In response to Lummox JR
Doh! Thank you very much.(both you and Hiead).

I would have realized that if I had been actually put some thought into it, but the resent release of an alchemy system in my favorite MUD and 3 straight days of playing GemStone IV, brewing potions over and over again, have turned my brain to mush. :)