Subject: Timers.
Author: ChrisBailey
Posted: 09/25/2008 03:08AM
I read a post further down the line involving timers but I'm not sure I understood it. I've just recently implemented a skill system and I would like skills to have a variable wait after being executed. How could I go about preventing users from executing certain skills for a set amount of time using the timer system? I'd rather use what's already in place than create my own =)
reply
Subject: Timers.
Author: Tyche
Posted: 09/25/2008 03:21PM
There's a significant difference between the way I handled it when that how to use timers message was written and the latest release. The "Kill the Hamster" message should be helpful.
You call world.set_timer(oid, name, time) to create a timer on an object. The mininum granularity is 1 second. You call world.unset_timer(oid, name) to remove it. A timer will create a :timer event on the eventqueue every n seconds. The nice thing is that timers set up this way are saved in the database across reboots.
So for example you could do something like this to a Character object...
def cast_spell
if @can_cast
@can_cast = false
world.set_timer this.id, :cast_spell, 2
else
endif
end
def timer e
case e.kind
when :cast_spell
@can_cast = true
world.unset_timer this.id, :cast_spell
end
end
reply
Subject: Timers.
Author: ChrisBailey
Posted: 09/25/2008 04:30PM
Well that is just beautiful! I'm redoing my skill and spell system right now and my biggest setback was figuring out how to implement a waiting period. I'm doing my best to get this whole codebase figured out because I know I'm not using it to it's potential.
reply
Subject: Timers.
Author: ChrisBailey
Posted: 09/25/2008 05:48PM
Well I've ran into a bit of a problem. I'm probably just not implementing it properly, but I can't quite get this to work. I have it set up as follows.
module Cmd
def timer(e)
case e.kind
when :attack
@can_attack == true
world.unset_timer(id,:attack)
end
end
end
def cmd_attack
if @can_attack
do_long_boring_combat_code
@can_attack = false
world.set_timer(id,:attack,3)
else
tell_players_not_now
end
end
I've tried a few variations like putting the timer method in the Character class(the id it's being initialized with is a character id), but I'm really unsure of how the timer method works. Is it a catch all for timer events or do I need to pass the event to it? If so, how in the world do I know when to pass the event to it?
The end result of my code is that the cmd_attack is performed properly once, @can_attack is set to false, so I'm assuming the timer is initialized(I get no errors) but it never breaks out of the timer.
reply
Subject: Timers.
Author: Tyche
Posted: 09/28/2008 01:13PM
Sorry I've been out for a few days.
ChrisBailey
? wrote:
> @can_attack == true
That looks to be the problem. Should be =.
> Is it a catch all for timer events or do I need to pass the event to it? If so, how in the world do I know when to pass the event to it?
Yes timer(e) is a catch all for all timers set up for that object, And e is the Event object passed to it.
ObEdit
?:
I'm not sure why you want to include timer in module Cmd. You end up with...
module Cmd
def timer
puts "Cmd::foo called."
end
end
class GameObject
def timer
puts "GameObject::timer called."
end
end
class Character < GameObject
include Cmd
end
The semantic problem is that timer really isn't a command. And in order to get method timer loaded into module Cmd, you have to define it in commands/teensy.yaml, thus making timer a player command. Any method defined in module Cmd is intended to be a player command.
You really want to define timer in Character. And quite possibly you want to call super from it.
class Character
def timer e
...code to handle events at character level...
super e
end
The only nice thing about module Cmd is that you can write commands offline and load them dynamically at runtime with the reload command. But there's nothing stopping one from writing code to dynamically load other code into into Character or Object at runtime.
reply
Subject: Timers.
Author: ChrisBailey
Posted: 09/28/2008 10:44PM
Well I have a better understanding of how it works now, I found some time and dug through the event and timer classes also. I can't believe I had mixed up the "==" and "=", I make little mistakes like that all the time and just don't notice them. I was trying to use x++ instead of x +=1 the other day and couldn't figure out the problem. So, I fixed that little issue but I get the same results. The if @can_attack == true fails every time after the first use of the attack command. I went and bought a copy of "The Ruby Way" today, maybe that will help me out.
reply