ID:1578602
 
(See the best response by KingCold999.)
Code:
mob/verb
Attack()
if(usr.attdelay == 1)
sleep(usr.attdelayt)
usr.attdelay = 0
return
if (usr.stam < usr.attstam || usr.KOED == 1)
return
usr.attdelay = 1
flick("Attack",usr)
AttackMastery()
AttackStam()
for(var/mob/M in get_step(usr,usr.dir))
if(M.KOED == 1)
Death(M)
else
var mdamage = usr.str * (500 / (500 + M.end))
var/damage = round(max(0, mdamage), 1)
M.hp-=damage
KOcheck(M)


Problem description:
When I hold down an attack macro to test the delay only the first attack will be delayed. Right after the delay my character can spam attack with no delay.
Best response
Firstly: Probably shouldn't use usr, src would suffice here. There are a whole lot of issues with using usr that can arise whenever you have sleeping procedures.

Secondly: if they spam the attack, the attack delay is always called, and will repeatedly turn off attackdelay, Try:

mob/verb
Attack()
if(src.attdelay == 1)
return
if (src.stam < src.attstam || src.KOED == 1)
return
src.attdelay = 1
flick("Attack",usr)
AttackMastery()
AttackStam()
for(var/mob/M in get_step(src,src.dir))
if(M.KOED == 1)
Death(M)
else
var mdamage = src.str * (500 / (500 + M.end))
var/damage = round(max(0, mdamage), 1)
M.hp-=damage
KOcheck(M)
spawn(src.attdelayt) src.attdelay=0


If the attack is called more than once in this situation, it returns immediately.

Then, as soon as spawn(src.attdelayt) (which basically waits attdelayt's value, then executes the code beside it) is finished, they will be able to attack again.
Works perfectly, thank you very much for the explanation.