IGMUNIT v1.0b

Like the total bonehead I am, I put the wrong ANSI unit in the ZIP last time.
Sorry.  :)  But that has been taken care of this time.

IGMUNIT is designed to make programming an IGM easier.  But you still need
to know how to program.

But!  If you DON'T know how to program, and still think you could design
the best IGM yet, contact me.  I write programs for other people (for
a percentage of the profits of course :), and would even market it for you.
If interested, contact me for details.  My address is available in the
DOCs for the IGM Village of the Phoenix (VOTP-10D.ZIP).

But enough of plugging my services, on to the unit!

Though two units are included here (IGMUNIT, DDANSI2), only one is mine.
ANSI comes from the very excelent DDPLUS (DDANSI2.PAS) package, and if you
are planning to write an IGM, that's the package I used and I recommend it
very strongly.

IGMUNIT contains various functions and procedures, which I have tried to group
together in clusters of related items.

This unit is FREEWARE, which means that I'm not going to charge anything for
it, but I want my name (Jeremy Stewart) mentioned in the docs somewhere if
you use it, and a line saying that you used the IGMUNIT package.

Also:  Bare in mind that a lot of people will have access to this unit, and
might write IGMs with it, so if you want YOUR IGM to stand out, try to change
what the displays look like.  You wouldn't want your IGM to look like
everyone elses now would you?

Files Included:

DDANSI2.PAS  Source to unit in DDPLUS package.
IGMUNIT.PAS  Source to the IGMUNIT, needs to be compiled to be used.
IGMUNIT.DOC  What you are reading now.
JOE.EXE      A sample program using this unit.
JOE.PHE      Support file for JOE.EXE, take a look at it.
JOE.PAS      Source to JOE.EXE

(In case you're wondering, JOE is named for Joe DeRouen, for whom I wrote
JOE.EXE to illustrate how easy it was to write a simple IGM)

JOE.PAS also has some very useful procedures in it, so take a look at it.

Preface:  NEW VARIABLES

These new variables will be available to you when you use this unit.

PLAYER_INFO
 It's not a variable, it's a type, as listed in LORDSTRC.PAS that comes with
 LORD.  It's what the player information is listed in.

type player_info = record
 names: string[20]; {player handle in the game}
 real_names: string[50] {real name/or handle from BBS} ;
 hit_points  {player hit points}
 ,bad  {don't know - might not be used at all}
 ,rate: integer; {again, couldn't find this one in the source}
 hit_max: integer; {hit_point max}
 weapon_num: integer; {weapon number}
 weapon: string[20]; {name of weapon}
 seen_master: integer; {equals 5 if seen master, else 0}
 fights_left: integer; {forest fights left}
 human_left: integer; {human fights left}
 gold: longint; {gold in hand}
 bank: longint; {gold in bank}
 def: integer;  {total defense points }
 strength: integer; {total strength}
 charm: integer; {good looking meter}
 seen_dragon: integer; {seen dragon?  5 if yes else 0}
 seen_violet: integer; {seen violet?  5 if yes else 0}
 level: integer; {level of player}
 time: word; {day # that player last played on}
 arm: string[20]; {armour name}
 arm_num: integer; {armour number}
 dead: shortint; {player dead?  5 if yes else 0}
 inn: shortint; {player sleeping at inn?  5 if yes else 0}
 gem: integer; {# of gems on hand}
 exp: longint; {experience}
 sex: shortint; {gender, 5 if female else 0}
 seen_bard: shortint; {seen bard?  5 if yes else 0}
 last_alive_time: integer; {day # player was last reincarnated on}
 Lays: integer; {players lays stat}
 Why: integer; {not used yet}
 on_now: boolean; {is player on?}
 m_time: integer; {day on_now stat was last used}
 time_on: string[5]; {time player logged on in Hour:Minutes format}
 class: shortint; {class, should be 1, 2 or 3}
 extra: integer;      {*NEW*  If 1, player has a horse}
 love: string[25]; {not used - may be used for inter-player marrages later}
 married: integer; {who player is married to, should be -1 if not married}
 kids: integer; {# of kids}
 king: integer; {# of times player has won game}
 skillw: shortint; {number of Death Knight skill points}
 skillm: shortint; {number of Mystical Skills points}
 skillt: shortint; {number of Thieving Skills points}
 levelw: shortint; {number of Death Knight skill uses left today}
 levelm: shortint; {number of Mystical skill uses left today}
 levelt: shortint; {number of Thieving skill uses left today}
 inn_random: boolean; {not used yet}
 married_to: integer; {same as Married, I think - don't know why it's here}
 v1: longint;
 v2: integer; {# of player kills}
 v3: integer; {if 5, 'wierd' event in forest will happen}
 v4: boolean; {has player done 'special' for that day?}
 v5: shortint; {has player flirted with another player that day?  if so, 5}
   new_stat1: shortint;
   new_stat2: shortint;  {these 3 are unused right now}
   new_stat3: shortint;  {Warning: Joseph's NPCLORD screws with all three}
   end;

PLAYER
 Player is a variable based on the type PLAYER_INFO listed above.

Player: Player_info;

TICKSSINCEMIDNIGHT
 TicksSinceMidnight is not really a variable that you store values in.  It
 has values stored in it automatically, ie the number of ticks that have
 occurred since midnight.  A tick is a measure of time the CPU makes, and
 there are roughly 18.2 ticks a second.  This variable is used by the WAIT
 procedure.

 TicksSinceMidnight : longint ABSOLUTE $0040:$006c;


Part one:  DISPLAY
{**************************************************************************}

Function AddColor(F:Byte):String;

 ADDCOLOR returns ANSI codes based on the number input.  For example,
 ADDCOLOR(Blue) would return the ANSI code for Blue in string format
 (assuming that you had CRT listed to tell it what the numeric value for
 BLUE was [1]).  This is mainly used by PUTCOLOR.

Function PutColor(Out:String):String;

 PUTCOLOR adds ANSI color codes (using ADDCOLOR) based on the LORD color
 code system.  `1 Changes the display to blue, `2 changes it back to green.
 This is mainly used by SHOW and SHOWLN;

Procedure Show(Out:String);
Procedure Showln(Out:String);

 SHOW and SHOWLN are direct replacements for WRITE and WRITELN.  They will
 automatically parse the input string for LORD color codes, making changes
 where appropriate.

 The most important difference between SHOW/SHOWLN and WRITE/WRITELN is that
 SHOW/SHOWLN needs ONE string passed to it.  Nothing else will do.

 Although

WRITELN;

 works fine, to use SHOWLN it would have to be

SHOWLN('');

 See?

WRITE('Number:',NUMVAR,'  String:',STRVAR);

 is fine, but for SHOW it would need to look like:

SHOW('Number:'+StrVal(NUMVAR)+'  String:'+STRVAR);

 Notice the use of '+' instead of ',' ?  And the change of NUMVAR from a
 number variable to a string using StrVal (explained below), since SHOW can
 only display strings.

Function SC(TempStr:String) : String;

 SC is short for SHOW COMMAND.  It will separate the input string into
 pieces and insert () around the first character.  This is used to show
 which commands are available.  The default color is MAGENTA surrounded by
 GREEN, change the source if you want something different.  This output isn't
 displayed, use SHOW for that.
 ie:

Show(SC(  This is a command.)+SC(  So is this.));


Part Two:  CASE
{**************************************************************************}

Function DWNCase(DWNCH:Char):Char;

 DWNCASE is the opposite of UPCASE, which comes with pascal.  It returns
 the lowercase of the input character.
 
Procedure DWNCaseString(Var CString:String);

 Converts an entire string to lower case using DWNCASE.

Procedure UPCaseStr(Var CString:String);

 Converts an entire string to upper case using UPPERCASE.

Function UPCaseString(CString:String) : String;

 Returns the uppercase string of the input string.


Part Three:  DOS STUFF
{**************************************************************************}

function direxist(d: pathstr): boolean;

 Does a directory exist?  Returns boolean value.

function fileExists(s : string) : boolean;

 Does a file exist?  Returns a boolean value.

Procedure GetPath(Var Path:String);

 Puts the path to the program being run in the input string.

Function GetPathFunc:String;

 Returns the path to the program being run in string format.

Procedure EraseFile(FileName:String);

 Erases a file.  Used by LOCKFILE and UNLOCKFILE mainly.

Procedure LockFile(FileName:String);

 Locks a file using LORD file locking type routines.

Procedure UnlockFile(FileName:String);

 Unlocks a previously locked file.


Part Four:  MISC
{**************************************************************************}

Procedure Wait(TimeDelay:LongInt);

 A direct replacement for DELAY for fast computers when DELAY doesn't work
 right.  On a computer faster than 20mHz, DELAY is too short.  WAIT uses the
 exact same structure as DELAY and is far more accurate on fast computers.

Function StrVal(Value:LongInt) : String;

 STRVAL, short for STRING OF VALUE returns the string of a value.
 STRVAL(1974) would return the string '1974'
 STRVAL(1+2) would return the string '3'

Function ValStr(Str:String) : LongInt;

 VALSTR, short for VALUE OF STRING returns the value in a string.
 VALSTR('John') would return 0
 VALSTR('202') would return 202

Function Date : String;

 Returns the date on the computer in string format.
 Useful for making sure that maintenence runs only once a day.

Part Five:  INTERACTION
{**************************************************************************}

Procedure PressAKey;

 Prompts the user to press a key, then erases the prompt when a key is
 pressed.

Function AreYouSure : Boolean;

 Asks the user if they are sure, and returns TRUE if they press 'Y' and
 FALSE if they press 'N'


Part Six:  LORD SPECIFIC
{**************************************************************************}

Procedure AddMail(MailNumber:Byte; AddMailString:String);

 Add's the AddMailString to the Mail of the player number MailNumber.
 This gives you the opportunity to use the LORD MAIL ROUTINES to modify
 characters instead of messing with the PLAYER.DAT file.  The following is
 the information taken from LORDSTRC.PAS on MAIL ROUTINES:

Mail and color codes:  A "`" (not a "'") proceeded by certain symbols
and numbers have special funtions when LORD reads them in someones
mail.  Except for colors, these codes must be at the beginning of a
line.  Look at some MAILXX.DAT files for examples.  Here is the list
of codes - for instance, you may want your 3rd party program to give
a certain player one more charm point - there is a code to do that!

NOTE:  In most cases, such as adding experience, if you put a negetive
amount, it will DECREASE the value.  It does do checking to make sure it's
not less then 1 when done.

`1 through `0, and `! through `% are colors.  (15 of them)
          (`^ was removed.  Who wants all black forground color?)
The following codes MUST be the first and only thing on the line.

`-<account num>  This will have LORD give the 'Write <name> back?' option.
`b<amount> this deposites the amount in the readers bank account.
`G<amount> this puts the amount in the readers 'money in hand'.
`E<amount> this adds to the readers experience by amount.
`?<account num>  Makes user MARRIED to this person. (-1 for not married)
`{ this increments the 'number of lays' stat of the reader.
`} {this increments the readers charm.)
`+<amount>  Users charm BECOMES this number. (Used in divorce mail-backs)
`K this increments the amount of kids the reader has.
`M<amount>  This increments readers Strength
`D<amount>  This increments readers Defence
`,<amount>  This increments forest fights per that day
`:<amount>  This increments user fighters per that day
`;<amount>  This increments readers Hitpoint Max

   (Note, the above mail codes can decrement if a - is placed before num.
   Checking is done to make sure user does not go below certain levels)

`S This raises the readers SKILL in his current class.  Will not let the
   skill pass 40.
`T <account num>  Indicates <account num> wants to flirt with reader
`Y <account num>  Indicates <account num> wants to kiss reader
`U <account num>  Indicates <account num> wants to have dinner with reader
`I <account num>  Indicates <account num> wants to sleep with reader
`P <account num>  Indicates <account num> wants to propose to reader
`O <account num> Begins an online battle with <account num> (Don't use this!)
`c clears, homes the screen and goes down two lines.

Function NoCodes(InString:String) : String;

 Returns the string without the LORD color codes.

Procedure GetPlayer (Var Player:Player_Info; Name:String);

 Extracts the player (NAME) from PLAYER.DAT into the variable PLAYER.

Procedure PutPlayer (Player:Player_Info; Name:String);

 Writes the variable PLAYER into the slot for NAME in PLAYER.DAT.  This is
 not reversible!  So use it carefully.

Procedure GetInfo(LordPath:String; Node:Byte;
                  Var Account,Graphic:Byte;
                  Var Rip,Fairy:Boolean;
                  Var Time:Integer;
                  Var Handle,Real_1,Real_2:String;
                  Var Com:Byte;
                  Var Baud,Port:LongInt;
                  Var Fossil,Registered,Clean:Boolean);

 This gets the information from the LORD drop file and stores it in the
 variables you provide.

 You need to provide the path to LORD and the NODE number.

Procedure PutInfo(LordPath:String; Node:Byte;
                  Account,Graphic:Byte;
                  Rip,Fairy:Boolean;
                  Time:Integer;
                  Handle,Real_1,Real_2:String;
                  Com:Byte;
                  Baud,Port:LongInt;
                  Fossil,Registered,Clean:Boolean);

 This puts the information into the LORD drop file from the variables you
 provide.

 You need to provide the path to LORD and the NODE number.

Part Seven:  Closing
{**************************************************************************}

Well, that's all there is to it!  I hope you find this unit usefull, I sure
did.  And check out Village Of The Phoenix, the IGM I wrote, available
everywhere!  :)
