ID:157079
 
Is there a better way of doing this? If so, could you give an example? Because this is the best way I could think of doing it.

mob/proc/Damage(A,B,C,D)
src.HP-=A
src.MP-=B
src.HP+=C
src.MP+=D
EvenOut()
DeathCheck()
..()
mob/proc/DeathCheck(src as mob)
if(HP<=0)
world << "<B>[usr] has killed [src]!"
mob/proc/EvenOut()
if(HP>MaxHP)
HP=MaxHP
if(MP>MaxMP)
MP=MaxMP
if(MP>0)
MP = 0
if(HP>0)
HP = 0
You're doing good, but there's a few things you got wrong. In Damage and EvenOut, you need to define a mob being affected. And in DeathCheck, you used usr in a proc, which is a very bad thing to do. There are some places where usr can be used in a proc, but that is not one of them. Define two mobs as arguments, one for the killer and one for the victim. But you haven't hard-coded anything, which is good, and you get what procs are used for, which is also good.
Well, if the damage check is that simple, you can just use negative values in A and B if you want to increase them.

Also, his procs are all attached to a mob as src, so I don't get what you mean by define a mob being affected.
In response to Warlord Fred
Alright, I revised it a bit, I'm pretty sure I am good with this now. I am going to try to now work on displaying numbers on the HUD. It is really complicated though, I may just do it in an inefficient way because I do not understand how libraries such as Lummox's works. (I'll be back asking for help XD)
Anyways:
mob/proc/Damage(A,B)
src.HP+=A
src.MP+=B
EvenOut()
DeathCheck()
..()
mob/proc/DeathCheck(mob/killer)
if(HP<=0)
world << "<B>[killer] has killed [src]!"
mob/proc/EvenOut()
if(HP>MaxHP)
HP=MaxHP
if(MP>MaxMP)
MP=MaxMP
if(MP>0)
MP = 0
if(HP>0)
HP = 0
In response to Darkjohn66
Advice revoked.
Yes. Yes, there is a better way of doing this. For one, let's learn something about Dream Maker, and objects in general.

Every object has its own functions. For example, atoms all have the Enter() function. Each atom's Enter() function is unique in that it belongs to that atom. In pretty much every language, we are provided with some way to refer to the source of the function (the object it belongs to). In DM, we have the src variable.

The src variable will always, always, always refer to the object that owns the function. You do not need to redefine it (and I'd assume you actually can't). It will always, always, always exist in an object function call.

The usr variable is something else entirely. The usr variable refers to the mob of the client that started the call stack (or if it was started by the world, nothing). 99% of the time someone is using usr on BYOND, they want to use src. Learning which one to use is vital, because if you don't know what you're doing, there is a good chance you're going to end up creating problems.

Do not use usr unless you know you need to. If you don't know, then chances are, you shouldn't.

Also, please be aware that the "as" modifier does absolutely nothing outside of verbs. The "as" modifier is for verbs and calls to input(), and probably some other places I'm forgetting. I'd comment on your EvenOut function, but I'll assume that you just made a typo twice in a row. If you still don't know what I'm talking about, every call to EvenOut() will either set your health to 0, or leave your health below 0 (same for mana).

Anyway, as for a better way to handle this, I'd like to think this method seems a little bit smarter.

mob
var
health = 100
max_health = 100

mana = 100
max_mana = 100

proc
// separate the act of taking damage and being healed.
// this is probably a good idea in general.
// PS: replicate functions for use with mana.
take_damage(damage, mob/attacker) // take damage. alternatively, supply our attacker
health -= damage
if(health < 1) die(attacker) // kill us. alternatively, supply our killer.

restore_health(heal) // heal us some healths
health += heal
if(health > max_health) health = max_health

die(mob/killer)
if(killer) // we were killed by someone.
world << "[killer] stands victoriously on top of [src]'s dead, non-living corpse."
// in an RPG, we might give [killer] some experience or something.
// etc...

else world << "[src] keels over, dead." // something killed us. who knows what?

if(!client) del src // NPCs get deleted.

// from here on out, we're dealing with player characters.
Move(locate("morgue")) // move us to the morgue.
health = max_health // fully heal us (replace this with the healing functions in future)
mana = max_mana // mana too


We can use events that trigger events, as opposed to arbitrary checks every time we want to do something. If we're being healed, make sure we aren't going over our cap. If we're taking damage and our health drops below 1, die. etc...
In response to Keeth
Alright, I am going to set up the victim variable within that code and look over what Keeth posted.

This is the setup of the logic:

/*


Counter = 0
CounterB = 0


//Numbers here going from right to left


1st number --- 0 to 9

2nd number --- 0 to 9, if counter>9&&!>100, counterB = counter, counter val - 10
The second number is that remaining value

3rd number --- 0 to 9, subtracts 100 each time unless less than 100, falls back on step 2

4th number --- subtracts 1000 if >999, falls back on three

5th number --- subtracts 10,000, falls back on 4

6th number --- subtracts 100,000, falls back on 5


//numbers here going from left to right

Run through

If > 100,000
-100,000
upgrade variable by 1
set 1st number to variable
Call Again
..()
else if > 10,000
-10,000
Call Again
upgrade variable by 1
set 2nd number to variable
..()
else if > 1,000
-10,000
Call Again
upgrade variable by 1
set 3rd number to variable
..()
else if > 100
-100
Call Again
upgrade variable by 1
set 4th number to variable
..()
else if > 10
-10
Call Again
upgrade variable by 1
set 5th number to variable
..()
else if > 1
-1
Call Again
upgrade variable by 1
set 6th number to variable
..()



*/


Also, Thank You!
In response to Warlord Fred
Warlord Fred wrote:
I'd recommend not using src in a damage proc, but instead defining a target mob as an argument. Also add a victim mob arg in DeathCheck, and a target mob arg in EvenOut.

I'd recommend ignoring this advice as it's wrong. src is by and away the only variable that makes sense to use in this context. However, you DO need an argument for the attacker in the damage proc, if only to pass it to the deathcheck proc.

And, small nitpicks: the last two inequalities in EvenOut() are backwards. ..() is thoroughly meaningless in the first definition of a proc (if you wrote "proc", then ..() by definition cannot possibly do anything).
In response to Darkjohn66
You should know about the % (modulo) operator. It's basically the remainder from division. So, to split a number into its digits:

proc/digits(var/N)
var/list/L = list()
while(N)
// Get the digit in the ones place
L += N % 10
// Shift the number to the right by one placce
N = round(N/10)
return L
In response to Garthor
This is confusing to me. I don't understand how I could do the math I need for this by using the modulus operator. I tried to mess around and test, but this is all I came up with.

mob/verb/digit_test()
digits(10000)
mob/proc/digits(var/N)
var/list/L = list()
while(N)
// Get the digit in the ones place
L += N % 10
// Shift the number to the right by one placce
N = round(N/10)
src << "[N] is N, [L.len] is L."

return L


Which when used, just tells me:
<font color=silver>
1000 is N, 1 is L.
100 is N, 2 is L.
10 is N, 3 is L.
1 is N, 4 is L.
0 is N, 5 is L.
</font>
In response to Darkjohn66
Modulo is the remainder after the most possible divisions (without a decimal) is used.
ex:
10 % 3 = 1
3 + 3 = 6 (+ 3) = 9 (+ 3) = 12(Which is greater than 10)
So it stops at 9, and returns the remainder of 10 - 9 which is 1.
At least that's how I think it works :/
In response to Leur
I don't understand how that could help me though Leur, and I am still pretty confused at the least.
In response to Darkjohn66
Because you should be looking at what's in L, not what N is at each iteration. What L will contain after that is {0,0,0,0,1}, which are the digits in the number (though backwards, but that really doesn't matter).