attributes-old

concepts
CONCEPT
	attributes, abilities and spells


LAST UPDATE
	Mateese, 20-Dec-92 01:30 MET


DESCRIPTION
	Attributes describe the physical and mental abilites of a
	living. In the broader meaning which is used here, they also
	include non-magical profiencies and magical skills.

	The magical skills are included since they from a basic aspect
	of life in such an non-technological environment as Nightfall.


	Attributes are defined by name and associated data.
	This data is mostly a simple integer, but may take any complex
	form needed.

	The standard names and structures are defined in
	/sys/attributes.h 


	Every attribute can be set or queried using:

	mixed QueryAttribute (string name)
	mixed SetAttribute (string name, mixed data)


	The simplest attributes have an instant effect on the livings
	behaviour - they are called 'hardcoded attributes' or simply
	'stats'. They can be accessed like normal properties, e.g.
	querying the stat 'Str' is done by 'QueryStr()', though
	'QueryAttribute (AT_STR)' has the same result.

	The set of all 'stats' at once can be handled as an alist via

	mixed *QueryStats ()
	mixed *SetStats ()

	
	All other attributes have only indirect effects on the living,
	since they are in general not evaluated by the living on its
	own. They are called 'softcoded attributes' or just
	'attributes'.
	They can be handled all at once as an alist via

	mixed *QueryAttributes ()
	mixed *SetAttributes ()


	Players have an extra list for boni/mali on stats and
	attributes. These are taken into account when the stats are
	changed to balance intrinsic race aspects with guild
	membership aspects.

	mixed *QueryBoni ()
	mixed *SetBoni (mixed *boni)
	  Sets or queries the list of boni.

	mixed QueryBonus (string name)
	void SetBonus (string name, mixed data)
	  Sets or queries a single bonus.

	void AddBonus (string name, int diff)
	  Add <diff> to the current value of bonus <name> (it must be
	  of integer type).

	Note that changing any bonus does not change the associated
	attribute.
	
	
	Abilities are a special sort of attributes, which describe a
	level of knowledge in a specific matter. The special thing is
	that the knowledge may be increased, either by training or by
	using the ability. On the other hand, not using the ability
	over a long time leads to a lossage in knowledge.

	Abilities are described using an array of:
        ({
	  int AD_TYPE;      a marker
	  int AD_LEVEL;     the knowledge level
	  int AD_MIN;       the minimal knowledge
	  int AD_MAX;       the maximal knowledge
	  int AD_LEARN;     the learning factor
	  int AD_UNLEARN;   the unlearning factor
	  string AD_DESC;   a descriptional string
	  mixed AD_OBJECT;  an optional ability object
	  mixed AD_DATA;    optional additional data
        })

	AD_TYPE is one of the values ADT_xxx and serves as a flag that
	the array describes an ability. Normal abilites are of type
	ADT_ABIL.
	AD_DESC is a string containing a description of the ability.
	It can be empty.
	All other numeric values are given in permille (0..1000).
	The learn factors give the shrinking of the distance between
	the LEVEL and the MAX (MIN) with every use (unuse) of the
	ability. Example:
	
	  LEVEL   = 200
	  MIN     = 100
	  MAX     = 750
	  LEARN   = 200
	  UNLEARN = 500

	  The living knows the ability with 20%. If it now uses it,
	  the level grows by 20% of the remaining difference to the
	  MAX, giving a new level of:
            new LEVEL = 20% + (75% - 20%) * 20% = 20% + 55% * 20%
                      = 31%

	  Similar for the unlearning, if the ability is not used for
	  long time:
            new LEVEL = 20% - (20% - 10%) * 50% = 20% - 10% * 50%
                      = 15%

	This way the nonlineary learning of 'real' livings can be
	modeled. Currently, every reset() (approx. once an hour) every
	ability is unlearned once.

	In AD_OBJECT an optional object can be specified as string or
	as object. It has to implement at least the functions:
	
	int check (string name, mixed *data, int chance)
	  The ability <name> with the given <data>set is queried and
	  its AD_LEVEL has to be returned.
	  If <chance> is defined and not zero, the AD_LEVEL is to be
	  compared against <chance>-1, and zero has to be returned if
	  AD_LEVEL is lower.

	int use (string name, mixed *data, int chance)	
	  The ability <name> with the given <data> set is queried and
	  learned, and its AD_LEVEL has to be returned.
	  If <chance> is defined and not zero, the AD_LEVEL is to be
	  compared against <chance>-1, and zero has to bereturned if
	  AD_LEVEL is lower.
	  Note that this call also has to do the learning (and
	  updating of <data> in the living) - it should use the
	  living's function DoLearn() to perform it.

	string *info (string name, mixed *data)
	  Return a short string with additional information from
	  data[AD_DATA]. The string mustn't end in "." or "\n".
	  This function is optional.

	string *desc (string name, mixed *data)
	  Return a string describing the ability. This function is
	  optional, any non-zero result supercedes data[AD_DESC].

	The living offers six functions to deal with abilities:

	mixed *DoLearn (mixed *data, void|string name)
	  The given <data>set for an ability is modified for one
	  learning as defined by AD_LEARN.
	  If <name> is defined and not zero, the new <data>set is
	  also updated into the living's attribute-list.

	mixed *UndoLearn (mixed *data)
	  The given <data>set for an ability is modified to neutralize
	  one learning as defined by AD_LEARN.
	  If <name> is defined and not zero, the new <data>set is
	  also updated into the living's attribute-list.

	mixed *UndoUnlearn (mixed *data)
	  The given <data>set for an ability is modified to neutralize
	  one unlearning as defined by AD_UNLEARN.
	  If <name> is defined and not zero, the new <data>set is
	  also updated into the living's attribute-list.

	int CheckAbility (string name, void | int chance)
	  The ability <name> is queried and its AD_LEVEL returned.
	  If defined, AD_OBJECT is called (see check()).
	  If <chance> is defined and not zero, the AD_LEVEL is
	  compared against <chance>-1, and zero is returned if
	  AD_LEVEL is lower.

	int UseAbility (string name, void | int chance)
	  The ability <name> is queried and learned, and its AD_LEVEL
	  returned. If defined, AD_OBJECT is called (see use()).
	  If <chance> is defined and not zero, the AD_LEVEL is
	  compared against <chance>-1, and zero is returned if
	  AD_LEVEL is lower.


	Players can do a bit more with abilities: they can 'use' and
	'train' them additionally. This allows the easy implemention
	of abilites which combine a knowledge with an action.

	For this, the ability must define an AD_OBJECT with two
	additional functions, which are called if the player issues
	the commands 'use <ability> [<args>]'
        or 'train <ability> [<args>]': 

	int Use (string name, string arg, mixed *data)
	  Use the ability <name>.

	int Train (string name, string arg, mixed *data)
	  Train the ability <name>.

	  <arg> are any additional arguments from the commandline (may
	  be 0 or empty), <data> the abilitie's <data>set.
	  It's the object's task to output any messages.
	  The functions have to return zero if the call fails.


	Spells are a special form of abilites with a defined
	spell-object AD_OBJECT	(AD_TYPE has value ADT_SPELL), and
	defined only for players.

	Spells normally can't be 'used' or 'trained', but instead are
	'casted', 'studied' and 'practised'.

	Therefore the spell-object has to implement the
	additional functions:

	int Cast (string name, string arg, mixed *data)
	  Start casting the spell <name>.

	int Study (string name, string arg, mixed *data)
	int Practise (string name, string arg, mixed *data)
	  Study or practise the spell <name>.

	  <arg> are any additional arguments from the commandline (may
	  be 0 or empty), <data> the abilitie's <data>set.
	  It's the object's task to output any messages.
	  The functions have to return zero if the call fails.

	The difference between 'normal' abilities and spells is that
	most spells need time to be casted. Within this time the
	player can't fight with normal weapons.

	The casting of a spell can be aborted if the spell allows to.
	Abortion is done either by casting another spell while the
	previous hasn't been completed, or by the 'stop' command.
	Note that abortion need not be possible. 

	The casting itself is done by a casting-object (which needn't
	be identical with the spell-object AD_OBJECT).
	The object is set in the player as the property P_CAST_OBJ
	("CastObj"). 
	This casting object has to implement three functions:

	int CastOn ()
	  This is the function called every heart_beat. It has to
	  count down the casting time and at last trigger the action.
          If it returns zero (as it should in most cases), no physical
          attack can take place in the same heart_beat.

	int StopCast ()
	int AbortCast ()
	  The player wants to stop the cast in progress, either by the
	  command 'stop' (StopCast()) or by casting another spell
	  (AbortCast()).
	  If the stop is possible, remove the cast-object from the player
	  and return non-zero, else just zero.
	  It's the object's task to output approbiate messages.



	The concept of abilities and spells involves that there are
	possibilities to learn these things.
	To easen learning from carryable things (like spells from
	books), the player contains a function implementing the
	command 'learn <what> from <which>'. It searches the <which>
	(which can be a complex description as 'book in knapsack')
	in its inventory and then in its environment, and if the
	object is found, the player calls in the object:

	int Learn (string what)

	The function has to return non-zero for success and output all
	approbiate messages.
	
	This feature needn't be used, but should make life easier.


SEE ALSO
	living(S), races(C), racemaster(O)