racemaster

daemons
OBJECT
	/obj/racemaster
	/obj/raceobj


SYNOPSIS
	#include <config.h>
	#include <races.h>
	#include <attributes.h>

	inherit "/obj/raceobj";
	RACEMASTER->lfun();


LAST UPDATE
	Mateese, 14-Mar-98


DESCRIPTION -- /obj/racemaster.c
	The racemaster is the central server for all race matters.
	It's main task is to provide information about the races, but
	it also contains adjusting/restricting functions.

	In fact, the RACEMASTER (so defined in /sys/config.h) calls
	itself the race-objects for the race specific functions.
	These objects are all descendants of /obj/raceobj and are
	collected in RACEDIR (defined in /sys/races.h), currently
	"/obj/race". 

	string *AllRaceNames()
	  Return an sorted array of the names of all known races.
	  The information is gathered by scanning the RACEDIR.

	object RaceObject (string race, void|object pl)
	  Return the race-object for the given <race> applicable to
	  the player <pl> (default is the current player), else 0.

	mixed *RaceData (string race, void|object pl)
	  Return the data for the given <race> applicable to
	  the player <pl> (default is the current player), or 0 if the
	  race-object can't be found.

	string RaceDescr (string race, void|object pl)
	  Return the descriptional string for the given <race>
	  applicable to the player <pl> (default is the current
	  player), or zero if the race-object can't be found.

	string RacePlural (string race, void|object pl)
	  Return the plural name for the given <race>
	  applicable to the player <pl> (default is the current
	  player).

	The information about one race consists of a long
	descriptional string, which shall serve for help and
	information, and an array containing the important values.
	The RD_NO_ITEMS content indices are defined in /sys/races.h as:

	int    RD_ALIGN     the basic alignment.
	int    RD_FOOD      P_MAX_FOOD
	int    RD_DRINK     P_MAX_DRINK
	int    RD_ALC       P_MAX_ALCOHOL
	int    RD_WEIGHT    the normal weight.
	mixed *RD_HANDS     the P_HANDS 'equipment'.
	int   *RD_DEFENCES  the intrinsic P_DEFENCES, at least ({ 0 })
	string RD_HOME      the default entry point
	string RD_PORTAL    if at RD_HOME is a portal, this is the
	                    counter-room.
	string RD_LONG      the living's long description
	alist  RD_STAT      the stats
	alist  RD_ATTR      the attributes, including skills and spells
	int    RD_SIZE      the comparative P_SIZE
	alist  RD_MAXSTAT   the max values for stats (experimental)
	                    (may be zero if not used).
        mapping RD_EQUIP    the equipment given to the player on login.
	string RD_PLURAL    the plural of the race name. If it can be
			    constructed simply by adding "s", this field
			    may be left 0.

	Concerning the attributes, it is important that the
	'stat'-attributes STR, DEX, INT and CON are given as
	_deviation_ from the human standard. They should be
	equibalanced, though.

	If the _effective_ stat value of a race should be limited to a
	certain amount, it is to be specified in RD_MAXSTAT.

	The RD_LONG description is process_string()ed at the moment it
	is given to a living.
	For nice descriptions, following functions may be used in the
	RD_LONG: 

	string Pl_name()
	string Pl_pro()
	string Pl_poss()
	string Pl_obj()
	  Return the living's name, pronoun, possessive pronoun and
	  objective pronoun, all in lower case.

	string Pl_Name()
	string Pl_Pro()
	string Pl_Poss()
	string Pl_Obj()
	  Return the living's name, pronoun, possessive pronoun and
	  objective pronoun, all in capitalized.


	Changing the race is done with:

	int InitRace (object pl, string race)
	  Sets the <race> of the living <pl>, and also all depending
	  values. 
	  At the end, it calls InitRace(<pl>) in the raceobject.
	  If there is no <race> applicable to <pl>, 0 is returned,
	  else non-zero.

	void RestoreRace (object pl)
	  This restores the unsaved but race dependant values of a
	  <pl>ayer when called directly after relogin.


	The race of a player has its effects on the possible
	attributes: where a human of level <n> might have stats of
	value <n>, an oglon might have a STR of <n>-3, but an INT of
	<n>+2. Furthermore, the player can have boni on several
	attributes, which are not taken into account while balancing.
	Additionally, no stat-attribute can be less than 1.

	The following functions check and balance this:

	int AdvanceCosts (string stat, int base, int delta)
	  Return amount of experience an increase of <stat> from the current
	  value <base> by <delta> has to cost.

	int CheckAdvance (object pl, string stat, int delta)
	  Check if the <pl>ayer has enough experience to advance this <stat>
  	  by the given <delta> value. Returns the costs in experience
	  if advancing is ok, else zero.
	  For now, the function also returns zero if the player ran
	  into a maximum value for its stat.

	int CheckStat (object pl, string stat, int val)
	  Check the given <stat> with value <val> for <pl> according 
	  to it's level and race against the max. allowed value (also
	  regarding a specified MAXSTAT value), and return the lowest of them.

	void AdjustStats (object pl)
	  Adjusts the attributes for <pl>ayer according to it's level
	  and race.


	The player may receive equipment on login, which is done by a
	call to:

	int EquipPlayer (object pl)
	  Equip the player (default: this_player()) with the objects
	  defined in its raceobject. Result is 0 on success and
	  non-zero on failure.
	  The function call for the actual equipping the lfun
	  EquipPlayer() in the raceobject.


	The 'level' of a player is derived from it's experience, and
	should not be mixed with its 'real' level he has in the game.
	It is solely meant for adjusting the attributes.

	int XPtoLevel (int xp)
	  Convert the experience <xp> into the approbiate 'general
	  level'.

	int XPfromLevel (int level)
	  Convert the <level> into the min. experience associated.

	The XP range 0..1000000 is converted into 19 levels, with 1
	MXP being the lower limit for level 19. Of course the function
	also converts higher experiences into higher levels.

	
DESCRIPTION -- /obj/raceobj.c

	The race-object is the object which does the real information
	holding and the more race specific things.
	
	The race-objects are all descendants of "/obj/raceobj" by
	inheritance.

	It defines two variables and query functions:

	static mixed *racedata;
	mixed *RaceData ()
	  The array containing the racial data.

	static string racedesc;
	string RaceDescr (string race)
	  The string containing the race description.

	Additionally, it may implement the function

	void InitRace (object pl)
	  Do extra initialization work for the player <pl>.
	  This function is called after all the data has been set by
	  the racemaster.


	In the create() the racedata is allocated, and the array- and
	alist-values (_HANDS, _DEFENCES, _ATTR) are
	preset to empty arrays/alists. RD_EQUIP is set to the default
	equipment for all players.

	Configuration is done by overloading create().
	The /obj/raceobj offers following functions to make
	configuration easier:

	void SetAlign  (int val)
	void SetFood   (int val)
	void SetDrink  (int val)
	void SetAlc    (int val)
	void SetWeight (int val)
	void SetHome   (string val)
	void SetPortal (string val)
	void SetLong   (string val)
	void SetPlural (string val)
	  These set the corresponding RD_xxx-entry in the array.

	void SetHands (mixed *val)
	  Set RD_HANDS.

	void AddHand (string dsc, int wc, void|int nohand)
	  Add to the already existing RD_HANDS another empty
	  hand with description <dsc> and hand-weapon-class <wc>.
	  If <nohand> is not zero, the hand may be used just as
	  natural weapon.

	void SetDef (int | int *val)
	  Set RD_DEFENCES. 
	  If <val> is no array, it is automatically converted. 

	void AddDef (int | int *val)
	  Add to the already existing RD_DEFENCES some more defences
	  <val>. 
	  If <val> ist no array, it is automatically converted.

	void SetStat  (mixed *val)
	void SetMaxStat  (mixed *val)
	void SetAttr  (mixed *val)
	  Set the alists RD_STAT, RD_ATTR and RD_MAXSTAT.

	void AddStat  (string key, mixed val)
	void AddMaxStat  (string key, mixed val)
	void AddAttr  (string key, mixed val)
	  Add to the already existing alist RD_xxx the new <val> under
	  the given <key>.

	void SetDesc (string s)
	  Set the race description 'racedesc' to <s>.

	void ReadDesc (string s)
	  Set the race description 'racedesc' to the contents of the
	  file <s>.

	void SetEquipment (mapping m)
	  Set the race equipment to the mapping m of width RDE_NO_ITEMS.
	  Each entry in the mapping describes one equipment item,
	  indexed by its main id string.
	  For each item, these data is stored:

	    string  RDE_FILE : the filename of the item to clone.
	      Alternatively, the entry may be a closure which is on need
	      evaluated with the player to equip as argument.
	      The closure has to return the filename of the object to
	      clone or the object itself. If it returns 0, the player
	      will not be equipped with this type of equipment.

	    int     RDE_LEVEL: the XP level up to which the item may be
	      given. 0 means 'every player', -1 means 'every player
	      and wizard'.

	    mapping RDE_PROPS: an additional mapping of properties to
	      be set in the equipment item. It may be 0.
	      A property value may be a closure which is then executed
	      to evaluate the actual value. The player to equip is
	      passed as argument.

	    string * RDE_ALIAS: an array of additional ids to look
	      for when checking the existance of the item. The data may be 0.

	void AddEquipment (string key, string file, int level
	                  , void|mapping props, void|string * alias)
	  Add one item to the RD_EQUIP mapping.

	int EquipPlayer (object pl)
	  Equip the player with the objects defined in RD_EQUIP.
	  Result is 0 on success and non-zero on failure.
	  The function will walk through the items given in RD_EQUIP
	  and clone all those which the player not yet owns (given
	  that he is of low enough level).

SEE ALSO
	attributes(C), light(C), living(S), nightday(C), races(C)