/* -*- LPC -*- */ /* * $Locker: $ * $Id: good_fighter.c,v 1.3 1998/04/11 23:55:16 sin Exp $ * $Log: good_fighter.c,v $ * Revision 1.3 1998/04/11 23:55:16 sin * Changed documentation to describe USE_UNARMED * * Revision 1.2 1998/02/06 22:18:18 sin * Change in preparation for the skills rearrange. * * Revision 1.1 1998/01/06 04:16:50 ceres * Initial revision * */ /** * The Good Fighter effect makes the npc fight a lot better. It has a * classification of "npc.fighter". * * <p>Many NPCs need to be able to fight well. Generally "fight well" * simply means using the special combat commands that their guild * offers. Of course, since the use of those commands requires that an * NPC have the requisite skills, the NPC will also have to include * logic to set those skills to an appropriate level. Since many * NPCs need to be good fighters, this kind of code is duplicated * all over the Disc. * * <p>This shadow does everything necessary to turn a plain, stupid, * NPC into a semi-intelligent fighter. * * <p>To be more specific, when this shadow is applied to an NPC, it'll * do everything necessary to make sure the NPC has the commands * appropriate to their level, has the skills to use those commands, * and has the intelligence to use the commands in a useful way. * * <p>Currently, this shadow is only really useful to members of the * warriors' guild. It should be relatively straightforward to * generalize this shadow to the needs of other guilds, or to write * customized shadows based on this one but tuned for those others. * But that is a later project. * * <p>To use this shadow, you must first set the NPC's guild, race, * and level, and their stats (strength, constitution, &c.). Then * add the effect to the NPC. Defines are provided in good_fighter.h * to simplify this. Generally, this would be done in the setup() * function for the NPC, but it can also be done later, in response * to some event, or a player's statement, or what have you. The * only thing that is important is that the effect needs to get added * after the NPC's stats are set, and before the NPC enters combat. * * <p>When you add the effect, you need to give an argument. This * argument tunes the effect to one of 15 different variants, depending * on how the fighter should use blunt, sharp, and pierce attacks, and * how the fighter defends itself. Defines for the attacks are * USE_SHARP, USE_PIERCE, USE_BLUNT, USE_UNARMED, and USE_BALANCED. * Defines for the defenses are DEFEND_DODGE, DEFEND_PARRY, and * DEFEND_BALANCED. As an example, if you want a fighter who uses * piercing attacks, while defending with parry, then use the following * code: * <pre> * add_effect(GOOD_FIGHTER, ({ USE_PIERCE, DEFEND_PARRY }) ); * </pre> * Always put the USE_xxx before the DEFEND_xxx! * * <p>Obviously, it doesn't make a whole lot of since to set an NPC * to USE_UNARMED and DEFEND_PARRY unless you also give them a * shield. * * <p>The skills and intelligence of the NPC are driven largely by * the NPC's level. The higher level an NPC is, the more special * commands will be available to the NPC, and the more often the NPC * will use these commands. * * <p>The effect applies a shadow to the NPC. It is in that shadow * that nearly all the intelligence resides. * * @see /std/shadows/fighting/combat * @see /std/race->set_guild() * @see /std/race->set_level() * @see clone_object() * * @author Sin * @created 12 November 1997 * @changed 13 November 1997 -- Sin * Converted it from a pure shadow to a shadow/effect pair. * @changed 6 Feb 1998 -- Sin * Fixed documentation, and modified effect to support the skill * changeover (USE_PIERCE). * @changed 11 April 1998 -- Sin * Changed documentation to discuss USE_UNARMED. */ #include "path.h" #include <effect.h> #define CLASS "npc.fighter" /** @ignore yes */ string query_classification() { return CLASS; } /** @ignore yes */ int query_indefinite() { return 1; } /** @ignore yes */ string query_shadow_ob() { return SHADOWS "good_fighter"; } /** @ignore yes */ void gfs(object player) { player->good_fighter_setup(); } /** @ignore yes */ int *beginning(object player, int *arg) { if (!arg || !arrayp(arg) || sizeof(arg) != 2) arg = ({ 0, 0 }); player->submit_ee("gfs", 1, EE_ONCE); return arg; } /* beginning() */ /** @ignore yes */ void restart(object player, int *arg) { beginning(player, arg); } /* restart() */ /** @ignore yes */ int *merge_effect(object player, int *oldarg, int *newarg) { return oldarg; } /* merge_effect() */ /** @ignore yes */ void end(object player, int *arg) { } /* end() */