/*** Template Spell ***/
/*** By Wonderflug ***/
#define SP_NAME "Template"
#define SPHERE "womble"
#define LEVEL 1
#define GP_COST LEVEL*2
#define TYPE "laughter"
inherit "/std/spells/patch.c";
/* help function */
string help()
{
return "\n\n"
"Spell Name: " SP_NAME "\n"
"Sphere: " SPHERE "\n"
"Level: "+LEVEL+"\n"
"Gp Cost: "+GP_COST+"\n"
"Damage Type: " TYPE "\n"
"Description: \n"
" This spell is buggy. The creator who made it is an idiot and "
"forgot to customize the help file. Laugh at them real hard.\n\n";
}
/* Prototype */
mixed spell(string str, object caster, int cast);
/* If this is cast by an NPC, cast will be the NPC casting it. Otherwise
* it will be 0.
* str is the argument string, ie, targets as typed by the player.
*/
int cast_spell(string str, object cast)
{
mixed ret;
object caster;
if(cast)
caster = cast;
else
{
/* The caster is a player, and the target string may contain nicknames
* which need expansion to their definitions prior to using them.
*/
caster = this_player();
str = caster->expand_nickname(str);
}
/* Cast the spell. Will return a string if there's an error; otherwise
* assume success. Note we call with a 1 to indicate the spell is being
* cast. This way creators can do the same call with a 0 and have the
* messages/gp requirements suppressed.
*/
ret = spell(str, caster, 1);
if (stringp(ret))
{
notify_fail(ret);
return 0;
}
tell_object(caster,"You start to cast " SP_NAME ".\n");
tell_room(environment(caster),caster->query_cap_name()+" begins to cast "
"a spell.\n", caster);
return 1;
}
/* This is just for convenience. Checks that should be done each
* round of casting/in multiple places should go in this function.
*/
mixed do_checks(string str, object caster, int cast)
{
/* Find the targets. Note that this should be repeated on each stage
* of the spell, if the effects are not instantaneous. Some of course
* may only need to check targets at the end. (eg a spell hitting everything
* in the room) At any rate, delete one of these before use :)
*/
/* This is the first way. A single target. */
ob = find_one_match(str, environment(caster));
if (sizeof(ob))
ob = ob[0];
else
return "You don't see your target here.\n";
/* This is the second way. Multiple targets. */
ob = find_unique_match(str, environment(caster));
if ( !sizeof(ob) || !ob )
return "You don't see your target here.";
/* Check if targets are living here. */
/* Check they have enough gp still. This also must be done each
* round of casting. We don't deduct GP til later though.
* Note if we have sphere based GP cost this check is inaccurate.
*/
if (cast && (int)caster->query_gp() < GP_COST )
return "You lack the power to cast this spell.\n";
else caster->adjust_gp(-GP_COST);
return ob;
}
mixed spell(string str, object caster, int cast)
{
mixed ob;
/* Can only cast one spell from a given sphere/school at a time */
if ((int)caster->query_spell_effect(SPHERE))
return "You are already casting a " SPHERE " spell.\n";
/* Do error checks; if we don't get a string we get the objects */
if ( stringp( ob=do_checks(str, caster, cast) ) )
return ob;
/* Do the spell effects here and delete the following lines, or add
* a casting delay and modify the following lines.
*/
caster->add_spell_effect(number of rounds to cast, SPHERE, SP_NAME,
this_object(), "hb_spell", ({ str, cast, ob, any other params you need }));
return 1;
}
/* If using add_spell_effect, this function will get called each round
* for the number of rounds you specified. caster is the object casting the
* spell; params is that last parameter you passed to add_spell_effect
* exactly how you passed it, and time is the number of rounds remaining
* in the effect. eg, if we specified 3 in add_spell_effect, this would
* get called successively with 3, 2, and 1 as the third parameter.
* NOTE: Always return low numbers (preferably zero) from these spell
* heartbeats-- the return value gets added to the player as xp.
*/
int hb_spell(object caster, mixed *params, int time)
{
mixed ob;
int cost;
/* Add/delete from this as necessary. Note we only do tell_room's if
* the spell was cast, ie, params[1] is nonzero
*/
switch( time )
{
case 4:
if ( stringp( ob=do_checks(params[0], caster, params[1]) ) )
{
tell_object(caster, ob);
if ( params[1] )
tell_room(environment(caster), caster->query_cap_name()+" stops casting.\n",
caster);
}
/* effects (messages) during 1st round of casting */
return 0;
case 3:
if ( stringp( ob=do_checks(params[0], caster, params[1]) ) )
{
tell_object(caster, ob);
if ( params[1] )
tell_room(environment(caster), caster->query_cap_name()+" stops casting.\n",
caster);
}
/* effects (messages) during 2nd round of casting */
return 0;
case 2:
if ( stringp( ob=do_checks(params[0], caster, params[1]) ) )
{
tell_object(caster, ob);
if ( params[1] )
tell_room(environment(caster), caster->query_cap_name()+" stops casting.\n",
caster);
}
/* effects (messages) during 3rd round of casting */
return 0;
default:
break;
}
if ( stringp( ob=do_checks(params[0], caster, params[1]) ) )
{
tell_object(caster, ob);
tell_room(environment(caster), caster->query_cap_name()+" stops casting.\n",
caster);
}
/* may want to alter below, based on sphere; if so
* move the check to after the sphere code
*/
cost = GP_COST;
if ( params[1] && caster->adjust_gp(-cost) < 0 )
{
tell_object(caster, "You are too exhausted to complete the spell.\n");
tell_room(environment(caster, caster->query_cap_name()+
" stops casting.\n", caster);
}
/* Effects of the spell go here. At this point, params[0] is the
* original target string, params[1] is whether it was cast as a spell
* or not, params[2] is the original matched targets, further params
* are as you added to the add_spell_effects call; ob contains the targets
* currently in the room. Yes, 3 sets of effects for different sphere
* powers.
*/
switch( caster->query_sphere_power(SPHERE) )
{
case "minor":
break;
case "major":
break;
default:
break;
}
if ( params[1] ) /* if cast as a spell */
{
/* Any casting specific messages go here. */
}
/* Noncasting specific messages go here. */
return 0;
}