Running a Timer within a Timer

Discuss, ask for help, share ideas, give suggestions, read tutorials, and tell us about bugs you have found with MicroMacro in here.

Do not post RoM-Bot stuff here. There is a subforum for that.
Forum rules
This is a sub-forum for things specific to MicroMacro.

This is not the place to ask questions about the RoM bot, which uses MicroMacro. There is a difference.
Post Reply
Message
Author
zer0
Posts: 213
Joined: Sat Feb 16, 2008 11:55 pm

Running a Timer within a Timer

#1 Post by zer0 » Sun Feb 17, 2008 12:11 am

I'm creating a script for shaiya, and I'm trying to implement being able to use buffs. I first tried using just a Timer using registerTimer but that is un-reliable, since the bot may be involved in something else like sitting, or some other key presses.
So then what I did is created a Timer, within a timer. Basically the first timer make sure the cooldown timer is finished, the second timer checks that the user is idle, and is able to cast the buff.
Here is a quick example:

Code: Select all

function buff_cooldown()
  registerTimer("buff_cast", 1000, buff_cast);
end

function buff_cast()
  if(user == IDLE)
    keyboardPress(VK_6);
    unregisterTimer("buff_cast");
  end
end

function main()
  registerTimer("buff_cooldown", 300000, buff_cooldown);
  while (alive)
  end
  unregisterTimer("buff_cooldown");
end
But I'm getting this error:
attempt to yield across metamethod/C-call boundary

Any ideas, how I can get around this?

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: Running a Timer within a Timer

#2 Post by Administrator » Sun Feb 17, 2008 2:54 am

This can happen when using calls such as rest, yrest, or an assortment of other MicroMacro functions from within a timer. That's also abusing the timer system. Timers are designed for small things like toggling switches or updating variables.

What you should do is have just one timer that sets a variable when triggered. In your main loop, or any sub-function thereof (not a timed function), you would check for this variable being set to whatever value, and if it is, then do the associated action.

For an example, lets say you want to cast a spell every 30 seconds, if the character state allows.

Note: Untested...there may be errors.

Code: Select all

-- example character state enumeration...
-- these would be set in the game itself
STATE_READY = 100;
STATE_SITTING = 101;
STATE_CASTING = 102;
STATE_FIGHTING = 103;
STATE_BUSY = 104;
STATE_DEAD = 105;

-- variable declaration
need_cast = false;
playerState = STATE_READY;

function update_variables()
  -- read memory from the client here
  playerState = memoryReadInt(myGame, "0xFFFFFFFF", 0);
end

function toggle_cast()
  -- tells the macro that we will want to cast ASAP
  need_cast = true;
end

function cast_spell()
  keyboardPress( key.VK_6 ); -- press key 6 to cast
  need_cast = false;
end

function main()
  registerTimer("update_variables", 100, update_variables);
  registerTimer("toggle_cast", 30000, toggle_cast);

  alive = true;
  while( alive ) do
    if( (playerState == STATE_READY) and (need_cast == true) ) then
      cast_spell();
    end

    if( playerState == STATE_DEAD ) then
      alive = false;
    end

    rest(10);
    coroutine.yield();
  end

end

startMacro(main);

zer0
Posts: 213
Joined: Sat Feb 16, 2008 11:55 pm

Re: Running a Timer within a Timer

#3 Post by zer0 » Sun Feb 17, 2008 3:24 am

Thanks for the quick reply.
Yeah you just said what conclusion I came too. I had several timers, and figured rather than adding all that overhead, I could just have 1 timer, and each skill have it's own time integer.
I think the error that I was getting wasn't from the actual code itself, because I was still getting it, and re-starting the application fixed the issue.

btw, thanks for creating this great proggy. I'm studying IT(games design & dev), and having to script in lua a is good learning experience for me, as I have never had a need to code in an interpretive language.

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: Running a Timer within a Timer

#4 Post by Administrator » Sun Feb 17, 2008 8:53 am

It probably originated from a long C function call from a Lua meta-thread, yet remained after removing the calls due to a minor bug in starting/stopping scripts. It doesn't appear to want to clear out all of the extra meta-threads when stopping sometimes, and they will continue when you start or load a new script. It had me confused at first when I'd be getting Fiesta stuff happening when I had the Shaiya script open... I have just fixed this.

Learning Lua will definitely help if you're looking for a job in game design. Just about every company I've looked at requires it. It doesn't even mater what position you want, either: main programmers, AI programmers, level designer, particle designer, etc. all use Lua in some way or other. The use of an interpreted script really is a time saver and friendly tool for game designers.

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests