com/cast.c and help/cast - examples for course 06

[previous example] [course06] [Table of contents] [next example]
/* Filename      : cast.c
 * Description   : command 'cast'
 *
 * written       : 03-10-1996 - Gunner
 * last modified : 27-05-1998 - Gunner
 * HTML-Version  : 02-02-2000 - Ghorwin
 */

#include <mudlib.h>
#include <colours.h>
#include "/doc/crashcourse/defs.h"
inherit I_COMMAND;

#define BASE_DAMAGE 50

string
query_action()
{
    return "cast";
}

string
short_help()
{
    return "A cast command which can cast several different spells.\n";
}

string
help()
{
    return HELPDIR+"cast";          // Defined in defs.h
}

string*
query_spells()
{
    return ({"fireball","snowball","lightning bolt","electric storm"});
}

int
query_damage(string spell)
{
    int damage = BASE_DAMAGE;       // Init value
    switch (spell)
    {
        case "fireball"         : damage = BASE_DAMAGE + random(20); break;
        case "snowball"         : damage = BASE_DAMAGE + random(10); break;
        case "lightning bolt"   : damage = BASE_DAMAGE + random(50); break;
        case "electric storm"   : damage = BASE_DAMAGE + random(30); break;
    }
    return damage;
}

string
query_damage_type(string spell)
{
    string damagetype = "blunt";    // Init value
    switch (spell)
    {
        case "fireball"         : damagetype = "fire"; break;
        case "snowball"         : damagetype = "cold"; break;
        case "lightning bolt"   : damagetype = "electricity"; break;
        case "electric storm"   : damagetype = "electricity"; break;
    }
    return damagetype;
}

int
query_cost(string spell)
{
    int cost = BASE_DAMAGE;         // Init value
    switch (spell)
    {
        case "fireball"         : cost = BASE_DAMAGE + 10; break;
        case "snowball"         : cost = BASE_DAMAGE + 5; break;
        case "lightning bolt"   : cost = BASE_DAMAGE + 25; break;
        case "electric storm"   : cost = BASE_DAMAGE + 15; break;
    }
    return cost;
}

/* 
 * fireball : Cast a fireball at attacker 
 */
void
fireball(object att)
{
    tell_object(TP,COL_YH(TP,"You send a ball of fire right at " + 
        Q_NAME(att) + "!\n"));
    tell_object(att,COL_HY(att,Q_NAME(TP) + " sends a ball of fire " +
        "right at you!\n"));
    tell_room(ENV(TP),Q_NAME(TP) + " sends a ball of fire right at " +
        Q_NAME(att) + "!\n",({TP,att}));

    R_SP(TP,query_cost("fireball"));

    att->hit_player(query_damage("fireball"),
        query_damage_type("fireball"),TP);
}

/* 
 * snowball : Cast a Snowball at attacker 
 */
void
snowball(object att)
{
    tell_object(TP,COL_YH(TP,"You send a ball of snow right at " + 
        Q_NAME(att) + "!\n"));
    tell_object(att,COL_HY(att,Q_NAME(TP) + " sends a ball of snow " +
        "right at you!\n"));
    tell_room(ENV(TP),Q_NAME(TP) + " sends a ball of snow right at " +
        Q_NAME(att) + "!\n",({TP,att}));

    R_SP(TP,query_cost("snowball"));

    att->hit_player(query_damage("snowball"),
        query_damage_type("snowball"),TP);
}

/* 
 * lightning_bolt : Cast a lightning bolt at attacker 
 */
void
lightning_bolt(object att)
{
    tell_object(TP,COL_YH(TP,"You send a lightning bolt right at " + 
        Q_NAME(att) + "!\n"));
    tell_object(att,COL_HY(att,Q_NAME(TP) + " sends a lightning bolt " +
        "right at you!\n"));
    tell_room(ENV(TP),Q_NAME(TP) + " sends a lightning bolt right at " +
        Q_NAME(att) + "!\n",({TP,att}));

    R_SP(TP,query_cost("lightning bolt"));

    att->hit_player(query_damage("lightning bolt"),
        query_damage_type("lightning bolt"),TP);
}

/* 
 * electric_storm : Cast an electric storm at all living objects in the room
 */
void
electric_storm(object att)
{
    object *ainv;
    int t;

    ainv = all_inventory(ENV(TP));

    tell_object(TP,"You start conjuring an electric storm...\n");
    tell_object(att,Q_NAME(TP) + " conjures an electric storm...\n");
    tell_room(ENV(TP),Q_NAME(TP) + " conjures an electric storm...\n",
        ({att,TP}));

    for(t=0;t<sizeof(ainv);t++)     // Hurt all living objects in the room
    {
        if (!living(ainv[t]) || ainv[t]->query_property("no_fight"))
            continue;

        // Make sure players can't use it against players
        if (ainv[t] != TP && (interactive(ainv[t]) && interactive(TP)))
            continue;

        tell_object(ainv[t],COL_HY(ainv[t],"The electric storm hits you!\n"));
        tell_room(ENV(TP),"The electric storm hits " + Q_NAME(ainv[t]) +
            "!\n",({ainv[t]}));

        // If we're hitting the player, halve the damage
        if (ainv[t] == TP)
            ainv[t]->hit_player(query_damage("electric storm")/2,
                query_damage_type("electric storm"), TP);
        else
        // If we're hitting someone else, full damage
            ainv[t]->hit_player(query_damage("electric storm"),
                query_damage_type("electric storm"), TP);
    }

    R_SP(TP,query_cost("electric storm"));

    att->hit_player(query_damage("electric storm"),
        query_damage_type("electric storm"),TP);
}

/* 
 * cast_spell : Call the different spell attacks
 */
void
cast_spell(object att, string spell)
{
    switch (spell)
    {
        case "fireball"         : fireball(att);       break;
        case "snowball"         : snowball(att);       break;
        case "lightning bolt"   : lightning_bolt(att); break;
        case "electric storm"   : electric_storm(att); break;
    }
}

/* 
 * main : THE MAIN FUNCTION 
 */
static int
main(string arg)
{
    object who;
    string spell, name;

    who = Q_ATT(TP);

    if (!who && !arg)
        NOT_FAIL("Cast <what> at <who>?\n");    // No attacker and no argument

    if (!who)   // No fighting, have to initiate an attack
    {
        if (sscanf(arg,"%s at %s",spell,name) != 2)
        {
            if (spell && member_array(spell,query_spells()) != -1)
                NOT_FAIL("Cast " + spell + " at <who>?\n");

            NOT_FAIL("Cast <what> at <who>?\n");
        }

        spell = lower_case(spell);
        name = lower_case(name);

        if (member_array(spell,query_spells()) == -1)
            NOT_FAIL("What spell is that?\n");

        who = present(name,ENV(TP));
        if (!who)
            NOT_FAIL(CAP(name) + " ain't here!\n");
    }
    else
    {
        if (sscanf(arg,"%s at %s",spell,name) != 2) // We got all or nothing
        {
            if (!spell) spell = arg;  // We got nothing, arg must be spell
            if (!spell || member_array(spell,query_spells()) == -1)
                NOT_FAIL("Cast <what> at <who>?\n");
        }
        else        // We got both name and spell
        {
            who = present(name,ENV(TP));
            if (!who)
                NOT_FAIL(CAP(name) + " ain't here!\n");
        }
    }

    if (!living(who))
        NOT_FAIL("Ehm... Hello? " + CAP(name) + " is not a living being!\n");

    if (Q_NOFIGHT(who))
        NOT_FAIL("You can't attack " + CAP(name) + ".\n");

    if (Q_NOFIGHT(who) || Q_NOMATT(ENV(TP)))
        NOT_FAIL("You can't use this spell here.\n");

    if (Q_SP(TP) < query_cost(spell))
        NOT_FAIL("You just don't have the power to cast this spell.\n");

    if (Q_BUSY(TP))
        NOT_FAIL("Not while you're busy with other things!\n");

    cast_spell(who,spell);    // Finally! Cast the spell!

    S_BUSY(TP);
    return 1;
}

help/cast


NAME
        cast - cast a spell on your opponent

SYNTAX
        cast <spellname> [at <monster/player>]

DESCRIPTION
        You can cast several different spell on you opponent.
        The different spells are:
            fireball
            snowball
            lightning bolt
            electric storm

EXAMPLE
        cast fireball at gunner

SEE ALSO