home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Between Heaven & Hell 2
/
BetweenHeavenHell.cdr
/
500
/
433
/
pycmdpro.inc
< prev
next >
Wrap
Text File
|
1986-10-23
|
54KB
|
1,751 lines
OVERLAY PROCEDURE StartUp; { Initialize everything when Pyroto starts }
VAR
CommentCh : CHAR;
NumItems : INTEGER;
SUChar : CHAR;
SUCntr : INTEGER;
SULine : Line;
BEGIN
CLRSCR;
WINDOW(1,3,80,25);
GOTOXY(1,5);
WRITELN(#17#16,' Start-up of Version ',Ver,' of Pyroto Mountain.');
SuppressOut := FALSE;
{------- Init variables -------}
Adding := FALSE;
Alert := FALSE;
Blanks := ' ';
Blanks := Blanks + Blanks; { 80 spaces }
CharDuringO := FALSE;
Charging := FALSE;
ChatAsk := FALSE;
Chattable := FALSE;
Cloaked := FALSE;
Contacting := FALSE;
CmdParm := '';
ExFnKey := FALSE;
Inputting := FALSE;
Level := 0;
IF UPPER(PARAMSTR(1)) = 'LOCAL'
THEN Comm := FALSE
ELSE Comm := TRUE;
Ascendable := TRUE;
Patience := 0;
SeismoActive := FALSE;
ShutDown := FALSE;
SpellRepeat := 1;
SysFail := FALSE;
TimeOutSecs := 30;
UpCaseInput := FALSE;
UserName := '';
Wrapping := FALSE;
Date := 0;
Mint := 0;
GetDate;
StartDate := Date;
StartMint := Mint;
SaveDescTexture := DescTexture[RANDOM(MaxDescTexture)+1];
SaveDescType := DescType[RANDOM(MaxDescType)+1];
SaveDescCharac := DescCharac[RANDOM(MaxDescCharac)+1];
{----- Read in Configuation -----}
{$I-}
ASSIGN(TxtFile,'PYCONFIG.DAT');
RESET(TxtFile);
IF OpenFailed THEN
BEGIN
CLRSCR;
WRITELN('Can''t open PYCONFIG.DAT on logged drive and/or directory.');
HALT;
END;
WRITELN(#17#16+' Reading in configuration data.');
CommentCh := #255;
NumItems := 26;
SUCntr := 0;
REPEAT
READLN(TxtFile,SULine);
IF (SULine[1] <> CommentCh) THEN
BEGIN
IF SUCntr > 0 THEN SULine := ParmFrom(SULine);
CASE SUCntr OF
00 : CommentCh := SULine[1];
01..08 : Banner[SUCntr] := SULine;
09 : BEGIN
VAL(SULine,Com1Base,VALRetCode);
IF VALRetCode <> 0 THEN
BEGIN
WRITELN('Non-numeric com port: ',SULine);
WRITELN('Try 1016 for COM1.');
HALT;
END;
END;
10 : ModemOkay := Upper(SULine);
11 : Modem300 := Upper(SULine);
12 : Modem1200 := Upper(SULine);
13 : Modem2400 := Upper(SULine);
14 : ModemAttn := SULine;
15 : ModemPickUp := SULine;
16 : ModemHangUp := SULine;
17 : ModemConfig := SULine;
18 : ModemReset := SULine;
19 : ModemDoAnswer := SULine;
20 : ModemNoAnswer := SULine;
21 : DFLocation := Upper(SULine + '\');
22 : MFLocation := Upper(SULine + '\');
23 : ServantWord := Upper(SULine);
24 : BEGIN
DisconMethod := Upper(SULine);
IF (DisconMethod <> 'DTR')
AND (DisconMethod <> 'ATTN') THEN
BEGIN
WRITELN('Disconnect method specified as: ',DisconMethod);
WRITELN('Invalid; should be DTR or ATTN. DTR assumed.');
DisconMethod := 'DTR';
END;
END;
25 : Attn := SULine;
26 : BEGIN
VAL(SULine,DisconDelay,VALRetCode);
IF VALRetCode <> 0 THEN
BEGIN
WRITELN('Non-numeric disconnect delay: ',SULine);
WRITELN('500 milliseconds assumed.');
DisconDelay := 500;
END;
END;
ELSE
WRITELN(SULine,' <-- Item ',SUCntr,' ignored.');
END; { of case }
SUCntr := SUCntr + 1;
END; { of not-a-comment }
UNTIL EOF(TxtFile) OR (SUCntr = (NumItems + 1));
CLOSE(TxtFile);
IF SUCntr < (NumItems + 1) THEN
BEGIN
WRITELN('Configuration file has less than '+IntToStr(NumItems)+' items!');
HALT;
END;
{------- Set up serial specs -------}
LowBaud := Com1Base;
HighBaud := Com1Base + 1;
DataPort := Com1Base;
IntReg := Com1Base + 1;
LineContrl := Com1Base + 3;
ModemContrl := Com1Base + 4;
StatusPort := Com1Base + 5;
ModemStatus := Com1Base + 6;
{----- Read in Spell Specs -----}
FOR SUCntr := 1 TO NumCmds DO
BEGIN
CmdCosts[SUCntr] := 0;
CmdLevels[SUCntr] := 0;
END;
ASSIGN(TxtFile,DFLocation + File_Specs);
RESET(TxtFile);
IF OpenFailed THEN
BEGIN
CLRSCR;
WRITELN('Can''t find ' + DFLocation + File_Specs + ' file.');
WRITELN('Copy it in from your installation disk.');
HALT;
END;
WRITELN(#17#16+' Reading in spell-specs data.');
CommentCh := #255;
READLN(TxtFile,SULine);
IF LENGTH(SULine) > 0 THEN CommentCh := SULine[1];
SUCntr := 0;
REPEAT
READLN(TxtFile,SULine);
IF (SULine[1] <> CommentCh) AND (LENGTH(SULine) <> 0) THEN
BEGIN
SUCntr := SUCntr + 1;
VAL(DeBlank(COPY(SULine,1,10)),CmdLevels[SUCntr],VALRetCode);
IF VALRetCode <> 0 THEN
WRITELN('Non-numeric spell level in line ',IntToStr(SUCntr),'.');
VAL(DeBlank(COPY(SULine,15,10)),CmdCosts[SUCntr],VALRetCode);
IF VALRetCode <> 0 THEN
WRITELN('Non-numeric spell cost in line ',IntToStr(SUCntr),'.');
END; { of not-a-comment }
UNTIL EOF(TxtFile) OR (SUCntr = NumCmds);
CLOSE(TxtFile);
IF SUCntr < NumCmds THEN
BEGIN
WRITELN('Spell-specs file has less than ',NumCmds,' items!');
WRITELN('Some spell levels and costs will be incorrect.');
END;
{------- Open the files -------}
{--- User File ---}
ASSIGN(UsersFile,DFLocation + File_Users);
RESET(UsersFile);
IF OpenFailed THEN
BEGIN
WRITELN('* Creating Users file: ' + DFLocation + File_Users);
WRITELN('* Press a key to begin ');
REPEAT UNTIL KEYPRESSED;
READ(KBD,SUChar);
REWRITE(UsersFile);
WRITELN('* Users file creation return code = '+IntToStr(IORESULT));
WRITELN('* Formatting Users file -- this takes a while');
WITH UsersRec DO
BEGIN
RealName := 'SERVANT OF TSOTL';
Phone := '0-000-000-0000 EXT. 00000';
UserName := 'SERVANT OF TSOTL';
Password := '.ABIA.'; { Ass-Backwards Into Adventure }
Points := 25000; Level := 500;
Date_Last := Date; Mint_Last := 0;
Width := 80;
MsgsSent := 0; MaxLevel := 0;
Date_A := 1; Mint_A := 0;
Date_B := 1; Mint_B := 0;
Date_C := 1; Mint_C := 0;
Date_D := 1; Mint_D := 0;
Date_P := 1; Mint_P := 0;
Date_S := 1; Mint_S := 0;
Date_X := 1; Mint_X := 0;
END;
WRITE(UsersFile,UsersRec);
WITH UsersRec DO
BEGIN
{ Fields are blanked to make file-dumps look nice }
RealName := ' ';
Phone := ' ';
UserName := ' ';
UserName := '';
Password := ' ';
Points := 0; Level := 0;
Date_Last := 0; Mint_Last := 0;
END;
FOR SUCntr := 2 TO MaxUsers DO WRITE(UsersFile,UsersRec);
RESET(UsersFile);
END;
{--- Next Msg # ---}
ASSIGN(NextMsgFile,DFLocation + File_Next);
RESET(NextMsgFile);
IF OpenFailed THEN
BEGIN
WRITELN('* Creating Next-Message file');
REWRITE(NextMsgFile);
WRITELN('* Return code = '+IntToStr(IORESULT));
NextMsg := 1;
WRITE(NextMsgFile,NextMsg);
RESET(NextMsgFile);
END;
{--- Msg Times ---}
ASSIGN(MsgTimesFile,DFLocation + File_Times);
RESET(MsgTimesFile);
IF OpenFailed THEN
BEGIN
WRITELN('* Creating Message-Times file');
REWRITE(MsgTimesFile);
WRITELN('* Return code = '+IntToStr(IORESULT));
WITH MsgTimesRec DO
BEGIN
Date_Added := 0; Mint_Added := 0; MsgBand := '?';
END;
FOR SUCntr := 1 TO MaxMsgs DO WRITE(MsgTimesFile,MsgTimesRec);
RESET(MsgTimesFile);
END;
{--- Seismoros ---}
ASSIGN(SeismoFile,DFLocation + File_Seismo);
RESET(SeismoFile);
IF OpenFailed THEN
BEGIN
REWRITE(SeismoFile);
WRITELN('* Creating Seismoros file');
WRITELN('* Return code = '+IntToStr(IORESULT));
WITH SeismoRec DO
BEGIN
Energy := 500; Spare1 := 0; Spare2 := 0;
END;
WRITE(SeismoFile,SeismoRec);
END;
RESET(SeismoFile);
{--- SysLog File ---}
ASSIGN(SysLogFile,DFLocation + File_SysLog);
RESET(SysLogFile);
IF OpenFailed
THEN
BEGIN
WRITELN('* Creating Observe file -- this takes a while');
REWRITE(SysLogFile);
IF IORESULT > 0
THEN OpenFail(DFLocation + File_SysLog)
ELSE
BEGIN
NextLog := 0;
IncrementLog;
WITH SysLogItem DO
BEGIN
SLDate := 0;
SLMint := 0;
SLType := '?';
SLText := '--- FORMAT OF SYSLOG FILE ---';
SLRept := 0;
END;
FOR SUCntr := 1 TO MaxSysLog DO WRITE(SysLogFile,SysLogItem);
END;
CLOSE(SysLogFile);
ASSIGN(SysLogFile,DFLocation + File_SysLog);
RESET(SysLogFile);
WRITELN;
END;
SEEK(SysLogFile,0);
READ(SysLogFile,SysLogItem);
NextLog := SysLogItem.SLRept;
{----- Question File -----}
ASSIGN(QuestFile,DFLocation + File_Queries);
RESET(QuestFile);
IF OpenFailed THEN
BEGIN
WRITELN('* Missing Question file ' + DFLocation + File_Queries);
WRITELN('* Copy it from installation disk.');
HALT;
END;
CLOSE(QuestFile);
{$I+}
{---------- Read in the data from the files ----------}
WRITELN(#17#16,' Reading in user file.');
SUCntr := 0;
REPEAT
SUCntr := SUCntr + 1;
READ(UsersFile,UsersRec);
UserNames[SUCntr] := UsersRec.UserName;
UNTIL SUCntr = MaxUsers;
{--- Read in Next msg # ---}
WRITELN(#17#16,' Reading in next message number.');
READ(NextMsgFile,NextMsg);
{--- Read in MsgTimes ---}
WRITELN(#17#16,' Reading in message times.');
FOR SUCntr := 1 TO MaxMsgs DO
BEGIN
READ(MsgTimesFile,MsgTimesRec);
MsgDates[SUCntr] := MsgTimesRec.Date_Added;
MsgMints[SUCntr] := MsgTimesRec.Mint_Added;
MsgBands[SUCntr] := MsgTimesRec.MsgBand;
MsgPosters[SUCntr] := MsgTimesRec.Poster;
END;
{----- Be Impressive -----}
WRITELN;
WRITELN('╔═════════════════════════════════════════════════════════════╗');
WRITELN('╟─┼───┼───┼─ THE PYROTO MOUNTAIN BBS/GAME SYSTEM ─┼───┼───┼─╢');
WRITELN('╟───┼───┼─── Entire product copyrighted (C) 1986 ───┼───┼───╢');
WRITELN('╟─┼───┼───┼─ P I N N A C L E S O F T W A R E ─┼───┼───┼─╢');
WRITELN('╟───┼───┼─── Post Office Box 163, Cartierville ───┼───┼───╢');
WRITELN('╟─┼───┼───┼─ Montreal, Quebec, Canada H4K 2J5 ─┼───┼───┼─╢');
WRITELN('╠╤═══════════════╤╤══════════════╤╤═════════╤╤═══════════════╤╣');
WRITELN('║│ VERSION ││ REVISION ││ PACKAGE ││ BETA-TEST │║');
WRITE('║│ ',Ver[1],' ││ ',Ver[3],Ver[4]);
WRITELN(' ││ ',Ver[5],' ││ ',Ver[6],' │║');
WRITELN('╚╧═══════════════╧╧══════════════╧╧═════════╧╧═══════════════╧╝');
WRITELN;
ModemInit;
SysLog('L','"No Visitors" sign taken down');
END;
{======= COMMAND PROCESSORS =======}
OVERLAY PROCEDURE Ascend; { Ascent-related spells: ASCEND, CLOAK, CHARGE }
VAR
AscOkay : BOOLEAN;
HintCntr : INTEGER;
QuesPtr : INTEGER;
SaveCmdP : Line;
SaveLevel : INTEGER;
SaveTOS : INTEGER;
SpellChk : INTEGER;
TestAns : STRING[30];
BEGIN
SaveLevel := Level;
Promo := FALSE;
IF Ascendable
THEN AscOkay := TRUE
ELSE
BEGIN
AscOkay := FALSE;
XLn('You can''t currently earn higher levels!');
IF NOT CharDuringO THEN XLn('The Guardian explains the reason why...');
IF NOT CharDuringO THEN XLn(LF+NoAscendMsg);
END;
IF AscOkay AND (Altitude = 500) THEN
BEGIN
AscOkay := FALSE;
XLn('You''re as high as you can go!');
XLn('Meet the challenge of power!');
END;
IF AscOkay AND ( Postings < ( Altitude DIV (8 - RANDOM(5)) ) )
AND (NOT WizOp)
THEN
BEGIN
XLn('TSOTL thinks you should get to know');
XLn('your fellow wizards a bit better. You');
XLn('will have to send a few messages before');
XLn('you can advance any further.');
AscOkay := FALSE;
END;
IF AscOkay THEN
BEGIN
IF (MaxLev < (Altitude + 1)) AND (MaxLev <> 0) THEN
BEGIN
XLn('Before you can rise any further, you');
XLn('must use the BESEECH spell to convince');
XLn('TSOTL that you are worthy. (However,');
XLn('if you gave the wrong phone-number at');
XLn('sign-up time ... don''t bother.)');
AscOkay := FALSE;
END;
END;
IF AscOkay THEN
BEGIN
IF NOT OpenQuestFile THEN XLn('Sorry; the Guardians are in a bad mood.')
ELSE
BEGIN
AscCnt := AscCnt + 1;
IF Altitude > 12 THEN AscCnt := AscCnt + 1;
IF Altitude > 20 THEN AscCnt := AscCnt + 1;
IF Altitude > 35 THEN AscCnt := AscCnt + 1;
IF RANDOM(20) < (AscCnt-2) THEN
BEGIN
X('The Guardian ');
CASE AscCnt OF
00..02 : XLn('is busy, having coffee.');
03..03 : XLn('is busy, filing his fangs.');
04..04 : BEGIN
XLn('is busy, reading a copy');
XLn('of "Guardian''s Monthly" magazine.');
END;
05..05 : BEGIN
XLn('is talking to another');
XLN('Guardian about the weather.');
END;
06..09 : XLn('pretends not to see you.');
10..12 : XLn('doesn''t want to talk.');
13..16 : XLn('looks annoyed.');
17..20 : XLn('looks very annoyed.');
ELSE
XLn('looks VERY irritated.');
END;
XLF;
IF RANDOM(100) < 25
THEN XLn('He turns away.')
ELSE XLn('He turns his back.');
IF AscCnt >= 20 THEN XLn(LF+'You are being totally ignored.');
END
ELSE
BEGIN
XLn('The Guardian is '+SaveDescTexture);
X(SaveDescType);
XLn(SaveDescCharac+'.');
X(LF+'He is checking his list...');
{ In case of same que. } QuesPtr := RANDOM(FileSize(QuestFile));
IF QuesPtr = AscLast THEN QuesPtr := RANDOM(FileSize(QuestFile));
AscLast := QuesPtr;
SEEK(QuestFile,QuesPtr);
READ(QuestFile,QuestRec);
XLF; XLn('He says to you...');
XLn(LF+QuestRec.Question);
IF Altitude < 35 THEN
BEGIN
X(LF+' ');
FOR HintCntr := 1 TO LENGTH(QuestRec.Answer) DO
BEGIN
IF QuestRec.Answer[HintCntr] = ' ' THEN X(' ') ELSE X('.');
END;
END;
XLF;
X('ANSWER HIM> ');
SaveCmdP := CmdParm;
CmdParm := '';
SaveTOS := TimeOutSecs;
TimeOutSecs := 50 - Level;
IF TimeOutSecs < 2 THEN TimeOutSecs := 2;
TestAns := Upper(GetInputLn); XLF;
TimeOutSecs := SaveTOS;
CmdParm := SaveCmdP;
WITH QuestRec DO
IF
( TestAns = Answer )
OR
(
( LENGTH(TestAns) > ( LENGTH(Answer) DIV 2 ) )
AND
(
( ( POS(TestAns,Answer)>0 ) AND ( POS(' ', Answer)>0 ) )
OR
( ( POS(Answer,TestAns)>0 ) AND ( POS(' ',TestAns)>0 ) )
)
)
THEN
BEGIN
XLn('"You may pass," says the Guardian.');
AscCnt := 0;
IF Level < 4 THEN
BEGIN
XLF; XLn('As you move uphill, he reminds you to use');
XLn('the magic HELP word to see new spells.'); XLF;
END;
IF (EsteemCalc > (100 + Level))
AND (Altitude = Level)
AND Pleaseable THEN
BEGIN
XLF;
XLn('And TSOTL, pleased with you,');
XLn('grants you some extra Manna.');
SetManna(Altitude*3+MannaPoints+2);
END;
IF Level < Altitude+1 THEN Level := Altitude+1;
SetAltitude(Altitude+1);
IF Promo THEN
BEGIN
XLF; XLn('Congratulations! You''re now part of');
XLn('the '+PresentBoard+'!');
XLF; XLn('Use READ to check the messages.');
END;
IF Altitude = 30 THEN
BEGIN
XLF; XLn('As you move uphill, the Guardian tells');
XLn('you that further ascent with CLOAK');
XLn('or ASCEND will cost as much Manna as');
XLn('the number of the level above.');
END;
IF (Altitude = 500) AND (SaveLevel = 499) THEN
BEGIN
XLF;
XLn('You have reached The Pinnacle!');
XLF;
XLn('TSOTL is very much impressed.');
XLF;
XLn('"WELCOME TO THE PINNACLE, MORTAL."');
SysLog('L',UserName+' reached Level 500!');
END;
END { Answer was right }
ELSE
BEGIN
IF (LENGTH(TestAns) <> LENGTH(QuestRec.Answer)) AND (Level > 3)
THEN AscCnt := AscCnt + 1;
IF Charging THEN
BEGIN
XLn('"Wrong!" yells the Guardian, and hurls');
IF LENGTH(TestAns) = 0
THEN
BEGIN
XLn('a fire-ball towards you.');
AscCnt := AscCnt + 1;
END
ELSE XLn('a bolt of lightning towards you.');
IF Cloaked
THEN XLn(LF+'Luckily, your cloaking spell saves you.')
ELSE Logoff := TRUE;
END
ELSE
BEGIN
IF LENGTH(TestAns) = 0
THEN
BEGIN
XLn('The Guardian shrugs.');
AscCnt := AscCnt + 1;
END
ELSE XLn('"No," says the Guardian. "Incorrect."');
IF (LENGTH(TestAns) = LENGTH(QuestRec.Answer))
AND (LENGTH(TestAns) > 5) THEN
BEGIN
HintCntr := 0;
FOR SpellChk := 1 TO LENGTH(TestAns) DO
IF TestAns[SpellChk] = QuestRec.Answer[SpellChk]
THEN HintCntr := HintCntr + 1;
IF (LENGTH(TestAns) - 2) <= HintCntr
THEN
BEGIN
XLF; XLn('As you depart, the Guardian mutters');
XLn('something about "bad spelling"...');
END;
END; { Worth spell-checking }
END; { Wasn't charging }
END; { Answer was wrong }
END; { Guard not fed up }
CLOSE(QuestFile);
END; { File opened okay }
END; { Posted enough and was sanctified enough }
Charging := FALSE;
Cloaked := FALSE;
END;
OVERLAY PROCEDURE Check;
BEGIN { Check }
XLnI('DAY:MINUTE ....... '+ShowDate(Date,Mint));
XLnI('Sorcery Level .... '+IntToStr(Level));
XLnI('Manna-points ..... '+IntToStr(MannaPoints));
XLnI('Maximum Manna .... '+IntToStr((Level+1) * 50));
XLnI('Manna Recovery ... '+IntToStr(25+Level) + ' per day.');
XLnI('TSOTL''s Esteem ... '+IntToStr(EsteemCalc));
IF WizOp THEN
XLnI(LF+'Next message # ... '+IntToStr(NextMsg));
XLnI(LF+'You are currently on a level used by');
XLnI('the '+PresentBoard+'.');
CharDuringO := FALSE;
END;
OVERLAY PROCEDURE Help; { HELP Spell }
VAR
HelpCntr : INTEGER;
BEGIN
Explained := FALSE;
ExplainKeys;
XLn('"YOU ARE PERMITTED TO USE THESE SPELLS"');
HelpCntr := 1;
IF Width >= 64 THEN XLF;
REPEAT
IF (CmdLevels[HelpCntr] <= Level)
AND ((CmdLevels[HelpCntr] < 499) OR WizOp)
AND (InFocus(CmdWords[HelpCntr]) OR InFocus(CmdDescs[HelpCntr]))
THEN
BEGIN
IF Width < 64 THEN
BEGIN XLn(LF+CmdWords[HelpCntr]); XLn(CmdDescs[HelpCntr]); END
ELSE
BEGIN
XLn(Fmt(CmdWords[HelpCntr],Left,10)+' '+CmdDescs[HelpCntr]);
END;
END;
HelpCntr := HelpCntr + 1;
UNTIL CharDuringO OR (HelpCntr > NumCmds);
END;
OVERLAY PROCEDURE Spells; { SPELLS spell }
VAR
OutCntr : INTEGER;
SpellCntr : INTEGER;
BEGIN
Explained := FALSE;
ExplainKeys;
OutCntr := 0;
SpellCntr := 0;
IF WIDTH < 80 THEN
BEGIN
XLn(' MAGIC MANNA- SORCERY');
XLn(' WORD POINTS LEVEL');
XLn('---------- ------- -------');
REPEAT
SpellCntr := SpellCntr + 1;
IF ((CmdLevels[SpellCntr] < 401) OR WizOp)
AND (InFocus(CmdWords[SpellCntr]) OR InFocus(CmdDescs[SpellCntr]))
THEN
BEGIN
X( Fmt( CmdWords[SpellCntr], Left, 10 ) + ' ' );
X( Fmt( IntToStr(CmdCosts[SpellCntr]), Right, 4 ) + ' ' );
X( Fmt( IntToStr(CmdLevels[SpellCntr]), Right, 3 ) );
XLF;
END;
UNTIL CharDuringO OR (SpellCntr = NumCmds);
END
ELSE
BEGIN
XLn(' MAGIC MANNA- SORCERY MAGIC MANNA- SORCERY');
XLn(' WORD POINTS LEVEL WORD POINTS LEVEL');
XLn('---------- ------- ------- ---------- ------- -------');
REPEAT
SpellCntr := SpellCntr + 1;
IF ((CmdLevels[SpellCntr] < 401) OR WizOp)
AND (InFocus(CmdWords[SpellCntr]) OR InFocus(CmdDescs[SpellCntr]))
THEN
BEGIN
X( Fmt( CmdWords[SpellCntr], Left, 10 ) + ' ' );
X( Fmt( IntToStr(CmdCosts[SpellCntr]), Right, 4 ) + ' ' );
X( Fmt( IntToStr(CmdLevels[SpellCntr]), Right, 3 ) );
OutCntr := OutCntr + 1;
IF ODD(OutCntr) THEN X(' ') ELSE XLF;
END;
UNTIL CharDuringO OR (SpellCntr = NumCmds);
END;
IF NOT CharDuringO THEN
BEGIN
IF ODD(OutCntr) THEN XLF;
XLF; XLn('It is not necessary to type the entire');
XLn('word -- just the first few letters.');
END;
END;
OVERLAY PROCEDURE Review; { REVIEW spell }
VAR
RStat : SFType;
SaveTune : Line;
BEGIN
ReadBand := '*';
SaveTune := TuneString;
TuneString := '';
MsgPtr := AskMsgTimesPtr + 1; { Add one 'cuz in-core index starts at zero }
IF MsgPtr > MaxMsgs
THEN XLn('Sorry, can''t find that message.')
ELSE RStat := XMsg;
TuneString := SaveTune;
END;
OVERLAY PROCEDURE Specs; { Specs spell }
VAR
XWidth : INTEGER;
BEGIN
XLn('Your screen width is set to '+IntToStr(Width)+'.');
XLF;
XWidth := GetInt('Specify a new screen width: ');
IF (XWidth < 10) OR (XWidth > 80)
THEN XLn('Width must be between 10 and 80.')
ELSE Width := XWidth;
BreakPoint := Width DIV 3;
END;
OVERLAY PROCEDURE TimeWarp; { TimeWarp spell }
BEGIN { TimeWarp }
XLn('It is now '+ShowDate(Date,Mint)+'.'+LF);
Date_Warp := GetInt('Warp back to which day? ');
Mint_Warp := GetInt('What minute of that day? ');
IF Date_Warp < 1 THEN
BEGIN
Date_Warp := 1;
Mint_Warp := 1;
END;
XLF;
IF (Date_Warp < Date)
OR ((Date_Warp = Date) AND (Mint_Warp < Mint))
THEN
BEGIN
XLnI('Your READ, SCROLLS & LISTEN spells will');
XLnI('now show messages sent after '+ShowDate(Date_Warp,Mint_Warp)+'.');
XLnI('');
XLnI('To set your "read-after" times back to');
XLnI('the way they were when you arrived');
XLnI('here, TIMEWARP to a future DAY:MINUTE');
XLnI('such as '+ShowDate( (Date DIV 10) * 10 + 10, 0 )+'.');
END
ELSE
BEGIN
Date_Warp := -1; { Inactive }
XLn('Back on normal time...');
END;
END;
OVERLAY PROCEDURE Detect;
VAR
BDate : INTEGER;
BDateStr : Line;
TempInt : INTEGER;
BEGIN
XLn('Today is day '+IntToStr(Date)+'.'); XLF;
BDate := GetInt('Display for what day and earlier? ');
XLF;
XLn(' DAY:MIN SENT BY LEVEL');
XLn('--------- -------------------- -------');
TempInt := NextMsg;
REPEAT
TempInt := MsgNumBefore(TempInt);
IF (MsgDates[TempInt] <> 0)
AND (BDate >= MsgDates[TempInt])
AND (InFocus(MsgPosters[TempInt]))
THEN
BEGIN
X( Fmt (IntToStr(MsgDates[TempInt]), Right, 4) + ':');
X( Fmt (IntToStr(MsgMints[TempInt]), Left, 4) + ' ');
X( Fmt (Upper(MsgPosters[TempInt]), Left, 20) + ' ');
CASE MsgBands[TempInt] OF
'0' : X(' 0 ');
'A' : X(' 1 - 29');
'B' : X('30 - 99');
'C' : X('100-299');
'D' : X('300-500');
'G' : X('Arrival');
'P' : X('Beseech');
'S' : X('Scrolls');
ELSE X('UNKNOWN');
END;
XLF;
END;
UNTIL (TempInt = NextMsg) OR CharDuringO;
END; { Detect }
OVERLAY PROCEDURE Change; { CHANGE spell }
VAR
ChChar : CHAR;
SaveIt : BOOLEAN;
BEGIN
MsgPtr := AskMsgTimesPtr;
IF MsgPtr = MaxMsgs
THEN XLn('Sorry, can''t find that message.')
ELSE
BEGIN
IF (MsgPosters[MsgPtr+1] <> UserName) AND (NOT WizOp)
THEN
BEGIN
XLn('TSOTL takes a dim view of those who');
XLn('try to alter what others have said...');
END
ELSE
BEGIN
IF NOT OpenFile(MsgFile(MsgPtr+1))
THEN XLn('That message is strangely immune.')
ELSE
BEGIN
XLn('One moment, please...');
ChSize := 0;
REPEAT
ChSize := ChSize + 1;
READLN(TxtFile,EditBuffer[ChSize]);
EditBuffer[ChSize] := DeCompress(EditBuffer[ChSize]);
UNTIL EOF(TxtFile);
ChChar := Editor('C');
END; { Got msg }
END; { His msg }
END; { Found msg }
END;
OVERLAY PROCEDURE Bestow; { BESTOW spell }
VAR
BAmntStr : TenType;
BAmnt : INTEGER;
PoorGuy : UNameType;
BEGIN
Tactical := TRUE;
X('Give Manna to who? ');
PoorGuy := Upper(GetInputLn); XLF;
IF NOT FindUserRecPtr(PoorGuy)
THEN XLn('No such person on THIS Mountain!')
ELSE
BEGIN
XLn('You have '+IntToStr(Mannapoints)+' Manna-points.'); XLF;
BAmnt := GetInt('How much will you give? ');
IF BAmnt > MannaPoints
THEN XLn('You don''t HAVE that many!')
ELSE
BEGIN
MannaPoints := MannaPoints - BAmnt;
SEEK(UsersFile,UserRecPtr);
READ(UsersFile,OtherUsersRec);
IF OtherUsersRec.UserName <> PoorGuy
THEN XLn('Strangely immune!')
ELSE
BEGIN
OtherUsersRec.Points := BigAdd(OtherUsersRec.Points,BAmnt);
SEEK(UsersFile,UserRecPtr);
WRITE(UsersFile,OtherUsersRec);
XLF;
IF BAmnt > 9
THEN XLn('Now at '+IntToStr(OtherUsersRec.Points)+' Manna-points!')
ELSE XLn('Not very generous, are you?');
IF (RANDOM(100) < 10) AND (BAmnt > 50)
THEN XLn(LF+'TSOTL values your generosity.');
SysLog('I',UserName+' bestowed '+IntToStr(BAmnt)+' to '+PoorGuy);
END;
END;
END;
END;
OVERLAY PROCEDURE Teleport;
VAR
TNum : INTEGER;
BEGIN { Teleport }
TNUm := GetInt('To which level are you going? ');
IF Tnum > Level THEN Tnum := Level;
IF (TNum DIV 25 < Postings) OR WizOp
THEN SetAltitude(TNum)
ELSE
BEGIN
XLn('TSOTL rumbles:');
XLF;
XLn('"I HOLD YOU IN VERY LOW ESTEEM!');
XLn('YOU MUST CLIMB THE HARD WAY!"');
XLF;
XLn('Looks like you''ll have to ASCEND.');
END;
END;
OVERLAY PROCEDURE Boost;
VAR
OkayLine : TenType;
TempInt : INTEGER;
BEGIN
IF BaudRate > 999
THEN
BEGIN
XLn('BOOST is only useable');
XLn('on low-speed modems.');
END
ELSE
BEGIN
XLn('Some modems can run faster over');
XLn('local lines if the terminal program');
XLn('has variable baud-rate selection...'); XLF;
TempInt := GetInt('What baud-rate do you want? '); XLF;
IF (TempInt <= 300) OR (TempInt > 999)
THEN
BEGIN
XLn('Impossible baud rate.');
XLn('Baud-rate unchanged.');
END
ELSE
BEGIN
XLn('If you don''t succeed, switch back to '+IntToStr(BaudRate)+' Baud.'); XLF;
XLn('Reset baud-rate, then type: TEST');
X('AWAITING TEST> ');
SetBaud(TempInt);
OkayLine := '';
FOR TempInt := 1 TO 4 DO OkayLine := OkayLine + UPCASE(SerialIn);
IF OkayLine <> 'TEST' THEN SetBaud(BaudRate);
XLF;
END; { Acceptable attempt }
END; { Low-speed modem }
END;
OVERLAY PROCEDURE SlowTime;
BEGIN
IF SlowedTime
THEN XLn('Don''t push TSOTL''s patience.')
ELSE
BEGIN
SlowX('Time slows down ...');
XLF;
Patience := Patience + 15;
SlowedTime := TRUE;
END;
END;
OVERLAY PROCEDURE Roster; { ROSTER spell }
VAR
RDiv : INTEGER;
PCntr : INTEGER;
RCntr : INTEGER;
BEGIN
RDiv := Width DIV 21;
PCntr := 1;
RCntr := 1;
REPEAT
IF (LENGTH(UserNames[RCntr]) > 0) AND (InFocus(UserNames[RCntr]))
THEN
BEGIN
IF Width < 22
THEN XLn(UserNames[RCntr])
ELSE
BEGIN
IF (PCntr DIV RDiv * RDiv) = PCntr
THEN XLn(UserNames[RCntr])
ELSE X(Fmt(UserNames[RCntr],Left,21));
PCntr := PCntr + 1;
END;
END;
RCntr := RCntr + 1;
UNTIL (RCntr = MaxUsers) OR CharDuringO;
XLF;
END;
OVERLAY PROCEDURE Probe; { PROBE spell }
VAR
VWho : UNameType;
Esteem : INTEGER;
BEGIN
X('Probe who? ');
VWho := Upper(GetInputLn); XLF;
IF LENGTH(VWho) = 0 THEN XLn('Okay ... FORGET it, then!')
ELSE
BEGIN
IF NOT FindUserRecPtr(VWho)
THEN XLn('Don''t know the person...')
ELSE
BEGIN
SEEK(UsersFile,UserRecPtr);
READ(UsersFile,OtherUsersRec);
IF VWho = UserName
THEN Esteem := EsteemCalc
ELSE Esteem := OtherUsersRec.MsgsSent*10 DIV (OtherUsersRec.Level + 1) * 10;
IF Esteem < 0 THEN Esteem := 0;
IF (OtherUsersRec.Level > Level + 400)
THEN XLn('Sorcery Level too high to probe!')
ELSE WITH OtherUsersRec DO
BEGIN
XLnI('Sorcery Level .... '+IntToStr(Level));
IF WizOp THEN XLnI('Maximum Level .... '+IntToStr(MaxLevel));
XLnI('Manna-points ..... '+IntToStr(Points));
XLnI('Manna Recovery ... '+IntToStr(25+Level)+' per day.');
XLnI('TSOTL''s Esteem ... '+IntToStr(Esteem));
IF WizOp THEN XLnI('Esteem Basis ..... '+IntToStr(MsgsSent));
IF Date_Last = 0
THEN XLnI('Status ........... BANISHED!')
ELSE XLnI('Last call at ..... '+ShowDate(Date_Last,Mint_Last));
IF WizOp THEN
BEGIN
XLnI('True Name ........ '+RealName);
XLnI('Phone Number ..... '+Phone);
XLnI('Terminal Width ... '+IntToStr(Width));
END;
END;
END;
END;
CharDuringO := FALSE;
END;
OVERLAY PROCEDURE Inquire;
VAR
TempInt : INTEGER;
BEGIN
XLn('The Spirit Of The Land says unto you:');
XLF;
XLn('"I WILL NOT PERMIT THIS VISIT TO LAST');
XLn('MORE THAN '+IntToStr(Patience)+' MINUTES."'); XLF;
X('You''ve been here about ');
TempInt := ROUND(ElapsedTime(StartDate,StartMint,Date,Mint));
X(IntToStr(TempInt));
X(' minute'); IF TempInt = 1 THEN XLn('.') ELSE XLn('s.');
END;
OVERLAY PROCEDURE Drain(DFunc : CHAR); { DRAIN spell }
VAR
PoorGuy : UNameType;
BEGIN
Tactical := TRUE;
X('Remove Manna from WHO? ');
PoorGuy := Upper(GetInputLn); XLF;
IF NOT FindUserRecPtr(PoorGuy)
THEN XLn('Don''t know that name.')
ELSE
BEGIN
SEEK(UsersFile,UserRecPtr);
READ(UsersFile,OtherUsersRec);
IF OtherUsersRec.UserName <> PoorGuy
THEN XLn('Strangely immune!')
ELSE
BEGIN
IF (MaxLev <> 0) AND (MaxLev < 16)
AND (OtherUsersRec.MaxLevel = 0)
THEN
BEGIN
XLn('That wizard has been sanctified for');
XLn('further advancement, but you have not.');
XLn('You must BESEECH for sanctification be-');
XLn('fore you can do this.');
END
ELSE
BEGIN
GetSpellRepeat;
IF SpellRepeat = 0
THEN XLn('That''s nice of you!')
ELSE
BEGIN
WITH OtherUsersRec DO
BEGIN
Points := BigSub(Points,SpellRepeat * 100);
IF (Level > 10) AND (Points = -30000)
THEN
BEGIN
Level := Level - 10;
XLn('"DOWNWARDS!"');
XLF;
END;
END;
SEEK(UsersFile,UserRecPtr);
WRITE(UsersFile,OtherUsersRec);
IF DFunc = 'S'
THEN SysLog('W',UserName+' stole from '+PoorGuy)
ELSE SysLog('I',UserName+' drained '+PoorGuy);
XLF;
XLn('Now at '+IntToStr(OtherUsersRec.Points)+' Manna-points!');
IF RANDOM(100) < 5 THEN XLn(LF+'TSOTL is amused.');
IF DFunc = 'S' THEN
BEGIN
IF Level > OtherUsersRec.Level THEN SpellRepeat := SpellRepeat * 2;
Postings := Postings - SpellRepeat;
END;
END; { Repeat > 0 }
END; { Sanc/Sanc draining }
END; { File checked okay }
END; { Name is okay }
END;
OVERLAY PROCEDURE Seismo(SFunc : CHAR); { FEED and STARVE spells }
VAR
SAmnt : INTEGER;
SReal : REAL;
SRand : INTEGER;
BEGIN
Tactical := TRUE;
XLn('Quoth Seismoros:');
XLF;
SRand := RANDOM(15);
X('"I AM ');
CASE SRand OF
00 : X('LIFE.');
01 : X('SHIVA.');
02 : X('MOTHER TO THE PHOENIX.');
03 : X('CREATOR.');
04 : X('DESTROYER.');
05 : X('SEISMOROS!');
06 : X('THE CIRCLE.');
07 : X('THE SPIRIT OF DEATH.');
08 : X('THE WILL OF REBIRTH.');
09 : X('THE AGENT OF WILL.');
10 : X('THE CYCLE OF THE SEASONS.');
11 : X('THE EQUALIZER.');
12 : X('THE HOPE OF THE OPPRESSED.');
13 : X('THE DESPISED ONE.');
14 : X('THE ONE THEY FEAR.');
END;
XLn('"');
XLF;
XLn('You have '+IntToStr(MannaPoints)+' Manna-points.');
XLF;
XLn('How many Manna-points will you use for');
IF SFunc = 'F'
THEN X('feeding')
ELSE X('starving');
SAmnt := GetInt(' Seismoros? ');
XLF;
IF (SAmnt <= 10) AND (NOT WizOp)
THEN XLn('Seismoros brushes you aside.')
ELSE
BEGIN
IF SAmnt > MannaPoints
THEN XLn('You don''t HAVE that many!')
ELSE
BEGIN
SetManna(MannaPoints - SAmnt);
RESET(SeismoFile);
READ(SeismoFile,SeismoRec);
IF SFunc = 'F'
THEN SAmnt := BigAdd(SeismoRec.Energy,SAmnt DIV 2)
ELSE SAmnt := BigSub(SeismoRec.Energy,SAmnt DIV 2);
IF SAmnt < 0 THEN SAmnt := 0;
SeismoRec.Energy := SAmnt;
IF SAmnt < 20000
THEN
BEGIN
SReal := SAmnt / 200.0;
XLn('Seismoros is '
+IntToStr( TRUNC(SReal) )
+'.'
+IntToStr( TRUNC( FRAC(SReal) * 10 ) )
+'% energized.');
END
ELSE
BEGIN
XLn('Seismoros is fully energized!');
XLF;
XLn('The Mountain is quivering!');
XLF;
XLn('SEISMOROS HAS BEEN UNLEASHED!');
SysLog('I','SEISMOROS HAS BEEN UNLEASHED!');
Logoff := TRUE;
SeismoActive := TRUE;
SeismoRec.Energy := 500;
END; { 100% energized! }
RESET(SeismoFile);
WRITE(SeismoFile,SeismoRec);
END; { Contribution <= Manna }
END; { Contribution exceeded 10 }
END;
OVERLAY PROCEDURE StopTime;
BEGIN
IF StoppedTime
THEN XLn('TSOTL says, "NOT TWICE IN ONE VISIT".')
ELSE
BEGIN
X('Time seems to be coming to a ');
DELAY(100); X('h'); DELAY(200); X('a');
DELAY(300); X('l'); DELAY(400); X('t');
DELAY(500); X('.'); DELAY(600);
XLF;
Patience := Patience + PatienceCalc;
StoppedTime := TRUE;
END;
END;
OVERLAY PROCEDURE Promote; { PROMOTE spell }
VAR
PoorGuy : UNameType;
PromoOK : BOOLEAN;
BEGIN
Tactical := TRUE;
PromoOK := TRUE;
SpellRepeat := 0;
X('Promote who? ');
PoorGuy := Upper(GetInputLn); XLF;
{----- Valid user? -----}
IF NOT FindUserRecPtr(PoorGuy) THEN
BEGIN
XLn('Can''t find that name.');
PromoOK := FALSE;
END;
{----- Index Error or Auto-Promote? -----}
IF PromoOK THEN
BEGIN
SEEK(UsersFile,UserRecPtr);
READ(UsersFile,OtherUsersRec);
IF (OtherUsersRec.UserName <> PoorGuy) OR (PoorGuy = UserName)
THEN
BEGIN
XLn('Nice try!');
PromoOK := FALSE;
END;
END;
{----- Higher-Wizard Promote? -----}
IF PromoOK THEN
BEGIN
IF OtherUsersRec.Level >= Level
THEN
BEGIN
XLn('You can''t promote somebody');
XLn('to a level above your own.');
PromoOK := FALSE;
END
END;
{----- Zero Promote? -----}
IF PromoOK THEN
BEGIN
GetSpellRepeat;
IF SpellRepeat = 0 THEN PromoOK := FALSE;
END;
{----- Past Sanctification Limit? -----}
IF PromoOK THEN
BEGIN
IF (OtherUsersRec.Level + SpellRepeat > OtherUsersRec.MaxLevel)
AND (OtherUsersRec.MaxLevel <> 0)
THEN
BEGIN
XLn('That wizard is not sanctified to rise');
XLn('above level '+IntToStr(OtherUsersRec.MaxLevel)+'.');
PromoOK := FALSE;
END;
END;
{----- Overhead Promote? -----}
IF PromoOK THEN
BEGIN
IF OtherUsersRec.Level + SpellRepeat > Level
THEN
BEGIN
XLn('You can''t promote somebody higher');
XLn('than your own sorcery level!');
PromoOK := FALSE;
END;
END;
{----- Esteemed Enough? -----}
IF PromoOK THEN
BEGIN
IF (OtherUsersRec.Level + SpellRepeat) DIV 30 > OtherUsersRec.MsgsSent
THEN
BEGIN
XLn('TSOTL doesn''t think that wizard');
XLn('deserves to be promoted that');
XLn('high -- power must be earned!');
PromoOK := FALSE;
END;
END;
{----- Do the Promote -----}
IF PromoOK THEN
BEGIN
OtherUsersRec.Level := OtherUsersRec.Level + SpellRepeat;
SEEK(UsersFile,UserRecPtr);
WRITE(UsersFile,OtherUsersRec);
XLn('Now at Level '+IntToStr(OtherUsersRec.Level)+'.');
IF RANDOM(100) < 5 THEN XLn(LF+'TSOTL is intrigued.');
SysLog('I',UserName+' promoted '+PoorGuy);
END
ELSE
BEGIN
XLF;
XLn('No promotion done.');
MannaPoints := MannaPoints + (SpellCost * SpellRepeat);
END;
END;
OVERLAY PROCEDURE Demote; { DEMOTE spell }
VAR
BelowNum : INTEGER;
PoorGuy : UNameType;
BEGIN
Tactical := TRUE;
IF NOT WizOp THEN
BEGIN
BelowNum := Level - 2;
XLn('You can demote any wizard who has a');
XLn('Sorcery Level below '+IntToStr(BelowNum)+'.');
XLF;
END;
X('Demote WHO? ');
PoorGuy := Upper(GetInputLn); XLF;
IF NOT FindUserRecPtr(PoorGuy)
THEN XLn('Can''t find that name.')
ELSE
BEGIN
SEEK(UsersFile,UserRecPtr);
READ(UsersFile,OtherUsersRec);
IF (OtherUsersRec.UserName <> PoorGuy) OR (PoorGuy = UserName)
THEN XLn('Strangely immune!')
ELSE
BEGIN
IF (OtherUsersRec.Level >= BelowNum) AND (NOT WizOp)
THEN XLn('Too powerful for you to do that!')
ELSE
BEGIN
IF WizOp
THEN
BEGIN
XLn(PoorGuy+' is at level '+IntToStr(OtherUsersRec.Level+1)+'.');
OtherUsersRec.Level := GetInt('Specify new level: ');
SpellRepeat := 1;
END
ELSE
BEGIN
GetSpellRepeat;
OtherUsersRec.Level := OtherUsersRec.Level - SpellRepeat; { ouch }
END;
IF SpellRepeat = 0
THEN XLn('Level unchanged.')
ELSE
BEGIN
IF OtherUsersRec.Level > 500 THEN OtherUsersRec.Level := 500;
IF OtherUsersRec.Level < 0 THEN OtherUsersRec.Level := 0;
SEEK(UsersFile,UserRecPtr);
WRITE(UsersFile,OtherUsersRec);
XLn('Now at Level '+IntToStr(OtherUsersRec.Level)+'.');
IF RANDOM(100) < 5 THEN XLn(LF+'TSOTL is intrigued.');
SysLog('I',UserName+' demoted '+PoorGuy);
END; { Repeat > 0 }
END; { Demoteable }
END; { File checks out, not himself }
END; { Valid name }
END;
OVERLAY PROCEDURE Suggest; { SUGGEST spell }
VAR
PQuest : STRING[40];
PAns : STRING[30];
QPosn : INTEGER;
BEGIN
Tactical := TRUE;
XLn('You may add a question to the list that');
XLn('the Guardians use to test a wizard''s');
XLn('qualifications to progress higher.');
XLF;
XLn('NOTE: Answers are uppercased automatically.');
XLF;
XLn('Enter your question (max 39 chars).');
XLn('----+----+----+----+----+----+----+----');
PQuest := GetInputLn; XLF;
IF LENGTH(PQuest) > 2 THEN
BEGIN
XLn('And the answer is? (max 30 chars).');
XLn('----+----+----+----+----+----+');
PAns := Upper(GetInputLn);
XLF; XLn('Ready to add the question.');
IF Yes THEN
BEGIN
XLF;
IF NOT OpenQuestFile THEN XLn('Sorry -- The Guardians are out.')
ELSE
BEGIN
WITH QuestRec DO BEGIN Question := PQuest; Answer := PAns; END;
QPosn := FILESIZE(QuestFile);
WRITELN(#17#16,' ',QPosn,' questions.'); WRITELN;
IF QPosn > 1000 THEN QPosn := RANDOM(1000) + 1; { 70,000 bytes max }
SEEK(QuestFile,QPosn);
WRITE(QuestFile,QuestRec);
CLOSE(QuestFile);
XLn('The Guardians thank you.');
AscCnt := AscCnt - 2;
SysLog('I',UserName+' suggested a new question');
IF RANDOM(100) < 15 THEN XLn(LF+'TSOTL likes that question.');
END;
END;
END
ELSE XLn('Hardly a question!');
END;
OVERLAY PROCEDURE Correct; { CORRECT spell }
VAR
CCntr : INTEGER;
CFind : STRING[40];
Corring : BOOLEAN;
GotQ : BOOLEAN;
PQuest : STRING[40];
PAns : STRING[30];
QSize : INTEGER;
BEGIN
Tactical := TRUE;
IF NOT WizOp THEN
BEGIN
XLn('NOTE: You can only change the');
XLn('QUESTION, not the answer! If this');
XLn('isn''t what you''d hoped, just press');
XLn('RETURN in answer to this:'); XLF;
END;
XLn('Enter a recognizable portion of the');
XLn('question you wish to rephrase.');
X('> ');
CFind := GetInputLn; XLF;
IF LENGTH(CFind) > 0 THEN
BEGIN
IF NOT OpenQuestFile THEN XLn('The Guardians ignore you.')
ELSE
BEGIN
CCntr := 0;
GotQ := FALSE;
QSize := FileSize(QuestFile);
REPEAT
READ(QuestFile,QuestRec);
IF POS(CFind,QuestRec.Question) > 0
THEN GotQ := TRUE
ELSE CCntr := CCntr + 1;
UNTIL GotQ OR (CCntr = QSize);
IF NOT GotQ THEN XLn('Can''t find that question.')
ELSE
BEGIN
Corring := FALSE;
XLn('----+----+----+----+----+----+----+----');
XLn(QuestRec.Question);
PQuest := GetInputLn; XLF;
IF LENGTH(PQuest) < 3
THEN XLn('Question unchanged.')
ELSE
BEGIN
QuestRec.Question := PQuest;
Corring := TRUE;
END;
IF WizOp THEN
BEGIN
XLn('You may change the answer.');
IF Yes THEN
BEGIN
XLF;
XLn('----+----+----+----+----+----+');
XLn(QuestRec.Answer);
PAns := Upper(GetInputLn); XLF;
IF LENGTH(PAns) = 0
THEN XLn('Answer unchanged.')
ELSE
BEGIN
QuestRec.Answer := PAns;
Corring := TRUE;
END;
END;
IF Corring THEN
BEGIN
SEEK(QuestFile,CCntr);
WRITE(QuestFile,QuestRec);
XLn('The Guardians thank you.');
AscCnt := AscCnt - 2;
SysLog('I',UserName+' corrected a question');
END;
END;
END;
CLOSE(QuestFile);
END;
END
ELSE XLn('No harm done.');
END;
OVERLAY PROCEDURE Focus; { FOCUS spell }
BEGIN
XLn('This will affect the display spells:');
XLn('What name or phrase are you seeking?');
X('> ');
UpCaseInput := TRUE;
FocusString := Upper(GetInputLn);
UpCaseInput := FALSE;
IF FocusString = '' THEN XLn('Defocussed.');
END;
OVERLAY PROCEDURE Tune; { TUNE spell }
BEGIN
XLn('This will affect the reading spells:');
XLn('What name or phrase are you seeking?');
X('> ');
UpCaseInput := TRUE;
TuneString := Upper(GetInputLn);
UpCaseInput := FALSE;
IF TuneString = '' THEN XLn('Detuned.');
END;
OVERLAY PROCEDURE Hurl; { HURL spell }
VAR
HCntr : INTEGER;
HDate : INTEGER;
HMint : INTEGER;
NewDate : INTEGER;
NewMint : INTEGER;
BEGIN
Tactical := TRUE;
HCntr := AskMsgTimesPtr;
IF HCntr = MaxMsgs
THEN XLn('Can''t find that message -- sorry!')
ELSE
BEGIN
NewDate := 1; NewMint := 0;
IF Level > 149 THEN
BEGIN
XLn('You may specify the actual new time.');
IF Yes THEN
BEGIN
XLF;
NewDate := GetInt('New date? ');
IF NewDate = 0 THEN NewDate := 1;
NewMint := GetInt('New minute? ');
END;
END;
XLF;
X('D'); SEEK(MsgTimesFile,HCntr);
X('O'); READ(MsgTimesFile,MsgTimesRec);
MsgDates[HCntr + 1] := NewDate; MsgTimesRec.Date_Added := NewDate;
MsgMints[HCntr + 1] := NewMint; MsgTimesRec.Mint_Added := NewMint;
X('N'); SEEK(MsgTimesFile,HCntr);
X('E'); WRITE(MsgTimesFile,MsgTimesRec); XLn('.');
SysLog('I',UserName+' hurled message by '+MsgPosters[HCntr + 1]);
IF RANDOM(100) < 25 THEN XLn(LF+'TSOTL is amused.');
END;
END;
OVERLAY PROCEDURE OmniView; { OMNIVIEW spell }
VAR
OVChar : CHAR;
OVCntr : INTEGER;
OVLevel : INTEGER;
MsgTotC : INTEGER;
MsgTot : INTEGER;
WizTot : INTEGER;
Wiz03 : INTEGER;
Wiz07 : INTEGER;
Wiz14 : INTEGER;
BEGIN
NonReadInfo := TRUE;
XLn('What is the lowest Sorcery Level');
OVLevel := GetInt('that you wish to display? ');
IF WizOp THEN XLn(LF+'For WizOp: Includes Esteem, MaxLevel, Phone.');
XLF; XLn('Display may pause for up to a minute.');
XLn('This is a normal cogitation delay.');
XLF; XLn(' WIZARD NAME LEV MANNA LAST CALL');
XLn('-------------------- --- ----- ---------');
OVCntr := 1;
WizTot := 0;
Wiz03 := 0;
Wiz07 := 0;
Wiz14 := 0;
RESET(UsersFile);
REPEAT
READ(UsersFile,OtherUsersRec);
WITH OtherUsersRec DO
BEGIN
IF (Date_Last > 0) AND (Level >= OVLevel)
AND (LENGTH(UserName) > 0)
AND (InFocus(UserName))
THEN
BEGIN
WizTot := WizTot + 1;
IF (Date - 2) <= Date_Last THEN Wiz03 := Wiz03 + 1;
IF (Date - 6) <= Date_Last THEN Wiz07 := Wiz07 + 1;
IF (Date - 13) <= Date_Last THEN Wiz14 := Wiz14 + 1;
X( Fmt(UserName, Left, 20) );
X( Fmt(IntToStr(Level), Right, 4) );
X( Fmt(IntToStr(Points), Right, 6) );
X( Fmt(IntToStr(Date_Last), Right, 5) + ':' );
X( Fmt(IntToStr(Mint_Last), Left, 4));
IF WizOp THEN
BEGIN
X( Fmt(IntToStr(MsgsSent * 10 DIV (Level + 1) * 10), Right, 6));
X( Fmt(IntToStr(MaxLevel), Right, 4)+' ');
X( Phone );
END;
XLF;
END;
END;
OVCntr := OVCntr + 1;
UNTIL CharDuringO OR (OVCntr = MaxUsers);
IF Level > 300 THEN
BEGIN
XLF;
IF NOT CharDuringO THEN
XLn('Number of wizards shown ..... '+Fmt(IntToStr(WizTot),Right, 3));
IF NOT CharDuringO THEN
XLn('Visited within 3 days ...... '+Fmt(IntToStr(Wiz03), Right, 3));
IF NOT CharDuringO THEN
XLn('Visited within 7 days ...... '+Fmt(IntToStr(Wiz07), Right, 3));
IF NOT CharDuringO THEN
XLn('Visited within 14 days ...... '+Fmt(IntToStr(Wiz14), Right, 3));
IF NOT CharDuringO THEN
BEGIN
MsgTot := 0;
MsgTotC := NextMsg;
REPEAT
IF ElapsedTime(MsgDates[MsgTotC],MsgMints[MsgTotC],Date,Mint)
<= 1440.0 THEN MsgTot := MsgTot + 1;
MsgTotC := MsgNumBefore(MsgTotC);
UNTIL (MsgTotC = NextMsg);
XLF;
XLn('Messages sent in 24 hours ... '+Fmt(IntToStr(MsgTot), Right, 3));
END;
END;
END;
OVERLAY PROCEDURE Manna;
VAR
TempInt : INTEGER;
BEGIN
IF MannaRecharge AND (NOT WizOp)
THEN XLn('TSOTL thinks you''re greedy.')
ELSE
BEGIN
IF Altitude < 100
THEN XLn('No Manna-Springs in sight.')
ELSE
BEGIN
TempInt := RANDOM(Altitude * 2) + 50;
IF WizOp THEN TempInt := TempInt * 2;
XLn('TSOTL grants you '+IntToStr(TempInt)+ ' Manna-Points.');
SetManna(MannaPoints + TempInt);
MannaRecharge := TRUE;
END;
END;
END;
OVERLAY PROCEDURE Banish(AttType : CHAR); { BANISH spell }
VAR
BelowNum : INTEGER;
PoorGuy : UNameType;
BEGIN
BelowNum := Level - 30;
IF AttType = 'R' THEN BelowNum := Level - 50;
Tactical := TRUE;
IF NOT WizOp THEN
BEGIN
XLn('You can attack any wizard who has a');
XLn('Sorcery Level below '+IntToStr(BelowNum)+'.');
XLF;
END;
X('WHO are you attacking? ');
PoorGuy := Upper(GetInputLn); XLF;
IF LENGTH(PoorGuy) = 0 THEN XLn('The spell discharges harmlessly.');
IF NOT FindUserRecPtr(PoorGuy) THEN
BEGIN
XLn('No such person!');
PoorGuy := '';
END;
IF LENGTH(PoorGuy) > 0 THEN
BEGIN
SEEK(UsersFile,UserRecPtr);
READ(UsersFile,OtherUsersRec);
IF OtherUsersRec.UserName <> PoorGuy
THEN XLn('Hmm, he''s strangely immune!')
ELSE
BEGIN
IF (OtherUsersRec.Level >= BelowNum) AND (NOT WizOp)
THEN XLn('Too powerful for that!')
ELSE
BEGIN
IF AttType = 'B'
THEN OtherUsersRec.Date_Last := 0
ELSE OtherUsersRec.Level := 0;
OtherUsersRec.Points := 50;
IF AttType = 'B'
THEN OtherUsersRec.MsgsSent := 1
ELSE
BEGIN
IF OtherUsersRec.MsgsSent > 15 THEN OtherUsersRec.MsgsSent := 15;
END;
SEEK(UsersFile,UserRecPtr);
WRITE(UsersFile,OtherUsersRec);
X('The deed is ... '); SlowX('DONE!'); XLF;
IF AttType = 'B'
THEN SysLog('I',UserName+' banished '+PoorGuy)
ELSE SysLog('I',UserName+' reduced '+PoorGuy);
END;
END;
END;
END;
OVERLAY PROCEDURE Sanctify; { SANCTIFY spell -- WizOp only }
VAR
FudjLoop : INTEGER;
PoorGuy : UNameType;
TempEst : INTEGER;
TempInfo : ComLine;
BEGIN
X('Sanctify who? ');
PoorGuy := Upper(GetInputLn); XLF;
IF NOT FindUserRecPtr(PoorGuy)
THEN XLn('No such person!')
ELSE
BEGIN
SEEK(UsersFile,UserRecPtr);
READ(UsersFile,OtherUsersRec);
IF OtherUsersRec.UserName <> PoorGuy
THEN XLn('Hmm, he''s strangely immune!')
ELSE
WITH OtherUsersRec DO
BEGIN
{----- Rise-Control -----}
XLn('You may respecify rise-control values.');
IF Yes THEN
BEGIN
XLF;
XLn('Maximum Level: '+IntToStr(MaxLevel));
XLn('TSOTL''s Esteem: '+IntToStr(MsgsSent * 10 DIV (Level + 1) * 10));
MaxLevel := GetInt('Maximum Level? (0 = No limit) ');
TempEst := GetInt('New Esteem? (Rounding may occur) ');
MsgsSent := TRUNC(TempEst / 10 * (Level + 1) / 10);
IF (TempEst / 10 * (Level + 1) / 10) > 3000.0
THEN
BEGIN
XLn('Esteem can''t be that high at level '+IntToStr(Level)+'.');
MsgsSent := 3000;
END
ELSE
BEGIN
{----- Loop to contend with round-off of DIV -----}
FudjLoop := 1;
WHILE (MsgsSent * 10 DIV (Level + 1) * 10 < TempEst)
AND (FudjLoop < 50)
DO
BEGIN
MsgsSent := MsgsSent + 1;
FudjLoop := FudjLoop + 1;
END;
END;
IF (MsgsSent * 10 DIV (Level + 1) * 10) <> TempEst
THEN
XLn('Rounded Esteem has been set to: '+
IntToStr(MsgsSent * 10 DIV (Level + 1) * 10));
END;
{----- Profile -----}
XLF;
XLn('You may change profile info.');
IF Yes THEN
BEGIN
XLF;
XLn('Respecify profile info or');
XLn('press RETURN for No Change.');
XLF;
XLn('User Name: '+PoorGuy);
XLn('(Type DELETE to remove)');
X('> ');
TempInfo := Upper(GetInputLn);
XLF;
IF LENGTH(TempInfo) > 0 THEN
BEGIN
IF TempInfo = 'DELETE' THEN TempInfo := '';
UserName := TempInfo;
UserNames[UserRecPtr + 1] := TempInfo;
END;
XLn('Name: '+RealName);
X('> ');
TempInfo := GetInputLn;
XLF;
IF LENGTH(TempInfo) > 0 THEN RealName := TempInfo;
XLn('Phone: '+Phone);
X('> ');
TempInfo := GetInputLn;
XLF;
IF LENGTH(TempInfo) > 0 THEN Phone := TempInfo;
XLn('Password: '+Password);
X('> ');
TempInfo := GetInputLn;
IF LENGTH(TempInfo) > 0 THEN Password := Upper(TempInfo);
END;
SEEK(UsersFile,UserRecPtr);
WRITE(UsersFile,OtherUsersRec);
XLF;
XLn('Done.');
END;
END;
END;