ID:1610393
 
Keywords: attack, basic, combat, delay, speed
(See the best response by Ter13.)
Code:
mob
verb
Attack(mob/M as mob in oview(1))
if (M.HP <= 15)
M.icon_state = "injured"
if (M.isdead == 1) //if the mob is dead
M.icon_state = null
if (M.isdead == 0) //otherwise...
var/damage = rand(1,10)
view() << "[usr] attacks [M] for [damage] damage!"
M.HP -= damage
if (M.HP <= 0)
src.exp += M.level*30
src.LevelCheck()
M.DeathCheck()


Problem description: In the current stage of this program I am able to attack as quickly as I can click (Or macro) the Attack verb. I would like for there to be a small delay between each attack so that spamming attack and getting an insta-kill isn't possible. With this delay in mind, how would I be able to make a speed stat that could determine how quick the delay was? Thanks for reading, and I apologize if it's a bit much to ask.

P.S. I am aware that I should change the damage system, but because I've been trying to work the delay thing out I left it as is. I do not need help with that part.
One way is through world.time, which is probably the way you want to do it. A simple example:

#define ATTACK_DELAY 1

mob
var/tmp/attack_timestamp

verb
attack()
if(src.attack_timestamp && world.time - src.attack_timestamp < ATTACK_DELAY)
return 0

//perform necessary attack actions...

src.attack_timestamp = world.time
Best response
Something else really cool is a cooldown tracker.

mob
var
list/cooldowns = list()
proc
setCooldown(cooldown,delay=0,time=0)
if(delay)
time = world.time + delay
cooldowns[cooldown] = time
return time

getCooldown(cooldown)
if(cooldown in cooldowns)
return cooldowns[cooldown] - world.time
else
return 0


The neat thing about this little cooldown tracker, is you can set up a whole bunch of separate cooldowns:

mob
verb
attack1()
if(getCooldown("global") || getCooldown("attack1"))
return
//do whatever
setCooldown("global",delay=5)
setCooldown("attack1",delay=10)
attack2()
if(getCooldown("global") || getCooldown("attack2"))
return
//do whatever
setCooldown("global",delay=5)
setCooldown("attack2",delay=10)


In the above example, I have three cooldowns, a global cooldown that makes all attacks unavailable, and a cooldown for both attacks I have.

This allows you to better balance your combat system by tweaking the timing and rotations of attacks. All with one compact little list and two procs.
In response to Ter13
Cool indeed (this game me an idea for something else too).
Just a quick question, what would happen if you didn't use world.time to track your cool downs?
Just a quick question, what would happen if you didn't use world.time to track your cool downs?

Not sure I understand your question.
In response to Ter13
Ter13 wrote:
Just a quick question, what would happen if you didn't use world.time to track your cool downs?

Not sure I understand your question.

You calculate the delay using world.time. What would be the difference if I were to create a delay based on a number rather than world.time+delay?
In response to Lavitiz
No difference, as long as that number changes over whatever concept of time you have going on. For example, a turn-based game could use the number of turns.
In response to Kaiochao
Thanks. :3