skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
/**
 * This is the kirikaeshi command.  Thank you, Kendo. :)
 * Initiates combat and makes a number of quick attacks on the target.
 * @author Sandoz, 2002.
 * @changed Rewrote completely for the new combat system.
 * - Sandoz, June 2003.
 */

#define __ATTACK_DATA_CLASS__
#include <combat.h>
#include <player.h>
#include <tasks.h>
#include <weapon.h>

#define GP_COST     50
#define LEARN_LEVEL 50
#define MAX_HITS    5
#define OFF_SKILL   "fighting.combat.special.tactics"
#define WEP_SKILL   "fighting.combat.special.weapon"
#define DEF_SKILL   "general.perception"

inherit COMMAND_BASE;

private void execute_attack( object off, object def, object wep,
                             string *names, mixed data, string *areas );

/**
 * This method returns whether or not the specified player
 * can learn this command.
 * @param ob the player to test
 * @return 1 if they can learn it, 0 if not
 */
int query_learnable_by( object ob ) {
    return ob->query_skill(OFF_SKILL) >= LEARN_LEVEL &&
           ob->query_skill(WEP_SKILL) >= LEARN_LEVEL;
} /* query_learnable_by() */

/** @ignore yes */
int cmd( object *targets, object *weapons ) {
    string *names, *areas;
    object target, weapon;
    int mod, i, off, def;
    mapping map;
    mixed data;
    mapping hiding;
    
    if( TP->query_fighting() ) {
        add_failed_mess("You cannot use a kirikaeshi attack while already "
            "in combat with someone.\n");
        return 0;
    }

    if( sizeof( targets ) > 1 ) {
        add_failed_mess("You can only make a kirikaeshi attack on one "
            "target at a time.\n");
        return 0;
    }

    targets = HEALTH_H->do_attack_checks( targets, 0 );

    if( !targets )
        return 0;

    if( !sizeof(targets) )
        return 1;

    target = targets[ 0 ];

    if( mapp( map = target->query_attackable_areas() ) ) {
        areas = ({ });
        if( !undefinedp( map["head"] ) )
            areas += ({"head"});
        if( !undefinedp( map["neck"] ) )
            areas += ({"neck"});
    }

    if( !sizeof(areas) ) {
        add_failed_mess("Oh dear, $I seems to have no head or neck to "
            "pummel at.  Puzzling, no?\n");
        return 0;
    }

    if( sizeof( weapons ) > 1 ) {
        add_failed_mess("You can only use one weapon for the kirikaeshi "
            "attack.\n");
        return 0;
    }

    if( !sizeof(weapons) ) {
        add_failed_mess("You need a weapon for the kirikaeshi "
            "attack.\n");
        return 0;
    }

    weapon = weapons[ 0 ];

    if( !weapon->query_weapon() || weapon->query_no_limbs() != 2 ) {
        add_failed_mess("You need a two-handed weapon to use the kirikaeshi "
            "attack.\n");
        return 0;
    }

    i = sizeof( names = weapon->query_attack_names() );
    data = weapon->query_attack_data();

    // Weed out unappropriate attacks.
    while( i-- ) {
        int j = i * W_ARRAY_SIZE;

        switch( data[j+W_SKILL] ) {
          case "sharp" :
          case "blunt" :
          continue;
          default:
            names = delete( names, i, 1 );
            data = delete( data, j, W_ARRAY_SIZE );
        }
    }

    if( !sizeof(names) ) {
        add_failed_mess("$I doesn't appear to be a suitable weapon to "
            "execute a kirikaeshi attack with, because it is not meant "
            "for swinging motions.\n");
        return 0;
    }

    if( target->is_fighting(TP) ) {
        add_failed_mess("$I appears to be fighting you already.\n", targets );
        return 0;
    }

    if( ENV(TP)->query_transport() ) {
        add_failed_mess("You cannot execute a kirikaeshi attack while you "
            "are mounted.\n");
        return 0;
    }

    if( ENV(target)->query_transport() ) {
        add_failed_mess("You cannot execute a kirikaeshi attack on mounted "
            "opponents.\n");
        return 0;
    }

    if( weapon->query_wielded() != TP ) {
        add_failed_mess("You are not holding $I.\n", weapons );
        return 0;
    }

    if( !TASKER->point_tasker( TP, "fighting", GP_COST ) ) {
        add_failed_mess("You do not have enough energy to execute a "
            "kirikaeshi attack on $I.\n", targets );
        return 0;
    }

    hiding = (mapping)TP->query_hide_invis();

    if( hiding["hiding"] ) {
        TP->remove_hide_invis("hiding");
    }

    // Start out with a 25% bonus.
    mod = 25;

    // Impose a lower limit to it, just in case.
    if( ( i = weapon->query_weight() ) < 10 )
        i = 10;

    // Increase the modifier by a weighted average of our
    // special.weapon skill and the weight of the weapon used.
    mod += TP->query_skill_bonus(WEP_SKILL) / i;

    off = TP->query_skill_bonus(OFF_SKILL);
    def = target->query_skill_bonus(DEF_SKILL);

    event( TP, "inform", sprintf("kirikaeshi: tactics %i vs perception %i, "
        "modifier: %i", off, def, mod ), "debug");

    mod = TASKER->compare_skills( TP, OFF_SKILL, target, DEF_SKILL,
                                  mod, TM_COMMAND, TM_FREE );

    switch( mod ) {
      case OFFAWARD :
        tell_object( TP, "%^YELLOW%^"+({
            "You feel more skilled at making surprise attacks",
            "You discover a new aspect of tactical fighting",
            "You realize something new about surprise attacks"})
            [ random( 3 ) ]+" as you execute the kirikaeshi attack on "+
            target->the_short()+"%^RESET%^\n" );
      case OFFWIN :
        XP_H->handle_xp( TP, GP_COST, 1 );
        call_out( (: execute_attack :), 0, TP, target, weapon,
            names, data, areas );
      break;
      case DEFAWARD :
        tell_object( def, "%^YELLOW%^You feel more perceptive as you "+
            choice( ({"foil ", "thwart "}) )+TP->poss_short()+" attempt "
            "to launch at you with "+weapon->poss_short()+".\n%^RESET%^");
      case DEFWIN :
        XP_H->handle_xp( TP, GP_COST, 0 );

        // Let's attack normally if we are good enough.
        // Otherwise let the target attack us instead.
        if( random(off) > def / 3 ) {
            tell_object( TP, "You attempt to launch at "+
                target->the_short()+" with "+weapon->poss_short()+", but "+
                target->HE+" turns to face you just in time, although you "
                "keep going, albeit with less vigour.\n");
            tell_object( target, TP->one_short()+" attempts to launch at you "
                "with "+weapon->poss_short()+", but you turn to face "+
                TP->HIM+" just in time, thwarting "+TP->HIS+" enthusiasm.\n");
            tell_room( ENV(TP), TP->one_short()+" attempts to launch at "+
                target->one_short()+" with "+weapon->poss_short()+", but "+
                target->HE+" turns to face "+TP->HIM+" just in time, "
                "thwarting "+TP->HIS+" enthusiasm.\n", ({ TP, target }) );
            TP->attack_ob(target);
        } else {
            tell_object( TP, "You attempt to launch at "+
                target->the_short()+" with "+weapon->poss_short()+", but "+
                target->HE+" turns to face you just in time and you lose your "
                "concentration.\n");
            tell_object( target, TP->one_short()+" attempts to launch at you "
                "with "+weapon->poss_short()+", but you turn to face "+
                TP->HIM+" just in time, foiling "+TP->HIS+" plans.\n");
            tell_room( ENV(TP), TP->one_short()+" attempts to launch at "+
                target->one_short()+" with "+weapon->poss_short()+", but "+
                target->HE+" turns to face "+TP->HIM+" just in time, "
                "foiling "+TP->HIS+" plans.\n", ({ TP, target }) );
            TP->adjust_time_left( -ROUND_TIME );
            target->attack_ob(TP);
        }
    }

    return 1;

} /* cmd() */

/** @ignore yes */
private void finish_attack( object off, object def ) {
    off->attack_ob(def);
    tell_object( off, "You run out of breath and proceed to attack "+
        def->the_short()+" normally.\n");
    tell_room( ENV(off), off->the_short()+" seems to have run "
        "out of breath and proceeds to attack "+
        def->the_short()+" normally.\n", off );
} /* finish_attack() */

/** @ignore yes */
private void execute_attack( object off, object def, object wep,
                             string *names, mixed data, string *areas ) {
    int i, j, dif, weight, perc, bon;

    if( !wep ) {
        tell_object( off, "Bereft of all hope, you abort your attack when "
            "you realize you are not in possession of the weapon anymore.\n");
        return 0;
    }

    if( wep->query_wielded() != off ) {
        tell_object( off, "Bereft of all hope, you abort your attack when "
            "you realize you are not holding "+wep->the_short()+" anymore.\n");
        return 0;
    }

    if( wep->query_no_limbs() != 2 ) {
        tell_object( off, "Bereft of all hope, you abort your attack when "
            "you realize "+wep->the_short()+" is not a two-handed weapon.\n");
        return 0;
    }

    if( ENV(off) != ENV(def) ) {
        tell_object( off, "Bereft of all hope, you abort your attack when "
            "you realize "+def->the_short()+" is not here anymore.\n");
        return 0;
    }

    tell_object( off, "You raise "+wep->poss_short()+" high above your "
        "head and launch at "+def->the_short()+" with a terrible cry, "
        "starting to hew at alternate sides of "+def->HIS+" "+
        query_multiple_short(areas)+".\n");
    tell_object( def, off->one_short()+" suddenly raises "+off->HIS+" "+
        wep->short()+" high above "+off->HIS+" head and launches at you "
        "with a terrible cry, starting to hew at alternate sides of your "+
        query_multiple_short(areas)+".\n");
    tell_room( ENV(off), off->one_short()+" suddenly raises "+off->HIS+" "+
        wep->short()+" high above "+off->HIS+" head and launches at "+
        def->one_short()+" with a terrible cry, starting to hew at "
        "alternate sides of "+def->HIS+" "+query_multiple_short(areas)+".\n",
        ({ off, def }) );

    // Impose a lower limit on the weight again.
    if( ( weight = wep->query_weight() ) < 10 )
        weight = 10;

    weight = 25 + ( 4 * weight ) / ( off->query_str() / 2 );

    perc = 50;
    perc += COMBAT_H->calc_attack_percentage( off, ({ wep }), ({ }) );

    // Start with a random attack to a random area, then alternate.
    j = random( sizeof(names) );

    bon = off->query_skill_bonus(WEP_SKILL);

    event( off, "inform", sprintf("Kirikaeshi base difficulty: %i, attack "
        "percentage: %i, sp.we: %i", weight, perc, bon ), "debug");

    for( i = 0; i < MAX_HITS; i++ ) {
        int a_dif, damage, k, a_bonus;
        class attack_data att;

        if( j == sizeof(names) )
            j = 0;

        damage = wep->calc_attack( j, perc );

        a_dif = damage / 5;

        k = j * W_ARRAY_SIZE;

        if( data[ k + W_CHANCE ] < 100 )
            a_dif += a_dif * ( 100 - data[ k + W_CHANCE ] ) / 100;

        a_dif += weight;

        dif += a_dif;

        a_bonus = to_int( bon / 50.0 + ( bon / 30.0 * ( MAX_HITS - 1 - i ) ) );

        event( off, "inform", sprintf("Attack no. %i - weapon damage: %i, att "
            "diff: %i, total diff: %i, att bonus: %i", i + 1, damage, a_dif,
            dif, a_bonus ), "debug");

        switch( TASKER->perform_task( off, WEP_SKILL, dif, TM_CONTINUOUS ) ) {
          case AWARD:
            tell_object( off, "%^YELLOW%^"+({
                "You feel more confident in handling "+wep->the_short()+".",
                "You realize you are more capable of quick movements with "+
                wep->the_short()+" than before."})[random(2)]+"%^RESET%^\n");
          case SUCCEED:
            att = new( class attack_data );
            att->attacker = off;
            att->target = def;
            att->weapon = wep;
            att->damage = damage;
            att->skill  = data[ k + W_SKILL ];
            att->type = data[ k + W_TYPE ];
            att->name = names[j++];
            att->focus = choice(areas);
            att->final_damage = damage;
            att->attack_bonus = a_bonus;
            att->unprotectable = 1;

            COMBAT_H->attack_round( off, !i, att );

            // We have ran out of time.
            if( !COMBAT_H->check_time_left( off, 1 ) ) {
                event( off, "inform", "We have ran out of time!", "debug");
                return finish_attack( off, def );
            }
          break;
          default :
            return finish_attack( off, def );
        }
    }

    return finish_attack( off, def );

} /* execute_attack() */

/** @ignore yes */
mixed query_patterns() {
    return ({
        "<indirect:living:here'target'> [with] <indirect:object:me'weapon'>",
        (: cmd( $1[0], $1[1] ) :),
        "<indirect:living:here'target'>",
        (: cmd( $1, TP->query_weapons() ) :),
    });
} /* query_patterns() */