[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  General
. . -> [Subject]  Wait function in a script

Wait function in a script

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Patrick   (3 posts)  [Biography] bio
Date Fri 16 Mar 2001 08:24 PM (UTC)
Message
I'm trying to implement a wait function that will cause my script to momentarily pause. I have included the following code in case anyone wants to reference to why it is not working.

I have tried messing with many different combinations, but have no success.

My function wait() takes one argument, which is set to be the total number of seconds required to wait. Once the function commences, the jscript functions Date() and getTime() are used to set the current time, and to retrieve the current time(in milliseconds). I have debugged the program to send me a note of what the inital time (in milliseconds) is, and a note of what the final time (in milliseconds) is, after the function pauses for sec*1000 milliseconds.

What happens, is the script freezes upon function call, and X seconds later, it displays the inital value and the final value (along with whatever else data was send from the server).

I am using this function to calculate the roundtime needed to wait before continuing with my actions. Any input would be appreciated.



**********************FUNCTION WAIT************************ 
function wait(sec) 
{ 
 world.note("Wait Function"); 
 var i = new Date(); 
 var d = i.getTime(); 
 var t = i.getTime() + sec*1000; 

 world.note(d); 
 dateLoop(i,d,t); 
} 

function dateLoop(a,b,c) 
{   
 for(;;){ 
   a = new Date(); 
   b = a.getTime(); 
   if (b>c) 
     break; 
 } 
 world.note(b); 
} 





After a little debugging, I found out that the function did actually work, and that I can successfully wait for X seconds before performing another action on the script. Unfortunately, the current implementation I have created will temporarily freeze the screen until the calculation is carried out. Only then, can I continue. While this isn't too big of a problem with running 1-10 second wait() functions, when I create an infinite loop, the application crashes. Could you help me create a way to include an infinite loop in the application without crashing it, and also be able to type in text while the script function is executing? Thanks!
[Go to top] top

Posted by Nick Gammon   Australia  (23,044 posts)  [Biography] bio   Forum Administrator
Date Reply #1 on Fri 16 Mar 2001 08:35 PM (UTC)
Message
What you have here is a classic demonstration of why scripts can't pause - because if they did, the whole program pauses, you can't key anything in, you can't receive data from any MUDs, you can't use the menus and so on.

The simplest way of implementing a pause is to make the script create a one-shot timer using AddTimer, and maybe give it a unique name with GetUniqueNumber. (eg. "Z123432").

The one-shot timer might fire in (say) 5 seconds, and when it fires it can call a script, which can then do whatever it was you wanted to do after the pause. That way, the program can be doing other things while the timer is running. Being a one-shot timer, it is then deleted when it fires, so you don't have to worry about it firing again in another 5 seconds.

Another possibility is to use Queue - this queues up a command to be sent to the MUD at the "speed walk" rate. It depends on why you want the pause. If it is just to send things more slowly, then consider using Queue.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (23,044 posts)  [Biography] bio   Forum Administrator
Date Reply #2 on Fri 16 Mar 2001 08:38 PM (UTC)
Message
On the other hand, if you want an infinite loop (and I would be interested to know why you want that), then you could just make a timer that fires every 10 seconds or so, which is not one-shot, and thus does whatever you were planning to do in that loop.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Patrick   (3 posts)  [Biography] bio
Date Reply #3 on Fri 16 Mar 2001 10:57 PM (UTC)
Message
Nick,

Thanks for the response! I'm currently going to try and impliment the timer. I saw it on the functions list, but didn't exactly know how to go about implementing it. If you don't mind, could you tell me how you coded a timer? That way I could understand how you keep counting without taking all of the processing power.

I wanted to implement an infinite loop in case I needed a script that would keep me from being booted off-line. I wanted to impliment something like this:

for(i = k.getTime();;i = k.getTime()){
k = new Date();
if (k.getTime % 100000 == 0)
world.send("exp");
}

Obviously, I would need to replace the time to a trigger fire to implement it correctly, but that way, I could keep this timer going while I'm afk, and not be booted offline.

Pat
[Go to top] top

Posted by Nick Gammon   Australia  (23,044 posts)  [Biography] bio   Forum Administrator
Date Reply #4 on Sat 17 Mar 2001 02:11 AM (UTC)
Message
Coding a timer in C is simple enough. There is a Windows function call, SetTimer I think it is. You specify how many milliseconds are to elapse, and when that time is up a message is sent to the program that the time is up. Meanwhile you can do other things.


As for stopping being booted when afk, you can do that really easily by just manually (ie. through the configuration screen) making a timer, and make it go off, say every 20 minutes, and just get it to send a command like "look".

Some MUDs will also boot you off if you send the same command too often (eg. 20 times in a row), so to defeat that you might set up 2 timers, one that sends "look" and another that sends "exp" or whatever.

Then you would make each one go off every 40 minutes, but have one of them have a 20-minute "offset". The idea of the offset is to make timed events occur at displaced times.

eg.

look .... wait 40 minutes ... however 20 minutes later:
exp .... wait 40 minutes
look .... wait 40 minutes ... and so on


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Patrick   (3 posts)  [Biography] bio
Date Reply #5 on Sat 17 Mar 2001 11:11 PM (UTC)
Message
Nick,

I have a few questions for you still. First, I am trying to develop a function that will allow me to cast the same spell on myself multiple number of times. What I came up with was something like this:

function spellup(spell, number)
{
if (number < 1)
{
world.deletetrigger("cast");
return (world.note("Spellup finished!"));
}
else
{
world.send("pr "+spell);
world.addtrigger("cast", "Your spell is
ready." , "cast", 1, -1, 0, "", "");
world.addTimer("cont"+number, 0, 0, 3, spellup
(spell,number-1), 5, "");
}
}

The problem I have with this implementation is this, instead of sending "pr <spell>", waiting until the spell is ready, casting, and then waiting 3 seconds before accessing the loop again, the execution seems to send "pr <spell>"*number, then waiting until the spell is ready, then casting*number.

Example: /spellup(103,3)

pr 103
pr 103
pr 103
Script Finished!
<wait until "Your spell is ready.">
cast
cast
cast

I have one more questino for you, Nick. Is there any possible way to actually extract data from the output screen rather than just set a "trigger" to act upon seeing the message? For instance, I would like to make a function that would tell me whether or not it is safe for me to hunt based on my current number of health points. Basically, if my health is greater than X amount, it is safe for me to hunt. Implimenting it trigger-wise would require me to enter a trigger for every value between X and my maximum health number (and a required upkeep based on advancing levels). I would much rather read my value from the output and compare it to my conditional statement. Thanks, Nick!

Patrick
[Go to top] top

Posted by Nick Gammon   Australia  (23,044 posts)  [Biography] bio   Forum Administrator
Date Reply #6 on Sun 18 Mar 2001 01:56 AM (UTC)

Amended on Sun 18 Mar 2001 01:57 AM (UTC) by Nick Gammon

Message
OK - first question - how to much the "cast a spell n times work"...

Your implementation would have called spellup as part of the AddTimer, and thus you got three "pr 103" in a row.

You need to defer it. Here is my solution, I did it in VBscript by mistake, but you will see the idea. I tested it and it works.

First, the spellup function - it:

1. Remembers the spell number for later
2. Remembers the counter for later
3. Makes a trigger to match on when the spell is ready
4. Prepares the first spell



sub spellup (spell, number) 
  world.setvariable "spellnumber", spell
  world.setvariable "spellcount", number
  world.addtrigger "cast", "Your spell is ready." , "cast", 1, -1, 0, "", "OnSpellReady"
  world.send "pr " + cstr (spell)
end sub




Second, the trigger calls a function OnSpellReady - it:

1. Gets the spellcount variable (saved when you called spellup), checks it exists, and then subtracts 1 (as we have one less to go).
2. Sends a debugging note to the world window, so you know what is happening
3. If we don't have any left to go we delete the trigger
4. Otherwise we prepare another spell - and - save the decremented spell counter




sub OnSpellReady (strTriggerName, trig_line, arrWildCards)
dim number
  number = world.getvariable ("spellcount")
  if IsEmpty (number) or IsNull (number) then
    exit sub
  end if
  number = number - 1
  world.note "Just cast spell " + cstr (world.getvariable ("spellnumber")) _
             + " - now have " + cstr (number) + " to go."
  if number < 1 then
    world.deletetrigger "cast"
  else
    world.send "pr " + world.getvariable ("spellnumber")
    world.setvariable "spellcount", number
  end if  
End Sub




Just translate it to Jscript and you should be cooking!

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (23,044 posts)  [Biography] bio   Forum Administrator
Date Reply #7 on Sun 18 Mar 2001 02:06 AM (UTC)
Message
Second question - how to process your stats without having to match on every possible HP - simple, you make a trigger that matches on a wildcard number of points. There is an example in the exampscript.vbs (and .jvs) that does this.

Here is the VBscript version:



' --------------------------------------------
' Example showing a script called by a trigger
'  Should be connected to a trigger matching on: <*hp *m *mv>*
'   (the above example will work for SMAUG default prompts (eg. <100hp 10m 40mv>)
'    it may need to be changed depending on the MUD prompt format).
' --------------------------------------------
sub OnStats (strTriggerName, trig_line, arrWildCards)

dim iHP
dim iMana
dim iMV

iHP = arrWildCards (1)
iMana = arrWildCards (2)
iMV = arrWildCards (3)

world.Note "Your HP are " & iHP
world.Note "Your Mana is " & iMana
world.Note "Your movement points are " & iMV

end sub



You could fine-tune it a bit by using regular expressions, and match on numbers, eg.


^\<[0-9]+hp [0-9]+m [0-9]+mv\>.*$


The sequence "[0-9]+" matches on 1 or more numbers, which is a bit more accurate than just using an asterisk which matches on anything, but I think the simpler example will probably work fine.

Then you could do something inside the trigger handler (other than what is in the example). A simple idea would be to set the status line, eg.



if iHP > 100 then
  world.setstatus "safe to hunt"
else
  world.setstatus "better go and rest"
end sub



You would make it fancier by changing your status line to give you maximum HP as well, change the trigger appropriately, and then change the script to show the "safe to hunt" message if you had (say) more than 20% of available HP.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


23,228 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]