home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Between Heaven & Hell 2
/
BetweenHeavenHell.cdr
/
500
/
433
/
pyroto.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-12-23
|
19KB
|
490 lines
{$C-}
PROGRAM Pyroto; { Version 3.0 }
{
┌──────────────────────────────────────────────────────┬──────────────────┐
│ Pinnacle Software's Pyroto Mountain BBS/Game System │ PYROTO.PAS │
├──────────────────────────────────────────────────────┴──────────────────┤
│ C O P Y R I G H T (C) 1986 BY P I N N A C L E S O F T W A R E │
│ P.O. Box 163, Cartierville Station, Montreal, Quebec, Canada H4K 2J5 │
├─────────────────────────────────────────────────────────────────────────┤
│ The Pyroto Mountain product may not be distributed except in its com- │
│ plete and unaltered form. Products based on this source code may not │
│ marketed or placed into public domain, except by prior written permis- │
│ sion from Pinnacle Software. │
└─────────────────────────────────────────────────────────────────────────┘
}
TYPE
TenType = STRING[10];
ComLine = STRING[42];
UNameType = STRING[20];
FNType = STRING[40];
Line = STRING[80];
String100 = STRING[100];
RegPack = RECORD
ax,bx,cx,dx,bp,di,si,ds,es,flags: INTEGER;
END;
SFType = (OpenError, Okay, Quit);
LeftRight = (Left, Right);
MsgTimesType =
RECORD
Date_Added : INTEGER;
Mint_Added : INTEGER;
MsgBand : CHAR;
Poster : UNameType;
END;
QuestType =
RECORD
Question : STRING[40];
Answer : STRING[30]; { antidisestablishmentarianism }
END;
SeismoType =
RECORD
Energy : INTEGER;
Spare1 : INTEGER;
Spare2 : INTEGER;
END;
SysLogType =
RECORD
SLDate : INTEGER; { Date }
SLMint : INTEGER; { Time }
SLType : CHAR; { Type of user who can read this }
SLText : Line; { What it was }
SLRept : INTEGER; { Repetitions }
END;
UsersType =
RECORD
{--- General Info ---} { ----+----1----+----2----+----3 }
RealName : UNameType; { Harry Q. Smithereens }
Phone : STRING[25]; { 1-514-555-1234 EXT. 12345 }
UserName : UNameType; { Johnny Strangechange }
Password : STRING[10]; { HOWDYDOODY }
Level : INTEGER;
Points : INTEGER;
Date_Last : INTEGER; { If ZERO, flagged as deleted }
Mint_Last : INTEGER;
Width : INTEGER;
MsgsSent : INTEGER;
MaxLevel : INTEGER; { If ZERO, no limit }
{--- Bulletins-Read Info ---}
Date_A : INTEGER; { Low-Wizards Board }
Mint_A : INTEGER;
Date_B : INTEGER; { Middle Wizards Board }
Mint_B : INTEGER;
Date_C : INTEGER; { Middle-High Wizards Board }
Mint_C : INTEGER;
Date_D : INTEGER; { High Wizards Board }
Mint_D : INTEGER;
Date_P : INTEGER; { Beseech Board }
Mint_P : INTEGER;
Date_S : INTEGER; { SCROLLS Board }
Mint_S : INTEGER;
Date_X : INTEGER; { Crowds 0 board }
Mint_X : INTEGER;
END; { PROCLAIM board time is same as "last call" }
CONST
CoP : ComLine = 'COPYRIGHT (C) 1986 by Pinnacle Software.';
Ver : TenType = '3.01AA';
CONST { Calender Info }
DaysInMonth : ARRAY[1..12] OF INTEGER =
(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
CONST { Control Characters }
BEL : CHAR = ^g;
BS : CHAR = ^h;
CR : CHAR = ^m;
ESC : CHAR = #27;
LF : CHAR = ^j;
NUL : CHAR = #0;
XON : CHAR = ^q;
XOF : CHAR = ^s;
CONST { Serial Control }
RReady = 1;
TReady = $20;
BaudConst : real = 115200.0;
CONST { Constraints and Configuration }
BoardNames : STRING[10] = '0ABCDGPSX'; { Not used universally }
File_Article : FNType = 'ARTICLE.TXT'; { Promote-discussion article }
File_Hints : FNType = 'HINTS.TXT'; { Hints for Pyroto }
File_Info : FNType = 'INFO.TXT'; { Info about Pyroto }
File_Nature : FNType = 'NATURE.TXT'; { Nature of TSOTL }
File_Next : FNType = 'MSGNEXT.DAT'; { Last msg# added }
File_Queries : FNType = 'QUERIES.DAT'; { Question files }
File_Rules : FNType = 'RULES.TXT'; { Rules }
File_Straight: FNType = 'STRAIGHT.TXT'; { Straight-talk }
File_Seismo : FNType = 'SEISMO.DAT'; { Seismoros }
File_Specs : FNType = 'SPELLS.DAT'; { Spell specifications }
File_SysLog : FNType = 'OBSERVE.DAT'; { OBSERVE log }
File_Times : FNType = 'MSGTIMES.DAT'; { Times of each message }
File_Users : FNType = 'USERLIST.DAT'; { List of users }
MaxMsgLen = 27; { Number of lines in a message }
MaxMsgs = 225; { Number of messages }
MaxSysLog = 250; { Filesize for OBSERVE log }
MaxUsers = 350; { In-core index size of 10,000 bytes per 500 }
NumCmds = 57;
CmdWords : ARRAY[1..NumCmds] OF TenType = (
'ARTICLE', 'ASCEND', 'BANISH', 'BESEECH', 'BESTOW',
'BOOST', 'BYE', 'CHANGE', 'CHARGE', 'CHECK',
'CLOAK', 'CLOSE', 'CONTACT', 'CORRECT', 'DEFOCUS',
'DEMOTE', 'DESCEND', 'DETECT', 'DETUNE', 'DRAIN',
'FEED', 'FOCUS', 'HELP', 'HINTS', 'HURL',
'INFO', 'INQUIRE', 'INSCRIBE', 'LISTEN', 'MANNA',
'NATURE', 'OBSERVE', 'OMNIVIEW', 'PROBE', 'PROCLAIM',
'PROMOTE', 'READ', 'RECALL', 'REDUCE', 'REVIEW',
'ROSTER', 'RULES', 'SANCTIFY', 'SCAN', 'SCROLLS',
'SEND', 'SLOWTIME', 'SPECS', 'SPELLS', 'STARVE',
'STEAL', 'STOPTIME', 'STRAIGHT', 'SUGGEST ', 'TELEPORT',
'TIMEWARP', 'TUNE'
);
CmdDescs : ARRAY[1..NumCmds] OF ComLine = (
'An article added to promote discussion', { ARTICLE }
'Attempt to pass into next sorcery level', { ASCEND }
'Banish somebody and destroy his power', { BANISH }
'Send message to The Spirit of the Land', { BESEECH }
'Give some of your MPs to another person', { BESTOW }
'Boost transmission speed (baud rate)', { BOOST }
'Depart (disconnect) from this place', { BYE }
'Change messages you''ve sent previously', { CHANGE }
'Attempt ascent - disconnect if you fail', { CHARGE }
'Display pertinent data about yourself', { CHECK }
'A protected form of CHARGE -- very safe', { CLOAK }
'Terminate system and return to DOS', { CLOSE }
'Speak to The Spirit Of The Land (TSOTL)', { CONTACT }
'Rewrite one of the Guardians'' questions', { CORRECT }
'Reset the "display" spells after FOCUS', { DEFOCUS }
'Demote somebody to lower sorcery level', { DEMOTE }
'Go downwards to visit the less powerful', { DESCEND }
'Display info about previous messages', { DETECT }
'Reset the "reading" spells after a TUNE', { DETUNE }
'Subtract 100 Manna-points from somebody', { DRAIN }
'Add some energy to the Seismoros spirit', { FEED }
'Focus "display" spells on given phrase', { FOCUS }
'Display your usable spells (this list)', { HELP }
'Display handy survival and usage tips', { HINTS }
'Cast a message back to the dawn of time', { HURL }
'Display some info about this place', { INFO }
'Display how long until TSOTL gets tired', { INQUIRE }
'Write upon the Tidings (news) Scrolls', { INSCRIBE }
'Display the messages sent via BESEECH', { LISTEN }
'Get a generous recharge of Manna-points', { MANNA }
'Read the about the True Nature of TSOTL', { NATURE }
'Display recent activity on the Mountain', { OBSERVE }
'Display PROBE stats for all wizards', { OMNIVIEW }
'Get information about specified wizard', { PROBE }
'Write a new greeting (sign-on) message', { PROCLAIM }
'Promote somebody to next sorcery level', { PROMOTE }
'Display messages you''re allowed to read', { READ }
'Display report of previous visitors', { RECALL }
'Reduce somebody to sorcery level zero', { REVIEW }
'Re-read a single message by DAY:MINUTE', { REDUCE }
'Display the names of all the wizards', { ROSTER }
'Display rules imposed on the Mountain', { RULES }
'Permit a user to rise to higher levels', { SANCTIFY }
'All-bands READ -- use with FOCUS & TUNE', { SCAN }
'Display the latest, most important news', { SCROLLS }
'Leave message for other wizards to read', { SEND }
'Add fifteen minutes to TSOTL''s patience', { SLOWTIME }
'Alter the way things look around here', { SPECS }
'Display the Levels & MP costs of spells', { SPELLS }
'Remove energy from the Seismoros spirit', { STARVE }
'Like DRAIN, but cheaper -- costs Esteem', { STEAL }
'Double the time TSOTL will tolerate you', { STOPTIME }
'Straight Talk article from the Servant', { STRAIGHT }
'Provide the Guardians with new question', { SUGGEST }
'Instant transition to specified level', { TELEPORT }
'Set a time after which you wish to READ', { TIMEWARP }
'Tune "reading" spells for given phrase' { TUNE }
);
CONST { Local colour }
MaxDescTexture = 15;
DescTexture : ARRAY[1..MaxDescTexture] OF STRING[20] =
( 'an incredibly scuzzy', 'a peculiar-looking', 'a flaming, white-hot',
'a horror! He is a', 'strange enough: A', 'a mottled & speckled',
'a vicious, ferocious', 'half-dog and half-', 'a slimey, oooozing',
'scarey! He''s a huge', 'something akin to a', 'shaped a bit like a',
'a gigantic, smelly', 'a bit similar to a', 'a green and yellow');
MaxDescType = 14;
DescType : ARRAY[1..MaxDescType] OF STRING[12] =
( 'dragon', 'lizard', 'robot', 'gnome', 'were-wolf', 'unicorn', 'bear',
'lion', 'gorilla', 'panther', 'leprechaun', 'man', 'reptile', 'cobra' );
MaxDescCharac = 26;
DescCharac : ARRAY[1..MaxDescCharac] OF STRING[26] =
( ' wearing plate armour', ', holding a nasty sabre',
' with a bazooka', ', wearing a digital watch',
' holding a ticking bomb', '. He''s chewing on a bone',
' with a slight lisp', ' with razor-sharp fangs',
'. He doesn''t look happy', ', grinning evilly',
' with a surly disposition', ', reading a book',
'. He is happy to see you', '. He seems nice enough',
' -- and he looks hungry..', ' with long yellow tusks',
'. A nightmare, for sure', ' with awful, staring eyes',
'. He''s got a gun..', ' dressed in black satin',
', playing solitaire', ' covered in dust and grime',
', picking his teeth..', ', wearing a tall top hat',
'. He looks up and snarls', '. Not a pretty sight' );
VAR { Listed in alphabetical order }
Adding : BOOLEAN;
Alert : BOOLEAN;
AlertName : Line;
Altitude : INTEGER;
AscCnt : INTEGER;
Ascendable : BOOLEAN;
AscLast : INTEGER;
Attn : ComLine;
Banner : ARRAY[1..8] OF ComLine;
BaudRate : INTEGER;
Blanks : Line;
BreakPoint : INTEGER;
BSCntr : INTEGER;
Charging : BOOLEAN;
ChatAsk : BOOLEAN;
Chattable : BOOLEAN;
ChPtr : INTEGER;
ChSize : INTEGER;
Cloaked : BOOLEAN;
Comm : BOOLEAN;
Cmd : Line;
CmdCosts : ARRAY[1..NumCmds] OF INTEGER;
CmdLevel : INTEGER;
CmdLevels : ARRAY[1..NumCmds] OF INTEGER;
CmdWasTyped : BOOLEAN;
CmdParm : Line;
CmdLen : BYTE ABSOLUTE CmdParm; { New for Version 3.01 }
CharDuringO : BOOLEAN;
Com1Base : INTEGER;
Communicative : BOOLEAN;
Contacting : BOOLEAN;
DataPort : INTEGER;
Date : INTEGER;
Date_Last : INTEGER;
Date_Warp : INTEGER;
DFLocation : FNType;
DisconDelay : INTEGER;
DisconMethod : ComLine;
DuringOChar : CHAR;
EditBuffer : ARRAY[1..MaxMsgLen] OF STRING[80];
ExFnKey : BOOLEAN;
Explained : BOOLEAN;
FocusString : Line;
HadCarrier : BOOLEAN;
HighBaud : INTEGER;
Inputting : BOOLEAN;
InputLine : String100;
InputLen : BYTE ABSOLUTE InputLine;
InputTime : REAL;
IntReg : INTEGER;
LastChar : CHAR;
Last2Char : CHAR;
Level : INTEGER;
LenCnt : INTEGER;
LineContrl : INTEGER;
LocalUser : BOOLEAN;
LowBaud : INTEGER;
Logoff : BOOLEAN;
MannaRecharge : BOOLEAN;
MannaPoints : INTEGER;
MaxLev : INTEGER;
Mint : INTEGER;
Mint_Last : INTEGER;
Mint_Warp : INTEGER;
MFLocation : FNType;
Modem300 : ComLine;
Modem1200 : ComLine;
Modem2400 : ComLine;
ModemAttn : ComLine;
ModemConfig : ComLine;
ModemContrl : INTEGER;
ModemDoAnswer : ComLine;
ModemHangUp : ComLine;
ModemNoAnswer : ComLine;
ModemOkay : ComLine;
ModemPickUp : ComLine;
ModemReset : ComLine;
ModemStatus : INTEGER;
Multiple : BOOLEAN;
MsgBands : ARRAY[1..MaxMsgs] OF CHAR;
MsgDates : ARRAY[1..MaxMsgs] OF INTEGER; { 300 msgs uses 1.2K core }
MsgMints : ARRAY[1..MaxMsgs] OF INTEGER; { See above }
MsgPosters : ARRAY[1..MaxMsgs] OF UNameType;
MsgPtr : INTEGER;
MsgTimesRec : MsgTimesType;
MyPassword : TenType;
NewUser : BOOLEAN;
NextLog : INTEGER;
NextMsg : INTEGER;
NoAscendMsg : ComLine;
NonReadInfo : BOOLEAN;
NumSends : INTEGER;
OtherUsersRec : UsersType;
OutFiling : BOOLEAN;
Patience : INTEGER;
Pleaseable : BOOLEAN;
Postings : INTEGER;
Promo : BOOLEAN;
QuestFileName : FNType;
QuestRec : QuestType;
Read_A : BOOLEAN;
Read_B : BOOLEAN;
Read_C : BOOLEAN;
Read_D : BOOLEAN;
Read_P : BOOLEAN;
Read_S : BOOLEAN;
Read_X : BOOLEAN;
ReadBand : CHAR;
ReadDate : INTEGER;
ReadMint : INTEGER;
SaveDescTexture : STRING[20];
SaveDescType : STRING[12];
SaveDescCharac : STRING[26];
SaveTime : INTEGER;
Secs : INTEGER;
SeismoActive : BOOLEAN;
SeismoRec : SeismoType;
ServantWord : ComLine;
ShutDown : BOOLEAN;
SlowedTime : BOOLEAN;
SpellCost : INTEGER;
SpellRepeat : INTEGER;
StartDate : INTEGER;
StartMint : INTEGER;
StatusPort : INTEGER;
StoppedTime : BOOLEAN;
SuppressOut : BOOLEAN;
SysFail : BOOLEAN;
SysLogItem : SysLogType;
Tactical : BOOLEAN;
TestPass : TenType;
TimeOutCntr : INTEGER;
TimeOutSecs : INTEGER;
TuneMatch : BOOLEAN;
TuneString : Line;
UpCaseInput : BOOLEAN;
UserName : UNameType;
UserNames : ARRAY[1..MaxUsers] OF UNameType;
UserRecPtr : INTEGER;
UsersRec : UsersType;
VALRetCode : INTEGER;
Width : INTEGER;
WizOp : BOOLEAN;
Wrapping : BOOLEAN;
YesNo : CHAR;
VAR { Files }
NextMsgFile : FILE OF INTEGER;
MsgTimesFile : FILE OF MsgTimesType;
QuestFile : FILE OF QuestType;
SeismoFile : FILE OF SeismoType;
SysLogFile : FILE OF SysLogType;
TxtFile : TEXT;
UsersFile : FILE OF UsersType;
{$I PYUTILIT.INC} { Very basic procedures and functions }
{$I PYSERIAL.INC} { I/O to the serial port }
{$I PYBASEUT.INC} { Basic utilities specific to Pyroto }
{$I PYFILES.INC} { All file-handling, including message reading/writing }
{$I PYSIGN.INC} { Overlays for sign-on and sign-off processing }
{$I PYCMDPRO.INC} { Overlays for command processing }
{$I PYCMDPAR.INC} { Parsing of commands }
PROCEDURE Contact; { CONTACT spell and F6 key }
VAR
ConLine : Line;
SaveIing : BOOLEAN;
SaveInput : Line;
SaveSup : BOOLEAN;
SaveUCI : BOOLEAN;
SoundCnt : INTEGER;
BEGIN
{----- Sound the alert -----}
IF CType <> 'I' THEN Communicative := TRUE;
SaveSup := SuppressOut;
SuppressOut := FALSE;
FOR SoundCnt := 1 TO 50 DO
BEGIN
SOUND(1000);
DELAY(5);
NOSOUND;
END;
{----- Reject unwanted types -----}
IF (NOT Chattable) AND (CType <> 'I') THEN
BEGIN
XLn('Neither TSOTL nor his Servant are free');
XLn('to talk at this time; please try later.');
ChatAsk := TRUE;
END;
{----- Accept communication -----}
IF Chattable OR (CType = 'I') THEN
BEGIN
{--- Appropriate messages ---}
IF CType <> 'I'
THEN
BEGIN
WRITELN(#17#16+' '+UserName+' wants to chat.');
XLn('Type. Perhaps TSOTL will talk to you.');
XLn('Enter E on an empty line to leave here.'); XLF;
END
ELSE
BEGIN
CharDuringO := FALSE;
XLF; XLF;
XLn('Incoming communication -- stand by.');
XLn('Enter E on an empty line to terminate.');
XLF;
END;
ChatAsk := FALSE;
Contacting := TRUE;
{--- Save environment ---}
SaveInput := InputLine;
SaveIing := Inputting;
SaveUCI := UpCaseInput;
{--- CONTACT environment ---}
Inputting := TRUE;
UpCaseInput := FALSE;
{--- Chat ---}
REPEAT
ConLine := GetInputLn;
IF (ConLine = 'W') OR (ConLine = 'w') THEN
BEGIN
Wrapping := NOT Wrapping;
IF Wrapping
THEN XLn('Word-wrap on.')
ELSE XLn('Word-wrap off.');
END;
UNTIL (Upper(ConLine) = 'E') OR LostCarrier;
Contacting := FALSE;
{--- Restore environment ---}
UpCaseInput := SaveUCI;
Inputting := SaveIing;
InputLine := SaveInput;
IF CType = 'I' THEN
BEGIN
XLF;
XLn('Continuing what you were doing...');
XLF;
IF Inputting THEN X(InputLine+^Q);
END;
END;
SuppressOut := SaveSup;
END;
{======= MAINLINE CODE =======}
BEGIN
StartUp;
REPEAT
IF NOT SysFail THEN {"""""""""""}
BEGIN { Before }
AwaitUser; { the }
SignOn; { visit }
END; {,,,,,,,,,,,}
IF (NOT Logoff) AND (NOT SysFail) THEN {"""""""""""}
BEGIN { }
REPEAT { }
GetCommand; { The }
DoCommand; { visit }
IF (NOT Logoff) AND (NOT SysFail) THEN CheckPatience; { }
UNTIL Logoff OR SysFail; { }
END; {,,,,,,,,,,,}
Disconnect; {"""""""""""}
UNTIL ShutDown OR SysFail; { After the }
CleanUp; { visit }
END. {,,,,,,,,,,,}