&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& A New EXPERIENCE/SKILLS system for CF &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& This patch represents a "developer's" version of the exp/skills system. While I have now achieved all of the objectives in sections "B" and "C" of the coding proposal (see README.PROPOSAL) and have play-tested as much of the code as possible, I am sure some big bugs must remain. (One for sure is that exp gained when using rod/horn/wand is wrong.) Below this section I outline 1) coding philosophy, 2) gross description of how the code impinges/interacts within older code. 3) designer's notes on the changes to the code. Comments on any area of this coding would be appreciated. Personally, I would like to see the Pow stat and a 2-type system of magic come into being. After all of you check out the code, I would like to discuss enhancements/bug fixes/implementation. For instance, is it too hard to figure out how to use the code! Sometime tomorrow exp2.tar.gz will be available in pub/thomas on ftp.astro.psu.edu. b.t. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& CODE PHILOSOPHY - &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& To move CF over to a new skills-based experience system. In this implementation several kinds of experience will exist. Players will gain experience in each kind of experience (or category) based on their actions in the game. The sum of all the various categories of experience equals the player "score", from which dam, wc, and hp are determined. All experience gaining actions will be through the use of certain skills -- so called "associated skills". Associated skills are each related to 1 kind of experience. Thus, for example, "stealing" is a skill associated with "agility" experience. There exists also "miscellaneous" skills which allow the use of a unique skill, but which are not related to any kind of experience and whose use does not generate experience points. In this implementation, skills and objects are both treated as objects in the inventory of the user. Experience "objects" each represent one kind of experience and are always invisible. Skills objects each represent one kind of skill available in the game. Skills objects may either be invisible or have an associated bitmap (in which case they are "tools"). All experience gaining actions will be through the use of certain skills -- called "associated skills". Associated skills are each related to 1 kind of experience. Thus, for example, "stealing" is a skill associated with "agility" experience. Both Players and NPC's may only use skills which are in their inventories. NPC's do not use experience objects. A breakdown of the properties of skills and exp objects objects is as follows: Object Property NPC use? ------ ----------------------------------- ------- Experience Each represents a different kind of NO experience in the game. The object in the player inventory keeps track of player experience in that category. Always is invisible. Skill- Represents a skill the player may YES associated perform. May be either invisible or visible as a "tool". Successful use of this skill generates experience. Experience is allocated to appropriate experience object. Skill- Same as above, *but* this skill is not YES miscell. related to any experience category, and use of this skill generates *no* experience. Linking of associated skills to experience categories is done during initialization of the code (in init()) based on the shared stats of both. How skills and experience categories are named and linked may be changed by editing the skills/experience object archetypes. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& CODE STRUCTURE and IMPLEMENTATION - &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& The most important thing is that I moved most of the code into the server/skills.c and server/skill_util.c files. The skills code is loosely implemented along the lines of the spell code. This is to say that: 1. skills use (do_skill) is called from fire(). 2. there is a skills[] table similar to spells[]. 3. server files skills.c and skill_util.c parallel spell_effect.c and spell_util.c in respective functionallity. Particular notes about the implementation are outlined below. Defines ------- #define MAX_EXP_CAT maximum number of exp categories. Must be >= number in the game. Always include the "NULL" exp object - EXP_NONE. #define EXP_NONE (MAX_EXP_CAT - 1) #define NROFSKILLS Equal to the number of elements in the skills[] array. See skillist.h for more info. #define MAX_EXP_IN_OBJ (MAX_EXPERIENCE/MAX_EXP_CAT) the maximum experience that an experience object may have. See fuller description in common/living.c Dump switch ----------- How the experience and skills archetypes are configured in any CF session can be seen by using the "-m5" flag. You must have DUMP_SWITCHES defined. Global parameters ----------------- Unfortunately, I had to make use of several global parameters. These are: exp_cat[] - the default experience objects nrofexpcat - number of exp categories in the current session. New Flags used by the code -------------------------- FLAG_IS_WOODED -- needed by the woodsman skill. Should be set on all "wooded" terrain (eg woods2, swamp, etc.) FLAG_IS_HILLY -- needed by the mountaineer skill. Should be set on all "mountainous" terrain. FLAG_READY_WEAPON -- Code needs this for both players and monsters, and its use differs for each. FLAG_READY_SKILL -- Code needs this for both players and monsters, and its use differs for each. New structures -------------- A couple of changes to the object structure where made: (following excerpt taken from structs.h) /* These are used by the skills code */ struct obj *chosen_skill; /* the skill chosen to use */ struct obj *exp_obj; /* the exp. obj (category) assoc. w/ this object */ uint32 hide; /* The object is hidden, not invisible */ And the 'skill' structure used by the skills[] table is: typedef struct skill_struct { char *name; /* how to describe it to the player */ short category; /* the experience category to which this skill belongs */ long time; /* How many ticks it takes to use the skill */ long bexp; /* base exp gain for this skill */ float lexp; /* level multiplier of exp gain for using this skill */ short stat1; /* primary stat effecting use of this skill */ short stat2; /* secondary stat for this skill */ short stat3; /* tertiary stat for this skill */ } skill; Interaction of the skills patch with older code ----------------------------------------------- Interaction of the skills "patch" with older code is minimized. below is an outline of how skills/exp code impinges on older CF code (did I miss anything here??)): -- in apply() and apply_special() changes were made to allow the use of skill "tools" and to better handle the readying of combat weapons (swords, bows, etc). -- in hit_player() changes made to allow skills control attacking. -- cosmetic changes (as in c_object.c to make pick_up() routine monster friendly) Changes in c_wiz.c, input.c fall into this category. -- new commands are inserted into the code 'skills' and 'use_skills'. -- In init() init_new_exp_system() is called. Linking of exp objects/skills is done here. -- add_exp() was rewritten to accommodate changes needed. new add_exp() is called from all same locations as before, plus it is called by do_skill(). See calc_skill_exp() in skills_util.c for details of how experience is calculated in skill use. -- fix_player() changed to allow skills to affect player/monster status. -- skill_attack() is called by hit_player(). -- do_skill() is called from fire(). This is the core routine for the use of skills. Only other way to use skills is by player undertaking an action requiring a skill (a "key" skill). These are currently: (unimplemented skills in parenthesis) action skill(s) auto-readied Notes ------ --------------------- ---------------------- combat - hand_weapons, Occurs when player: missile_weapons. 1. readies a weapon 2. runs into opponent *and* has ready weapon wand/rod/horn- use magic item Occurs when player zaps approprite item. magic use - spellcasting, Occurs when player (praying) attempts to cast a spell of appropriate nature rod/horn/wand - (magic item use) Occurs when player use uses wand/rod/horn. In all of these cases, skills are used merely as "keys" needed by the player in order to perform an action. For example, if a player doesn't have "spellcasting", they are unable to cast spells. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& DESIGNER'S NOTES - more nitty gritty &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& I have just taken the objectives from the crossfire proposal I made earlier. Each is discussed one-by-one: > Part B - Multiple experience categories > -------- > B1 - Multiple categories in which a player may gain experience. Experience objects owned by the player are not directly viewed. The "skills" command does give some information. > B3 - Each experience category will have an associated stat(s)- There must exist an experience category with Str and Int set. Otherwise, no wc, or sp will be gained after 1st level. Multiple Str, Int experience objects could exist, but will only accelerate player wc, sp gains. > B4 - Wc, hp and dam will become related to the appropriate Right now hp are related to the player "score" which is the total of all player experience. > Part C - Skills > -------- > C1 - Two kinds of skills will be available: "associated" skills Implemented. Seems to work well. > C2 - Skills will be objects in the character inventory. These Implemented. Seems to work well. > C3 - experience will be now only be gained through the use of > skills associated to one of the categories of experience. Implemented. Seems to work well. > C4 - Both NPC and players will be able to use skills. Implemented. Seems to work well. > C5 - Players will be able to learn skills by reading scrolls of Fixed a minor bug in this. General background note on why experience objects change stats from Brian Thomas, Aug 20, 1997: Nope. Stats are used by experience objects to 'tag' the category of experience, ie "physique" exp objects have Str 1 "wisdom" exp object have Wis 1 There shouldnt be an increase in the stat in question. [ now for a bit of explaination, longish...] This setup seems a bit arcane I know..so why this way? Why not hardcode the experience archetypes, eg have type EXP_FIGHTING, EXP_MAGIC, and so on? Well... at the time I did this, there was some debate about what experience system was the best, as some ppl wanted to have only 4 instead of 6 categories, and so on .. (*sigh*). In the attempt to make the experience system as flexible as possible, I coded the experience 'categories' to be defined by the archetypes and using various stats to differentiate them. Properities of the experience categories are set by the stat(s) they have defined. To my knowledge the stats have the following properties: str --> gains experience, from fighting con --> controls hp progression somewhat (if a define in living.c is set). dex --> gains exp from agility skills wis --> gains exp from priest skills, effects grace calculation int --> gain exp from mental skills cha --> gain exp from personality skills pow --> gain exp from wizard skills, effects mana calc. So, If you didnt like the current 6 experience catagories and wanted only 3 for your server, say "fighting" "presense" and "holyness" you could remove all of the old experience archetypes and define the following new ones: Name Properties Explaination fighting Str 1, Con 1, Dex 1 Combines old physique, agility exp presence Pow 1, Cha 1 Combines old magic, personality exp holyness Wis 1 same as old wisdom exp So, every player on this server would only see 3 types of experience to be gained. If you fight or steal something, then experience points go to the "fighting" category. And note, since we DIDNT design an arch with Int 1, there will be NO experience gained for use of mental skills (at least in theory this should be the case. I dont recogmend leaving out a stat, eg you should have a every stat covered between all of your new experience archetypes). Even though I wrote a doc to help explain how to do this, probably nobody but me (or maybe Peter) really is knowledgeable enough (and has the desire) to reconfigure the game experience to suit their individual tastes. This might be some code we could 'simplify' (heh, remove it).