// Hexen RPG specs v1.0 -- NOT! This was the old opening. Hexen RPG specs v0.8 -- and this is the new one. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Table of Contents: ------------------ 1.0 Introduction 1.1 Credits 2.0 The RPG 2.1 Basics 2.1.1 Experience 2.1.2 Gold 2.1.3 Stats 2.1.4 Spells 2.1.5 Levels 2.1.6 Advancement 2.1.7 Treasure... 2.1.8 Artifacts, etc. 2.1.9 Weapons 2.2 NPCs 2.2.1 Interaction 2.2.2 Merchants 2.2.3 Misc 3.0 Programmer's Corner 3.1 Architecture 3.2 The Adventure Introducer 3.3 Compression 3.4 API 3.4.1 API: Compression 3.4.2 API: Speech 3.4.3 API: Interaction 3.4.4 API: Experience & Gold givers 3.4.5 API: Stat testers 3.4.6 API: Misc 3.5 The Reserved Vars/Scripts 3.6 Misc 4.0 Programmers Perspective, or the How-Tos 4.1 Basics 4.1.1 Experience 4.1.2 Gold 4.1.3 Stats 4.1.4 Spells 4.1.5 Levels 4.1.6 Advancement 4.1.7 Treasure... 4.1.8 Artifacts, etc. 4.1.9 Weapons 3.2 NPCs 3.2.1 Interaction 3.2.2 Merchants 3.2.3 Misc 5.0 Closing Remarks =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1.0 - Introduction ------------------ This package contains tools and standards that will allow willing WAD authors to build RPGs with merchants, NPCs, spells, gold, and experience! How would it feel to haggle with a merchant over the price of that Firestorm? Now you've actually got a REASON to kill that last monster. The awesome possibilities are limitless. The docs can be seperated into two sections: Player Docs and Programmer Docs. The player docs include the following: RPGSPC10.TXT: sections 1.0 and all of 2.0 - info on playing a Hexen RPG README.TXT: all - info on the various utils included The Programmer Docs include the Player Docs and everything else. :) Note to programmers: Before you start working on ANY RPG WADs, READ THIS DOCUMENT FROM BEGINNING TO END. I am not much of a spec writer, and although I tried to include as much information in here as possible, it is not very organized and if you, say, skip reading through the API you may miss some important information. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1.1 - Credits ------------- Mike Murtha - for introducing me to D&D (tm) Mike Reichers - for helping me, umm... in general. Yeah! In general. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2.0 - The RPG ------------- \\Plotline// The gods created your soul, but allow you a chance to choose what you want to be in your life, be it mage, warrior, or cleric. After you speak your choice, you are born. Years later, you have shown much improvement. Some stats are naturally higher then others, and others are low due to lack of devotion. But that doesn't stop you from planning to improve them later... Your training is of the best, and you can use every single weapon made by your class, and of those not of your class you can scavage for ammo! Yes, life is good. Until one day, the gods decide that you are ready to embark on your mission. You fall asleep, drunk in a tavern... but awaken in a strange land. You hear the gods whisper that if you prove yourself to them, they may give you their powers... //End Plot\\ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2.1 - Basics ------------ These are nine basic concepts that you should understand before playing a Hexen RPG. @@@@ 2.1.1 - Experience Experience is a "score" given to you by the gods. For every monster you kill, every charector you save, every mission you complete, you get experience. You need experience to advance to greated levels of power. You can gain experience... or lose it! @@@@ 2.1.2 - Gold The mint of the day. You can get gold in almost any way imagionable and can by just about anything! @@@@ 2.1.3 - Stats This is a subject not to be taken lightly. You have several "stats" which make up your charector. Each class has its own "primary" and "secondary" stats. When your charector is made, each stat is generated by rolling four electronic dice and (with the additions of special rules) three of which are added to form a stat between 3 and 18. Primary (most important) stats get 1 added to them. -INT- Intelligence - How smart you are. This stat is used extensively in your search for secret doors. This is the most important stat for mages. -WIS- Wisdom - How wise you are. Your level of enlightenment. If you ever pray to the gods, you will want plenty of this! This is the most important stat for clerics. -STR- Strength - Don't try to move large bolders without it! How strong you are. For fighters THIS is the most important stat. -DEX- Dexterity - Your hand-eye coordination, if you will. How well you can keep balence, aim well, etc. This is the Mage's secondary stat. -CON- Constitution - Stamina & ability to heal quickly. Fighter's 2nd stat. -CHR- Charisma - How charming you are. With this, you can get better prices, more support, etc. People tend to like you more. Mage's #2. @@@@ 2.1.4 - Spells With the exception of the Fletchett, this includes practically every artifact in Hexen. You automatically know all of the spells of your MAGIC level (see Levels). You can use any spell in your inventory. To put a spell into your inventory, you need to "rememorize" it. To do this, you need to rest for the night. At the penalty of not being able to heal (normally you would be healed to 100 life), you can choose to rememorize a spell. It then will become part of your inventory. You choose to rest for the night by stepping through the porthole. You choose to rememorize by stepping into the fire. In general, in the Hexen RPG, an artifact is something that is loaded with spells, and everything in your inventory that is not a puzzle item or treasure is a spell. @@@@ 2.1.5 - Levels As you gain experience, you will gain more power in the form of "levels". See GIVAWAYS.ACS for the experience you need for each level. There are two kinds of levels: Normal levels, and MAGIC levels. You start out at MAGIC level 1, Normal level 0. -Normal Levels- This is your rank, from 0 to IMMORTAL(21), on the ladder to power. The experience required increases exponantially with each level. -Magic Levels- This is your level when it comes to magic. Most spells require you to be at least a certain MAGIC level. See GIVAWAYS.ACS for the MAGIC level required by each spell. @@@@ 2.1.6 - Advancement As you gain levels, you also become more skilled. At LEAST every other level you can cast a new spell as your MAGIC level rises. For mages, this happens more quickly then for fighters and clerics. Although with each level you become more powerful, your missions also become more difficult so that you can earn the experience you need for the next level. @@@@ 2.1.7 - Treasure... Treasure, for the most part, is in the form of gems (sometimes called "planets") You can sell gems almost anywhere that there is a merchant. Blue gems usually sell for 500gp (Gold Pieces), green for 1000gp, red for 2000gp, and big red gems (so valuable as to be deemed D'Speril's heart!) at 5000GP!! Note: Before you get dreams about getting rich in the gem trade, remember that even blue gems ARE VERY RARE AND USUALLY HIDDEN IN SECRET ROOMS!!! Also, some gems are special enough to be set apart from the normal set... @@@@ 2.1.8 - Artifacts, etc. Artifacts have spells stored in them. Some artifacts have more charges* then others... * x charges equals the ability to cast x of the spell @@@@ 2.1.9 - Weapons One of the centers of the game. Fighters, mages & clerics each are only skilled in certain weapons. Although you can find weapons, it is often easier to buy them, with one exception: You can buy the most powerful weapon already assembled ONLY AT A VERY HIGH PRICE!!! Your only other option is to buy the first (and most common piece) at a VERY discount price, at one 60th of the cost of the pre-assembled weapon. The Frost Shards, Arc of Death, and Firestorm can usually only be bought at a magic shop, while the Timon's Axe, Hammer of Retribution, and Serpant Staff can usually only be bought at a weapon shop. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2.1 - NPCs ---------- NPCs are a central part of a good RPG. They represent just about every monster in the game. Think of the monsters you kill, as evil monsters. Other monsters (you can tell them apart because they won't attack you) are neutral, and some are even good! Most monsters in the game are referred to as "NPC"s @@@@ 3.2.1 - Interaction If you want to talk to an NPC, walk right up to him/her and press the spacebar. You should then back up. The NPC often has an opening remark, such as "Hello", and then, one by one, several switches start to rise. As each switch rises the option it represents appears. After all of the switches have risen, --and its often a good idea to wait, although in theory you don't HAVE to wait before you choose--flip the switch that is the option you want. If you miss reading one of the options, you can usally assume that the last switch will end the conversation. NOTE: You MUST end a conversation before starting a new one. @@@@ 3.2.2 - Merchants Merchants are the shopkeepers who will sell you things. Not all merchants will sell you their product in the same way, but what you need to do to buy is usually intuitive. Often, you can even haggle over a price! You interact with merchants just as you do with other NPCs. @@@@ 3.2.3 - Misc NPCs represent the "good, bad, and the ugly". They can talk to you, you can talk to them. Remember: That skeleton on the floor might not just be some dead remnants... =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3.0 - The Programmer's Corner ----------------------------- For all of you WAD authors out there, this may seem like a lot of work, but I have taken the liberty of creating, authoring, and programming code to do nearly everything shown in the RPG section. For explanations as to each feature, see 4.0 - Programmer's Perspective. If you are going to take advantage of this code, then, before any of your code, include the following lines of code: #define X_MapID [insert map number here] #include "rpglib.acs" RPGLIB.ACS already includes the COMMON.ACS file (included), so you should not include it a second time. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3.1 - Architecture ------------------ A key feature of the RPG system is that the player can reuse his charector, and so a definate architecture exists so that the player can switch between WADs. First off, it is important to understand that Hexen only saves the level CLUSTER. Therefore, if the player was to load a game using a WAD with the exact same cluster thay the player started in, the player can, in essence, jump from WAD to WAD. Here is a diagram to illustrate how the system works: /-----------------\ /------------------------\ |Charector Creator|________\ |RPG Base (swapout level)|<---------\ | RPGCREAT.WAD | / | RPGBASE.WAD | | |cluster 1 -MAP01 | | cluster 8 -MAP60 |------\ | \-----------------/ \------------------------/ | | | / \ | | | | | | \ / | | | / - - - - - - - - - - - - \ | | Adventure Introducer | | | ????????.WAD | | | cluster 1 -MAP01 | | _ _ _ _ _ _ _ _ _ _ _ _ _ | | | / \ | | | | | | \ / | | | /-------------------------\ | | | RPG Adventure |<----/ | | ????????.WAD | | |cluster 1/2 -MAP01/-MAP??|---------/ \-------------------------/ Mentioned in the diagram is the existance of a "Adventure Introducer." This is an optional WAD that would be a form of "town" setting on which several adventures could be introduced (e.g. a new-comer in the Tavern could ask for your assistance.) As the diagram shows, after the player has created his charector, he proceeds to the RPG Base area. In this area, the player can save the game, quit, load Hexen with RPGBASE.WAD and the RPG WAD that the player wishes to play through, and load his charector. He then steps through the porthole and proceeds to either the Adventure Introducer or the actual RPG Adventure first. No matter which of the two is chosen, the level must be in cluster 1, MAP01. If the player went to the Adventure Introducer, the Adventure Introducer then has the responsibility of introducing the plot to the adventurer and eventually taking the player to the actual RPG Adventure which may reside on any level. A player can complete an adventure by three means: Completion (a.k.a. he succeeded), Exit (a.k.a. he gives up and leaves the adventure by walking out of it, etc.), or he is Thrown Out (needs no explanation). Either way, the player returns to the last WAD he came from. If he entered the RPG Adventure from an Adventure Introducer, then that is where he returns. If he entered from the RPG Base, then that is where he returns to. If the Adventure Introducer needs to be replaced with either a different version of itself, or a completely new "Introducer", then the player will return to the RPG Base and "swap out" the "Introducer" for a new one. Otherwise, the player can stay in the "Introducer" and "swap out" for another RPG Adventure compatable with it. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3.2 - The Adventure Introducer ------------------------------ Lets say that you are creating a series of RPG WADs for Hexen that are based on a single, definate town setting that does not need to be changed from RPG WAD to RPG WAD. You can use it as an Adventure Introducer. Picure this: You want your RPGs to be based on a series of quests all based on a town. You can create a seperate WAD that is ONLY THE TOWN. Then, when in the docs to your add-ons to the town, you can tell the player what to do in the town to start the adventure. Maybe the player needs to talk to a guy in the Taven that has a quest for him. In fact, you can base several adventures on a town, and then continuously update and change the town (through use of world vars) until the player "completes" the town! And the best part is that the player would never have to leave the town and return to the RPG Base! THIS is the purpose of an Adventure Introducer. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3.3 - Compression ----------------- Hexen has many, many limits on scripts, levels, variables, etc. Even more are placed on the RPG WAD author by the RPG spec. For information on these limits, see 3.5 - Reservations. Hexen has a limit of 64 world vars, 32 map vars, and only 3 parmater vars per script. The worst part is that at not only are all variables 31bit (the 32nd tells whether the number is negative), but scripters RARELY use all 31 bits! However, with a small sacrifise on speed, I believe I have temporarily solved this problem by creating 6 compression routines. (For more information, see 3.4.1 - API: Compression) For example, I managed to compress all 6 stats (5 bits apiece for a range of 0-31) in a single world variable, easily saving five world variables for open use. In another case, I needed to fit four parms into a script call, so I was able to compress two into one. This breakes down several barriers to script writers. Why use 31 Map Vars for 31 flags? Why not just one and COMPRESS THEM! There are only two major drawbacks. A) There is a fairly minor sacrifice of speed. B) Care must be taken so that two scripts won't accidentally call the compression and decompressino scripts AT THE SAME TIME. This involves padding your code with several scriptwaits. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3.3 - API --------- IF YOU USE THE API, YOU MUST MUST MUST INCLUDE A #define X_MapID ## (where ## is the map number of the file) BEFORE YOUR #include "rpglib.acs" STATEMENT. YOU DO NOT, REPEAT, DO NOT HAVE TO INCLUDE COMMONS.ACS!!! That having been said, now to explain what the API is. The API is a collection of about 20 scripts that are designed to make your RPG scripting life easier. Every script has a name which you can call instead of always calling the number. By "calling" I refer to the use of ACS_Execute and or scriptwait(), of course. I have divided the scripts into six groups. Each script name either begins with a C_, for Call, or an I_, for Internal. In general, it is not a good idea to directly call the Internal scripts. Here is an example of a script definition... -=- ACS_Execute(C_SampleCall(3), X_MapID, int sampleParm, int anotherParm, 0); -=- C_Result <--- int garfaParm -=- ---> int garfaReturn -=- The C_Result variable is a map variable that has two uses. If the script requires a 4th parameter, it is placed in C_Result. If the script needs to return a result, the result is placed in C_Result. In this case, sampleParm & anotherParm are the arguments you specify in ACS_Execute, 0 means that you don't need an argument there and should put 0 in its place, and X_MapID is the number of the map (it is recommended you use the X_MapID define in all of your script calls to make your scripts more portable). C_SampleCall(3) refers to the script name (C_SampleCall) and the script number (3). For portability reasons (a.k.a. if I renumber the API calls), it is recommended that you use the NAME instead of the NUMBER. Also, if this script name began with an I_, as in I_Proccessor, it is reccomended that you NEVER CALL IT UNLESS YOU KNOWN WHAT YOU ARE DOING. After the definition shown above, each of the declared variables is explained, as well as the function of the script. Note: the variable following the <--- is the value you put INTO the C_Result variable before calling the script, and the variable following the ---> is the value that is returned in C_Result AFTER the script finishes. You should probably use a scriptwait() before reading the return value. Also, because the C_Result variable is often used by several scripts at one, you need to COPY ITS VALUE INTO ANOTHER VARIABLE IMMIDIATELY AFTER USE, LEST IT CHANGE!!!!!!!! @@@@ 3.3.1 - API: Compression There are six routines, shown from lowest-level to highest-level, that allow you to compress your variables and flags. (see 3.1 - Compression) Unfortunately, these only compress integers, not strings. -=- ACS_Execute(C_EncodeBit(14), X_MapID, int var, int bitNum, int newBit); -=- C_Result <--- 0 -=- ---> int newVar -=- .The C_EncodeBit script sets an individual bit of var to either 1 or 0. . . -var- The variable you wish to change. . -bitNum- The number of the bit you wish to change. . -newBit- The new bit, either 1 or 0, that you wish to change the old . bit to . . -newVar- The resulting variable with the changed bit. . . . -=- ACS_Execute(C_DecodeBit(15), X_MapID, int var, int bitNum, 0); -=- C_Result <--- 0 -=- ---> int bit -=- .The C_DecodeBit returns the bit number bitNum in variable var. . . -var- The variable you wish to know the bit of. . -bitNum- The number of the bit you wish to know. . . -bit- The bit that is returned, either 1 or 0. . . . -=- ACS_Execute(C_EncodeVar(12), X_MapID, int var, int bitCount, int varNum); -=- C_Result <--- int newVar -=- ---> 0 -=- .The C_EncodeVar encodes that variable newVar into the variable var. .C_EncodeVar also needs to known how many bits each variable is in var (e.g. .in my stats_1 variable, each stat is 5 bits), which is specified in bitCount, .and the number of the place that variable will be encoded into (e.g. at 5 .bits each, I managed to fit 6 vars into one. The first var is 1, 2nd 2, etc.) . . -var- The variable you want to compress newVar into. . -bitNum- The number of the bits per compressed variable in var. . -varNum- The number of the place in var, the first place being 1, that . you want to encode newVar into. . -newVar- The variable you want to encode into var. . . . -=- ACS_Execute(C_DecodeVar(13), X_MapID, int var, int bitCount, int varNum); -=- C_Result <--- 0 -=- ---> int uVar -=- .C_DecodeVar retrieves the variable uVar from the variable var. . . -var- The variable you want to retrieve uVar from. . -bitNum- The number of the bits per compressed variable in var. . -varNum- The number of the place in var, the first place being 1, that . you want to retrieve uVar from. . . -uVar- The variable that was retrieved from var. . . . -=- ACS_Execute(C_GetVar(16), X_MapID, int varNum, 0, 0); -=- C_Result <--- 0 -=- ---> int uVar -=- .In order to make it easier to retrieve commonly used variables, I created the .C_GetVar script. The C_GetVar script will automatically retrieve the variable .as defined by varNum. (see RPGLIB.ACS for a list of the variable this script .can retrieve) Go ahead and add your own variables to the list. . . -varNum- The variable number you want to retrieve (see RPGLIB.ACS for the list) . . -uVar- The variable that was retrieved. . . . -=- ACS_Execute(C_SetVar(17), X_MapID, int varNum, int newVar, 0); -=- C_Result <--- 0 -=- ---> 0 -=- .In order to make it easier to encode commonly used variables, I created the .C_SetVar script. The C_SetVar script will automatically encode the variable .defined by varNum. (see RPGLIB.ACS for a list of the variable this script can .retrieve) Go ahead and add your own variables to the list. . . -varNum- The variable number you want to encode (see RPGLIB.ACS for . the list). . -newVar- The variable that you want to encode. @@@@ 3.4.2 - API: Speech There are three scripts that make it easier for you to have the charectors speak. -=- ACS_Execute(C_Speech(7), X_MapID, int wait, 0, 0); -=- C_Result <--- 0 -=- ---> 0 -=- .Before running the C_Speech script, put the name of the charector into TalkC, .and what he/she says into TalkL. Lets say you want "Rinkydink" to say "oy!": . TalkC = "Rinkydink"; . TalkL = "oy!"; . ACS_Execute(C_Speech, X_MapID,0,0,0); scriptwait(C_Speech); .And the output is - RINKYDINK: 'OY!' - in gold letters .This script allows you to have a charector say multiple lines of dialogue by .simply changing the TalkL variable and calling C_Speech. The script will wait .for wait ticks before terminatin. (If wait is 0, it waits 35 ticks) .Note: You might worry that the status display on the top of the screen will . disrupt anything you write up there. WELL DON'T! C_Speech will auto- . matically disable that display until it terminates. . . -wait- How long * 1/35 sec you want C_Speech to pause before . terminating. (don't forget the scriptwait()!) If you put 0 as . this parameter, it waits for two seconds. . . . -=- ACS_Execute(C_SpeechFromLineNum(8), X_MapID, int wait, int lineNum, 0); -=- C_Result <--- 0 -=- ---> 0 -=- .Yet another easy way to display multiple lines of dialogue. There are five .variables, TalkL_1 through TalkL_5, that basically act as a TalkL. Run this .script on each of the 5 lines, and you've got something like this: . TalkC = "Rinkydink"; . TalkL_1 = "42 is" . TalkL_2 = "the meaning" . TalkL_3 = "of life," . TalkL_4 = "the universe," . TalkL_5 = "and everything." . ACS_Execute(C_SpeechFromLineNum, X_MapID,1,0,0); scriptwait(8); . ACS_Execute(C_SpeechFromLineNum, X_MapID,2,0,0); scriptwait(8); . ... .You get the point. .In essense, C_SpeechFromLineNum simply runs C_Speech on the TalkL line you tell .it to display, so assume the same features listed in C_Speech apply to .C_SpeechFromLineNum. . .Note: If you run low on map vars, you can comment out some of the TalkL_x vars, . but make sure you comment out the corrisponding code that refers to them! . (Don't worry, you'll see.) Same goes for adding more TalkL_x vars. . Remeber: This code is for YOUR benefit. Fine tine these little details . as much as you want as long as you don't go against the RPG v1.0 spec! . . -wait- How long * 1/35 sec you want C_Speech to pause before . terminating. (don't forget the scriptwait()!) If you put 0 in . this parameter, it waits for two seconds. . -lineNum- The number of the TalkL that you want displayed. . . . -=-ACS_Execute(C_Dialogue(11), X_MapID, int wait, int lineStart, int lineCount); -=- C_Result <--- 0 -=- ---> 0 -=- . TalkC = "Rinkydink"; . TalkL_1 = "42 is" . TalkL_2 = "the meaning" . TalkL_3 = "of life," . TalkL_4 = "the universe," . TalkL_5 = "and everything." .Remember this example from C_SpeechFromLineNum? Here is the TRUE power of the .speech API... . ACS_Execute(C_Dialogue, X_MapID, 0, 1, 5); .There you go, all five lines displayed with only one line of code! . .Note: This script basically runs C_SpeechFromLineNum several times for you. . Read the notes, features, benefits, etc. of C_SpeechFromLineNum before . you use this script. . . -wait- How long * 1/35 sec you want to pause between each line. . (don't forget the scriptwait()!) If you put 0 in this parameter, \ . it waits for two seconds. . -lineStart- The first line number you want to display. . -lineCount- The number of lines to display consecutively after line number . lineStart. . . . @@@@ 3.4.2 - API: Interaction Although there are only two script in here, they are some of the most useful script in the entire API! They automate the task of engaging in conversation. Because there is so much involved in this subject, I kept the API docs at the bare bone. For more information, see 3.2.1 - Interaction. -=- ACS_Execute(C_MultiChoice(4), X_MapID, int ss, int es, int callscript); -=- C_Result <--- 0 -=- ---> 0 -=- . When engaging in a conversation, have your charector make some opening .remarks, and then its the player's turn. This script will show the player his .options, and when the player makes his choice, will call a the script you gave .C_MultiChoice with the choice the player has chosen. . . -ss- The first switch in the chain of switches that are the player's . choices. . -es- The last switch in the chain of switches that are the player's . choices. . -callscript-The script to call after the player has made his choice. The . script should have only one argument: an integer. This is the . number of the choice. . . . -=- ACS_Execute(I_Processor(5), X_MapID, int callscript, int D_s, int cs); -=- C_Result <--- 0 -=- ---> 0 -=- . This script should NEVER be called directly unless you have a very, very good .reason to. Even then, reconsider. . This script is called once the player has made his choice. It lowers the .switches, displays the choice, and calls the callscript. . . -callscript-The script that needs to be called after processing is complete. . -D_s- A compressed variable. Bitsize: 15. . varNum = 1: ss . varNum = 2: es . -ss- This variable is the same variable that was given in . C_MultiChoice, minus 1. . -es- This variable is the same variable given in C_MultiChoice. . . . @@@@ 3.3.4 - API: Experience and Gold givers These are several routines that automate the process of giving the player gold and experience, and some routines that automate buying and selling items in a merchant's shop. -=- ACS_Execute(C_GiveExp(1), X_MapID, int exp, int sm, 0); -=- C_Result <--- 0 -=- ---> 0 -=- . This script gives the player experience and prints a message to the screen .informing the player. This script can be used in your scripts for the added .benefit of displaying the message, or you can add it to your monster specials .to automatically give the player his experience. . . -exp- The amount of experience you want to give to the player. . -sm- Put 1 in here if you want to suppress displaying the message. . Otherwise, put anything else in here. . . . -=- ACS_Execute(C_GiveGold(2), X_MapID, int gp, int sm, 0); -=- C_Result <--- 0 -=- ---> 0 -=- . This script gives the player gold and prints a message to the screen .informing the player. This script can be used in your scripts for the added .benefit of displaying the message, or you can add it to your monster specials .to automatically give the player his gold. . . -gp- The amount of gold you want to give to the player. . -sm- Put 1 in here if you want to suppress displaying the message. . Otherwise, put anything else in here. . . . -=- ACS_Execute(C_GiveBoth(3), X_MapID, int exp, int gp, int sm); -=- C_Result <--- 0 -=- ---> 0 -=- . This script gives the player both gold and experience, and displays a message .to the screen informing the player. In essense, it just calls C_GiveExp and .C_GiveGold (in that order). READ THE DESCRIPTION OF SM CAREFULLY! . . -gp- The amount of gold you want to give to the player. . -exp- The amount of experience you want to give to the player. . -sm- Put 0 in here to show messages for both C_GiveExp and . C_GiveGold (it will pause for 1 second between the messages). . Put 1 in here to suppress ONLY the experience message. . Put 2 in here to suppress ONLY the gold message. . Put 3 in here to suppress both messages. . . . -=- ACS_Execute(C_BuyItem(21), X_MapID, int gpCost, int spawnSpot, -=- C_Result <--- 0 int spawnThing); -=- ---> 0 -=- . The script automates the processes of purchasing an item. It will .automatically check the player to see if he has enough gold to but it, and, if .so, will subtract that much gold from the player's total and "spawn" the item .spawnThing at spawnSpot, informing the player. Otherwise, it will tell the .player that he doesn't have enough money. . This script can often be most useful in a merchants shop when the price is .set and you don't want the hassel of writing your own purchasing script. . . -gpCost- The price of the item the player wants to buy. . -spawnSpot- The tid of the place where you want the purchased item spawned. . -spawnThing-The thing number that the player bought. Look in HEXSPC09.DOC . (included) and DEFS.ACS (also included) for the list of things . you can spawn and their numbers. . . . -=- ACS_Execute(C_SellItem(22), X_MapID, int gpCost, 0, 0); -=- C_Result <--- 0 -=- ---> 0 -=- . Unfortunately, the only things that can be sold are puzzle items & treasure. .All of the same, a Use_PuzzItem that points to this script will automate the .process of having the player sell something to the merchant. It adds the cost .of the item to the player's gold total, informing the player. . This script can often be most useful in a merchants shop when the price is .set and you don't want the hassel of writing your own sell script. . . -gpCost- The price of the item the player sold. . . . @@@@ 3.3.5 - API: Stat testers In order to immerge the player in RPG experience, and to actually make the stats WORTH something :), these are routines that simulate the aspect of chance of the RPG. At the moment, there are only three routines. A dice throwing script, a stat testing script, and a script that handles secret doors. -=- ACS_Execute(C_DiceRoll(10), X_MapID, int count, int sides, 0); -=- C_Result <--- 0 -=- ---> int diceTotal -=- . This script simulates throwing count dice, each having sides sides, numbered .1 through sides. It adds them together, and returns the total in diceTotal. . Basically, this script runs count random(1, sides), and adds them together. . . -count- How many dice you want to throw. . -sides- The number of sides, numbered 1 through sides, on each of the . dice. . . -diceTotal- The sum of the dice. . . . -=- ACS_Execute(C_DiceRoll(9), X_MapID, int stat, int hilow, 0); -=- C_Result <--- 0 -=- ---> int testResult -=- . This script rolls one twenty sided die, and checks to see whether the result .is either higher or lower then the stat you tell it to check. . This script lets you see if the player has enough strength, etc. to pass a .test, and so usually the player would want a roll lower then their stat. . . -stat- The stat you want to check. This should be one of the V_ defines . (see C_GetVar) . -hilow- Either TEST_higher(1) if the player wants a higher roll, or . TEST_lower(0, recommeded) if the player wants a lower roll. . . -testResult-True, if the player passed the "stat check", false if he failed. . . . -=- ACS_Execute(C_SecretDoor(18), X_MapID, int lineID, 0, 0); -=- C_Result <--- 0 -=- ---> 0 -=- . Most of you WAD authors out there are used to a different kind of secret .door. One which usually stands out from the rest of a wall and which merely .needs to be opened. However, in the Hexen RPG, there is a new kind of secret .door. . Although the secret door should be fairly inconspicuous (pardon the spelling) .it can have something unusual about it that can be seen through CLOSE .EXAMINATION. Also, the secret door can't just be easily opened. The opening .requires a stat check. This routine automates all of this for you. . First off, create a secret door as you normally would, with all of the .attributes of one WITH ONE EXCEPTION: instead of using a Door_ special, it .needs to have a Line_SetIdentification special, with the ID set to the same as .the tag of the sector. Also, an OPEN script in your map script file MUST have .the following line for every secret door in your WAD, substituting #lineID for .the ID and tag of each of your secret doors: . .ACS_Execute(C_InitSecretDoor,X_MapID,#lineID,0,0); scriptwait(C_InitSecretDoor) . . From that point on the C_SecretDoor and C_Grunt (see 3.3.6 - API: Misc) .scripts will automate the secret door. . . To a degree, this script is an internal script as in you should not call it .unless you known what you are doing. However, I decided that it better fit the .category of a call script because, in theory, you could put it to some other .use. . . -lineID- The ID of the line and sector of the secret door. . . . -=- ACS_Execute(C_InitSecretDoor(23), X_MapID, int lineID, 0, 0); -=- C_Result <--- 0 -=- ---> 0 -=- . Most of you WAD authors out there are used to a different kind of secret .door. One which usually stands out from the rest of a wall and which merely .needs to be opened. However, in the Hexen RPG, there is a new kind of secret .door. . Although the secret door should be fairly inconspicuous (pardon the spelling) .it can have something unusual about it that can be seen through CLOSE .EXAMINATION. Also, the secret door can't just be easily opened. The opening .requires a stat check. This routine automates all of this for you. . First off, create a secret door as you normally would, with all of the .attributes of one WITH ONE EXCEPTION: instead of using a Door_ special, it .needs to have a Line_SetIdentification special, with the ID set to the same as .the tag of the sector. Also, an OPEN script in your map script file MUST have .the following line for every secret door in your WAD, substituting #lineID for .the ID and tag of each of your secret doors: . .ACS_Execute(C_InitSecretDoor,X_MapID,#lineID,0,0); scriptwait(C_InitSecretDoor) . . From that point on the C_SecretDoor and C_Grunt (see 3.3.6 - API: Misc) .scripts will automate the secret door. . . Note: The reason this script has nearly the exact same docs of the . C_SecretDoor script is because I added it later and decided just to . copy the docs, considering they weren't describing the script itself. . IF YOU AREN'T PAY ATTENTION LISTEN UP AND READ THE FOLLOWING: . In your OPEN script, running this script will set the special of the . linedef of the secret door to call C_SecretDoor. When the player . finds the secret door, C_SecretDoor changes the wall texture to that . of a door and sets the linedef special to Door_Raise. . . -lineID- The ID of the line and sector of the secret door. . . . @@@@ 3.3.6 - API: Misc These are the routines which don't really fit into any catagory. -=- ACS_Execute(C_Grunt(19), X_MapID,0,0,0); -=- C_Result <--- 0 -=- ---> 0 -=- . This is a fun script to call. Each class in Hexen has its own grunt, and so .this script figures out which grunt to play, and plays it. In fact, it is .almost impossable to distinguish the C_Grunt from a real grunt! This script is .used when hiding things, such as secret doors. . . . -=- ACS_Execute(I_StatShowLoop(20),X_MapID,0,0,0); -=- C_Result <--- 0 -=- ---> 0 -=- . Why anyone would need to call this script is beyond me, especially .considering that it is the only OPEN script (at the moment) in the API. .However, for those of you who want to know, this is what it does... . As you play through a Hexen RPG, you will notice three messages flashing at .the top of the screen: . ### EXP . LEVEL ## . ### GOLD . These messages tell you, respectively, how much experience you have, what .level you are, and how much gold you have. Guess which script displays them? .Yup! This one. Also, this script keeps track of how long it has been from the .last time you slept for the night. After five minutes, you can sleep again. . . . -=- ACS_Execute(C_TellSpellType(6), X_MapID, int spellNum, int typeNum, -=- C_Result <--- 0 int chargeCount); -=- ---> 0 -=- . This script is meant to be placed on artifacts you put in your levels. It .tells the player what kind of object he has picked up and how many charges it .has. (see 4.1.3 - Spells) For a list of the numbers of the spells and spell .types, see the defines in RPGLIB.ACS . . -spellNum- The number of the spell the player has obtained. . -typeNum- The number of the type of the spell the player has obtained. . -chargeCnt- The number of charges in the object the player picked up. . (ignored if the spell type is 1 ("Scroll") or 4 ("Artifact")) . . . =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3.5 - The Reserved Vars/Scripts --------------------------------------------- Before you read this section, take a deep breath. Ready? Ok, read on... v1.0 - Scripts 1-50 are reserved for API and internal RPG use v1.0 - A minimum of three map variables is required for rpglib, a minimum of at least eight map vars is recommended if you are going to use C_MultiChoice v1.0 - All world vars EXCEPT for 48 through 64 are RESERVED for RPG and internal use. Also, other world vars from 1-47 are availuable on request. At the time of this spec, the following world vars are in service: 1 2 3 1234567890123456789012345678901 1: gold | 2: experience | 3: int |wis |str |chr |con |dex |@ @ = F_Talking 4:slpwt|lvl |clss|mlvl|0000000000@ @ = F_SleptYet There are three things you need to tell me when requesting a world var between 1-47. a) Why you need something so perminant (48-64 are for individual adventures and will change from adventure to adventure, 1-47 are PERMINANT and will stick with the player's charector FOREVER) b) What the benefit the RPG community will recieve from this. c) The MINIMUM number of bits you need. Also, you will need to submit to me source code that will modify the variable (don't worry, this is just for verification purposes). If you do not use your world var bits then you must face the possibility of CONFISCATION. You also have the option of volintarily releasing your reservation on the bits. v1.0 - The following puzzle items have a specific name and cannot be renamed or used for an entirely different purpose: ZZ_GemGreen1 - Green Gem ZZ_GemBlue1 - Blue Gem ZZ_GemRed - Red Gem ZZ__BigGem, known as Korax's Heart - Big Red Gem You may do whatever you want with these AS GEMS*, but because the player will carry tons of them around, you cannot, say, change their graphics and use them for something else. Also, any OTHER puzzle items that the player manages to find in your RPG WAD must be returned, other wise the player could pick up a clock piece in one RPG WAD, swap out, and use it in another. This is not always a good thing. Don't be afraid to use puzzle items, but proceed at your own discretion. * in other words you can have the player need to find a gem and put it into a maching, but you can't use the exact same puzzle item, change the graphics, and then, say, have the player hunt for Barney's head and sacrifise it to the gods, or something v1.0 - Cluster 8 and MAPs 55-60 are reserved for RPGBASE.WAD use. I will not dwell on this subject any longer, but if I recieve, say, thousands of complaints from angry RPG WAD authors I may losen these restrictions. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3.6 - Misc ---------- Nothing here yet... =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 4.0 - Programmers Perspective, or the How-Tos --------------------------------------------- This section is a fairly detailed description of how to do everything I mentioned in section 2.0 - The RPG. Everything quoted in here comes from the "Player Docs". =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 4.1 - Basics ---------------- @@@@ 2.1.1 - Experience Experience is a "score" given to the players. In order to be consistant from adventure to adventure, each monster has been assigned a certain amount of exp, and unless the monster was a good and/or maybe neutral NPC, the player should obtain that amount of experience. The easiest way to do this is to set the monster's special to call the script C_GiveExp, or script 1, with the experience gained as the first argument. (see 3.4 - API) Even when you are scripting you should call the C_GiveExp script for purposes of flexibility, and also because it has the added benefit of informing the player. However, if you must, you can also modify the experience variable directly. It is world var #2 and is even declared in the rpglib.acs file. @@@@ 2.1.2 - Gold Money. Need I say more? No, but might as well. :) If you want the player to get both experience AND gold when he kills a monster, set the special of the monster to call the C_GiveBoth script. (see 3.4 - API). More will be discussed on what to DO with money later. @@@@ 2.1.3 - Stats These are the player's six stats. Lets review through them: "-INT- Intelligence - How smart you are. This stat is used extensively in your search for secret doors. This is the most important stat for mages." "-WIS- Wisdom - How wise you are. Your level of enlightenment. If you ever pray to the gods, you will want plenty of this! This is the most important stat for clerics." "-STR- Strength - Don't try to move large bolders without it! How strong you are. For fighters THIS is the most important stat." "-DEX- Dexterity - Your hand-eye coordination, if you will. How well you can keep balence, aim well, etc. This is the Mage's secondary stat." "-CON- Constitution - Stamina & ability to heal quickly. Fighter's 2nd stat." "-CHR- Charisma - How charming you are. With this, you can get better prices, more support, etc. People tend to like you more." In your RPG adventure, try to come up with some obsticles that involve the stats. For example, if there is a big rock blocking the entrance to a cave, have the player try to push it asside, but in order to move it even an inch he has to pass a "strength check". You should preform such a "stat check" by calling the script C_DiceTest, telling it you want to test the player's strength, and that the player must roll lower then his strength. C_DiceTest will roll a twenty sided die, and tell you if the player passed the test. If he succeeds, then he has moved aside the rock. Otherwise, he "grunts" (see C_Grunt) and fails. However, don't always retest the player for every inch he moves the rock. Such tedious work can get old VERY QUICKLY. @@@@ 2.1.4 - Spells "With the exception of the Fletchett, this includes practically every artifact in Hexen. You automatically know all of the spells of your MAGIC level (see Levels). You can use any spell in your inventory. To put a spell into your inventory, you need to "rememorize" it. To do this, you need to rest for the night. At the penalty of not being able to heal (normally you would be healed to 100 life), you can choose to rememorize a spell. It then will become part of your inventory. You choose to rest for the night by stepping through the porthole. You choose to rememorize by stepping into the fire. In general, in the Hexen RPG, an artifact is something that is loaded with spells, and everything in your inventory that is not a puzzle item or treasure is a spell." Note: When I refer to artifacts, I refer to Hexen artifacts unless explicitly stated (usually through quotation marks) that I am not. To make the Hexen RPG more interesting, an attempt should be made to differentiate between "scrolls", "staffs", "wands", and "artifacts". "Scrolls" are objects in which there is only one "charge", or spell use. "Wands" are objects that contain more then one charge of a spell. To simulate this, place several copies of an artiface in one place, so the player seems to pick them all up at once. "Staffs" are just like "Wands", only more powerful. "Artifacts" are to "Scrolls" as "Staffs" are to "Wands", in other words, consider an "Artifact" to be a very power "Scroll" with only one charge. Also, Fletchetts and Dark Servants are "Artifacts" only. Nothing else. BTW, by "more powerful" I mean that the more powerful spells (you can tell them because on my list of prices there is a considerable gap between weaker spells and powerful spells) only exist in the form of "Artifacts" or "Staffs". Go ahead and differentaite between the four findable spells at your discretion. In order to make the game... more interesting. I have included a script, which you can use to tell the player what he has picked up and how many charges it has. (see C_TellSpellType) Another aspect of spells is rememorization. At certain points along an adventure, the player should be able to "rest for the night". As you know, I have included an example WAD in this package. Simple, but demonstative. Copy from it two rooms. One was a dark room with a porthole on one side and a flame on the other. Stepping through the porthole takes the player into a room of health vials and a porthole leading home. Stepping through the flame takes the player into a room full of artifacts and switches. The artifacts are the spells of the Hexen RPG. The switches, only raised in front of some of the artifacts, represent the spells a player can rememorize. Using a switch lowers all of the switches in the room, turns off the light in the room, and another flame appears. Stepping through the flame returns the player to his "place of departure" If you want, you can copy these rooms and paste it in your WAD. Make sure you don't use any conflicting TIDs, tags, etc! 'course, this should be no problem unless you use TIDs, etc over 200. If you "import" those rooms, then you can use the undocumented C_NightRest script. Put a "bed" in a room, and when the player walks onto the bed call the C_NightRest script with only one argument: the TID of return. The script will handle the rest. @@@@ 2.1.5 - Levels "As you gain experience, you will gain more power in the form of "levels". See GIVAWAYS.ACS for the experience you need for each level. There are two kinds of levels: Normal levels, and MAGIC levels. You start out at MAGIC level 1, Normal level 0. -Normal Levels- This is your rank, from 0 to IMMORTAL(21), on the ladder to power. The experience required increases exponantially with each level. -Magic Levels- This is your level when it comes to magic. Most spells require you to be at least a certain MAGIC level. See GIVAWAYS.ACS for the MAGIC level required by each spell." Unless you are going to use the Magic Levels (which would be really awesome), you do not need to worry about levels, although you could find a way to use them to your advantage if you wanted... @@@@ 2.1.6 - Advancement "As you gain levels, you also become more skilled. Every 4 levels you gain +1 to your primary and every 8 levels you gain +1 to your secondary. Although with each level you become more powerful, your missions also become more difficult so that you can earn the experience you need for the next level." All I've got to say about advancement is that it only applies when you first create the RPG WAD when you need to think out two things: 1) What level the RPG WAD is designed for. 2) How much progress the player can make in terms of experience & gold. @@@@ 2.1.7 - Treasure... "Treasure, for the most part, is in the form of gems (sometimes called "planets") You can sell gems almost anywhere that there is a merchant. Blue gems usually sell for 500gp (Gold Pieces), green for 1000gp, red for 2000gp, and big red gems (so valuable as to be deemed D'Speril's heart!) at 5000GP!! Note: Before you get dreams about getting rich in the gem trade, remember that even blue gems ARE VERY RARE AND USUALLY HIDDEN IN SECRET ROOMS!!! Also, some gems are special enough to be set apart from the normal set..." Again, not much to say. The above description is pretty self-explanitory. As with the gold, I will go through here in more detail later. However, just know that when I refer to gems, I refer to puzzle items: GemBlue1, GemGreen1, GemRed, and Korax's Heart. @@@@ 2.1.8 - Artifacts, etc. I just went through all of this in 2.1.3 - Spells. @@@@ 2.1.9 - Weapons "One of the centers of the game. Fighters, mages & clerics each are only skilled in certain weapons. Although you can find weapons, it is often easier to buy them, with one exception: You can buy the most powerful weapon already assembled ONLY AT A VERY HIGH PRICE!!! Your only other option is to buy the first (and most common piece) at a VERY discount price, at one 60th of the cost of the pre-assembled weapon. The Frost Shards, Arc of Death, and Firestorm can usually only be bought at a magic shop, while the Timon's Axe, Hammer of Retribution, and Serpant Staff can usually only be bought at a weapon shop." Read my lips. NO EASY TO GET WEAPONS. Weapons are supposed to be rare luxuries, considerinh there are only four of them. IF, and I mean, IF, you include any weapons in your adventure, unless it is designed for a level 20 player, MAKE THEM VERY, VERY, VERY hard to find. However, the one weapon which, although the hardest to find, I ENCOURAGE having in your adventure is pieces of #4. But again VERY VERY VERY ... VERY hard to find. Thank you, that will be all. :) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2.1 - NPCs ---------- "NPCs are a central part of a good RPG. They represent just about every monster in the game. Think of the monsters you kill, as evil monsters. Other monsters (you can tell them apart because they won't attack you) are neutral, and some are even good!" NPCs... you can live with 'em, you can't live without them, so shut up and learn how to make them. :) @@@@ 3.2.1 - Interaction "If you want to talk to an NPC, walk right up to him/her and press the spacebar. You should then back up. The NPC often has an opening remark, such as "Hello", and then, one by one, several switches start to rise. As each switch rises the option it represents appears. After all of the switches have risen, --and its often a good idea to wait, although in theory you don't HAVE to wait before you choose--flip the switch that is the option you want. If you miss reading one of the options, you can usally assume that the last switch will end the conversation. NOTE: Although I tried to be "flexible" in the entire thing, there is still a bug which should be corrected by the time you read this document, so nevermind. But although the system is pretty stable, PLEASE end a conversation before you try to open one with someone else. Failure to do so may result in TOTAL CHAOS. Thank you." And here comes the fun part. You need to design a series of charector that the player will interact with throughout the game. The basic method of interaction is simple, and here's how to set it up. 1) Descide what "thing" your charector will be. (e.g. corpse, cleric boss, etc.), create it, and make it dormant. 2) Draw two two-sided "boxes" around it. 3) Set the inner one* to be an impassable, special: Line_SetIdentification, use type: impact or projectile cross (whichever works). 4) Set the outer one to be special: Line_SetIdentification, use type: use (e.g. spacebar) Easiest things first. Decide what you want to happen when the NPC is punched. In the OPEN script of your level, set the inner box* that you tagged to do whatever it should do when the guy is punched. I reccomend that you write a script to have the guy say "FOOL. YOU WILL DIE NOW!" or something like that^, activate the NPC, and then turn off the impassable flag of the inner box. Then clear the specials (e.g. set them to be "No Acton", or 0) of both boxes and let the two fight it out. Its not a good idea, however, to give the player experience if he kills the NPC, though. Ok, now the NPC will react if the player punches/shoots him, but now we need to have the player be able to talk to him. Remember the outer box? In your OPEN script you need to set it to run one of your scripts. In that script, the charector will, say, make an opening remark or something. Then, and I'll discuss this later, call C_MultiChoice to present the player with his options. The player will choose one, and then the charector will do something and then its the players turn again, and so forth. I'll leave it up to you to decide what will happen. And now for one of the most useful scripts in RPGLIB.ACS: C_MultiChoice. This is the way it works. VERY close to the NPC create a series of switches, all lowered to the ground so the player doesn't even know that they are there. Each switch should be about 32 wide, 32 tall, and 8 thick, its lower texture~ should be the mouth switch (only fitting, I say. (: ), its special should be Line_SetIdentification, and its activation use. Also, you will need to tag each of the switches (linedef & sector tag) consecutively, so that, say, switch 31 will be on the farthest left, 32 to the right of it, 33 to the right of 32, etc. Don't worry about setting the line special in your OPEN script though THIS time. Now, this is what will happen when the player walks up to the guy and hits spacebar. Your script, once run, will set EACH OF THE TalkL_# vars WITH AN OPTION FOR THE PLAYER. Now lets say that you have four options, and therefor AT LEAST four switches have been set up right next to each other and consecutively numbered 31, 32, 33, and 34. Now, your script will call C_MultiChoice with three arguments. The first one is the number of the first switch in the series, which in this case is 31. The second argument is the LAST switch in the series, which is 34. And the third argument is the number of the script that will be called when the player has chosen. It will have only one argument, the number of the choice, NOT THE SWITCH, but the choice of the player. Switch 31 would be choice 1, switch 32 choice 2, etc. And this is what the player will see. He will see (providing you included it) an opening remark, like "MERCHANT: 'HELLO'", and then, one by one, his options will be shown on the screen indivually for about two seconds as the switch representing that option rises. He will then choose an option, and all of the switches will lower while his choice is displayed at the top of the screen. After all of the switches have lowered, the script number that was specified earlier to C_MultiChoice will be called and the number of the player's choice given to it. This is how players and NPCs interact. Before moving on, there are some final points to make: *) You can ALWAYS assume that the player will end one conversation before starting another. Although it is, in theory, possible to allow the player to start a conversation with another NPC when he didn't end his old one, unless YOU SPECIFICALLY INTEND TO, SAY, HAVE A DIALOGUE BETWEEN TWO NPCs, it is too great a tax on resources to allow. The players have already been warned, it is their fault not yours. *) Be careful how many of the limited resources you use in NPCs. In other words, make them awesome, but 10 good NPCs are better then 2 awesome ones. Remember: There is always compression! *) The only thing that NPCs cannot do in Hexen is be made to move, walk, etc. in any way. * when ever I refer to the "box", I refer to all four lines making up the box. ^ once, I had the say, 1st: "OUCH", 2nd: "OUCH", 3rd: "STOP", 4th: "CUT IT OUT!", 5th: "THIS IS YOU LAST WARNING!", 6th: ten dark bishops appear, and the guy is only level 0 so he only has a fist, heh heh heh... ~ I am referring to the side of the switch that the player will use, of course. @@@@ 3.2.2 - Merchants "Merchants are the shopkeepers who will sell you things. Not all merchants will sell you their product in the same way, but what you need to do to buy is usually intuitive. Often, you can even haggle over a price! You interact with merchants just as you do with other NPCs." When it comes to merchants and shops, as long as, on average, the player will spend the amount shown in GIVAWAYS.ACS on his goods, and as long as your method is implicit and easy to use, you can have the player buy goods from the mercant IN ANY MANNER YOU DEEM FIT. You can have the goods in showcases, you can have them in slot machines, you can have the player buy them from the merchant himself, etc. Your choice here. Now to talk a little about treasures and gold. All along the player's adventure he has accumulated amounts of gold and maybe a gem. Merchants give the players a change to spend their new found wealth. Also, merchant provide a way for players to sell their gems, etc. However, there are DEFINATE PRICES for things listed in GIVAWAYS.ACS. You can be a little low or a little high or have limited time sales or haggling or whatever. Just don't go way off. If, say, you want a player to put his gems in a slot in the side of the wall, you could set the wall special to Use_PuzzItem, and call my C_SellItem script. If, say, you want a player to buy things by walking up to the showcase with the item and pressing spacebar you can just have it call my C_BuyItem script. Easy! @@@@ 3.2.3 - Misc "NPCs represent the "good, bad, and the ugly". They can talk to you, you can talk to them. Remember: That skeleton on the floor might not just be some dead remnants..." =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 5.0 - Closing Remarks --------------------- Programmers, remember the following: *) Please do not go against the spec NO MATTER WHAT. The spec was created so that there would be a central standard. I am not a dictator, and I admit I probably made some mistakes and/or misjudgements. If you want something changed, e-me at cogmc@prodigy.com and we'll see from there. Players, remember the following: *) Thou shalt not engage in more then one conversation at a time before saving the game lest thou create HAVOK! :) My mail address is: Gregory Crosswhite 4022 Foreston Rd Beltsville, MD 20705 USA My e-mail address is: cogmc@prodigy.com I am anxious to hear you opinions, so please let me know what you think. (Although "IT SUCKS!" will be accepted, it will hardly help anything. Please include some constructive critisism.) Also, if you are interested in making an RPG WAD, please let me know your name and e-mail address. If you make an RPG WAD, let me know so I can add it to my list and/or throw in my two cents. Thanks.