/* NOTE: This is a C/C++ conversion of the original LORDSTRC.PAS for those programmers who write in C/C++. Revisions by GSValore: 06-09-1999: First Conversion to C/C++ format. 12-07-1999: Fixed a few things 05-20-2000: Made sure this would compile in pure C format. Also cleaned up the code some. Confirm these structure sizes when you compiler: lord_player_info : 236 lord_monst : 239 Tested with: DJGPP 2.952 Visual C++ 4.0 Standard ____________________ Original Comments _____________________________ A quick note as of 8-31-97: The entire source to Seth's IGM Barak's house is available for download at www.rtsoft.com. A good place to start if you want to make an easy to install IGM that runs great! These are the pascal file structures for the players and enemies for Legend Of The Red Dragon 3.20 to 3.53a This file was last updated on 12-12-95. For software developers. 3.53a does NOT change the format of the PLAYER.DAT file. Carry on! Check the BOTTOM of this file for NEW things about 3.53a developers should know. Legend Of The Red Dragon (c) Copyright 1995; Robinson Technologies ALL RIGHTS RESERVED. Note from Seth A. Robinson: You have my permission to build add-ons, editers, whatever - BUT, if you decide to charge money for them I would appreciate it if you would upload me your file privately, let me evualuate it and see if it deserves my stamp of approval. That's right, I'm not against others making money off their mods, in fact, I don't demand any percentage whatsoever. God knows I've made much more than I deserve already. Just try not to charge more than I do for LORD itself, k? Also, in ANY util for LORD, be sure to give some credit to ME! If you are going to build a LORD In Game Module, you *MUST* meet these specifications to call it such: 1. It reads *NO* external drop file, but gets all data from the info.? file AND node?.dat file. 2. It has options to install *AND* uninstall itself. (ie, add the program to the 3RDPARTY.DAT file itself) 3. The top line if the file_id.diz is like this: LORD IGM (Decorate if you like) The reason I'm giving these specific instructions is because a few others have released their software as IGM's, sysops expect the simple installation they got with Barak's House and instead find themselves having to mess with writing dropfiles for the LORD mod separatly - which can be a mess, especially if the drop file is overwritten while someone else goes into the realm, ect. *PLEASE* abide by these rules. If you don't - I, uh, will send someone to break your thumbs! ;> 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. `- This will have LORD give the 'Write back?' option. `b this deposites the amount in the readers bank account. `G this puts the amount in the readers 'money in hand'. `E this adds to the readers experience by amount. `? 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.) `+ Users charm BECOMES this number. (Used in divorce mail-backs) `K this increments the amount of kids the reader has. `M This increments readers Strength `D This increments readers Defence `, This increments forest fights per that day `: This increments user fighters per that day `; 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 Indicates wants to flirt with reader `Y Indicates wants to kiss reader `U Indicates wants to have dinner with reader `I Indicates wants to sleep with reader `P Indicates wants to propose to reader `O Begins an online battle with (Don't use this!) `c clears, homes the screen and goes down two lines. ***** HOW DO I MAKE AN IN GAME MODULE FOR LORD? ***** It is really sort of easy. The smartest way is to write your door to be able to read the NODEX.DAT files - (For com port, port speed, ect) these are text editable, so you should be able to figure them out ok. It comes down to this: Someone will be able to unzip your program, and run the CFG/Installer, and it will add two lines to the 3RDPARTY.DAT file. These two lines are ALL LORD needs to automatically list your door name as it appears to the players, (second line) and the path and name of the EXE or BAT file that is run. Look at the 3RDPARTY.DAT file, it comes empty, but does contain a commented out example. Note: the 3RDPARTY.DAT file is automatically created when LORD is run if it doesn't exist. Notice that a * anywhere in the first line will have LORD subsitute the node number. So with say "C:\LORD\NEWBAR.EXE /N*" would give your program the /N6 parm if node 6 was playing. LORD will go up to 999 nodes. (In theory only ) Why is this important? Because you can then retrieve the correct NODEX.DAT file yourself from the LORD dir. LORD will drop a file called INFO., it contains the account number of the user who just dropped. (this file also contains extra data, pherhaps enough so your program will not NEED to open another file) Your door should pick up that, (it's a text file) and load that record. Let them use the door, and write it upon exitting. This means you could load different INFO and NODE data for each node - thereby making your addon multi-node. Simple, eh? Another thing. The max "Add On's" 3.50+ can handle is a lot. At least a thousand. Please be considerate enough to throw a 'Uninstall' option in your configure program - To find your two lines and strip them out, just in case the sysop decides not to keep it. Sure, most sysops can edit the 3RDPARTY.DAT file themselves, but it's a nice option anyway. There you have it - The goal of this is to make installing add-ons much easier then installing a whole new door, because they will not have to re-configure any com port settings, or node settings, because you will be reading the NODEX.DAT files. This also means you don't have to mess with drop files at all, since using the 'account number' from the INFO.??? file lets you load the entire account, including their BBS handle and LORD handle of course. The structure of the LORD. file: 13 <-Account, from 0 to 149 3 <-Graphic Setting, 3 is ANSI, less is ASCII RIP YES <-Obvious - It's RIP NO when they are not RIP. FAIRY YES <- Do they have a fairy with them? Time Left <- In minutes. This is READ AGAIN when they come back. You should keep track and change this number accordingly, so LORD will how much time to give them. LORD Handle \ Real First Name \ Real Last Name \ Com Port; | Other info you may find useful. You should still Caller Baud Rate; / read the NODEX.DAT files, because they contain Port Baud Rate / more info - Such as a nonstardard com port. -=-=New things added to the info.? file in 3.26=-=- Note: LORD never reads any of these in, only writes them for your convenience. FOSSIL <- (will say INTERNAL if they are using LORD's internal routines) REGISTERED <- LORD registration status, else UNREGISTERED. CLEAN MODE ON <- else CLEAN MODE OFF NOTE: Look at the INFO.? file yourself while someone is in a In Game Module from LORD, you'll notice there are NO spaces in the file. */ #if !defined( LORDSTRUCT__H ) #define LORDSTRUCT__H 1 /* Structure alignment must be 1. If your compiler supports the pragma pack option, set it to 1 to make these structures their correct sizes. */ #if defined( _WIN32 ) || defined( DJGPP ) #pragma pack( 1 ) #endif /* Note on strings: Pascal strings have a different layout than C/C++ strings. The first byte in a pascal string is it's length and there is no null character but the structs will read fine using the C FILE streams should work the same with the C++ fstream class. here's a conversion function for changing a pascal string to C style: void ConvertToC(signed char *PascalString) { / * Assign the string length * / unsigned char StringSize = PascalString[0]; / * Move the string by memcpy * / memcpy( PascalString, PascalString + 1, StringSize ); / * Remove the last character and make null * / PascalString[ StringSize ] = '\x00'; } this function is public domain... do whatever you want with it:) Fix the comments, I added a space so the compiler didn't get confused. */ /* player record */ typedef struct { signed char name[ 21 ]; /* Player handle in the game */ signed char real_names[ 51 ]; /* real name/or handle from BBS */ signed short int hit_points; /* Player hit points */ signed short int bad; /* Unknown */ signed short int rate; /* Unknown */ signed short int hit_max; /* hit point max */ signed short int weapon_num; /* weapon number */ signed char weapon[ 21 ]; /* name of weapon */ signed short int seen_master; /* equals 5 if seen master, else 0 */ signed short int fights_left; /* forest fights left */ signed short int human_left; /* human fights left */ signed long int gold; /* gold in hand */ signed long int bank; /* gold in bank */ signed short int def; /* total defense points */ signed short int strength; /* total strength */ signed short int charm; /* good looking meter */ signed short int seen_dragon; /* seen dragon? 5 if yes else 0 */ signed short int seen_violet; /* seen violet? 5 if yes else 0 */ signed short int level; /* level of player */ unsigned short int time; /* day # that player last played on */ signed char arm[ 21 ]; /* armour name */ signed short int arm_num; /* armour number */ signed char dead; /* player dead? 5 if yes else 0 */ signed char inn; /* sleeping at inn? 5 if yes else 0 */ signed short int gem; /* # of gems on hand */ signed long int exp; /* experience */ signed char sex; /* gender, 5 if female else 0 */ signed char seen_bard; /* seen bard? 5 if yes else 0 */ signed short int last_alive_time; /* day # player was last alive on */ signed short int Lays; /* players lays stat */ signed short int Why; /* not used yet */ signed char on_now; /* is player on? */ signed short int m_time; /* day on_now stat was last used */ signed char time_on[ 6 ]; /* time player logged on in HH:MM */ signed char Class; /* class, (1 = Warrior, 2 = Mystic, */ /* 3 = Thief) */ signed short int extra; /* *NEW* If 1, player has a horse */ signed char love[ 26 ]; /* Unknown */ signed short int married; /* player married to, -1 if not */ signed short int kids; /* # of kids */ signed short int king; /* # of times player has won game */ signed char skillw; /* Death Knight skill points */ signed char skillm; /* Mystical Skills points */ signed char skillt; /* Thieving Skills points */ signed char levelw; /* Death Knight skill uses left */ signed char levelm; /* Mystical skill uses left today */ signed char levelt; /* Thieving skill uses left today */ signed char inn_random; /* Not Used Yet */ signed short int married_to; /* Unknown [Maybe equal to married] */ signed long int v1; /* Unknown */ signed short int v2; /* # of player kills */ signed short int v3; /* 5 = 'wierd' event will happen */ signed char v4; /* player done special for that day? */ signed char v5; /* flirted with player? 5 = yes */ signed char new_stat1; /* Unused */ signed char new_stat2; /* these 3 are unused right now */ signed char new_stat3; /* Notice: Joseph's NPCLORD uses */ /* these 3 variables */ } lord_player_info; /* Remember, in 3.20+ player skill points for each class can reach 40. It's ok to have your editer change the player level to say, 12 or such, LORD will automatically not let the player play if the game is not registered. If in your program you let the player get a new weapon, remember, you CAN change the name of his weapon, but the weapon NUMBER stat is what tells LORD which weapon he has, and if he sells it, will SUBTRACT the correct number from his overall strength. Kind of complicated. Armour works the exact same way. INFO: arm_value is the defense added or subtracted when bought or sold. wep_value is the strength added or subtracted when bought or sold. array form: *** NOTE: Price array is the same for both const unsigned long int prices[ 15 ] = { 200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000, 1000000, 4000000, 10000000, 40000000, 100000000, 400000000 }; const unsigned char arm_name[ 15 ][ 20 ] = { "Coat", "Heavy Coat", "Leather Vest", "Bronze Armour", "Iron Armour", "Graphite Armour", "Erdricks Armour", "Armour Of Death", "Able\'s Armour", "Full Body Armour", "Blood Armour", "Magic Protection", "Belars\'s Mail", "Golden Armour", "Armour Of Lore" }; const unsigned short int arm_value[ 15 ] = { 1, 3, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000 }; const unsigned char wep_name[ 15 ][ 20 ] = { "Stick", "Dagger", "Short Sword", "Long Sword", "Huge Axe", "Bone Cruncher", "Twin Swords", "Power Axe", "Able\'s Sword", "Wan\'s Weapon", "Spear Of Gold", "Crystal Shard", "Niras\'s Teeth", "Blood Sword" }; const unsigned short int wep_value[ 15 ] = { 5, 10, 20, 30, 40, 60, 80, 120, 180, 250, 350, 500, 800, 1200, 1800 }; */ // forest monster record format typedef struct { signed char name[ 61 ]; /* Monster's Name */ signed long int strength; /* Monster's Strength */ signed long int gold; /* Gold amount user receives */ signed char weapon[ 61 ]; /* Weapon name for monster */ signed long int exp_points; /* Experience points that */ /* user will gain */ signed long int hit_points; /* Hit points of the monster */ signed char death[ 101 ]; /* Phrase said when monster */ /* is killed by a power move */ } lord_monst; /* There are eleven monsters for each level - they are in the file in order. You cannot ADD monsters, but you can change them. Or one possibilty would to write an .EXE that is run before LORD is played each time that randomly replaces some monsters in each level with new ones. ** NEW! LORD'S FILE LOCKING ROUTINES! ** Get BCShare or compatible file locking system.That is what LORD uses now. A 3.50 addition: People can STAY in other towns/ect! (IGM's) No IGM currently uses this feature of this writing, (duh, since 3.50 is required to use it, and it ain't released as I write this) but I'm HOPING it would work ok. ;> Everytime a user enters an IGM, LORD creates a file called OUT.. This a text file. The first line is the description LORD will give someone when they view 'who's online' or try to attack them. The addition: You can let people exit straight back to the BBS by making the second line read QUIT. Specifying something else will now have LORD log them off, and automatically return to THAT command line specified on they're next log on. So if you rewrote the out.1 file while player num 1 was in your IGM like this: is sleeping in Barak's house. c:\barak\barak.exe * Then LORD would actually let that person stay at Barak's. Specifying a second line also makes LORD display 'where they are' slightly differently so a 'who is online' would look like this: Billy Bob is sleeping in Barak's house. No one can attack someone who is 'out of the realm' so be careful if you use this function. Note: Before return a user to your IGM when they log on the next day or whenever, it processes mail and "new day" routines if needed. ********* ABOUT MAIN.BAT *********** This is a batch file run every day RIGHT AFTER LORD does its maint. This way you could run your IGM's maint, or add things to the daily log in LORD ect, BEFORE anyone plays that day. If you want to use this, do the following in your install program: 1. See if maint.bat exists. If it doesn't, assume they are running an older version, and tell them to get 3.53a. 2. Check to see what is already in the MAINT.BAT file, if your IGM name or whatever program you use is ALREADY in there, don't add it again, take it out if you need to and add a different line, or just leave the old one in. 3. When someone uses the UNINSTALL option, make sure your program takes out the additions in MAINT.BAT in a non destructive way. Don't screw up another IGM's stuff above or below yours. Just like the 3rdparty.dat file, really. 4. In your maint or whatever, display some kind of progress report, and the IGM's name. Sysops like to know what they are doing, if they happen to be watching at midnight, give them a treat. Don't clear the screen if you can help it. And DON'T require a keypress to continue or anything. Also, it is technically possible to RUN an IGM this way - it creates an INFO.? file just like normal. Not sure how this would be handy but.. ********** INFO ON BADWORDS.DAT ********* Check this file out, you'll understand it easily. A thought is to run this by all user inputs in your IGM, that way the 'swear patrol' is online even out of LORD. This ain't required, but hey it would be cool. */ #endif