TeensyMud - 'A ruby mud server.'

Subject: Timers.
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 
    # cast the spell code
    # ....
    @can_cast = false
    # set the cast delay to 2 seconds
    world.set_timer this.id, :cast_spell, 2
  else
    # tell user they can cast the spell yet
  endif
end

def timer e
  case e.kind
  when :cast_spell
    @can_cast = true
    # remove the timer 
    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  # dynamically loaded at startup by command.rb
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   # calls GameObject::timer
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