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

private mapping _motions;
private mapping _new_citizens;
private int _completion_id;

void save_me();
class nomic_motion find_motion(string area, int rule_no, int type);
void update_immutables(string area);
void send_council_inform(string area, int only_magistrates,
                         string mess);
string motion_as_string(int indent, string area, class nomic_motion motion, int brief);

void create() {
   _motions = ([ ]);
   _new_citizens = ([ ]);
   citizen_elections::create();
   nomic_rules::create();
   case_control::create();

   //
   // Check for motion completions at midnight... (well, 2 minutes after).
   //
   _completion_id = call_out("check_for_completions",
       (time() - time() % (24 * 60 * 60) + (24 * 60 * 60) + (2 * 60)) - time());
} /* create() */

/**
 * This method creates a new area.
 * @param area the new area
 */
void create_area(string area) {
   citizen_elections::create_area(area);
   nomic_rules::create_area(area);
   case_control::create_area(area);

   _motions[area] = ({ });
   _new_citizens[area] = ({ });
   update_immutables(area);
} /* create_area() */

/**
 * This method updates the immutable laws with the new set of general rules.
 * @param area the area to update.
 */
void update_immutables(string area) {
   string tmp;
   string type;
   string file;
   int int_type;
   class nomic_rule rule;

   //
   // Get rid of the old immutables first.
   //
   foreach (rule in query_all_nomic_rules(area)) {
      if (rule->type == NOMIC_TYPE_IMMUTABLE) {
         remove_nomic_rule(area, rule->id);
      }
   }

   //
   // Add in all the default rules.
   //
   foreach (file in get_dir(NOMIC_RULE_DEFAULT_DIR)) {
      if (file_size(NOMIC_RULE_DEFAULT_DIR + "/" + file) > 0) {
         tmp = read_file(NOMIC_RULE_DEFAULT_DIR + "/" + file);
         type = explode(tmp, "\n")[0];
         tmp = implode(explode(tmp, "\n")[1..], "\n");
         switch (type) {
         case "immutable" :
            int_type = NOMIC_TYPE_IMMUTABLE;
            break;
         case "citizen" :
            int_type = NOMIC_TYPE_CITIZEN;
            break;
         case "general" :
            int_type = NOMIC_TYPE_GENERAL;
            break;
         default :
            int_type = -1;
            printf("Ignoring file " + file + "\n");
            break;
         }
         if (int_type != -1) {
            add_nomic_rule(area, int_type, area + " administrator", tmp);
         }
      }
   }
   save_me();
} /* create_area() */

private int query_next_motion_id(string area) {
   int num;
   class nomic_motion fluff;

   num = 1;
   foreach (fluff in _motions[area]) {
      if (num <= fluff->identifier) {
         num = fluff->identifier + 1;
      }
   }

   return num;
} /* query_next_motion_id() */

/**
 * This method puts a new rule up for voting.  It is first placed into
 * the hands of the magistrates, then into the hands of the players.
 * @param area the area for the rule to be voted on in
 * @param type the type of the rules
 * @param text the text associated with the new rule
 * @return 1 on success, 0 on failure
 */
int add_create_rule_motion(string area, int type, string text,
                          string creator) {
   class nomic_motion fluff;

   if (!is_magistrate_of(area, creator)) {
      return 0;
   }
   fluff = new(class nomic_motion);
   fluff->motion_type = NOMIC_MOTION_TYPE_RULE_ADD;
   fluff->rule = new(class nomic_rule);
   fluff->rule->creator = creator;
   fluff->rule->text = text;
   fluff->rule->type = type;
   fluff->rule->amendments = ({ });
   fluff->rule->date_created = time();
   fluff->comments = ({ });
   fluff->voted = ({ });
   fluff->state = NOMIC_STATE_COUNCIL_REVIEW;
   fluff->date_added = time();
   fluff->date_event = time();
   fluff->yes_votes = 0;
   fluff->no_votes = 0;
   fluff->added_by = creator;
   fluff->identifier = query_next_motion_id(area);
   _motions[area] += ({ fluff });
   save_me();
   send_council_inform(area, 1, creator + " added a new rule motion");
   post_magistrate_message(area, "New: Create rule motion",
              PLAYER_OB->convert_message(motion_as_string(0, area, fluff, 0)));
   return 1;
} /* add_motion_for_voting() */

/**
 * This method puts up a request to move a rule from one type to another.
 * @param area the area to do the move in
 * @param rule_no the rule number to move
 * @param type the type to move the rule to
 * @param creator the creator of this request
 * @return 1 on success, 0 on failure
 */
int add_move_rule_type_motion(string area, int rule_no, int type,
                              string creator) {
   class nomic_motion fluff;
   class nomic_rule bing;

   bing = query_nomic_rule(area, rule_no);
   if (!bing) {
      return 0;
   }

   if (bing->type == type) {
      return 0;
   }

   //
   // First check and see if are alread moveing this rule.
   //
   fluff = find_motion(area, rule_no, NOMIC_MOTION_TYPE_RULE_MOVE);
   if (fluff) {
      return 0;
   }

   fluff = new(class nomic_motion);
   fluff->motion_type = NOMIC_MOTION_TYPE_RULE_MOVE;
   fluff->rule = bing;
   fluff->new_rule_type = type;
   fluff->comments = ({ });
   fluff->voted = ({ });
   fluff->state = NOMIC_STATE_COUNCIL_REVIEW;
   fluff->date_added = time();
   fluff->date_event = time();
   fluff->yes_votes = 0;
   fluff->no_votes = 0;
   fluff->added_by = creator;
   fluff->identifier = query_next_motion_id(area);
   _motions[area] += ({ fluff });
   save_me();
   send_council_inform(area, 1, creator + " added a move rule motion");
   post_magistrate_message(area, "New: Move rule motion",
              PLAYER_OB->convert_message(motion_as_string(0, area, fluff, 0)));
   return 1;
} /* add_move_rule_type() */

/**
 * This method adds in a request to amend a rule.
 * @param area the area to put the amendment in
 * @param rule_no the rule to amend
 * @param amendment the amendment text
 * @param creator the person doing the amendment
 * @return 1 on success, 0 on failure
 */
int add_amend_rule_motion(string area, int rule_no, string amendment,
                           string creator) {
   class nomic_motion fluff;
   class nomic_rule bing;
   class nomic_amendment amend;

   bing = query_nomic_rule(area, rule_no);
   if (!bing) {
      return 0;
   }

   //
   // First check and see if are already amending this rule.
   //
   fluff = find_motion(area, rule_no, NOMIC_MOTION_TYPE_RULE_AMEND);
   if (fluff) {
      return 0;
   }

   fluff = new(class nomic_motion);
   fluff->motion_type = NOMIC_MOTION_TYPE_RULE_AMEND;
   amend = new (class nomic_amendment);
   amend->amender = creator;
   amend->text = amendment;
   amend->date_amended = time();
   bing->amendments += ({ amend });
   fluff->rule = bing;
   fluff->comments = ({ });
   fluff->voted = ({ });
   fluff->state = NOMIC_STATE_COUNCIL_REVIEW;
   fluff->date_added = time();
   fluff->date_event = time();
   fluff->yes_votes = 0;
   fluff->no_votes = 0;
   fluff->added_by = creator;
   fluff->identifier = query_next_motion_id(area);
   _motions[area] += ({ fluff });
   save_me();
   send_council_inform(area, 1, creator + " added an add rule motion");
   post_magistrate_message(area, "New: Ammend rule motion",
              PLAYER_OB->convert_message(motion_as_string(0, area, fluff, 0)));
   return 1;
} /* add_rule_amendment() */

/**
 * This method remove a request to amend a rule.
 * @param area the area to put the amendment in
 * @param rule_no the rule to amend
 * @param amendment the amendment text
 * @param creator the person doing the amendment
 * @return 1 on success, 0 on failure
 */
int remove_rule_motion(string area, int rule_no, string creator) {
   class nomic_motion fluff;
   class nomic_rule bing;

   bing = query_nomic_rule(area, rule_no);
   if (!bing) {
      return 0;
   }

   //
   // First check and see if are alread removeing this rule.
   //
   fluff = find_motion(area, rule_no, NOMIC_MOTION_TYPE_RULE_REMOVE);
   if (fluff) {
      return 0;
   }

   fluff = new(class nomic_motion);
   fluff->motion_type = NOMIC_MOTION_TYPE_RULE_REMOVE;
   fluff->rule = bing;
   fluff->comments = ({ });
   fluff->voted = ({ });
   fluff->state = NOMIC_STATE_COUNCIL_REVIEW;
   fluff->date_added = time();
   fluff->date_event = time();
   fluff->yes_votes = 0;
   fluff->no_votes = 0;
   fluff->added_by = creator;
   fluff->identifier = query_next_motion_id(area);
   _motions[area] += ({ fluff });
   save_me();
   send_council_inform(area, 1, creator + " added a remove rule motion");
   post_magistrate_message(area, "New: Remove rule motion",
              PLAYER_OB->convert_message(motion_as_string(0, area, fluff, 0)));
   return 1;
} /* remove_rule_motion() */

/**
 * This method returns a nice new rule.
 * @param area the areat to look in
 * @param id the id of the new rule to find
 * @return 1 on success, 0 on failure
 */
class nomic_motion query_motion(string area, int id) {
   class nomic_motion fluff;

   if (!_motions[area]) {
      return 0;
   }

   foreach (fluff in _motions[area]) {
      if (fluff->identifier == id) {
         return fluff;
      }
   }

   return 0;
} /* query_motion() */

/**
 * This method returns all the new rules for the specified area.
 * @param area the area to return the new rules in
 * @return the array of new rules
 */
class nomic_motion* query_all_motions(string area) {
   if (!_motions[area]) {
      return ({ });
   }

   return copy(_motions[area]);
} /* query_all_motions() */

/**
 * This method finds the specified motion.
 * @param area the area to look in
 * @param rule_no the rule number
 * @param type the type of the motion
 * @return the motion if successful, 0 if not
 */
class nomic_motion find_motion(string area, int rule_no, int type) {
   class nomic_motion motion;

   foreach (motion in _motions[area]) {
      if (motion->rule->id == rule_no &&
          motion->motion_type == type) {
         return motion;
      }
   }
   return 0;
} /* find_motion() */

/**
 * This method adds a comment to the new rule/amendment/whatever.
 * @param area the area the comment is to go in
 * @param id the rule update id
 * @param comment the comment to make
 * @param commenter the person commenting
 * @return 1 on success, 0 on failure
 */
int comment_on_motion(string area, int id, string comment_text,
                            string commenter) {
   class nomic_comment comment; 
   class nomic_motion bing;
   
   bing = query_motion(area, id);
   if (!bing) {
      return 0;
   }

   if (bing->state != NOMIC_STATE_COUNCIL_REVIEW &&
       bing->state != NOMIC_STATE_COUNCIL_VOTE) {
      return 0;
   }

   comment = new(class nomic_comment);
   comment->text = comment_text;
   comment->commenter = commenter;
   comment->date_commented = time();
   bing->comments += ({ comment });
   save_me();
   return 1;
} /* add_motion_update_comment() */

/**
 * This method adds an amendment to the new rule/amendment/whatever, this
 * rewrites the text of the ammendment of whatever it is.
 * @param area the area the amendmend is to go in
 * @param id the rule update id
 * @param amendmend the amendmend to make
 * @param amendmender the person amendmending
 * @return 1 on success, 0 on failure
 */
int amend_motion(string area, int id, string amend_text,
                    string amender) {
   //class nomic_amendment amend;
   class nomic_motion bing;
   
   bing = query_motion(area, id);
   if (!bing) {
      return 0;
   }

   // This only works in the review phase.
   if (bing->state != NOMIC_STATE_COUNCIL_REVIEW) {
      return 0;
   }

/*
   amend = new(class nomic_amendment);
   amend->text = amend_text;
   amend->amender = amender;
   amend->date_amended = time();
   bing->rule->amendments += ({ amend });
 */
   switch (bing->motion_type) {
   case NOMIC_MOTION_TYPE_RULE_ADD :
      bing->rule->text = amend_text;
      break;
   case NOMIC_MOTION_TYPE_RULE_REMOVE :
   case NOMIC_MOTION_TYPE_RULE_MOVE :
      return 0;
   case NOMIC_MOTION_TYPE_RULE_AMEND :
      bing->rule->amendments[<1]->text = amend_text;
   }
   save_me();
   return 1;
} /* add_motion_update_comment() */

/**
 * This method votes for the specified ammentment/whatever.
 * @param area the area to vote in
 * @param id the id to vote for
 * @param vote_type the type of the vote
 * @param voter the person is voting
 * @return 1 on success, 0 on failure
 */
int vote_for_motion(string area, int id, int vote_type, string voter) {
   class nomic_motion bing;

   bing = query_motion(area, id);
   if (!bing) {
      return 0;
   }

   if (member_array(voter, bing->voted) != -1) {
      return 0;
   }

   if (bing->state != NOMIC_STATE_COUNCIL_VOTE &&
       bing->state != NOMIC_STATE_CITIZEN_VOTE) {
      return 0;
   }

   switch (vote_type) {
   case NOMIC_VOTE_YES :
      bing->yes_votes++;
      break;
   case NOMIC_VOTE_NO :
      bing->no_votes++;
      break;
   case NOMIC_VOTE_ABSTAIN :
      bing->abstain_votes++;
      break;
   default :
      return 0;
   }
   bing->voted += ({ voter });
   save_me();
   return 1;
} /* vote_for_motion() */

/**
 * This method checks to see if the person has voted for the specified
 * new rule/amendment/whatever
 * @param area the area to check
 * @param id the id to check
 * @param voter the person to check for voting
 * @return 1 on success, 0 on failure
 */
int has_voted_for_motion(string area, int id, string voter) {
   class nomic_motion bing;

   bing = query_motion(area, id);
   if (!bing) {
      return 0;
   }

   return member_array(voter, bing->voted) != -1;
} /* has_voted_for_motion() */

/**
 * This method returns the current set of votes for the specied new rule.
 * @param area the area to lookup the votes in
 * @param id the idea to check
 * @return ({ yes, no, abstain })
 */
int* query_votes_for_motion(string area, int id) {
   class nomic_motion bing;

   bing = query_motion(area, id);
   if (!bing) {
      return 0;
   }

   return ({ bing->yes_votes, bing->no_votes, bing->abstain_votes });
} /* query_voted_for_motions() */

private void remove_motion(string area, class nomic_motion motion) {
   int i;

   for (i = 0; i < sizeof(_motions[area]); i++) {
      if (_motions[area][i] == motion) {
         _motions[area] = _motions[area][0..i-1] + _motions[area][i+1..];
      }
   }
} /* remove_motion() */

/**
 * This method sends informs to all the specified council of some sort of
 * nifty council event.
 * @param area the area the council is for
 * @param only_magistrates only send it to the magistrates?
 * @param mess the message to send
 */
void send_council_inform(string area, int only_magistrates,
                         string mess) {
   object *obs;

   if (only_magistrates) {
      obs = filter(users(), (: is_magistrate_of($2, $1->query_name()) :), area);
   } else {
      obs = filter(users(), (: is_citizen_of($2, $1->query_name()) :), area);
   }
   call_other(obs, "event_inform", this_object(), mess, "council");
} /* send_council_inform() */

/**
 * This method figures out the compleion time for the specified motion.
 * @param area the area to check
 * @param the motion in the area
 * @return the completion time
 */
int query_completion_time(string area, class nomic_motion motion) {
   return (motion->date_event - motion->date_event % (24 * 60 * 60) +
           7 * (24 * 60 * 60));
} /* query_completion_time() */

/**
 * This method completes the vote on the specified new rule.
 * @param area the area to complete the rule in
 * @param id the id to complete
 * @return 1 on success, 0 on failure
 */
int complete_motion(string area, int id) {
   class nomic_motion bing;
   class nomic_motion motion;
   int passed;
   int new_num;
   string mess;
   int only_magistrates;
   string voting_result;

   bing = query_motion(area, id);
   if (!bing) {
      return 0;
   }

   passed = bing->yes_votes > bing->no_votes;

   voting_result = "Voting Results:\n"
                   "    Yes: " + bing->yes_votes + "\n"
                   "     No: " + bing->no_votes + "\n"
                   "Abstain: " + bing->abstain_votes + "\n";
   mess = "Motion added by " + bing->added_by + " to ";
   switch (bing->motion_type) {
   case NOMIC_MOTION_TYPE_RULE_ADD :
      mess += "add a new rule";
      break;
   case NOMIC_MOTION_TYPE_RULE_REMOVE :
      mess += "remove rule " + bing->rule->id;
      break;
   case NOMIC_MOTION_TYPE_RULE_MOVE :
      mess += "move rule " + bing->rule->id;
      break;
   case NOMIC_MOTION_TYPE_RULE_AMEND :
      mess += "amend rule " + bing->rule->id;
      break;
   }
   if (passed || bing->state == NOMIC_STATE_COUNCIL_REVIEW) {
      switch (bing->state) {
      case NOMIC_STATE_COUNCIL_REVIEW :
         bing->yes_votes = 0;
         bing->no_votes = 0;
         bing->abstain_votes = 0;
         bing->voted = ({ });
         bing->state = NOMIC_STATE_COUNCIL_VOTE;
         mess += " is open for magistrates to vote";
         only_magistrates = 1;
         post_magistrate_message(area, "Motion now in voting phase",
              PLAYER_OB->convert_message(motion_as_string(0, area, bing, 0)));
         break;
      case NOMIC_STATE_COUNCIL_VOTE :
         //
         // Pass this and set all the defaults back up.
         //
         bing->yes_votes = 0;
         bing->no_votes = 0;
         bing->abstain_votes = 0;
         bing->voted = ({ });
         bing->state = NOMIC_STATE_CITIZEN_VOTE;
         bing->comments = ({ });
         mess += " is open for citizens to vote";
         post_magistrate_message(area, "Law passed onto citizens",
                    PLAYER_OB->convert_message(rule_as_string(0, bing->rule)) +
                              "\n\n" + voting_result);
         post_citizen_message(area, "New motion for voting on",
              PLAYER_OB->convert_message(motion_as_string(0, area, bing, 0)));
         break;
      case NOMIC_STATE_CITIZEN_VOTE :
         switch (bing->motion_type) {
         case NOMIC_MOTION_TYPE_RULE_ADD :
            add_nomic_rule_class(area, bing->rule, bing->motion_type);
            break;
         case NOMIC_MOTION_TYPE_RULE_AMEND :
            change_nomic_rule(area, bing->rule);
            break;
         case NOMIC_MOTION_TYPE_RULE_MOVE :
            new_num = move_nomic_rule(area, bing->rule, bing->new_rule_type);
            foreach (motion in _motions[area]) {
               if (motion->rule->id == bing->rule->id) {
                  motion->rule->id = new_num;
               }
            }
            break;
         case NOMIC_MOTION_TYPE_RULE_REMOVE :
            remove_nomic_rule(area, bing->rule->id);
            break;
         }
         remove_motion(area, bing);
         mess += " is now law";
         post_citizen_message(area, "New Law!",
                    PLAYER_OB->convert_message(rule_as_string(0, bing->rule)));
         post_magistrate_message(area, "New Law!",
                    PLAYER_OB->convert_message(rule_as_string(0, bing->rule)) +
                    "\n\n" + voting_result);
         break;
      }
      bing->date_event = time();
   } else {
      if (bing->state == NOMIC_STATE_COUNCIL_VOTE) {
         mess += " not passed by the magistrates";
         only_magistrates = 1;
         post_magistrate_message(area, "Law not passed onto citizens",
                              rule_as_string(0, bing->rule) + "\n\n" +
                              voting_result);
      } else {
         mess += " not ratified by the citizens";
         only_magistrates = 0;
         post_citizen_message(area, "Law not passed",
                              rule_as_string(0, bing->rule));
         post_magistrate_message(area, "Law not passed",
                              rule_as_string(0, bing->rule) + "\n\n" +
                              voting_result);
      }
      remove_motion(area, bing);
   }

   save_me();
   send_council_inform(area, only_magistrates, mess);
   return 1;
} /* complete_motion() */

/**
 * This method figures out all the current things and when they completed.
 */
void check_for_completions() {
   string area;
   class nomic_motion* bits;
   class nomic_motion motion;

   foreach (area, bits in _motions) {
      foreach (motion in bits) {
         if (query_completion_time(area, motion) < time()) {
            complete_motion(area, motion->identifier);
         }
      }
   }

   remove_call_out(_completion_id);
   _completion_id = call_out("check_for_completions",
            (time() - time() % (24 * 60 * 60) + (24 * 60 * 60)) - time());

   //
   // Check the cases to see if they want to mess around too.
   //
   update_recently_closed_cases();
} /* check_for_completions() */

/**
 * This method returns the new motion as a string.
 * @param indent the indentation to putin front of all the lines
 * @param area the area the motion is defined in
 * @param motion the new motion to turn into a styring
 * @param brief disable comments
 * @return the string version of the motion
 */
string motion_as_string(int indent, string area, class nomic_motion motion,
                        int brief) {
   string ret;
   class nomic_comment comment;

   ret = "";
   switch (motion->motion_type) {
   case NOMIC_MOTION_TYPE_RULE_ADD :
      ret += "$I$" + (indent + 5) + "=" + sprintf("%*s", indent, "") +
             motion->identifier + ") Add new rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "\n";
      break;
   case NOMIC_MOTION_TYPE_RULE_REMOVE :
      ret += "$I$" + (indent + 5) + "=" + sprintf("%*s", indent, "") +
             motion->identifier + ") Remove rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "\n";
      break;
   case NOMIC_MOTION_TYPE_RULE_MOVE :
      ret += "$I$" + (indent + 5) + "=" + sprintf("%*s", indent, "") +
             motion->identifier + ") Transmogrify rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "\n";
      break;
   case NOMIC_MOTION_TYPE_RULE_AMEND :
      ret += "$I$" + (indent + 5) + "=" + sprintf("%*s", indent, "") +
             motion->identifier + ") Amend rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "\n";
      break;
   }

   ret += rule_as_string(5 + indent, motion->rule);
   if (sizeof(motion->comments)) {
      if (!brief) {
         ret += "$I$" + (indent + 5) + "=     Comments:\n";
         foreach (comment in motion->comments) {
            ret += "$I$" + (indent + 11) + "=" + sprintf("%*s", indent + 3, "") +                capitalize(comment->commenter) + " (" +
                   ctime(comment->date_commented) + "):\n" +
                   comment->text + "\n";
         }
      } else {
         ret += "$I$0=" + sprintf("%*s", indent, "") + "     " +
                 sizeof(motion->comments) + " Comments.\n";
      }
   } else {
      ret += "$I$0=" + sprintf("%*s", indent, "") + "     No Comments.\n";
   }

   switch (motion->state) {
   case NOMIC_STATE_COUNCIL_REVIEW :
      ret += "$I$0=" + sprintf("%*s", indent, "") +
             "The item is currently being reviewed by the magistrates.\n";
      break;
   case NOMIC_STATE_COUNCIL_VOTE :
      ret += "$I$0=" + sprintf("%*s", indent, "") +
             "The item is currently being voted on by the magistrates.\n";
      break;
   case NOMIC_STATE_CITIZEN_VOTE :
      ret += "$I$0=" + sprintf("%*s", indent, "") +
             "The item is currently being ratified by the citizens.\n";
      break;
   }

   //
   // The next stage!
   //
   ret += "$I$0=" + sprintf("%*s", indent, "") +
          "The item will go onto the next stage at " +
          ctime(query_completion_time(area, motion)) +
          ".\n";

   return ret;
} /* motion_as_string() */

/**
 * This method turns a rule into html.
 * @param rule the rule to turn into html
 * @return the rule as a string
 */
string rule_as_html(class nomic_rule rule) {
   string ret;
   class nomic_amendment amend;

   ret = "<i><b>" + (rule->id?rule->id+"":"(" +
          NOMIC_HANDLER->query_type_name(rule->type) + ")") + "</b> by " +
          capitalize(rule->creator) + " (" +
          ctime(rule->date_created) + "):</i>\n"
          "<p style=\"margin-left: 30pt;margin-top: 5pt\">\n" +
          replace_string(rule->text, "\n", "<br>") +
          "<br>\n";
   foreach (amend in rule->amendments) {
      ret += "<i><b>Ammendment</b> by " + capitalize(amend->amender) + " (" +
             ctime(amend->date_amended) + "):</i>\n"
             "<p style=\"margin-left: 60pt;margin-top: 5pt\">\n" +
             replace_string(amend->text, "\n", "<br>") +
             "\n</p>\n";
   }

   ret += "</p>\n";
   return ret;
} /* rule_as_html() */

/**
 * This method returns the new motion as a string.
 * @param area the area the motion is defined in
 * @param motion the new motion to turn into a styring
 * @return the string version of the motion
 */
string motion_as_html(string area, class nomic_motion motion) {
   string ret;
   class nomic_comment comment;

   ret = "";
   switch (motion->motion_type) {
   case NOMIC_MOTION_TYPE_RULE_ADD :
      ret += "<b>" + motion->identifier + ") Add new rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "</b>\n";
      break;
   case NOMIC_MOTION_TYPE_RULE_REMOVE :
      ret += "<b>" + motion->identifier + ") Remove rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "</b>\n";
      break;
   case NOMIC_MOTION_TYPE_RULE_MOVE :
      ret += "<b>" + motion->identifier + ") Transmogrify rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "</b>\n";
      break;
   case NOMIC_MOTION_TYPE_RULE_AMEND :
      ret += "<b>" + motion->identifier + ") Amend rule; added by " +
             capitalize(motion->added_by) + " at " +
             ctime(motion->date_added) + "</b>\n";
      break;
   }

   ret += "<ul>" + rule_as_html(motion->rule) + "</ul>";
   if (sizeof(motion->comments)) {
      ret += "<b>Comments:</b><br>\n";
      foreach (comment in motion->comments) {
         ret += ctime(comment->date_commented) + "):<br>\n" +
                comment->text + "<p>\n";
      }
   }

   switch (motion->state) {
   case NOMIC_STATE_COUNCIL_REVIEW :
      ret += "The item is currently being reviewed by the magistrates.\n";
      break;
   case NOMIC_STATE_COUNCIL_VOTE :
      ret += "The item is currently being voted on by the magistrates.\n";
      break;
   case NOMIC_STATE_CITIZEN_VOTE :
      ret += "The item is currently being ratified by the citizens.\n";
      break;
   }

   //
   // The next stage!
   //
   ret += "<br>The item will go onto the next stage at " +
          ctime(query_completion_time(area, motion)) +
          ".\n";

   return ret;
} /* motion_as_string() */