diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..a452c48
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "utils"]
+ path = utils
+ url = D:\\dev\\code\\utils
diff --git a/mystic/bbs_cfg_language.pas b/mystic/bbs_cfg_language.pas
deleted file mode 100644
index 396f25b..0000000
--- a/mystic/bbs_cfg_language.pas
+++ /dev/null
@@ -1,133 +0,0 @@
-Unit bbs_cfg_Language;
-
-{$I M_OPS.PAS}
-
-Interface
-
-Procedure Lang_Editor;
-
-Implementation
-
-Uses
- m_Strings,
- bbs_Common,
- bbs_Core;
-
-Procedure Lang_Editor;
-var
- a : SmallInt;
- Old : RecTheme;
-Begin
- Session.SystemLog ('*LANG EDITOR*');
- Old := Session.Lang;
-{ Reset (LangFile);}
- Repeat
- Session.io.OutFullLn ('|CL|14Language Editor|CR|CR|15## FileName Description|CR|09-- -------- ------------------------------');
-assign(session.langfile, config.datapath+'theme.dat');
- {$I-} Reset (Session.LangFile);{$I+}
- if ioresult <> 0 then rewrite(session.langfile);
-
- while not eof(Session.LangFile) do begin
- read (Session.LangFile, Session.Lang);
- Session.io.OutFullLn ('|15' + strPadR(strI2S(filepos(Session.LangFile)), 4, ' ') +
- '|14' + strPadR(Session.Lang.FileName, 10, ' ') + '|10' + Session.Lang.Desc);
- end;
- Session.Lang := Old;
- Session.io.OutFull ('|CR|09(I)nsert, (D)elete, (E)dit, (Q)uit? ');
- case Session.io.OneKey ('DIEQ', True) of
- 'D' : begin
- Session.io.OutRaw ('Delete which? ');
- a := strS2I(Session.io.GetInput(3, 3, 11, ''));
- if filesize(Session.LangFile) = 1 then
- Session.io.OutFullLn ('|CR|14You must have at least one language definition.|CR|PA')
- Else
- KillRecord (Session.LangFile, A, SizeOf(RecTheme));
- end;
- 'I' : begin
- Session.io.OutRaw ('Insert before? (1-' + strI2S(filesize(Session.LangFile)+1) + '): ');
- a := strS2I(Session.io.GetInput(3, 3, 11, ''));
- if (a > 0) and (a <= filesize(Session.LangFile)+1) then begin
- AddRecord (Session.LangFile, A, SizeOf(RecTheme));
- Session.lang.filename := '';
- Session.lang.textpath := '';
- Session.lang.menupath := '';
- write (Session.LangFile, Session.Lang);
- end;
- end;
- 'E' : begin
- Session.io.OutRaw ('Edit which? ');
- a := strS2I(Session.io.GetInput(3, 3, 11, ''));
- if (a > 0) and (a <= filesize(Session.LangFile)) then begin
- seek (Session.LangFile, a-1);
- read (Session.LangFile, Session.Lang);
- repeat
- Session.io.OutFullLn ('|CL|14Language ' + strI2S(FilePos(Session.LangFile)) + ' of ' + strI2S(FileSize(Session.LangFile)) + '|CR|03');
- Session.io.OutRawln ('A. Description: ' + Session.Lang.Desc);
- Session.io.OutRawln ('B. Filename : ' + Session.Lang.FileName);
- Session.io.OutRawln ('C. Text Path : ' + Session.Lang.TextPath);
- Session.io.OutRawln ('D. Menu Path : ' + Session.Lang.MenuPath);
- Session.io.OutRawln ('M. Allow ASCII: ' + Session.io.OutYN(Session.Lang.Flags AND ThmAllowASCII <> 0));
- Session.io.OutRawln ('N. Allow ANSI : ' + Session.io.OutYN(Session.Lang.Flags AND ThmAllowANSI <> 0));
-
- Session.io.OutFullLn ('|CRE. Use Lightbar Y/N : ' + Session.io.OutYN(Session.Lang.Flags AND ThmLightbarYN <> 0));
- Session.io.OutFull ('|03|16H. Input Field Color: ');
- Session.io.AnsiColor(Session.Lang.FieldColor1);
- Session.io.OutFullLn ('Test|03|16');
-
- Session.io.OutRaw ('I. Quote Bar Color : ');
- Session.io.AnsiColor(Session.Lang.QuoteColor);
- Session.io.OutFullLn ('Test|03|16');
-
- Session.io.OutRawLn ('J. Echo Character : ' + Session.Lang.EchoChar);
- Session.io.OutRawLn ('K. Input Character : ' + Session.Lang.FieldChar);
- Session.io.OutRawLn ('L. File Tag Char : ' + Session.Lang.TagChar);
-
- Session.io.OutRaw ('O. File Search Hi : ');
- Session.io.AnsiColor(Session.Lang.FileDescHI);
- Session.io.OutFullLn ('Test|03|16');
-
- Session.io.OutRaw ('P. File Desc. Lo : ');
- Session.io.AnsiColor(Session.Lang.FileDescLO);
- Session.io.OutFullLn ('Test|03|16');
-
- Session.io.OutRawLn ('R. LB New Msg Char : ' + Session.Lang.NewMsgChar);
-
- Session.io.OutFull ('|CR|09Command (Q/Quit): ');
- case Session.io.onekey('ABCDEFGHIJKLMNOPQR', True) of
- 'A' : Session.Lang.Desc := Session.io.InXY(17, 3, 30, 30, 11, Session.Lang.Desc);
- 'B' : Session.Lang.filename := Session.io.InXY(17, 4, 8, 8, 11, Session.Lang.filename);
- 'C' : Session.Lang.textpath := CheckPath(Session.io.InXY(17, 5, 40, 40, 11, Session.Lang.textpath));
- 'D' : Session.Lang.menupath := CheckPath(Session.io.InXY(17, 6, 40, 40, 11, Session.Lang.MenuPath));
- 'E' : Session.Lang.Flags := Session.Lang.Flags XOR ThmLightbarYN;
- 'H' : Session.Lang.FieldColor1 := getColor(Session.Lang.FieldColor1);
- 'I' : Session.Lang.QuoteColor := getColor(Session.Lang.QuoteColor);
- 'J' : Begin Session.io.OutRaw ('Char: '); Session.Lang.EchoChar := Session.io.GetKey; End;
- 'K' : Begin
- Session.io.OutRaw ('Char: ');
- Session.Lang.FieldChar := Session.io.GetKey;
- If Not (Session.Lang.FieldChar in [#32..#255]) Then
- Session.Lang.FieldChar := ' ';
- End;
- 'L' : Begin Session.io.OutRaw ('Char: '); Session.Lang.TagChar := Session.io.GetKey; End;
- 'M' : Session.Lang.Flags := Session.Lang.Flags XOR ThmAllowASCII;
- 'N' : Session.Lang.Flags := Session.Lang.Flags XOR ThmAllowANSI;
- 'O' : Session.Lang.FileDescHI := getColor(Session.Lang.FileDescHI);
- 'P' : Session.Lang.FileDescLo := GetColor(Session.Lang.FileDescLO);
- 'Q' : break;
- 'R' : Begin Session.io.OutRaw('Char: '); Session.Lang.NewMsgChar := Session.io.GetKey; End;
- end;
- until false;
- seek (Session.LangFile, filepos(Session.LangFile)-1);
- write (Session.LangFile, Session.Lang);
- end;
- end;
- 'Q' : break;
- end;
-
- until False;
- close (Session.LangFile);
-
- If Not Session.LoadThemeData(Old.FileName) Then Session.Lang := Old;
-End;
-
-End.
diff --git a/mystic/makelang.pas b/mystic/makelang.pas
deleted file mode 100644
index 5635e70..0000000
--- a/mystic/makelang.pas
+++ /dev/null
@@ -1,139 +0,0 @@
-// ====================================================================
-// Mystic BBS Software Copyright 1997-2012 By James Coyle
-// ====================================================================
-//
-// This file is part of Mystic BBS.
-//
-// Mystic BBS is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Mystic BBS is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Mystic BBS. If not, see .
-//
-// ====================================================================
-
-Program MakeLang;
-
-{$I M_OPS.PAS}
-
-Uses
- DOS,
- m_Strings;
-
-{$I RECORDS.PAS}
-
-Var
- ConfigFile : File of RecConfig;
- PromptFile : File of PromptRec;
- Config : RecConfig;
- Prompt : PromptRec;
- Done : Array[0..mysMaxLanguageStr] of Boolean;
- tFile : Text;
- A : Integer;
- Temp : String;
- FName : NameStr;
- FExt : ExtStr;
- FDir : DirStr;
-Begin
- WriteLn;
- WriteLn ('MAKELANG (' + OSID + ') - Mystic Language Compiler v', mysVersion);
- WriteLn ('Copyright (C) 1997-2012 By James Coyle. All Rights Reserved.');
- WriteLn;
-
- Assign (ConfigFile, 'mystic.dat');
- {$I-}Reset (ConfigFile);{$I+}
-
- If IoResult <> 0 Then Begin
- WriteLn ('ERROR: MYSTIC.DAT not found. Run from main BBS directory.');
- Halt(1);
- End;
-
- Read (ConfigFile, Config);
- Close (ConfigFile);
-
- If Config.DataChanged <> mysDataChanged Then Begin
- WriteLn('ERROR: Data files are not current and must be upgraded.');
- Halt(1);
- End;
-
-
- If ParamCount <> 1 Then Begin
- WriteLn ('Usage: MAKELANG [language_file]');
- Halt(1);
- End;
-
- FSplit (ParamStr(1), FDir, FName, FExt);
-
- Assign (tFile, FName + FExt);
- {$I-} Reset (tFile); {$I+}
-
- If IoResult <> 0 Then Begin
- WriteLn ('ERROR: Language file (' + FName + FExt + ') not found.');
- Halt(1);
- End;
-
- Write ('Compiling language file: ');
-
- Assign (PromptFile, Config.DataPath + FName + '.lng');
- {$I-} ReWrite (PromptFile); {$I+}
-
- If IoResult <> 0 Then Begin
- WriteLn;
- WriteLn;
- WriteLn (^G'ERROR: Cannot run while Mystic is loaded.');
- Halt(1);
- End;
-
- Prompt := '';
-
- For A := 0 to mysMaxLanguageStr Do Begin
- Done[A] := False;
- Write (PromptFile, Prompt);
- End;
-
- Reset (PromptFile);
-
- While Not Eof(tFile) Do Begin
- ReadLn (tFile, Temp);
-
- If Copy(Temp, 1, 3) = '000' Then A := 0 Else
- If strS2I(Copy(Temp, 1, 3)) > 0 Then A := strS2I(Copy(Temp, 1, 3)) Else
- A := -1;
-
- If A <> -1 Then Begin
- If A > mysMaxLanguageStr Then Begin
- WriteLn;
- WriteLn;
- WriteLn (^G'ERROR: String #', A, ' was not expected. Language file not created.');
- Close (PromptFile);
- Erase (PromptFile);
- Halt(1);
- End;
-
- Done[A] := True;
- Seek (PromptFile, A);
- Prompt := Copy(Temp, 5, Length(Temp));
- Write (PromptFile, Prompt);
- End;
- End;
-
- Close (tFile);
- Close (PromptFile);
-
- WriteLn ('Done.');
-
- For A := 0 to mysMaxLanguageStr Do Begin
- If Not Done[A] Then Begin
- WriteLn;
- WriteLn (^G'ERROR: String #', A, ' was not found. Language file not created.');
- Erase (PromptFile);
- End;
- End;
-End.
diff --git a/scripts/rumors.mps b/scripts/rumors.mps
new file mode 100644
index 0000000..60095ff
--- /dev/null
+++ b/scripts/rumors.mps
@@ -0,0 +1,144 @@
+// ==========================================================================
+// File: RUMORS.MPS
+// Desc: Rumors engine for Mystic BBS v1.10
+// Author: g00r00
+// ==========================================================================
+//
+// INSTALLATION:
+//
+// 1) Copy RUMORS.MPS into its own directory or your scripts path and
+// compile it with MPLC or MIDE
+//
+// 2) For each menu you want to display rumors on, you must edit with the
+// MCFG -> Menu Editor and add the following menu command:
+//
+// HotKey: EVERY
+// Command: GX (Execute MPL)
+// Data: rumors show
+//
+// Note that if you have it in a path other than the scripts path, then
+// you will have to specify that in the Data field above. For example
+// rumors show
+//
+// This MPL will create a rumors.dat file in the same directory where
+// you have located the compiled MPX.
+//
+// 3) When rumors show is ran, it generates a rumor and stores it into
+// the &1 MCI code. Therefore, you will need to edit your menu prompt
+// or ANSI to include |&1 into it where you want it to display the rumor
+//
+// If for some reason to are auto executing other functions which use
+// PromptInfo MCI codes (specially &1) you will want to add your EVERY
+// execution of this MPL program AFTER those, so that the last value
+// assigned to the MCI code was done by the rumor engine.
+//
+// 4) There are options in addition to the SHOW command in which you can
+// use to add other functionality to your BBS. They are:
+//
+// ADD : Allows adding of a rumor to the rumor database. The database
+// keeps the 50 most currently added rumors.
+//
+// EXAMPLE:
+//
+// Hotkey: A
+// Command: GX (Execute MPL)
+// Data: rumors add
+//
+// CUSTOMIZATION:
+//
+// If you wish to customize the prompts used in the Rumors, you can do
+// so by changing the PromptAdd and PromptSave values set below. Do
+// whatever you want with this. It was developed to demonstration IPLC
+// which is one of MPL's alternative syntax options.
+//
+// ==========================================================================
+
+{$syntax iplc}
+
+const
+ // Prompts used
+ PromptAdd = "|CR|15E|07n|08ter |07y|08our |07r|08umor|CR:|07"
+ PromptSave = "|CR|15S|07a|08ve |07t|08his |07r|08umor? |XX"
+
+ // max number of characters for a rumor
+ rumorSize = 78;
+
+proc rumoradd {
+ @ string str
+ @ string(50) data
+ @ byte datasize, count
+ @ file f
+
+ write(promptadd)
+ str = input(rumorSize, rumorSize, 1, "")
+
+ if str == "" exit
+ if !inputyn(promptsave) exit
+
+ fassign (f, justpath(progname) + "rumors.dat", 2)
+ freset (f);
+
+ if ioresult <> 0 frewrite(f);
+
+ while !feof(f) && datasize < 50 {
+ datasize = datasize + 1
+ freadln(f, data(datasize))
+ }
+
+ fclose(f)
+
+ if datasize == 50 {
+ for count = 1 to 49
+ data(count) = data(count+1)
+ } else
+ datasize = datasize + 1
+
+ data(datasize) = str
+
+ frewrite(f)
+ for count = 1 to datasize
+ fwriteln(f, data(count));
+
+ fclose(f)
+}
+
+proc rumorshow {
+ @ string(50) data
+ @ byte datasize, count
+ @ file f
+
+ fassign (f, justpath(progname) + "rumors.dat", 2)
+ freset (f)
+
+ if ioresult <> 0 exit
+
+ while !feof(f) && datasize < 50 {
+ datasize = datasize + 1
+ freadln(f, data(datasize))
+ }
+
+ count = random(datasize) + 1
+ datasize = 0
+
+ freset(f)
+ while datasize <> count {
+ datasize = datasize + 1
+ freadln(f, data(datasize))
+ }
+
+ fclose(f)
+
+ setpromptinfo(1, data(datasize))
+}
+
+{
+ @ string options = upper(progparams);
+
+ if pos("ADD", options) > 0
+ rumoradd()
+ else
+ if pos("SHOW", options) > 0
+ rumorshow()
+ else
+ writeln("RUMORS: Invalid option: press a key|PN")
+}