From the NannyMUD documentation

LAST CHANGE

2000-12-16

NAME

        simple_wand - A generic magic wand.

INHERITS

/std/basic_thing

FUNCTIONS

QUERY FUNCTIONS

	query_charges  - the number of charges remaining
	query_magic    - returns 1.
	query_readied  - returns the object readying the item
	is_stdwand     - returns 1.

SETUP FUNCTIONS

	set_charges    - set the number of charges the item has (see below)
	add_charges    - interface to set_charges

OTHER FUNCTIONS

	charge_desc    - add info about charges to the item's desc
	command_desc   - add info about commands to the item's desc
	wand_cmd       - add a command to this item which uses charges
        do_damage      - do damage in a standardized wand sort of way
        get_target     - get a target for the wand
        allowed_combat - check if the combat is allowed (see below)
	do_ready       - ready the item
	do_unready     - unready the item
	query_value    - the item can have a per-charge value
	short          - may have the text " (readied)" tacked on to the end
	do_cmd         - the 'unready' and 'ready' verbs are added here
	reset          - the item's charges can be reset in reset(1)
	remote_prevent_ready
	remote_do_ready
	remote_prevent_unready
	remote_do_unready
	remote_fail_message
	remote_prevent_wand
	remote_do_fail
	remote_do_wand

PROPERTIES

INTERNAL PROPERTIES


NAME

        Internal properties. - Various internal properties.

DESCRIPTION

	max_charge - the max number of charges for the item; optional
	value_per_charge - the additional gold piece value per charge
	no_allow_ready - don't allow people to ready the item
	silently_ready - don't do a message when the item is readied
	silently_unready - don't do a message when the item is unreadied
	required_ready - people must ready the item to use its magic
	no_busy - using this item does not check busy
	cost_busy - valued prop-- busy time for usage, in heartbeats
	charges_per_fail - the number of charges a fizzle costs
	charges_per_use - the number of charges a successful use costs
	reset_charge - reset charges to the value of max_charge on reset
	mess_reset_charge - print a message when charges reset
	sp_cost_recharge - the approximate sp cost that adding one charge
	                   to the wand at a recharger should cost a player
	gp_cost_recharge - the approximate gp cost that adding one charge
	                   to the wand at a recharger should cost a player
	no_count_charge - see charge_desc
	mess_worn_out - see charge_desc
	no_worn_out - see charge_desc
	worn_out_command - see command_desc
	mess_command - see command_desc
	verb_command - see command_desc
	chance_fail - see wand_cmd
	range_fail - see wand_cmd
	base_fail - see wand_cmd

DESCRIPTION

        This object is intended to be used for generic 'magic items'
	object which uses charges, such as wands (or even multiple-use
	scrolls).

NOTE

	This object is designed for charged magical items only.
	While it is technically possible to use it for a nonmagical
	item like a crossbow, this is not recommended.

FUNCTION


NAME

        set_charges - Set the number of charges in the item.

SYNTAX

	void set_charges(int amount);

DESCRIPTION

	This function sets the number of charges currently in the item.
	There are sanity checks so that there may never be less than 0
	charges, and if the property max_charge is used, never more
	than that amount.

FUNCTION


NAME

        add_charges - Add or subtract charges from the item.

SYNTAX

	void add_charges(int amount);

DESCRIPTION

	This is a shortcut function.  It is the same as:
		set_charges(query_charges() + amount);

FUNCTION


NAME

        charge_desc - Function used by eval to get a desc about charges.

SYNTAX

	string charge_desc(string s);

DESCRIPTION

	This is an interface function used by eval to generate a
	portion of a description (usually the long description)
	related to the number of charges remaining in the item.
	The argument to charge_desc is itself passed through
	eval; see the examples below.
	If there are no newlines in a non-eval()uated desc, then
	charge_desc() will automatically linebreak it at 77 columns.
	(the same as used by set_long() and add_item() in /std/basic)
	charge_desc() makes use of the following properties:
	* max_charge: If this has a value greater than zero,
	  the the desc will compare the current charges to
	  the value of max_charge, unless no_count_charge is set.
	* no_count_charge: If this is set, the current charges are
	  not compared to the max charges by charge_desc()
	* mess_worn_out: If max_charge is set, this is used instead
	  of the default 'worn out' message, which is:
	  "It looks a little worn out.\n"
	* no_worn_out: if no_count_charge is set, mess_worn_out is
	  still used unless no_worn_out is set.

EXAMPLE

	set_long("@charge_desc(This is a wand of lightning.)");
	set_long("@command_desc(@charge_desc(This is a wand of lightning.)");
	set_long("@command_desc(@charge_desc(@handle_long()))");

FUNCTION


NAME

        command_desc - Add an item's activation command to the desc.

SYNTAX

	string command_desc(string s);

DESCRIPTION

	This function is very similar to charge_desc, the only thing
	different is that instead of talking about charges, this talks
	about the item's activation command.
	Note that the command_desc addons are only printed if the item
	has charges remaining.  It is possible to override this
	behavior with add_property("worn_out_command").
	command_desc() checks the following properties:
	* worn_out_command: Print the command_desc() extras even if
	  the item is out of charges.
	* mess_command: Print the value of this property as the only
	  extra command_desc adds on.
	* verb_command: If mess_command is not set, and you do:
	    add_property("verb_command","zzap");
	  Then the text "Use it with 'zzap'.\n" will be added on to
	  the base description by command_desc().

EXAMPLE

	add_property("mess_command",
	  "You can wave this wand at your foe.\n");
	add_property("verb_command","Use it with 'zzap'.\n");
	set_long("@command_desc(@charge_desc(This is a wand of lightning.))");
	set_long("@command_desc(This is a wand of lightning.))");

NOTE

	If you use command_desc() without setting the either
	mess_command or verb_command, all you will do is reduce the
	efficiency of your set_long(), add_item(), or whatever.

FUNCTION


NAME

        do_ready - Ready the item.

SYNTAX

	varargs int do_ready(int silently);

DESCRIPTION

	This is an internal function, which can be called by code,
	and is also called when the player types 'ready '.
	It only works (and in fact, the player only gets the verbs
	'ready' and 'unready' if the item does not have the property
	no_allow_ready set.

	It calls the following remote functions (described below).
	* remote_prevent_ready
	* remote_do_ready

	If a false argument was passed to do_ready(), no message will
	be printed when the player readies the item.
	Attempting to ready an item causes the player to make an
	implicit attempt to unready any other readied item.

RETURN VALUES

	-1: the item was already readied, or cannot be readied.
	0: we failed to ready the item for some reason
	1: we successfully readied the item.

NOTE

	Readiable items are items where is_stdwand() or
	query_generic_wand() return 1.
	query_generic_wand is only checked for compatibility; the
	pre-std generic wands have this instead of is_stdwand().

FUNCTION


NAME

        do_unready - Unready the item.

SYNTAX

	varargs int do_unready(int silently);

DESCRIPTION

	This function is the inverse of remote_do_ready.
	It unreadies the item.  This can be done either by the owner
	using the 'unready' verb (see do_cmd), by code from another
	object, by the owner readying a different simple_wand
	object, or by drop() being called in the item.

	It checks the remote_prevent_unready and remote_do_unready
	functions (see below).

RETURN VALUES

	-1: the item was not readied.
	0: we failed to unready the item for some reason
	1: we successfully unreadied the item.

FUNCTION


NAME

        do_cmd - Link the 'ready' and 'unready' verbs.

DESCRIPTION

	This internal function adds the verbs 'ready' and 'unready'
	to any living carrying the item.  The only time this does not
	happen is when the no_allow_ready property is set.
	In the 'ready' command, when the player attempts to ready the
	item, do_ready() is called.  It's called silently if the
	property "silently_ready" is set.
	Likewise, the 'unready' command checks "silently_unready".

	The 'unready' command will attempt to unready the item even
	if no argument is supplied, so while you might have to do
	'ready wand' to ready an item, you can unready it just by
	typing 'unready' with no arguments.

NOTE

	If you use add_command() or add_item_cmd() on the verbs
	ready or unready, you will override the default verbs.

FUNCTION


NAME

        wand_cmd - A support function for an 'item use' command.

SYNTAX

	int wand_cmd(string eval_arg,string user_typed_arg)

DESCRIPTION

	This function should never be called directly, rather it
	should be called using eval().
	It's the driving function in the simple_wand.

	Before actually consuming charges or setting busy or doing
	the item effect, the following checks are done:
	* Is the item carried by the player?
	* Is the player alive (non-ghost)?
        * Is the item readied? Does it need to be readied?
	* Is this a no_magic room?
	* Does the remote object wish to block the command?
	* If the item checks busy, is the player busy?
	* Does the item have any charges remaining?
	* Is there an inherent chance for the item to fail? Will it?

	Finally, the 'use item' function may occur.  If success is
	returned here (from execution of the remote_do_wand remote
	function), then charges are decremented and busy is set.

	This function calls several remote functions and checks a
	large number of properties.
	The remote functions are:
	* remote_fail_message - print nonstandard failure messages
	* remote_prevent_wand - block the player from using the item
	* remote_do_fail - executed if the item 'fizzles'
	* remote_do_wand - your special code is executed here
	The properties in the simple_wand which are checked are:
	* required_ready - must we ready the item to use it?
	* no_busy - this item should not use busy time
	* cost_busy - a valued property-- the busytime in heartbeats
	* chance_fail - see just below
	* range_fail - see just below
	* base_fail - see just below
        * charges_per_fail - how many charges does a fizzle cost?
	* charges_per_use - how many charges does a use cost?

	The code for a 'fizzle' is as follows:
	A fizzle happens if chance_fail is greater than the sum of
	random(query_property("range_fail")) and
	query_property("base_fail").
	range_fail defaults to a value of 100, and base_fail defaults
	to a value of 1.
	It is important to note that a fizzle sets busy in the user.

EXAMPLE

	add_command("wave wand","@wand_cmd()");
	add_command("zzap %s","@wand_cmd()");

NOTE

	If a successful use of the item costs more than one charge,
	and the item only has one charge left, the player will be
	able to use the item one last time unless you check this
	yourself in remote_prevent_wand.

NOTE

	If you do something like:
	  add_command("zzap %s","@wand_cmd(lightning)");
	Then in all the wand_cmd() and all the remote functions, it
	calls, then the value of the variable eval_arg will be
	"lightning".

FUNCTION


NAME

        get_target - Get a target for the item.

SYNTAX

	varargs object get_target(string name_of_target,
                                  object player,
                                  int noncombat);

DESCRIPTION

	This support function (intended for use by remote_do_wand)
	returns a living (but not necessarily non-dead/non-ghost)
	target.  The target returned is guaranteed to be in the same
	room as the player.
	If no player is specified in the argument, the player defaults
	to the environment of the item.
	If no name_of_target is specified, then one of two things
	can happen:
	* If the noncombat flag was given (as non-zero), then the
	  player himself is returned.
	* Otherwise, whatever the player is currently attacking, if
	  anything, is returned.
	Otherwise, name_of_target is checked.
	If the first letter in name_of_target is a capital letter,
	then the target is assumed to be a player only.
	Otherwise, it may be either a player or an NPC.

EXAMPLE

	object o;
	o = get_target(s);
	if(!objectp(o))
	{
	  notify_fail("Fireball who?\n");
	  return 0;
	}

	object o;
	o = get_target(s,environment(wand),1);
	if(!objectp(o))
	{
	  notify_fail("Heal who?\n");
	  return 0;
	}

NOTE

	The noncombat flag and the player are both optional arguments,
	but while the name_of_target may have a zero value, it should
	be passed as an argument.

FUNCTION


NAME

        allowed_combat - Is combat allowed between these two?

SYNTAX

	varargs int allowed_combat(object target[,object player]);

DESCRIPTION

	Like transfer(), this function returns a zero value on success
	and different non-zero values explaining why the combat was
	not allowed.  This is a quick way of handling all the checks;
	instead, all you have to do is set an error message and
	return zero (although it is recommended you return 1 on case 5
	so that a charge is deducted from the wand-- remember to
	call target->attacked_by(player) if you do this, though.)
	It is recommended that you do not set the same error message
	for all five non-zero return values, as this could become
	confusing to the player.  Particularly, you should set
	special messages for values 1 and 5.

EXAMPLE

	switch(allowed_attack(target))
	{
	  case 1:
	    notify_fail("The wand won't allow itself to be used here.\n");
	    return 0;
	  case 2..4:
	    notify_fail("You are not allowed to attack that target.\n");
	    return 0;
	  case 5:
	    "/std/msg"->msg("\bPRON zap\b$ a lightning bolt on \b2PRON,\n" +
	      "but it is reflected.\n",this_player(),target);
	    target->attacked_by(this_player());
	    return 1;
	}

RETURN VALUES

	0: combat is allowed
	1: the environment is no_fight
	2: the player targetted himself
	3: the target is dead or a ghost.
	4: the player is not allowed to kill the target according to
	   player->attack_allowed(target);
	   Note that in the case a message is automatically printed.
	5: the target has protection_magic set, and should therefore
	   be immune to effects that check no_magic (done earlier).

NOTE

	If no player is specified, then it defaults to the item's
	environment.

	The order that things are checked is the same as the order of
	the return values (with the exception of 0).  So no_fight will
	be checked in the room before attack_allowed() is called in the
	room.  If you wish to change this order, you will have to
	check each of these things manually.

FUNCTION


NAME

        do_damage - Use the item to deal damage.

SYNTAX

	varargs void do_damage(string msg,
	                       object target,
	                       int random_damage,
	                       string type,
	                       /* optional */ int extra_damage,
	                       /* optional */ object player);

DESCRIPTION

	This object uses the item to deal damage to the target.
	The player receives one experience point for each point of
	damage dealt.
	The damage dealt is: random(random_damage) + 1 + xdam.
	The message is sent through /std/msg, the player is
	\b1, the target is \b2.

NOTE

	If the player is not specified, it defaults to the environment
	of the item.

	Remember to perform all the appropriate checks before you
	call this function.

	attacked_by is called in the target, but not in the player.

FUNCTION


NAME

        reset - Reset the item.

DESCRIPTION

	The reset function in the item checks three properties.
	If max_charge is set, and reset_charge is set, the item's
	charges are reset to the value of max_charge in reset(1) if
	the wand is not already fully charged.  Whenever this
	recharge happens, the mess_reset_charge property is checked.
	If this has a string value, that is printed to the item's
	environment by tell_object.  Otherwise, if the property is
	set, a default message about how the item glows softly is
	printed.

NOTE

	This feature will only work if you remember to call
	::reset(arg); in the reset of your item.

FUNCTION


NAME

        remote_prevent_ready - 

SYNTAX

	int remote_prevent_ready(object item,object owner,int silently);

DESCRIPTION

	These remote functions are called from do_ready() and
	do_unready() respectively.  If the silently argument has a
	nonzero value, it means that the remote functions should
	print no messages.

RETURN VALUES

	For remote_prevent_*, a return value of 1 prevents the action
	from happening.

FUNCTION


NAME

        remote_do_ready - 

SYNTAX

	void remote_do_ready(object item,object owner,int silently);

DESCRIPTION

	See the description of remote_prevent_ready.

FUNCTION


NAME

        remote_prevent_unready - 

SYNTAX

	int remote_prevent_unready(object item,object owner,int silently);

DESCRIPTION

	See the description of remote_prevent_ready.

FUNCTION


NAME

        remote_do_unready - 

SYNTAX

	void remote_do_unready(object item,object owner,int silently);

DESCRIPTION

	See the description of remote_prevent_ready.

FUNCTION


NAME

        remote_fail_message - Print nonstandard failure messages.

SYNTAX

	int remote_fail_message(string type,
                                string user_typed_arg,
                                object item,
                                string eval_arg);

DESCRIPTION

	This function is used to override the default failure
	messages used by wand_cmd().  The following types are valid
	for the first argument; following them is the default.
        * ghost - notify_fail("You can't use the " + query_name() +
                              " in your immaterial state.\n");
        * unready - notify_fail("You have to ready this item to use it.\n");
        * no_magic - notify_fail("The " + query_name() +
                                 " doesn't do a thing.\n");
        * busy - notify_fail("The " + query_name() + " isn't ready yet.\n");
        * no_charge - notify_fail("Nothing happens.\n");
        * fail - write("The " + query_name() +
                       " sputters as you invoke it, but does\n" +
                       "nothing.  The charge is wasted.\n");
        * do_wand - Nothing.  This is a special case, the notify_fail
	  should have already been set by remote_do_wand().

	If you wish to set a notify_fail or print a message instead
	of the default occuring, you should do so and then return 1.

RETURN VALUES

	0: set the default failure message for this type, either by
	   notify_fail or by write().
	1: do not set or print any failure message, it has been
	   taken care of by this function

FUNCTION


NAME

        remote_do_fail - 

SYNTAX

	int remote_do_fail(string user_typed_arg,
	                   object item,
	                   string eval_arg);

DESCRIPTION

	0: deduct charges for a fizzle, as normal.
	1: do not deduct any charges for this fizzle.

FUNCTION


NAME

        remote_prevent_wand - 

SYNTAX

	int remote_prevent_wand(string user_typed_arg,
	                        object item,
	                        string eval_arg);

DESCRIPTION

	0: continue on
	1: block the item use from occuring- we set an error message

FUNCTION


NAME

        remote_do_wand - 

SYNTAX

	int remote_do_wand(string user_typed_arg,
	                   object item,
	                   string eval_arg);

DESCRIPTION

	0: The use failed, don't deduct charges or set busy.
	   We set an error message.
	1: The use succeeded.  Deduct charges and set busy.