skylib_mudos_v1/
skylib_mudos_v1/bin/
skylib_mudos_v1/bin/db/
skylib_mudos_v1/mudlib/banish/a/
skylib_mudos_v1/mudlib/banish/b/
skylib_mudos_v1/mudlib/banish/c/
skylib_mudos_v1/mudlib/banish/d/
skylib_mudos_v1/mudlib/banish/e/
skylib_mudos_v1/mudlib/banish/f/
skylib_mudos_v1/mudlib/banish/g/
skylib_mudos_v1/mudlib/banish/h/
skylib_mudos_v1/mudlib/banish/j/
skylib_mudos_v1/mudlib/banish/l/
skylib_mudos_v1/mudlib/banish/m/
skylib_mudos_v1/mudlib/banish/n/
skylib_mudos_v1/mudlib/banish/o/
skylib_mudos_v1/mudlib/banish/p/
skylib_mudos_v1/mudlib/banish/r/
skylib_mudos_v1/mudlib/banish/s/
skylib_mudos_v1/mudlib/banish/t/
skylib_mudos_v1/mudlib/banish/u/
skylib_mudos_v1/mudlib/banish/w/
skylib_mudos_v1/mudlib/cmds/
skylib_mudos_v1/mudlib/cmds/admin/
skylib_mudos_v1/mudlib/cmds/guild-race/
skylib_mudos_v1/mudlib/cmds/guild-race/crafts/
skylib_mudos_v1/mudlib/cmds/guild-race/magic/
skylib_mudos_v1/mudlib/cmds/guild-race/other/
skylib_mudos_v1/mudlib/cmds/living/broken/
skylib_mudos_v1/mudlib/cmds/player/group_cmds/
skylib_mudos_v1/mudlib/d/admin/
skylib_mudos_v1/mudlib/d/admin/room/
skylib_mudos_v1/mudlib/d/admin/room/we_care/
skylib_mudos_v1/mudlib/d/admin/save/
skylib_mudos_v1/mudlib/d/admin/text/
skylib_mudos_v1/mudlib/d/learning/TinyTown/buildings/
skylib_mudos_v1/mudlib/d/learning/TinyTown/map/
skylib_mudos_v1/mudlib/d/learning/TinyTown/roads/
skylib_mudos_v1/mudlib/d/learning/chars/
skylib_mudos_v1/mudlib/d/learning/functions/
skylib_mudos_v1/mudlib/d/learning/handlers/
skylib_mudos_v1/mudlib/d/learning/help_topics/
skylib_mudos_v1/mudlib/d/learning/help_topics/npcs/
skylib_mudos_v1/mudlib/d/learning/help_topics/objects/
skylib_mudos_v1/mudlib/d/learning/help_topics/rcs_demo/
skylib_mudos_v1/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_mudos_v1/mudlib/d/learning/help_topics/rooms/
skylib_mudos_v1/mudlib/d/learning/help_topics/rooms/crowd/
skylib_mudos_v1/mudlib/d/learning/help_topics/rooms/situations/
skylib_mudos_v1/mudlib/d/learning/save/
skylib_mudos_v1/mudlib/d/learning/school/
skylib_mudos_v1/mudlib/d/learning/school/add_sc/
skylib_mudos_v1/mudlib/d/learning/school/characters/
skylib_mudos_v1/mudlib/d/learning/school/general/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/basic_commands/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/edtutor/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_mudos_v1/mudlib/d/learning/school/items/
skylib_mudos_v1/mudlib/d/learning/school/npc_school/
skylib_mudos_v1/mudlib/d/learning/school/room_school/
skylib_mudos_v1/mudlib/d/learning/school/room_school/room_basic/
skylib_mudos_v1/mudlib/d/learning/school/room_school/situations/
skylib_mudos_v1/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_mudos_v1/mudlib/d/learning/text/
skylib_mudos_v1/mudlib/d/liaison/
skylib_mudos_v1/mudlib/d/mudlib/
skylib_mudos_v1/mudlib/d/mudlib/changes/
skylib_mudos_v1/mudlib/d/playtesters/
skylib_mudos_v1/mudlib/d/playtesters/effects/
skylib_mudos_v1/mudlib/d/playtesters/handlers/
skylib_mudos_v1/mudlib/d/playtesters/items/
skylib_mudos_v1/mudlib/d/sage/
skylib_mudos_v1/mudlib/doc/
skylib_mudos_v1/mudlib/doc/creator/
skylib_mudos_v1/mudlib/doc/driver/
skylib_mudos_v1/mudlib/doc/driver/efuns/arrays/
skylib_mudos_v1/mudlib/doc/driver/efuns/buffers/
skylib_mudos_v1/mudlib/doc/driver/efuns/compile/
skylib_mudos_v1/mudlib/doc/driver/efuns/filesystem/
skylib_mudos_v1/mudlib/doc/driver/efuns/floats/
skylib_mudos_v1/mudlib/doc/driver/efuns/functions/
skylib_mudos_v1/mudlib/doc/driver/efuns/general/
skylib_mudos_v1/mudlib/doc/driver/efuns/mappings/
skylib_mudos_v1/mudlib/doc/driver/efuns/mixed/
skylib_mudos_v1/mudlib/doc/driver/efuns/mudlib/
skylib_mudos_v1/mudlib/doc/driver/efuns/numbers/
skylib_mudos_v1/mudlib/doc/driver/efuns/parsing/
skylib_mudos_v1/mudlib/doc/known_command/
skylib_mudos_v1/mudlib/doc/login/
skylib_mudos_v1/mudlib/doc/lpc/basic_manual/
skylib_mudos_v1/mudlib/doc/lpc/intermediate/
skylib_mudos_v1/mudlib/doc/new/add_command/
skylib_mudos_v1/mudlib/doc/new/events/
skylib_mudos_v1/mudlib/doc/new/handlers/
skylib_mudos_v1/mudlib/doc/new/living/race/
skylib_mudos_v1/mudlib/doc/new/living/spells/
skylib_mudos_v1/mudlib/doc/new/object/
skylib_mudos_v1/mudlib/doc/new/player/
skylib_mudos_v1/mudlib/doc/new/room/guild/
skylib_mudos_v1/mudlib/doc/new/room/outside/
skylib_mudos_v1/mudlib/doc/new/room/storeroom/
skylib_mudos_v1/mudlib/doc/object/
skylib_mudos_v1/mudlib/doc/playtesters/
skylib_mudos_v1/mudlib/doc/policy/
skylib_mudos_v1/mudlib/doc/weapons/
skylib_mudos_v1/mudlib/global/
skylib_mudos_v1/mudlib/global/creator/
skylib_mudos_v1/mudlib/global/handlers/
skylib_mudos_v1/mudlib/global/virtual/setup_compiler/
skylib_mudos_v1/mudlib/include/cmds/
skylib_mudos_v1/mudlib/include/effects/
skylib_mudos_v1/mudlib/include/npc/
skylib_mudos_v1/mudlib/include/room/
skylib_mudos_v1/mudlib/include/shops/
skylib_mudos_v1/mudlib/net/daemon/
skylib_mudos_v1/mudlib/net/daemon/chars/
skylib_mudos_v1/mudlib/net/inherit/
skylib_mudos_v1/mudlib/net/obj/
skylib_mudos_v1/mudlib/obj/amulets/
skylib_mudos_v1/mudlib/obj/b_day/
skylib_mudos_v1/mudlib/obj/clothes/
skylib_mudos_v1/mudlib/obj/dwarmours/plate/
skylib_mudos_v1/mudlib/obj/dwclothes/transport/horse/
skylib_mudos_v1/mudlib/obj/dwscabbards/
skylib_mudos_v1/mudlib/obj/dwweapons/axes/
skylib_mudos_v1/mudlib/obj/dwweapons/chains/
skylib_mudos_v1/mudlib/obj/faith/symbols/
skylib_mudos_v1/mudlib/obj/fungi/
skylib_mudos_v1/mudlib/obj/gatherables/
skylib_mudos_v1/mudlib/obj/instruments/
skylib_mudos_v1/mudlib/obj/magic/
skylib_mudos_v1/mudlib/obj/media/
skylib_mudos_v1/mudlib/obj/misc/player_shop/
skylib_mudos_v1/mudlib/obj/monster/godmother/
skylib_mudos_v1/mudlib/obj/monster/transport/
skylib_mudos_v1/mudlib/obj/rings/
skylib_mudos_v1/mudlib/obj/spells/
skylib_mudos_v1/mudlib/obj/stationery/
skylib_mudos_v1/mudlib/obj/stationery/envelopes/
skylib_mudos_v1/mudlib/obj/stationery/papers/
skylib_mudos_v1/mudlib/obj/toys/
skylib_mudos_v1/mudlib/obj/vessels/
skylib_mudos_v1/mudlib/obj/weapons/swords/
skylib_mudos_v1/mudlib/save/autodoc/
skylib_mudos_v1/mudlib/save/leaflets/
skylib_mudos_v1/mudlib/save/mail/
skylib_mudos_v1/mudlib/save/new_soul/data/
skylib_mudos_v1/mudlib/save/parcels/
skylib_mudos_v1/mudlib/save/playerinfo/
skylib_mudos_v1/mudlib/save/players/d/
skylib_mudos_v1/mudlib/save/random_names/
skylib_mudos_v1/mudlib/save/random_names/data/
skylib_mudos_v1/mudlib/save/terrains/
skylib_mudos_v1/mudlib/save/terrains/tutorial_desert/
skylib_mudos_v1/mudlib/save/terrains/tutorial_grassy_field/
skylib_mudos_v1/mudlib/save/terrains/tutorial_mountain/
skylib_mudos_v1/mudlib/save/todo_lists/
skylib_mudos_v1/mudlib/secure/
skylib_mudos_v1/mudlib/secure/cmds/admin/
skylib_mudos_v1/mudlib/secure/cmds/lord/
skylib_mudos_v1/mudlib/secure/config/
skylib_mudos_v1/mudlib/secure/handlers/autodoc/
skylib_mudos_v1/mudlib/secure/handlers/intermud/
skylib_mudos_v1/mudlib/secure/include/global/
skylib_mudos_v1/mudlib/secure/save/
skylib_mudos_v1/mudlib/secure/save/handlers/
skylib_mudos_v1/mudlib/secure/std/classes/
skylib_mudos_v1/mudlib/secure/std/modules/
skylib_mudos_v1/mudlib/std/commands/
skylib_mudos_v1/mudlib/std/commands/shadows/
skylib_mudos_v1/mudlib/std/creator/
skylib_mudos_v1/mudlib/std/dom/
skylib_mudos_v1/mudlib/std/effects/
skylib_mudos_v1/mudlib/std/effects/external/
skylib_mudos_v1/mudlib/std/effects/fighting/
skylib_mudos_v1/mudlib/std/effects/priest/
skylib_mudos_v1/mudlib/std/effects/room/
skylib_mudos_v1/mudlib/std/environ/
skylib_mudos_v1/mudlib/std/guilds/
skylib_mudos_v1/mudlib/std/guilds/old/
skylib_mudos_v1/mudlib/std/languages/
skylib_mudos_v1/mudlib/std/languages/BACKUPS/
skylib_mudos_v1/mudlib/std/liquids/
skylib_mudos_v1/mudlib/std/npc/
skylib_mudos_v1/mudlib/std/npc/goals/
skylib_mudos_v1/mudlib/std/npc/goals/basic/
skylib_mudos_v1/mudlib/std/npc/goals/misc/
skylib_mudos_v1/mudlib/std/npc/plans/
skylib_mudos_v1/mudlib/std/npc/plans/basic/
skylib_mudos_v1/mudlib/std/npc/types/
skylib_mudos_v1/mudlib/std/npc/types/helper/
skylib_mudos_v1/mudlib/std/npcs/
skylib_mudos_v1/mudlib/std/outsides/
skylib_mudos_v1/mudlib/std/races/shadows/
skylib_mudos_v1/mudlib/std/room/basic/topography/
skylib_mudos_v1/mudlib/std/room/controller/
skylib_mudos_v1/mudlib/std/room/inherit/topography/
skylib_mudos_v1/mudlib/std/room/topography/area/
skylib_mudos_v1/mudlib/std/room/topography/iroom/
skylib_mudos_v1/mudlib/std/room/topography/milestone/
skylib_mudos_v1/mudlib/std/shadows/curses/
skylib_mudos_v1/mudlib/std/shadows/disease/
skylib_mudos_v1/mudlib/std/shadows/fighting/
skylib_mudos_v1/mudlib/std/shadows/healing/
skylib_mudos_v1/mudlib/std/shadows/magic/
skylib_mudos_v1/mudlib/std/shadows/poison/
skylib_mudos_v1/mudlib/std/shadows/rituals/
skylib_mudos_v1/mudlib/std/shadows/room/
skylib_mudos_v1/mudlib/std/shops/controllers/
skylib_mudos_v1/mudlib/std/shops/objs/
skylib_mudos_v1/mudlib/std/shops/player_shop/
skylib_mudos_v1/mudlib/std/socket/
skylib_mudos_v1/mudlib/std/soul/
skylib_mudos_v1/mudlib/std/soul/d/
skylib_mudos_v1/mudlib/std/soul/e/
skylib_mudos_v1/mudlib/std/soul/i/
skylib_mudos_v1/mudlib/std/soul/j/
skylib_mudos_v1/mudlib/std/soul/k/
skylib_mudos_v1/mudlib/std/soul/l/
skylib_mudos_v1/mudlib/std/soul/n/
skylib_mudos_v1/mudlib/std/soul/o/
skylib_mudos_v1/mudlib/std/soul/q/
skylib_mudos_v1/mudlib/std/soul/u/
skylib_mudos_v1/mudlib/std/soul/v/
skylib_mudos_v1/mudlib/std/soul/y/
skylib_mudos_v1/mudlib/std/soul/z/
skylib_mudos_v1/mudlib/std/stationery/
skylib_mudos_v1/mudlib/w/
skylib_mudos_v1/mudlib/w/default/
skylib_mudos_v1/mudlib/w/default/armour/
skylib_mudos_v1/mudlib/w/default/clothes/
skylib_mudos_v1/mudlib/w/default/item/
skylib_mudos_v1/mudlib/w/default/npc/
skylib_mudos_v1/mudlib/w/default/room/
skylib_mudos_v1/mudlib/w/default/weapon/
skylib_mudos_v1/mudlib/www/
skylib_mudos_v1/mudlib/www/download/
skylib_mudos_v1/mudlib/www/java/
skylib_mudos_v1/mudlib/www/secure/
skylib_mudos_v1/mudlib/www/secure/lpc/advanced/
skylib_mudos_v1/mudlib/www/secure/lpc/intermediate/
skylib_mudos_v1/v22.2b14-DSv10/
skylib_mudos_v1/v22.2b14-DSv10/ChangeLog.old/
skylib_mudos_v1/v22.2b14-DSv10/Win32/
skylib_mudos_v1/v22.2b14-DSv10/compat/
skylib_mudos_v1/v22.2b14-DSv10/compat/simuls/
skylib_mudos_v1/v22.2b14-DSv10/include/
skylib_mudos_v1/v22.2b14-DSv10/mudlib/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/clone/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/command/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/data/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/etc/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/include/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/inherit/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/inherit/master/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/log/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/tests/compiler/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/tests/efuns/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/tests/operators/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/u/
skylib_mudos_v1/v22.2b14-DSv10/tmp/
skylib_mudos_v1/v22.2b14-DSv10/windows/
/**
 * This file contains all the armour related code for the living
 * objects.
 * @author Pinkfish
 */

inherit "/std/armour_logic";

#define IMMUNE_TYPES ({ "sharp", "blunt", "pierce", "magic", "fire", "ice", "self" })

nosave string skin;
nosave object *wearing;
nosave mixed stopped;
private string *_immuneto;

void create() {
    skin = "morphological field";
    wearing = ({ });
    ::create();
} /* create() */

/**
 * This method returns the types of attacks that this thing is immune to.
 * @return the list of attacks this thing is immune to
 * @see add_immune(), remove_immune()
 */
string *query_immune() { return _immuneto || ({ }); }

/**
 * This method removes an immune type from the list of damage types
 * this creature is immune to.
 * @param str the damage type to remove from the immunity list
 * @see query_immune(), add_immune()
 */
void remove_immune( string str ) {
    if( !sizeof(_immuneto) )
        return;
    _immuneto -= ({ str });
} /* remove_immune() */

/**
 * This method adds a type of attack to the list of things this
 * object is immune to.
 * @param type the type or array of types of damage to add to
 * the immune list
 * @see query_immune(), remove_immune()
 */
void add_immune( mixed type ) {
    if( !pointerp( _immuneto ) )
        _immuneto = ({ });

    if( pointerp( type ) )
        foreach( string str in type )
            add_immune( str );

    if( stringp( type ) && member_array( type, IMMUNE_TYPES ) != -1 &&
        member_array( type, _immuneto ) == -1 )
        _immuneto += ({ type });

} /* add_immune() */

/**
 * This method returns the current skin of the living object.
 * @return the skin of the object
 * @see set_skin()
 */
string query_skin() { return skin; }

/**
 * This method sets the current skin of the living object.  This can
 * be done by the race object and by specific spells or effects.
 * @param word the new skin type
 * @see query_skin()
 */
void set_skin( string word ) { skin = word; }

/**
 * This method returns all the objects you are currently wearing.
 * @return the current array of worn objects
 * @return the array of worn stuff
 * @see query_armours()
 */
object *query_wearing() {
    wearing -= ({ 0 });
    return copy( wearing );
} /* query_wearing() */

/**
 * This method returns all the armours that the is currently being
 * worn.  This will always return the same value as query_wearing()
 * @see query_wearing()
 * @return the array of armours
 */
object *query_armours() {
    return query_wearing();
} /* query_armours() */

/**
 * This method will make sure all the armours are unworn by the living
 * object.
 * @see query_wearing()
 */
void clear_armours() {
    wearing->set_worn_by( 0 );
    wearing = ({ });
} /* clear_armours() */

/**
 * This returns the object which stopped the blow.  This is only valid
 * inside and after a query_ac() call.
 * @return the object which stopped the call
 */
mixed query_stopped() {
    return stopped;
} /* query_stopped() */

/**
 * This method sets the object which stops the call.  This should be
 * used to do weird stuff.  I have no idea what it should be used for
 * at all and I am just rambling.
 * @param arg the new value of the stopped object
 */
void set_stopped( mixed arg ) { stopped = arg; }

/**
 * This method checks to see if the two armour types are
 * equivilant or not.
 * @param comp the first type
 * @param type the second type
 */
protected int equivalent_armour_types( mixed comp, string type ) {
    string word;

    if( stringp( comp ) ) {
        if( CLOTHING_H->query_equivilant_type( comp ) )
            return CLOTHING_H->query_equivilant_type( comp ) == type;
        return comp == type;
    }

    foreach( word in comp ) {
        if( equivalent_armour_types( word, type ) )
            return 1;
    }

    return 0;

} /* equivalent_armour_types() */

/**
 * This is the method used to get the living object to wear a piece of
 * armour or clothing.  This is called from inside the armour or clothing
 * code itself.  It will call the function set_worn_by() on the
 * armour or clothing and if this returns a non-zero result then it
 * will add it into the current list of worn types.  Assuming the
 * type of the armour fits into the allowed list.  It will also
 * call the functon hold_item on the object if it is required to be
 * held as well (ie: shield).
 * @param armour the armour to wear
 * @param doing_hold if this is called by the hold command
 * @return the failure message, or 0 if ok
 * @see remove_armour()
 * @see query_armours()
 * @see query_wearing()
 */
string wear_armour( object armour, int doing_hold ) {
    int no_limbs;
    string type, word;
    mixed types;
    object thing;
    mapping things;

    wearing -= ({ 0 });
    types = (mixed)armour->query_type();

    if( word = (string)TO->not_allowed_to_wear( types ) )
        return word;

    if( member_array( armour, wearing ) != -1 )
        return "already wearing";

    things = ([ ]);
    if( stringp( types ) )
        types = ({ types });

    if( !pointerp( types ) )
        return "oh dear";

    foreach( type in types ) {
        if( CLOTHING_H->query_equivilant_type( type ) )
            type = CLOTHING_H->query_equivilant_type( type );
        things[ type ] = ({ });
        foreach( thing in wearing ) {
            if( equivalent_armour_types( (mixed)thing->query_type(), type ) )
                things[ type ] += ({ thing });
        }
    }
    word = (string)TO->query_race_ob();
    foreach( type in keys( things ) ) {
        if( (int)word->query_number_worn( type ) <= sizeof( things[ type ] ) ) {
            return "since you are already wearing "+
                    query_multiple_short( things[ type ] );
        }
    }
    no_limbs = (int)armour->query_no_limbs();
    if( no_limbs && !doing_hold ) {
        if( member_array( armour, (object *)TO->query_holding() ) != -1 )
            return "already wearing";
        if( sizeof( (int *)armour->hold_item( TO, -1 ) ) )
            return 0;
        else
            return "already holding";
    }
    if( !armour->set_worn_by( TO ) )
        return "oh dear";

    wearing += ({ armour });
    call_out( "calc_burden", 1 );
    return 0;

} /* wear_armour() */

/**
 * This method will remove the armour from the living object.
 * @param thing the armour to remove
 * @return 1 if was unsuccessful and 0 if it was successful
 * @see wear_armour()
 * @see query_armours()
 * @see query_wearing()
 */
int remove_armour( object thing ) {
    int i;

    wearing -= ({ 0 });

    if( ( i = member_array( thing, wearing ) ) == -1 )
        return 1;

    if( !thing->set_worn_by( 0 ) )
        return 1;

    if( member_array( thing, (object *)TO->query_holding() ) != -1 )
        if( !sizeof( (int *)TO->set_unhold( thing ) ) )
            return 1;

    wearing = delete( wearing, i, 1 );
    call_out( "calc_burden", 1 );
    return 0;

} /* remove_armour() */

/**
 * This function returns the amount of damage that is blocked
 * my the armour on a specified zone.  It automatically
 * damages the armour, and sets the stopped object to be the
 * the object (piece of armour) that stopped the blow.
 *
 * @param type The type of damage, eg: "sharp", "blunt", "pierce".
 * @param amount The amount of damage that is being done.
 * @param zone The zone which the damage is being done through, eg: "head".
 * @return The amount of damage that will be blocked.
 * @see query_wearing()
 */
varargs int query_ac( string type, int amount, string zone ) {
    int part, total;
    string word;
    object thing;
    object *defenses;

    stopped = 0;

    if( sizeof(_immuneto) && member_array( type, _immuneto ) != -1 ) {
        stopped = skin;
        return amount;
    }

    /*
     * This is used by magic and poisons, etc. so the identity of
     * "stopped" is irrelevant, since it bypasses all armour.
     */
    if( zone == "self" )
        return ::query_ac( type, amount, zone );

    if( !zone ) {
        switch( random(20) ) {
        case 0..1: zone = "head"; break;
        case 2: zone = "neck"; break;
        case 3..6: zone="chest"; break;
        case 7..9: zone="abdomen"; break;
        case 10..12: zone = "arms"; break;
        case 13..14: zone = "hands"; break;
        case 15..18: zone = "legs"; break;
        case 19: zone = "feet"; break;
        }
    }

    foreach ( word in CLOTHING_H->query_clothing_zone( zone ) ) {
        wearing -= ({ 0 });
        defenses = wearing + filter( TO->query_holding(),
                               (: $1 && $1->query_armour() :) );
        foreach( thing in defenses )
        if( equivalent_armour_types( (mixed)thing->query_type(), word ) ) {
            part = (int)thing->query_ac( type, amount, zone );
            if( !stopped && part )
                stopped = thing;
            total += part;
            amount -= part;
        }
        if( amount < 1 )
            break;
    }

    if( amount > 0 ) {
        if( !stopped )
            stopped = skin;
        if( type == "fire" && TO->effects_matching("body.wetness") &&
            sizeof( (int *)TO->effects_matching("body.wetness") ) )
            TO->add_effect("/std/effects/other/wetness", -amount );
        total += ::query_ac( type, amount, zone );
    }

    return total;

} /* query_ac() */

/** @ignore yes */
mixed stats() {
    return ::stats() + ({
      ({ "skin", skin }),
    });
} /* stats() */