~ubuntu-branches/ubuntu/hoary/inform/hoary

« back to all changes in this revision

Viewing changes to include/timesys.h

  • Committer: Bazaar Package Importer
  • Author(s): Mark Baker
  • Date: 2004-03-29 23:52:44 UTC
  • Revision ID: james.westby@ubuntu.com-20040329235244-fox1z1yv7d6vojoo
Tags: upstream-6.30
ImportĀ upstreamĀ versionĀ 6.30

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
!====================================================================================
 
2
! TIMESYS 1.0   INFORM TIME-ORIENTED GAME EXTENSION
 
3
!
 
4
!                       An Inform library to provide an understanding of English time
 
5
!                       strings, and give an enhanced Wait command.
 
6
 
7
!             (c) Kevin Forchione, 1998, but freely usable.
 
8
!             Compatible with Inform 6.15, library 6/7.
 
9
!                Based on WaitTime.h by L. Ross Raszewski, 1996 
 
10
!                     and TimeWait.h by Andrew Clover, 1995
 
11
!                       with much appreciation for their efforts.
 
12
!
 
13
! IMPLEMENTATION REQUIREMENTS:
 
14
!
 
15
!     Time-oriented games only
 
16
!       Replace DrawStatus; and set constant to STYLE you wish (see STYLES below)       
 
17
!     Replace WaitSub(); (the replacement routine is already provided in the
 
18
!               extension.
 
19
!     Change WAIT verb to META in GRAMMAR.H
 
20
!     #include TimeSys.h somewhere after #include "Grammar";
 
21
!       Set the day-of-the-week (if desired) in Initialise() with 
 
22
!               TimeSys('day'); (see below)
 
23
!       Day-of-week advancement (if desired) At the top of TimePasses(); 
 
24
!               call TimeSys.NextDay() for automatic handling of day-of-week advancement.
 
25
!
 
26
! COMMENTS:
 
27
 
28
!       This is hardly an ideal solution (That being an overhaul of the 
 
29
!       InformLibrary itself to extend its time-keeping capabilities.)
 
30
!
 
31
!       Nonetheless, by making the WAIT command META we take control out of the 
 
32
!       InformLibrary's Turn__end process and allow the extension to process
 
33
!       Waiting() and StopWaiting() requests without falling back into final execution 
 
34
!       of InformLibrary.End_Turn_Sequence, which causes problems with StopWaiting() 
 
35
!       requests. (i.e. the request stops the extension at the desired time, but 
 
36
!       InformLibrary.Turn__end gets the final word and bumps the time up one more step.) 
 
37
!
 
38
!       DRAWBACKS: However, there are some drawbacks...
 
39
!
 
40
!       Unfortunately the functions of the TimeSys object are completely dependent 
 
41
!       upon being called through the wait subroutines as were those of it's predecessor 
 
42
!       tw_waiting (It's never in scope). 
 
43
!
 
44
!       Making the WAIT verb META compounds the difficulty in generation of actions 
 
45
!       to an object's before() and Orders(). 
 
46
!
 
47
!       ENHANCEMENTS: The TimeSys object has been significantly enhanced over 
 
48
!                         the old tw_waiting object. 
 
49
!
 
50
!       The variables in TimeSys have all been made private. Access methods 
 
51
!       It now contains coding for the advancement of the day-of-week, which should
 
52
!       be called from TimePasses() with TimeSys.NextDay().
 
53
!
 
54
!       The redundant call to TimePasses() in the Waiting process that occurred in 
 
55
!       WaitTime.h has been removed and this process moved to the TimeSys object 
 
56
!       instead of being handled in a standalone routine. In addition this means 
 
57
!       that the wait process is effected only once each cycle by  the 
 
58
!       InformLibrary.End_Turn_Sequence(). 
 
59
!
 
60
!       You can set a wait default (independent of time_step) which will allow you
 
61
!       to wait a default number of minutes (such as in Infocom's "Sherlock: The Riddle
 
62
!       of the Crown Jewels"). 
 
63
!
 
64
!       The non-waiting time_rate is kept independent of the waiting process, so 
 
65
!       that you can SetTime() for any rate you wish for the normal (non-waiting)
 
66
!       passage of time. Waiting converts minutes to turns (as WaitTime.h did), 
 
67
!       then when the waiting process is finished the original non-waiting time_rate
 
68
!       is restored.
 
69
!
 
70
!       Other features are documented below.
 
71
!          
 
72
!====================================================================================
 
73
 
 
74
Object TimeSys "TimeSys"
 
75
   has proper
 
76
   private 
 
77
   TS_day                               0               ! Day-of-the-week numeric value                 
 
78
   ,TS_WaitDefault              10              ! Default value for Wait with no operand
 
79
   ,TS_WaitMax                  1440            ! Maximum number of minutes allowed in a Wait
 
80
   ,TS_wait_time_initial        0               ! Number of minutes to be waited
 
81
   ,TS_wait_time_remaining      0               ! Number of minutes for waiting remaining
 
82
   ,TS_normal_time_rate         0               ! Saved value of non-wait game time-rate
 
83
   ,TS_prev_time_save           0               ! Saved value used to determine new day
 
84
   with name "TimeSys"
 
85
 
 
86
   ,Waiting
 
87
        [ i;
 
88
                if (noun > self.TS_WaitMax) {give self locked; "That's too long to wait.";};
 
89
                if (noun==0) {give self locked; "Time doesn't pass.^";};
 
90
                print "Time passes...^";
 
91
                give self on;
 
92
                self.TS_wait_time_initial=noun;
 
93
                self.TS_wait_time_remaining=noun;
 
94
                self.TS_normal_time_rate=time_rate;
 
95
                SetTime(the_time,1);
 
96
 
 
97
                for (i=noun : (i>0)&&(deadflag==0)&&(self has on) : i--)
 
98
                {
 
99
 
 
100
                        self.TS_wait_time_remaining--;
 
101
 
 
102
                #ifdef InformLibrary;
 
103
                        InformLibrary.End_Turn_Sequence();
 
104
                #ifnot;
 
105
                #ifdef EndTurnSequence;
 
106
                        EndTurnSequence();
 
107
                #ifnot;
 
108
                Message fatalerror "waittime.h requires \
 
109
                        InformLibrary.End_Turn_Sequence() or \
 
110
                        EndTurnSequence() to be defined (this should be done \
 
111
                        by the Inform Library)";
 
112
                #endif;
 
113
                #endif;
 
114
                        DisplayStatus();
 
115
                #IFV5;
 
116
                        DrawStatusLine();
 
117
                #ENDIF;
 
118
                }
 
119
                SetTime(the_time,self.TS_normal_time_rate);
 
120
                if ((self hasnt on)&&(self.TS_wait_time_remaining>0)&&(deadflag==0))
 
121
                   print "^(waiting stopped)^";
 
122
        ]
 
123
 
 
124
!--------------------------------------------------------------------------------------
 
125
! This routine allows the author to code StopWaiting requests for any event s/he chooses.
 
126
! It also give the player the choice of continued waiting if they wish.
 
127
!----------------------------------------------------------------------------------------
 
128
   ,StopWaiting
 
129
        [; 
 
130
           if (self.TS_wait_time_remaining==0) rfalse;
 
131
 
 
132
           DisplayStatus();
 
133
           #IFV5;
 
134
           DrawStatusLine();
 
135
           #ENDIF;
 
136
 
 
137
           print "^Do you want to continue waiting?";
 
138
           if (YesOrNo()==0) give self ~on;
 
139
        ]
 
140
 
 
141
   ,SetDefault
 
142
        [ d; self.TS_WaitDefault=d;
 
143
        ]
 
144
 
 
145
   ,GetDefault
 
146
        [; return self.TS_WaitDefault;
 
147
        ]
 
148
 
 
149
!-----------------------------------------------------------------------------------------
 
150
! This function allows the author to set the game day using the name for the
 
151
! day-of-the-week, instead of having to use its numeric value. This allows TimeSys
 
152
! to keep this variable private.
 
153
!-----------------------------------------------------------------------------------------
 
154
   ,SetDay
 
155
        [ d;
 
156
                switch(d)
 
157
                { 'Sunday','sunday','Sun','sun',"Sunday","sunday","Sun","sun": 
 
158
                        self.TS_day=0;
 
159
                  'Monday','monday','Mon','mon',"Monday","monday","Mon","mon": 
 
160
                        self.TS_day=1;
 
161
                  'Tuesday','tuesday','Tue','tue',"Tuesday","tuesday","Tue","tue": 
 
162
                        self.TS_day=2;
 
163
                  'Wednesday','wednesday','Wed','wed',"Wednesday","wednesday","Wed","wed": 
 
164
                        self.TS_day=3;
 
165
                  'Thursday','thursday','Thu','thu',"Thursday","thursday","Thur","thur": 
 
166
                        self.TS_day=4;
 
167
                  'Friday','friday','Fri','fri',"Friday","friday","Fri","fri": 
 
168
                        self.TS_day=5;
 
169
                  'Saturday','saturday','Sat','sat',"Saturday","saturday","Sat","sat": 
 
170
                        self.TS_day=6;
 
171
                  default: self.TS_day=d;
 
172
                };
 
173
        ]
 
174
 
 
175
!-----------------------------------------------------------------------------------------
 
176
! This function allows time-oriented games to have the day-of-the-week pushed forward with
 
177
! the passage of time. Although it goes beyond the scope of purely 'waiting' it aspires to
 
178
! a more mature time-keeping system we can only now dream of.
 
179
!
 
180
! This should be called from TimePasses() as TimeSys.NextDay() for automatic advancement.
 
181
!------------------------------------------------------------------------------------------
 
182
   ,NextDay
 
183
        [;
 
184
         if (the_time < self.TS_prev_time_save) {self.TS_day++;};
 
185
         if (self.TS_day > 6) {self.TS_day=0;};
 
186
         self.TS_prev_time_save=the_time;
 
187
        ]
 
188
  
 
189
!------------------------------------------------------------------------------------------
 
190
! This routine returns either the number value or the associated name for the 
 
191
! day_of_the_week, and can be included in any StatusLine routine that needs to know the 
 
192
! this information
 
193
!------------------------------------------------------------------------------------------
 
194
   ,GetDay
 
195
        [ f i; 
 
196
           if (f==0) return self.TS_day;
 
197
           if (f==1)
 
198
           switch(self.TS_day)
 
199
                { 0: i="Sunday   ";
 
200
                  1: i="Monday   ";
 
201
                  2: i="Tuesday  ";
 
202
                  3: i="Wednesday";
 
203
                  4: i="Thursday ";
 
204
                  5: i="Friday   ";
 
205
                  6: i="Saturday ";
 
206
                }
 
207
           else
 
208
           switch(self.TS_day)
 
209
                { 0: i="Sun";
 
210
                  1: i="Mon";
 
211
                  2: i="Tue";
 
212
                  3: i="Wed";
 
213
                  4: i="Thu";
 
214
                  5: i="Fri";
 
215
                  6: i="Sat";
 
216
                };
 
217
           return i;
 
218
        ];
 
219
 
 
220
!------------------------------------------------------------------------------------------
 
221
! STATUSLINE STYLES
 
222
!
 
223
!       Some of the styles listed below mimic styles from classic Infocom games 
 
224
!       (versions may differ). To select a style of statusline simply define the 
 
225
!       constant listed below as one of the following:
 
226
!
 
227
!       BASIC_STYLE: Mimics statuslines of the following:
 
228
!               Cutthroats                                              Release 23 / Serial number 840809
 
229
!               Deadline: An Interlogic Mystery         Release 27 / Serial Number 831005
 
230
!               MoonMist                                                Release  9 / Serial Number 861022
 
231
!               Suspect: An Interactive Mystery         Release 14 / Serial Number 841005
 
232
!               The_Witness: An Interlogic Mystery              Release 22 / Serial Number 840924
 
233
!               Wishbringer: The Magick Stone of Dreams Release 69 / Serial Number 850920
 
234
!
 
235
!       STANDARD_STYLE: Displays day/time information
 
236
!
 
237
!       FULL_STYLE: Displays day/time/score information 
 
238
!
 
239
!       SHERLOCK_STYLE: Mimics statuslines of Infocom's Sherlock game, which used
 
240
!               an hh:mm:ss format, even though the game didn't handle seconds:
 
241
!               Sherlock: The Riddle of the Crown Jewels        Release 21 / Interpreter 6 / 
 
242
!                                                                       Version j / Serial Number 871214        
 
243
!                       
 
244
!===========================================================================================
 
245
 
 
246
Constant FULL_STYLE;
 
247
 
 
248
#IFDEF BASIC_STYLE;
 
249
[ DrawStatusLine i width pos;
 
250
   @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
 
251
   width = 0->33;
 
252
   if (width == 0) width = 80;
 
253
   spaces (width-1);
 
254
   @set_cursor 1 2;  PrintShortName(location);
 
255
   pos = width-19;
 
256
   @set_cursor 1 pos;
 
257
   print "Time: ";
 
258
   i=sline1%12; if (i<10) print " ";
 
259
   if (i==0) i=12;
 
260
   print i, ":";
 
261
   if (sline2<10) print "0";
 
262
   print sline2;
 
263
   if ((sline1/12) > 0) print " pm"; else print " am";
 
264
   @set_cursor 1 1; style roman; @set_window 0;
 
265
];
 
266
#ENDIF; ! BASIC_STYLE
 
267
 
 
268
#IFDEF STANDARD_STYLE;
 
269
[ DrawStatusLine i width pos;
 
270
   @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
 
271
   width = 0->33;
 
272
   if (width == 0) width = 80;
 
273
   pos = width-22;
 
274
   spaces (width-1);
 
275
   @set_cursor 1 2;  PrintShortName(location);
 
276
   @set_cursor 1 pos;
 
277
   print (string) TimeSys.GetDay(1);
 
278
   i=sline1%12; if (i<10) print " ";
 
279
   if (i==0) i=12;
 
280
   print i, ":";
 
281
   if (sline2<10) print "0";
 
282
   print sline2;
 
283
   if ((sline1/12) > 0) print " pm"; else print " am";
 
284
   @set_cursor 1 1; style roman; @set_window 0;
 
285
];
 
286
#ENDIF; !STANDARD_STYLE
 
287
 
 
288
#IFDEF FULL_STYLE;
 
289
[ DrawStatusLine i width pos;
 
290
   @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
 
291
   width = 0->33;
 
292
   if (width == 0) width = 80;
 
293
   spaces (width-1);
 
294
   @set_cursor 1 2;  PrintShortName(location);
 
295
   pos = width-41;
 
296
   @set_cursor 1 pos;
 
297
   print (string) TimeSys.GetDay(1); 
 
298
   i=sline1%12; if (i<10) print " ";
 
299
   if (i==0) i=12;
 
300
   print i, ":";
 
301
   if (sline2<10) print "0";
 
302
   print sline2;
 
303
   if ((sline1/12) > 0) print " pm"; else print " am";
 
304
   pos = width-10;
 
305
   @set_cursor 1 pos; print "Score: ", score;
 
306
   @set_cursor 1 1; style roman; @set_window 0;
 
307
];
 
308
#ENDIF; ! FULL_STYLE
 
309
 
 
310
#IFDEF SHERLOCK_STYLE;
 
311
[ DrawStatusLine i width pos;
 
312
   @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
 
313
   width = 0->33;
 
314
   if (width == 0) width = 80;
 
315
   spaces (width-1);
 
316
   @set_cursor 1 2;  PrintShortName(location);
 
317
   pos = width-41;
 
318
   @set_cursor 1 pos;
 
319
   print (string) TimeSys.GetDay(1);
 
320
   i=sline1%12; if (i<10) print " ";
 
321
   if (i==0) i=12;
 
322
   print i, ":";
 
323
   if (sline2<10) print "0";
 
324
   print sline2;
 
325
   if ((sline1/12) > 0) print ":00 p.m."; else print ":00 a.m.";
 
326
   pos = width-10;
 
327
   @set_cursor 1 pos; print "Score: ", score;
 
328
   @set_cursor 1 1; style roman; @set_window 0;
 
329
];
 
330
#ENDIF; ! SHERLOCK_STYLE
 
331
 
 
332
!------------------------------------------------------------------------------------------
 
333
!Action routines for Wait command...
 
334
!------------------------------------------------------------------------------------------
 
335
 
 
336
[WaitSub;
 
337
  noun=TimeSys.GetDefault();
 
338
  TimeSys.Waiting();
 
339
];
 
340
 
 
341
[ WaitMovesSub; TimeSys.Waiting(); ];
 
342
 
 
343
[ WaitHoursSub;
 
344
  noun=noun*60+second;
 
345
  TimeSys.Waiting();
 
346
];
 
347
 
 
348
[ WaitUntilSub;
 
349
  if (parsed_number>=the_time) noun=parsed_number-the_time;
 
350
  if (parsed_number<the_time) 
 
351
      {parsed_number=the_time-parsed_number;
 
352
      noun=1440-parsed_number;
 
353
      }
 
354
  if (noun==0) {noun=1440; print "(tomorrow)^^";};
 
355
 
 
356
  TimeSys.Waiting();   
 
357
];
 
358
 
 
359
!-----------------------------------------------------------------------------------
 
360
! ParseTime takes data from the next words (using wn) and returns a
 
361
! the_time format time number, or -1 for unrecognisable. It can recognise
 
362
! time expressed in any of the following formats:
 
363
!
 
364
! a. <"0"-"59">|<"one"-"twenty">|"half"|"quarter" ["minutes"|"minute"]
 
365
!    "past"|"to" <"1"-"12">|<"one"-"twelve"> ["am"|"pm"]
 
366
! b. <"1"-"12">|<"one"-"twelve"> ["o'clock"] ["am"|"pm"]
 
367
! c. <"1"-"12">|<"one"-"twelve"> <"0"-"59">|<"one"-"twenty"> ["am"|"pm"]
 
368
! d. <"1"-"12">":"<"0"-"59"> ["am"|"pm"]
 
369
! e. "midnight"|"midday"|"noon"
 
370
!    If no am/pm is specified, the next time likely to come up is chosen; that
 
371
!    is, the one that's just ahead of the current time. However, if this
 
372
!    happens, the TimeSys object is given the 'general' attribute. Thus you
 
373
!    can change the time returned by twelve hours in an action like SetClock
 
374
!    if necessary.
 
375
!
 
376
!    The next dictionary command is there to allow us to compare a typed
 
377
!    string with "o'clock", something we can't normally do as it is bounded by
 
378
!    single quotes.
 
379
!-----------------------------------------------------------------------------------
 
380
 
 
381
constant TS_OCLOCK 'o^clock';
 
382
 
 
383
[ ParseTime i j k flg loop dig hr mn;
 
384
  give TimeSys ~general;
 
385
  i=NextWord();
 
386
  if (i=='midday' or 'noon' or 'midnight')           ! then case (e) applies
 
387
    {
 
388
    if (i=='midnight')
 
389
      hr=0;
 
390
    else
 
391
      hr=12;
 
392
    mn=0;
 
393
    parsed_number=(hr*60+mn);
 
394
    }
 
395
  else
 
396
    {
 
397
    k=(wn-1)*4+1;                                    ! test for case (d)
 
398
    j=parse->k;
 
399
    j=j+buffer;
 
400
    k=parse->(k-1);
 
401
    flg=0;
 
402
    for (loop=0:loop<k:loop++)
 
403
      {
 
404
      dig=j->loop;
 
405
      if (dig==':')
 
406
        flg=1;
 
407
      }
 
408
    if ((k>2)&&(k<6)&&(flg==1))                      ! then case (d) applies
 
409
      {
 
410
      hr=0;
 
411
      mn=0;
 
412
      loop=0;
 
413
      .tw_diglph;
 
414
      dig=j->loop;
 
415
      loop++;
 
416
      if (dig~=':')
 
417
        hr=hr*10;
 
418
      if (dig=='0') { hr=hr+0; jump tw_diglph; }
 
419
      if (dig=='1') { hr=hr+1; jump tw_diglph; }
 
420
      if (dig=='2') { hr=hr+2; jump tw_diglph; }
 
421
      if (dig=='3') { hr=hr+3; jump tw_diglph; }
 
422
      if (dig=='4') { hr=hr+4; jump tw_diglph; }
 
423
      if (dig=='5') { hr=hr+5; jump tw_diglph; }
 
424
      if (dig=='6') { hr=hr+6; jump tw_diglph; }
 
425
      if (dig=='7') { hr=hr+7; jump tw_diglph; }
 
426
      if (dig=='8') { hr=hr+8; jump tw_diglph; }
 
427
      if (dig=='9') { hr=hr+9; jump tw_diglph; }
 
428
      if (dig~=':') return -1;
 
429
      while (loop<k)
 
430
        {
 
431
        dig=j->loop;
 
432
        mn=mn*10;
 
433
        if (dig=='0') { mn=mn+0; jump tw_digokm; }
 
434
        if (dig=='1') { mn=mn+1; jump tw_digokm; }
 
435
        if (dig=='2') { mn=mn+2; jump tw_digokm; }
 
436
        if (dig=='3') { mn=mn+3; jump tw_digokm; }
 
437
        if (dig=='4') { mn=mn+4; jump tw_digokm; }
 
438
        if (dig=='5') { mn=mn+5; jump tw_digokm; }
 
439
        if (dig=='6') { mn=mn+6; jump tw_digokm; }
 
440
        if (dig=='7') { mn=mn+7; jump tw_digokm; }
 
441
        if (dig=='8') { mn=mn+8; jump tw_digokm; }
 
442
        if (dig=='9') { mn=mn+9; jump tw_digokm; }
 
443
        return -1;
 
444
        .tw_digokm;
 
445
        loop++;
 
446
        }                                            ! decode digital time
 
447
      }
 
448
    else
 
449
      {
 
450
      j=NextWordStopped();
 
451
      if ((j==TS_OCLOCK or -1)||(j=='am' or 'pm'))   ! then case (c) applies
 
452
        {
 
453
        hr=TryNumber(wn-2);
 
454
        mn=0;
 
455
        if (j~=TS_OCLOCK)
 
456
          wn--;
 
457
        }
 
458
      else
 
459
        {
 
460
        k=TryNumber(wn-1);
 
461
        if (k~=-1000)                                ! then case (b) applies
 
462
          {
 
463
          mn=k;
 
464
          hr=TryNumber(wn-2);
 
465
          }
 
466
        else                                         ! well, must be case (a)
 
467
          {
 
468
          mn=TryNumber(wn-2);
 
469
          if (i=='quarter')
 
470
            mn=15;
 
471
          if (i=='twenty-five')
 
472
            mn=25;
 
473
          if (i=='half' or 'thirty')
 
474
            mn=30;
 
475
          if (j=='minute' or 'minutes')
 
476
            j=NextWord();                            ! ignore 'minutes'
 
477
          hr=TryNumber(wn);
 
478
          wn++;
 
479
          if (j~='past' or 'to')
 
480
            hr=-1;
 
481
          if (j=='to')
 
482
            {
 
483
            hr--;
 
484
            mn=60-mn;
 
485
            if (hr==0)
 
486
              hr=12;
 
487
            }
 
488
          }
 
489
        }
 
490
      }
 
491
    if ((hr>12)||(hr<1)||(mn>59)||(mn<0))
 
492
      parsed_number=-1;
 
493
    else
 
494
      {
 
495
      if (hr==12)                                    ! now sort out am/pm
 
496
        hr=0;
 
497
      i=NextWord();
 
498
      if (i=='pm')
 
499
        hr=hr+12;
 
500
      else
 
501
        if (i~='am')                                 ! am or pm implied, then?
 
502
          {
 
503
          give TimeSys general;
 
504
          wn--;
 
505
          i=(hr*60+mn);
 
506
          j=((hr+12)*60+mn);
 
507
          i=i-the_time;
 
508
          j=j-the_time;
 
509
          if (i<0)
 
510
            i=i+(24*60);
 
511
          if (j<0)
 
512
            j=j+(24*60);
 
513
          if (i>j)
 
514
            hr=hr+12;
 
515
          }
 
516
      parsed_number=(hr*60+mn);
 
517
      }
 
518
    }
 
519
  if (parsed_number==-1)
 
520
    return -1;
 
521
  else
 
522
    return 1;
 
523
];
 
524
 
 
525
!----------------------------------------------------------------------------
 
526
! Now the grammar for the new Wait actions.
 
527
! You can use parsetime in other new actions. For example, you could perhaps
 
528
! allow setting of watches, etc. with grammar like:
 
529
! extend "set" first
 
530
!     * is_timepiece "to" parsetime -> SetClock;
 
531
!----------------------------------------------------------------------------
 
532
 
 
533
extend 'wait' replace
 
534
    *                                                                                   -> Wait
 
535
    * 'until'/'til'/'till'/'for' parsetime                              -> WaitUntil
 
536
    * 'for' number 'hour'/'hours'                                               -> WaitHours
 
537
    * 'for' number 'minute'/'minutes'                                   -> WaitMoves
 
538
    * 'for' number 'hour'/'hours' number 'minute'/'minutes'             -> WaitHours
 
539
    * 'for' number 'hour'/'hours' 'and' number 'minute'/'minutes' -> WaitHours
 
540
    * number 'minute'/'minutes'                                         -> WaitMoves
 
541
    * number 'hour'/'hours'                                     -> WaitHours
 
542
    * number                                                                    -> WaitMoves
 
543
    * number 'hour'/'hours' number 'minute'/'minutes'           -> WaitHours
 
544
    * number 'hour'/'hours' 'and' number 'minute'/'minutes'     -> WaitHours
 
545
    * parsetime                                                                 -> WaitUntil;