dw_fluffos_v1/
dw_fluffos_v1/fluffos-1.22c11/
dw_fluffos_v1/fluffos-1.22c11/ChangeLog.old/
dw_fluffos_v1/fluffos-1.22c11/Win32/
dw_fluffos_v1/fluffos-1.22c11/compat/
dw_fluffos_v1/fluffos-1.22c11/compat/simuls/
dw_fluffos_v1/fluffos-1.22c11/include/
dw_fluffos_v1/fluffos-1.22c11/mudlib/
dw_fluffos_v1/fluffos-1.22c11/testsuite/
dw_fluffos_v1/fluffos-1.22c11/testsuite/clone/
dw_fluffos_v1/fluffos-1.22c11/testsuite/command/
dw_fluffos_v1/fluffos-1.22c11/testsuite/data/
dw_fluffos_v1/fluffos-1.22c11/testsuite/etc/
dw_fluffos_v1/fluffos-1.22c11/testsuite/include/
dw_fluffos_v1/fluffos-1.22c11/testsuite/inherit/
dw_fluffos_v1/fluffos-1.22c11/testsuite/inherit/master/
dw_fluffos_v1/fluffos-1.22c11/testsuite/log/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/tests/compiler/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/tests/efuns/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/tests/operators/
dw_fluffos_v1/fluffos-1.22c11/testsuite/u/
dw_fluffos_v1/fluffos-1.22c11/tmp/
dw_fluffos_v1/lib/
dw_fluffos_v1/lib/binaries/cmds/
dw_fluffos_v1/lib/binaries/cmds/creator/
dw_fluffos_v1/lib/binaries/cmds/living/
dw_fluffos_v1/lib/binaries/cmds/player/
dw_fluffos_v1/lib/binaries/d/admin/obj/
dw_fluffos_v1/lib/binaries/d/liaison/
dw_fluffos_v1/lib/binaries/global/virtual/
dw_fluffos_v1/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v1/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v1/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v1/lib/binaries/obj/misc/
dw_fluffos_v1/lib/binaries/obj/misc/buckets/
dw_fluffos_v1/lib/binaries/obj/monster/
dw_fluffos_v1/lib/binaries/obj/reactions/
dw_fluffos_v1/lib/binaries/obj/reagents/
dw_fluffos_v1/lib/binaries/secure/cmds/creator/
dw_fluffos_v1/lib/binaries/secure/master/
dw_fluffos_v1/lib/binaries/std/
dw_fluffos_v1/lib/binaries/std/dom/
dw_fluffos_v1/lib/binaries/std/effects/object/
dw_fluffos_v1/lib/binaries/std/guilds/
dw_fluffos_v1/lib/binaries/std/languages/
dw_fluffos_v1/lib/binaries/std/races/
dw_fluffos_v1/lib/binaries/std/room/
dw_fluffos_v1/lib/binaries/std/room/basic/
dw_fluffos_v1/lib/binaries/std/shops/
dw_fluffos_v1/lib/binaries/std/shops/inherit/
dw_fluffos_v1/lib/binaries/www/
dw_fluffos_v1/lib/cmds/guild-race/
dw_fluffos_v1/lib/cmds/guild-race/crafts/
dw_fluffos_v1/lib/cmds/guild-race/other/
dw_fluffos_v1/lib/cmds/playtester/
dw_fluffos_v1/lib/cmds/playtester/senior/
dw_fluffos_v1/lib/d/admin/
dw_fluffos_v1/lib/d/admin/log/
dw_fluffos_v1/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v1/lib/d/admin/meetings/
dw_fluffos_v1/lib/d/admin/obj/
dw_fluffos_v1/lib/d/admin/room/we_care/
dw_fluffos_v1/lib/d/admin/save/
dw_fluffos_v1/lib/d/dist/
dw_fluffos_v1/lib/d/dist/mtf/
dw_fluffos_v1/lib/d/dist/pumpkin/
dw_fluffos_v1/lib/d/dist/pumpkin/chars/
dw_fluffos_v1/lib/d/dist/pumpkin/desert/
dw_fluffos_v1/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v1/lib/d/dist/pumpkin/hospital/
dw_fluffos_v1/lib/d/dist/pumpkin/inherit/
dw_fluffos_v1/lib/d/dist/pumpkin/map/
dw_fluffos_v1/lib/d/dist/pumpkin/plain/
dw_fluffos_v1/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v1/lib/d/dist/pumpkin/save/
dw_fluffos_v1/lib/d/dist/pumpkin/squash/
dw_fluffos_v1/lib/d/dist/pumpkin/terrain/
dw_fluffos_v1/lib/d/dist/pumpkin/woods/
dw_fluffos_v1/lib/d/dist/start/
dw_fluffos_v1/lib/d/learning/TinyTown/buildings/
dw_fluffos_v1/lib/d/learning/TinyTown/map/
dw_fluffos_v1/lib/d/learning/TinyTown/roads/
dw_fluffos_v1/lib/d/learning/add_command/
dw_fluffos_v1/lib/d/learning/arms_and_weps/
dw_fluffos_v1/lib/d/learning/chars/
dw_fluffos_v1/lib/d/learning/cutnpaste/
dw_fluffos_v1/lib/d/learning/examples/npcs/
dw_fluffos_v1/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v1/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v1/lib/d/learning/functions/
dw_fluffos_v1/lib/d/learning/handlers/
dw_fluffos_v1/lib/d/learning/help_topics/npcs/
dw_fluffos_v1/lib/d/learning/help_topics/objects/
dw_fluffos_v1/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v1/lib/d/learning/help_topics/rooms/
dw_fluffos_v1/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v1/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v1/lib/d/learning/items/
dw_fluffos_v1/lib/d/learning/save/
dw_fluffos_v1/lib/d/liaison/
dw_fluffos_v1/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v1/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v1/lib/db/
dw_fluffos_v1/lib/doc/
dw_fluffos_v1/lib/doc/creator/
dw_fluffos_v1/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v1/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v1/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v1/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v1/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v1/lib/doc/creator/autodoc/std/key/
dw_fluffos_v1/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v1/lib/doc/creator/autodoc/std/map/
dw_fluffos_v1/lib/doc/creator/autodoc/std/race/
dw_fluffos_v1/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v1/lib/doc/creator/files/
dw_fluffos_v1/lib/doc/creator/policy/
dw_fluffos_v1/lib/doc/creator/room/
dw_fluffos_v1/lib/doc/effects/
dw_fluffos_v1/lib/doc/ideas/
dw_fluffos_v1/lib/doc/known_command/
dw_fluffos_v1/lib/doc/lpc/basic_manual/
dw_fluffos_v1/lib/doc/lpc/intermediate/
dw_fluffos_v1/lib/doc/new/add_command/
dw_fluffos_v1/lib/doc/new/handlers/
dw_fluffos_v1/lib/doc/new/living/
dw_fluffos_v1/lib/doc/new/living/race/
dw_fluffos_v1/lib/doc/new/living/spells/
dw_fluffos_v1/lib/doc/new/player/
dw_fluffos_v1/lib/doc/new/room/guild/
dw_fluffos_v1/lib/doc/new/room/outside/
dw_fluffos_v1/lib/doc/new/room/storeroom/
dw_fluffos_v1/lib/doc/object/
dw_fluffos_v1/lib/doc/playtesters/
dw_fluffos_v1/lib/doc/policy/
dw_fluffos_v1/lib/doc/weapons/
dw_fluffos_v1/lib/global/handlers/
dw_fluffos_v1/lib/global/virtual/setup_compiler/
dw_fluffos_v1/lib/include/
dw_fluffos_v1/lib/include/cmds/
dw_fluffos_v1/lib/include/effects/
dw_fluffos_v1/lib/include/npc/
dw_fluffos_v1/lib/include/shops/
dw_fluffos_v1/lib/net/daemon/chars/
dw_fluffos_v1/lib/net/inherit/
dw_fluffos_v1/lib/net/intermud3/
dw_fluffos_v1/lib/net/intermud3/services/
dw_fluffos_v1/lib/net/obj/
dw_fluffos_v1/lib/net/save/
dw_fluffos_v1/lib/net/smnmp/
dw_fluffos_v1/lib/net/snmp/
dw_fluffos_v1/lib/obj/amulets/
dw_fluffos_v1/lib/obj/b_day/
dw_fluffos_v1/lib/obj/examples/
dw_fluffos_v1/lib/obj/food/alcohol/
dw_fluffos_v1/lib/obj/food/chocolates/
dw_fluffos_v1/lib/obj/food/fruits/
dw_fluffos_v1/lib/obj/food/meat/
dw_fluffos_v1/lib/obj/food/nuts/
dw_fluffos_v1/lib/obj/food/seafood/
dw_fluffos_v1/lib/obj/food/vegetables/
dw_fluffos_v1/lib/obj/fungi/
dw_fluffos_v1/lib/obj/furnitures/artwork/
dw_fluffos_v1/lib/obj/furnitures/bathroom/
dw_fluffos_v1/lib/obj/furnitures/beds/
dw_fluffos_v1/lib/obj/furnitures/cabinets/
dw_fluffos_v1/lib/obj/furnitures/chairs/
dw_fluffos_v1/lib/obj/furnitures/chests/
dw_fluffos_v1/lib/obj/furnitures/clocks/
dw_fluffos_v1/lib/obj/furnitures/crockery/
dw_fluffos_v1/lib/obj/furnitures/cupboards/
dw_fluffos_v1/lib/obj/furnitures/cushions/
dw_fluffos_v1/lib/obj/furnitures/fake_plants/
dw_fluffos_v1/lib/obj/furnitures/lamps/
dw_fluffos_v1/lib/obj/furnitures/mirrors/
dw_fluffos_v1/lib/obj/furnitures/outdoor/
dw_fluffos_v1/lib/obj/furnitures/safes/
dw_fluffos_v1/lib/obj/furnitures/shelves/
dw_fluffos_v1/lib/obj/furnitures/sideboards/
dw_fluffos_v1/lib/obj/furnitures/sofas/
dw_fluffos_v1/lib/obj/furnitures/stoves/
dw_fluffos_v1/lib/obj/furnitures/tables/
dw_fluffos_v1/lib/obj/furnitures/wardrobes/
dw_fluffos_v1/lib/obj/handlers/
dw_fluffos_v1/lib/obj/handlers/autodoc/
dw_fluffos_v1/lib/obj/jewellery/anklets/
dw_fluffos_v1/lib/obj/jewellery/bracelets/
dw_fluffos_v1/lib/obj/jewellery/earrings/
dw_fluffos_v1/lib/obj/jewellery/misc/
dw_fluffos_v1/lib/obj/jewellery/necklaces/
dw_fluffos_v1/lib/obj/jewellery/rings/
dw_fluffos_v1/lib/obj/media/
dw_fluffos_v1/lib/obj/misc/buckets/
dw_fluffos_v1/lib/obj/misc/jars/
dw_fluffos_v1/lib/obj/misc/papers/
dw_fluffos_v1/lib/obj/misc/player_shop/
dw_fluffos_v1/lib/obj/misc/shops/
dw_fluffos_v1/lib/obj/misc/traps/
dw_fluffos_v1/lib/obj/monster/
dw_fluffos_v1/lib/obj/monster/godmother/
dw_fluffos_v1/lib/obj/monster/transport/
dw_fluffos_v1/lib/obj/plants/inherit/
dw_fluffos_v1/lib/obj/potions/
dw_fluffos_v1/lib/open/boards/
dw_fluffos_v1/lib/save/autodoc/
dw_fluffos_v1/lib/save/bank_accounts/
dw_fluffos_v1/lib/save/boards/frog/
dw_fluffos_v1/lib/save/books/bed_catalog/
dw_fluffos_v1/lib/save/creators/
dw_fluffos_v1/lib/save/mail/
dw_fluffos_v1/lib/save/mail/p/
dw_fluffos_v1/lib/save/newsrc/b/
dw_fluffos_v1/lib/save/newsrc/c/
dw_fluffos_v1/lib/save/newsrc/d/
dw_fluffos_v1/lib/save/newsrc/f/
dw_fluffos_v1/lib/save/newsrc/p/
dw_fluffos_v1/lib/save/newsrc/s/
dw_fluffos_v1/lib/save/newsrc/w/
dw_fluffos_v1/lib/save/players/c/
dw_fluffos_v1/lib/save/players/d/
dw_fluffos_v1/lib/save/players/g/
dw_fluffos_v1/lib/save/players/p/
dw_fluffos_v1/lib/save/players/s/
dw_fluffos_v1/lib/save/soul/data/
dw_fluffos_v1/lib/save/tasks/
dw_fluffos_v1/lib/save/vaults/
dw_fluffos_v1/lib/secure/cmds/lord/
dw_fluffos_v1/lib/secure/config/
dw_fluffos_v1/lib/secure/items/
dw_fluffos_v1/lib/secure/player/
dw_fluffos_v1/lib/soul/
dw_fluffos_v1/lib/soul/i/
dw_fluffos_v1/lib/soul/j/
dw_fluffos_v1/lib/soul/k/
dw_fluffos_v1/lib/soul/o/
dw_fluffos_v1/lib/soul/q/
dw_fluffos_v1/lib/soul/to_approve/
dw_fluffos_v1/lib/soul/u/
dw_fluffos_v1/lib/soul/v/
dw_fluffos_v1/lib/soul/wish_list/
dw_fluffos_v1/lib/soul/y/
dw_fluffos_v1/lib/soul/z/
dw_fluffos_v1/lib/std/creator/
dw_fluffos_v1/lib/std/effects/
dw_fluffos_v1/lib/std/effects/attached/
dw_fluffos_v1/lib/std/effects/external/
dw_fluffos_v1/lib/std/effects/fighting/
dw_fluffos_v1/lib/std/effects/other/
dw_fluffos_v1/lib/std/environ/
dw_fluffos_v1/lib/std/guilds/
dw_fluffos_v1/lib/std/hospital/
dw_fluffos_v1/lib/std/house/
dw_fluffos_v1/lib/std/house/onebedhouse/
dw_fluffos_v1/lib/std/house/onebedhut/
dw_fluffos_v1/lib/std/house/tworoomflat/
dw_fluffos_v1/lib/std/languages/
dw_fluffos_v1/lib/std/liquids/
dw_fluffos_v1/lib/std/nationality/
dw_fluffos_v1/lib/std/nationality/accents/
dw_fluffos_v1/lib/std/nationality/accents/national/
dw_fluffos_v1/lib/std/nationality/accents/regional/
dw_fluffos_v1/lib/std/npc/goals/
dw_fluffos_v1/lib/std/npc/goals/basic/
dw_fluffos_v1/lib/std/npc/goals/misc/
dw_fluffos_v1/lib/std/npc/inherit/
dw_fluffos_v1/lib/std/npc/plans/
dw_fluffos_v1/lib/std/npc/plans/basic/
dw_fluffos_v1/lib/std/outsides/
dw_fluffos_v1/lib/std/races/shadows/
dw_fluffos_v1/lib/std/room/basic/topography/
dw_fluffos_v1/lib/std/room/controller/
dw_fluffos_v1/lib/std/room/controller/topography/
dw_fluffos_v1/lib/std/room/furniture/games/
dw_fluffos_v1/lib/std/room/furniture/inherit/
dw_fluffos_v1/lib/std/room/inherit/carriage/
dw_fluffos_v1/lib/std/room/inherit/topography/
dw_fluffos_v1/lib/std/room/punishments/
dw_fluffos_v1/lib/std/room/topography/area/
dw_fluffos_v1/lib/std/room/topography/iroom/
dw_fluffos_v1/lib/std/room/topography/milestone/
dw_fluffos_v1/lib/std/shadows/
dw_fluffos_v1/lib/std/shadows/attached/
dw_fluffos_v1/lib/std/shadows/curses/
dw_fluffos_v1/lib/std/shadows/disease/
dw_fluffos_v1/lib/std/shadows/fighting/
dw_fluffos_v1/lib/std/shadows/room/
dw_fluffos_v1/lib/std/shops/controllers/
dw_fluffos_v1/lib/std/shops/objs/
dw_fluffos_v1/lib/std/shops/player_shop/
dw_fluffos_v1/lib/std/shops/player_shop/office_code/
dw_fluffos_v1/lib/std/socket/
dw_fluffos_v1/lib/www/
dw_fluffos_v1/lib/www/external/autodoc/
dw_fluffos_v1/lib/www/external/java/telnet/Documentation/
dw_fluffos_v1/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v1/lib/www/external/java/telnet/examples/
dw_fluffos_v1/lib/www/external/java/telnet/tools/
dw_fluffos_v1/lib/www/pics/
dw_fluffos_v1/lib/www/secure/creator/
dw_fluffos_v1/lib/www/secure/editors/
dw_fluffos_v1/lib/www/secure/survey_results/
/******************************************************************************
 * This file contains the personnel related functions
 *****************************************************************************/

/**
 * @ignore yes 
 * Adds a new employee.
 * Also prevent the employee from receiving a bonus until they have
 * worked a full month by setting EMP_NOBONUS to 1.
 * @param player the employee to add
 */
private void add_employee(string player)
{
    if (!_employees[player])
    {
        _employees += ([player:EMP_MAP]);
        _employees[player][EMP_NOBONUS] = 1;
        set_emp_time(player);
        _got_bonus += ({player});
        save_me();
        save_emps();
    }
}
/* add_employee() */

/**
 * @ignore yes 
 * Demote a manager or supervisor.
 * @param demoter the person doing the demoting
 * @param demotee the person being demoted
 */
private void demote(string demoter, string demotee)
{
    int points = _employees[demotee][EMP_POINTS] & CLOCKED_IN;
    if (_employees[demotee][EMP_POINTS] & MANAGER)
        points += (SUPER_POINTS * 32) + EMPLOYEE + SUPERVISOR;      
    else points += EMPLOYEE;
    _employees[demotee][EMP_POINTS] = points;
    save_emps();
    PLAYER_SHOP->auto_mail(demotee, _proprietor, "Demotion", "",
      "This is to advise you that you have today been demoted.\n"
      "This demotion will now stay on your employment record.\n");
    employee_log(demotee, "Demoted by "+ demoter);
    shop_log(PERSONNEL, demoter, "demoted "+ cap_name(demotee), PAID);
}
/* demote() */

/**
 * @ignore yes 
 * Managers' office.
 * Commend employees.  Adds 5% of their promotion target.
 */
int do_commend(string emp)
{
    string commender;

    if (!_employees[emp])
    {
        tell_object(this_player(), cap_name(emp)+
          " is not an active employee!\n");
        return 1;
    }
    if (_employees[emp][EMP_POINTS] & MANAGER)
    {
        tell_object(this_player(), "You can't commend a manager.\n");
        return 1;
    }
    if (_employees[emp][EMP_POINTS] & NPC)
    {
        tell_object(this_player(), "Don't be silly!  "
          "You can't commend $C$"+ emp +".\n");
        return 1;
    }
    commender = this_player()->query_cap_name();
    AUTO_MAILER->auto_mail(emp, lower_case(commender), "Commendation",
      "", "This is to advise you that you have today received a "
      "commendation for outstanding service.\nThis will now stay on "
      "your employment record.\n");
    employee_log(emp, "Received a commendation from "+ commender);
    shop_log(PERSONNEL, commender, "commended "+ cap_name(emp), PAID);
    _employees[emp][EMP_POINTS] += (_employees[emp][EMP_POINTS] & SUPERVISOR)?
    to_int(MANAGER_POINTS * 0.05 * 32) : to_int(SUPER_POINTS * 0.05 * 32);
    save_emps();
    tell_object(this_player(), "You commend "+ cap_name(emp)+ ".\n");
    return 1;
}
/* do_commend() */

/**
 * @ignore yes 
 * Managers' office.
 * Demote supervisors or managers.
 */
int do_demote(string emp)
{
    object tp = this_player();
    emp = lower_case(emp);
    if (!_employees[emp])
    {
        tell_object(tp, cap_name(emp)+ " is not an active employee!\n");
        return 1;
    }
    if (_employees[emp][EMP_POINTS] & MANAGER && !tp->query_creator())
    {
        tell_object(tp, "You don't have the authority to "
          "demote $C$"+ emp +".\n");
        return 1;
    }
    if (!( _employees[emp][EMP_POINTS] & SUPERVISOR))
    {
        tell_object(tp, "Don't be silly!  You can't demote $C$"+
          emp +".\n");
        return 1;
    }
    demote(tp->query_cap_name(), emp);
    tell_object(tp, "You demote "+ cap_name(emp)+ ".\n");
    return 1;
}
/* do_demote() */

/**
 * @ignore yes 
 * Managers' office.
 * Fire an employee.
 */
int do_fire(mixed *args)
{
    args[0] = lower_case(args[0]);
    if (!_employees[args[0]])
    {
        tell_object(this_player(), cap_name(args[0])+
          " doesn't work at the shop!\n");
        return 1;
    }
    if ((member_array(args[0], _retired) != -1) ||
      query_manager(args[0]) && !this_player()->query_creator())
    {
        tell_object(this_player(), "You don't have the authority "
          "to fire $C$"+ args[0] +".\n");
        return 1;
    }
    if (_employees[args[0]][EMP_POINTS] & NPC)
    {
        tell_object(this_player(), "Don't be silly!  You can't fire $C$"+
          args[0] +".\n");
        return 1;
    }
    fire_them(this_player()->query_name(), args[0], args[1]);
    tell_object(this_player(), "You fire "+ cap_name(args[0])+
      " for "+ args[1]+ ".\n" );
    return 1;
}
/* do_fire() */

/**
 * @ignore yes 
 * Managers' office.
 * Place an employee on leave.
 */
int do_leave(mixed *args)
{
    object tp = this_player();
    args[0] = lower_case(args[0]);
    if (!_employees[args[0]])
    {
        tell_object(tp, cap_name(args[0])+ " is not an employee!\n");
        return 1;
    }
    if (args[1] > MAX_LEAVE)
    {
        tell_object(tp, "You cannot place an employee on leave "
          "for more than "+ MAX_LEAVE+ " days at a time.\n");
        return 1;
    }
    _times[args[0]] = time() + (args[1] * 86400);
    remove_call_out(_call_times);
    _call_times = call_out((: save_times() :), PERS_DELAY);
    add_succeeded_mess(cap_name(args[0])+
      " is on leave until "+ ctime(time() + (args[1] * 86400))+ ".\n");
    shop_log(PERSONNEL, tp->query_name(), "placed "+
      cap_name(args[0])+ " on leave for " + args[1]+ " days", PAID);
    employee_log(args[0], "Placed on leave by "+ tp->query_cap_name()+
      " for "+ args[1]+ " days.");
    tell_object(tp, "You place "+ cap_name(args[0])+
      " on leave for " + args[1]+ " days.\n");
    return 1;
}
/* do_leave() */

/**
 * @ignore yes 
 * This employee has requested to be passed over (or not) for promotion.
 */
private int do_promote(string on)
{
    object tp = this_player();
    add_succeeded_mess("");
    if (tp->query_creator())
    {
        tell_object(tp, "Creators don't get promoted.\n");
        return 1;
    }
    switch (on)
    {
    case "off" :
        _employees[tp->query_name()][EMP_NOPROMOTE] = TRUE;
        tell_object(tp, "You have now requested to be "
          "passed over for promotion.\n");
        break;
    case "on" :
        if (tp->query_property("no score"))
        {
            tell_object(tp, "Sorry, you cannot be promoted.\n");
            return 1;
        }
        _employees[tp->query_name()][EMP_NOPROMOTE] = FALSE;
        tell_object(tp, "You have now requested to be "
          "considered for promotion.\n");
        break;
    }
    save_emps();
    return 1;
}
/* do_promote() */

/**
 * @ignore yes 
 * Employee wishes to terminate their employment with the shop.
 */
private int do_resign()
{
    string word = this_player()->query_name();

    add_succeeded_mess("$N $V.\n");
    remove_employee(word);
    shop_log(PERSONNEL, word, "resigned", UNPAID);
    employee_log(word, "Resigned");
    return 1;
}
/* do_resign() */

/**
 * @ignore yes 
 * Managers' office.
 * Retire from management.
 */
int do_retire()
{
    string manager = this_player()->query_name();
    if (!(_employees[manager][EMP_POINTS] & MANAGER)) return 0;
    remove_employee(manager);
    _retired += ({manager});
    shop_log(PERSONNEL, manager, "retired from management", UNPAID);
    employee_log(manager, "Retired from management");
    save_me();
    add_succeeded_mess("$N retire$s.\n");
    return 1;
}
/* do_retire() */

/**
 * @ignore yes 
 * Managers' office.
 * Suspend employee's bonus for x months.
 */
int do_suspend(mixed *args)
{
    string suspender;
    object tp = this_player();

    args[0] = lower_case(args[0]);
    if (!_employees[args[0]])
    {
        tell_object(tp, cap_name(args[0])+ " is not an active employee!\n");
        return 1;
    }
    if ((_employees[args[0]][EMP_POINTS] & MANAGER) && 
      (!tp->query_creator()))
    {
        tell_object(tp, "You don't have the authority to "
          "suspend $C$"+ args[0] +"'s bonus.\n");
        return 1;
    }
    if (_employees[args[0]][EMP_POINTS] & NPC)
    {
        tell_object(tp, "Don't be silly!  "
          "You can't suspend $C$"+ args[0] +"'s bonus.\n");
        return 1;
    }
    suspender = tp->query_cap_name();
    _employees[args[0]][EMP_NOBONUS] = args[1];
    save_emps();
    AUTO_MAILER->auto_mail(args[0], _proprietor, "Suspended bonus", "",
      sprintf( "This is to advise you that you have had your bonus "
        "entitlement suspended for %d month%s.\nThis suspension will "
        "now stay on your employment record.\n", args[1],
        (args[1] == 1)?"":"s"));
    employee_log(args[0], sprintf("Bonus suspended for %d month%s by %s",
        args[1], (args[1] == 1)?"":"s", suspender));
    shop_log(PERSONNEL, suspender,
      sprintf("suspended %s's bonus for %d month%s", args[0],
        args[1], (args[1] == 1)?"":"s"), PAID);
    tell_object(tp, "You suspend "+ cap_name(args[0])+
      "'s bonus for "+ args[1]+ " months.\n");
    return 1;
}
/* do_suspend() */

/**
 * @ignore yes 
 * Managers' office.
 * Warn employees.  Removes 5% of their promotion target.
 */
int do_warn(mixed *args)
{
    string warner;
    object tp = this_player();
    int points;

    args[0] = lower_case(args[0]);
    if (!_employees[args[0]])
    {
        tell_object(tp, cap_name(args[0])+ " is not an active employee!\n");
        return 1;
    }
    if (_employees[args[0]][EMP_POINTS] & MANAGER && !tp->query_creator() )
    {
        tell_object( tp, "You don't have the authority to "
          "warn $C$"+ args[0] +".\n" );
        return 1;
    }
    if (_employees[args[0]][EMP_POINTS] & NPC)
    {
        tell_object(tp, "Don't be silly!  You can't warn $C$"+ args[0] +".\n");
        return 1;
    }
    warner = tp->query_cap_name();
    AUTO_MAILER->auto_mail(args[0], _proprietor, "Official warning", "",
      "This is to advise you that you have today received a formal "
      "warning for " + args[1] + ".\nThis warning will now stay on "
      "your employment record.\n");
    employee_log(args[0], "Received a warning from "+ warner+ 
      " for "+ args[1]);
    shop_log(PERSONNEL, warner, "warned "+
      cap_name( args[0] ) + " for "+ args[1], PAID);
    points = _employees[args[0]][EMP_POINTS] & CLOCKED_IN;
    if (_employees[args[0]][EMP_POINTS] & SUPERVISOR)
        _employees[args[0]][EMP_POINTS] -= to_int(MANAGER_POINTS * 0.05 * 32);
    else
    {
        _employees[args[0]][EMP_POINTS] -= to_int(SUPER_POINTS * 0.05 * 32) +
        EMPLOYEE;
        if (_employees[args[0]][EMP_POINTS] < 1)
            _employees[args[0]][EMP_POINTS] = EMPLOYEE + points;
    }
    save_emps();
    tell_object(tp, "You warn "+ cap_name(args[0])+ " for "+
      args[1]+ ".\n");
    return 1;
}
/* do_warn() */

/**
 * @ignore yes 
 * Used when employees are fired by managers, or automatically.
 * @param word the person doing the firing
 * @param them the person being fired
 * @param reason the reason for being fired
 */
private void fire_them(string word, string them, string reason)
{
    if (!_employees[them]) return;
    BANK_HANDLER->adjust_account(them, BANKS[_employees[them][EMP_BANK]][1],
      _employees[them][EMP_PAY]);
    shop_log(ACCOUNTS, _proprietor, "paid "+ 
      MONEY_HAND->money_value_string(_employees[them][EMP_PAY], _place)+
      " to "+ cap_name(them), UNPAID);
    shop_log(PERSONNEL, word, "fired "+ cap_name(them) +
      " for "+ reason, PAID);
    PLAYER_SHOP->auto_mail(them, word, _shop_name, "", 
      "Unfortunately, I have to inform you that you have today "
      "been fired for " + reason + ".  You have been paid the sum of "+
      MONEY_HAND->money_value_string( _employees[them][EMP_PAY], _place )+
      " for the work you have carried out to this date.\nIf you feel you "
      "have been unfairly dismissed, please refer to a manager.\n");
    employee_log(them, "Fired by "+ cap_name(word)+
      " for "+ reason);
    remove_employee(them);
}
/* fire_them() */

/**
 * @ignore yes 
 * Used when applicant has sufficient supporting votes to be accepted.
 * @param word the person to hire
 */
private void hire(string word)
{
    int gender;

    remove_applicant(word);

    /* Do not hire if not a user, already an employee, or banned */
    if (!test_player(word) || _employees[word] || query_baddie(word)) return;

    add_employee(word);
    employee_log(word, "Hired");
    shop_log(PERSONNEL, _proprietor, "hired "+ cap_name(word), UNPAID);
    PLAYER_SHOP->auto_mail(word, _proprietor, _shop_name, "", 
      "Congratulations!  You've been hired to work at "+ _shop_name+
      ".  You'll find that you can now move through the counter "
      "to the back areas of the shop.  The first things you should "
      "do are \"claim\" a new badge and staff handbook.\n");
    gender = PLAYER_HANDLER->test_gender(word);
    add_board_message("New employee", sprintf("%s has today been employed to "
        "work for the shop.  Please make %s feel welcome, and assist %s while "
        "%s gets started in %s new position.\n", cap_name(word),
        ({"it", "him", "her"})[gender] ,({"it", "him", "her"})[gender],
        ({"it", "he", "she"})[gender], ({"its", "his", "her"})[gender]));

    /* Update the other accepted applicants */
    remove_call_out(_call_mail_hirees);
    _call_mail_hirees = call_out((: mail_hirees() :), 5);
}
/* hire() */

/**
 * @ignore yes 
 * Used by the employee list to show managers & creators the last
 * time an employee was active.  Employees will be highlighted yellow
 * if they are currently on an inactivity warning, and red if they are
 * within 7 days of being fired/demoted
 * @param emp the employee to query
 */
private string query_worked(string emp)
{
    string blurb;

    /* Clocked in */
    if (_employees[emp][EMP_POINTS] & CLOCKED_IN)
        return " is currently clocked in";

    /* NPC */
    if (_employees[emp][EMP_POINTS] & NPC)
        return " has gone home for tea";

    /* On leave */
    if (_times[emp] > time())
        return " - %^CYAN%^on leave until "+ ctime(_times[emp])+ "%^RESET%^";

    blurb = " - last action ";

    if (_employees[emp][EMP_POINTS] & MANAGER)
    {
        if ((time() - _times[emp]) > ((60*60*24*MGR_DEMOTE)-7))
            blurb += "%^RED%^"; 
        else if ((time() - _times[emp]) > (60*60*24*MGR_WARN))
            blurb += "%^RED%^"; 
    }
    else if (_employees[emp][EMP_POINTS] & SUPERVISOR)
    {
        if (( time() - _times[emp]) > ((60*60*24*SPR_DEMOTE)-7))
            blurb += "%^RED%^"; 
        else if ((time() - _times[emp]) > (60*60*24*SPR_WARN))
            blurb += "%^YELLOW%^"; 
    }
    else if (( time() - _times[emp]) > ((60*60*24*EMP_FIRE)-7))
        blurb += "%^RED%^";
    else if ((time() - _times[emp]) > (60*60*24*EMP_WARN))
        blurb += "%^YELLOW%^";
    return blurb + ctime(_times[emp])+ "%^RESET%^";
}
/* query_worked() */

/**
* @ignore yes 
* Sets the last action time of an employee.
* This time is the last time an employee did something worth
* recording and is used to determine if they are inactive.
* @param employee The employee.
*/
private void set_emp_time(string employee)
{
    if (!_employees[employee]) return;
    if (_employees[employee][EMP_INACTIVE])
    {
        _employees[employee][EMP_INACTIVE] = 0;   // Reset inactivity flag
        save_emps();
    }
    if (!sizeof(_times)) _times = ([employee:0]);
    else if (!_times[employee]) _times += ([employee:0]);
    _times[employee] = time();
    remove_call_out(_call_times);
    _call_times = call_out((: save_times() :), PERS_DELAY);
}
/* set_emp_time() */

/**
 * @ignore yes 
 * View an employee's history or an applicant's application.
 * This method displays a formatted display of the employee's history
 * with a particular shop, and is viewable by managers of that shop.
 * If passed the name of an applicant, it will view the relevant application.
 * @param person The employee or applicant.
 */
void view_record(string person, string pattern)
{   
    if (pattern == VIEW_EMP)
    {
        string text = sprintf("Employment history of %s:\n\n", cap_name(person));
        load_history();
        if (!sizeof(_history) || !_history[person])
        {
            tell_object(this_player(), "There is no history for that person.\n");
            return;
        }
        for(int i = 0; i < sizeof(_history[person][0]); i++)
            text += sprintf("%s: %s\n", ctime(_history[person][0][i]),
              _history[person][1][i]); 
        tell_object(this_player(), sprintf("$P$%s's history$P$%s",
            cap_name(person), text));
        clear_history();
    }
    else
    {
        if (!query_applicant(person))
        {
            tell_object(this_player(), "That person has no application form "
              "on file.\n");
            return;
        }
        load_applicants();
        tell_object(this_player(),
          sprintf("$P$%s's history$P$Application of %s:\n\n%s", cap_name(person),
            cap_name(person), _applicants[person][APP_MESSAGE]));
        clear_applicants();
    }
}
/* view_record() */