ID:147958
 
This is an "Insanly Serious Problem." I've been workin on a battle system, and it worked fine, but after a battle is on too long, it crashes. So I had my friend help me with it, I accidentally send him the wrong source, but he thought I was just being safe. Well, after he finished, and I copied and pasted so that it would work with my current code, all hell broke loose. First, it wouldn't work, period. Then I got it (with the help of Loduwijk) so that all the things it says to appear and work correctly, or so i thought. When I attack, it says I hit the Brown Slime(for example). I knew I did more than enouph damage to kill the Brown Slime, but it lived. It happened as if it skipped my DeathCheck command. Then the Brown Slime attacked, it did 1 damage, no where near enouph to kill me, and yet, I died. It says the stuff how it should, it says I attacked the Brown Slime for 1,000 or whatever, and he hit me for 1 while i had like 300 life. And yet, it killed me. Now I asked Loduwijk about this, and he couldn't help, he had NO IDEA where there's a problem, so I ask you, O' Great Coders, Please help me fix this problem, Here's the Attack, NPCDeathcheck, and PlayerDeathCheck procs. Please inform me if you need other procs:

  NPCDeathCheck(mob/M)
world<<"{NPC DeathCheck}- src=[src],usr=[usr],M=[M]"
//if(client)
if(src.hp <= 0)
M << "<font color = blue><b>You have killed the [src]!"
M << 'winbattle.wav'
M << "<font color = blue><b>You recieve [src.expreward] exp and [src.gold] Gold!"
if(src.jobexpreward >= 1)
M << "<font color = blue><b>You recieve [src.jobexpreward] job exp!"
M.jobexp += jobexpreward
M.attack = M.memattack
M.defense = M.memdefense
M.intelligence = M.memintelligence
M.agility = M.memagility
M.luck = M.memluck
if(M.attackdoubled == 1)
M.attackdoubled = 0
if(M.defensedoubled == 1)
M.defensedoubled = 0
if(M.intelligencedoubled == 1)
M.intelligencedoubled = 0
if(M.luckdoubled == 1)
M.luckdoubled = 0
if(M.agilitydoubled == 1)
M.agilitydoubled = 0
M.exp += src.expreward
M.gold += src.gold
M.islocked = 0
M.battle = 0
M.lib = 0
checkjoblevel(M)
checklevel(M)
M.mem = 0
del src
if(M.boss1 == 1)
M.boss1 = 0
M.boss1defeated = 1
M.loc = locate(16,9,1)
else
NPCAttack(M)

Attack(mob/M)
world<<"{Attack}- src=[src],usr=[usr],M=[M]"
var
chancetohit = rand(0,10)
damage = (usr.attack - M.defense) + rand(-5,5)
luckchance = rand(0,19)
hitchance = rand(0,3)
critdamage = damage * 3 - rand(-10,10)
if(chancetohit == 5)
usr << "<b><font color = blue>You attack the [src]!"
usr << 'attack.wav'
sleep(10)
usr << "<b><font color = blue>You missed!"
usr << 'dodge.wav'
sleep(10)
NPCDeathCheck(M)
else if(damage <= 0)
usr << "<b><font color = blue>You attack the [src]!"
usr << 'attack.wav'
sleep(10)
if(hitchance == 1)
usr << "<b><font color = blue>You barely hit the [src] damaging it for 1 HP!"
usr << 'hit.wav'
M.hp -= 1
else
usr << "<b><font color = blue>The [src] dodges the attack!"
usr << 'dodge.wav'
sleep(10)
NPCDeathCheck(M)
else if(luckchance == 10)
usr << "<b><font color = blue>You attack the [src]!"
usr << 'attack.wav'
sleep(10)
usr << "<b><font color = blue>Critical hit!"
usr << 'criticalhit.wav'
sleep(10)
if(chancetohit == 5)
usr << "<b><font color = blue>You miss!"
usr << 'dodge.wav'
sleep(10)
NPCDeathCheck(M)
else if(critdamage <= 0)
usr << "<b><font color = blue>The [src] dodges your attack!"
usr << 'dodge.wav'
sleep(10)
NPCDeathCheck(M)
else
usr << "<b><font color = blue>You hit the [src] for [critdamage] HP!"
usr << 'hit.wav'
M.hp -= critdamage
sleep(10)
NPCDeathCheck(M)
else
usr << "<b><font color = blue>You attack the [src]!"
usr << 'attack.wav'
sleep(10)
usr << "<b><font color = blue>You hit the [src] for [damage] HP!"
usr << 'hit.wav'
M.hp -= damage
sleep(10)
NPCDeathCheck(M)

PlayerDeathCheck(mob/M)
world<<"{Player DeathCheck}- src=[src],usr=[usr],M=[M]"
if(M.poisoned == 1)
var
poisond = M.maxhp/20
M << "<b><font color = blue>You lose HP due to poison!"
M.hp -= poisond
M.hp = round(M.hp)
if(M.hp <= 0)
M << "<b><font color = blue>You died! The [src] runs away with half your gold!"
M.gold/=2
M.gold = round(M.gold)
M.islocked = 0
M.hp = M.maxhp
M.lefttown = 0
M.battle = 0
M.lib = 0
M.poisoned = 0
M.x = M.innx
M.y = M.inny
M.z = M.innz
M.attack = M.memattack
M.defense = M.memdefense
M.intelligence = M.memintelligence
M.agility = M.memagility
M.luck = M.memluck
if(M.attackdoubled == 1)
M.attackdoubled = 0
if(M.defensedoubled == 1)
M.defensedoubled = 0
if(M.intelligencedoubled == 1)
M.intelligencedoubled = 0
if(M.luckdoubled == 1)
M.luckdoubled = 0
if(M.agilitydoubled == 1)
M.agilitydoubled = 0
M.mem = 0
del src
else
Battle(M)
else
if(M.hp <= 0)
M << "<b><font color = blue>You died! The [src] runs away with half your gold!"
M.gold/=2
M.gold = round(M.gold)
M.islocked = 0
M.hp = M.maxhp
M.lefttown = 0
M.battle = 0
M.lib = 0
M.x = M.innx
M.y = M.inny
M.z = M.innz
M.attack = M.memattack
M.defense = M.memdefense
M.intelligence = M.memintelligence
M.agility = M.memagility
M.luck = M.memluck
if(M.attackdoubled == 1)
M.attackdoubled = 0
if(M.defensedoubled == 1)
M.defensedoubled = 0
if(M.intelligencedoubled == 1)
M.intelligencedoubled = 0
if(M.luckdoubled == 1)
M.luckdoubled = 0
if(M.agilitydoubled == 1)
M.agilitydoubled = 0
del src
M.mem = 0
else
Battle(M)


Please help, I really need this code fixed sometime soon. Also the whole thing is about 3500 lines long so dont expect me to copy and paste it all
You gotta use the greater than/less than signs to use DM tags
In response to Branks
This still doesn't help my problem, can you please help me?
Well, there are a few serious problems here. The first is:

No put usr in proc. Ungh.

Now for the death checks: Why do you have to separate death check procs when there should be just one? At most, the monster's DeathCheck() should override a default used for players.

One of the problems is that when you call NPCDeathCheck(), you're calling it wrong; instead of calling M.NPCDeathCheck(src) (which would in a perfect world be just M.DeathCheck(src)), you're calling NPCDeathCheck(M), where src is still the player. Seems the same is going on with PCDeathCheck().These of course should, I repeat, be a single DeathCheck() proc. This accounts for at least part of what you described.

Also: Using the deathcheck procs to drive your battle engine is a very very bad move; and since you're not using spawn(), you run the risk of infinite recursion. The battle engine should call these procs, wait for an answer, then give the next combatant a turn.

Finally, you have a "del src" line before several other lines of code that will never see the light of day, because del(src) will kill the proc before it gets to them.

Lummox JR
In response to Metroid
I highly suggest starting over, that looks like a mess (no offense)

try to think of creating a robust battle system, one that isnt so dependent, it should be more flexible

you dont have to take my advice. but im just saying that it's more effort to try to fix that code than to start over and make clean new robust system. even if you did fix that code, you'd find your self adding a lot more to it when all you wanna do is add a new monster/weapon/or skill

i know this isnt the message your looking for, just my 2.5 cents
In response to Lummox JR
That didn't help a lot. See now, I go into my Battle proc:

mob
proc
Battle(mob/M)
if(M.defend == 1)
M.defense /= 2
M.defend = 0
if(M.mem == 0)
M.memattack = M.attack
M.memdefense = M.defense
M.memintelligence = M.intelligence
M.memagility = M.agility
M.memluck = M.luck
M.mem = 1
M.lib = 1
M.battle = 1
switch(alert("[M] encountered! Command?",,"Commence Battle","Defend","Run"))
if("Commence Battle")
M.CommencedBattle(src)
if("Defend")
M.defense *= 2
M.defend = 1
M.NPCDeathCheck(src)
if("Run")
M.Run(src)<dm>

(using M.proc(src) as u said) and if I hit Commence Battle, it doesn't go into:

<dm>CommencedBattle(mob/M)
switch(alert(M,"Command?",,"Attack","Spell","Item"))
if("Attack")
M.Attack(src)
if("Spell")
M.Spell(src)
if("Item")
M.Item(src)<dm>

It just goes right into my Attack verb as if I was attacking.
You attack the Brown Slime!
You hit the Brown Slime for 999 HP!
Connection died.
That's what happens. Same thing that has been happening, but now I can't even pick what to kill myself with. Very confusing. Please help.
In response to FIREking
I actually understand, since this is my first completely, self done battle system, it did have lots of bugs in the begining so Im tring to get every bug out, then make a new one so that I know exactly what to do and not what to do, and avoid all the not to dos.
In response to Lummox JR
Lummox JR wrote:
Also: Using the deathcheck procs to drive your battle engine is a very very bad move; and since you're not using spawn(), you run the risk of infinite recursion. The battle engine should call these procs, wait for an answer, then give the next combatant a turn.
Lummox JR


What do you mean by spawn() anyway?
In response to Metroid
ahh good method
In response to Metroid
Try the reference before you ask next time. =)
In response to Crispy
So how the heck am I supposed to use this in my battle system, and still, the other things u suggested, I did do, and they made it worse!
In response to Metroid
You use spawn() whenever you're calling something recursively. For example:

<code><font color=red>//WRONG</font> proc/worldtimer() world << "Tick!" sleep(100) worldtimer() //Call this proc again <font color=red>//RIGHT</font> proc/worldtimer() world << "Tick!" spawn(100) //Note the indentation below here! worldtimer() //Call this proc again</code>

Lummox's suggestions were all good ones. It doesn't help to say "it made it worse"; HOW is it worse? What's happening? What does your code look like now? More information please!

There's also no need to be so insulting. We're not paid to help you, you know.
In response to Crispy
I dunno where you want me to put the spawn() code anyway, but here's the code after I added/changed what he said to do.

Attack(mob/M)
var
chancetohit = rand(0,10)
damage = (M.attack - M.defense) + rand(-5,5)
luckchance = rand(0,19)
hitchance = rand(0,3)
critdamage = damage * 3 - rand(-10,10)
if(chancetohit == 5)
M << "<b><font color = blue>You attack the [src]!"
M << 'attack.wav'
sleep(10)
M << "<b><font color = blue>You missed!"
M << 'dodge.wav'
sleep(10)
M.NPCDeathCheck(src)
else if(damage <= 0)
M << "<b><font color = blue>You attack the [src]!"
M << 'attack.wav'
sleep(10)
if(hitchance == 1)
M << "<b><font color = blue>You barely hit the [src] damaging it for 1 HP!"
M << 'hit.wav'
M.hp -= 1
else
M << "<b><font color = blue>The [src] dodges the attack!"
M << 'dodge.wav'
sleep(10)
M.NPCDeathCheck(src)
else if(luckchance == 10)
M << "<b><font color = blue>You attack the [src]!"
M << 'attack.wav'
sleep(10)
M << "<b><font color = blue>Critical hit!"
M << 'criticalhit.wav'
sleep(10)
if(chancetohit == 5)
M << "<b><font color = blue>You miss!"
M << 'dodge.wav'
sleep(10)
M.NPCDeathCheck(src)
else if(critdamage <= 0)
M << "<b><font color = blue>The [src] dodges your attack!"
M << 'dodge.wav'
sleep(10)
M.NPCDeathCheck(src)
else
M << "<b><font color = blue>You hit the [src] for [critdamage] HP!"
M << 'hit.wav'
M.hp -= critdamage
sleep(10)
M.NPCDeathCheck(src)
else
M << "<b><font color = blue>You attack the [src]!"
M << 'attack.wav'
sleep(10)
M << "<b><font color = blue>You hit the [src] for [damage] HP!"
M << 'hit.wav'
M.hp -= damage
sleep(10)
M.NPCDeathCheck(src)


NPCDeathCheck(mob/M)
//if(client)
if(src.hp <= 0)
M << "<font color = blue><b>You have killed the [src]!"
M << 'winbattle.wav'
M << "<font color = blue><b>You recieve [src.expreward] exp and [src.gold] Gold!"
if(src.jobexpreward >= 1)
M << "<font color = blue><b>You recieve [src.jobexpreward] job exp!"
M.jobexp += jobexpreward
M.attack = M.memattack
M.defense = M.memdefense
M.intelligence = M.memintelligence
M.agility = M.memagility
M.luck = M.memluck
if(M.attackdoubled == 1)
M.attackdoubled = 0
if(M.defensedoubled == 1)
M.defensedoubled = 0
if(M.intelligencedoubled == 1)
M.intelligencedoubled = 0
if(M.luckdoubled == 1)
M.luckdoubled = 0
if(M.agilitydoubled == 1)
M.agilitydoubled = 0
M.exp += src.expreward
M.gold += src.gold
M.islocked = 0
M.battle = 0
M.lib = 0
M.checkjoblevel(src)
M.checklevel(src)
M.mem = 0
del src
if(M.boss1 == 1)
M.boss1 = 0
M.boss1defeated = 1
M.loc = locate(16,9,1)
else
M.NPCAttack(src)

PlayerDeathCheck(mob/M)
if(M.poisoned == 1)
var
poisond = M.maxhp/20
M << "<b><font color = blue>You lose HP due to poison!"
M.hp -= poisond
M.hp = round(M.hp)
if(M.hp <= 0)
M << "<b><font color = blue>You died! The [src] runs away with half your gold!"
M.gold/=2
M.gold = round(M.gold)
M.islocked = 0
M.hp = M.maxhp
M.lefttown = 0
M.battle = 0
M.lib = 0
M.poisoned = 0
M.x = M.innx
M.y = M.inny
M.z = M.innz
M.attack = M.memattack
M.defense = M.memdefense
M.intelligence = M.memintelligence
M.agility = M.memagility
M.luck = M.memluck
if(M.attackdoubled == 1)
M.attackdoubled = 0
if(M.defensedoubled == 1)
M.defensedoubled = 0
if(M.intelligencedoubled == 1)
M.intelligencedoubled = 0
if(M.luckdoubled == 1)
M.luckdoubled = 0
if(M.agilitydoubled == 1)
M.agilitydoubled = 0
M.mem = 0
del src
else
M.Battle(src)
else
if(M.hp <= 0)
M << "<b><font color = blue>You died! The [src] runs away with half your gold!"
M.gold/=2
M.gold = round(M.gold)
M.islocked = 0
M.hp = M.maxhp
M.lefttown = 0
M.battle = 0
M.lib = 0
M.x = M.innx
M.y = M.inny
M.z = M.innz
M.attack = M.memattack
M.defense = M.memdefense
M.intelligence = M.memintelligence
M.agility = M.memagility
M.luck = M.memluck
if(M.attackdoubled == 1)
M.attackdoubled = 0
if(M.defensedoubled == 1)
M.defensedoubled = 0
if(M.intelligencedoubled == 1)
M.intelligencedoubled = 0
if(M.luckdoubled == 1)
M.luckdoubled = 0
if(M.agilitydoubled == 1)
M.agilitydoubled = 0
del src
M.mem = 0
else
M.Battle(src)
<dm>

That's it edited, I still don't like the idea of 1 deathcheck, I like just one, it doesn't really hurt the code does it? Either way, please answer that question and try to help with the main problem, thanks.
In response to Metroid
Can someone please help me?!?!
In response to Metroid
You've still fixed precious little, including the lack of spawn() that I mentioned and that Crispy very clearly explained for you. You've still got your deathcheck procs driving the battle engine by calling the next attack, which is utterly wrong.

And yes, you really do need to condense DeathCheck() down to one proc, just for simplicity's sake. For one thing, it'll give you one more reason to fix the battle engine. The Attack() proc (of which there also should only be one) should call DeathCheck() for the target, but DeathCheck() should never call the counterattack; your battle engine should be calling all the attacks itself.

DeathCheck() may need to behave differently for players than for monsters. However that's easy to override, or simply put in an if/else for the parts that need to be handled in a different way.

Lummox JR
In response to Lummox JR
Then tell me basically what I should do to make the deathchecks one proc, cause every time i try to do it, it never works.