ID:147714
 
I am trying to create an auto attack system as you can see below. It all works fine except the fact that when I hit the macro again to turn it off and try and turn it on again right away in the game, its caught up in the sleep proc put in, and won't turn on again until 3 seconds later(the delay time), and displays the auto attack off message for 3 seconds. Then when you hit the auto attack macro again to turn it on, it works. I know the problem is the sleep proc, but I cant figure out a way to get around it if they turn the attack off and want to turn it back on right away. Have puzzled this a few hours and think maybe I need some help to look through it.

Heres the code:
mob/verb/Melee()
set hidden=1
if(usr.attackon==1)
usr.turnattkoff=1
Melee_Attack()
usr<<"Auto attack off."

else
Melee_Attack()


mob
var
attackon
turnattkoff
attackmd
weapondelay=30
attackp
target
weapdmgdisplay
weapdmgdisplay2
hp
canbeattacked
strength
weapdmg



proc
Melee_Attack()
if(usr.turnattkoff==1)
if(usr.attackon==0)
usr.turnattkoff=0
usr.attackmd=0
else
if(!usr.target)
usr<<"You must select a target first."
return 0
else
if(usr.target:canbeattacked==0)
usr<<"This target cannot be attacked."

else
if(usr.target in oview(1))
usr.attackon=1
if(usr.attackmd==1)
else
usr<<"Auto attack on."
usr.attackmd=1
usr.attackp=usr.strength+usr.weapdmg
usr.target:hp-=usr.attackp
usr<<"You [usr.weapdmgdisplay] [usr.target:name] for [usr.attackp]."
usr.target<<"[usr] [usr.weapdmgdisplay2] you for [usr.attackp]."
if(usr.target:hp<=0)
del(usr.target)
usr.attackon=0
usr<<"Auto attack off."
return 0
else
sleep(usr.weapondelay)
if(usr.turnattkoff==1)
usr.attackon=0
Melee_Attack()
else
usr.attackon=1
if(usr.attackmd==1)
else
usr<<"Auto attack on."
usr.attackmd=1

usr<<"[usr.target:name] is out of range."
sleep(usr.weapondelay)
if(usr.turnattkoff==1)
usr.attackon=0
Melee_Attack()
You have two problems. First, you have usr all over that proc. Second, you are using colons.
In response to Garthor
Yes I know im using usr all over the proc, thats because the proc doesnt isnt a mob proc. What is wrong with using colons? That really doesnt help my problem though.
In response to Valderalg
Valderalg wrote:
Yes I know im using usr all over the proc, thats because the proc doesnt isnt a mob proc.

So what? That doesn't make usr valid in it. In fact, it's even more likely to be invalid in that case. Don't use "usr" in procs; it can lead to unpredictable results. See usr Unfriendly by Lummox JR for more information.

What is wrong with using colons?

Everything. All the colon does is suppress compiler errors; so instead of getting them at compile-time, where it's easy to spot them and fix them, you get them at runtime. If you like having millions of unfixable runtime errors, by all means keep using the colon. </sarcasm>

That really doesnt help my problem though.

You'll thank us later. Misuse of usr and the colon are leading causes of DM programmers going insane due to runtime errors they just can't seem to fix.
In response to Crispy
Alright, what do you suggest I use instead of colons? I see your point about the usr in procs. Do you have any clue how do make my code do what I would like it to do?
In response to Crispy
Crispy wrote:
You'll thank us later. Misuse of usr and the colon are leading causes of DM programmers going insane due to runtime errors they just can't seem to fix.

Mothers Against USR in Proc (MAUIP)
In response to Valderalg
Valderalg wrote:
Alright, what do you suggest I use instead of colons?

Dots, periods, full stops, or whatever you want to call them. If that gives you a compiler error, then you haven't defined the variable as the right type. In the case of your target var, for example, you've defined it like this:

<code>mob var target</code>

When you really need to define it like this:

<code>mob var mob/target</code>

Do you have any clue how do make my code do what I would like it to do?

I looked at it for a bit, but couldn't decipher it that well. It would help if you commented your code. =)
In response to Crispy
Btw, I wasnt arguing with you about the usr in proc and the colons, just wanted to understand why they werent ok to use.
Anyways here it is commented and without the usr and colons in the proc.
mob/verb/Melee()//called by a macro
set hidden=1
if(usr.attackon==1)//if they have activiated the attack
usr.turnattkoff=1//set it to be turned off
Melee_Attack()//call the proc so i can be turned off
usr<<"Auto attack off."

else//if its already off
Melee_Attack()//call the proc


proc
Melee_Attack()//the proc
if(src.turnattkoff==1)//if turnattkoff=1 turn the proc off
if(src.attackon==0)//this probably isnt needed but i added it anyway
src.turnattkoff=0//set it back to 0
src.attackmd=0//set it back to 0 so it displays the attack on message again
else
if(!src.target)//if they dont have a target
src<<"You must select a target first."//tell them they need to
return 0
else
if(src.target.canbeattacked==0)//if they cant be attacked stop them from attacking the npc
src<<"This target cannot be attacked."

else
if(src.target in oview(1))
src.attackon=1//turns the attack variable on
if(src.attackmd==1)//if the message has been displayed dont show it
else
src<<"Auto attack on."//else show it
src.attackmd=1//set it so it has been shown
src.attackp=src.strength+src.weapdmg//the mobs attack power is their strength plus their weapondmg, this formula will change later if you were wondering
src.target.hp-=src.attackp//take away hp from the mob being attacked
src<<"You [src.weapdmgdisplay] [src.target.name] for [src.attackp]."//show them the message
src.target<<"[src] [src.weapdmgdisplay2] you for [src.attackp]."//again shows the message
if(src.target.hp<=0)//if they have no hp left
del(src.target)//kill them!
src.attackon=0//turn the attack off
src<<"Auto attack off."
return 0
else
sleep(src.weapondelay)//sleeps the weapon delay before attacking again, calling the proc, this is where the problem is
if(src.turnattkoff==1)//if their attackoff is on, turn their attack off so its intercepted by the if statement at the top
src.attackon=0
Melee_Attack()//call the proc again
else//if mobs out of range
src.attackon=1//turn the attack on
if(src.attackmd==1)//show them or dont show them the message
else
src<<"Auto attack on."
src.attackmd=1

src<<"[usr.target.name] is out of range."//tell them the targets out of range
sleep(src.weapondelay)//again sleep the weapon delay before attacking again this is where the problem is
if(src.turnattkoff==1)//if the attack needs to be turned off, do so
src.attackon=0
Melee_Attack()//call the proc again

In response to Valderalg
First, it should be a mob proc. Second, your if/else trees look rather sloppy. You can just do something like:
if(A)
else if(B)
else if(C)
else if(D)
else

Instead of:
if(A)
else
if(B)
else
if(C)
else
if(D)
else

Saves horizontal space.

Then, could you describe your problem a bit better? It was hard to understand from your description.
In response to Garthor
[EDIT]had the wrong code posted, correct code is now posted[/EDIT]
First, sorry for the delayed reply. Now for a second shot at explaining the problem. When I activate the proc/verb, it all works fine except when you call them again, there is a 3 second delay where the sleep() is where it hangs you up before setting it to turn the attack on again. I am looking for a way to turn the attack on again, right after it has been turned off. If you could offer any suggestions I would be thankfull.

</dm>
mob/verb/Melee()//called by a macro
set hidden=1
if(src.attackon==1)//if they have activiated the attack
src.turnattkoff=1//set it to be turned off
Melee_Attack()//call the proc so i can be turned off
src<<"Auto attack off."

else//if its already off
Melee_Attack()//call the proc


mob/proc
Melee_Attack()//the proc
if(src.turnattkoff==1)//if turnattkoff=1 turn the proc off
if(src.attackon==0)//this probably isnt needed but i added it anyway
src.turnattkoff=0//set it back to 0
src.attackmd=0//set it back to 0 so it displays the attack on message again
else if(!src.target)//if they dont have a target
src<<"You must select a target first."//tell them they need to
return 0
else if(src.target.canbeattacked==0)//if they cant be attacked stop them from attacking the npc
src<<"This target cannot be attacked."
else if(src.target in oview(1))
src.attackon=1//turns the attack variable on
if(src.attackmd==1)//if the message has been displayed dont show it
else
src<<"Auto attack on."//else show it
src.attackmd=1//set it so it has been shown
src.attackp=src.strength+src.weapdmg//the mobs attack power is their strength plus their weapondmg, this formula will change later if you were wondering
src.target.hp-=src.attackp//take away hp from the mob being attacked
src<<"You [src.weapdmgdisplay] [src.target.name] for [src.attackp]."//show them the message
src.target<<"[src] [src.weapdmgdisplay2] you for [src.attackp]."//again shows the message
if(src.target.hp<=0)//if they have no hp left
del(src.target)//kill them!
src.attackon=0//turn the attack off
src<<"Auto attack off."
return 0
else
sleep(src.weapondelay)//sleeps the weapon delay before attacking again, calling the proc, this is where the problem is
if(src.turnattkoff==1)//if their attackoff is on, turn their attack off so its intercepted by the if statement at the top
src.attackon=0
Melee_Attack()//call the proc again
else//if mobs out of range
src.attackon=1//turn the attack on
if(src.attackmd==1)//show them or dont show them the message
else
src<<"Auto attack on."
src.attackmd=1
src<<"[usr.target.name] is out of range."//tell them the targets out of range
sleep(src.weapondelay)//again sleep the weapon delay before attacking again this is where the problem is
if(src.turnattkoff==1)//if the attack needs to be turned off, do so
src.attackon=0
Melee_Attack()//call the proc again</dm>
In response to Valderalg
                if(src.turnattkoff==1)//if turnattkoff=1 turn the proc off
if(src.attackon==0)//this probably isnt needed but i added it anyway
src.turnattkoff=0//set it back to 0
src.attackmd=0//set it back to 0 so it displays the attack on message again

Your problem is there.

Also, it helps if you put <DM> before any code you post, and </DM> after any code you post.
In response to Garthor
I think I did put dm tags in, but not sure, I usually do. And what do you mean the problem is there? Really, there is no problem, its just that the code isnt doing what I would like it to do. Which I believe resides in where its telling it to sleep, before calling the proc again.
In response to Valderalg
Someone's attackon var is set to 1. They press the Melee macro.

Read the code LINE BY LINE, and LINE BY LINE tell me EXACTLY WHAT HAPPENS.
In response to Garthor
Nevermind, I now see that it cannot do what I would like it to do as it is now, but have created an alternate way that works just as good.