diff -crN nakedmudv1.5/doc/commands.txt nakedmudv2.0/doc/commands.txt
*** nakedmudv1.5/doc/commands.txt	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/doc/commands.txt	2010-11-01 15:54:18.000000000 -0500
***************
*** 2,5 ****
--- 2,6 ----
  you can benefit from them, too:
  
  
+ a perl command fo replacing oldtext with newtext in all files listed
  perl -pi -e "s/oldtext/newtext/g;" files
diff -crN nakedmudv1.5/doc/liscence.txt nakedmudv2.0/doc/liscence.txt
*** nakedmudv1.5/doc/liscence.txt	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/doc/liscence.txt	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,8 ****
! NakedMud version 0.1 is public domain; it is free to use for any purpose you
! would like to use it for, without restriction from the creator, Geoff Hollis. 
! By using it, or any pieces of the code, you agree to absolve responsibility 
! from the creator, Geoff Hollis, and take full responsibility for anything 
! NakedMud or pieces of the NakedMud code may cause to happen.
  
  Since NakedMud was based on SocketMud by Brian Graversen, I ask that you follow
  Brian's requests as per giving credit to Erwin Andreasen for the snippets he
--- 1,8 ----
! NakedMud version 2.0 is free to use for any purpose you would like to use it 
! for, without restriction from the creator, Geoff Hollis. By using it, or any 
! pieces of the code, you agree to absolve responsibility from the creator, Geoff
! Hollis, and take full responsibility for anything NakedMud or pieces of the 
! NakedMud code may cause to happen.
  
  Since NakedMud was based on SocketMud by Brian Graversen, I ask that you follow
  Brian's requests as per giving credit to Erwin Andreasen for the snippets he
diff -crN nakedmudv1.5/doc/README nakedmudv2.0/doc/README
*** nakedmudv1.5/doc/README	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/doc/README	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,4 ****
! NakedMud version 0.1
  
  NakedMud is a project I started up to keep myself entertained, and fool around
  with a couple ideas I could not work with on the MUD I run. The basic idea
--- 1,4 ----
! NakedMud version 2.0
  
  NakedMud is a project I started up to keep myself entertained, and fool around
  with a couple ideas I could not work with on the MUD I run. The basic idea
diff -crN nakedmudv1.5/doc/scripts.txt nakedmudv2.0/doc/scripts.txt
*** nakedmudv1.5/doc/scripts.txt	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/doc/scripts.txt	2010-11-01 15:54:18.000000000 -0500
***************
*** 50,55 ****
--- 50,60 ----
  example: ch.send('hello, world!')
  Send a character a text message.
  
+ SENDING MESSAGES
+ ch.sendaround('message')
+ example: ch.send('hello world to everyone around me!')
+ Send a text message to everyone in the same room as ch, but not ch
+ 
  PERFORMING ACTIONS
  ch.act('command')
  example: ch.act('say hello, world!')
***************
*** 74,83 ****
  and the second is what you would like to load the mob to. "to" can be a room,
  a room vnum, or a piece of furniture.
  
! COUNTING OCCURANCES OF MOBILES
  count_mob(vnum/name, where = entire game)
  exmaple: room_pcs = count_mobs(-1, 100)
! Count the occurances of the number of mobs that are in the scope of where. Where
  can be either a room, a room vnum, or a piece of furniture. if where is not
  provided (e.g. count_mobs('jim')) then all characters in the entire game are
  looked over for matches. Either a mob vnum can be used, or the mob's name. If
--- 79,88 ----
  and the second is what you would like to load the mob to. "to" can be a room,
  a room vnum, or a piece of furniture.
  
! COUNTING OCCURENCES OF MOBILES
  count_mob(vnum/name, where = entire game)
  exmaple: room_pcs = count_mobs(-1, 100)
! Count the occurences of the number of mobs that are in the scope of where. Where
  can be either a room, a room vnum, or a piece of furniture. if where is not
  provided (e.g. count_mobs('jim')) then all characters in the entire game are
  looked over for matches. Either a mob vnum can be used, or the mob's name. If
***************
*** 112,118 ****
  COUNTING OBJECTS
  count_objs(vnum/name, where = entire game)
  exmaple: inv_items = count_objs(141, ch)
! Count the occurances of the number of objects that are in the scope of where. 
  Where can be a room, a room vnum, a container, or a character. If where is not
  provided (e.g. count_objs('table')) then all objects in the entire game are
  looked over for matches. Either a obj vnum can be used, or the objects's name. 
--- 117,123 ----
  COUNTING OBJECTS
  count_objs(vnum/name, where = entire game)
  exmaple: inv_items = count_objs(141, ch)
! Count the occurences of the number of objects that are in the scope of where. 
  Where can be a room, a room vnum, a container, or a character. If where is not
  provided (e.g. count_objs('table')) then all objects in the entire game are
  looked over for matches. Either a obj vnum can be used, or the objects's name. 
***************
*** 130,135 ****
--- 135,145 ----
  
  
  The following functions are available for use with Python mud objects:
+ SENDING MESSAGES TO CHARACTERS
+ room.send('message')
+ example: room.send('Hello to everyone in this room!')
+ Sends a message to everyone that is in the room
+ 
  CLOSING DOORS
  room.close('direction')
  example: room.close('north')
diff -crN nakedmudv1.5/doc/startup.txt nakedmudv2.0/doc/startup.txt
*** nakedmudv1.5/doc/startup.txt	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/doc/startup.txt	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,6 ****
  Startup should be pretty easy. To compile, simply go into the src directory and
  type "make". Everything should compile automagically. From here, to start, you
! simply type ./NakedMud <port> & If you do not supply a port, the MUD will
  start up on port 4000 by default.
  
  If you're having troubles compiling when it gets to the scripts, you will want
--- 1,6 ----
  Startup should be pretty easy. To compile, simply go into the src directory and
  type "make". Everything should compile automagically. From here, to start, you
! simply type ./NakedMud [port] & If you do not supply a port, the MUD will
  start up on port 4000 by default.
  
  If you're having troubles compiling when it gets to the scripts, you will want
Binary files nakedmudv1.5/.DS_Store and nakedmudv2.0/.DS_Store differ
Binary files nakedmudv1.5/lib/.DS_Store and nakedmudv2.0/lib/.DS_Store differ
diff -crN nakedmudv1.5/lib/misc/help nakedmudv2.0/lib/misc/help
*** nakedmudv1.5/lib/misc/help	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/misc/help	2010-11-01 15:54:18.000000000 -0500
***************
*** 44,49 ****
--- 44,112 ----
        socunlink [command]
        socedit [social]
        socials
+   backups  :=
+     keywords : socials
+     editor   : Alister
+     timestamp: Jan 29 18:52:49
+     info     :~
+       There are 9 fields assocciated with social editing; two are for messages when
+       the social has no target. Two are for messages when the target is the character
+       performing the social. Three are for situations when a target other than the
+       character is provided for the social. The remaining two are the minimum and
+       maximum positions the socials can be used from. If a social is not to have a
+       target, the "target" fields can be left blank. Likewise, if the social is never
+       to have the character as a target, the assocciated fields can be left blank.
+       When trying to reference character information, the following symbols can be
+       used:
+       
+         $n character name
+         $N target name
+         $e character he/she
+         $E target he/she
+         $m character him/her
+         $M target him/her
+         $s character his/hers
+         $S target his/hers
+       
+       To see examples of how to write socials, check some of the pre-existing ones.
+       To generate a list of all socials, type "socials".
+       
+       If you would like more than one command to trigger the same social, you can
+       link a new command to a pre-existing social. Likewise, if you would like to
+       disable a social command, that is possible too.
+       
+       Commands:
+         hlink [new command] [old command]
+         hunlink [command]
+         socedit [social]
+         socials
+     -
+     keywords : socials
+     editor   : Alister
+     timestamp: Jan 29 17:03:12
+     info     :~
+       There are 9 fields assocciated with social editing; two are for messages when
+       the social has no target. Two are for messages when the target is the character
+       performing the social. Three are for situations when a target other than the
+       character is provided for the social. The remaining two are the minimum and
+       maximum positions the socials can be used from. If a social is not to have a
+       target, the "target" fields can be left blank. Likewise, if the social is never
+       to have the character as a target, the assocciated fields can be left blank.
+       When trying to reference character information, the following symbols can be
+       used:
+       
+         $n character name
+         $N target name
+         $e character he/she
+         $E target he/she
+         $m character him/her
+         $M target him/her
+         $s character his/hers
+         $S target his/hers
+       
+       To see examples of how to write socials, check some of the pre-existing ones.
+       To generate a list of all socials, type "socials".
+     -
    -
    keywords : MCCP
    editor   : Alister
***************
*** 117,122 ****
--- 180,204 ----
        help
      
      See also: WRITE
+   backups  :=
+     keywords : help
+     editor   : Alister
+     timestamp: Jan 29 18:31:08
+     info     :~
+       There are various tools available for creating and editing helpfiles. You
+       can update the contents of any helpfile with the hupdate command. The
+       contents of your notepad (see: write) will be transferred to the helpfile.
+       You can also link a new word to an already existing helpfile with the hlink
+       command. Unlinking is also possible with the hunlink command.
+       
+       Commands:
+         hupdate [helpfile]
+         hlink [new topic] [old topic]
+         hunlink [topic]
+         help
+       
+       See also: WRITE
+     -
    -
    keywords : dig, fill
    editor   : Alister
diff -crN nakedmudv1.5/lib/misc/socials nakedmudv2.0/lib/misc/socials
*** nakedmudv1.5/lib/misc/socials	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/misc/socials	2010-11-01 15:54:18.000000000 -0500
***************
*** 19,24 ****
--- 19,33 ----
    min_pos      : standing
    max_pos      : standing
    -
+   cmds         : ponder
+   to_char_notgt: You sink deeply into your thoughts.
+   to_room_notgt: $n sinks deeply into $s thoughts.
+   to_char_tgt  : You ponder the plight of $N.
+   to_vict_tgt  : $n looks to be deep in thought at $e stares at you.
+   to_room_tgt  : $n looks deep in thought as $e stares at $N.
+   min_pos      : sitting
+   max_pos      : flying
+   -
    cmds         : snicker
    to_char_notgt: You snicker softly.
    to_room_notgt: $n snickers softly.
diff -crN nakedmudv1.5/lib/misc/time nakedmudv2.0/lib/misc/time
*** nakedmudv1.5/lib/misc/time	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/misc/time	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,6 ****
! hour        : 18
! day_of_week : 2
! day_of_month: 11
! month       : 2
! year        : 0
  -
--- 1,6 ----
! hour        : 23
! day_of_week : 1
! day_of_month: 10
! month       : 1
! year        : 1
  -
diff -crN nakedmudv1.5/lib/txt/greeting nakedmudv2.0/lib/txt/greeting
*** nakedmudv1.5/lib/txt/greeting	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/txt/greeting	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,5 ****
  {n
!                     NakedMud(tm), content-less MUD engine.
  
                                    Created By
                                   Geoff Hollis
--- 1,5 ----
  {n
!                    NakedMud(tm) v2.0, content-less MUD engine.
  
                                    Created By
                                   Geoff Hollis
diff -crN nakedmudv1.5/lib/world/0/rooms~ nakedmudv2.0/lib/world/0/rooms~
*** nakedmudv1.5/lib/world/0/rooms~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/0/rooms~	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,25 ****
- list:=
-   desc     :~
-     You are surrounded by nothingness.

-   auxiliary:-
-     time_aux_data  :-
-       night_desc: 
-       -
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   terrain  : 0
-   vnum     : 0
-   name     : Floating in Limbo
-   exits    :=
-   edescs   :-
-     list:=
-       desc    :~
-            Well, there's not too much of it, that's for sure.  Or maybe that's all 

-         there is.  It's quite mind blowing, really.

-       keywords: nothingness
-       -
-     -
-   -
- -
--- 0 ----
diff -crN nakedmudv1.5/lib/world/0/zone nakedmudv2.0/lib/world/0/zone
*** nakedmudv1.5/lib/world/0/zone	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/0/zone	2010-11-01 15:54:18.000000000 -0500
***************
*** 5,16 ****
  name       : The null zone
  desc       :~
       This zone has no purpose and should be taken out when the MUD is first 

- auxiliary  :-
-   zone_map_data :-
-     zone_display_map: 0
-     -
-   autopilot_data:-
-     autopilot_on: 0
-     -
-   -
  -
--- 5,8 ----
diff -crN nakedmudv1.5/lib/world/1/mobs nakedmudv2.0/lib/world/1/mobs
*** nakedmudv1.5/lib/world/1/mobs	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/mobs	2010-11-01 15:54:18.000000000 -0500
***************
*** 15,38 ****
    race      : human
    dialog    : 100
    auxiliary :-
!     stat_data        :-
!       health          : 5
!       curr_health     : 5
!       power           : 5
!       curr_power      : 0
!       awareness       : 5
!       curr_awareness  : 0
!       courage         : 5
!       curr_courage    : 0
!       control         : 5
!       curr_control    : 0
!       speed           : 5
!       curr_speed      : 0
!       personality     : 5
!       curr_personality: 0
        -
      script_aux_data  :-
        scripts:=
          vnum: 150
          -
          vnum: 140
--- 15,38 ----
    race      : human
    dialog    : 100
    auxiliary :-
!     combat_state_data:-
!       health      : 100
!       curr_health : 100
!       power       : 100
!       curr_power  : 100
!       control     : 100
!       curr_control: 100
!       defense     : 100
!       curr_defense: 100
!       agility     : 100
!       curr_agility: 100
!       wits        : 100
!       curr_wits   : 100
        -
      script_aux_data  :-
        scripts:=
+         vnum: 195
+         -
          vnum: 150
          -
          vnum: 140
***************
*** 54,74 ****
    race      : human
    dialog    : 101
    auxiliary :-
!     stat_data        :-
!       health          : 5
!       curr_health     : 5
!       power           : 5
!       curr_power      : 0
!       awareness       : 5
!       curr_awareness  : 0
!       courage         : 5
!       curr_courage    : 0
!       control         : 5
!       curr_control    : 0
!       speed           : 5
!       curr_speed      : 0
!       personality     : 5
!       curr_personality: 0
        -
      script_aux_data  :-
        scripts:=
--- 54,72 ----
    race      : human
    dialog    : 101
    auxiliary :-
!     combat_state_data:-
!       health      : 100
!       curr_health : 100
!       power       : 100
!       curr_power  : 100
!       control     : 100
!       curr_control: 100
!       defense     : 100
!       curr_defense: 100
!       agility     : 100
!       curr_agility: 100
!       wits        : 100
!       curr_wits   : 100
        -
      script_aux_data  :-
        scripts:=
***************
*** 93,113 ****
    race      : human
    dialog    : 102
    auxiliary :-
!     stat_data        :-
!       health          : 5
!       curr_health     : 5
!       power           : 5
!       curr_power      : 0
!       awareness       : 5
!       curr_awareness  : 0
!       courage         : 5
!       curr_courage    : 0
!       control         : 5
!       curr_control    : 0
!       speed           : 5
!       curr_speed      : 0
!       personality     : 5
!       curr_personality: 0
        -
      -
    -
--- 91,109 ----
    race      : human
    dialog    : 102
    auxiliary :-
!     combat_state_data:-
!       health      : 100
!       curr_health : 100
!       power       : 100
!       curr_power  : 100
!       control     : 100
!       curr_control: 100
!       defense     : 100
!       curr_defense: 100
!       agility     : 100
!       curr_agility: 100
!       wits        : 100
!       curr_wits   : 100
        -
      -
    -
***************
*** 128,148 ****
    race      : human
    dialog    : -1
    auxiliary :-
!     stat_data        :-
!       health          : 5
!       curr_health     : 5
!       power           : 5
!       curr_power      : 0
!       awareness       : 5
!       curr_awareness  : 0
!       courage         : 5
!       curr_courage    : 0
!       control         : 5
!       curr_control    : 0
!       speed           : 5
!       curr_speed      : 0
!       personality     : 5
!       curr_personality: 0
        -
      -
    -
--- 124,142 ----
    race      : human
    dialog    : -1
    auxiliary :-
!     combat_state_data:-
!       health      : 100
!       curr_health : 100
!       power       : 100
!       curr_power  : 100
!       control     : 100
!       curr_control: 100
!       defense     : 100
!       curr_defense: 100
!       agility     : 100
!       curr_agility: 100
!       wits        : 100
!       curr_wits   : 100
        -
      -
    -
diff -crN nakedmudv1.5/lib/world/1/mobs~ nakedmudv2.0/lib/world/1/mobs~
*** nakedmudv1.5/lib/world/1/mobs~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/mobs~	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,149 ****
- list:=
-   vnum      : 100
-   name      : Mysty
-   keywords  : mysty, blonde, waitress
-   rdesc     : A small, buxom blonde is here, serving the tavern patrons.
-   desc      :~
-        She's a rather petite woman - just over five feet.  She has long, curly 
-     blonde hair that hangs down past her shoulders.  Her low-cut, white cotton 
-     shirt reveals her cleavage - and quite a bit of cleavage at that!  She darts 
-     from table to table, always carrying a tray of drinks with amazing balance and 
-     control.  There is always a bounce to her step, and fire in her eyes.  She 
-     seems like she's quite the feisty one.
-   level     : 2
-   sex       : 1
-   race      : 0
-   dialog    : 100
-   auxiliary :-
-     stat_data        :-
-       health          : 5
-       curr_health     : 5
-       power           : 5
-       curr_power      : 0
-       awareness       : 5
-       curr_awareness  : 0
-       courage         : 5
-       curr_courage    : 0
-       control         : 5
-       curr_control    : 0
-       speed           : 5
-       curr_speed      : 0
-       personality     : 5
-       curr_personality: 0
-       -
-     script_aux_data  :-
-       scripts:=
-         vnum: 150
-         -
-         vnum: 140
-         -
-       -
-     -
-   -
-   vnum      : 101
-   name      : Julesz
-   keywords  : Julesz, bartender, man
-   rdesc     : A handsome, darkhaired man is here, standing behind the bar.
-   desc      :~
-        He is about average height, with short black hair and piercing grey eyes.
-     He has an air about him that screams mischief.  He looks quite preoccupied 
-     pouring drinks, but you notice he never gets too busy to not glance at the 
-     ladies walking by the bar.
-   level     : 2
-   sex       : 0
-   race      : 0
-   dialog    : 101
-   auxiliary :-
-     stat_data        :-
-       health          : 5
-       curr_health     : 5
-       power           : 5
-       curr_power      : 0
-       awareness       : 5
-       curr_awareness  : 0
-       courage         : 5
-       curr_courage    : 0
-       control         : 5
-       curr_control    : 0
-       speed           : 5
-       curr_speed      : 0
-       personality     : 5
-       curr_personality: 0
-       -
-     script_aux_data  :-
-       scripts:=
-         vnum: 141
-         -
-         vnum: 151
-         -
-       -
-     -
-   -
-   vnum      : 102
-   name      : a gruff looking man
-   keywords  : garod, gruff, man
-   rdesc     : A gruff looking man is here, keeping to himself.
-   desc      :~
-        If surly had a poster child, he would be it.  His face is pocked, and he 
-     has a sour look on his face.  His eyebrows are thick and bushy, and he has 
-     a scraggly beard that looks like it has been growing for a few weeks.  He 
-     has a large, bulbous nose and squinty, black eyes.
-   level     : 1
-   sex       : 0
-   race      : 0
-   dialog    : 102
-   auxiliary :-
-     stat_data        :-
-       health          : 5
-       curr_health     : 5
-       power           : 5
-       curr_power      : 0
-       awareness       : 5
-       curr_awareness  : 0
-       courage         : 5
-       curr_courage    : 0
-       control         : 5
-       curr_control    : 0
-       speed           : 5
-       curr_speed      : 0
-       personality     : 5
-       curr_personality: 0
-       -
-     -
-   -
-   vnum      : 130
-   name      : a barfly
-   keywords  : barfly
-   rdesc     : A barfly is here, mulling about.
-   desc      :~
-        He is middle aged, and looks like he has led a pretty tough life.  His 
-     hands look strong and calloused.  He might be a miner, or perhaps some kind 
-     of tradesman.  His face is slightly pocked, and his eyebrows are big and 
-     bushy.  He looks a bit too preoccupied with his mug of ale to pay you much 
-     attention.
-   multirdesc: A group of %d barflies are here, mulling about.
-   multiname : a group of %d bar flies
-   level     : 2
-   sex       : 0
-   race      : 0
-   dialog    : -1
-   auxiliary :-
-     stat_data        :-
-       health          : 5
-       curr_health     : 5
-       power           : 5
-       curr_power      : 0
-       awareness       : 5
-       curr_awareness  : 0
-       courage         : 5
-       curr_courage    : 0
-       control         : 5
-       curr_control    : 0
-       speed           : 5
-       curr_speed      : 0
-       personality     : 5
-       curr_personality: 0
-       -
-     -
-   -
- -
--- 0 ----
diff -crN nakedmudv1.5/lib/world/1/objs nakedmudv2.0/lib/world/1/objs
*** nakedmudv1.5/lib/world/1/objs	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/objs	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,14 ****
  list:=
    vnum      : 100
-   type      : 2
-   subtype   : 0
-   value 0   : 0
-   value 1   : 0
-   value 2   : 0
-   value 3   : 0
-   value 4   : 0
    weight    : 1.000000
-   capacity  : 0.000000
    name      : a white cotton shirt
    keywords  : shirt
    rdesc     : A revealing, white cotton shirt is lying here.
--- 1,6 ----
***************
*** 18,34 ****
      woman.
    multiname : %d white cotton shirts
    multirdesc: A pile of %d white cotton shirts has formed, here.
    -
    vnum      : 101
-   type      : 2
-   subtype   : 4
-   value 0   : 0
-   value 1   : 0
-   value 2   : 0
-   value 3   : 0
-   value 4   : 0
    weight    : 0.100000
-   capacity  : 0.000000
    name      : a pair of long, dangly earrings
    keywords  : earrings
    rdesc     : A pair of long, dangly earrings are lying here.
--- 10,28 ----
      woman.
    multiname : %d white cotton shirts
    multirdesc: A pile of %d white cotton shirts has formed, here.
+   auxiliary :-
+     type_data      :-
+       types:=
+         type: worn
+         data:-
+           type: shirt
+           -
+         -
+       -
+     -
    -
    vnum      : 101
    weight    : 0.100000
    name      : a pair of long, dangly earrings
    keywords  : earrings
    rdesc     : A pair of long, dangly earrings are lying here.
***************
*** 37,53 ****
      whenever they are turned in the light.
    multiname : %d sets of long dangly earrings
    multirdesc: %d pairs of long, dangly earrings are lying here.
    -
    vnum      : 120
-   type      : 4
-   subtype   : 0
-   value 0   : 5
-   value 1   : 0
-   value 2   : 0
-   value 3   : 0
-   value 4   : 0
    weight    : 80.000000
-   capacity  : 0.000000
    name      : a wooden table
    keywords  : table
    rdesc     : An empty table is here.
--- 31,49 ----
      whenever they are turned in the light.
    multiname : %d sets of long dangly earrings
    multirdesc: %d pairs of long, dangly earrings are lying here.
+   auxiliary :-
+     type_data      :-
+       types:=
+         type: worn
+         data:-
+           type: earrings
+           -
+         -
+       -
+     -
    -
    vnum      : 120
    weight    : 80.000000
    name      : a wooden table
    keywords  : table
    rdesc     : An empty table is here.
***************
*** 57,92 ****
      could seat about four or five people at it.
    multiname : %d wooden tables
    multirdesc: There are %d empty tables scattered around.
!   bits      : a
    -
    vnum      : 130
-   type      : 4
-   subtype   : 0
-   value 0   : 12
-   value 1   : 0
-   value 2   : 0
-   value 3   : 0
-   value 4   : 0
    weight    : 500.000000
-   capacity  : 0.000000
    name      : the bar
    keywords  : bar
    rdesc     : A long bar counter is here, lined with seats.
    desc      :~
         It is about twenty feet long, and it is lined with stools.  It is made 
      out of a polished, dark wood.
!   bits      : a
    -
    vnum      : 140
-   type      : 5
-   subtype   : 0
-   value 0   : 1
-   value 1   : -1
-   value 2   : 0
-   value 3   : 0
-   value 4   : 0
    weight    : 0.100000
-   capacity  : 1.000000
    name      : a small leather coin pouch
    keywords  : pouch
    rdesc     : A small leather coin pouch is here.
--- 53,94 ----
      could seat about four or five people at it.
    multiname : %d wooden tables
    multirdesc: There are %d empty tables scattered around.
!   obj_bits  : notake
!   auxiliary :-
!     type_data      :-
!       types:=
!         type: furniture
!         data:-
!           capacity: 5
!           type    : 0
!           -
!         -
!       -
!     -
    -
    vnum      : 130
    weight    : 500.000000
    name      : the bar
    keywords  : bar
    rdesc     : A long bar counter is here, lined with seats.
    desc      :~
         It is about twenty feet long, and it is lined with stools.  It is made 
      out of a polished, dark wood.
!   obj_bits  : notake
!   auxiliary :-
!     type_data      :-
!       types:=
!         type: furniture
!         data:-
!           capacity: 9
!           type    : 0
!           -
!         -
!       -
!     -
    -
    vnum      : 140
    weight    : 0.100000
    name      : a small leather coin pouch
    keywords  : pouch
    rdesc     : A small leather coin pouch is here.
***************
*** 104,120 ****
          threads.  It is a bit frayed, but looks quite durable.
        -
      -
    -
    vnum      : 141
-   type      : 0
-   subtype   : 0
-   value 0   : 0
-   value 1   : 0
-   value 2   : 0
-   value 3   : 0
-   value 4   : 0
    weight    : 0.200000
-   capacity  : 0.000000
    name      : a pint of ale
    keywords  : pintglass, glass, ale
    rdesc     : A pint of ale has been left here.
--- 106,129 ----
          threads.  It is a bit frayed, but looks quite durable.
        -
      -
+   auxiliary :-
+     type_data      :-
+       types:=
+         type: container
+         data:-
+           capacity : 2.000000
+           key      : -1
+           pick_diff: 0
+           closable : 1
+           closed   : 0
+           locked   : 0
+           -
+         -
+       -
+     -
    -
    vnum      : 141
    weight    : 0.200000
    name      : a pint of ale
    keywords  : pintglass, glass, ale
    rdesc     : A pint of ale has been left here.
diff -crN nakedmudv1.5/lib/world/1/objs~ nakedmudv2.0/lib/world/1/objs~
*** nakedmudv1.5/lib/world/1/objs~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/objs~	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,134 ****
- list:=
-   value 2   : 0
-   bits      : 
-   rdesc     : A revealing, white cotton shirt is lying here.
-   value 0   : 0
-   subtype   : 0
-   desc      :~
-        It is a white cotton shirt, with a rather low cot v-line that would reveal 

-     qutie a bit.  It is small, and looks lke it was made for a rather petite 

-     woman.

-   value 3   : 0
-   type      : 2
-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   value 1   : 0
-   multirdesc: A pile of %d white cotton shirts has formed, here.
-   name      : a white cotton shirt
-   vnum      : 100
-   contents  :=
-   edescs    :-
-     list:=
-     -
-   multiname : %d white cotton shirts
-   keywords  : shirt
-   -
-   value 2   : 0
-   bits      : 
-   rdesc     : A pair of long, dangly earrings are lying here.
-   value 0   : 0
-   subtype   : 4
-   desc      :~
-      They are made of long, dangly strips of green-grey metal, and shimmer 

-     whenever they are turned in the light.

-   value 3   : 0
-   type      : 2
-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   value 1   : 0
-   multirdesc: %d pairs of long, dangly earrings are lying here.
-   name      : a pair of long, dangly earrings
-   vnum      : 101
-   contents  :=
-   edescs    :-
-     list:=
-     -
-   multiname : %d sets of long dangly earrings
-   keywords  : earrings
-   -
-   value 2   : 0
-   bits      : a
-   rdesc     : A circular wooden table is here.
-   value 0   : 5
-   subtype   : 0
-   desc      :~
-        It is made of wood, and is circular.  It stands about four feet off 

-     the ground, and has a few chairs seated around it.  It looks like it 

-     could seat about four or five people at it.

-   value 3   : 0
-   type      : 4
-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   value 1   : 0
-   multirdesc: There are %d empty wooden tables clustered about the tavern.
-   name      : a wooden table
-   vnum      : 120
-   contents  :=
-   edescs    :-
-     list:=
-     -
-   multiname : %d wooden tables
-   keywords  : table
-   -
-   value 2   : 0
-   bits      : a
-   rdesc     : A long bar counter is here, lined with seats.
-   value 0   : 12
-   subtype   : 0
-   desc      :~
-        It is about twenty feet long, and it is lined with stools.  It is made 

-     out of a polished, dark wood.

-   value 3   : 0
-   type      : 4
-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   value 1   : 0
-   multirdesc: 
-   name      : the bar
-   vnum      : 130
-   contents  :=
-   edescs    :-
-     list:=
-     -
-   multiname : 
-   keywords  : bar
-   -
-   value 2   : 0
-   bits      : 
-   rdesc     : a pint glass has been left here.
-   value 0   : 0
-   subtype   : 0
-   desc      :~
-        It looks like a typical pint glass.  Its base is a bit smaller than its 

-     top, and it has a little bulge about four fifths of the way up the glass.

-   value 3   : 0
-   type      : 0
-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   value 1   : 0
-   multirdesc: %d pint glasses are scattered about.
-   name      : a pint glass
-   vnum      : 141
-   contents  :=
-   edescs    :-
-     list:=
-     -
-   multiname : %d pint glasses
-   keywords  : pintglass, glass
-   -
- -
--- 0 ----
diff -crN nakedmudv1.5/lib/world/1/rooms~ nakedmudv2.0/lib/world/1/rooms~
*** nakedmudv1.5/lib/world/1/rooms~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/rooms~	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,211 ****
- list:=
-   desc     :~
-        This looks like quite the popular place; many tables are scattered around 

-     the tavern.  Groups of people huddle around them.  Some chat amongst 

-     themselves, some are playing card and dice games, and others are simply 

-     watching the entertainment stage to the north.  The bar is to the south.

-     People are lined up all along it, but you can spot a few open seats.  There 

-     are also a couple empty tables scattered throughout the tavern.  To the north, 

-     you see a small entertainment stage which seems to be attracting quite the 

-     crowd.

-   auxiliary:-
-     time_aux_data  :-
-       night_desc: 
-       -
-     script_aux_data:-
-       scripts:=
-         vnum: 100
-         -
-       -
-     -
-   terrain  : 0
-   vnum     : 100
-   name     : Within a Tavern
-   exits    :=
-     pick_level: 0
-     key       : -1
-     desc      :~
-          The entertainment stage is directly to your north.  Quite a few people have 

-       gathered around it, and it looks like there is a performance going on.

-     closable  : 0
-     enter     : 
-     direction : north
-     hide_level: 0
-     to        : 102
-     leave     : 
-     name      : 
-     keywords  : 
-     -
-     pick_level: 0
-     key       : -1
-     desc      :~
-        You see a rather crowded bar to the south.  There are still a couple of 

-       stools left, but it looks to be filling up fast.

-     closable  : 0
-     enter     : 
-     direction : south
-     hide_level: 0
-     to        : 101
-     leave     : $n makes $s way to the bar.
-     name      : going to the bar
-     keywords  : 
-     -
-     pick_level: 0
-     key       : -1
-     desc      :~
-          The light does not really get to that corner of the tavern.  A few people 

-       sit around tables, but most of them appear to be alone and not wanting any 

-       company.

-     closable  : 0
-     enter     : 
-     direction : southwest
-     hide_level: 0
-     to        : 103
-     leave     : 
-     name      : 
-     keywords  : 
-     -
-   edescs   :-
-     list:=
-     -
-   -
-   desc     :~
-        The bar is fairly busy, but you notice a couple of stools left unoccupied.

-     Servers come past now and then, picking up trays of drinks for their 

-     customers.  Most of the customers at the bar seem to be older on in the years, 

-     paying more attention to their drinks than to the crowd.  The bartenders all 

-     seem to be busy with preparing drinks for the customers.  A crowd seems to be 

-     gathering to the north, by the entertainment stage.  It looks like there is 

-     some sort of performance going on.

-   auxiliary:-
-     time_aux_data  :-
-       night_desc: 
-       -
-     script_aux_data:-
-       scripts:=
-         vnum: 101
-         -
-       -
-     -
-   terrain  : 0
-   vnum     : 101
-   name     : At the Bar
-   exits    :=
-     pick_level: 0
-     key       : -1
-     desc      :~
-          There are various tables scattered about, occupied by groups of people.  At 

-       the northern end of the tavern, you see a small entertainment stage which 

-       seems to have gathered quite the crowd.

-     closable  : 0
-     enter     : 
-     direction : north
-     hide_level: 0
-     to        : 100
-     leave     : 
-     name      : 
-     keywords  : 
-     -
-     pick_level: 0
-     key       : -1
-     desc      :~
-          The light does not really get to that corner of the tavern.  A few people 

-       sit around tables, but most of them appear to be alone and not wanting any 

-       company.

-     closable  : 0
-     enter     : 
-     direction : west
-     hide_level: 0
-     to        : 103
-     leave     : 
-     name      : 
-     keywords  : 
-     -
-   edescs   :-
-     list:=
-     -
-   -
-   desc     :~
-     This room was created by Alister.

-   auxiliary:-
-     time_aux_data  :-
-       night_desc: 
-       -
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   terrain  : 0
-   vnum     : 102
-   name     : By the Stage
-   exits    :=
-     pick_level: 0
-     key       : -1
-     desc      :~
-        Tables are scattered about.  Most of them have groups of people sitting at 

-       them.  At the south end of the tavern, you see the bar.

-     closable  : 0
-     enter     : 
-     direction : south
-     hide_level: 0
-     to        : 100
-     leave     : 
-     name      : 
-     keywords  : 
-     -
-   edescs   :-
-     list:=
-     -
-   -
-   desc     :~
-        The light is much more dim in here than it is in the rest of the tavern.

-     There are also quite a few less people sitting in this area of the tavern.

-     Most that are seem to be keeping to themselves, and don't appear to want 

-     much to do with strangers.

-   auxiliary:-
-     time_aux_data  :-
-       night_desc: 
-       -
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   terrain  : 0
-   vnum     : 103
-   name     : A Poorly Lit Corner
-   exits    :=
-     pick_level: 0
-     key       : -1
-     desc      :~
-          To the east, you see the bar.  It looks like it is starting to fill up 

-       quick, but you spot a couple open stools.  The bartenders look like they are 

-       quite busy with all the customers.

-     closable  : 0
-     enter     : 
-     direction : east
-     hide_level: 0
-     to        : 101
-     leave     : $n makes $s way towards the bar.
-     name      : 
-     keywords  : 
-     -
-     pick_level: 0
-     key       : -1
-     desc      :~
-          There are various tables scattered about, occupied by groups of people.  At 

-       the northern end of the tavern, you see a small entertainment stage which 

-       seems to have gathered quite the crowd.

-     closable  : 0
-     enter     : 
-     direction : northeast
-     hide_level: 0
-     to        : 100
-     leave     : 
-     name      : 
-     keywords  : 
-     -
-   edescs   :-
-     list:=
-     -
-   -
- -
--- 0 ----
diff -crN nakedmudv1.5/lib/world/1/scripts nakedmudv2.0/lib/world/1/scripts
*** nakedmudv1.5/lib/world/1/scripts	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/scripts	2010-11-01 15:54:18.000000000 -0500
***************
*** 75,82 ****
    narg: 0
    name: Crowd Cheering
    code:~
!     # When someone gets on stage, the crod starts cheering, adding a
!     # bit of flavor.
      ch.send("{yAs you get up on stage, you hear hoots and hollers from below. It looks like the crowd is waiting you to start performing.")
    -
    vnum: 140
--- 75,82 ----
    narg: 0
    name: Crowd Cheering
    code:~
!     # Whensomeone gets on stage, the crowd starts cheering, adding a
!     # bit of flavor to this special exit
      ch.send("{yAs you get up on stage, you hear hoots and hollers from below. It looks like the crowd is waiting you to start performing.")
    -
    vnum: 140
***************
*** 162,167 ****
--- 162,182 ----
      if obj != None and ch.on == None and obj.vnum == 130:
        me.act("delay 1 say what can I get for you? If you'd like to know what we have on tap, please ask")
    -
+   vnum: 195
+   type: 1
+   narg: 0
+   name: How to exit a script
+   args: hello
+   code:~
+     # At times, you will want to exit a script prematurely. This example script
+     # Shows you how it is done.
+     
+     # only trigger the script for PCs
+     if ch.is_npc:
+       exit()
+     else:
+       me.act("say Hello, " + ch.name)
+   -
    vnum: 196
    type: 1
    narg: 0
diff -crN nakedmudv1.5/lib/world/1/zone nakedmudv2.0/lib/world/1/zone
*** nakedmudv1.5/lib/world/1/zone	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/zone	2010-11-01 15:54:18.000000000 -0500
***************
*** 7,18 ****
       The ambition of this zone is to act as a repository for "proofs of 
    concept".  Hopefully, there will be enough examples in this zone to act as a 
  editors    : Alister
- auxiliary  :-
-   zone_map_data :-
-     zone_display_map: 0
-     -
-   autopilot_data:-
-     autopilot_on: 0
-     -
-   -
  -
--- 7,10 ----
diff -crN nakedmudv1.5/lib/world/1/zone~ nakedmudv2.0/lib/world/1/zone~
*** nakedmudv1.5/lib/world/1/zone~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/lib/world/1/zone~	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,10 ****
- pulse_timer: -1
- editors    : Alister
- max        : 199
- desc       :~
-      The ambition of this zone is to act as a repository for "proofs of 

-   concept".  Hopefully, there will be enough examples in this zone to act as a 

- name       : The "Proof of Concept" zone
- vnum       : 1
- min        : 100
- -
--- 0 ----
Binary files nakedmudv1.5/log/.DS_Store and nakedmudv2.0/log/.DS_Store differ
diff -crN nakedmudv1.5/src/action.c nakedmudv2.0/src/action.c
*** nakedmudv1.5/src/action.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/action.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 33,40 ****
  #include "character.h"
  #include "action.h"
  
  typedef struct action_data ACTION_DATA;
! HASHMAP *actors = NULL;
  
  struct action_data {
    void (*  on_complete)(void *ch, void *data, bitvector_t where, char *arg);
--- 33,44 ----
  #include "character.h"
  #include "action.h"
  
+ #ifdef MODULE_FACULTY
+ #include "faculty/faculty.h"
+ #endif
+ 
  typedef struct action_data ACTION_DATA;
! MAP *actors = NULL;
  
  struct action_data {
    void (*  on_complete)(void *ch, void *data, bitvector_t where, char *arg);
***************
*** 98,103 ****
--- 102,115 ----
  }
  
  
+ // used to kill all of a character's actions on death
+ void stop_all_actions(CHAR_DATA *ch) {
+ #ifdef MODULE_FACULTY
+   interrupt_action(ch, FACULTY_ALL);
+ #else
+   interrupt_action(ch, 1);  
+ #endif
+ }
  
  
  //*****************************************************************************
***************
*** 107,117 ****
  //*****************************************************************************
  void init_actions() {
    // use the standard pointer hasher and comparator
!   actors = newHashmap(NULL, NULL, 50);
  
    // add in our example delayed action
    add_cmd("dsay", NULL, cmd_dsay, 0, POS_SITTING, POS_FLYING, 
  	  LEVEL_ADMIN, TRUE, FALSE);
  }
  
  bool is_acting(void *ch, bitvector_t where) {
--- 119,132 ----
  //*****************************************************************************
  void init_actions() {
    // use the standard pointer hasher and comparator
!   actors = newMap(NULL, NULL, 50);
  
    // add in our example delayed action
    add_cmd("dsay", NULL, cmd_dsay, 0, POS_SITTING, POS_FLYING, 
  	  LEVEL_ADMIN, TRUE, FALSE);
+ 
+   // make sure the character does not continue actions after being extracted
+   add_extract_mob_func(stop_all_actions);
  }
  
  bool is_acting(void *ch, bitvector_t where) {
diff -crN nakedmudv1.5/src/action.d nakedmudv2.0/src/action.d
*** nakedmudv1.5/src/action.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/action.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ action.d action.o: action.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h character.h action.h
diff -crN nakedmudv1.5/src/alias/alias.d nakedmudv2.0/src/alias/alias.d
*** nakedmudv1.5/src/alias/alias.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/alias/alias.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ alias/alias.d alias/alias.o: alias/alias.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h auxiliary.h storage.h \
+   character.h alias/alias.h
diff -crN nakedmudv1.5/src/autorun.py nakedmudv2.0/src/autorun.py
*** nakedmudv1.5/src/autorun.py	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/autorun.py	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,43 ----
+ ################################################################################
+ #
+ # autorun.py
+ #
+ # This autorun script was designed to be used with NakedMud. It will 
+ # automagically restart your MUD any time it crashes. If the MUD is manually
+ # shut down, the autorun script will terminate. 
+ #
+ # Geoff Hollis
+ # http://www.ualberta.ca/~hollis/nakedmud.html
+ #
+ ################################################################################
+ 
+ from time import sleep   # we delay before restarting
+ from os   import system  # to start running the MUD
+ 
+ # how long do we delay before a restart (seconds)
+ restart_delay = 5
+ 
+ # the path to the MUD binary
+ path = './NakedMud'
+ 
+ # the port we will be running the MUD under
+ port = 4000
+ 
+ # the command we execute to boot up the MUD
+ cmd  = "%s %d" % (path, port)
+ 
+ # now, while we have not exited without an error, run the MUD 
+ # and reboot it every time we exit with an error (we crash)
+ while True:
+     # run the MUD
+     status = system(cmd)
+ 
+     # exited normally
+     if status == 0:
+ 	break;
+     else:
+ 	# We should probably see if we can figure out what kind of
+ 	# error caused the crash here, and report it
+ 
+ 	# wait out our delay, then restart the MUD
+ 	sleep(restart_delay)
diff -crN nakedmudv1.5/src/auxiliary.c nakedmudv2.0/src/auxiliary.c
*** nakedmudv1.5/src/auxiliary.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/auxiliary.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 90,101 ****
    AUXILIARY_FUNCS *funcs = NULL;
    const char       *name = NULL;
  
!   while( (name = hashIteratorCurrentKey(hash_i)) != NULL) {
!     funcs = hashIteratorCurrentVal(hash_i);
!     hashIteratorNext(hash_i);
      if(IS_SET(funcs->aux_type, aux_type))
        hashPut(data, name, funcs->new());
-   }
    deleteHashIterator(hash_i);
    return data;
  }
--- 90,98 ----
    AUXILIARY_FUNCS *funcs = NULL;
    const char       *name = NULL;
  
!   ITERATE_HASH(name, funcs, hash_i)
      if(IS_SET(funcs->aux_type, aux_type))
        hashPut(data, name, funcs->new());
    deleteHashIterator(hash_i);
    return data;
  }
***************
*** 107,118 ****
    AUXILIARY_FUNCS *funcs = NULL;
    const char       *name = NULL;
  
!   while( (name = hashIteratorCurrentKey(hash_i)) != NULL) {
!     funcs = hashIteratorCurrentVal(hash_i);
!     hashIteratorNext(hash_i);
      if(IS_SET(funcs->aux_type, aux_type) && !hashGet(data, name))
        hashPut(data, name, funcs->new());
-   }
    deleteHashIterator(hash_i);
  }
  
--- 104,112 ----
    AUXILIARY_FUNCS *funcs = NULL;
    const char       *name = NULL;
  
!   ITERATE_HASH(name, funcs, hash_i) 
      if(IS_SET(funcs->aux_type, aux_type) && !hashGet(data, name))
        hashPut(data, name, funcs->new());
    deleteHashIterator(hash_i);
  }
  
***************
*** 125,133 ****
    void            *entry  = NULL;
    const char      *name   = NULL;
  
!   while( (name = hashIteratorCurrentKey(hash_i)) != NULL) {
!     entry = hashIteratorCurrentVal(hash_i);
!     hashIteratorNext(hash_i);
      funcs = auxiliariesGetFuncs(name);
      funcs->delete(entry);
    }
--- 119,125 ----
    void            *entry  = NULL;
    const char      *name   = NULL;
  
!   ITERATE_HASH(name, entry, hash_i) {
      funcs = auxiliariesGetFuncs(name);
      funcs->delete(entry);
    }
***************
*** 144,152 ****
    void            *entry  = NULL;
    const char      *name   = NULL;
  
!   while( (name = hashIteratorCurrentKey(hash_i)) != NULL) {
!     entry = hashIteratorCurrentVal(hash_i);
!     hashIteratorNext(hash_i);
      funcs = auxiliariesGetFuncs(name);
      store_set(set, name, funcs->store(entry));
    }
--- 136,142 ----
    void            *entry  = NULL;
    const char      *name   = NULL;
  
!   ITERATE_HASH(name, entry, hash_i) {
      funcs = auxiliariesGetFuncs(name);
      store_set(set, name, funcs->store(entry));
    }
***************
*** 162,170 ****
    AUXILIARY_FUNCS *funcs = NULL;
    const char       *name = NULL;
  
!   while( (name = hashIteratorCurrentKey(hash_i)) != NULL) {
!     funcs = hashIteratorCurrentVal(hash_i);
!     hashIteratorNext(hash_i);
      if(!IS_SET(funcs->aux_type, aux_type))
        continue;
      hashPut(data, name, funcs->read(read_set(set, name)));
--- 152,158 ----
    AUXILIARY_FUNCS *funcs = NULL;
    const char       *name = NULL;
  
!   ITERATE_HASH(name, funcs, hash_i) {
      if(!IS_SET(funcs->aux_type, aux_type))
        continue;
      hashPut(data, name, funcs->read(read_set(set, name)));
***************
*** 184,192 ****
    // first, delete all of the old data
    if(hashSize(to) > 0) {
      hash_i = newHashIterator(to);
!     while( (name = hashIteratorCurrentKey(hash_i)) != NULL) {
!       entry = hashIteratorCurrentVal(hash_i);
!       hashIteratorNext(hash_i);
        funcs = auxiliariesGetFuncs(name);
        funcs->delete(entry);
      }
--- 172,178 ----
    // first, delete all of the old data
    if(hashSize(to) > 0) {
      hash_i = newHashIterator(to);
!     ITERATE_HASH(name, entry, hash_i) {
        funcs = auxiliariesGetFuncs(name);
        funcs->delete(entry);
      }
***************
*** 196,204 ****
    // now, copy in all of the new data
    if(hashSize(from) > 0) {
      hash_i = newHashIterator(from);
!     while( (name = hashIteratorCurrentKey(hash_i)) != NULL) {
!       entry = hashIteratorCurrentVal(hash_i);
!       hashIteratorNext(hash_i);
        funcs = auxiliariesGetFuncs(name);
        hashPut(to, name, funcs->copy(entry));
      }
--- 182,188 ----
    // now, copy in all of the new data
    if(hashSize(from) > 0) {
      hash_i = newHashIterator(from);
!     ITERATE_HASH(name, entry, hash_i) {
        funcs = auxiliariesGetFuncs(name);
        hashPut(to, name, funcs->copy(entry));
      }
diff -crN nakedmudv1.5/src/auxiliary.d nakedmudv2.0/src/auxiliary.d
*** nakedmudv1.5/src/auxiliary.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/auxiliary.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ auxiliary.d auxiliary.o: auxiliary.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h storage.h auxiliary.h
diff -crN nakedmudv1.5/src/auxiliary.h nakedmudv2.0/src/auxiliary.h
*** nakedmudv1.5/src/auxiliary.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/auxiliary.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 18,23 ****
--- 18,24 ----
  #define AUXILIARY_TYPE_ROOM      (1 << 1)
  #define AUXILIARY_TYPE_OBJ       (1 << 2)
  #define AUXILIARY_TYPE_ZONE      (1 << 3)
+ #define AUXILIARY_TYPE_SOCKET    (1 << 4)
  
  
  //
diff -crN nakedmudv1.5/src/bitvector.c nakedmudv2.0/src/bitvector.c
*** nakedmudv1.5/src/bitvector.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/bitvector.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,250 ----
+ //*****************************************************************************
+ //
+ // bitvector.c
+ //
+ // One of the questions that came up when designing NakedMud is, how do we
+ // efficiently implement bitvectors while maintaining the modularity of the mud?
+ // For those unfamiliar with the purposes of a bitvector, let me elaborate:
+ // there are many instances in which we may want to know about the presence or
+ // absence of a property (e.g. is the room dark? is the character blind?). We
+ // could easily have a variable for each of these properties in the relevant
+ // datastructures, but this is often quite wasteful on memory. What would be
+ // really nice is if we could compress the space that it took to store one
+ // bit of information (in C, the smallest basic datatype is 8 bits ... i.e. we
+ // are wasting 7 bits to store a piece of information that be represented as
+ // on/off). In a nutshell, this is the purpose of a bitvector (there are more
+ // reasons why bitvectors are attractive, but this is perhaps the most important
+ // one in the context of muds).
+ //
+ // For anyone who has ever worked on a DIKU-derivative, they know that
+ // bits in a bitvector are typically declared on after another like this:
+ //    #define BIT_ONE    (1 << 0)
+ //    #define BIT_TWO    (1 << 1)
+ //    #define BIT_THREE  (1 << 2)
+ //    ...
+ //
+ // Of course, this is hugely unattractive for us: If we had a module that wanted
+ // to add a new bit, we surely would not want to add it to some global header
+ // file; we would want to keep the definition within the module headers. And,
+ // most certainly we cannot do this because we have to assocciate a position
+ // with each bit name, and every other module has to know that position so that
+ // noone else adds a new bit with the same position. This module is an attempt
+ // to address this problem, allowing modules to use bits, keep their 
+ // declarations in some place local to the module, and make sure there are no
+ // conflicting definitions. This also ensures that bits are persistent for all
+ // rooms, objects, and characters (ie. they save if we crash, or the player
+ // logs off, or whatnot).
+ //
+ //*****************************************************************************
+ 
+ #include "mud.h"
+ #include "utils.h"
+ 
+ #include "bitvector.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // local functions, datastructures, and defines
+ //*****************************************************************************
+ 
+ // optimally, this should be about 120% bigger than the number
+ // of distinct types of bitvectors we'd expect to have in the game
+ #define BITVECTOR_TABLE_SIZE      50
+ 
+ // a table of mappings between bitvector names, and the 
+ // data assocciated with them (i.e. bit:value mappings)
+ HASHTABLE *bitvector_table = NULL;
+ 
+ typedef struct bitvector_data {
+   HASHTABLE *bitmap; // a mapping from bit name to bit number
+   char        *name; // which bitvector is this?
+ } BITVECTOR_DATA;
+ 
+ struct bitvector {
+   BITVECTOR_DATA *data; // the data corresponding to this bitvector
+   char           *bits; // the bits we have set/unset
+ };
+ 
+ BITVECTOR_DATA *newBitvectorData(const char *name) {
+   BITVECTOR_DATA *data = malloc(sizeof(BITVECTOR_DATA));
+   data->bitmap = newHashtable(32);
+   data->name   = strdup(name);
+   return data;
+ }
+ 
+ 
+ 
+ 
+ //*****************************************************************************
+ // implementation of bitvector.h
+ //*****************************************************************************
+ void init_bitvectors() {
+   // create the bitvector table
+   bitvector_table = newHashtable(BITVECTOR_TABLE_SIZE);
+ 
+   // and also create some of the basic bitvectors and 
+   // bits that come stock and are required for the core release
+   bitvectorCreate("char_prfs");
+   bitvectorAddBit("char_prfs", "buildwalk");
+ 
+   bitvectorCreate("obj_bits");
+   bitvectorAddBit("obj_bits", "notake");
+ }
+ 
+ void bitvectorAddBit(const char *name, const char *bit) {
+   BITVECTOR_DATA *data = hashGet(bitvector_table, name);
+   if(data != NULL)
+     hashPut(data->bitmap, bit, (void *)(hashSize(data->bitmap) + 1));
+ }
+ 
+ void bitvectorCreate(const char *name) {
+   if(!hashGet(bitvector_table, name))
+     hashPut(bitvector_table, name, newBitvectorData(name));
+ }
+ 
+ BITVECTOR *newBitvector() {
+   BITVECTOR *v = malloc(sizeof(BITVECTOR));
+   bzero(v, sizeof(BITVECTOR));
+   return v;
+ }
+ 
+ BITVECTOR   *bitvectorInstanceOf(const char *name) {
+   BITVECTOR_DATA *data = hashGet(bitvector_table, name);
+   BITVECTOR    *vector = NULL;
+   if(data != NULL) {
+     int vector_len = hashSize(data->bitmap)/8 + 1;
+     vector = newBitvector();
+     vector->data = data;
+     vector->bits = malloc(sizeof(char) * vector_len);
+     bzero(vector->bits, vector_len);
+   }
+   return vector;
+ }
+ 
+ void         deleteBitvector(BITVECTOR *v) {
+   if(v->bits) free(v->bits);
+   free(v);
+ }
+ 
+ void         bitvectorCopyTo(BITVECTOR *from, BITVECTOR *to) {
+   int bit_len = 1 + hashSize(from->data->bitmap)/8;
+   to->data = from->data;
+   if(to->bits) free(to->bits);
+   to->bits = malloc(sizeof(char) * bit_len);
+   to->bits = memcpy(to->bits, from->bits, bit_len);
+ }
+ 
+ BITVECTOR   *bitvectorCopy(BITVECTOR *v) {
+   BITVECTOR *newvector = bitvectorInstanceOf(v->data->name);
+   bitvectorCopyTo(v, newvector);
+   return newvector;
+ }
+ 
+ bool bitIsSet(BITVECTOR *v, const char *bit) {
+   // first, parse all of the names
+   bool found = FALSE;
+   int i, num_names = 0;
+   char **bits = parse_keywords(bit, &num_names);
+ 
+   // check for one
+   for(i = 0; i < num_names && !found; i++) {
+     found = bitIsOneSet(v, bits[i]);
+     free(bits[i]);
+   }
+ 
+   // continue our clean up
+   for(; i < num_names; i++)
+     free(bits[i]);
+   free(bits);
+   return found;
+ }
+ 
+ bool bitIsAllSet(BITVECTOR *v, const char *bit) {
+   // first, parse all of the names
+   bool found = TRUE;
+   int i, num_names = 0;
+   char **bits = parse_keywords(bit, &num_names);
+ 
+   // check for each one
+   for(i = 0; i < num_names && found; i++) {
+     found = bitIsOneSet(v, bits[i]);
+     free(bits[i]);
+   }
+ 
+   // continue our clean up
+   for(; i < num_names; i++)
+     free(bits[i]);
+   free(bits);
+   return found;
+ }
+ 
+ bool bitIsOneSet(BITVECTOR *v, const char *bit) {
+   int val = (int)hashGet(v->data->bitmap, bit);
+   return IS_SET(v->bits[val/8], (1 << (val % 8)));
+ }
+ 
+ void bitSet(BITVECTOR *v, const char *name) {
+   // first, parse all of the names
+   int i, num_names = 0;
+   char **bits = parse_keywords(name, &num_names);
+ 
+   // set each one
+   for(i = 0; i < num_names; i++) {
+     int val = (int)hashGet(v->data->bitmap, bits[i]);
+     free(bits[i]);
+     // 0 is a filler meaning 'this is not an actual name for a bit'
+     if(val == 0) continue;
+     SET_BIT(v->bits[val/8], (1 << (val % 8)));
+   }
+   free(bits);
+ }
+ 
+ void bitRemove(BITVECTOR *v, const char *name) {
+   // first, parse all of the names
+   int i, num_names = 0;
+   char **bits = parse_keywords(name, &num_names);
+ 
+   // set each one
+   for(i = 0; i < num_names; i++) {
+     int val = (int)hashGet(v->data->bitmap, bits[i]);
+     REMOVE_BIT(v->bits[val/8], (1 << (val % 8)));
+     free(bits[i]);
+   }
+   free(bits);
+ }
+ 
+ void bitToggle(BITVECTOR *v, const char *name) {
+   // first, parse all of the names
+   int i, num_names = 0;
+   char **bits = parse_keywords(name, &num_names);
+ 
+   // set each one
+   for(i = 0; i < num_names; i++) {
+     int val = (int)hashGet(v->data->bitmap, bits[i]);
+     free(bits[i]);
+     // 0 is a filler meaning 'this is not an actual name for a bit'
+     if(val == 0) continue;
+     TOGGLE_BIT(v->bits[val/8], (1 << (val % 8)));
+   }
+   free(bits);
+ }
+ 
+ const char *bitvectorGetBits(BITVECTOR *v) {
+   static char bits[MAX_BUFFER];
+   HASH_ITERATOR *hash_i = newHashIterator(v->data->bitmap);
+   const char *key = NULL;
+   void *val       = NULL;
+   int bit_i       = 0;
+   *bits = '\0';
+ 
+   // add each set bit to our list to store
+   ITERATE_HASH(key, val, hash_i) {
+     if(bitIsOneSet(v, key)) {
+       bit_i += snprintf(bits+bit_i, MAX_BUFFER-bit_i, "%s%s", 
+ 			(bit_i == 0 ? "" : ", "), key);
+     }
+   }
+   deleteHashIterator(hash_i);
+   return bits;
+ }
diff -crN nakedmudv1.5/src/bitvector.d nakedmudv2.0/src/bitvector.d
*** nakedmudv1.5/src/bitvector.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/bitvector.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ bitvector.d bitvector.o: bitvector.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h
diff -crN nakedmudv1.5/src/bitvector.h nakedmudv2.0/src/bitvector.h
*** nakedmudv1.5/src/bitvector.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/bitvector.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,100 ----
+ #ifndef BITVECTOR_H
+ #define BITVECTOR_H
+ //*****************************************************************************
+ //
+ // bitvector.h
+ //
+ // One of the questions that came up when designing NakedMud is, how do we
+ // efficiently implement bitvectors while maintaining the modularity of the mud?
+ // For those unfamiliar with the purposes of a bitvector, let me elaborate:
+ // there are many instances in which we may want to know about the presence or
+ // absence of a property (e.g. is the room dark? is the character blind?). We
+ // could easily have a variable for each of these properties in the relevant
+ // datastructures, but this is often quite wasteful on memory. What would be
+ // really nice is if we could compress the space that it took to store one
+ // bit of information (in C, the smallest basic datatype is 8 bits ... i.e. we
+ // are wasting 7 bits to store a piece of information that be represented as
+ // on/off). In a nutshell, this is the purpose of a bitvector (there are more
+ // reasons why bitvectors are attractive, but this is perhaps the most important
+ // one in the context of muds).
+ //
+ // For anyone who has ever worked on a DIKU-derivative, they know that
+ // bits in a bitvector are typically declared on after another like this:
+ //    #define BIT_ONE    (1 << 0)
+ //    #define BIT_TWO    (1 << 1)
+ //    #define BIT_THREE  (1 << 2)
+ //    ...
+ //
+ // Of course, this is hugely unattractive for us: If we had a module that wanted
+ // to add a new bit, we surely would not want to add it to some global header
+ // file; we would want to keep the definition within the module headers. And,
+ // most certainly we cannot do this because we have to assocciate a position
+ // with each bit name, and every other module has to know that position so that
+ // noone else adds a new bit with the same position. This module is an attempt
+ // to address this problem, allowing modules to use bits, keep their 
+ // declarations in some place local to the module, and make sure there are no
+ // conflicting definitions. This also ensures that bits are persistent for all
+ // rooms, objects, and characters (ie. they save if we crash, or the player
+ // logs off, or whatnot).
+ //
+ //*****************************************************************************
+ 
+ typedef struct bitvector BITVECTOR;
+ 
+ //
+ // prepare bitvector systems for use
+ void init_bitvectors();
+ 
+ //
+ // Create a new type of bitvector. This must be called before any bit types 
+ // can be added, or before a bitvector of the given name can be created
+ void bitvectorCreate(const char *name);
+ 
+ //
+ // Add a new bit to an existing bitvector. The bitvector must have already
+ // been created. Multiple bits can be added if their names are comma-separated.
+ // This should only be called after init_bitvectors() is run, and it should 
+ // never be called when the game is actually running (i.e. the world has loaded,
+ // mobs have spawned, etc...). Ideally, bitvectorAddBit should only ever be 
+ // called in a module's initialization function.
+ void bitvectorAddBit(const char *name, const char *bit);
+ 
+ //
+ // create a new instance of the bitvector with the given name. 
+ // Return NULL if a bitvector with the given name does not exist
+ BITVECTOR   *bitvectorInstanceOf(const char *name);
+ void         deleteBitvector(BITVECTOR *v);
+ void         bitvectorCopyTo(BITVECTOR *from, BITVECTOR *to);
+ BITVECTOR   *bitvectorCopy(BITVECTOR *v);
+ 
+ //
+ // checks to see if ANY of the bits in the name list are set. Name can be 
+ // a single bit, or a comma-separated list of bits
+ bool bitIsSet(BITVECTOR *v, const char *bit);
+ 
+ //
+ // checks to see if ALL of the bits in the name list are set
+ bool bitIsAllSet(BITVECTOR *v, const char *bit);
+ 
+ //
+ // Check to see if only one bit is set, unlike bit_is_set and
+ // bit_is_all_set, which check for potentially multiple functions
+ bool bitIsOneSet(BITVECTOR *v, const char *bit);
+ 
+ //
+ // set the bits in the name list onto the bitvector
+ void bitSet(BITVECTOR *v, const char *name);
+ 
+ //
+ // remove the bits in the name list from the bitvector
+ void bitRemove(BITVECTOR *v, const char *name);
+ 
+ //
+ // toggle the specified bits on or off... whichever one they are not, currently
+ void bitToggle(BITVECTOR *v, const char *name);
+ 
+ //
+ // return a comma-separated list of the bits the vector has set
+ const char *bitvectorGetBits(BITVECTOR *v);
+ 
+ #endif // BITVECTOR_H
diff -crN nakedmudv1.5/src/body.d nakedmudv2.0/src/body.d
*** nakedmudv1.5/src/body.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/body.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ body.d body.o: body.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h body.h utils.h
diff -crN nakedmudv1.5/src/buffer.c nakedmudv2.0/src/buffer.c
*** nakedmudv1.5/src/buffer.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/buffer.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,311 ----
+ //*****************************************************************************
+ //
+ // buffer.c
+ //
+ // The buffer datastructure is a string-like thing of infinite length. Contains
+ // some basic utilities for interacting with it.
+ //
+ //*****************************************************************************
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ #include "mud.h"
+ #include "utils.h"
+ #include "buffer.h"
+ 
+ 
+ struct buffer_data {
+   char *data;   // what we're holding
+   int  maxlen;  // what's the maximum storage capacity of data
+   int  len;     // what's the current content length of data
+ };
+ 
+ BUFFER    *newBuffer   (int start_capacity) {
+   BUFFER *buf = malloc(sizeof(BUFFER));
+   buf->data   = malloc(sizeof(char) * start_capacity);
+   *buf->data  = '\0';
+   buf->maxlen = start_capacity;
+   buf->len    = 0;
+   return buf;
+ }
+ 
+ void        deleteBuffer(BUFFER *buf) {
+   free(buf->data);
+   free(buf);
+ }
+ 
+ void        bufferExpand(BUFFER *buf, int newsize) {
+   char *newdata = malloc(sizeof(char) * newsize);
+   strcpy(newdata, buf->data);
+   free(buf->data);
+   buf->maxlen = newsize;
+   buf->data = newdata;
+ }
+ 
+ void        bufferCat   (BUFFER *buf, const char *txt) {
+   int txtlen = strlen(txt);
+   // see if we need to expand the size of the buffer
+   if(txtlen + buf->len >= buf->maxlen)
+     bufferExpand(buf, ((txtlen + buf->len) * 5) / 4 + 20); 
+   // copy the new text over
+   strcat(buf->data+buf->len, txt);
+   buf->len += txtlen;
+ }
+ 
+ void        bufferClear (BUFFER *buf) {
+   *buf->data = '\0';
+   buf->len = 0;
+ }
+ 
+ BUFFER    *bufferCopy  (BUFFER *buf) {
+   BUFFER *newbuf = newBuffer(buf->maxlen);
+   memcpy(newbuf->data, buf->data, buf->maxlen);
+   newbuf->len = buf->len;
+   return newbuf;
+ }
+ 
+ void        bufferCopyTo(BUFFER *from, BUFFER *to) {
+   free(to->data);
+   to->data   = strdup(from->data);
+   to->len    = from->len;
+   to->maxlen = from->maxlen;
+ }
+ 
+ const char *bufferString(BUFFER *buf) {
+   return buf->data;
+ }
+ 
+ int         bufferLength(BUFFER *buf) {
+   return buf->len;
+ }
+ 
+ int bprintf(BUFFER *buf, char *fmt, ...) {  
+   static int printsize = 8192;
+   char buftmp[printsize];
+   va_list va;
+   int res;
+ 
+   va_start(va, fmt);
+   res = vsnprintf(buftmp, printsize, fmt, va);
+   va_end(va);
+     
+   if (res >= printsize - 1)
+     *buftmp = '\0';
+   else
+     bufferCat(buf, buftmp);
+    
+   return res;
+ }
+ 
+ int bufferReplace(BUFFER *buf, const char *a, const char *b, int all) {
+   // first, check if we'll need to expand the size of the buffer
+   int a_len = strlen(a), b_len = strlen(b);
+   int len_needed = buf->maxlen;
+   int replaced = 0;
+ 
+   if(b_len - a_len > 0) {
+     int to_replace = (all ? 
+ 		      count_occurences(buf->data, a) : 
+ 		      strstr(buf->data, a) != NULL);
+     // if we don't have any to replace, do nothing
+     if(to_replace == 0) return 0;
+ 
+     // if we won't have enough room, do the expansion
+     if(to_replace * (b_len - a_len) + buf->len > buf->maxlen)
+       len_needed = ((buf->maxlen + to_replace*(b_len-a_len))*5)/4 + 20;
+   }
+ 
+   int buf_i, tmp_i;
+   char buftmp[len_needed];
+ 
+   // go through and replace all the occurences we need to
+   for(buf_i = tmp_i = 0; buf->data[buf_i] != '\0';) {
+     // we found a match
+     if(!strncmp(buf->data+buf_i, a, a_len)) {
+       replaced++;
+       strcpy(buftmp+tmp_i, b);
+       buf_i += a_len;
+       tmp_i += b_len;
+       // exit if we only need to replace the first occurence
+       if(all == 0) break;
+     }
+     else {
+       buftmp[tmp_i] = buf->data[buf_i];
+       tmp_i++; buf_i++;
+     }
+   }
+ 
+   // continue filling up the tmpbuf (if we only replaced 1, and not all)
+   for(; buf->data[buf_i] != '\0'; buf_i++, tmp_i++)
+     buftmp[tmp_i] = buf->data[buf_i];
+ 
+   // make sure the end of string marker is in place
+   buftmp[tmp_i] = '\0';
+ 
+   // copy over all the changes
+   if(buf->maxlen >= len_needed) {
+     strcpy(buf->data, buftmp);
+     buf->len = tmp_i;
+   }
+   else {
+     free(buf->data);
+     buf->data = malloc(len_needed);
+     strcpy(buf->data, buftmp);
+     buf->maxlen = len_needed;
+     buf->len    = tmp_i;
+   }
+ 
+   return replaced;
+ }
+ 
+ 
+ int bufferInsert(BUFFER *buf, const char *newline, int line) {
+   // first, check if we'll need to expand the size of the buffer
+   int line_len = strlen(newline);
+   if(line_len + buf->len + 2 >= buf->maxlen) // +2 for \r\n
+     bufferExpand(buf, ((line_len + buf->len + 2) * 5)/4 + 20);
+ 
+   // insert it in
+   char *start = line_start(buf->data, line);
+   if(start != NULL) {
+     char tmpbuf[buf->maxlen];
+     sprintf(tmpbuf, "%s", start);
+     sprintf(start, "%s\r\n", newline);
+     strcpy(start+line_len+2, tmpbuf);
+     buf->len = buf->len + line_len + 2;
+     return TRUE;
+   }
+ 
+   return FALSE;
+ }
+ 
+ int bufferRemove(BUFFER *buf, int line) {
+   char *start = line_start(buf->data, line);
+   if(start == NULL) 
+     return FALSE;
+ 
+   int i;
+   // copy over the line with everything from the end of the line onwards
+   for(i = 0; start[i] != '\0'; i++) {
+     if(start[i] == '\n') {
+       i++;
+       break;
+     }
+   }
+   strcpy(start, start+i);
+   buf->len = strlen(buf->data);
+   return TRUE;
+ }
+ 
+ int bufferReplaceLine(BUFFER *buf, const char *newline, int line) {
+   if(bufferRemove(buf, line))
+     return bufferInsert(buf, newline, line);
+   else
+     return 0;
+ }
+ 
+ 
+ void bufferFormat(BUFFER *buf, int max_width, int indent) {
+   char formatted[(buf->len * 3)/2];
+   bool needs_capital = TRUE, needs_indent = FALSE;
+   int fmt_i = 0, buf_i = 0, col = 0;
+ 
+   // put in our indent
+   if(indent > 0) {
+     char fmt[20];
+     sprintf(fmt, "%%%ds", indent);
+     sprintf(formatted, fmt, " ");
+     fmt_i += indent;
+     col   += indent;
+ 
+     // skip the leading spaces
+     while(isspace(buf->data[buf_i]) && buf->data[buf_i] != '\0')
+       buf_i++;
+   }
+ 
+ 
+   for(; buf->data[buf_i] != '\0'; buf_i++) {
+     // we have to put a newline in because the word won't fit on the line
+     if(col + next_space_in(buf->data+buf_i) > max_width-2) {
+       formatted[fmt_i] = '\r'; fmt_i++;
+       formatted[fmt_i] = '\n'; fmt_i++;
+       col = 0;
+     }
+ 
+     char ch = buf->data[buf_i];
+ 
+     // no spaces on newlines
+     if(isspace(ch) && col == 0)
+       continue;
+     // we will do our own sentance formatting
+     else if(needs_capital && isspace(ch))
+       continue;
+     // delete multiple spaces
+     else if(isspace(ch) && fmt_i > 0 && isspace(formatted[fmt_i-1]))
+       continue;
+     // treat newlines as spaces (to separate words on different lines), 
+     // since we are creating our own newlines
+     else if(ch == '\r' || ch == '\n') {
+       // we've already spaced
+       if(col == 0)
+ 	continue;
+       formatted[fmt_i] = ' ';
+       col++;
+     }
+     // if someone is putting more than 1 sentence delimiter, we
+     // need to catch it so we will still capitalize the next word
+     else if(strchr("?!.", ch)) {
+       needs_capital = TRUE;
+       needs_indent  = TRUE;
+       formatted[fmt_i] = ch;
+       col++;
+     }
+     // see if we are the first letter after the end of a sentence
+     else if(needs_capital) {
+       // check if indenting will make it so we don't
+       // have enough room to print the word. If that's the
+       // case, then skip down to a new line instead
+       if(col + 2 + next_space_in(buf->data+buf_i) > max_width-2) {
+ 	formatted[fmt_i] = '\r'; fmt_i++;
+ 	formatted[fmt_i] = '\n'; fmt_i++;
+ 	col = 0;
+       }
+       // indent two spaces if we're not at the start of a line 
+       else if(needs_indent && buf_i-1 >= 0 && buf->data[buf_i-1] != '\n') {
+ 	formatted[fmt_i] = ' '; fmt_i++;
+ 	formatted[fmt_i] = ' '; fmt_i++;
+ 	col += 2;
+       }
+       // capitalize the first letter on the new word
+       formatted[fmt_i] = toupper(ch);
+       needs_capital = FALSE;
+       needs_indent  = FALSE;
+       col++;
+     }
+     else {
+       formatted[fmt_i] = ch;
+       col++;
+     }
+ 
+     fmt_i++;
+   }
+ 
+   // tag a newline onto the end of the string if there isn't one already
+   if(fmt_i > 0 && formatted[fmt_i-1] != '\n') {
+     formatted[fmt_i++] = '\r';
+     formatted[fmt_i++] = '\n';
+   }
+ 
+   formatted[fmt_i] = '\0';
+ 
+   // make sure we have enough room to copy everything over
+   if(fmt_i >= buf->maxlen)
+     bufferExpand(buf, (fmt_i * 5)/4 + 20);
+   
+   // copy over our changes
+   strcpy(buf->data, formatted);
+   buf->len = fmt_i;
+ }
diff -crN nakedmudv1.5/src/buffer.d nakedmudv2.0/src/buffer.d
*** nakedmudv1.5/src/buffer.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/buffer.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ buffer.d buffer.o: buffer.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h
diff -crN nakedmudv1.5/src/buffer.h nakedmudv2.0/src/buffer.h
*** nakedmudv1.5/src/buffer.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/buffer.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,58 ----
+ #ifndef BUFFER_H
+ #define BUFFER_H
+ //*****************************************************************************
+ //
+ // buffer.h
+ //
+ // The buffer datastructure is a string-like thing of infinite length. Contains
+ // some basic utilities for interacting with it.
+ //
+ //*****************************************************************************
+ 
+ typedef struct buffer_data BUFFER;
+ 
+ // allocate/deallocate a buffer. start capacity must be supplied, but the
+ // buffer can grow indefinitely.
+ BUFFER *newBuffer(int start_capacity);
+ void deleteBuffer(BUFFER *buf);
+ 
+ // concatinate the text to the end of the buffer
+ void        bufferCat   (BUFFER *buf, const char *txt);
+ 
+ // clear the buffer's contents
+ void bufferClear(BUFFER *buf);
+ 
+ // copy the contents of one buffer to another
+ void bufferCopyTo(BUFFER *from, BUFFER *to);
+ 
+ // return a copy of the buffer
+ BUFFER *bufferCopy(BUFFER *buf);
+ 
+ // return the string contents of the buffer
+ const char *bufferString(BUFFER *buf);
+ 
+ // return the length of the buffer's contents
+ int bufferLength(BUFFER *buf);
+ 
+ // do a formatted print onto the buffer (concats it)
+ int bprintf(BUFFER *buf, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+ 
+ // replace 'a' with 'b'. Return back how many occurences were replaced. If
+ // all is FALSE, then only the first occurence is replaced.
+ int bufferReplace(BUFFER *buf, const char *a, const char *b, int all);
+ 
+ // insert the line into the string at the specified place. If the line was
+ // inserted, return TRUE. Otherwise, return FALSE.
+ int bufferInsert(BUFFER *buf, const char *newline, int line);
+ 
+ // delete the specified line. Return TRUE if successful and FALSE otherwise
+ int bufferRemove(BUFFER *buf, int line);
+ 
+ // replace the given line number with the new information. Return TRUE if
+ // successful and FALSE otherwise.
+ int bufferReplaceLine(BUFFER *buf, const char *newline, int line);
+ 
+ // format a string with the given arguments
+ void bufferFormat(BUFFER *buf, int max_width, int indent);
+ 
+ #endif // BUFFER_H
diff -crN nakedmudv1.5/src/character.c nakedmudv2.0/src/character.c
*** nakedmudv1.5/src/character.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/character.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 91,97 ****
  struct char_data {
    // data for PCs only
    char                 * password;
-   bitvector_t            prfs;  
    room_vnum              loadroom;
    int                    imm_invis;
  
--- 91,96 ----
***************
*** 105,111 ****
    SOCKET_DATA          * socket;
    ROOM_DATA            * room;
    OBJ_DATA             * furniture;
!   char                 * desc;
    char                 * name;
    int                    level;
    int                    sex;
--- 104,110 ----
    SOCKET_DATA          * socket;
    ROOM_DATA            * room;
    OBJ_DATA             * furniture;
!   BUFFER               * desc;
    char                 * name;
    int                    level;
    int                    sex;
***************
*** 113,118 ****
--- 112,118 ----
  
    LIST                 * inventory;
    HASHTABLE            * auxiliary_data;
+   BITVECTOR            * prfs;
  
    // data for NPCs only
    dialog_vnum            dialog;
***************
*** 129,135 ****
    bzero(ch, sizeof(*ch));
  
    ch->password      = strdup("");
-   ch->prfs          = 0;
    ch->imm_invis     = 0;
  
    ch->loadroom      = NOWHERE;
--- 129,134 ----
***************
*** 140,146 ****
    ch->room          = NULL;
    ch->furniture     = NULL;
    ch->socket        = NULL;
!   ch->desc          = strdup("");
    ch->name          = strdup("");
    ch->level         = LEVEL_PLAYER;
    ch->sex           = SEX_NEUTRAL;
--- 139,145 ----
    ch->room          = NULL;
    ch->furniture     = NULL;
    ch->socket        = NULL;
!   ch->desc          = newBuffer(1);
    ch->name          = strdup("");
    ch->level         = LEVEL_PLAYER;
    ch->sex           = SEX_NEUTRAL;
***************
*** 153,158 ****
--- 152,158 ----
    ch->multi_name    = strdup("");
    ch->dialog        = NOTHING;
    ch->vnum          = NOBODY;
+   ch->prfs          = bitvectorInstanceOf("char_prfs");
  
    ch->auxiliary_data = newAuxiliaryData(AUXILIARY_TYPE_CHAR);
  
***************
*** 181,208 ****
    ch->multi_name =   strdup(multi_name ? multi_name : "");
  }
  
- void         charSetBit       ( CHAR_DATA *ch, int field, int bit) {
-   if(field == BITFIELD_PRFS)
-     SET_BIT(ch->prfs, (1 << bit));
- }
- 
- void         charRemoveBit    ( CHAR_DATA *ch, int field, int bit) {
-   if(field == BITFIELD_PRFS)
-     REMOVE_BIT(ch->prfs, (1 << bit));
- }
- 
- void         charToggleBit    ( CHAR_DATA *ch, int field, int bit) {
-   if(field == BITFIELD_PRFS)
-     TOGGLE_BIT(ch->prfs, (1 << bit));
- }
- 
- bool         charIsBitSet     ( CHAR_DATA *ch, int field, int bit) {
-   if(field == BITFIELD_PRFS && IS_SET(ch->prfs, (1 << bit)))
-     return TRUE;
- 
-   return FALSE;
- }
- 
  bool charIsNPC( CHAR_DATA *ch) {
    return (ch->uid >= START_MOB_UID);
  }
--- 181,186 ----
***************
*** 241,251 ****
  };
  
  const char  *charGetDesc      ( CHAR_DATA *ch) {
!   return ch->desc;
  }
  
! char       **charGetDescPtr   ( CHAR_DATA *ch) {
!   return &(ch->desc);
  }
  
  const char  *charGetRdesc     ( CHAR_DATA *ch) {
--- 219,229 ----
  };
  
  const char  *charGetDesc      ( CHAR_DATA *ch) {
!   return bufferString(ch->desc);
  }
  
! BUFFER      *charGetDescBuffer( CHAR_DATA *ch) {
!   return ch->desc;
  }
  
  const char  *charGetRdesc     ( CHAR_DATA *ch) {
***************
*** 273,285 ****
    return ch->position;
  };
  
- bitvector_t  charGetBits      ( CHAR_DATA *ch, int field) {
-   if(field == BITFIELD_PRFS)
-     return ch->prfs;
- 
-   return 0;
- }
- 
  BODY_DATA   *charGetBody      ( CHAR_DATA *ch) {
    return ch->body;
  }
--- 251,256 ----
***************
*** 308,313 ****
--- 279,288 ----
    return ch->imm_invis;
  }
  
+ BITVECTOR *charGetPrfs(CHAR_DATA *ch) {
+   return ch->prfs;
+ }
+ 
  void         charSetSocket    ( CHAR_DATA *ch, SOCKET_DATA *socket) {
    ch->socket = socket;
  };
***************
*** 339,346 ****
  };
  
  void         charSetDesc      ( CHAR_DATA *ch, const char *desc) {
!   if(ch->desc) free(ch->desc);
!   ch->desc = strdup(desc ? desc : "");
  };
  
  void         charSetBody      ( CHAR_DATA *ch, BODY_DATA *body) {
--- 314,321 ----
  };
  
  void         charSetDesc      ( CHAR_DATA *ch, const char *desc) {
!   bufferClear(ch->desc);
!   bufferCat(ch->desc, (desc ? desc : ""));
  };
  
  void         charSetBody      ( CHAR_DATA *ch, BODY_DATA *body) {
***************
*** 398,408 ****
  
    if(mob->password)    free(mob->password);
    if(mob->name)        free(mob->name);
!   if(mob->desc)        free(mob->desc);
    if(mob->rdesc)       free(mob->rdesc);
    if(mob->multi_rdesc) free(mob->multi_rdesc);
    if(mob->multi_name)  free(mob->multi_name);
    if(mob->keywords)    free(mob->keywords);
    deleteAuxiliaryData(mob->auxiliary_data);
  
    free(mob);
--- 373,384 ----
  
    if(mob->password)    free(mob->password);
    if(mob->name)        free(mob->name);
!   if(mob->desc)        deleteBuffer(mob->desc);
    if(mob->rdesc)       free(mob->rdesc);
    if(mob->multi_rdesc) free(mob->multi_rdesc);
    if(mob->multi_name)  free(mob->multi_name);
    if(mob->keywords)    free(mob->keywords);
+   if(mob->prfs)        deleteBitvector(mob->prfs);
    deleteAuxiliaryData(mob->auxiliary_data);
  
    free(mob);
***************
*** 423,428 ****
--- 399,405 ----
    charSetSex(mob,          read_int   (set, "sex"));
    charSetRace(mob,         read_string(set, "race"));
    charSetPassword(mob,     read_string(set, "password"));
+   bitSet(mob->prfs,        read_string(set, "prfs"));
  
    // read in PC data
    if(*charGetPassword(mob)) {
***************
*** 430,436 ****
      charSetUID(mob,        read_int   (set, "uid"));
      charSetLoadroom(mob,   read_int   (set, "loadroom"));
      charSetPos(mob,        read_int   (set, "position"));
-     mob->prfs = parse_bits(read_string(set, "prfs"));
    }
    // and NPC data
    else
--- 407,412 ----
***************
*** 459,476 ****
    store_string(set, "name",       mob->name);
    store_string(set, "keywords",   mob->keywords);
    store_string(set, "rdesc",      mob->rdesc);
!   store_string(set, "desc",       mob->desc);
    store_string(set, "multirdesc", mob->multi_rdesc);
    store_string(set, "multiname",  mob->multi_name);
    store_int   (set, "level",      mob->level);
    store_int   (set, "sex",        mob->sex);
    store_string(set, "race",       mob->race);
  
    // PC-only data
    if(!charIsNPC(mob)) {
      store_int   (set, "imm_invis",  mob->imm_invis);
      store_int   (set, "position",   mob->position);
-     store_string(set, "prfs",       write_bits(mob->prfs));
      store_string(set, "password",   mob->password);
      store_int   (set, "uid",        mob->uid);
      store_int   (set, "loadroom",   roomGetVnum(charGetRoom(mob)));
--- 435,452 ----
    store_string(set, "name",       mob->name);
    store_string(set, "keywords",   mob->keywords);
    store_string(set, "rdesc",      mob->rdesc);
!   store_string(set, "desc",       bufferString(mob->desc));
    store_string(set, "multirdesc", mob->multi_rdesc);
    store_string(set, "multiname",  mob->multi_name);
    store_int   (set, "level",      mob->level);
    store_int   (set, "sex",        mob->sex);
    store_string(set, "race",       mob->race);
+   store_string(set, "prfs",       bitvectorGetBits(mob->prfs));
  
    // PC-only data
    if(!charIsNPC(mob)) {
      store_int   (set, "imm_invis",  mob->imm_invis);
      store_int   (set, "position",   mob->position);
      store_string(set, "password",   mob->password);
      store_int   (set, "uid",        mob->uid);
      store_int   (set, "loadroom",   roomGetVnum(charGetRoom(mob)));
***************
*** 500,505 ****
--- 476,482 ----
    charSetRace       (to, charGetRace(from));
    charSetBody       (to, bodyCopy(charGetBody(from)));
    charSetImmInvis   (to, charGetImmInvis(from));
+   bitvectorCopyTo   (from->prfs, to->prfs);
  
    auxiliaryDataCopyTo(from->auxiliary_data, to->auxiliary_data);
  }
diff -crN nakedmudv1.5/src/character.d nakedmudv2.0/src/character.d
*** nakedmudv1.5/src/character.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/character.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ character.d character.o: character.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h body.h races.h handler.h \
+   auxiliary.h storage.h room.h character.h
diff -crN nakedmudv1.5/src/character.h nakedmudv2.0/src/character.h
*** nakedmudv1.5/src/character.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/character.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 49,54 ****
--- 49,58 ----
  __attribute__ ((format (printf, 2, 3)));
  void  send_to_list          (LIST *list, const char *format, ...) 
  __attribute__ ((format (printf, 2, 3)));
+ void send_around_char(CHAR_DATA *ch, bool hide_nosee, const char *format, ...) 
+ __attribute__ ((format (printf, 3, 4)));
+ void send_to_level(int level, const char *format, ...) 
+ __attribute__ ((format (printf, 2, 3)));
  
  
  //*****************************************************************************
***************
*** 66,74 ****
  const char  *charGetMultiName ( CHAR_DATA *ch);
  int          charGetLevel     ( CHAR_DATA *ch);
  int          charGetSex       ( CHAR_DATA *ch);
- bitvector_t  charGetBits      ( CHAR_DATA *ch, int field);
  // for editing with the text editor
! char       **charGetDescPtr   ( CHAR_DATA *ch);
  LIST        *charGetInventory ( CHAR_DATA *ch);
  BODY_DATA   *charGetBody      ( CHAR_DATA *ch);
  const char  *charGetRace      ( CHAR_DATA *ch);
--- 70,77 ----
  const char  *charGetMultiName ( CHAR_DATA *ch);
  int          charGetLevel     ( CHAR_DATA *ch);
  int          charGetSex       ( CHAR_DATA *ch);
  // for editing with the text editor
! BUFFER      *charGetDescBuffer( CHAR_DATA *ch);
  LIST        *charGetInventory ( CHAR_DATA *ch);
  BODY_DATA   *charGetBody      ( CHAR_DATA *ch);
  const char  *charGetRace      ( CHAR_DATA *ch);
***************
*** 78,83 ****
--- 81,88 ----
  int          charGetPos       ( CHAR_DATA *ch);
  void        *charGetAuxiliaryData(const CHAR_DATA *ch, const char *name);
  int          charGetImmInvis  ( CHAR_DATA *ch);
+ BITVECTOR   *charGetPrfs      ( CHAR_DATA *ch);
+ 
  
  void         charSetSocket    ( CHAR_DATA *ch, SOCKET_DATA *socket);
  void         charSetRoom      ( CHAR_DATA *ch, ROOM_DATA *room);
***************
*** 116,140 ****
  
  //*****************************************************************************
  //
- // Bitfields and their bits
- //
- //*****************************************************************************
- void         charToggleBit    ( CHAR_DATA *ch, int field, int bit);
- void         charSetBit       ( CHAR_DATA *ch, int field, int bit);
- void         charRemoveBit    ( CHAR_DATA *ch, int field, int bit);
- bool         charIsBitSet     ( CHAR_DATA *ch, int field, int bit);
- 
- // hmmm... we should really replace bitvectors with something a bit
- // more amenable to extention by modules. Perhaps use char_vars?
- #define BITFIELD_PRFS             0
- 
- #define PRF_BUILDWALK             0    // (1 << 0)
- #define PRF_MAPWALK               1    // (1 << 1)
- 
- 
- 
- //*****************************************************************************
- //
  // Sexes
  //
  //*****************************************************************************
--- 121,126 ----
diff -crN nakedmudv1.5/src/char_vars/char_vars.d nakedmudv2.0/src/char_vars/char_vars.d
*** nakedmudv1.5/src/char_vars/char_vars.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/char_vars/char_vars.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ char_vars/char_vars.d char_vars/char_vars.o: char_vars/char_vars.c mud.h wrapsock.h property_table.h \
+   list.h map.h hashtable.h set.h buffer.h bitvector.h utils.h character.h \
+   storage.h auxiliary.h char_vars/char_vars.h
diff -crN nakedmudv1.5/src/cmd_admin.c nakedmudv2.0/src/cmd_admin.c
*** nakedmudv1.5/src/cmd_admin.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/cmd_admin.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 29,34 ****
--- 29,109 ----
  
  
  //
+ // Perform a command multiple times
+ //
+ COMMAND(cmd_repeat) {
+   if(!arg || !*arg) {
+     send_to_char(ch, "What did you want to repeat, and how many times?\r\n");
+     return;
+   }
+ 
+   // how many times should we repeat?
+   char rep_buf[SMALL_BUFFER];
+   arg = one_arg(arg, rep_buf);
+   int  repeats = atoi(rep_buf);
+ 
+   // no command to delay
+   if(!*arg)
+     send_to_char(ch, "What command did you want to repeat?\r\n");
+   else if(repeats < 1)
+     send_to_char(ch, "You can only repeat commands a positive amounts of time.\r\n");
+   else {
+     int i;
+     // now, do the repeating
+     for(i = 0; i < repeats; i++)
+       do_cmd(ch, arg, TRUE, TRUE);
+   }
+ }
+ 
+ 
+ //
+ // Perform a command at another room or person
+ //
+ COMMAND(cmd_at) {
+   if(!arg || !*arg) {
+     send_to_char(ch, "Do what where?\r\n");
+     return;
+   }
+ 
+   // how many times should we repeat?
+   char where[SMALL_BUFFER];
+   arg = one_arg(arg, where);
+ 
+   // no command to delay
+   if(!*arg)
+     send_to_char(ch, "What were you trying to do, and where?\r\n");
+   else {
+     // first, are we trying to do this at a room vnum?
+     ROOM_DATA *room = NULL;
+ 
+     // are we looking for a vnum?
+     if(isdigit(*where))
+       room = worldGetRoom(gameworld, atoi(where));
+ 
+     // no room? Maybe its the name of someone
+     if(room == NULL) {
+       CHAR_DATA *tgt = generic_find(ch, where, FIND_TYPE_CHAR,
+ 				    FIND_SCOPE_ALL | FIND_SCOPE_VISIBLE,
+ 				    FALSE, NULL);
+       if(tgt != NULL)
+ 	room = charGetRoom(tgt);
+     }
+ 
+     if(room == NULL)
+       send_to_char(ch, "Where were you trying to do that?\r\n");
+     else {
+       ROOM_DATA *old_room = charGetRoom(ch);
+       char_from_room(ch);
+       char_to_room(ch, room);
+       do_cmd(ch, arg, TRUE, TRUE);
+       char_from_room(ch);
+       char_to_room(ch, old_room);
+     }
+   }
+ }
+ 
+ 
+ //
  // Go to a specific room, object, or character in the game. Rooms are referenced
  // by vnum. Everything else is referenced by name.
  //   usage: goto [thing]
***************
*** 122,174 ****
  // Perform a copyover
  //
  COMMAND(cmd_copyover) { 
!   FILE *fp;
!   SOCKET_DATA *dsock;
!   char buf[100];
!   char control_buf[20];
!   char port_buf[20];
!   LIST_ITERATOR *sock_i = newListIterator(socket_list);
!   
!   if ((fp = fopen(COPYOVER_FILE, "w")) == NULL)
!   {
!     text_to_char(ch, "Copyover file not writeable, aborted.\n\r");
!     return;
!   }
! 
!   sprintf(buf, "\n\r <*>            The world starts spinning             <*>\n\r");
! 
!   /* For each playing descriptor, save its state */
!   //  for (dsock = dsock_list; dsock ; dsock = dsock_next)
!   ITERATE_LIST(dsock, sock_i) {
!     compressEnd(dsock, dsock->compressing, FALSE);
!     if (dsock->state != STATE_PLAYING) {
!       text_to_socket(dsock, "\r\nSorry, we are rebooting. Come back in a few minutes.\r\n");
!       close_socket(dsock, FALSE);
!     }
!     else {
!       fprintf(fp, "%d %s %s\n",
! 	      dsock->control, charGetName(dsock->player), dsock->hostname);
!       /* save the player */
!       save_player(dsock->player);
!       text_to_socket(dsock, buf);
!     }
!   }
!   deleteListIterator(sock_i);
!   
!   fprintf (fp, "-1\n");
!   fclose (fp);
! 
! 
!   /* close any pending sockets */
!   recycle_sockets();
!   
!   /* exec - descriptors are inherited */
!   sprintf(control_buf, "%d", control);
!   sprintf(port_buf, "%d", mudport);
!   execl(EXE_FILE, "NakedMud", "-copyover", control_buf, port_buf, NULL);
! 
!   /* Failed - sucessful exec will not return */
!   text_to_char(ch, "Copyover FAILED!\n\r");
  }
  
  
--- 197,203 ----
  // Perform a copyover
  //
  COMMAND(cmd_copyover) { 
!   do_copyover(ch);
  }
  
  
diff -crN nakedmudv1.5/src/cmd_admin.d nakedmudv2.0/src/cmd_admin.d
*** nakedmudv1.5/src/cmd_admin.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/cmd_admin.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ cmd_admin.d cmd_admin.o: cmd_admin.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h world.h inform.h character.h \
+   handler.h utils.h log.h socket.h save.h event.h action.h storage.h
diff -crN nakedmudv1.5/src/cmd_builder.c nakedmudv2.0/src/cmd_builder.c
*** nakedmudv1.5/src/cmd_builder.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/cmd_builder.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 20,40 ****
  #include "inform.h"
  #include "utils.h"
  #include "races.h"
- #include "items.h"
  #include "dialog.h"
  
! // optional modules
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
  #include "scripts/script_set.h"
! #endif
  
  
  //
  // Try to dig a special exit in a specific direction. Unlike cmd_dig,
  // specdig does not link the room we're digging to, back to us, since
  // we can't really figure out what the opposite direction is
- //
  void try_specdig(CHAR_DATA *ch, const char *dir, room_vnum to) {
    if(roomGetExitSpecial(charGetRoom(ch), dir))
      send_to_char(ch, "You must fill in the %s exit before you dig a new exit.\r\n", dir);
--- 20,42 ----
  #include "inform.h"
  #include "utils.h"
  #include "races.h"
  #include "dialog.h"
  
! 
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
  #include "scripts/script_set.h"
! #include "items/items.h"
! 
  
  
  //
  // Try to dig a special exit in a specific direction. Unlike cmd_dig,
  // specdig does not link the room we're digging to, back to us, since
  // we can't really figure out what the opposite direction is
  void try_specdig(CHAR_DATA *ch, const char *dir, room_vnum to) {
    if(roomGetExitSpecial(charGetRoom(ch), dir))
      send_to_char(ch, "You must fill in the %s exit before you dig a new exit.\r\n", dir);
***************
*** 52,58 ****
  // Try to fill in a special exit in a specific direction. Unlike cmd_dig,
  // specdig does not fill in the exit on the other side, since we can't
  // really figure out what the opposite direction is.
- //
  void try_specfill(CHAR_DATA *ch, const char *dir) {
    if(!roomGetExitSpecial(charGetRoom(ch), dir))
      send_to_char(ch, "There doesn't seem to be an exit in that direction.\r\n");
--- 54,59 ----
***************
*** 193,204 ****
  	char_to_game(mob);
  	char_to_room(mob, charGetRoom(ch));
  
- #ifdef MODULE_SCRIPTS
  	// check for initialization scripts
  	try_scripts(SCRIPT_TYPE_INIT,
  		    mob, SCRIPTOR_CHAR,
  		    NULL, NULL, charGetRoom(mob), NULL, NULL, 0);
- #endif
        }
      }
  
--- 194,203 ----
***************
*** 212,223 ****
  	obj_to_game(obj);
  	obj_to_char(obj, ch);
  
- #ifdef MODULE_SCRIPTS
  	// check for initialization scripts
  	try_scripts(SCRIPT_TYPE_INIT,
  		    obj, SCRIPTOR_OBJ,
  		    ch, NULL, charGetRoom(ch), NULL, NULL, 0);
- #endif
        }
      }
    }
--- 211,220 ----
***************
*** 319,343 ****
  }
  
  
  //*****************************************************************************
  //
  // Functions for listing different types of data (zones, mobs, objs, etc...)
  //
  //*****************************************************************************
  
  //
  // Generic xxxlist for builders. If the thing to list doesn't have any types
! // (e.g. dialogs) then typer and type_namer can both be NULL
! //
  void do_list(CHAR_DATA *ch, 
! 	     void *getter, void *namer, 
! 	     void *typer,  void *type_namer, 
! 	     const char *datatype, char *arg) {
!   int (* type_func)(void *)              = typer;
!   const char *(* type_naming_func)(int)  = type_namer;
!   const char *(* naming_func)(void *)    = namer;
!   void *(* get_func)(void *, int)        = getter;
!   ZONE_DATA *zone                        = NULL;
    
    if(!arg || !*arg)
      zone = worldZoneBounding(gameworld, roomGetVnum(charGetRoom(ch)));
--- 316,359 ----
  }
  
  
+ //
+ // toggle buildwalking on and off
+ //
+ COMMAND(cmd_buildwalk) {
+   bitToggle(charGetPrfs(ch), "buildwalk");
+   send_to_char(ch, "Buildwalk %s.\r\n",
+ 	       (bitIsOneSet(charGetPrfs(ch), "buildwalk") ? "on":"off"));
+ }
+ 
+ 
  //*****************************************************************************
  //
  // Functions for listing different types of data (zones, mobs, objs, etc...)
  //
  //*****************************************************************************
+ const char *charGetListType(CHAR_DATA *ch) {
+   return charGetRace(ch);
+ }
+ 
+ const char *roomGetListType(ROOM_DATA *room) {
+   return terrainGetName(roomGetTerrain(room));
+ }
+ 
+ const char *scriptGetListType(SCRIPT_DATA *script) {
+   return scriptTypeName(scriptGetType(script));
+ }
+ 
  
  //
  // Generic xxxlist for builders. If the thing to list doesn't have any types
! // (e.g. dialogs) then type_namer can be NULL.
  void do_list(CHAR_DATA *ch, 
! 	     void *getter, void *namer, void *type_namer, 
! 	     const char *datatype, const char *arg) {
!   const char *(* type_naming_func)(void *)  = type_namer;
!   const char *(* naming_func)(void *)       = namer;
!   void *(* get_func)(void *, int)           = getter;
!   ZONE_DATA *zone                           = NULL;
    
    if(!arg || !*arg)
      zone = worldZoneBounding(gameworld, roomGetVnum(charGetRoom(ch)));
***************
*** 351,394 ****
      send_to_char(ch,
  " {wVnum  Name                                                                %s\r\n"
  "{b-------------------------------------------------------------------------------{n\r\n",
! 		 ((type_func == NULL || type_naming_func == NULL) ? "" : "Type")
! 		 );
      for(vnum = zoneGetMinBound(zone); vnum <= zoneGetMaxBound(zone); vnum++) {
        void *data = get_func(zone, vnum);
        if(data != NULL)
  	send_to_char(ch, "{y[{c%4d{y] {c%-50s{w%22s{n\r\n", 
  		     vnum, naming_func(data), 
! 		     ((type_func == NULL || type_naming_func == NULL) ? "" :
! 		      type_naming_func(type_func(data))));
      }
    }
  }
  
- 
- #ifdef MODULE_SCRIPTS
  COMMAND(cmd_sclist) {
!   do_list(ch, zoneGetScript, scriptGetName, scriptGetType, scriptTypeName,
! 	  "scripts", arg);
  }
- #endif
  
  COMMAND(cmd_rlist) {
!   do_list(ch, zoneGetRoom, roomGetName, roomGetTerrain, terrainGetName,
! 	  "rooms", arg);
  }
  
  COMMAND(cmd_mlist) {
!   //  do_list(ch, zoneGetMob, charGetName, charGetRace, raceGetName,
!   //	  "mobs", arg);
  }
  
  COMMAND(cmd_olist) {
!   do_list(ch, zoneGetObj, objGetName, objGetType, itemGetType,
! 	  "objects", arg);
  }
  
  COMMAND(cmd_dlist) {
!   do_list(ch, zoneGetDialog, dialogGetName, NULL, NULL, "dialogs", arg);
  }
  
  int zone_comparator(ZONE_DATA *zone1, ZONE_DATA *zone2) {
--- 367,401 ----
      send_to_char(ch,
  " {wVnum  Name                                                                %s\r\n"
  "{b-------------------------------------------------------------------------------{n\r\n",
! 		 (type_naming_func == NULL ? "" : "Type"));
      for(vnum = zoneGetMinBound(zone); vnum <= zoneGetMaxBound(zone); vnum++) {
        void *data = get_func(zone, vnum);
        if(data != NULL)
  	send_to_char(ch, "{y[{c%4d{y] {c%-50s{w%22s{n\r\n", 
  		     vnum, naming_func(data), 
! 		     (type_naming_func == NULL ? "" : type_naming_func(data)));
      }
    }
  }
  
  COMMAND(cmd_sclist) {
!   do_list(ch, zoneGetScript, scriptGetName, scriptGetListType, "scripts", arg);
  }
  
  COMMAND(cmd_rlist) {
!   do_list(ch, zoneGetRoom, roomGetName, roomGetListType, "rooms", arg);
  }
  
  COMMAND(cmd_mlist) {
!   do_list(ch, zoneGetMob, charGetName, charGetListType, "mobs", arg);
  }
  
  COMMAND(cmd_olist) {
!   do_list(ch, zoneGetObj, objGetName, objGetTypes, "objs", arg);
  }
  
  COMMAND(cmd_dlist) {
!   do_list(ch, zoneGetDialog, dialogGetName, NULL, "dialogs", arg);
  }
  
  int zone_comparator(ZONE_DATA *zone1, ZONE_DATA *zone2) {
diff -crN nakedmudv1.5/src/cmd_builder.d nakedmudv2.0/src/cmd_builder.d
*** nakedmudv1.5/src/cmd_builder.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/cmd_builder.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ cmd_builder.d cmd_builder.o: cmd_builder.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h world.h zone.h room.h \
+   exit.h movement.h character.h object.h handler.h inform.h utils.h \
+   races.h dialog.h scripts/script.h scripts/script_set.h items/items.h
diff -crN nakedmudv1.5/src/cmd_comm.c nakedmudv2.0/src/cmd_comm.c
*** nakedmudv1.5/src/cmd_comm.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/cmd_comm.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,25 ****
  #include "dialog.h"
  
  
! // option modules
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
! #endif
  
  
  //
--- 16,27 ----
  #include "dialog.h"
  
  
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
! 
  
  
  //
***************
*** 31,37 ****
  //   examples:
  //     ask bob about cats           ask bob about the topic, "cats"
  //     ask jim can I have a salad?  ask jim if you can have a salad
- //
  COMMAND(cmd_ask)
  {
    if(!arg || !*arg)
--- 33,38 ----
***************
*** 69,77 ****
  	send_to_char(ch, "{wYou ask %s%s, '%s'{n\r\n", 
  		     charGetName(tgt), (ask_about ? " about" : ""), arg);
  
- #ifdef MODULE_SCRIPTS
  	try_speech_script(ch, tgt, arg);
- #endif	
  
  	// see if the NPC has something to say in return
  	if(!try_dialog(ch, tgt, arg))
--- 70,76 ----
***************
*** 275,277 ****
--- 274,299 ----
      message(ch, NULL, NULL, NULL, FALSE, TO_WORLD, buf);
    }
  }
+ 
+ 
+ //
+ // Send a message to another character, and also make it beep
+ //
+ COMMAND(cmd_page) {
+   CHAR_DATA *tgt = NULL;
+   char name[SMALL_BUFFER];
+   arg = one_arg(arg, name);
+ 
+   if(!*name)
+     send_to_char(ch, "Page whom?\r\n");
+   else if( (tgt = generic_find(ch, name, FIND_TYPE_CHAR, 
+ 			       FIND_SCOPE_ALL | FIND_SCOPE_VISIBLE,
+ 			       FALSE, NULL)) == NULL)
+     send_to_char(ch, "Who were you looking for?\r\n");
+   else if(ch == tgt)
+     send_to_char(ch, "What did you want to let yourself know?\r\n");
+   else {
+     send_to_char(ch,  "\007\007You page %s.\r\n", see_char_as(ch, tgt));
+     send_to_char(tgt, "\007\007*%s* %s\r\n", see_char_as(tgt, ch), arg);
+   }
+ }
diff -crN nakedmudv1.5/src/cmd_comm.d nakedmudv2.0/src/cmd_comm.d
*** nakedmudv1.5/src/cmd_comm.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/cmd_comm.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ cmd_comm.d cmd_comm.o: cmd_comm.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h handler.h inform.h \
+   character.h world.h dialog.h scripts/script.h
diff -crN nakedmudv1.5/src/cmd_manip.c nakedmudv2.0/src/cmd_manip.c
*** nakedmudv1.5/src/cmd_manip.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/cmd_manip.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 13,19 ****
  #include "handler.h"
  #include "inform.h"
  #include "character.h"
- #include "items.h"
  #include "exit.h"
  #include "world.h"
  #include "room.h"
--- 13,18 ----
***************
*** 22,27 ****
--- 21,34 ----
  
  
  
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "items/items.h"
+ #include "items/container.h"
+ 
+ 
+ 
  //
  // try to lock an exit or container. The container can be anything in our
  // immediate visible range (room, inventory, body). do_lock automatically
***************
*** 67,73 ****
    }
  
    else if(found && found_type == FOUND_OBJ) {
!     if(objGetType(found) != ITEM_CONTAINER)
        send_to_char(ch, "%s is not a container.\r\n", objGetName(found));
      else if(!containerIsClosed(found))
        send_to_char(ch, "%s must be closed first.\r\n", objGetName(found));
--- 74,80 ----
    }
  
    else if(found && found_type == FOUND_OBJ) {
!     if(!objIsType(found, "container"))
        send_to_char(ch, "%s is not a container.\r\n", objGetName(found));
      else if(!containerIsClosed(found))
        send_to_char(ch, "%s must be closed first.\r\n", objGetName(found));
***************
*** 125,131 ****
    }
  
    else if(found && found_type == FOUND_OBJ) {
!     if(objGetType(found) != ITEM_CONTAINER)
        send_to_char(ch, "%s is not a container.\r\n", objGetName(found));
      else if(!containerIsLocked(found))
        send_to_char(ch, "%s is not locked.\r\n", objGetName(found));
--- 132,138 ----
    }
  
    else if(found && found_type == FOUND_OBJ) {
!     if(!objIsType(found, "container"))
        send_to_char(ch, "%s is not a container.\r\n", objGetName(found));
      else if(!containerIsLocked(found))
        send_to_char(ch, "%s is not locked.\r\n", objGetName(found));
***************
*** 186,192 ****
    }
  
    // make sure we have a container
!   if(objGetType(cont) != ITEM_CONTAINER) {
      send_to_char(ch, "%s is not a container.\r\n", objGetName(cont));
      return;
    }
--- 193,199 ----
    }
  
    // make sure we have a container
!   if(!objIsType(cont, "container")) {
      send_to_char(ch, "%s is not a container.\r\n", objGetName(cont));
      return;
    }
***************
*** 253,259 ****
    // open a container
    else if(found && found_type == FOUND_OBJ) {
      // make sure it's a container and it can be opened
!     if(objGetType(found) != ITEM_CONTAINER || !containerIsClosable(found))
        send_to_char(ch, "But it cannot be opened!\r\n");
      else if(!containerIsClosed(found))
        send_to_char(ch, "It is already opened.\r\n");
--- 260,266 ----
    // open a container
    else if(found && found_type == FOUND_OBJ) {
      // make sure it's a container and it can be opened
!     if(!objIsType(found, "container") || !containerIsClosable(found))
        send_to_char(ch, "But it cannot be opened!\r\n");
      else if(!containerIsClosed(found))
        send_to_char(ch, "It is already opened.\r\n");
***************
*** 315,321 ****
    // close a container
    else if(found && found_type == FOUND_OBJ) {
      // make sure it's a container and it can be closed
!     if(objGetType(found) != ITEM_CONTAINER || !containerIsClosable(found))
        send_to_char(ch, "But it cannot even be closed!\r\n");
      else if(containerIsClosed(found))
        send_to_char(ch, "It is already closed.\r\n");
--- 322,328 ----
    // close a container
    else if(found && found_type == FOUND_OBJ) {
      // make sure it's a container and it can be closed
!     if(!objIsType(found, "container") || !containerIsClosable(found))
        send_to_char(ch, "But it cannot even be closed!\r\n");
      else if(containerIsClosed(found))
        send_to_char(ch, "It is already closed.\r\n");
***************
*** 361,367 ****
        send_to_char(ch, "Get what from what?\r\n");
        return;
      }
!     else if(objGetType(cont) != ITEM_CONTAINER) {
        send_to_char(ch, "%s is not a container.\r\n", objGetName(cont));
        return;
      }
--- 368,374 ----
        send_to_char(ch, "Get what from what?\r\n");
        return;
      }
!     else if(!objIsType(cont, "container")) {
        send_to_char(ch, "%s is not a container.\r\n", objGetName(cont));
        return;
      }
diff -crN nakedmudv1.5/src/cmd_manip.d nakedmudv2.0/src/cmd_manip.d
*** nakedmudv1.5/src/cmd_manip.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/cmd_manip.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ cmd_manip.d cmd_manip.o: cmd_manip.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h handler.h inform.h \
+   character.h exit.h world.h room.h extra_descs.h object.h items/items.h \
+   items/container.h
diff -crN nakedmudv1.5/src/cmd_misc.c nakedmudv2.0/src/cmd_misc.c
*** nakedmudv1.5/src/cmd_misc.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/cmd_misc.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 34,62 ****
  
  
  //
- // Various preference bits that can be turned on and off
- //
- COMMAND(cmd_tog_prf) {
-   switch(subcmd) {
-   case PRF_MAPWALK:
-     charToggleBit(ch, BITFIELD_PRFS, PRF_MAPWALK);
-     send_to_char(ch, "Mapwalk %s.\r\n",
- 		 (charIsBitSet(ch, BITFIELD_PRFS, PRF_MAPWALK) ? "on":"off"));
-     break;
-   case PRF_BUILDWALK:
-     charToggleBit(ch, BITFIELD_PRFS, PRF_BUILDWALK);
-     send_to_char(ch, "Buildwalk %s.\r\n", 
- 		 (charIsBitSet(ch, BITFIELD_PRFS, PRF_BUILDWALK) ? "on":"off"));
-     break;
- 
-   default:
-     log_string("ERROR: attempted to toggle prf with subcmd %d on %s, but "
- 	       "subcmd does not exit!", subcmd, charGetName(ch));
-   }
- }
- 
- 
- //
  // clear the screen
  //
  COMMAND(cmd_clear) {
--- 34,39 ----
***************
*** 83,90 ****
    //
    if(charGetSocket(ch)) {
      SOCKET_DATA *sock = charGetSocket(ch);
-     sock->player = NULL;
      charSetSocket(ch, NULL);
      close_socket(sock, FALSE);
    }
  
--- 60,67 ----
    //
    if(charGetSocket(ch)) {
      SOCKET_DATA *sock = charGetSocket(ch);
      charSetSocket(ch, NULL);
+     socketSetChar(sock, NULL);
      close_socket(sock, FALSE);
    }
  
***************
*** 103,136 ****
  
  
  //
- // compress output
- //
- COMMAND(cmd_compress)
- {
-   /* no socket, no compression */
-   if (!charGetSocket(ch))
-     return;
- 
-   /* enable compression */
-   if (!charGetSocket(ch)->out_compress)
-   {
-     text_to_char(ch, "Trying compression.\n\r");
-     text_to_buffer(charGetSocket(ch), (char *) compress_will2);
-     text_to_buffer(charGetSocket(ch), (char *) compress_will);
-   }
-   else /* disable compression */
-   {
-     if (!compressEnd(charGetSocket(ch), charGetSocket(ch)->compressing, FALSE))
-     {
-       text_to_char(ch, "Failed.\n\r");
-       return;
-     }
-     text_to_char(ch, "Compression disabled.\n\r");
-   }
- }
- 
- 
- //
  // the function for executing a delayed command
  //
  void event_delayed_cmd(CHAR_DATA *ch, void *data, char *cmd) {
--- 80,85 ----
***************
*** 169,177 ****
  //
  // An entrypoint into the character's notepad
  //
  COMMAND(cmd_write) {
    if(!charGetSocket(ch))
      send_to_char(ch, "You cannot use notepad if you have no socket.\r\n");
!   else
!     start_notepad(charGetSocket(ch), "", MAX_BUFFER, EDITOR_MODE_NORMAL);
  }
--- 118,131 ----
  //
  // An entrypoint into the character's notepad
  //
+ /*
  COMMAND(cmd_write) {
    if(!charGetSocket(ch))
      send_to_char(ch, "You cannot use notepad if you have no socket.\r\n");
!   else {
!     send_around_char(ch, TRUE, "%s pulls out a notepad and begins writing.", 
! 		     charGetName(ch));
!     start_notepad(charGetSocket(ch), "");
!   }
  }
+ */
diff -crN nakedmudv1.5/src/cmd_misc.d nakedmudv2.0/src/cmd_misc.d
*** nakedmudv1.5/src/cmd_misc.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/cmd_misc.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ cmd_misc.d cmd_misc.o: cmd_misc.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h character.h socket.h utils.h \
+   save.h event.h action.h handler.h
diff -crN nakedmudv1.5/src/commands.h nakedmudv2.0/src/commands.h
*** nakedmudv1.5/src/commands.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/commands.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 17,22 ****
--- 17,24 ----
  COMMAND(cmd_wizhelp);
  COMMAND(cmd_invis);
  COMMAND(cmd_visible);
+ COMMAND(cmd_repeat);
+ COMMAND(cmd_at);
  
  
  /* builder.c */
***************
*** 31,36 ****
--- 33,39 ----
  COMMAND(cmd_olist);
  COMMAND(cmd_dlist);
  COMMAND(cmd_zlist);
+ COMMAND(cmd_buildwalk);
  
  
  /* cmd_manip.c */
***************
*** 54,59 ****
--- 57,63 ----
  COMMAND(cmd_chat);
  COMMAND(cmd_emote);
  COMMAND(cmd_gemote);
+ COMMAND(cmd_page);
  
  
  /* cmd_misc.c */
***************
*** 63,73 ****
  COMMAND(cmd_save);
  COMMAND(cmd_commands);
  COMMAND(cmd_compress);
- COMMAND(cmd_tog_prf);
  COMMAND(cmd_more);
  COMMAND(cmd_back);
  COMMAND(cmd_stop);
- COMMAND(cmd_write);
  
  
  /* inform.c */
--- 67,75 ----
diff -crN nakedmudv1.5/src/.depend nakedmudv2.0/src/.depend
*** nakedmudv1.5/src/.depend	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/.depend	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,179 ****
- gameloop.o: gameloop.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h socket.h world.h character.h object.h utils.h \
-   text_editor.h save.h handler.h inform.h log.h action.h event.h \
-   auxiliary.h storage.h races.h body.h time/mudtime.h scripts/script.h \
-   olc/olc.h alias/alias.h char_vars/char_vars.h socials/socials.h \
-   help/help.h
- mud.o: mud.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h storage.h
- utils.o: utils.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h character.h object.h world.h zone.h room.h exit.h \
-   socket.h utils.h text_editor.h save.h handler.h inform.h dialog.h \
-   event.h action.h scripts/script.h
- interpret.o: interpret.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h character.h socket.h \
-   room.h movement.h commands.h action.h scripts/script.h alias/alias.h
- handler.o: handler.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h handler.h room.h exit.h extra_descs.h character.h \
-   object.h utils.h text_editor.h body.h items.h inform.h scripts/script.h
- inform.o: inform.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h character.h object.h world.h room.h exit.h \
-   extra_descs.h utils.h text_editor.h body.h races.h items.h handler.h \
-   socket.h inform.h log.h time/mudtime.h
- movement.o: movement.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h character.h world.h zone.h room.h exit.h movement.h \
-   handler.h inform.h utils.h text_editor.h items.h object.h \
-   scripts/script.h
- action.o: action.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h character.h action.h
- mccp.o: mccp.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h socket.h utils.h text_editor.h
- save.o: save.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h character.h world.h utils.h text_editor.h handler.h \
-   body.h object.h room.h storage.h
- socket.o: socket.c wrapsock.h mud.h property_table.h list.h hashmap.h \
-   hashtable.h set.h character.h utils.h text_editor.h socket.h olc/olc.h
- io.o: io.c mud.h wrapsock.h property_table.h list.h hashmap.h hashtable.h \
-   set.h utils.h text_editor.h
- strings.o: strings.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h
- event.o: event.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h character.h event.h
- cmd_comm.o: cmd_comm.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h handler.h inform.h character.h \
-   world.h dialog.h scripts/script.h
- cmd_manip.o: cmd_manip.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h handler.h inform.h \
-   character.h items.h exit.h world.h room.h extra_descs.h object.h
- cmd_misc.o: cmd_misc.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h character.h socket.h utils.h text_editor.h save.h \
-   event.h action.h handler.h
- cmd_admin.o: cmd_admin.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h world.h inform.h character.h handler.h \
-   utils.h text_editor.h log.h socket.h save.h event.h action.h storage.h
- cmd_builder.o: cmd_builder.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h world.h zone.h room.h exit.h movement.h \
-   character.h object.h handler.h inform.h utils.h text_editor.h races.h \
-   items.h dialog.h scripts/script.h scripts/script_set.h
- text_editor.o: text_editor.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h socket.h text_editor.h utils.h \
-   scripts/script.h olc/olc.h
- races.o: races.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h body.h utils.h text_editor.h races.h
- items.o: items.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h object.h items.h
- log.o: log.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h character.h storage.h log.h
- auxiliary.o: auxiliary.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h storage.h auxiliary.h
- world.o: world.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h zone.h room.h character.h object.h dialog.h utils.h \
-   text_editor.h storage.h world.h scripts/script.h
- character.o: character.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h body.h races.h \
-   handler.h auxiliary.h storage.h room.h character.h
- room.o: room.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h exit.h extra_descs.h utils.h text_editor.h handler.h \
-   character.h auxiliary.h storage.h room_reset.h room.h scripts/script.h
- exit.o: exit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h storage.h exit.h
- extra_descs.o: extra_descs.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h storage.h \
-   extra_descs.h
- object.o: object.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h extra_descs.h utils.h text_editor.h items.h body.h \
-   handler.h storage.h auxiliary.h object.h
- body.o: body.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h body.h utils.h text_editor.h
- zone.o: zone.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h storage.h object.h character.h room.h utils.h \
-   text_editor.h auxiliary.h dialog.h zone.h scripts/script.h
- dialog.o: dialog.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h dialog.h storage.h
- room_reset.o: room_reset.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h storage.h room.h \
-   world.h character.h body.h object.h exit.h handler.h items.h \
-   room_reset.h
- list.o: list.c list.h
- property_table.o: property_table.c mud.h wrapsock.h property_table.h \
-   list.h hashmap.h hashtable.h set.h utils.h text_editor.h
- hashtable.o: hashtable.c list.h hashtable.h
- hashmap.o: hashmap.c list.h hashmap.h
- storage.o: storage.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h storage.h
- set.o: set.c list.h set.h
- time.o: time/time.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h inform.h character.h room.h \
-   event.h storage.h auxiliary.h time/mudtime.h
- alias.o: alias/alias.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h auxiliary.h storage.h \
-   character.h alias/alias.h
- char_vars.o: char_vars/char_vars.c mud.h wrapsock.h property_table.h \
-   list.h hashmap.h hashtable.h set.h utils.h text_editor.h character.h \
-   storage.h auxiliary.h char_vars/char_vars.h
- socials.o: socials/socials.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h storage.h handler.h \
-   inform.h character.h socials/socials.h
- dedit.o: olc/dedit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h socket.h utils.h text_editor.h dialog.h olc/olc.h
- edesc_edit.o: olc/edesc_edit.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h socket.h utils.h text_editor.h \
-   extra_descs.h olc/olc.h
- exedit.o: olc/exedit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h exit.h socket.h utils.h text_editor.h olc/olc.h
- medit.o: olc/medit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h world.h character.h socket.h utils.h text_editor.h \
-   races.h dialog.h olc/olc.h scripts/script_set.h scripts/script.h
- oedit.o: olc/oedit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h world.h object.h extra_descs.h socket.h utils.h \
-   text_editor.h body.h items.h olc/olc.h scripts/script_set.h \
-   scripts/script.h
- redit.o: olc/redit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h world.h room.h exit.h room_reset.h extra_descs.h \
-   socket.h utils.h text_editor.h olc/olc.h scripts/script_set.h \
-   scripts/script.h time/mudtime.h
- zedit.o: olc/zedit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h world.h zone.h socket.h utils.h text_editor.h \
-   olc/olc.h
- ssedit.o: olc/ssedit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h socket.h world.h utils.h text_editor.h olc/olc.h \
-   scripts/script.h scripts/script_set.h
- scedit.o: olc/scedit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h socket.h utils.h text_editor.h olc/olc.h \
-   scripts/script.h
- resedit.o: olc/resedit.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h socket.h utils.h text_editor.h world.h \
-   object.h character.h room_reset.h olc/olc.h
- socedit.o: olc/socedit.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h socket.h utils.h text_editor.h character.h \
-   socials/socials.h olc/olc.h
- olc.o: olc/olc.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h socket.h object.h character.h world.h zone.h room.h \
-   room_reset.h exit.h extra_descs.h dialog.h olc/olc.h scripts/script.h \
-   scripts/script_set.h socials/socials.h
- script_set.o: scripts/script_set.c mud.h wrapsock.h property_table.h \
-   list.h hashmap.h hashtable.h set.h utils.h text_editor.h world.h \
-   scripts/script_set.h scripts/script.h
- script.o: scripts/script.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h utils.h text_editor.h socket.h character.h \
-   room.h object.h storage.h auxiliary.h scripts/script.h \
-   scripts/script_set.h scripts/pychar.h scripts/pyroom.h scripts/pyobj.h \
-   scripts/pymud.h
- pychar.o: scripts/pychar.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h world.h room.h character.h object.h items.h \
-   races.h handler.h utils.h text_editor.h scripts/script.h \
-   scripts/pychar.h scripts/pyroom.h scripts/pyobj.h char_vars/char_vars.h
- pyobj.o: scripts/pyobj.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h world.h room.h character.h object.h races.h \
-   handler.h utils.h text_editor.h scripts/script.h scripts/pychar.h \
-   scripts/pyroom.h scripts/pyobj.h
- pymud.o: scripts/pymud.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h scripts/script.h scripts/pyroom.h \
-   scripts/pychar.h scripts/pyobj.h
- pyroom.o: scripts/pyroom.c mud.h wrapsock.h property_table.h list.h \
-   hashmap.h hashtable.h set.h world.h room.h exit.h character.h races.h \
-   handler.h utils.h text_editor.h scripts/script.h scripts/pyroom.h \
-   scripts/pychar.h scripts/pyobj.h
- help.o: help/help.c mud.h wrapsock.h property_table.h list.h hashmap.h \
-   hashtable.h set.h utils.h text_editor.h storage.h character.h socket.h \
-   help/help.h
--- 0 ----
diff -crN nakedmudv1.5/src/depend.sh nakedmudv2.0/src/depend.sh
*** nakedmudv1.5/src/depend.sh	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/depend.sh	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,11 ----
+ #!/bin/sh
+ 
+ DIR=$(dirname $1)
+ case "$DIR" in
+ "" | ".")
+ gcc -MM -MG "$@" | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@'
+ ;;
+ *)
+ gcc -MM -MG "$@" | sed -e "s@^\(.*\)\.o:@$DIR/\1.d $DIR/\1.o:@" 
+ ;;
+ esac
diff -crN nakedmudv1.5/src/dialog.c nakedmudv2.0/src/dialog.c
*** nakedmudv1.5/src/dialog.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/dialog.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 17,30 ****
  struct dialog_data {
    int   vnum;      // what vnum are we in the world?
    char *name;      // the name of this dialog (e.g. generic citizen dialog)
!   char *greet;     // what do we say when someone approaches/greets us?
    LIST *responses; // what kind of topics do we talk about?
  };
  
  
  struct response_data {
    char *keywords;      // what triggers the talking?
!   char *message;       // what is the response?
    DIALOG_DATA *dialog; // which dialog do we belong to?
  };
  
--- 17,30 ----
  struct dialog_data {
    int   vnum;      // what vnum are we in the world?
    char *name;      // the name of this dialog (e.g. generic citizen dialog)
!   BUFFER *greet;   // what do we say when someone approaches/greets us?
    LIST *responses; // what kind of topics do we talk about?
  };
  
  
  struct response_data {
    char *keywords;      // what triggers the talking?
!   BUFFER *message;     // what is the response?
    DIALOG_DATA *dialog; // which dialog do we belong to?
  };
  
***************
*** 33,62 ****
  //*****************************************************************************
  //
  // response stuff
! //
  //*****************************************************************************
! RESPONSE_DATA *newResponse(const char *keywords, const char *message) {
    RESPONSE_DATA *response = malloc(sizeof(RESPONSE_DATA));
!   response->keywords = strdup(keywords ? keywords : "");
!   response->message  = strdup(message  ? message  : "");
    response->dialog = NULL;
    return response;
  }
  
  void deleteResponse(RESPONSE_DATA *response) {
    if(response->keywords) free(response->keywords);
!   if(response->message)  free(response->message);
    free(response);
  }
  
  RESPONSE_DATA *responseRead(STORAGE_SET *set) {
!   return newResponse(read_string(set, "keywords"), read_string(set, "message"));
  }
  
  STORAGE_SET *responseStore(RESPONSE_DATA *data) {
    STORAGE_SET *set = new_storage_set();
    store_string(set, "keywords", data->keywords);
!   store_string(set, "message",  data->message);
    return set;
  }
  
--- 33,65 ----
  //*****************************************************************************
  //
  // response stuff
! 
  //*****************************************************************************
! RESPONSE_DATA *newResponse(void) {
    RESPONSE_DATA *response = malloc(sizeof(RESPONSE_DATA));
!   response->keywords = strdup("");
!   response->message  = newBuffer(1);
    response->dialog = NULL;
    return response;
  }
  
  void deleteResponse(RESPONSE_DATA *response) {
    if(response->keywords) free(response->keywords);
!   if(response->message)  deleteBuffer(response->message);
    free(response);
  }
  
  RESPONSE_DATA *responseRead(STORAGE_SET *set) {
!   RESPONSE_DATA *response = newResponse();
!   responseSetKeywords(response, read_string(set, "keywords"));
!   responseSetMessage (response, read_string(set, "message"));
!   return response;
  }
  
  STORAGE_SET *responseStore(RESPONSE_DATA *data) {
    STORAGE_SET *set = new_storage_set();
    store_string(set, "keywords", data->keywords);
!   store_string(set, "message",  bufferString(data->message));
    return set;
  }
  
***************
*** 66,72 ****
  }
  
  RESPONSE_DATA *responseCopy(RESPONSE_DATA *response) {
!   RESPONSE_DATA *newresp = newResponse(response->keywords, response->message);
    return newresp;
  }
  
--- 69,76 ----
  }
  
  RESPONSE_DATA *responseCopy(RESPONSE_DATA *response) {
!   RESPONSE_DATA *newresp = newResponse();
!   responseCopyTo(response, newresp);
    return newresp;
  }
  
***************
*** 88,95 ****
  }
  
  void responseSetMessage(RESPONSE_DATA *response, const char *message) {
!   if(response->message) free(response->message);
!   response->message = strdup(message ? message : "");
  }
  
  const char *responseGetKeywords(RESPONSE_DATA *response) {
--- 92,99 ----
  }
  
  void responseSetMessage(RESPONSE_DATA *response, const char *message) {
!   bufferClear(response->message);
!   bufferCat(response->message, message);
  }
  
  const char *responseGetKeywords(RESPONSE_DATA *response) {
***************
*** 97,105 ****
  }
  
  const char *responseGetMessage(RESPONSE_DATA *response) {
!   return response->message;
  }
  
  
  
  
--- 101,112 ----
  }
  
  const char *responseGetMessage(RESPONSE_DATA *response) {
!   return bufferString(response->message);
  }
  
+ BUFFER *responseGetMessageBuffer(RESPONSE_DATA *response) {
+   return response->message;
+ }
  
  
  
***************
*** 111,118 ****
  DIALOG_DATA *newDialog() {
    DIALOG_DATA *dialog = malloc(sizeof(DIALOG_DATA));
    dialog->responses = newList();
    dialog->name  = strdup("");
-   dialog->greet = strdup("");
    dialog->vnum  = NOTHING;
    return dialog;
  }
--- 118,125 ----
  DIALOG_DATA *newDialog() {
    DIALOG_DATA *dialog = malloc(sizeof(DIALOG_DATA));
    dialog->responses = newList();
+   dialog->greet = newBuffer(1);
    dialog->name  = strdup("");
    dialog->vnum  = NOTHING;
    return dialog;
  }
***************
*** 121,128 ****
    RESPONSE_DATA *response = NULL;
    while( (response = listPop(dialog->responses)) != NULL)
      deleteResponse(response);
    if(dialog->name)  free(dialog->name);
-   if(dialog->greet) free(dialog->greet);
    free(dialog);
  }
  
--- 128,135 ----
    RESPONSE_DATA *response = NULL;
    while( (response = listPop(dialog->responses)) != NULL)
      deleteResponse(response);
+   if(dialog->greet) deleteBuffer(dialog->greet);
    if(dialog->name)  free(dialog->name);
    free(dialog);
  }
  
***************
*** 130,136 ****
    STORAGE_SET *set = new_storage_set();
    store_int   (set, "vnum",     dialog->vnum);
    store_string(set, "name",     dialog->name);
!   store_string(set, "greet",    dialog->greet);
    store_list(set, "responses", gen_store_list(dialog->responses,responseStore));
    return set;
  }
--- 137,143 ----
    STORAGE_SET *set = new_storage_set();
    store_int   (set, "vnum",     dialog->vnum);
    store_string(set, "name",     dialog->name);
!   store_string(set, "greet",    bufferString(dialog->greet));
    store_list(set, "responses", gen_store_list(dialog->responses,responseStore));
    return set;
  }
***************
*** 167,177 ****
    deleteListIterator(resp_i);
  
    // now the name and greet
    if(to->name) free(to->name);
-   if(to->greet) free(to->greet);
- 
    to->name  = strdup(from->name ? from->name : "");
-   to->greet = strdup(from->greet ? from->greet : "");
    to->vnum  = from->vnum;
  }
  
--- 174,183 ----
    deleteListIterator(resp_i);
  
    // now the name and greet
+   bufferClear(to->greet);
+   bufferCat(to->greet, bufferString(from->greet));
    if(to->name) free(to->name);
    to->name  = strdup(from->name ? from->name : "");
    to->vnum  = from->vnum;
  }
  
***************
*** 217,223 ****
    ITERATE_LIST(response, resp_i)
      if(responseIsKeyword(response, keyword))
        break;
-   
    deleteListIterator(resp_i);
    return response;
  }
--- 223,228 ----
***************
*** 238,250 ****
    return listSize(dialog->responses);
  }
  
! const char *dialogGetGreet(DIALOG_DATA *dialog) {
    return dialog->greet;
  }
  
  void dialogSetGreet(DIALOG_DATA *dialog, const char *greet) {
!   if(dialog->greet) free(dialog->greet);
!   dialog->greet = strdup(greet ? greet : "");
  }
  
  void dialogSetVnum(DIALOG_DATA *dialog, dialog_vnum vnum) {
--- 243,259 ----
    return listSize(dialog->responses);
  }
  
! BUFFER *dialogGetGreetBuffer(DIALOG_DATA *dialog) {
    return dialog->greet;
  }
  
+ const char *dialogGetGreet(DIALOG_DATA *dialog) {
+   return bufferString(dialog->greet);
+ }
+ 
  void dialogSetGreet(DIALOG_DATA *dialog, const char *greet) {
!   bufferClear(dialog->greet);
!   bufferCat(dialog->greet, (greet ? greet : ""));
  }
  
  void dialogSetVnum(DIALOG_DATA *dialog, dialog_vnum vnum) {
diff -crN nakedmudv1.5/src/dialog.d nakedmudv2.0/src/dialog.d
*** nakedmudv1.5/src/dialog.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/dialog.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ dialog.d dialog.o: dialog.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h dialog.h storage.h
diff -crN nakedmudv1.5/src/dialog.h nakedmudv2.0/src/dialog.h
*** nakedmudv1.5/src/dialog.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/dialog.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 11,19 ****
  //*****************************************************************************
  
  
! 
! 
! RESPONSE_DATA *newResponse       (const char *keywords, const char *message);
  void           deleteResponse    (RESPONSE_DATA *response);
  
  void           responseCopyTo    (RESPONSE_DATA *from, RESPONSE_DATA *to);
--- 11,17 ----
  //*****************************************************************************
  
  
! RESPONSE_DATA *newResponse       (void);
  void           deleteResponse    (RESPONSE_DATA *response);
  
  void           responseCopyTo    (RESPONSE_DATA *from, RESPONSE_DATA *to);
***************
*** 28,33 ****
--- 26,32 ----
  
  const char   *responseGetKeywords(RESPONSE_DATA *response);
  const char   *responseGetMessage (RESPONSE_DATA *response);
+ BUFFER       *responseGetMessageBuffer(RESPONSE_DATA *response);
  
  DIALOG_DATA   *newDialog         ();
  void           deleteDialog      (DIALOG_DATA *dialog);
***************
*** 48,53 ****
--- 47,53 ----
  RESPONSE_DATA *dialogGetNum      (DIALOG_DATA *dialog, int entry_num);
  int            dialogGetSize     (DIALOG_DATA *dialog);
  
+ BUFFER        *dialogGetGreetBuffer(DIALOG_DATA *dialog);
  const char    *dialogGetGreet    (DIALOG_DATA *dialog);
  void           dialogSetGreet    (DIALOG_DATA *dialog, const char *greet);
  
Binary files nakedmudv1.5/src/.DS_Store and nakedmudv2.0/src/.DS_Store differ
diff -crN nakedmudv1.5/src/editor/editor.c nakedmudv2.0/src/editor/editor.c
*** nakedmudv1.5/src/editor/editor.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/editor/editor.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,392 ----
+ //*****************************************************************************
+ //
+ // editor.c
+ //
+ // one of the problems that came up with the origional text editor what that
+ // it started becoming rather kludgy and hackish as we started adding more
+ // features to it, like script editing capabilities. It was difficult to
+ // coordinate when we wanted certain options and when we didn't. This is an
+ // attempt to make things a bit easier to scale up with.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../auxiliary.h"
+ #include "../socket.h"
+ #include "editor.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // auxiliary data for sockets
+ //*****************************************************************************
+ typedef struct editor_aux_data {
+   EDITOR *editor;      // the editor we're using
+   BUFFER *buf;         // the buffer we're editing
+   BUFFER *working_buf; // the buffer where we do our work
+ } EDITOR_AUX_DATA;
+ 
+ EDITOR_AUX_DATA *newEditorAuxData() {
+   EDITOR_AUX_DATA *data = malloc(sizeof(EDITOR_AUX_DATA));
+   bzero(data, sizeof(EDITOR_AUX_DATA));
+   return data; // the buffer, working buffer, and editor are null 'til needed
+ }
+ 
+ void deleteEditorAuxData(EDITOR_AUX_DATA *data) {
+   // if we have a working buf, free it. Don't touch anything else. that
+   // stuff will be needed by the rest of the program
+   if(data->working_buf) deleteBuffer(data->working_buf);
+   free(data);
+ }
+ 
+ void clearEditorAuxData(EDITOR_AUX_DATA *data) {
+   if(data->working_buf) deleteBuffer(data->working_buf);
+   data->working_buf = NULL;
+   data->editor      = NULL;
+   data->buf         = NULL;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // local structures, functions, and defines
+ //*****************************************************************************
+ // a basic text editor for use by other modules
+ EDITOR *text_editor = NULL;
+ // an editor for dialog. Essentially, text without newlines
+ EDITOR *dialog_editor = NULL;
+ 
+ // how many buckets are in our command table?
+ #define EDITOR_CMD_TABLE_SIZE       20
+ 
+ struct editor_data {
+   HASHTABLE *cmds;  // mappings from commands to their functions and descs
+   void (* prompt)(SOCKET_DATA *sock); // the prompt display
+   void (*   init)(SOCKET_DATA *sock); // reset variables for using the editor
+   void (* append)(SOCKET_DATA *sock, char *arg, BUFFER *buf); // append text to the buffer
+ };
+ 
+ // data for a command in the editor
+ typedef struct command_data {
+   // the function this command calls
+   void (* func)(SOCKET_DATA *sock, char *arg, BUFFER *buf);
+   char *desc;    // the one-line helpfile description
+   bool reserved; // is this command protected from being written over?
+ } CMD_DATA;
+ 
+ CMD_DATA *
+ newEditorCommand(const char *desc, 
+ 		 void func(SOCKET_DATA *sock, char *arg, BUFFER *buf),
+ 		 bool reserved) {
+   CMD_DATA *cmd = malloc(sizeof(CMD_DATA));
+   cmd->desc     = strdup(desc ? desc : "");
+   cmd->func     = func;
+   cmd->reserved = reserved;
+   return cmd;
+ }
+ 
+ void deleteEditorCommand(CMD_DATA *cmd) {
+   if(cmd->desc) free(cmd->desc);
+   free(cmd);
+ }
+ 
+ 
+ //
+ // the default prompt display for editors
+ //
+ void editorDefaultPrompt(SOCKET_DATA *sock) {
+   text_to_buffer(sock, "] ");
+ }
+ 
+ 
+ //
+ // the default header display for editors
+ //
+ void editorDefaultHeader(SOCKET_DATA *sock) {
+   text_to_buffer(sock, 
+ "==========================================================================\r\n"
+ "Begin editing. /q on a new line to quit, /a to abort. /h for help         \r\n"
+ "==========================================================================\r\n"
+ 		 );
+ }
+ 
+ 
+ //
+ // the default function for appending text to the working buffer
+ //
+ void editorDefaultAppend(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   bufferCat(buf, arg);
+   bufferCat(buf, "\r\n");
+ }
+ 
+ 
+ //
+ // the function for appending text to a dialog buffer. 
+ //
+ void editorDialogAppend(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   // if the buffer isn't empty, cat a space
+   if(bufferLength(buf) > 0)
+     bufferCat(buf, " ");
+   bufferCat(buf, arg);
+ }
+ 
+ 
+ //
+ // The function that takes in a new command and figures out what to
+ // do with it
+ //
+ void editorInputHandler(SOCKET_DATA *sock, char *arg) {
+   EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "editor_aux_data");
+ 
+   // is it a command?
+   if(*arg == '/') {
+     // separate the command and the argument
+     char buf[SMALL_BUFFER];
+     arg = one_arg(arg, buf);
+ 
+     // pull up the command
+     CMD_DATA *cmd = hashGet(data->editor->cmds, buf+1);
+     if(cmd == NULL)
+       text_to_buffer(sock, "Invalid command.\r\n");
+     else
+       cmd->func(sock, arg, data->working_buf);
+   }
+   else
+     data->editor->append(sock, arg, data->working_buf);
+ }
+ 
+ 
+ //*****************************************************************************
+ // implementation of basic editor commands
+ //*****************************************************************************
+ void editorQuit(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   // save the current changes
+   EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "editor_aux_data");
+   bufferCopyTo(buf, data->buf);
+   clearEditorAuxData(data);
+   text_to_buffer(sock, "Saved and quit.\r\n");
+   // and then pop the input handler
+   socketPopInputHandler(sock);
+ }
+ 
+ void editorAbort(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "editor_aux_data");
+   clearEditorAuxData(data);
+   text_to_buffer(sock, "Editor aborted.\r\n");
+   socketPopInputHandler(sock);
+ }
+ 
+ void editorDisplayHelp(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   const char *key = NULL;
+   CMD_DATA   *val = NULL;
+   HASH_ITERATOR *hash_i = newHashIterator(socketGetEditor(sock)->cmds);
+ 
+   // print out all of the commands and their descriptions
+   ITERATE_HASH(key, val, hash_i)
+     send_to_socket(sock, "/%-3s %s\r\n", key, val->desc);
+   deleteHashIterator(hash_i);
+ }
+ 
+ void editorDeleteLine(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   char tmp[SMALL_BUFFER];
+   arg = one_arg(arg, tmp);
+   int line = atoi(tmp);
+   if(!isdigit(*tmp) || !bufferRemove(buf, line))
+     text_to_buffer(sock, "Line does not exist.\r\n");
+ }
+ 
+ void editorEditLine(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   char tmp[SMALL_BUFFER];
+   arg = one_arg(arg, tmp);
+   int line = atoi(tmp);
+   if(!isdigit(*tmp) || !bufferReplaceLine(buf, arg, line))
+     text_to_buffer(sock, "Line does not exist.\r\n");
+ }
+ 
+ void editorInsertLine(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   char tmp[SMALL_BUFFER];
+   arg = one_arg(arg, tmp);
+   int line = atoi(tmp);
+   if(!isdigit(*tmp) || !bufferInsert(buf, arg, line))
+     text_to_buffer(sock, "Insertion failed.\r\n");
+ }
+ 
+ void editorListDialogBuffer(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   if(!*bufferString(buf))
+     text_to_buffer(sock, "Buffer contains not contents.\r\n");
+   else
+     send_to_socket(sock, "%s\r\n", bufferString(buf));
+ }
+ 
+ void editorListBuffer(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   if(!*bufferString(buf))
+     text_to_buffer(sock, "Buffer contains not contents.\r\n");
+   else
+     text_to_buffer(sock, bufferString(buf));
+ }
+ 
+ void editorReplace(SOCKET_DATA *sock, char *arg, BUFFER *buf, bool all) {
+   char *a;
+   char *b;
+ 
+   if(count_letters(arg, '\'', strlen(arg)) != 4) {
+     text_to_buffer(sock, "arguments must take the form: 'to replace' 'replacement'\r\n");
+     return;
+   }
+ 
+   // pull the first argument
+   a = strtok(arg, "\'");
+   if(a == NULL) {
+     text_to_buffer(sock, "format is: /r[a] 'to replace' 'replacement'\r\n");
+     return;
+   }
+ 
+   // kill the leading the leading ' of b
+   strtok(NULL, "\'");
+ 
+   b = strtok(NULL, "\'");
+   if(b == NULL)
+     b = "\0"; // "\0" will get deleted at the end of this block
+ 
+   int replaced = bufferReplace(buf, a, b, all);
+   send_to_socket(sock, "%d occurence%s of '%s' replaced with '%s'.\r\n",
+ 		 replaced, (replaced == 1 ? "" : "s"), a, b);
+ }
+ 
+ void editorReplaceString(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   editorReplace(sock, arg, buf, FALSE);
+ }
+ 
+ void editorReplaceAllString(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
+   editorReplace(sock, arg, buf, TRUE);
+ }
+ 
+ void editorClear(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   bufferClear(buf);
+ }
+ 
+ void editorFormatBuffer(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   bufferFormat(buf, 80, 3);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // implementation of editor.h
+ //*****************************************************************************
+ void init_editor() {
+   // install the editor components
+   auxiliariesInstall("editor_aux_data", 
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_SOCKET,
+ 				       newEditorAuxData, deleteEditorAuxData,
+ 				       NULL, NULL, NULL, NULL));
+   text_editor   = newEditor();
+   dialog_editor = newEditor();
+   editorSetAppend(dialog_editor, editorDialogAppend);
+   editorRemoveCommand(dialog_editor, "f");
+   editorAddCommand(dialog_editor, "l", 
+ 		   "        List the current buffer contents",
+ 		   editorListDialogBuffer);
+ }
+ 
+ EDITOR *newEditor() {
+   EDITOR *editor = malloc(sizeof(EDITOR));
+   // set up the default commands
+   editor->cmds = newHashtable(EDITOR_CMD_TABLE_SIZE);
+   hashPut(editor->cmds, "q", 
+ 	  newEditorCommand("        Quit editor and save changes",
+ 			   editorQuit, TRUE));
+   hashPut(editor->cmds, "a", 
+ 	  newEditorCommand("        Quit editor and don't save",
+ 			   editorAbort, TRUE));
+   hashPut(editor->cmds, "h", 
+ 	  newEditorCommand("        Display editor commands",
+ 			   editorDisplayHelp, TRUE));
+   hashPut(editor->cmds, "c", 
+ 	  newEditorCommand("        Clear the contents of the buffer",
+ 			   editorClear, TRUE));
+   hashPut(editor->cmds, "l",
+ 	  newEditorCommand("        List the current buffer contents",
+ 			   editorListBuffer, FALSE));
+   hashPut(editor->cmds, "d", 
+ 	  newEditorCommand("#       Delete line with the specified number", 
+ 			   editorDeleteLine, FALSE));
+   hashPut(editor->cmds, "e", 
+ 	  newEditorCommand("# <txt> Sets the text at the specified line to the new text",
+ 			   editorEditLine, FALSE));
+   hashPut(editor->cmds, "i", 
+ 	  newEditorCommand("# <txt> Insert new text at the specified line number",
+ 			   editorInsertLine, FALSE));
+   hashPut(editor->cmds, "f",
+ 	  newEditorCommand("        Formats your text into a paragraph",
+ 			   editorFormatBuffer, FALSE));
+   hashPut(editor->cmds, "r",
+ 	  newEditorCommand("'a' 'b' replace first occurence of 'a' with 'b'",
+ 			   editorReplaceString, FALSE));
+   hashPut(editor->cmds, "ra",
+ 	  newEditorCommand("'a' 'b' repalce all occurences of 'a' with 'b'",
+ 			   editorReplaceAllString, FALSE));
+ 
+   // set up the default prompt, header, and appending function
+   editor->prompt = editorDefaultPrompt;
+   editor->append = editorDefaultAppend;
+   editor->init   = NULL;
+   return editor;
+ }
+ 
+ void editorSetPrompt(EDITOR *editor, void prompt(SOCKET_DATA *sock)) {
+   editor->prompt = prompt;
+ }
+ 
+ void editorSetInit(EDITOR *editor, void init(SOCKET_DATA *sock)) {
+   editor->init = init;
+ }
+ 
+ void editorSetAppend(EDITOR *editor,
+ 		     void append(SOCKET_DATA *sock, char *arg, BUFFER *buf)) {
+   editor->append = append;
+ }
+ 
+ void editorAddCommand(EDITOR *editor, const char *cmd, const char *desc, 
+ 		      void func(SOCKET_DATA *sock, char *arg, BUFFER *buf)) {
+   CMD_DATA *old_cmd = hashGet(editor->cmds, cmd);
+   // make sure we're not trying to replace a reserved command
+   if(!old_cmd || !old_cmd->reserved) {
+     hashPut(editor->cmds, cmd, newEditorCommand(desc, func, FALSE));
+     if(old_cmd) deleteEditorCommand(old_cmd);
+   }
+ }
+ 
+ void editorRemoveCommand(EDITOR *editor, const char *cmd) {
+   CMD_DATA *old_cmd = hashGet(editor->cmds, cmd);
+   // make sure the command isn't reserved
+   if(old_cmd && !old_cmd->reserved) {
+     hashRemove(editor->cmds, cmd);
+     deleteEditorCommand(old_cmd);
+   }
+ }
+ 
+ void socketStartEditor(SOCKET_DATA *sock, EDITOR *editor, BUFFER *buf) {
+   EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "editor_aux_data"); 
+   data->working_buf = bufferCopy(buf);
+   data->buf         = buf;
+   data->editor      = editor;
+   if(editor->init) editor->init(sock);
+ 
+   editorDefaultHeader(sock);
+   
+   // if we have a "list" command, execute it. Otherwise, cat the buf
+   CMD_DATA *list = NULL;
+   if((list = hashGet(editor->cmds, "l")) != NULL)
+     list->func(sock, "", buf);
+   else
+     text_to_buffer(sock, bufferString(buf));
+ 
+   socketPushInputHandler(sock, editorInputHandler, editor->prompt);
+ }
+ 
+ EDITOR *socketGetEditor(SOCKET_DATA *sock) {
+   EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "editor_aux_data");
+   return data->editor;
+ }
diff -crN nakedmudv1.5/src/editor/editor.d nakedmudv2.0/src/editor/editor.d
*** nakedmudv1.5/src/editor/editor.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/editor/editor.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ editor/editor.d editor/editor.o: editor/editor.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h auxiliary.h socket.h \
+   editor/editor.h
diff -crN nakedmudv1.5/src/editor/editor.h nakedmudv2.0/src/editor/editor.h
*** nakedmudv1.5/src/editor/editor.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/editor/editor.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,86 ----
+ #ifndef EDITOR_H
+ #define EDITOR_H
+ //*****************************************************************************
+ //
+ // editor.h
+ //
+ // one of the problems that came up with the origional text editor what that
+ // it started becoming rather kludgy and hackish as we started adding more
+ // features to it, like script editing capabilities. It was difficult to
+ // coordinate when we wanted certain options and when we didn't. This is an
+ // attempt to make things a bit easier to scale up with.
+ //
+ //*****************************************************************************
+ 
+ typedef struct editor_data EDITOR;
+ 
+ // a basic text editor that can be used by other modules
+ extern EDITOR *text_editor;
+ 
+ // an editor for dialog. Essentially, text without newlines
+ extern EDITOR *dialog_editor;
+ 
+ 
+ // prepare the editing system for use
+ void init_editor();
+ 
+ // sets up a little notepad that the character can write/post stuff from.
+ // Notepads are erased when the socket disconnects.
+ void init_notepad();
+ const char *socketGetNotepad(SOCKET_DATA *sock);
+ void socketSetNotepad(SOCKET_DATA *sock, const char *txt);
+ void socketStartNotepad(SOCKET_DATA *sock);
+ 
+ 
+ // editors are intended to be permenant and, thus, have no delete function.
+ // Modules that need an editing tool tailored to them (e.g. scripts) should make
+ // one copy of the editor when the module is initialized, and that should be the
+ // only copy ever used.
+ EDITOR *newEditor();
+ 
+ //
+ // Change the function that displays the editor prompt. By default, the editor
+ // prompt displays this:
+ // ] 
+ void editorSetPrompt(EDITOR *editor, void prompt(SOCKET_DATA *sock));
+ 
+ //
+ // When an editor is first entered, the socket may need some auxiliary data
+ // reset (e.g.: script editing will need indents set to zero). This is where
+ // all of that stuff is performed. The default editor does not have an init()
+ // and can be written over at will.
+ void editorSetInit(EDITOR *editor, void init(SOCKET_DATA *sock));
+ 
+ //
+ // change the function that appends data to the buffer. This may be useful in
+ // some cases where previous input determines how the next input is appended.
+ // So, for instance, if/else blocks for scripts.
+ void editorSetAppend(EDITOR *editor,
+ 		     void append(SOCKET_DATA *sock, char *arg, BUFFER *buf));
+ 
+ //
+ // add a new command to the text editor, and map it to an editor function. The
+ // desc is the line that will be displayed in the help menu. The following 
+ // commands are reserved, and cannot be added over or removed:
+ //   /s, /q      quit and save changes
+ //   /a          quit but do not save changes
+ //   /h, /?      display the help menu
+ void editorAddCommand(EDITOR *editor, const char *cmd, const char *desc, 
+ 		      void func(SOCKET_DATA *sock, char *arg, BUFFER *buf));
+ 
+ //
+ // Remove a command from the text editor. None of the reserved commands can be
+ // removed. This is basically intended to allow programmers to remove
+ // functionality from the default editor to customize it.
+ void editorRemoveCommand(EDITOR *editor, const char *cmd);
+ 
+ //
+ // Make the socket start editing the specified buffer with the supplied
+ // text editor.
+ void socketStartEditor(SOCKET_DATA *sock, EDITOR *editor, BUFFER *buf);
+ 
+ //
+ // get a pointer to the current editor the socket is using, if any
+ EDITOR *socketGetEditor(SOCKET_DATA *sock);
+ 
+ #endif // EDITOR_H
diff -crN nakedmudv1.5/src/editor/module.mk nakedmudv2.0/src/editor/module.mk
*** nakedmudv1.5/src/editor/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/editor/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ SRC += editor/editor.c editor/notepad.c
diff -crN nakedmudv1.5/src/editor/notepad.c nakedmudv2.0/src/editor/notepad.c
*** nakedmudv1.5/src/editor/notepad.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/editor/notepad.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,100 ----
+ //*****************************************************************************
+ //
+ // notepad.c
+ //
+ // Here is the proof of concept for the editor utility. This is a basic text
+ // editor that allows players to write/read information contained within a
+ // notepad.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../inform.h"
+ #include "../auxiliary.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "editor.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // auxiliary data for sockets
+ //*****************************************************************************
+ typedef struct notepad_data {
+   BUFFER *notepad;
+ } NOTEPAD_DATA;
+ 
+ NOTEPAD_DATA *newNotepadData() {
+   NOTEPAD_DATA *data = malloc(sizeof(NOTEPAD_DATA));
+   data->notepad = newBuffer(1);
+   return data;
+ }
+ 
+ void deleteNotepadData(NOTEPAD_DATA *data) {
+   if(data->notepad) deleteBuffer(data->notepad);
+   free(data);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // local datastructures, functions, and commands for players
+ //*****************************************************************************
+ void socketStartNotepad(SOCKET_DATA *sock) {
+   NOTEPAD_DATA *data = socketGetAuxiliaryData(sock, "notepad_data");
+   socketStartEditor(sock, text_editor, data->notepad);
+ }
+ 
+ COMMAND(cmd_write) {
+   if(!charGetSocket(ch))
+     text_to_char(ch, "You need an attached socket for that!\r\n");
+   else {
+     message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR, 
+ 	    "$n pulls out a pen and begins jotting notes down.");
+     socketStartNotepad(charGetSocket(ch));
+   }
+ }
+ 
+ COMMAND(cmd_notepad) {
+   if(!charGetSocket(ch))
+     text_to_char(ch, "You need an attached socket for that!\r\n");
+   else {
+     SOCKET_DATA *sock = charGetSocket(ch);
+     NOTEPAD_DATA *data = socketGetAuxiliaryData(sock, "notepad_data");
+     if(!*bufferString(data->notepad))
+       text_to_char(ch, "Your notepad is empty.\r\n");
+     else
+       text_to_char(ch, bufferString(data->notepad));
+   }
+ }
+ 
+ const char *socketGetNotepad(SOCKET_DATA *sock) {
+   NOTEPAD_DATA *data = socketGetAuxiliaryData(sock, "notepad_data");
+   return bufferString(data->notepad);
+ }
+ 
+ void socketSetNotepad(SOCKET_DATA *sock, const char *txt) {
+   NOTEPAD_DATA *data = socketGetAuxiliaryData(sock, "notepad_data");
+   bufferClear(data->notepad);
+   bufferCat(data->notepad, txt);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // setting everything up...
+ //*****************************************************************************
+ void init_notepad() {
+   // install the editor components
+   auxiliariesInstall("notepad_data", 
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_SOCKET,
+ 				       newNotepadData, deleteNotepadData,
+ 				       NULL, NULL, NULL, NULL));
+ 
+   // install our commands
+   add_cmd("write", NULL, cmd_write, 0, POS_SITTING, POS_FLYING,
+ 	  LEVEL_PLAYER, FALSE, TRUE);
+   add_cmd("notepad", NULL, cmd_notepad, 0, POS_SITTING, POS_FLYING,
+ 	  LEVEL_PLAYER, FALSE, TRUE);
+ }
diff -crN nakedmudv1.5/src/editor/notepad.d nakedmudv2.0/src/editor/notepad.d
*** nakedmudv1.5/src/editor/notepad.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/editor/notepad.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ editor/notepad.d editor/notepad.o: editor/notepad.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h utils.h inform.h \
+   auxiliary.h socket.h character.h editor/editor.h
diff -crN nakedmudv1.5/src/event.c nakedmudv2.0/src/event.c
*** nakedmudv1.5/src/event.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/event.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 114,119 ****
--- 114,124 ----
    // add our proof of concept command
    add_cmd("devent", NULL, cmd_devent, 0, POS_SLEEPING, POS_FLYING,
  	  LEVEL_ADMIN, TRUE, FALSE);
+ 
+   // make sure all events involving the object/char are cancelled when
+   // either is extracted from the game
+   add_extract_obj_func((void (*)(OBJ_DATA *)) interrupt_events_involving);
+   add_extract_mob_func((void (*)(CHAR_DATA *))interrupt_events_involving);
  }
  
  void interrupt_event(EVENT_DATA *event) {
diff -crN nakedmudv1.5/src/event.d nakedmudv2.0/src/event.d
*** nakedmudv1.5/src/event.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/event.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ event.d event.o: event.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h character.h event.h
diff -crN nakedmudv1.5/src/exit.c nakedmudv2.0/src/exit.c
*** nakedmudv1.5/src/exit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/exit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 19,25 ****
  struct exit_data {
    char *name;              // what is the name of our door for descriptions?
    char *keywords;          // what keywords can the door be referenced by?
!   char *description;       // what does a person see when they look at us?
  
    char *spec_enter;        // the message when we enter from this exit
    char *spec_leave;        // the message when we leave through this exit
--- 19,25 ----
  struct exit_data {
    char *name;              // what is the name of our door for descriptions?
    char *keywords;          // what keywords can the door be referenced by?
!   BUFFER *desc;            // what does a person see when they look at us?
  
    char *spec_enter;        // the message when we enter from this exit
    char *spec_leave;        // the message when we leave through this exit
***************
*** 40,82 ****
    EXIT_DATA *exit = malloc(sizeof(EXIT_DATA));
    exit->name        = strdup("");
    exit->keywords    = strdup("");
-   exit->description = strdup("");
    exit->spec_enter  = strdup("");
    exit->spec_leave  = strdup("");
!   exit->key    = NOTHING;
!   exit->to     = NOWHERE;
!   exit->hide_lev = 0;
!   exit->pick_lev = 0;
!   exit->status   = 0;
!   exit->closable = FALSE;
    return exit;
  };
  
  
  void deleteExit(EXIT_DATA *exit) {
    if(exit->name)        free(exit->name);
-   if(exit->description) free(exit->description);
    if(exit->spec_enter)  free(exit->spec_enter);
    if(exit->spec_leave)  free(exit->spec_leave);
    if(exit->keywords)    free(exit->keywords);
  
    free(exit);
  };
  
  
  void exitCopyTo(const EXIT_DATA *from, EXIT_DATA *to) {
!   exitSetName       (to, exitGetName(from));
!   exitSetKeywords   (to, exitGetKeywords(from));
!   exitSetDescription(to, exitGetDesc(from));
!   exitSetTo         (to, exitGetTo(from));
!   exitSetPickLev    (to, exitGetPickLev(from));
!   exitSetHidden     (to, exitGetHidden(from));
!   exitSetKey        (to, exitGetKey(from));
!   exitSetLocked     (to, exitIsLocked(from));
!   exitSetClosed     (to, exitIsClosed(from));
!   exitSetClosable   (to, exitIsClosable(from));
!   exitSetSpecEnter  (to, exitGetSpecEnter(from));
!   exitSetSpecLeave  (to, exitGetSpecLeave(from));
  }
  
  
--- 40,82 ----
    EXIT_DATA *exit = malloc(sizeof(EXIT_DATA));
    exit->name        = strdup("");
    exit->keywords    = strdup("");
    exit->spec_enter  = strdup("");
    exit->spec_leave  = strdup("");
!   exit->desc        = newBuffer(1);
!   exit->key         = NOTHING;
!   exit->to          = NOWHERE;
!   exit->hide_lev    = 0;
!   exit->pick_lev    = 0;
!   exit->status      = 0;
!   exit->closable    = FALSE;
    return exit;
  };
  
  
  void deleteExit(EXIT_DATA *exit) {
    if(exit->name)        free(exit->name);
    if(exit->spec_enter)  free(exit->spec_enter);
    if(exit->spec_leave)  free(exit->spec_leave);
    if(exit->keywords)    free(exit->keywords);
+   if(exit->desc)        deleteBuffer(exit->desc);
  
    free(exit);
  };
  
  
  void exitCopyTo(const EXIT_DATA *from, EXIT_DATA *to) {
!   exitSetName     (to, exitGetName(from));
!   exitSetKeywords (to, exitGetKeywords(from));
!   exitSetDesc     (to, exitGetDesc(from));
!   exitSetTo       (to, exitGetTo(from));
!   exitSetPickLev  (to, exitGetPickLev(from));
!   exitSetHidden   (to, exitGetHidden(from));
!   exitSetKey      (to, exitGetKey(from));
!   exitSetLocked   (to, exitIsLocked(from));
!   exitSetClosed   (to, exitIsClosed(from));
!   exitSetClosable (to, exitIsClosable(from));
!   exitSetSpecEnter(to, exitGetSpecEnter(from));
!   exitSetSpecLeave(to, exitGetSpecLeave(from));
  }
  
  
***************
*** 88,103 ****
  
  EXIT_DATA *exitRead(STORAGE_SET *set) {
    EXIT_DATA *exit = newExit();
!   exitSetName(exit,        read_string(set, "name"));
!   exitSetKeywords(exit,    read_string(set, "keywords"));
!   exitSetDescription(exit, read_string(set, "desc"));
!   exitSetSpecEnter(exit,   read_string(set, "enter"));
!   exitSetSpecLeave(exit,   read_string(set, "leave"));
!   exitSetTo(exit,          read_int   (set, "to"));
!   exitSetKey(exit,         read_int   (set, "key"));
!   exitSetHidden(exit,      read_int   (set, "hide_level"));
!   exitSetPickLev(exit,     read_int   (set, "pick_level"));
!   exitSetClosable(exit,    read_int   (set, "closable"));
    return exit;
  }
  
--- 88,103 ----
  
  EXIT_DATA *exitRead(STORAGE_SET *set) {
    EXIT_DATA *exit = newExit();
!   exitSetName(exit,      read_string(set, "name"));
!   exitSetKeywords(exit,  read_string(set, "keywords"));
!   exitSetDesc(exit,      read_string(set, "desc"));
!   exitSetSpecEnter(exit, read_string(set, "enter"));
!   exitSetSpecLeave(exit, read_string(set, "leave"));
!   exitSetTo(exit,        read_int   (set, "to"));
!   exitSetKey(exit,       read_int   (set, "key"));
!   exitSetHidden(exit,    read_int   (set, "hide_level"));
!   exitSetPickLev(exit,   read_int   (set, "pick_level"));
!   exitSetClosable(exit,  read_int   (set, "closable"));
    return exit;
  }
  
***************
*** 105,111 ****
    STORAGE_SET *set = new_storage_set();
    store_string(set, "name",       exit->name);
    store_string(set, "keywords",   exit->keywords);
!   store_string(set, "desc",       exit->description);
    store_string(set, "enter",      exit->spec_enter);
    store_string(set, "leave",      exit->spec_leave);
    store_int   (set, "to",         exit->to);
--- 105,111 ----
    STORAGE_SET *set = new_storage_set();
    store_string(set, "name",       exit->name);
    store_string(set, "keywords",   exit->keywords);
!   store_string(set, "desc",       bufferString(exit->desc));
    store_string(set, "enter",      exit->spec_enter);
    store_string(set, "leave",      exit->spec_leave);
    store_int   (set, "to",         exit->to);
***************
*** 166,172 ****
  };
  
  const char *exitGetDesc(const EXIT_DATA *exit) {
!   return exit->description;
  };
  
  const char *exitGetSpecEnter(const EXIT_DATA *exit) {
--- 166,172 ----
  };
  
  const char *exitGetDesc(const EXIT_DATA *exit) {
!   return bufferString(exit->desc);
  };
  
  const char *exitGetSpecEnter(const EXIT_DATA *exit) {
***************
*** 177,185 ****
    return exit->spec_leave;
  };
  
! char      **exitGetDescPtr(EXIT_DATA *exit) {
!   return &(exit->description);
! };
  
  void        exitSetClosable(EXIT_DATA *exit, bool closable) {
    exit->closable = (closable != 0);
--- 177,185 ----
    return exit->spec_leave;
  };
  
! BUFFER *exitGetDescBuffer(const EXIT_DATA *exit) {
!   return exit->desc;
! }
  
  void        exitSetClosable(EXIT_DATA *exit, bool closable) {
    exit->closable = (closable != 0);
***************
*** 223,232 ****
    else               exit->keywords = strdup("");
  };
  
! void        exitSetDescription(EXIT_DATA *exit, const char *desc) {
!   if(exit->description) free(exit->description);
!   if(desc)              exit->description = strdup(desc);
!   else                  exit->description = strdup("");
  };
  
  void        exitSetSpecEnter(EXIT_DATA *exit, const char *enter) {
--- 223,231 ----
    else               exit->keywords = strdup("");
  };
  
! void        exitSetDesc(EXIT_DATA *exit, const char *desc) {
!   bufferClear(exit->desc);
!   bufferCat(exit->desc, (desc ? desc : ""));
  };
  
  void        exitSetSpecEnter(EXIT_DATA *exit, const char *enter) {
diff -crN nakedmudv1.5/src/exit.d nakedmudv2.0/src/exit.d
*** nakedmudv1.5/src/exit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/exit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ exit.d exit.o: exit.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h utils.h storage.h exit.h
diff -crN nakedmudv1.5/src/exit.h nakedmudv2.0/src/exit.h
*** nakedmudv1.5/src/exit.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/exit.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 65,72 ****
  const char *exitGetDesc        (const EXIT_DATA *exit);
  const char *exitGetSpecLeave   (const EXIT_DATA *exit);
  const char *exitGetSpecEnter   (const EXIT_DATA *exit);
! // for editing exit descriptions in the text editor
! char      **exitGetDescPtr     (EXIT_DATA *exit);
  
  void        exitSetClosable    (EXIT_DATA *exit, bool closable);
  void        exitSetClosed      (EXIT_DATA *exit, bool closed);
--- 65,71 ----
  const char *exitGetDesc        (const EXIT_DATA *exit);
  const char *exitGetSpecLeave   (const EXIT_DATA *exit);
  const char *exitGetSpecEnter   (const EXIT_DATA *exit);
! BUFFER     *exitGetDescBuffer  (const EXIT_DATA *exit);
  
  void        exitSetClosable    (EXIT_DATA *exit, bool closable);
  void        exitSetClosed      (EXIT_DATA *exit, bool closed);
***************
*** 77,83 ****
  void        exitSetTo          (EXIT_DATA *exit, room_vnum room);
  void        exitSetName        (EXIT_DATA *exit, const char *name);
  void        exitSetKeywords    (EXIT_DATA *exit, const char *keywords);
! void        exitSetDescription (EXIT_DATA *exit, const char *desc);
  void        exitSetSpecLeave   (EXIT_DATA *exit, const char *leave);
  void        exitSetSpecEnter   (EXIT_DATA *exit, const char *enter);
  
--- 76,82 ----
  void        exitSetTo          (EXIT_DATA *exit, room_vnum room);
  void        exitSetName        (EXIT_DATA *exit, const char *name);
  void        exitSetKeywords    (EXIT_DATA *exit, const char *keywords);
! void        exitSetDesc        (EXIT_DATA *exit, const char *desc);
  void        exitSetSpecLeave   (EXIT_DATA *exit, const char *leave);
  void        exitSetSpecEnter   (EXIT_DATA *exit, const char *enter);
  
diff -crN nakedmudv1.5/src/extra_descs.c nakedmudv2.0/src/extra_descs.c
*** nakedmudv1.5/src/extra_descs.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/extra_descs.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 20,27 ****
  
  struct edesc_data {
    EDESC_SET *set;
!   char *keywords;
!   char *desc;
  };
  
  
--- 20,27 ----
  
  struct edesc_data {
    EDESC_SET *set;
!   char      *keywords;
!   BUFFER    *desc;
  };
  
  
***************
*** 44,50 ****
  STORAGE_SET *edescStore(EDESC_DATA *data) {
    STORAGE_SET *set = new_storage_set();
    store_string(set, "keywords", data->keywords);
!   store_string(set, "desc",     data->desc);
    return set;
  }
  
--- 44,50 ----
  STORAGE_SET *edescStore(EDESC_DATA *data) {
    STORAGE_SET *set = new_storage_set();
    store_string(set, "keywords", data->keywords);
!   store_string(set, "desc",     bufferString(data->desc));
    return set;
  }
  
***************
*** 69,75 ****
  }
  
  
! void copyEdescSetTo(EDESC_SET *from, EDESC_SET *to) {
    // delete all of the current entries
    deleteListWith(to->edescs, deleteEdesc);
    to->edescs = newList();
--- 69,75 ----
  }
  
  
! void edescSetCopyTo(EDESC_SET *from, EDESC_SET *to) {
    // delete all of the current entries
    deleteListWith(to->edescs, deleteEdesc);
    to->edescs = newList();
***************
*** 78,100 ****
    EDESC_DATA    *entry   = NULL;
    LIST_ITERATOR *edesc_i = newListIterator(from->edescs);
    ITERATE_LIST(entry, edesc_i)
!     edescSetPut(to, copyEdesc(entry));
    deleteListIterator(edesc_i);
  }
  
  
! EDESC_SET *copyEdescSet(EDESC_SET *set) {
    EDESC_SET *newset = newEdescSet();
!   copyEdescSetTo(set, newset);
    return newset;
  }
  
! EDESC_DATA *getEdesc            (EDESC_SET *set, const char *keyword) {
    LIST_ITERATOR *edesc_i = newListIterator(set->edescs);
    EDESC_DATA       *desc = NULL;
  
    ITERATE_LIST(desc, edesc_i)
!     if(isEdescKeyword(desc, keyword))
        break;
    
    deleteListIterator(edesc_i);
--- 78,100 ----
    EDESC_DATA    *entry   = NULL;
    LIST_ITERATOR *edesc_i = newListIterator(from->edescs);
    ITERATE_LIST(entry, edesc_i)
!     edescSetPut(to, edescCopy(entry));
    deleteListIterator(edesc_i);
  }
  
  
! EDESC_SET *edescSetCopy(EDESC_SET *set) {
    EDESC_SET *newset = newEdescSet();
!   edescSetCopyTo(set, newset);
    return newset;
  }
  
! EDESC_DATA *edescSetGet            (EDESC_SET *set, const char *keyword) {
    LIST_ITERATOR *edesc_i = newListIterator(set->edescs);
    EDESC_DATA       *desc = NULL;
  
    ITERATE_LIST(desc, edesc_i)
!     if(edescIsKeyword(desc, keyword))
        break;
    
    deleteListIterator(edesc_i);
***************
*** 106,112 ****
    listQueue(set->edescs, edesc);
  }
  
! EDESC_DATA *getEdescNum         (EDESC_SET *set, int num) {
    return listGet(set->edescs, num);
  }
  
--- 106,112 ----
    listQueue(set->edescs, edesc);
  }
  
! EDESC_DATA *edescSetGetNum         (EDESC_SET *set, int num) {
    return listGet(set->edescs, num);
  }
  
***************
*** 115,128 ****
      edesc->set = NULL;
  }
  
! EDESC_DATA *removeEdescEntry    (EDESC_SET *set, const char *keyword) {
!   EDESC_DATA *entry = getEdesc(set, keyword);
    if(entry && listRemove(set->edescs, entry))
      entry->set = NULL;
    return entry;
  }
  
! EDESC_DATA *removeEdescEntryNum (EDESC_SET *set, int num) {
    EDESC_DATA *entry = listRemoveNum(set->edescs, num);
    if(entry)
      entry->set = NULL;
--- 115,128 ----
      edesc->set = NULL;
  }
  
! EDESC_DATA *edescSetRemove    (EDESC_SET *set, const char *keyword) {
!   EDESC_DATA *entry = edescSetGet(set, keyword);
    if(entry && listRemove(set->edescs, entry))
      entry->set = NULL;
    return entry;
  }
  
! EDESC_DATA *edescSetRemoveNum (EDESC_SET *set, int num) {
    EDESC_DATA *entry = listRemoveNum(set->edescs, num);
    if(entry)
      entry->set = NULL;
***************
*** 139,149 ****
    free(set);
  }
  
! int         getEdescSetSize     (EDESC_SET *set) {
    return listSize(set->edescs);
  }
  
! LIST       *getEdescList        (EDESC_SET *set) {
    return set->edescs;
  }
  
--- 139,149 ----
    free(set);
  }
  
! int         edescGetSetSize     (EDESC_SET *set) {
    return listSize(set->edescs);
  }
  
! LIST       *edescSetGetList        (EDESC_SET *set) {
    return set->edescs;
  }
  
***************
*** 176,231 ****
    EDESC_DATA *edesc = malloc(sizeof(struct edesc_data));
  
    edesc->set      = NULL;
-   edesc->desc     = (desc ? strdup(desc) : strdup(""));
    edesc->keywords = strdup((keywords ? keywords : ""));
  
    return edesc;
  }
  
  void deleteEdesc(EDESC_DATA *edesc) {
    if(edesc->keywords) free(edesc->keywords);
!   if(edesc->desc)     free(edesc->desc);
    free(edesc);
  }
  
! EDESC_DATA *copyEdesc(EDESC_DATA *edesc) {
!   return newEdesc(edesc->keywords, edesc->desc);
  }
  
! void copyEdescTo(EDESC_DATA *from, EDESC_DATA *to) {
    // copy over the new desc
!   if(to->desc) free(to->desc);
!   to->desc = strdup(from->desc ? from->desc : "");
    if(to->keywords) free(to->keywords);
    to->keywords = strdup(from->keywords ? from->keywords : "");
  }
  
! const char *getEdescKeywords(EDESC_DATA *edesc) {
    return edesc->keywords;
  }
  
! const char *getEdescDescription(EDESC_DATA *edesc) {
!   return edesc->desc;
  }
  
! char **getEdescPtr(EDESC_DATA *edesc) {
!   return &(edesc->desc);
  }
  
! void setEdescKeywords(EDESC_DATA *edesc, const char *keywords) {
    if(edesc->keywords) free(edesc->keywords);
    edesc->keywords   = strdup((keywords ? keywords :""));
  }
  
! void setEdescDescription(EDESC_DATA *edesc, const char *description) {
!   if(edesc->desc) free(edesc->desc);
!   edesc->desc = (description ? strdup(description) : strdup(""));
  }
  
! EDESC_SET *getEdescSet(EDESC_DATA *edesc) {
    return edesc->set;
  }
  
! bool isEdescKeyword(EDESC_DATA *edesc, const char *keyword) {
    return is_keyword(edesc->keywords, keyword, TRUE);
  }
--- 176,231 ----
    EDESC_DATA *edesc = malloc(sizeof(struct edesc_data));
  
    edesc->set      = NULL;
    edesc->keywords = strdup((keywords ? keywords : ""));
+   edesc->desc     = newBuffer(1);
+   bufferCat(edesc->desc, (desc ? desc : ""));
  
    return edesc;
  }
  
  void deleteEdesc(EDESC_DATA *edesc) {
    if(edesc->keywords) free(edesc->keywords);
!   if(edesc->desc)     deleteBuffer(edesc->desc);
    free(edesc);
  }
  
! EDESC_DATA *edescCopy(EDESC_DATA *edesc) {
!   return newEdesc(edesc->keywords, bufferString(edesc->desc));
  }
  
! void edescCopyTo(EDESC_DATA *from, EDESC_DATA *to) {
    // copy over the new desc
!   bufferCopyTo(from->desc, to->desc);
    if(to->keywords) free(to->keywords);
    to->keywords = strdup(from->keywords ? from->keywords : "");
  }
  
! const char *edescSetGetKeywords(EDESC_DATA *edesc) {
    return edesc->keywords;
  }
  
! const char *edescSetGetDesc(EDESC_DATA *edesc) {
!   return bufferString(edesc->desc);
  }
  
! BUFFER *edescGetDescBuffer(EDESC_DATA *edesc) {
!   return edesc->desc;
  }
  
! void edescSetKeywords(EDESC_DATA *edesc, const char *keywords) {
    if(edesc->keywords) free(edesc->keywords);
    edesc->keywords   = strdup((keywords ? keywords :""));
  }
  
! void edescSetDesc(EDESC_DATA *edesc, const char *description) {
!   bufferClear(edesc->desc);
!   bufferCat(edesc->desc, (description ? description : ""));
  }
  
! EDESC_SET *edescGetSet(EDESC_DATA *edesc) {
    return edesc->set;
  }
  
! bool edescIsKeyword(EDESC_DATA *edesc, const char *keyword) {
    return is_keyword(edesc->keywords, keyword, TRUE);
  }
diff -crN nakedmudv1.5/src/extra_descs.d nakedmudv2.0/src/extra_descs.d
*** nakedmudv1.5/src/extra_descs.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/extra_descs.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ extra_descs.d extra_descs.o: extra_descs.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h utils.h storage.h \
+   extra_descs.h
diff -crN nakedmudv1.5/src/extra_descs.h nakedmudv2.0/src/extra_descs.h
*** nakedmudv1.5/src/extra_descs.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/extra_descs.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 22,37 ****
  //*****************************************************************************
  EDESC_SET  *newEdescSet         ();
  void        deleteEdescSet      (EDESC_SET *set);
! void        copyEdescSetTo      (EDESC_SET *from, EDESC_SET *to);
! EDESC_SET  *copyEdescSet        (EDESC_SET *set);
  void        edescSetPut         (EDESC_SET *set, EDESC_DATA *edesc);
! EDESC_DATA *getEdesc            (EDESC_SET *set, const char *keyword);
! EDESC_DATA *getEdescNum         (EDESC_SET *set, int num);
! EDESC_DATA *removeEdescEntry    (EDESC_SET *set, const char *keyword);
! EDESC_DATA *removeEdescEntryNum (EDESC_SET *set, int num);
  void        removeEdesc         (EDESC_SET *set, EDESC_DATA *edesc);
! int         getEdescSetSize     (EDESC_SET *set);
! LIST       *getEdescList        (EDESC_SET *set);
  char       *tagEdescs           (EDESC_SET *set, const char *string,
  				 const char *start_tag, const char *end_tag);
  
--- 22,37 ----
  //*****************************************************************************
  EDESC_SET  *newEdescSet         ();
  void        deleteEdescSet      (EDESC_SET *set);
! void        edescSetCopyTo      (EDESC_SET *from, EDESC_SET *to);
! EDESC_SET  *edescSetCopy        (EDESC_SET *set);
  void        edescSetPut         (EDESC_SET *set, EDESC_DATA *edesc);
! EDESC_DATA *edescSetGet         (EDESC_SET *set, const char *keyword);
! EDESC_DATA *edescSetGetNum      (EDESC_SET *set, int num);
! EDESC_DATA *edescSetRemove      (EDESC_SET *set, const char *keyword);
! EDESC_DATA *edescSetRemoveNum   (EDESC_SET *set, int num);
  void        removeEdesc         (EDESC_SET *set, EDESC_DATA *edesc);
! int         edescGetSetSize  (EDESC_SET *set);
! LIST       *edescSetGetList     (EDESC_SET *set);
  char       *tagEdescs           (EDESC_SET *set, const char *string,
  				 const char *start_tag, const char *end_tag);
  
***************
*** 57,110 ****
  // make a storage set out of the extra desc set, or parse an extra
  // desc set from the storage set.
  //
! EDESC_SET    *edescSetRead(STORAGE_SET *set);
  STORAGE_SET *edescSetStore(EDESC_SET *edescs);
  
  //
  // Make a copy of the EDESC
  //
! EDESC_DATA *copyEdesc(EDESC_DATA *edesc);
  
  //
  // copy the contents of one EDESC to another
  //
! void copyEdescTo(EDESC_DATA *from, EDESC_DATA *to);
  
  //
  // Get a list of the keywords
  //
! const char *getEdescKeywords(EDESC_DATA *edesc);
  
  //
  // return a pointer to the description
  //
! const char *getEdescDescription(EDESC_DATA *edesc);
  
  //
  // get a pointer to the edesc description (for text editing in OLC)
  //
! char **getEdescPtr(EDESC_DATA *edesc);
  
  //
  // set the keywords to this new list of keywords. Keywords
  // must be comma-separated
  //
! void setEdescKeywords(EDESC_DATA *edesc, const char *keywords);
  
  //
  // set the description to this new description
  //
! void setEdescDescription(EDESC_DATA *edesc, const char *description);
  
  //
  // returns TRUE if the keyword is a valid one
  //
! bool isEdescKeyword(EDESC_DATA *edesc, const char *keyword);
  
  //
  // get the set the edesc belongs to
  //
! EDESC_SET *getEdescSet(EDESC_DATA *edesc);
  
  //
  // For each keyword in our list, tag copies of it in string
--- 57,110 ----
  // make a storage set out of the extra desc set, or parse an extra
  // desc set from the storage set.
  //
! EDESC_SET *edescSetRead(STORAGE_SET *set);
  STORAGE_SET *edescSetStore(EDESC_SET *edescs);
  
  //
  // Make a copy of the EDESC
  //
! EDESC_DATA *edescCopy(EDESC_DATA *edesc);
  
  //
  // copy the contents of one EDESC to another
  //
! void edescCopyTo(EDESC_DATA *from, EDESC_DATA *to);
  
  //
  // Get a list of the keywords
  //
! const char *edescSetGetKeywords(EDESC_DATA *edesc);
  
  //
  // return a pointer to the description
  //
! const char *edescSetGetDesc(EDESC_DATA *edesc);
  
  //
  // get a pointer to the edesc description (for text editing in OLC)
  //
! BUFFER *edescGetDescBuffer(EDESC_DATA *edesc);
  
  //
  // set the keywords to this new list of keywords. Keywords
  // must be comma-separated
  //
! void edescSetKeywords(EDESC_DATA *edesc, const char *keywords);
  
  //
  // set the description to this new description
  //
! void edescSetDesc(EDESC_DATA *edesc, const char *description);
  
  //
  // returns TRUE if the keyword is a valid one
  //
! bool edescIsKeyword(EDESC_DATA *edesc, const char *keyword);
  
  //
  // get the set the edesc belongs to
  //
! EDESC_SET *edescGetSet(EDESC_DATA *edesc);
  
  //
  // For each keyword in our list, tag copies of it in string
diff -crN nakedmudv1.5/src/gameloop.c nakedmudv2.0/src/gameloop.c
*** nakedmudv1.5/src/gameloop.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/gameloop.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,11 ****
  //*****************************************************************************
- //
  // gameloop.c
  //
  // contains the entrypoint for the MUD, plus various state-handling functions.
- //
  //*****************************************************************************
- 
  #include "mud.h"
  #include "socket.h"
  #include "world.h"
--- 1,8 ----
***************
*** 15,21 ****
  #include "save.h"
  #include "handler.h"
  #include "inform.h"
- #include "text_editor.h"
  #include "log.h"
  #include "action.h"
  #include "event.h"
--- 12,17 ----
***************
*** 25,58 ****
  #include "body.h"
  
  
  // optional modules
  #ifdef MODULE_TIME
  #include "time/mudtime.h"
  #endif
- #ifdef MODULE_SCRIPTS
- #include "scripts/script.h"
- #endif
- #ifdef MODULE_OLC
- #include "olc/olc.h"
- #endif
- #ifdef MODULE_ALIAS
- #include "alias/alias.h"
- #endif
- #ifdef MODULE_CHAR_VARS
- #include "char_vars/char_vars.h"
- #endif
  #ifdef MODULE_SOCIALS
  #include "socials/socials.h"
  #endif
  #ifdef MODULE_HELP
  #include "help/help.h"
  #endif
! 
! 
! /* mccp support */
! const unsigned char do_echo         [] = { IAC, WONT, TELOPT_ECHO,      '\0' };
! const unsigned char dont_echo       [] = { IAC, WILL, TELOPT_ECHO,      '\0' };
! 
  
  /* local procedures */
  void game_loop    ( int control );
--- 21,54 ----
  #include "body.h"
  
  
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "editor/editor.h"
+ #include "char_vars/char_vars.h"
+ #include "items/items.h"
+ #include "olc2/olc.h"
+ #include "set_val/set_val.h"
+ #include "scripts/script.h"
+ 
+ 
+ 
+ //*****************************************************************************
  // optional modules
+ //*****************************************************************************
  #ifdef MODULE_TIME
  #include "time/mudtime.h"
  #endif
  #ifdef MODULE_SOCIALS
  #include "socials/socials.h"
  #endif
  #ifdef MODULE_HELP
  #include "help/help.h"
  #endif
! #ifdef MODULE_ALIAS
! #include "alias/alias.h"
! #endif
  
  /* local procedures */
  void game_loop    ( int control );
***************
*** 69,76 ****
  WORLD_DATA *gameworld = NULL;   /*  the gameworld, and ll the prototypes */
  LIST * object_list = NULL;      /*  the list of all existing objects */
  LIST * socket_list = NULL;      /*  the list of active sockets */
- LIST * socket_free = NULL;      /*  the list of free sockets */
  LIST * mobile_list = NULL;      /*  the list of existing mobiles */
  PROPERTY_TABLE *mob_table = NULL;/* a table of mobs by UID, for quick lookup */
  PROPERTY_TABLE *obj_table = NULL;
  
--- 65,73 ----
  WORLD_DATA *gameworld = NULL;   /*  the gameworld, and ll the prototypes */
  LIST * object_list = NULL;      /*  the list of all existing objects */
  LIST * socket_list = NULL;      /*  the list of active sockets */
  LIST * mobile_list = NULL;      /*  the list of existing mobiles */
+ LIST * extract_obj_funcs = NULL;/*  functions called when an obj is extracted */
+ LIST * extract_mob_funcs = NULL;/*  functions called when a char is extracted */
  PROPERTY_TABLE *mob_table = NULL;/* a table of mobs by UID, for quick lookup */
  PROPERTY_TABLE *obj_table = NULL;
  
***************
*** 83,88 ****
--- 80,86 ----
   */
  int main(int argc, char **argv)
  {
+   extern fd_set fSet;
    int i;
    bool fCopyOver = FALSE;
  
***************
*** 112,142 ****
      return 1;
    }
  
  
  
    /************************************************************/
!   /*               INITIALIZE WHAT WE NEED TO                 */
    /************************************************************/
  
!   /* create our global lists */
    object_list = newList();
    socket_list = newList();
-   socket_free = newList();
    mobile_list = newList();
!   // if you've got more than 12000 or so mobs in your
!   // game at a time, you may want to increase this 
!   // value by a bit
    mob_table   = newPropertyTable(charGetUID, 3000);
    obj_table   = newPropertyTable(objGetUID,  3000);
  
!   /* note that we are booting up */
!   log_string("Program starting.");
  
-   /* seed the random number generator */
-   srand(time(0));
  
!   /* get the current time */
!   current_time = time(NULL);
  
    /* initialize our mud settings, such as top character id */
    log_string("Initializing MUD settings.");
--- 110,153 ----
      return 1;
    }
  
+   /* seed the random number generator */
+   srand(time(0));
+ 
+   /* get the current time */
+   current_time = time(NULL);
+ 
+   // change to the lib directory
+   //log_string("Changing to lib directory.");
+   //chdir("../lib");
  
  
    /************************************************************/
!   /*           INITIALIZE ALL OUR LISTS AND TABLES            */
    /************************************************************/
  
!   // lists for storing objects, sockets, and mobiles that are
!   // currently loaded into the game
    object_list = newList();
    socket_list = newList();
    mobile_list = newList();
! 
!   // tables for quick lookup of mobiles and objects by UID.
!   // For optimal speed, the table sizes should be roughly
!   // 25% larger than the number of mobs/objs you intend to have
!   // loaded into the game at any given time.
    mob_table   = newPropertyTable(charGetUID, 3000);
    obj_table   = newPropertyTable(objGetUID,  3000);
  
!   // functions that should be called when objs/mobs 
!   // are extracted from the game world
!   extract_obj_funcs = newList();
!   extract_mob_funcs = newList();
  
  
! 
!   /************************************************************/
!   /*        INITIALIZE OUR SETTINGS AND BASIC SYSTEMS         */
!   /************************************************************/
  
    /* initialize our mud settings, such as top character id */
    log_string("Initializing MUD settings.");
***************
*** 146,198 ****
    log_string("Preparing auxiliary data for usage.");
    init_auxiliaries();
  
!   /* prepare races and bodies for use */
    log_string("Initializing races and default bodies.");
    init_races();
  
-   /* initialize our command table */
    log_string("Initializing command table.");
    init_commands();
  
-   /* initialize actions */
    log_string("Initializing action handler.");
    init_actions();
  
-   /* initialize events */
    log_string("Initializing event handler.");
    init_events();
  
!   // change to the lib directory
!   //log_string("Changing to lib directory.");
!   //chdir("../lib");
  
- #ifdef MODULE_SCRIPTS
-   /* initialize the scripting language */
-   log_string("Initializing scripts.");
-   init_scripts();
- #endif
  
- #ifdef MODULE_OLC
-   /* initialize online creation */
-   log_string("Initializing OLC.");
-   init_olc();
- #endif
  
! #ifdef MODULE_TIME
!   log_string("Initializing game time.");
!   init_time();
! #endif
  
- #ifdef MODULE_CHAR_VARS
    log_string("Initializing character variables.");
    init_char_vars();
- #endif
  
  #ifdef MODULE_ALIAS
    log_string("Initializing aliases.");
    init_aliases();
  #endif
  
  #ifdef MODULE_SOCIALS
    log_string("Initializing socials.");
    init_socials();
--- 157,219 ----
    log_string("Preparing auxiliary data for usage.");
    init_auxiliaries();
  
!   log_string("Initializing bitvectors.");
!   init_bitvectors();
! 
    log_string("Initializing races and default bodies.");
    init_races();
  
    log_string("Initializing command table.");
    init_commands();
  
    log_string("Initializing action handler.");
    init_actions();
  
    log_string("Initializing event handler.");
    init_events();
  
!   log_string("Initializing logging system.");
!   init_logs();
  
  
  
!   /**********************************************************************/
!   /*                START MANDATORY MODULE INSTALLATION                 */
!   /**********************************************************************/
!   log_string("Initializing item types.");
!   init_items();
! 
!   log_string("Initializing editor.");
!   init_editor();
!   init_notepad();
  
    log_string("Initializing character variables.");
    init_char_vars();
  
+   log_string("Initializing OLC v2.0.");
+   init_olc2();
+ 
+   log_string("Initializing set utility.");
+   init_set();
+ 
+   log_string("Initializing scripts.");
+   init_scripts();
+ 
+ 
+   
+   /**********************************************************************/
+   /*                 START OPTIONAL MODULE INSTALLATION                 */
+   /**********************************************************************/
  #ifdef MODULE_ALIAS
    log_string("Initializing aliases.");
    init_aliases();
  #endif
  
+ #ifdef MODULE_TIME
+   log_string("Initializing game time.");
+   init_time();
+ #endif
+ 
  #ifdef MODULE_SOCIALS
    log_string("Initializing socials.");
    init_socials();
***************
*** 203,234 ****
    init_help();
  #endif
  
    /* initialize the socket */
    if (!fCopyOver) {
      log_string("Initializing sockets.");
      control = init_socket();
    }
  
!   /* load all of the logs */
!   log_string("Initializing logging system.");
!   init_logs();
  
!   /* load all external data */
!   log_string("Logging world and reconnecting copyover sockets.");
!   load_muddata(fCopyOver);
  
-   // force-pulse everything once
-   log_string("Force-resetting world");
-   worldForceReset(gameworld);
  
    // main game loop
    log_string("Entering game loop");
    game_loop(control);
  
- #ifdef MODULE_SCRIPTS
    // stop the scripts
    finalize_scripts();
- #endif
  
    // close down the socket
    close(control);
--- 224,273 ----
    init_help();
  #endif
  
+ 
+ 
+ 
+   /**********************************************************************/
+   /*                          SPAWN THE WORLD                           */
+   /**********************************************************************/
+   /* load all game data */
+   log_string("Loading gameworld.");
+   load_muddata();
+ 
+   // force-pulse everything once
+   log_string("Force-resetting world");
+   worldForceReset(gameworld);
+ 
+ 
+   /**********************************************************************/
+   /*                  HANDLE THE SOCKET STARTUP STUFF                   */
+   /**********************************************************************/
    /* initialize the socket */
    if (!fCopyOver) {
      log_string("Initializing sockets.");
      control = init_socket();
    }
  
!   /* clear out the file socket set */
!   FD_ZERO(&fSet);
  
!   /* add control to the set */
!   FD_SET(control, &fSet);
! 
!   // attach our old sockets
!   if(fCopyOver)
!     copyover_recover();
  
  
+   /**********************************************************************/
+   /*             START THE GAME UP, AND HANDLE ITS SHUTDOWN             */
+   /**********************************************************************/
    // main game loop
    log_string("Entering game loop");
    game_loop(control);
  
    // stop the scripts
    finalize_scripts();
  
    // close down the socket
    close(control);
***************
*** 266,293 ****
  
  void game_loop(int control)   
  {
-   SOCKET_DATA *dsock;
    static struct timeval tv;
    struct timeval last_time, new_time;
    extern fd_set fSet;
!   fd_set rFd;
    long secs, usecs;
-   LIST_ITERATOR *sock_i = newListIterator(socket_list);
  
    /* set this for the first loop */
    gettimeofday(&last_time, NULL);
  
-   /* clear out the file socket set */
-   FD_ZERO(&fSet);
- 
-   /* add control to the set */
-   FD_SET(control, &fSet);
- 
-   /* copyover recovery */
-   ITERATE_LIST(dsock, sock_i)
-     FD_SET(dsock->control, &fSet);
-   deleteListIterator(sock_i);
- 
    /* do this untill the program is shutdown */
    while (!shut_down)
    {
--- 305,319 ----
  
  void game_loop(int control)   
  {
    static struct timeval tv;
    struct timeval last_time, new_time;
    extern fd_set fSet;
!   extern fd_set rFd;
    long secs, usecs;
  
    /* set this for the first loop */
    gettimeofday(&last_time, NULL);
  
    /* do this untill the program is shutdown */
    while (!shut_down)
    {
***************
*** 302,309 ****
        continue;
  
      /* check for new connections */
!     if (FD_ISSET(control, &rFd))
!     {
        struct sockaddr_in sock;
        unsigned int socksize;
        int newConnection;
--- 328,334 ----
        continue;
  
      /* check for new connections */
!     if (FD_ISSET(control, &rFd)) {
        struct sockaddr_in sock;
        unsigned int socksize;
        int newConnection;
***************
*** 313,380 ****
          new_socket(newConnection);
      }
  
-     /* poll sockets in the socket list */
-     //    listIteratorReset(sock_i);
-     sock_i = newListIterator(socket_list);
- 
-     ITERATE_LIST(dsock, sock_i) {
-       /*
-        * Close sockects we are unable to read from.
-        */
-       if (FD_ISSET(dsock->control, &rFd) && !read_from_socket(dsock)) {
-         close_socket(dsock, FALSE);
-         continue;
-       }
- 
-       /* Ok, check for a new command */
-       next_cmd_from_buffer(dsock);
  
!       /* Is there a new command pending ? */
!       // I switched to a true/false variable instead of checking if the
!       // first char was \0 so that people in OLC and in scripts can easily
!       // put newlines down when they need to.
!       if (dsock->cmd_read)
!       {
!         /* figure out how to deal with the incoming command */
!         switch(dsock->state)
!         {
! 	default:
! 	  bug("Descriptor in bad state.");
! 	  break;
! 	case STATE_NEW_NAME:
! 	case STATE_NEW_PASSWORD:
! 	case STATE_VERIFY_PASSWORD:
! 	case STATE_ASK_PASSWORD:
! 	case STATE_ASK_SEX:
!    	case STATE_ASK_RACE:
! 	  handle_new_connections(dsock, dsock->next_command);
! 	  break;
! 	case STATE_PLAYING:
! 	  handle_cmd_input(dsock, dsock->next_command);
! 	  break;
! #ifdef MODULE_OLC
! 	case STATE_OLC:
! 	  olc_loop(dsock, dsock->next_command);
! 	  break;
! #endif
! 	case STATE_TEXT_EDITOR:
! 	  text_editor_loop(dsock, dsock->next_command);
! 	  break;
!         }
!         dsock->next_command[0] = '\0';
! 	dsock->cmd_read = FALSE;
!       }
! 
!       /* if the player quits or get's disconnected */
!       if (dsock->state == STATE_CLOSED) continue;
! 
!       /* Send all new data to the socket and close it if any errors occour */
!       if (!flush_output(dsock))
!         close_socket(dsock, FALSE);
!     }
!     deleteListIterator(sock_i);
  
!     /* call the top-level update handler */
      update_handler();
  
      /*
--- 338,348 ----
          new_socket(newConnection);
      }
  
  
!     /* check all of the sockets for input */
!     socket_handler();
  
!     /* call the top-level update handler for events and actions */
      update_handler();
  
      /*
***************
*** 413,431 ****
          continue;
      }
  
-     /* wait out the rest of the pulse */
-     /*
-     while(TRUE) {
-       gettimeofday(&new_time, NULL);
-       secs  = (int) (new_time.tv_sec - last_time.tv_sec);
-       usecs = (int) (new_time.tv_usec - last_time.tv_usec);
- 
-       // check to see if we've gone over time time that is in PULSES_PER_SECOND
-       if(secs * 1000000 + usecs >= 1000000 / PULSES_PER_SECOND)
- 	break;
-     }
-     */
- 
      /* reset the last time we where sleeping */
      gettimeofday(&last_time, NULL);
  
--- 381,386 ----
***************
*** 433,741 ****
      recycle_sockets();
    }
  }
- 
- 
- 
- //*****************************************************************************
- //
- // STATE HANDLER AND RELATED FUNCTIONS
- //
- // Below this point are functions to do with handling a socket's state
- // (e.g. get new name, password, character creation stuff, etc...)
- //
- //*****************************************************************************
- 
- //
- // Ask a new connection for a name. This is the first thing that is called
- // whenever a new socket connects to us
- //
- void state_new_name(SOCKET_DATA *dsock, char *arg) {
-   CHAR_DATA *p_new;
- 
-   if (dsock->lookup_status != TSTATE_DONE) {
-     text_to_buffer(dsock, 
- 		   "Making a dns lookup, please have patience.\n\r"
- 		   "What is your name? ");
-     return;
-   }
-   if (!check_name(arg)) /* check for a legal name */ {
-     text_to_buffer(dsock, 
- 		   "Sorry, that's not a legal name, please pick another.\n\r"
- 		   "What is your name? ");
-     return;//    break;
-   }
-   arg[0] = toupper(arg[0]);
-   log_string("%s is trying to connect.", arg);
- 
- 
-   /* Check for a new Player */
-   if ((p_new = load_profile(arg)) == NULL) {
-     p_new = newChar();
- 
-     /* give the player it's name */
-     charSetName(p_new, arg);
- 
-     /* and room description. In the future, we may want
-        to consider allowing players to seet their own rdescs */
-     char rdesc[SMALL_BUFFER];
-     sprintf(rdesc, "%s is here.", arg);
-     charSetRdesc(p_new, rdesc);
- 
-     /* prepare for next step */
-     text_to_buffer(dsock, "Please enter a new password: ");
-     dsock->state = STATE_NEW_PASSWORD;
-   }
-   else /* old player */ {
-     /* prepare for next step */
-     text_to_buffer(dsock, "What is your password? ");
-     dsock->state = STATE_ASK_PASSWORD;
-   }
-   text_to_buffer(dsock, (char *) dont_echo);
- 
-   /* socket <-> player */
-   charSetSocket(p_new, dsock);
-   dsock->player = p_new;
- }
- 
- 
- //
- // Ask a character for a password. This is only called once, when
- // the character first creates.
- //
- void state_new_password(SOCKET_DATA *dsock, char *arg) {
-   int i;
- 
-   if (strlen(arg) < 5 || strlen(arg) > 12) {
-     text_to_buffer(dsock, 
- 		   "\r\nBetween 5 and 12 chars please!\n\r"
- 		   "Please enter a new password: ");
-     return;
-   }
-   charSetPassword(dsock->player, crypt(arg, charGetName(dsock->player)));
- 
-   for (i = 0; i < strlen(charGetPassword(dsock->player)); i++) {
-     if (charGetPassword(dsock->player)[i] == '~') {
-       text_to_buffer(dsock,
- 		     "Illegal password!\n\r"
- 		     "Please enter a new password: ");
-       return;
-     }
-   }
- 
-   text_to_buffer(dsock, "\r\nPlease verify the password: ");
-   dsock->state = STATE_VERIFY_PASSWORD;
- }
- 
- 
- //
- // Verify that the character's new password is correct. This is
- // only called once, when the character creates
- //
- void state_verify_password(SOCKET_DATA *dsock, char *arg) {
-   if (compares(crypt(arg, charGetName(dsock->player)), 
- 	       charGetPassword(dsock->player))) {
-     text_to_buffer(dsock, (char *) do_echo);
- 
-     /* onto the sex check */
-     dsock->state = STATE_ASK_SEX;
-     text_to_buffer(dsock, "\r\nWhat is your sex (M/F/N): ");
-   }
-   else {
-     charSetPassword(dsock->player, NULL);
-     text_to_buffer(dsock, 
- 		   "\r\nPassword mismatch!\n\r"
- 		   "Please enter a new password: ");
-     dsock->state = STATE_NEW_PASSWORD;
-   }
- }
- 
- void list_races(SOCKET_DATA *sock) {
-   send_to_socket(sock, "Available races are:\r\n");
-   send_to_socket(sock, "%s", raceGetList(TRUE));
-   send_to_socket(sock, "\r\n\r\nPlease enter your choice: ");
- }
- 
- //
- // Ask for the character's race. Called each time a character is created
- //
- void state_ask_race(SOCKET_DATA *dsock, char *arg) {
-   if(!arg || !*arg || !raceIsForPC(arg)) {
-     send_to_socket(dsock, "Invalid race! Please try again: ");
-     return;
-   }    
-   else {
-     charSetRace(dsock->player, arg);
-     charResetBody(dsock->player);
-   }
- 
-   /* give the character a unique id */
-   charSetUID(dsock->player, next_char_uid());
- 
-   /* if it's the first player, set him as the highest level */
-   if(charGetUID(dsock->player) == 1)
-     charSetLevel(dsock->player, MAX_LEVEL);
- 
-   /* add the character to the game */
-   char_to_game(dsock->player);
- 
-   log_string("New player: %s has entered the game.", 
- 	     charGetName(dsock->player));
-     
-   /* and into the game */
-   dsock->state = STATE_PLAYING;
-   text_to_buffer(dsock, motd);
- 
-   // we should do some checks here to make sure the start room exists
-   char_to_room(dsock->player, worldGetRoom(gameworld, START_ROOM));
-   look_at_room(dsock->player, charGetRoom(dsock->player));
- 
-   /* and save him */
-   save_player(dsock->player);
- 
- #ifdef MODULE_SCRIPTS
-   // check enterance scripts
-   try_enterance_script(dsock->player, charGetRoom(dsock->player), NULL);
- #endif
- }
- 
- //
- // Ask for the character's sex. This will be called each time the
- // character creates
- //
- void state_ask_sex(SOCKET_DATA *dsock, char *arg) {
-   switch(*arg) {
-   case 'f':
-   case 'F':
-     charSetSex(dsock->player, SEX_FEMALE);
-     break;
-   case 'm':
-   case 'M':
-     charSetSex(dsock->player, SEX_MALE);
-     break;
-   case 'n':
-   case 'N':
-     charSetSex(dsock->player, SEX_NEUTRAL);
-     break;
-   default:
-     text_to_buffer(dsock, "\r\nInvalid sex. Try again (M/F/N) :");
-     return;
-   }
- 
-   /* onto the password check */
-   dsock->state = STATE_ASK_RACE;
-   list_races(dsock);
- }
- 
- 
- //
- // Ask the character for his or her password. This will be called
- // every time the character logs on, after the first time when the
- // character creates
- //
- void state_ask_password(SOCKET_DATA *dsock, char *arg) {
-   CHAR_DATA *p_new;
- 
-   text_to_buffer(dsock, (char *) do_echo);
-   if (compares(crypt(arg, charGetName(dsock->player)), 
- 	       charGetPassword(dsock->player)))
-   {
-     if ((p_new = check_reconnect(charGetName(dsock->player))) != NULL) {
-       // we do NOT want to extract, here... the player hasn't even
-       // entered the game yet. We just want to DELETE the profile character
-       deleteChar(dsock->player);
- 
-       /* attach the new player */
-       dsock->player = p_new;
-       charSetSocket(p_new, dsock);
- 
-       log_string("%s has reconnected.", charGetName(dsock->player));
- 
-       /* and let him enter the game */
-       dsock->state = STATE_PLAYING;
-       text_to_buffer(dsock, "You take over a body already in use.\n\r");
-     }
-     else if ((p_new = load_player(charGetName(dsock->player))) == NULL) {
-       text_to_socket(dsock, "ERROR: Your pfile is missing!\n\r");
-       // no extract, just delete! We haven't entered the game yet,
-       // so there is no need to extract
-       deleteChar(dsock->player);
- 
-       dsock->player = NULL;
-       close_socket(dsock, FALSE);
-       return;
-     }
-     else {
-       // No extract, just delete. We have not entered the game yet,
-       // so there is no need to extract from it.
-       deleteChar(dsock->player);
- 
-       /* attach the new player */
-       dsock->player = p_new;
-       charSetSocket(p_new, dsock);
- 
-       // try putting the character into the game.
-       // Close the socket if we fail
-       if(try_enter_game(p_new)) {
- 	log_string("%s has entered the game.", charGetName(p_new));
- 	dsock->state = STATE_PLAYING;
- 	text_to_buffer(dsock, motd);
- 	look_at_room(p_new, charGetRoom(p_new));
- 
- #ifdef MODULE_SCRIPTS
- 	// check enterance scripts
- 	try_enterance_script(p_new, charGetRoom(p_new), NULL);
- #endif
-       }
-       else {
- 	// do not extract, just delete. We failed to enter
- 	// the game, so there is no need to extract from the game.
- 	deleteChar(dsock->player);
- 
- 	dsock->player = NULL;
- 	close_socket(dsock, FALSE);
-       }
-     }
-   }
-   else {
-     text_to_socket(dsock, "Bad password!\n\r");
-     // do not extract, just delete. We have not entered the game
-     // yet, so there is no need to extract from the game.
-     deleteChar(dsock->player);
- 
-     dsock->player = NULL;
-     close_socket(dsock, FALSE);
-   }
- }
- 
- 
- void handle_new_connections(SOCKET_DATA *dsock, char *arg) {
-   switch(dsock->state) {
-   case STATE_NEW_NAME:
-     state_new_name(dsock, arg);
-     break;
- 
-   case STATE_NEW_PASSWORD:
-     state_new_password(dsock, arg);
-     break;
-     
-   case STATE_VERIFY_PASSWORD:
-     state_verify_password(dsock, arg);
-     break;
-     
-   case STATE_ASK_PASSWORD:
-     state_ask_password(dsock, arg);
-     break;
- 
-   case STATE_ASK_SEX:
-     state_ask_sex(dsock, arg);
-     break;
- 
-   case STATE_ASK_RACE:
-     state_ask_race(dsock, arg);
-     break;
- 
-   default:
-     bug("Handle_new_connections: Bad state.");
-     break;
-   }
- }
--- 388,390 ----
diff -crN nakedmudv1.5/src/gameloop.d nakedmudv2.0/src/gameloop.d
*** nakedmudv1.5/src/gameloop.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/gameloop.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,7 ----
+ gameloop.d gameloop.o: gameloop.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h socket.h world.h character.h \
+   object.h utils.h save.h handler.h inform.h log.h action.h event.h \
+   auxiliary.h storage.h races.h body.h editor/editor.h \
+   char_vars/char_vars.h items/items.h olc2/olc.h set_val/set_val.h \
+   scripts/script.h time/mudtime.h socials/socials.h help/help.h \
+   alias/alias.h
diff -crN nakedmudv1.5/src/.gdb_history nakedmudv2.0/src/.gdb_history
*** nakedmudv1.5/src/.gdb_history	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/.gdb_history	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,51 ****
  run
! bt
  quit
  run
  bt
- qiut
  quit
  quit
  run
  bt
  quit
  run
  quit
! run
  bt
  quit
  run
  bt
- print buflen
- up
  up
  up
! up
! up
! print buflen
! print buf
! print i
  quit
  run
  quit
  run
  bt
- bt
  quit
  run
! bt
  quit
  run
! bt
! bt
! print dsock->player
! print dsock->page
! print dsock->page_string
! q
! run
! print dsock->page_string
! print dsock->player
! print dsock
  bt
  quit
  run
--- 1,44 ----
  run
! quit
! run
  quit
  run
  bt
  quit
+ run
  quit
  run
  bt
  quit
  run
+ bt
  quit
! run 4000
  bt
  quit
  run
  bt
  up
  up
! print data
! print data->curr_path
! print listSize(data->curr_path)
  quit
  run
  quit
  run
  bt
  quit
  run
! print i
! print j
! print map->rooms[i]
! print map->rooms[j]
! print map->rooms
  quit
  run
! quit
! run 4000
  bt
  quit
  run
***************
*** 55,164 ****
  quit
  run
  bt
! print dsock
! print dsock->control
! print rFd
! print dsock->outbuf
! print dsock->inbuf
! print dsock->state
! print dsock->indent
  quit
  run
- clear
  bt
  quit
  run
  bt
  quit
  run
  quit
  run
  quit
  run
  quit
  run
  bt
  quit
  run
  quit
  run
  bt
  quit
  run
  quit
! run 3000
! quit
! run 4000
  bt
  bt
- up
- print i
  down
- print i
- print num
  up
  up
  up
! bt
! print i
! print param
! print one_arg
! print arg
! print one_arg
! quit
! run 3000
  quit
  run 4000
  bt
  quit
  run 4000
- quit
- run 3000
  bt
  quit
  run 4000
! bt
  quit
  run 4000
  quit
! run
  quit
  run
  quit
  run
  quit
  bt
! info local
! bt
! ls -l
  bt
  down
  up
  up
! bt
  quit
  bt
  quit
  run
  bt
- up
- print event
- print event->owner
- print event->data
- print event->arg
- print event->delay
- print events
- print events->size
- print events->head->elem
- print events->head->removed
- print events->head->next->removed
- print events->head->next->next->removed
- print events->head->next->next->next->removed
- print events->head->next->next->next->next->removed
- print events->head->next->next->next->next->next->removed
- print events->head->next->next->next->next->next->next->removed
- print events->head->next->next->next->next->next->next->next->removed
- print events->head->next->next->next->next->next->next->next->next->removed
  quit
  run
  quit
--- 48,150 ----
  quit
  run
  bt
! quit
! run 4000
! print data
  quit
  run
  bt
  quit
  run
+ print val
+ print val
  bt
+ print num_bits
+ print bits
+ clear
  quit
  run
+ print val
  quit
  run
  quit
  run
+ bt
  quit
  run
  bt
  quit
  run
+ bt
+ quit
+ run 4000
  quit
  run
  bt
  quit
  run
+ bt
  quit
! run
  bt
+ print L
+ print listSize(L)
+ down
+ print
+ info local
+ info
  bt
  down
  up
+ bt
  up
  up
! print listSize(scripts)
  quit
  run 4000
  bt
  quit
  run 4000
  bt
+ print data
+ print data->item_table
+ print type
+ print funcs
  quit
  run 4000
! shutdo
  quit
  run 4000
  quit
! quit
! run 4000
! bt
  quit
  run
  quit
  run
  quit
+ run
  bt
! quit
! run
  bt
  down
  up
  up
! up
! print key
! print data
! print (char *)data
! print data->item_table
! print funcs
! print key
  quit
+ run 4000
  bt
  quit
  run
  bt
  quit
  run
  quit
***************
*** 166,219 ****
  bt
  quit
  run
! print event
! print event->owner
! print sizeof(*event->owner)
! bt
! print ev_i->L->size
! print ev_i->curr
! print ev_i->L->head
! print ev_i->L->head->next
! print ev_i->L->head->next->removed
! print ev_i->L->head->removed
! bt
! print event
! print event->delay
! print time
! info local
! info global
! help info
! info all-registers
! man info
! help info
! info thread
! info stack
! info scope
! info
  quit
  run
! print 0x30bfa0
! print 0x30bfa0
  quit
  run
! print event
  quit
  run
  quit
  run
- print node
- print node->next
  quit
  run
  quit
  run
  quit
  run
  quit
  run
  bt
  quit
! run
  quit
  run
  bt
--- 152,205 ----
  bt
  quit
  run
! bt
! down
! up
! up
! up
! up
! print key
! print val
! print type_table
! print hashSize(type_table)
  quit
  run
! bt
! quit
! run 4000
! bt
! up
! up
! up
! up
! print key
! print val
! print hash_i
! print val
! info local
  quit
  run
! bt
  quit
  run
  quit
  run
  quit
  run
+ bt
  quit
  run
+ bt
  quit
  run
  quit
  run
  bt
+ print type
  quit
! run 4000
! bt
! run 4000
  quit
  run
  bt
***************
*** 221,236 ****
  run
  bt
  quit
! run 4000
! bt
  quit
  run
  bt
! up
! up
! print data
! print data->curr_path
! print listSize(data->curr_path)
  quit
  run
  quit
--- 207,220 ----
  run
  bt
  quit
! run
  quit
  run
+ run
+ q
+ run
  bt
! clear
  quit
  run
  quit
***************
*** 238,256 ****
  bt
  quit
  run
! print i
! print j
! print map->rooms[i]
! print map->rooms[j]
! print map->rooms
  quit
  run
  quit
! run 4000
  bt
  quit
  run
  quit
  run
  bt
  quit
--- 222,256 ----
  bt
  quit
  run
! bt
  quit
  run
+ bt
  quit
! run
  bt
  quit
  run
+ bt
+ up
+ print from->prfs
+ print to->prfs
+ print from->name
+ print to->name
+ print from->prfs
  quit
  run
  bt
  quit
+ run
+ make
+ run
+ make
+ make
+ make
+ make
+ run
+ make
+ clear
+ run
+ quit
diff -crN nakedmudv1.5/src/handler.c nakedmudv2.0/src/handler.c
*** nakedmudv1.5/src/handler.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/handler.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,34 ****
  #include "object.h"
  #include "utils.h"
  #include "body.h"
- #include "items.h"
  #include "inform.h"
  
! // optional modules
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
! #endif
  
  
  //*****************************************************************************
- //
  // obj/char from/to functions
- //
  //*****************************************************************************
  void obj_from_char(OBJ_DATA *obj) {
    if(objGetCarrier(obj)) {
--- 16,37 ----
  #include "object.h"
  #include "utils.h"
  #include "body.h"
  #include "inform.h"
  
! 
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
! #include "items/items.h"
! #include "items/container.h"
! #include "items/worn.h"
! 
  
  
  //*****************************************************************************
  // obj/char from/to functions
  //*****************************************************************************
  void obj_from_char(OBJ_DATA *obj) {
    if(objGetCarrier(obj)) {
***************
*** 178,184 ****
  //
  //*****************************************************************************
  void do_get(CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container) {
!   if(objIsBitSet(obj, BITFIELD_OBJ, OBJ_NOTAKE))
      send_to_char(ch, "You cannot take %s.\r\n", objGetName(obj));
    else if(container) {
      send_to_char(ch, "You get %s from %s.\r\n", 
--- 181,187 ----
  //
  //*****************************************************************************
  void do_get(CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container) {
!   if(bitIsOneSet(objGetBits(obj), "notake"))
      send_to_char(ch, "You cannot take %s.\r\n", objGetName(obj));
    else if(container) {
      send_to_char(ch, "You get %s from %s.\r\n", 
***************
*** 199,219 ****
  
  void do_put(CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container) {
    if(containerIsClosed(container))
!     send_to_char(ch, "%s is closed. Open it first.\r\n", objGetName(container));
    else if(obj == container)
      send_to_char(ch, "You cannot put %s into itself.\r\n", objGetName(obj));
    // make sure we have enough room
    else if(objGetWeight(obj) > 
! 	  (objGetCapacity(container) - 
  	   objGetWeight(container) + objGetWeightRaw(container)))
      send_to_char(ch, "There is not enough room in %s for %s.\r\n", 
! 		 objGetName(container), objGetName(obj));
    // do the move
    else {
      obj_from_char(obj);
      obj_to_obj(obj, container);
      send_to_char(ch, "You put %s into %s.\r\n", 
! 		 objGetName(obj), objGetName(container));
      message(ch, NULL, obj, container, TRUE, TO_ROOM | TO_NOTCHAR,
  	    "$n puts $o into $O.");
    }
--- 202,223 ----
  
  void do_put(CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container) {
    if(containerIsClosed(container))
!     send_to_char(ch, "%s is closed. Open it first.\r\n", 
! 		 see_obj_as(ch, container));
    else if(obj == container)
      send_to_char(ch, "You cannot put %s into itself.\r\n", objGetName(obj));
    // make sure we have enough room
    else if(objGetWeight(obj) > 
! 	  (containerGetCapacity(container) - 
  	   objGetWeight(container) + objGetWeightRaw(container)))
      send_to_char(ch, "There is not enough room in %s for %s.\r\n", 
! 		 see_obj_as(ch, container), see_obj_as(ch, obj));
    // do the move
    else {
      obj_from_char(obj);
      obj_to_obj(obj, container);
      send_to_char(ch, "You put %s into %s.\r\n", 
! 		 see_obj_as(ch, obj), see_obj_as(ch, container));
      message(ch, NULL, obj, container, TRUE, TO_ROOM | TO_NOTCHAR,
  	    "$n puts $o into $O.");
    }
***************
*** 230,236 ****
    obj_from_char(obj);
    obj_to_char(obj, recv);
  
- #ifdef MODULE_SCRIPTS  
    // object give
    try_scripts(SCRIPT_TYPE_GIVE,
  	      obj, SCRIPTOR_OBJ,
--- 234,239 ----
***************
*** 240,246 ****
    try_scripts(SCRIPT_TYPE_GIVE,
  	      recv, SCRIPTOR_CHAR,
  	      ch, obj, charGetRoom(ch), NULL, NULL, 0);
- #endif
  }
  
  
--- 243,248 ----
***************
*** 249,255 ****
    obj_from_char(obj);
    obj_to_room(obj, charGetRoom(ch));
  
- #ifdef MODULE_SCRIPTS  
    // check for triggers
    try_scripts(SCRIPT_TYPE_DROP,
  	      charGetRoom(ch), SCRIPTOR_ROOM,
--- 251,256 ----
***************
*** 257,268 ****
    try_scripts(SCRIPT_TYPE_DROP,
  	      obj, SCRIPTOR_OBJ,
  	      ch, obj, charGetRoom(ch), NULL, NULL, 0);
- #endif
  }
  
  
  void do_wear(CHAR_DATA *ch, OBJ_DATA *obj, const char *where) {
!   if(objGetType(obj) != ITEM_WORN)
      send_to_char(ch, "You cannot wear %s!\r\n", objGetName(obj));
    else {
      obj_from_char(obj);
--- 258,268 ----
    try_scripts(SCRIPT_TYPE_DROP,
  	      obj, SCRIPTOR_OBJ,
  	      ch, obj, charGetRoom(ch), NULL, NULL, 0);
  }
  
  
  void do_wear(CHAR_DATA *ch, OBJ_DATA *obj, const char *where) {
!   if(objIsType(obj, "worn"))
      send_to_char(ch, "You cannot wear %s!\r\n", objGetName(obj));
    else {
      obj_from_char(obj);
***************
*** 294,300 ****
  //*****************************************************************************
  
  bool try_equip(CHAR_DATA *ch, OBJ_DATA *obj, const char *poslist) {
!   if(objGetType(obj) != ITEM_WORN/* && objGetType(obj) != ITEM_WEAPON*/)
      return FALSE;
  
    bool success       = FALSE;
--- 294,300 ----
  //*****************************************************************************
  
  bool try_equip(CHAR_DATA *ch, OBJ_DATA *obj, const char *poslist) {
!   if(!objIsType(obj, "worn"))
      return FALSE;
  
    bool success       = FALSE;
***************
*** 306,312 ****
    // see where we _want_ to equip to
    if(poslist && *poslist)
      wanted = list_postypes(charGetBody(ch), poslist);
!   needed = wornGetPositions(objGetSubtype(obj));
  
    // just equip to the first free slots
    if(!wanted)
--- 306,312 ----
    // see where we _want_ to equip to
    if(poslist && *poslist)
      wanted = list_postypes(charGetBody(ch), poslist);
!   needed = wornGetPositions(obj);
  
    // just equip to the first free slots
    if(!wanted)
***************
*** 534,540 ****
      if(count && at_count == 1) {
        if(found_type)
  	*found_type = FOUND_EDESC;
!       return getEdesc(objGetEdescs(on), at);
      }
      else
        at_count--;
--- 534,540 ----
      if(count && at_count == 1) {
        if(found_type)
  	*found_type = FOUND_EDESC;
!       return edescSetGet(objGetEdescs(on), at);
      }
      else
        at_count--;
***************
*** 870,876 ****
      if(count && at_count == 1) {
        if(found_type)
  	*found_type = FOUND_EDESC;
!       return getEdesc(roomGetEdescs(charGetRoom(looker)), at);
      }
      else
  	at_count--;
--- 870,876 ----
      if(count && at_count == 1) {
        if(found_type)
  	*found_type = FOUND_EDESC;
!       return edescSetGet(roomGetEdescs(charGetRoom(looker)), at);
      }
      else
  	at_count--;
diff -crN nakedmudv1.5/src/handler.d nakedmudv2.0/src/handler.d
*** nakedmudv1.5/src/handler.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/handler.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ handler.d handler.o: handler.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h handler.h room.h exit.h \
+   extra_descs.h character.h object.h utils.h body.h inform.h \
+   scripts/script.h items/items.h items/container.h items/worn.h
diff -crN nakedmudv1.5/src/hashmap.c nakedmudv2.0/src/hashmap.c
*** nakedmudv1.5/src/hashmap.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/hashmap.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,267 ****
- //*****************************************************************************
- //
- // hashmap.c
- //
- // similar to a hashtable, but keys as well as values can be can be anything.
- //
- //*****************************************************************************
- 
- #include <stdlib.h>
- #include "list.h"
- #include "hashmap.h"
- 
- int gen_hash_cmp(const void *key1, const void *key2) {
-   int val = (key2 - key1);
-   if(val < 0)      return -1;
-   else if(val > 0) return  1;
-   else             return  0;
-   return val;
- }
- 
- int gen_hash_func(const void *key) {
-   int val = (int)key;
-   if(val < 0) return -val;
-   else        return  val;
- }
- 
- struct map_iterator {
-   int curr_bucket;
-   struct hashmap *map;
-   struct list_iterator *bucket_i;
- };
- 
- struct hashmap_entry {
-   void *key;
-   void *val;
- };
- 
- struct hashmap {
-   int num_buckets;
-   struct list **buckets;
-   int (* hash_func)(const void *key);
-   int (*  compares)(const void *key1, const void *key2);
- };
- 
- 
- //
- // an internal form of hashGet that returns the entire entry (key and val)
- //
- struct hashmap_entry *mapGetEntry(struct hashmap *map, void *key) {
-   int bucket = map->hash_func(key) % map->num_buckets;
- 
-   if(map->buckets[bucket] == NULL)
-     return NULL;
-   else {
-     struct list_iterator *list_i = newListIterator(map->buckets[bucket]);
-     struct hashmap_entry *elem   = NULL;
- 
-     for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
-       if(!map->compares(key, elem->key))
- 	break;
-     deleteListIterator(list_i);
- 
-     return elem;
-   }
- }
- 
- 
- struct hashmap_entry *newHashmapEntry(void *key, void *val) {
-   struct hashmap_entry *entry = malloc(sizeof(struct hashmap_entry));
-   entry->key = key;
-   entry->val = val;
-   return entry;
- }
- 
- void deleteHashmapEntry(struct hashmap_entry *entry) {
-   free(entry);
- }
- 
- 
- //*****************************************************************************
- //
- // implementation of hashmap.h
- // documentation in hashmap.h
- //
- //*****************************************************************************
- struct hashmap *newHashmap(void *hash_func,
- 			   void *compares,
- 			   int num_buckets) {
-   int i;
-   struct hashmap *map = malloc(sizeof(struct hashmap));
-   map->num_buckets = num_buckets;
-   map->hash_func   = (hash_func ? hash_func : gen_hash_func);
-   map->compares    = (compares  ? compares  : gen_hash_cmp);
-   map->buckets = malloc(sizeof(struct list *) * num_buckets);
-   for(i = 0; i < num_buckets; i++)
-     map->buckets[i] = NULL;
-   return map;
- }
- 
- void  deleteHashmap(struct hashmap *map) {
-   int i;
-   for(i = 0; i < map->num_buckets; i++) {
-     if(map->buckets[i]) {
-       struct hashmap_entry *entry = NULL;
-       while((entry=(struct hashmap_entry *)listPop(map->buckets[i])) !=NULL)
- 	deleteHashmapEntry(entry);
-       deleteList(map->buckets[i]);
-     }
-   }
-   free(map->buckets);
-   free(map);
- }
- 
- int  mapPut    (struct hashmap *map, void *key, void *val) {
-   struct hashmap_entry *elem = mapGetEntry(map, key);
- 
-   // update the val if it's already here
-   if(elem) {
-     elem->val = val;
-     return 1;
-   }
-   else {
-     int bucket = map->hash_func(key) % map->num_buckets;
- 
-     // if the bucket doesn't exist yet, create it
-     if(map->buckets[bucket] == NULL)
-       map->buckets[bucket] = newList();
- 
-     struct hashmap_entry *entry = newHashmapEntry(key, val);
-     listPut(map->buckets[bucket], entry);
-     return 1;
-   }
- }
- 
- void *mapGet    (struct hashmap *map, void *key) {
-   struct hashmap_entry *elem = mapGetEntry(map, key);
-   if(elem)
-     return elem->val;
-   else
-     return NULL;
- }
- 
- void *mapRemove (struct hashmap *map, void *key) {
-   int bucket = map->hash_func(key) % map->num_buckets;
- 
-   if(map->buckets[bucket] == NULL)
-     return NULL;
-   else {
-     struct list_iterator *list_i = newListIterator(map->buckets[bucket]);
-     struct hashmap_entry *elem   = NULL;
- 
-     for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
-       if(!map->compares(key, elem->key))
- 	break;
-     deleteListIterator(list_i);
- 
-     if(elem) {
-       void *val = elem->val;
-       listRemove(map->buckets[bucket], elem);
-       deleteHashmapEntry(elem);
-       return val;
-     }
-     else
-       return NULL;
-   }
- }
- 
- int   mapIn     (struct hashmap *map, void *key) {
-   return (mapGet(map, key) != NULL);
- }
- 
- int   mapSize   (struct hashmap *map) {
-   int i;
-   int size = 0;
- 
-   for(i = 0; i < map->num_buckets; i++)
-     if(map->buckets[i])
-       size += listSize(map->buckets[i]);
- 
-   return size;
- }
- 
- 
- //*****************************************************************************
- //
- // implementation of the hashmap iterator
- // documentation in hashmap.h
- //
- //*****************************************************************************
- struct map_iterator *newMapIterator(struct hashmap *map) {
-   struct map_iterator *I = malloc(sizeof(struct map_iterator));
-   I->map = map;
-   I->bucket_i = NULL;
-   mapIteratorReset(I);
- 
-   return I;
- }
- 
- void        deleteMapIterator     (struct map_iterator *I) {
-   if(I->bucket_i) deleteListIterator(I->bucket_i);
-   free(I);
- }
- 
- void        mapIteratorReset      (struct map_iterator *I) {
-   int i;
- 
-   if(I->bucket_i) deleteListIterator(I->bucket_i);
-   I->bucket_i = NULL;
-   I->curr_bucket = 0;
- 
-   // bucket_i will be NULL if there are no elements
-   for(i = 0; i < I->map->num_buckets; i++) {
-     if(I->map->buckets[i] != NULL &&
-        listSize(I->map->buckets[i]) > 0) {
-       I->curr_bucket = i;
-       I->bucket_i = newListIterator(I->map->buckets[i]);
-       break;
-     }
-   }
- }
- 
- 
- void        mapIteratorNext       (struct map_iterator *I) {
-   // no elements in the hashmap
-   if(I->bucket_i == NULL)
-     return;
-   // we're at the end of our list
-   else if(listIteratorNext(I->bucket_i) == NULL) {
-     deleteListIterator(I->bucket_i);
-     I->bucket_i = NULL;
-     I->curr_bucket++;
-     
-     for(; I->curr_bucket < I->map->num_buckets; I->curr_bucket++) {
-       if(I->map->buckets[I->curr_bucket] != NULL &&
- 	 listSize(I->map->buckets[I->curr_bucket]) > 0) {
- 	I->bucket_i = newListIterator(I->map->buckets[I->curr_bucket]);
- 	break;
-       }
-     }
-   }
- }
- 
- void *mapIteratorCurrentKey (struct map_iterator *I) {
-   if(!I->bucket_i)
-     return NULL;
-   else {
-     struct hashmap_entry *entry = ((struct hashmap_entry *)
- 				     listIteratorCurrent(I->bucket_i));
-     if(entry)
-       return entry->key;
-     else
-       return NULL;
-   }
- }
- 
- void       *mapIteratorCurrentVal (struct map_iterator *I) {
-   if(!I->bucket_i) 
-     return NULL;
-   else {
-     struct hashmap_entry *entry = ((struct hashmap_entry *)
- 				     listIteratorCurrent(I->bucket_i));
-     if(entry)
-       return entry->val;
-     else
-       return NULL;
-   }
- }
--- 0 ----
diff -crN nakedmudv1.5/src/hashmap.h nakedmudv2.0/src/hashmap.h
*** nakedmudv1.5/src/hashmap.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/hashmap.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,41 ****
- #ifndef __HASHMAP_H
- #define __HASHMAP_H
- //*****************************************************************************
- //
- // hashmap.h
- //
- // similar to a hashtable, but keys as well as values can be can be anything.
- //
- //*****************************************************************************
- 
- //
- // if hash_func and/or compares are null, generic hashing and comparing
- // functions are used.
- //
- // hash_func is expected to be a function that takes the key type used in
- // this map, and returns an integer based on that key.
- //
- // compares is expected to be a function that takes two keys and compares
- // them togher. If they are equal, 0 is returned. if key1 is less than key2,
- // -1 is returned. otherwise, 1 is returned.
- //
- struct hashmap *newHashmap(void *hash_func,
- 			   void *compares,
- 			   int num_buckets);
- void            deleteHashmap(struct hashmap *map);
- 
- int   mapPut    (struct hashmap *map, void *key, void *val);
- void *mapGet    (struct hashmap *map, void *key);
- void *mapRemove (struct hashmap *map, void *key);
- int   mapIn     (struct hashmap *map, void *key);
- int   mapSize   (struct hashmap *map);
- 
- struct map_iterator *newMapIterator(struct hashmap *map);
- void              deleteMapIterator(struct map_iterator *I);
- 
- void  mapIteratorReset      (struct map_iterator *I);
- void  mapIteratorNext       (struct map_iterator *I);
- void *mapIteratorCurrentKey (struct map_iterator *I);
- void *mapIteratorCurrentVal (struct map_iterator *I);
- 
- #endif // __MAP_H
--- 0 ----
diff -crN nakedmudv1.5/src/hashtable.c nakedmudv2.0/src/hashtable.c
*** nakedmudv1.5/src/hashtable.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/hashtable.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 8,31 ****
  //*****************************************************************************
  
  #include <stdlib.h>
  #include <string.h>
  #include "list.h"
  #include "hashtable.h"
  
  struct hashtable_iterator {
    int curr_bucket;
!   struct hashtable *table;
!   struct list_iterator *bucket_i;
  };
  
! struct hashtable_entry {
    char *key;
    void *val;
! };
  
  struct hashtable {
    int num_buckets;
!   struct list **buckets;
  };
  
  
--- 8,32 ----
  //*****************************************************************************
  
  #include <stdlib.h>
+ #include <ctype.h>
  #include <string.h>
  #include "list.h"
  #include "hashtable.h"
  
  struct hashtable_iterator {
    int curr_bucket;
!   HASHTABLE *table;
!   LIST_ITERATOR *bucket_i;
  };
  
! typedef struct hashtable_entry {
    char *key;
    void *val;
! } HASH_ENTRY;
  
  struct hashtable {
    int num_buckets;
!   LIST **buckets;
  };
  
  
***************
*** 38,44 ****
  
    for (i = 0; i < len; i++) {
      base *= BASE;
!     hvalue += key[i] * base;
    }
  
    return (hvalue < 0 ? hvalue * -1 : hvalue);
--- 39,45 ----
  
    for (i = 0; i < len; i++) {
      base *= BASE;
!     hvalue += tolower(key[i]) * base;
    }
  
    return (hvalue < 0 ? hvalue * -1 : hvalue);
***************
*** 48,64 ****
  //
  // an internal form of hashGet that returns the entire entry (key and val)
  //
! struct hashtable_entry *hashGetEntry(struct hashtable *table, const char *key){
    int bucket = hash(key) % table->num_buckets;
  
    if(table->buckets[bucket] == NULL)
      return NULL;
    else {
!     struct list_iterator *list_i = newListIterator(table->buckets[bucket]);
!     struct hashtable_entry *elem = NULL;
  
      for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
!       if(!strcmp(key, elem->key))
  	break;
      deleteListIterator(list_i);
  
--- 49,65 ----
  //
  // an internal form of hashGet that returns the entire entry (key and val)
  //
! HASH_ENTRY *hashGetEntry(HASHTABLE *table, const char *key){
    int bucket = hash(key) % table->num_buckets;
  
    if(table->buckets[bucket] == NULL)
      return NULL;
    else {
!     LIST_ITERATOR *list_i = newListIterator(table->buckets[bucket]);
!     HASH_ENTRY *elem = NULL;
  
      for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
!       if(!strcasecmp(key, elem->key))
  	break;
      deleteListIterator(list_i);
  
***************
*** 66,79 ****
    }
  }
  
! struct hashtable_entry *newHashtableEntry(const char *key, void *val) {
!   struct hashtable_entry *entry = malloc(sizeof(struct hashtable_entry));
    entry->key = strdup(key);
    entry->val = val;
    return entry;
  }
  
! void deleteHashtableEntry(struct hashtable_entry *entry) {
    if(entry->key) free(entry->key);
    free(entry);
  }
--- 67,80 ----
    }
  }
  
! HASH_ENTRY *newHashtableEntry(const char *key, void *val) {
!   HASH_ENTRY *entry = malloc(sizeof(HASH_ENTRY));
    entry->key = strdup(key);
    entry->val = val;
    return entry;
  }
  
! void deleteHashtableEntry(HASH_ENTRY *entry) {
    if(entry->key) free(entry->key);
    free(entry);
  }
***************
*** 85,106 ****
  // documentation in hashtable.h
  //
  //*****************************************************************************
! struct hashtable *newHashtable(int num_buckets) {
    int i;
!   struct hashtable *table = malloc(sizeof(struct hashtable));
    table->num_buckets = num_buckets;
!   table->buckets = malloc(sizeof(struct list *) * num_buckets);
    for(i = 0; i < num_buckets; i++)
      table->buckets[i] = NULL;
    return table;
  }
  
! void  deleteHashtable(struct hashtable *table) {
    int i;
    for(i = 0; i < table->num_buckets; i++) {
      if(table->buckets[i]) {
!       struct hashtable_entry *entry = NULL;
!       while((entry=(struct hashtable_entry *)listPop(table->buckets[i])) !=NULL)
  	deleteHashtableEntry(entry);
        deleteList(table->buckets[i]);
      }
--- 86,107 ----
  // documentation in hashtable.h
  //
  //*****************************************************************************
! HASHTABLE *newHashtable(int num_buckets) {
    int i;
!   HASHTABLE *table = malloc(sizeof(HASHTABLE));
    table->num_buckets = num_buckets;
!   table->buckets = malloc(sizeof(LIST *) * num_buckets);
    for(i = 0; i < num_buckets; i++)
      table->buckets[i] = NULL;
    return table;
  }
  
! void  deleteHashtable(HASHTABLE *table) {
    int i;
    for(i = 0; i < table->num_buckets; i++) {
      if(table->buckets[i]) {
!       HASH_ENTRY *entry = NULL;
!       while((entry=(HASH_ENTRY *)listPop(table->buckets[i])) !=NULL)
  	deleteHashtableEntry(entry);
        deleteList(table->buckets[i]);
      }
***************
*** 110,117 ****
    free(table);
  }
  
! int  hashPut    (struct hashtable *table, const char *key, void *val) {
!   struct hashtable_entry *elem = hashGetEntry(table, key);
  
    // if it's already in, update the value
    if(elem) {
--- 111,118 ----
    free(table);
  }
  
! int  hashPut    (HASHTABLE *table, const char *key, void *val) {
!   HASH_ENTRY *elem = hashGetEntry(table, key);
  
    // if it's already in, update the value
    if(elem) {
***************
*** 125,155 ****
      if(table->buckets[bucket] == NULL)
        table->buckets[bucket] = newList();
  
!     struct hashtable_entry *entry = newHashtableEntry(key, val);
      listPut(table->buckets[bucket], entry);
      return 1;
    }
  }
  
! void *hashGet    (struct hashtable *table, const char *key) {
!   struct hashtable_entry *elem = hashGetEntry(table, key);
    if(elem != NULL)
      return elem->val;
    else
      return NULL;
  }
  
! void *hashRemove (struct hashtable *table, const char *key) {
    int bucket = hash(key) % table->num_buckets;
  
    if(table->buckets[bucket] == NULL)
      return NULL;
    else {
!     struct list_iterator *list_i = newListIterator(table->buckets[bucket]);
!     struct hashtable_entry *elem = NULL;
  
      for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
!       if(!strcmp(key, elem->key))
  	break;
      deleteListIterator(list_i);
  
--- 126,156 ----
      if(table->buckets[bucket] == NULL)
        table->buckets[bucket] = newList();
  
!     HASH_ENTRY *entry = newHashtableEntry(key, val);
      listPut(table->buckets[bucket], entry);
      return 1;
    }
  }
  
! void *hashGet    (HASHTABLE *table, const char *key) {
!   HASH_ENTRY *elem = hashGetEntry(table, key);
    if(elem != NULL)
      return elem->val;
    else
      return NULL;
  }
  
! void *hashRemove (HASHTABLE *table, const char *key) {
    int bucket = hash(key) % table->num_buckets;
  
    if(table->buckets[bucket] == NULL)
      return NULL;
    else {
!     LIST_ITERATOR *list_i = newListIterator(table->buckets[bucket]);
!     HASH_ENTRY *elem = NULL;
  
      for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
!       if(!strcasecmp(key, elem->key))
  	break;
      deleteListIterator(list_i);
  
***************
*** 164,174 ****
    }
  }
  
! int   hashIn     (struct hashtable *table, const char *key) {
!   return (hashGet(table, key) != NULL);
  }
  
! int   hashSize   (struct hashtable *table) {
    int i;
    int size = 0;
  
--- 165,193 ----
    }
  }
  
! int   hashIn     (HASHTABLE *table, const char *key) {
!   int bucket = hash(key) % table->num_buckets;
! 
!   if(table->buckets[bucket] == NULL)
!     return 0;
!   else {
!     int found  = 0;
!     LIST_ITERATOR *list_i = newListIterator(table->buckets[bucket]);
!     HASH_ENTRY *elem = NULL;
! 
!     for(;(elem = listIteratorCurrent(list_i)) != NULL;listIteratorNext(list_i)){
!       if(!strcasecmp(key, elem->key)) {
! 	found = 1;
! 	break;
!       }
!     }
!     deleteListIterator(list_i);
! 
!     return found;
!   }
  }
  
! int   hashSize   (HASHTABLE *table) {
    int i;
    int size = 0;
  
***************
*** 186,193 ****
  // documentation in hashtable.h
  //
  //*****************************************************************************
! struct hashtable_iterator *newHashIterator(struct hashtable *table) {
!   struct hashtable_iterator *I = malloc(sizeof(struct hashtable_iterator));
    I->table = table;
    I->bucket_i = NULL;
    hashIteratorReset(I);
--- 205,212 ----
  // documentation in hashtable.h
  //
  //*****************************************************************************
! HASH_ITERATOR *newHashIterator(HASHTABLE *table) {
!   HASH_ITERATOR *I = malloc(sizeof(HASH_ITERATOR));
    I->table = table;
    I->bucket_i = NULL;
    hashIteratorReset(I);
***************
*** 195,206 ****
    return I;
  }
  
! void        deleteHashIterator     (struct hashtable_iterator *I) {
    if(I->bucket_i) deleteListIterator(I->bucket_i);
    free(I);
  }
  
! void        hashIteratorReset      (struct hashtable_iterator *I) {
    int i;
  
    if(I->bucket_i) deleteListIterator(I->bucket_i);
--- 214,225 ----
    return I;
  }
  
! void        deleteHashIterator     (HASH_ITERATOR *I) {
    if(I->bucket_i) deleteListIterator(I->bucket_i);
    free(I);
  }
  
! void        hashIteratorReset      (HASH_ITERATOR *I) {
    int i;
  
    if(I->bucket_i) deleteListIterator(I->bucket_i);
***************
*** 219,225 ****
  }
  
  
! void        hashIteratorNext       (struct hashtable_iterator *I) {
    // no elements in the hashtable
    if(I->bucket_i == NULL) 
      return;
--- 238,244 ----
  }
  
  
! void        hashIteratorNext       (HASH_ITERATOR *I) {
    // no elements in the hashtable
    if(I->bucket_i == NULL) 
      return;
***************
*** 240,251 ****
  }
  
  
! const char *hashIteratorCurrentKey (struct hashtable_iterator *I) {
    if(!I->bucket_i) 
      return NULL;
    else {
!     struct hashtable_entry *entry = ((struct hashtable_entry *)
! 				     listIteratorCurrent(I->bucket_i));
      if(entry)
        return entry->key;
      else
--- 259,269 ----
  }
  
  
! const char *hashIteratorCurrentKey (HASH_ITERATOR *I) {
    if(!I->bucket_i) 
      return NULL;
    else {
!     HASH_ENTRY *entry = ((HASH_ENTRY *) listIteratorCurrent(I->bucket_i));
      if(entry)
        return entry->key;
      else
***************
*** 254,265 ****
  }
  
  
! void       *hashIteratorCurrentVal (struct hashtable_iterator *I) {
    if(!I->bucket_i) 
      return NULL;
    else {
!     struct hashtable_entry *entry = ((struct hashtable_entry *)
! 				     listIteratorCurrent(I->bucket_i));
      if(entry)
        return entry->val;
      else
--- 272,282 ----
  }
  
  
! void       *hashIteratorCurrentVal (HASH_ITERATOR *I) {
    if(!I->bucket_i) 
      return NULL;
    else {
!     HASH_ENTRY *entry = ((HASH_ENTRY *) listIteratorCurrent(I->bucket_i));
      if(entry)
        return entry->val;
      else
diff -crN nakedmudv1.5/src/hashtable.d nakedmudv2.0/src/hashtable.d
*** nakedmudv1.5/src/hashtable.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/hashtable.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ hashtable.d hashtable.o: hashtable.c list.h hashtable.h
diff -crN nakedmudv1.5/src/hashtable.h nakedmudv2.0/src/hashtable.h
*** nakedmudv1.5/src/hashtable.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/hashtable.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 9,31 ****
  //
  //*****************************************************************************
  
! struct hashtable *newHashtable(int num_buckets);
! void  deleteHashtable(struct hashtable *table);
  
! int   hashPut    (struct hashtable *table, const char *key, void *val);
! void *hashGet    (struct hashtable *table, const char *key);
! void *hashRemove (struct hashtable *table, const char *key);
! int   hashIn     (struct hashtable *table, const char *key);
! int   hashSize   (struct hashtable *table);
! 
! 
! struct hashtable_iterator *newHashIterator(struct hashtable *table);
! void        deleteHashIterator     (struct hashtable_iterator *I);
! 
! void        hashIteratorReset      (struct hashtable_iterator *I);
! void        hashIteratorNext       (struct hashtable_iterator *I);
! const char *hashIteratorCurrentKey (struct hashtable_iterator *I);
! void       *hashIteratorCurrentVal (struct hashtable_iterator *I);
  
  
  #endif // __HASHTABLE_H
--- 9,34 ----
  //
  //*****************************************************************************
  
! typedef struct hashtable                  HASHTABLE;
! typedef struct hashtable_iterator         HASH_ITERATOR;
  
! 
! HASHTABLE *newHashtable(int num_buckets);
! void  deleteHashtable(HASHTABLE *table);
! 
! int   hashPut    (HASHTABLE *table, const char *key, void *val);
! void *hashGet    (HASHTABLE *table, const char *key);
! void *hashRemove (HASHTABLE *table, const char *key);
! int   hashIn     (HASHTABLE *table, const char *key);
! int   hashSize   (HASHTABLE *table);
! 
! HASH_ITERATOR *newHashIterator     (HASHTABLE *table);
! void        deleteHashIterator     (HASH_ITERATOR *I);
! 
! void        hashIteratorReset      (HASH_ITERATOR *I);
! void        hashIteratorNext       (HASH_ITERATOR *I);
! const char *hashIteratorCurrentKey (HASH_ITERATOR *I);
! void       *hashIteratorCurrentVal (HASH_ITERATOR *I);
  
  
  #endif // __HASHTABLE_H
Binary files nakedmudv1.5/src/help/.DS_Store and nakedmudv2.0/src/help/.DS_Store differ
diff -crN nakedmudv1.5/src/help/help.c nakedmudv2.0/src/help/help.c
*** nakedmudv1.5/src/help/help.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/help/help.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 13,18 ****
--- 13,20 ----
  #include "../character.h"
  #include "../socket.h"
  
+ #include "../editor/editor.h"
+ 
  #include "help.h"
  
  
***************
*** 329,336 ****
      if(*ptr == '_') *ptr = ' ';
  
    HELP_DATA *data = get_help_data(arg, FALSE);
!   start_notepad(charGetSocket(ch), (data ? data->info : ""), 
! 		MAX_BUFFER, EDITOR_MODE_NORMAL);
  }
  
  
--- 331,339 ----
      if(*ptr == '_') *ptr = ' ';
  
    HELP_DATA *data = get_help_data(arg, FALSE);
! 
!   socketSetNotepad(charGetSocket(ch), (data ? data->info : ""));
!   socketStartNotepad(charGetSocket(ch));
  }
  
  
***************
*** 342,349 ****
      send_to_char(ch, "Which helpfile were you trying to update?\r\n");
      return;
    }
!   if(!charGetSocket(ch) || !charGetSocket(ch)->notepad || 
!      !*charGetSocket(ch)->notepad) {
      send_to_char(ch, "You have nothing in your notepad! Try writing something.\r\n");
      return;
    }
--- 345,351 ----
      send_to_char(ch, "Which helpfile were you trying to update?\r\n");
      return;
    }
!   if(!charGetSocket(ch) || !*socketGetNotepad(charGetSocket(ch))) {
      send_to_char(ch, "You have nothing in your notepad! Try writing something.\r\n");
      return;
    }
***************
*** 354,360 ****
    for(ptr = arg; *ptr; ptr++)
      if(*ptr == '_') *ptr = ' ';
  
!   update_help(charGetName(ch), arg, charGetSocket(ch)->notepad);
  }
  
  
--- 356,362 ----
    for(ptr = arg; *ptr; ptr++)
      if(*ptr == '_') *ptr = ' ';
  
!   update_help(charGetName(ch), arg, socketGetNotepad(charGetSocket(ch)));
  }
  
  
diff -crN nakedmudv1.5/src/help/help.d nakedmudv2.0/src/help/help.d
*** nakedmudv1.5/src/help/help.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/help/help.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ help/help.d help/help.o: help/help.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h storage.h character.h \
+   socket.h editor/editor.h help/help.h
diff -crN nakedmudv1.5/src/inform.c nakedmudv2.0/src/inform.c
*** nakedmudv1.5/src/inform.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/inform.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 18,35 ****
  #include "utils.h"
  #include "body.h"
  #include "races.h"
- #include "items.h"
  #include "handler.h"
  #include "socket.h"
  #include "inform.h"
  #include "log.h"
  
  // optional module headers
  #ifdef MODULE_TIME
  #include "time/mudtime.h"
  #endif
  
  
  //*****************************************************************************
  //
  // local functions
--- 18,49 ----
  #include "utils.h"
  #include "body.h"
  #include "races.h"
  #include "handler.h"
  #include "socket.h"
  #include "inform.h"
  #include "log.h"
  
+ 
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "items/items.h"
+ #include "items/portal.h"
+ #include "items/container.h"
+ #include "items/furniture.h"
+ 
+ 
+ 
+ //*****************************************************************************
  // optional module headers
+ //*****************************************************************************
  #ifdef MODULE_TIME
  #include "time/mudtime.h"
  #endif
  
  
+ 
  //*****************************************************************************
  //
  // local functions
***************
*** 46,52 ****
    char *chars = print_list(can_see, charGetName, charGetMultiName);
    if(*chars) send_to_char(ch, "%s %s %s %s%s.\r\n",
  			  chars, (listSize(can_see) == 1 ? "is" : "are"),
! 			  (objGetSubtype(furniture) == FURNITURE_AT ?"at":"on"),
  			  objGetName(furniture),
  			  (charGetFurniture(ch) == furniture ?" with you": ""));
    // everyone was invisible to us... we should still show the furniture though
--- 60,66 ----
    char *chars = print_list(can_see, charGetName, charGetMultiName);
    if(*chars) send_to_char(ch, "%s %s %s %s%s.\r\n",
  			  chars, (listSize(can_see) == 1 ? "is" : "are"),
! 			  (furnitureGetType(furniture)==FURNITURE_AT?"at":"on"),
  			  objGetName(furniture),
  			  (charGetFurniture(ch) == furniture ?" with you": ""));
    // everyone was invisible to us... we should still show the furniture though
***************
*** 136,142 ****
    free(new_desc);
  
    // list container-related stuff
!   if(objGetType(obj) == ITEM_CONTAINER) {
      send_to_char(ch, "{g%s is %s%s.\r\n",
  		 objGetName(obj), 
  		 (containerIsClosed(obj) ? "closed" : "opened"),
--- 150,156 ----
    free(new_desc);
  
    // list container-related stuff
!   if(objIsType(obj, "container")) {
      send_to_char(ch, "{g%s is %s%s.\r\n",
  		 objGetName(obj), 
  		 (containerIsClosed(obj) ? "closed" : "opened"),
***************
*** 156,162 ****
    }
  
    // list furniture-related stuff
!   else if(objGetType(obj) == ITEM_FURNITURE) {
      int num_sitters = listSize(objGetUsers(obj));
  
      send_to_char(ch, "\r\n");
--- 170,176 ----
    }
  
    // list furniture-related stuff
!   else if(objIsType(obj, "furniture")) {
      int num_sitters = listSize(objGetUsers(obj));
  
      send_to_char(ch, "\r\n");
***************
*** 169,175 ****
        char *chars = print_list(can_see, charGetName, charGetMultiName);
        if(*chars) send_to_char(ch, "{g%s %s %s %s%s.\r\n",
  			      chars, (listSize(can_see) == 1 ? "is" : "are"),
! 			      (objGetSubtype(obj) == FURNITURE_AT ? "at":"on"),
  			      objGetName(obj),
  			      (charGetFurniture(ch) == obj ? " with you" : ""));
        deleteList(can_see);
--- 183,189 ----
        char *chars = print_list(can_see, charGetName, charGetMultiName);
        if(*chars) send_to_char(ch, "{g%s %s %s %s%s.\r\n",
  			      chars, (listSize(can_see) == 1 ? "is" : "are"),
! 			      (furnitureGetType(obj)==FURNITURE_AT ? "at":"on"),
  			      objGetName(obj),
  			      (charGetFurniture(ch) == obj ? " with you" : ""));
        deleteList(can_see);
***************
*** 353,362 ****
  
  
  void text_to_char(CHAR_DATA *ch, const char *txt) {
!   if (txt && *txt && charGetSocket(ch) && 
!       socketGetState(charGetSocket(ch)) == STATE_PLAYING) {
      text_to_buffer(charGetSocket(ch), txt);
!     charGetSocket(ch)->bust_prompt = TRUE;
    }
  
    // if it's a PC or we are not in game, then
--- 367,377 ----
  
  
  void text_to_char(CHAR_DATA *ch, const char *txt) {
!   //  if (txt && *txt && charGetSocket(ch) && 
!   //      socketGetState(charGetSocket(ch)) == STATE_PLAYING) {
!   if(txt && *txt && charGetSocket(ch)) {
      text_to_buffer(charGetSocket(ch), txt);
!     socketBustPrompt(charGetSocket(ch));
    }
  
    // if it's a PC or we are not in game, then
***************
*** 495,512 ****
      // is it an extra description?
      else if(found_type == FOUND_EDESC) {
        // get the set it belongs to
!       EDESC_SET *set = getEdescSet(found);
        // if it belongs to a set, highlight keywords
        if(set) {
  	char *new_edesc = tagEdescs(set,
! 				    getEdescDescription(found),
  				    "{c", "{g");
  	send_to_char(ch, "{g%s", new_edesc);
  	free(new_edesc);
        }
        // otherwise, just show the plain desc
        else
! 	send_to_char(ch, "{g%s", getEdescDescription(found));
      }
  
      // is it an item?
--- 510,527 ----
      // is it an extra description?
      else if(found_type == FOUND_EDESC) {
        // get the set it belongs to
!       EDESC_SET *set = edescGetSet(found);
        // if it belongs to a set, highlight keywords
        if(set) {
  	char *new_edesc = tagEdescs(set,
! 				    edescSetGetDesc(found),
  				    "{c", "{g");
  	send_to_char(ch, "{g%s", new_edesc);
  	free(new_edesc);
        }
        // otherwise, just show the plain desc
        else
! 	send_to_char(ch, "{g%s", edescSetGetDesc(found));
      }
  
      // is it an item?
***************
*** 516,533 ****
      // is it something inside of an object?
      else if(found_type == FOUND_IN_OBJ) {
        // show the destination we're peering at
!       if(objGetType(found) == ITEM_PORTAL) {
! 	ROOM_DATA *dest = worldGetRoom(gameworld, objGetVal(found, 0));
  	if(dest) {
! 	  send_to_char(ch, "You peer inside the portal.\r\n");
  	  look_at_room(ch, dest);
  	}
  	else
  	  send_to_char(ch, 
! 		       "The portal is murky, and you cannot "
! 		       "make out anything on the other side.\r\n");
        }
!       else if(objGetType(found) != ITEM_CONTAINER)
  	send_to_char(ch, "%s is not a container or portal.\r\n",
  		     objGetName(found));
        else if(containerIsClosed(found))
--- 531,549 ----
      // is it something inside of an object?
      else if(found_type == FOUND_IN_OBJ) {
        // show the destination we're peering at
!       if(objIsType(found, "portal")) {
! 	ROOM_DATA *dest = worldGetRoom(gameworld, portalGetDest(found));
  	if(dest) {
! 	  send_to_char(ch, "You peer inside %s.\r\n", see_obj_as(ch, found));
  	  look_at_room(ch, dest);
  	}
  	else
  	  send_to_char(ch, 
! 		       "%s is murky, and you cannot "
! 		       "make out anything on the other side.\r\n",
! 		       see_obj_as(ch, found));
        }
!       else if(!objIsType(found, "container"))
  	send_to_char(ch, "%s is not a container or portal.\r\n",
  		     objGetName(found));
        else if(containerIsClosed(found))
***************
*** 597,603 ****
  {
    CHAR_DATA *plr;
    SOCKET_DATA *dsock;
!   BUFFER *buf = buffer_new(MAX_BUFFER);
    LIST_ITERATOR *sock_i = newListIterator(socket_list);
    int socket_count = 0, playing_count = 0;
  
--- 613,619 ----
  {
    CHAR_DATA *plr;
    SOCKET_DATA *dsock;
!   BUFFER *buf = newBuffer(MAX_BUFFER);
    LIST_ITERATOR *sock_i = newListIterator(socket_list);
    int socket_count = 0, playing_count = 0;
  
***************
*** 608,629 ****
  
    ITERATE_LIST(dsock, sock_i) {
      socket_count++;
!     if (dsock->state != STATE_PLAYING) continue;
!     if ((plr = dsock->player) == NULL) continue;
      playing_count++;
      bprintf(buf, "{y%-8s %-3s  {g)  {c%-12s {b%26s\r\n", 
  	    (charGetLevel(plr) == LEVEL_PLAYER ? "player" :
  	     (charGetLevel(plr) == LEVEL_BUILDER  ? "builder" :
  	      (charGetLevel(plr) == LEVEL_SCRIPTER    ? "scripter" : "admin"))),
  	    raceGetAbbrev(charGetRace(plr)),
! 	    charGetName(plr), dsock->hostname);
    }
  
    bprintf(buf, "\r\n{g%d character%s connected. %d playing.\r\n",
  	  socket_count, (socket_count == 1 ? "" : "s"), playing_count);
!   page_string(charGetSocket(ch), buf->data);
    //  send_to_char(ch, buf->data);
!   buffer_free(buf);
    deleteListIterator(sock_i);
  }
  
--- 624,645 ----
  
    ITERATE_LIST(dsock, sock_i) {
      socket_count++;
!     //    if (dsock->state != STATE_PLAYING) continue;
!     if ((plr = socketGetChar(dsock)) == NULL) continue;
      playing_count++;
      bprintf(buf, "{y%-8s %-3s  {g)  {c%-12s {b%26s\r\n", 
  	    (charGetLevel(plr) == LEVEL_PLAYER ? "player" :
  	     (charGetLevel(plr) == LEVEL_BUILDER  ? "builder" :
  	      (charGetLevel(plr) == LEVEL_SCRIPTER    ? "scripter" : "admin"))),
  	    raceGetAbbrev(charGetRace(plr)),
! 	    charGetName(plr), socketGetHostname(dsock));
    }
  
    bprintf(buf, "\r\n{g%d character%s connected. %d playing.\r\n",
  	  socket_count, (socket_count == 1 ? "" : "s"), playing_count);
!   page_string(charGetSocket(ch), bufferString(buf));
    //  send_to_char(ch, buf->data);
!   deleteBuffer(buf);
    deleteListIterator(sock_i);
  }
  
***************
*** 738,745 ****
        case '$':
  	buf[j] = '$';
  	j++;
        default:
! 	// do nothing ...
  	break;
        }
      }
--- 754,762 ----
        case '$':
  	buf[j] = '$';
  	j++;
+ 	break;
        default:
! 	// do nothing
  	break;
        }
      }
diff -crN nakedmudv1.5/src/inform.d nakedmudv2.0/src/inform.d
*** nakedmudv1.5/src/inform.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/inform.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,5 ----
+ inform.d inform.o: inform.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h character.h object.h world.h \
+   room.h exit.h extra_descs.h utils.h body.h races.h handler.h socket.h \
+   inform.h log.h items/items.h items/portal.h items/container.h \
+   items/furniture.h time/mudtime.h
diff -crN nakedmudv1.5/src/interpret.c nakedmudv2.0/src/interpret.c
*** nakedmudv1.5/src/interpret.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/interpret.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 14,26 ****
  #include "commands.h"
  #include "action.h"
  
  // optional modules
  #ifdef MODULE_FACULTY
  #include "faculty/faculty.h"
  #endif
- #ifdef MODULE_SCRIPTS
- #include "scripts/script.h"
- #endif
  #ifdef MODULE_ALIAS
  #include "alias/alias.h"
  #endif
--- 14,34 ----
  #include "commands.h"
  #include "action.h"
  
+ 
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "scripts/script.h"
+ 
+ 
+ 
+ //*****************************************************************************
  // optional modules
+ //*****************************************************************************
  #ifdef MODULE_FACULTY
  #include "faculty/faculty.h"
  #endif
  #ifdef MODULE_ALIAS
  #include "alias/alias.h"
  #endif
***************
*** 87,99 ****
  	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("ask",        NULL, cmd_ask,      0, POS_SITTING,  POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
  
    // B
    add_cmd("back",       NULL, cmd_back,     0, POS_UNCONCIOUS, POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("buildwalk",  NULL, cmd_tog_prf,  PRF_BUILDWALK, 
  	  POS_UNCONCIOUS, POS_FLYING, LEVEL_BUILDER, FALSE, FALSE);
! 
  
    // C
    add_cmd("chat",       NULL, cmd_chat,     0, POS_UNCONCIOUS, POS_FLYING,
--- 95,112 ----
  	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("ask",        NULL, cmd_ask,      0, POS_SITTING,  POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
+   add_cmd("at",         NULL, cmd_at,       0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, TRUE, FALSE);
  
    // B
    add_cmd("back",       NULL, cmd_back,     0, POS_UNCONCIOUS, POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
+   add_cmd("buildwalk",  NULL, cmd_buildwalk, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, FALSE);
+   /*
    add_cmd("buildwalk",  NULL, cmd_tog_prf,  PRF_BUILDWALK, 
  	  POS_UNCONCIOUS, POS_FLYING, LEVEL_BUILDER, FALSE, FALSE);
!   */
  
    // C
    add_cmd("chat",       NULL, cmd_chat,     0, POS_UNCONCIOUS, POS_FLYING,
***************
*** 120,127 ****
  	  LEVEL_PLAYER, TRUE, TRUE );
  
    // E
-   add_cmd("enter",      NULL, cmd_enter,    0, POS_STANDING, POS_FLYING,
- 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("emote",      NULL, cmd_emote,    0, POS_SITTING,  POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd(":",          NULL, cmd_emote,    0, POS_SITTING,  POS_FLYING,
--- 133,138 ----
***************
*** 149,158 ****
    add_cmd("goto",       NULL, cmd_goto,     0, POS_STANDING, POS_FLYING,
  	  LEVEL_BUILDER, FALSE, TRUE );
  
-   // H
-   //  add_cmd("help",       NULL, cmd_help,     0, POS_UNCONCIOUS, POS_FLYING,
-   //	  LEVEL_PLAYER, TRUE, FALSE);
- 
    // I
    add_cmd("inventory",  NULL, cmd_inventory,0, POS_SITTING,  POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
--- 160,165 ----
***************
*** 172,179 ****
  	  LEVEL_ADMIN, FALSE, FALSE);
  
    // M
-   add_cmd("mapwalk",    NULL, cmd_tog_prf,  PRF_MAPWALK,
- 	  POS_UNCONCIOUS, POS_FLYING, LEVEL_PLAYER, FALSE, FALSE);
    add_cmd("mlist",      NULL, cmd_mlist,    0, POS_UNCONCIOUS, POS_FLYING,
  	  LEVEL_BUILDER, FALSE, FALSE);
    add_cmd("more",       NULL, cmd_more,     0, POS_UNCONCIOUS, POS_FLYING,
--- 179,184 ----
***************
*** 186,193 ****
  	  LEVEL_PLAYER, TRUE, TRUE );
  
    // P
!   add_cmd("put",        NULL, cmd_put,      0, POS_SITTING,  POS_FLYING,
  	  LEVEL_PLAYER, TRUE,  TRUE );
    add_cmd("purge",      NULL, cmd_purge,    0, POS_SITTING,  POS_FLYING,
  	  LEVEL_BUILDER, FALSE, FALSE);
    
--- 191,200 ----
  	  LEVEL_PLAYER, TRUE, TRUE );
  
    // P
!   add_cmd("put",        "p", cmd_put,       0, POS_SITTING,  POS_FLYING,
  	  LEVEL_PLAYER, TRUE,  TRUE );
+   add_cmd("page",       NULL, cmd_page,     0, POS_SITTING,  POS_FLYING,
+ 	  LEVEL_BUILDER, TRUE, FALSE);
    add_cmd("purge",      NULL, cmd_purge,    0, POS_SITTING,  POS_FLYING,
  	  LEVEL_BUILDER, FALSE, FALSE);
    
***************
*** 200,205 ****
--- 207,214 ----
  	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("rlist",      NULL, cmd_rlist,    0, POS_UNCONCIOUS, POS_FLYING,
  	  LEVEL_BUILDER, FALSE, FALSE);
+   add_cmd("repeat",     NULL, cmd_repeat,   0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_ADMIN, FALSE, FALSE);
  
    // S
    add_cmd("say",        NULL, cmd_say,      0, POS_SITTING,  POS_FLYING,
***************
*** 218,230 ****
  	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("stop",       NULL, cmd_stop,     0, POS_SITTING, POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
- #ifdef MODULE_SCRIPTS
    // really, we -should- put this in the scripts module, but there are some
    // very nice functions in builder.c that cmd_sclist uses to print scripts,
    // which wouldn't be accessable from outside of builder.c
    add_cmd("sclist",     NULL, cmd_sclist,   0, POS_UNCONCIOUS, POS_FLYING,
  	  LEVEL_BUILDER, FALSE, FALSE);
- #endif
  
    // T
    add_cmd("take",       NULL, cmd_get,      0, POS_SITTING,  POS_FLYING,
--- 227,237 ----
***************
*** 253,260 ****
  	  LEVEL_BUILDER, FALSE, FALSE);
    add_cmd("worn",       NULL, cmd_equipment,0, POS_SITTING,  POS_FLYING,
  	  LEVEL_PLAYER, TRUE, FALSE);
-   add_cmd("write",      NULL, cmd_write,    0, POS_SITTING, POS_FLYING,
- 	  LEVEL_PLAYER, TRUE, TRUE);
  
    // Z
    add_cmd("zlist",      NULL, cmd_zlist,    0, POS_SITTING,  POS_FLYING,
--- 260,265 ----
***************
*** 299,304 ****
--- 304,316 ----
  }
  
  //
+ // return TRUE if the command already exists.
+ //
+ bool cmd_exists(const char *cmd) {
+   return (find_cmd(cmd, FALSE) != NULL);
+ }
+ 
+ //
  // remove (and delete) a command
  //
  void remove_cmd(const char *cmd) {
***************
*** 335,341 ****
  
  // show the character all of the commands he or she can perform
  void show_commands(CHAR_DATA *ch, int min_lev, int max_lev) {
!   BUFFER *buf = buffer_new(MAX_BUFFER);
    int i, col = 0;
  
    // go over all of our buckets
--- 347,353 ----
  
  // show the character all of the commands he or she can perform
  void show_commands(CHAR_DATA *ch, int min_lev, int max_lev) {
!   BUFFER *buf = newBuffer(MAX_BUFFER);
    int i, col = 0;
  
    // go over all of our buckets
***************
*** 348,361 ****
  	continue;
        bprintf(buf, "%-20.20s", cmd->cmd_name);
        if (!(++col % 4))
! 	bprintf(buf, "\r\n");      
      }
      deleteListIterator(buck_i);
    }
  
    if (col % 4) bprintf(buf, "\r\n");
!   text_to_char(ch, buf->data);
!   buffer_free(buf);
  }
  
  
--- 360,373 ----
  	continue;
        bprintf(buf, "%-20.20s", cmd->cmd_name);
        if (!(++col % 4))
! 	bufferCat(buf, "\r\n");
      }
      deleteListIterator(buck_i);
    }
  
    if (col % 4) bprintf(buf, "\r\n");
!   text_to_char(ch, bufferString(buf));
!   deleteBuffer(buf);
  }
  
  
***************
*** 433,439 ****
  
  void handle_cmd_input(SOCKET_DATA *dsock, char *arg) {
    CHAR_DATA *ch;
!   if ((ch = dsock->player) == NULL)
      return;
    do_cmd(ch, arg, TRUE, TRUE);
  }
--- 445,451 ----
  
  void handle_cmd_input(SOCKET_DATA *dsock, char *arg) {
    CHAR_DATA *ch;
!   if ((ch = socketGetChar(dsock)) == NULL)
      return;
    do_cmd(ch, arg, TRUE, TRUE);
  }
***************
*** 480,489 ****
  
    // if we've got a command script, and we're not supposed
    // to follow through with our normal command, return out
- #ifdef MODULE_SCRIPTS
    if(scripts_ok && try_command_script(ch, command, arg))
      return;
- #endif
  
  
    // iterate over the commands that would be in our 
--- 492,499 ----
diff -crN nakedmudv1.5/src/interpret.d nakedmudv2.0/src/interpret.d
*** nakedmudv1.5/src/interpret.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/interpret.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ interpret.d interpret.o: interpret.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h character.h socket.h \
+   room.h movement.h commands.h action.h scripts/script.h alias/alias.h
diff -crN nakedmudv1.5/src/io.d nakedmudv2.0/src/io.d
*** nakedmudv1.5/src/io.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/io.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ io.d io.o: io.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h utils.h
diff -crN nakedmudv1.5/src/items/container.c nakedmudv2.0/src/items/container.c
*** nakedmudv1.5/src/items/container.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/container.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,238 ----
+ //*****************************************************************************
+ //
+ // container.c
+ //
+ // handles all of the functioning of the container item type. Stores data about 
+ // the contents and capacity of a container, and all the functions for 
+ // interacting with container types.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../storage.h"
+ #include "../object.h"
+ #include "../world.h"
+ #include "../socket.h"
+ #include "../olc2/olc.h"
+ 
+ #include "items.h"
+ #include "iedit.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // item data for containers
+ //*****************************************************************************
+ typedef struct container_data {
+   double capacity;
+   int    key;
+   int    pick_diff;
+   bool   closable;
+   bool   closed;
+   bool   locked;
+ } CONTAINER_DATA;
+ 
+ CONTAINER_DATA *newContainerData() {
+   CONTAINER_DATA *data = malloc(sizeof(CONTAINER_DATA));
+   data->capacity  = 0;
+   data->key       = NOTHING;
+   data->pick_diff = 0;
+   data->closed    = FALSE;
+   data->locked    = FALSE;
+   return data;
+ }
+ 
+ void deleteContainerData(CONTAINER_DATA *data) {
+   free(data);
+ }
+ 
+ void containerDataCopyTo(CONTAINER_DATA *from, CONTAINER_DATA *to) {
+   *to = *from;
+ }
+ 
+ CONTAINER_DATA *containerDataCopy(CONTAINER_DATA *data) {
+   CONTAINER_DATA *new_data = newContainerData();
+   containerDataCopyTo(data, new_data);
+   return new_data;
+ }
+ 
+ STORAGE_SET *containerDataStore(CONTAINER_DATA *data) {
+   STORAGE_SET *set = new_storage_set();
+   store_double(set, "capacity", data->capacity);
+   store_int   (set, "key",      data->key);
+   store_int   (set, "pick_diff",data->pick_diff);
+   store_int   (set, "closable", data->closable);
+   store_int   (set, "closed",   data->closed);
+   store_int   (set, "locked",   data->locked);
+   return set;
+ }
+ 
+ CONTAINER_DATA *containerDataRead(STORAGE_SET *set) {
+   CONTAINER_DATA *data = newContainerData();
+   data->capacity = read_double(set, "capacity");
+   data->key      = read_int   (set, "key");
+   data->pick_diff= read_int   (set, "pick_diff");
+   data->closable = read_int   (set, "closable");
+   data->closed   = read_int   (set, "closed");
+   data->locked   = read_int   (set, "locked");
+   return data;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for interacting with containers
+ //*****************************************************************************
+ double containerGetCapacity(OBJ_DATA *obj) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   return data->capacity;
+ }
+ 
+ void containerSetCapacity(OBJ_DATA *obj, double capacity) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   data->capacity = capacity;
+ }
+ 
+ bool containerIsClosable (OBJ_DATA *obj) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   return data->closable;
+ }
+ 
+ bool containerIsClosed   (OBJ_DATA *obj) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   return data->closed;
+ }
+ 
+ bool containerIsLocked   (OBJ_DATA *obj) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   return data->locked;
+ }
+ 
+ int  containerGetKey     (OBJ_DATA *obj) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   return data->key;
+ }
+ 
+ int  containerGetPicKDiff(OBJ_DATA *obj) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   return data->pick_diff;
+ }
+ 
+ void containerSetClosed  (OBJ_DATA *obj, bool closed) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   data->closed = closed;
+ }
+ 
+ void   containerSetClosable(OBJ_DATA *obj, bool closable) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   data->closable = closable;
+ }
+ 
+ void containerSetLocked  (OBJ_DATA *obj, bool locked) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   data->locked = locked;
+ }
+ 
+ void containerSetKey     (OBJ_DATA *obj, int  vnum) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   data->key = vnum;
+ }
+ 
+ void containerSetPickDiff(OBJ_DATA *obj, int  diff) {
+   CONTAINER_DATA *data = objGetTypeData(obj, "container");
+   data->pick_diff = diff;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // container olc
+ //*****************************************************************************
+ #define IEDIT_CONTAINER_CAPACITY      1
+ #define IEDIT_CONTAINER_KEY           2
+ #define IEDIT_CONTAINER_PICK_DIFF     3
+ 
+ // the resedit olc needs these declared
+ void iedit_container_menu   (SOCKET_DATA *sock, CONTAINER_DATA *data) {
+   send_to_socket(sock, 
+ 		 "{g1) Capacity : {c%1.2lf\r\n"
+ 		 "{g2) Key      : {c%d (%s)\r\n"
+ 		 "{g3) Closable : {c%s\r\n"
+ 		 "{g4) Pick diff: {c%d\r\n",
+ 		 data->capacity,
+ 		 data->key, 
+ 		 (worldGetObj(gameworld, data->key) ? 
+ 		  objGetName(worldGetObj(gameworld, data->key)) : "nothing"),
+ 		 (data->closable ? "yes" : "no"),
+ 		 data->pick_diff);
+ }
+ 
+ int  iedit_container_chooser(SOCKET_DATA *sock, CONTAINER_DATA *data, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter a new weight capacity for the container: ");
+     return IEDIT_CONTAINER_CAPACITY;
+   case '2':
+     text_to_buffer(sock, "Enter akey vnum for the container (-1 for none): ");
+     return IEDIT_CONTAINER_KEY;
+   case '3':
+     data->closable = (data->closable + 1) % 2;
+     return MENU_NOCHOICE;
+   case '4':
+     text_to_buffer(sock, "How difficult is the lock to pick: ");
+     return IEDIT_CONTAINER_PICK_DIFF;
+   default: return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool iedit_container_parser (SOCKET_DATA *sock, CONTAINER_DATA *data, int choice, 
+ 			  const char *arg) {
+   switch(choice) {
+   case IEDIT_CONTAINER_CAPACITY: {
+     double capacity = atof(arg);
+     if(capacity <= 0)
+       return FALSE;
+     data->capacity = capacity;
+     return TRUE;
+   }
+   case IEDIT_CONTAINER_KEY: {
+     int key = atoi(arg);
+     // ugh... ugly logic. Clean this up one day?
+     //   Make sure what we're getting is a positive number or make sure it is
+     //   the NOTHING number (-1). Also make sure that, if it's not NOTHING, it
+     //   corresponds to a vnum of an object already created.
+     if((key != NOTHING && !worldGetObj(gameworld, key)) ||
+        (key != NOTHING && !isdigit(*arg)))
+       return FALSE;
+     data->key = key;
+     return TRUE;
+   }
+   case IEDIT_CONTAINER_PICK_DIFF: {
+     int diff = atoi(arg);
+     if(diff < 0 || !isdigit(*arg))
+       return FALSE;
+     data->pick_diff = diff;
+     return TRUE;
+   }
+   default: return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // install the container item type
+ //*****************************************************************************
+ 
+ //
+ // this will need to be called by init_items() in items/items.c
+ void init_container(void) {
+   item_add_type("container", 
+   		newContainerData, deleteContainerData,
+   		containerDataCopyTo, containerDataCopy, 
+   		containerDataStore, containerDataRead);
+ 
+   // set up the container OLC too
+   item_add_olc("container", iedit_container_menu, iedit_container_chooser, 
+   	       iedit_container_parser);
+ }
diff -crN nakedmudv1.5/src/items/container.d nakedmudv2.0/src/items/container.d
*** nakedmudv1.5/src/items/container.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/container.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ items/container.d items/container.o: items/container.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h storage.h object.h world.h \
+   socket.h olc2/olc.h items/items.h items/iedit.h
diff -crN nakedmudv1.5/src/items/container.h nakedmudv2.0/src/items/container.h
*** nakedmudv1.5/src/items/container.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/container.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,26 ----
+ #ifndef CONTAINER_H
+ #define CONTAINER_H
+ //*****************************************************************************
+ //
+ // container.h
+ //
+ // handles all of the functioning of the container item type. Stores data about 
+ // the contents and capacity of a container, and all the functions for 
+ // interacting with container types.
+ //
+ //*****************************************************************************
+ 
+ double containerGetCapacity(OBJ_DATA *obj);
+ bool   containerIsClosable (OBJ_DATA *obj);
+ bool   containerIsClosed   (OBJ_DATA *obj);
+ bool   containerIsLocked   (OBJ_DATA *obj);
+ int    containerGetKey     (OBJ_DATA *obj);
+ int    containerGetPicKDiff(OBJ_DATA *obj);
+ void   containerSetCapacity(OBJ_DATA *obj, double capacity);
+ void   containerSetClosed  (OBJ_DATA *obj, bool closed);
+ void   containerSetClosable(OBJ_DATA *obj, bool closable);
+ void   containerSetLocked  (OBJ_DATA *obj, bool locked);
+ void   containerSetKey     (OBJ_DATA *obj, int  vnum);
+ void   containerSetPickDiff(OBJ_DATA *obj, int  diff);
+ 
+ #endif // CONTAINER_H
diff -crN nakedmudv1.5/src/items/furniture.c nakedmudv2.0/src/items/furniture.c
*** nakedmudv1.5/src/items/furniture.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/furniture.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,175 ----
+ //*****************************************************************************
+ //
+ // furniture.c
+ //
+ // handles all of the functioning of the furniture item type. Stores data about 
+ // the capacity of the furniture, and what type of furniture it is. 
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../storage.h"
+ #include "../object.h"
+ #include "../world.h"
+ #include "../socket.h"
+ #include "../olc2/olc.h"
+ 
+ #include "items.h"
+ #include "iedit.h"
+ #include "furniture.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // item data for furnitures
+ //*****************************************************************************
+ typedef struct furniture_data {
+   int capacity;
+   int type;
+ } FURNITURE_DATA;
+ 
+ FURNITURE_DATA *newFurnitureData() {
+   FURNITURE_DATA *data = malloc(sizeof(FURNITURE_DATA));
+   data->capacity  = 0;
+   data->type      = FURNITURE_AT;
+   return data;
+ }
+ 
+ void deleteFurnitureData(FURNITURE_DATA *data) {
+   free(data);
+ }
+ 
+ void furnitureDataCopyTo(FURNITURE_DATA *from, FURNITURE_DATA *to) {
+   *to = *from;
+ }
+ 
+ FURNITURE_DATA *furnitureDataCopy(FURNITURE_DATA *data) {
+   FURNITURE_DATA *new_data = newFurnitureData();
+   furnitureDataCopyTo(data, new_data);
+   return new_data;
+ }
+ 
+ STORAGE_SET *furnitureDataStore(FURNITURE_DATA *data) {
+   STORAGE_SET *set = new_storage_set();
+   store_int(set, "capacity", data->capacity);
+   store_int(set, "type",     data->type);
+   return set;
+ }
+ 
+ FURNITURE_DATA *furnitureDataRead(STORAGE_SET *set) {
+   FURNITURE_DATA *data = newFurnitureData();
+   data->capacity = read_int(set, "capacity");
+   data->type     = read_int(set, "type");
+   return data;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for interacting with furnitures
+ //*****************************************************************************
+ int furnitureGetCapacity(OBJ_DATA *obj) {
+   FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
+   return data->capacity;
+ }
+ 
+ void furnitureSetCapacity(OBJ_DATA *obj, int capacity) {
+   FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
+   data->capacity = capacity;
+ }
+ 
+ int furnitureGetType(OBJ_DATA *obj) {
+   FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
+   return data->type;
+ }  
+ 
+ void furnitureSetType(OBJ_DATA *obj, int type) {
+   FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
+   data->type = type;
+ }  
+ 
+ const char *furniture_names[NUM_FURNITURES] = {
+   "table furniture",
+   "sitting furniture"
+ };
+ 
+ const char *furnitureTypeGetName(int type) {
+   return furniture_names[type];
+ }
+ 
+ int furnitureTypeGetNum(const char *type) {
+   int i;
+   for(i = 0; i < NUM_FURNITURES; i++)
+     if(!strcasecmp(furniture_names[i], type))
+       return i;
+   return FURNITURE_NONE;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // furniture olc
+ //*****************************************************************************
+ #define IEDIT_FURNITURE_CAPACITY      1
+ #define IEDIT_FURNITURE_TYPE          2
+ 
+ // the resedit olc needs these declared
+ void iedit_furniture_menu(SOCKET_DATA *sock, FURNITURE_DATA *data) {
+   send_to_socket(sock, 
+ 		 "{g1) Capacity : {c%d\r\n"
+ 		 "{g2) Type     : {y[{c%s{y]\r\n",
+ 		 data->capacity,
+ 		 furnitureTypeGetName(data->type));
+ }
+ 
+ int  iedit_furniture_chooser(SOCKET_DATA *sock, FURNITURE_DATA *data, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter a new weight capacity for the furniture: ");
+     return IEDIT_FURNITURE_CAPACITY;
+   case '2':
+     olc_display_table(sock, furnitureTypeGetName, NUM_FURNITURES, 1);
+     return IEDIT_FURNITURE_TYPE;
+   default: return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool iedit_furniture_parser (SOCKET_DATA *sock, FURNITURE_DATA *data, int choice, 
+ 			  const char *arg) {
+   switch(choice) {
+   case IEDIT_FURNITURE_CAPACITY: {
+     int capacity = atoi(arg);
+     if(capacity <= 0)
+       return FALSE;
+     data->capacity = capacity;
+     return TRUE;
+   }
+   case IEDIT_FURNITURE_TYPE: {
+     int type = atoi(arg);
+     if(type < 0 || type >= NUM_FURNITURES || !isdigit(*arg))
+       return FALSE;
+     data->type = type;
+     return TRUE;
+   }
+   default: return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // install the furniture item type
+ //*****************************************************************************
+ 
+ //
+ // this will need to be called by init_items() in items/items.c
+ void init_furniture(void) {
+   item_add_type("furniture", 
+   		newFurnitureData, deleteFurnitureData,
+   		furnitureDataCopyTo, furnitureDataCopy, 
+   		furnitureDataStore, furnitureDataRead);
+ 
+   // set up the furniture OLC too
+   item_add_olc("furniture", iedit_furniture_menu, iedit_furniture_chooser, 
+   	       iedit_furniture_parser);
+ }
diff -crN nakedmudv1.5/src/items/furniture.d nakedmudv2.0/src/items/furniture.d
*** nakedmudv1.5/src/items/furniture.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/furniture.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ items/furniture.d items/furniture.o: items/furniture.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h storage.h object.h world.h \
+   socket.h olc2/olc.h items/items.h items/iedit.h items/furniture.h
diff -crN nakedmudv1.5/src/items/furniture.h nakedmudv2.0/src/items/furniture.h
*** nakedmudv1.5/src/items/furniture.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/furniture.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,25 ----
+ #ifndef FURNITURE_H
+ #define FURNITURE_H
+ //*****************************************************************************
+ //
+ // furniture.h
+ //
+ // handles all of the functioning of the furniture item type. Stores data about 
+ // the capacity of the furniture, and what type of furniture it is. 
+ //
+ //*****************************************************************************
+ 
+ #define FURNITURE_NONE       -1
+ #define FURNITURE_AT          0
+ #define FURNITURE_ON          1
+ #define NUM_FURNITURES        2
+ 
+ int  furnitureGetCapacity(OBJ_DATA *obj);
+ void furnitureSetCapacity(OBJ_DATA *obj, int capacity);
+ int  furnitureGetType(OBJ_DATA *obj);
+ void furnitureSetType(OBJ_DATA *obj, int type);
+ 
+ const char *furnitureTypeGetName(int type);
+ int  furnitureTypeGetNum(const char *type);
+ 
+ #endif // FURNITURE_H
diff -crN nakedmudv1.5/src/items/iedit.c nakedmudv2.0/src/items/iedit.c
*** nakedmudv1.5/src/items/iedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/iedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,146 ----
+ //*****************************************************************************
+ //
+ // iedit.c
+ //
+ // Although it is not core to the functioning of items, we will more likely
+ // than not want to be able to edit their type information in OLC. This will
+ // require a parser, a chooser, and a menu for editing the type information.
+ // Item types can add in their OLC functions via this framework. iedit uses
+ // the OLC2 framework. For more detailed instructions on how to set up an OLC,
+ // users should refer to the OLC2 source headers.
+ //
+ // NOTE: the menu, chooser, and parser should only take the item-specific data,
+ //       and not the WHOLE object! It has been set up this way to encourage
+ //       people to localize all of the data associated with one item type.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "items.h"
+ #include "iedit.h"
+ 
+ #include "../olc2/olc.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // local functions, variables, and datastructures
+ //*****************************************************************************
+ 
+ //
+ // how many buckets will be in our item_olc_table? This should be about 120%
+ // bigger than the number of item types we have, although it's not a huge deal.
+ #define IEDIT_TABLE_SIZE       50
+ 
+ // used to store the different sub-olc functions for different item types
+ HASHTABLE *item_olc_table = NULL;
+ 
+ typedef struct item_olc_data {
+   void    (* menu)(SOCKET_DATA *sock, void *data);
+   int  (* chooser)(SOCKET_DATA *sock, void *data, char option);
+   bool  (* parser)(SOCKET_DATA *sock, void *data, int choice, const char *arg);
+ } ITEM_OLC_DATA;
+ 
+ ITEM_OLC_DATA *newItemOLC(void *menu, void *chooser, void *parser) {
+   ITEM_OLC_DATA *data = malloc(sizeof(ITEM_OLC_DATA));
+   data->menu    = menu;
+   data->chooser = chooser;
+   data->parser  = parser;
+   return data;
+ }
+ 
+ void deleteItemOLC(ITEM_OLC_DATA *data) {
+   free(data);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // implementation of iedit.h
+ //*****************************************************************************
+ #define IEDIT_EDIT        1
+ #define IEDIT_DELETE      2
+ 
+ 
+ //
+ // list off all the item types available for editing. Print the type in green
+ // if the item currently is not of that type. Print the type in yellow if the
+ // item is of that type.
+ void iedit_show_types(SOCKET_DATA *sock, OBJ_DATA *obj) {
+   LIST *list = itemTypeList();
+   LIST_ITERATOR *list_i = newListIterator(list);
+   char *type = NULL;
+   int col = 0;
+ 
+   text_to_buffer(sock, "{wEditable item types:\r\n");
+   ITERATE_LIST(type, list_i) {
+     send_to_socket(sock, "  %s%-14s%s", (objIsType(obj, type) ? "{y" : "{g"),
+ 		   type, ((col != 0 && col % 4 == 0) ? "\r\n": "   "));
+     col++;
+   }
+   deleteListIterator(list_i);
+   deleteListWith(list, free);
+ 
+   if(col % 4 != 0) text_to_buffer(sock, "\r\n");
+ }
+ 
+ void item_add_olc(const char *type, void *menu, void *chooser, void *parser) {
+   ITEM_OLC_DATA *data = NULL;
+   // check to see if we already have functions for this item type installed
+   if( (data = hashRemove(item_olc_table, type)) != NULL)
+     deleteItemOLC(data);
+   data = newItemOLC(menu, chooser, parser);
+   hashPut(item_olc_table, type, data);
+ }
+ 
+ void iedit_menu(SOCKET_DATA *sock, OBJ_DATA *obj) {
+   iedit_show_types(sock, obj);
+   text_to_buffer(sock, 
+ 		 "\r\n"
+ 		 "    {gE) edit type\r\n"
+ 		 "    D) delete type\r\n");
+ }
+ 
+ int  iedit_chooser(SOCKET_DATA *sock, OBJ_DATA *obj, char option) {
+   switch(toupper(option)) {
+   case 'E':
+     text_to_buffer(sock, "Which item type would you like to edit: ");
+     return IEDIT_EDIT;
+   case 'D':
+     text_to_buffer(sock, "Which item type would you like to delete: ");
+     return IEDIT_DELETE;
+   default: return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool iedit_parser(SOCKET_DATA *sock, OBJ_DATA *obj,int choice, const char *arg){
+   switch(choice) {
+   case IEDIT_EDIT: {
+     ITEM_OLC_DATA *funcs = NULL;
+     if(!objIsType(obj, arg))
+       objSetType(obj, arg);
+     // pull up the OLC functions and see if we can edit the type
+     if((funcs = hashGet(item_olc_table, arg)) != NULL) {
+       void *item_data = objGetTypeData(obj, arg);
+       do_olc(sock, funcs->menu, funcs->chooser, funcs->parser,
+ 	     NULL, NULL, NULL, NULL, item_data);
+     }
+     return TRUE;
+   }
+   case IEDIT_DELETE:
+     objDeleteType(obj, arg);
+     return TRUE;
+   default: return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // initialization of item olc
+ //*****************************************************************************
+ void init_item_olc() {
+   item_olc_table = newHashtable(IEDIT_TABLE_SIZE);
+ }
diff -crN nakedmudv1.5/src/items/iedit.d nakedmudv2.0/src/items/iedit.d
*** nakedmudv1.5/src/items/iedit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/iedit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ items/iedit.d items/iedit.o: items/iedit.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h items/items.h \
+   items/iedit.h olc2/olc.h
diff -crN nakedmudv1.5/src/items/iedit.h nakedmudv2.0/src/items/iedit.h
*** nakedmudv1.5/src/items/iedit.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/iedit.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,28 ----
+ #ifndef IEDIT_H
+ #define IEDIT_H
+ //*****************************************************************************
+ //
+ // iedit.h
+ //
+ // Although it is not core to the functioning of items, we will more likely
+ // than not want to be able to edit their type information in OLC. This will
+ // require a parser, a chooser, and a menu for editing the type information.
+ // Item types can add in their OLC functions via this framework. iedit uses
+ // the OLC2 framework. For more detailed instructions on how to set up an OLC,
+ // users should refer to the OLC2 source headers.
+ //
+ // NOTE: the menu, chooser, and parser should only take the item-specific data,
+ //       and not the WHOLE object! It has been set up this way to encourage
+ //       people to localize all of the data associated with one item type.
+ //
+ //*****************************************************************************
+ 
+ void item_add_olc(const char *type, void *menu, void *chooser, void *parser);
+ 
+ //
+ // these functions will be needed by oedit
+ void iedit_menu(SOCKET_DATA *sock, OBJ_DATA *obj);
+ int  iedit_chooser(SOCKET_DATA *sock, OBJ_DATA *obj, char option);
+ bool iedit_parser(SOCKET_DATA *sock, OBJ_DATA *obj,int choice, const char *arg);
+ 
+ #endif // IEDIT_H
diff -crN nakedmudv1.5/src/items/items.c nakedmudv2.0/src/items/items.c
*** nakedmudv1.5/src/items/items.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/items.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,288 ----
+ //*****************************************************************************
+ //
+ // items.c
+ //
+ // Objects can serve many different functions; they might be containers, they
+ // might be weapons, they might be pieces of clothing... the list goes on and
+ // on. The classification of what type of item the object is is what handles
+ // these sorts of distinctions. This is a general framework for adding new
+ // item types. Contains functions for storing type data on objects. Item types
+ // are expected to be able to handle their own subtyping (if neccessary). 
+ // Objects can be multi-typed (e.g. a desk with a drawer can be both a piece
+ // of furniture and a container).
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../object.h"
+ #include "../auxiliary.h"
+ #include "../storage.h"
+ 
+ #include "items.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // local functions, datastructures, and defines
+ //*****************************************************************************
+ // this is the size of the table where we store all of the functions for 
+ // creating/deleting/copying/etc... data of item types. Ideally, this will be
+ // about 120% bigger than the total number of item types we have installed.
+ #define TYPE_TABLE_SIZE       50
+ 
+ // objects can have more than one item type; this is the size of the table
+ // that holds all of the item types for a single object. I'm doubtful an item
+ // will ever have more than 2-3 types, so 5 is a very generous size
+ #define ITEM_TABLE_SIZE        5
+ 
+ // a table of all our item types, and their assocciated new/delete/etc.. funcs
+ HASHTABLE *type_table = NULL;
+ 
+ //
+ // this is what will go into our type_data table
+ typedef struct item_func_data {
+   void          *(* new)();
+   void        (* delete)(void *data);
+   void         *(* copy)(void *data);
+   void        (* copyto)(void *from, void *to);
+   STORAGE_SET *(* store)(void *data);
+   void         *(* read)(STORAGE_SET *set);
+ } ITEM_FUNC_DATA;
+ 
+ 
+ //
+ // create a new structure for holding item type functions
+ ITEM_FUNC_DATA *newItemFuncData(void *new, void *delete, void *copyTo,
+ 				void *copy, void *store, void *read) {
+   ITEM_FUNC_DATA *data = malloc(sizeof(ITEM_FUNC_DATA));
+   data->new    = new;
+   data->delete = delete;
+   data->copy   = copy;
+   data->copyto = copyTo;
+   data->store  = store;
+   data->read   = read;
+   return data;
+ }
+ 
+ 
+ //
+ // deletes one structure for holding item type functions
+ void deleteItemFuncData(ITEM_FUNC_DATA *data) {
+   free(data);
+ }
+ 
+ //
+ // goes through an object's item table and deletes everything in it. Does
+ // not delete the table itself
+ void clearItemTable(HASHTABLE *table) {
+   // if our hashtable isn't empty, we have to make sure 
+   // we delete all of the data within it
+   if(hashSize(table) > 0) {
+     HASH_ITERATOR *hash_i = newHashIterator(table);
+     const char       *key = NULL;
+     void             *val = NULL;
+     // delete the contents of our hashtable
+     ITERATE_HASH(key, val, hash_i) {
+       ITEM_FUNC_DATA *funcs = hashGet(type_table, key);
+       funcs->delete(hashRemove(table, key));
+     }
+     deleteHashIterator(hash_i);
+   }
+ }
+ 
+ //
+ // copies the contents of one item table over to another. clears the destination
+ // table first.
+ void copyItemTableTo(HASHTABLE *from, HASHTABLE *to) {
+   clearItemTable(to);
+   // if the table we're copying has contents, go throug hand copy them all
+   if(hashSize(from) > 0) {
+     HASH_ITERATOR *hash_i = newHashIterator(from);
+     const char       *key = NULL;
+     void             *val = NULL;
+     // copy all the contents
+     ITERATE_HASH(key, val, hash_i) {
+       ITEM_FUNC_DATA *funcs = hashGet(type_table, key);
+       hashPut(to, key, funcs->copy(val));
+     }
+     deleteHashIterator(hash_i);
+   }
+ }
+ 
+ //
+ // Creates a new item table and copies the contents of the old one 
+ // over to the new one 
+ HASHTABLE *copyItemTable(HASHTABLE *table) {
+   HASHTABLE *newtable = newHashtable(ITEM_TABLE_SIZE);
+   copyItemTableTo(table, newtable);
+   return newtable;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // auxiliary data
+ //*****************************************************************************
+ typedef struct item_data {
+   HASHTABLE *item_table;
+ } ITEM_DATA;
+ 
+ ITEM_DATA *newItemData() {
+   ITEM_DATA *data  = malloc(sizeof(ITEM_DATA));
+   data->item_table = newHashtable(ITEM_TABLE_SIZE);
+   return data;
+ }
+ 
+ void deleteItemData(ITEM_DATA *data) {
+   clearItemTable(data->item_table);
+   deleteHashtable(data->item_table);
+   free(data);
+ }
+ 
+ void itemDataCopyTo(ITEM_DATA *from, ITEM_DATA *to) {
+   copyItemTableTo(from->item_table, to->item_table);
+ }
+ 
+ ITEM_DATA *itemDataCopy(ITEM_DATA *data) {
+   ITEM_DATA *newdata = newItemData();
+   itemDataCopyTo(data, newdata);
+   return newdata;
+ }
+ 
+ STORAGE_SET *itemDataStore(ITEM_DATA *data) {
+   STORAGE_SET       *set = new_storage_set();
+   // if we have a type or more, go through them all and store 'em
+   if(hashSize(data->item_table) > 0) {
+     STORAGE_SET_LIST *list = new_storage_list();
+     HASH_ITERATOR  *hash_i = newHashIterator(data->item_table);
+     ITEM_FUNC_DATA  *funcs = NULL;
+     const char        *key = NULL;
+     void              *val = NULL;
+ 
+     // store all of our item type data
+     ITERATE_HASH(key, val, hash_i) {
+       STORAGE_SET *one_set = new_storage_set();
+       funcs = hashGet(type_table, key);
+       store_string(one_set, "type", key);
+       store_set(one_set, "data", funcs->store(val));
+       storage_list_put(list, one_set);
+     }
+     deleteHashIterator(hash_i);
+ 
+     store_list(set, "types", list);
+   }
+   return set;
+ }
+ 
+ 
+ ITEM_DATA *itemDataRead(STORAGE_SET *set) {
+   ITEM_DATA         *data = newItemData();
+   STORAGE_SET_LIST *types = read_list(set, "types");
+   ITEM_FUNC_DATA   *funcs = NULL;
+   STORAGE_SET  *one_entry = NULL;
+ 
+   // go through each entry and parse the item type
+   while( (one_entry = storage_list_next(types)) != NULL) {
+     const char      *type = read_string(one_entry, "type");
+     // make sure the type is valid
+     if((funcs = hashGet(type_table, type)) == NULL) 
+       continue;
+     STORAGE_SET *type_set = read_set(one_entry, "data");
+     hashPut(data->item_table, type, funcs->read(type_set));
+   }
+   return data;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // implementation of items.h
+ //*****************************************************************************
+ void init_items(void) {
+   type_table = newHashtable(TYPE_TABLE_SIZE);
+   auxiliariesInstall("type_data",
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_OBJ, newItemData, 
+ 				       deleteItemData, itemDataCopyTo,
+ 				       itemDataCopy, itemDataStore, 
+ 				       itemDataRead));
+ 
+   // initialize item olc
+   extern void init_item_olc(void); init_item_olc();
+ 
+   // now, initialize our basic items types
+   extern void init_container(); init_container();
+   extern void init_portal();    init_portal();
+   extern void init_furniture(); init_furniture();
+   extern void init_worn();      init_worn();
+ }
+ 
+ void item_add_type(const char *type, 
+ 		   void *new,    void *delete,
+ 		   void *copyTo, void *copy, 
+ 		   void *store,  void *read) {
+   ITEM_FUNC_DATA *funcs = NULL;
+   // first, make sure no item type by this name already
+   // exists. If one does, delete it so it can be replaced
+   if((funcs = hashRemove(type_table, type)) != NULL)
+     deleteItemFuncData(funcs);
+   funcs = newItemFuncData(new, delete, copyTo, copy, store, read);
+   hashPut(type_table, type, funcs);
+ }
+ 
+ LIST *itemTypeList(void) {
+   LIST *list = newList();
+   HASH_ITERATOR *hash_i = newHashIterator(type_table);
+   const char       *key = NULL;
+   void             *val = NULL;
+   ITERATE_HASH(key, val, hash_i)
+     listPutWith(list, strdup(key), strcasecmp);
+   deleteHashIterator(hash_i);
+   return list;
+ }
+ 
+ void *objGetTypeData(OBJ_DATA *obj, const char *type) {
+   ITEM_DATA *data = objGetAuxiliaryData(obj, "type_data");
+   return hashGet(data->item_table, type);
+ }
+ 
+ void objSetType(OBJ_DATA *obj, const char *type) {
+   ITEM_FUNC_DATA *funcs = hashGet(type_table, type);
+   ITEM_DATA *data       = objGetAuxiliaryData(obj, "type_data");
+   void *old_item_data   = hashGet(data->item_table, type);
+   if(old_item_data) return;
+   else hashPut(data->item_table, type, funcs->new());
+ }
+ 
+ void objDeleteType(OBJ_DATA *obj, const char *type) {
+   ITEM_FUNC_DATA *funcs = hashGet(type_table, type);
+   ITEM_DATA *data       = objGetAuxiliaryData(obj, "type_data");
+   void *old_item_data   = hashRemove(data->item_table, type);
+   if(old_item_data) funcs->delete(old_item_data);
+ }
+ 
+ bool objIsType(OBJ_DATA *obj, const char *type) {
+   ITEM_DATA *data = objGetAuxiliaryData(obj, "type_data");
+   return hashIn(data->item_table, type);
+ }
+ 
+ const char *objGetTypes(OBJ_DATA *obj) {
+   static char buf[MAX_BUFFER];
+   ITEM_DATA *data = objGetAuxiliaryData(obj, "type_data");
+   if(hashSize(data->item_table) == 0)
+     sprintf(buf, "none");
+   else {
+     *buf = '\0';
+     HASH_ITERATOR *hash_i = newHashIterator(data->item_table);
+     const char       *key = NULL;
+     void             *val = NULL;
+     int             count = 0;
+ 
+     ITERATE_HASH(key, val, hash_i) {
+       sprintf(buf, "%s%s%s", buf, (count > 0 ? ", " : ""), key);
+       count++;
+     }
+     deleteHashIterator(hash_i);
+   }
+   return buf;
+ }
diff -crN nakedmudv1.5/src/items/items.d nakedmudv2.0/src/items/items.d
*** nakedmudv1.5/src/items/items.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/items.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ items/items.d items/items.o: items/items.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h object.h auxiliary.h \
+   storage.h items/items.h
diff -crN nakedmudv1.5/src/items/items.h nakedmudv2.0/src/items/items.h
*** nakedmudv1.5/src/items/items.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/items.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,89 ----
+ #ifndef ITEMS_H
+ #define ITEMS_H
+ //*****************************************************************************
+ //
+ // items.h
+ //
+ // Objects can serve many different functions; they might be containers, they
+ // might be weapons, they might be pieces of clothing... the list goes on and
+ // on. The classification of what type of item the object is is what handles
+ // these sorts of distinctions. This is a general framework for adding new
+ // item types. Contains functions for storing type data on objects. Item types
+ // are expected to be able to handle their own subtyping (if neccessary). 
+ // Objects can be multi-typed (e.g. a desk with a drawer can be both a piece
+ // of furniture and a container).
+ //
+ //*****************************************************************************
+ 
+ //
+ // prepare the items module for use
+ void init_items(void);
+ 
+ //
+ // install a new item type. type should be the name of the item type.
+ //
+ // new should create a new datastructure to hold data for the object assocciated
+ // with its item type. It should take no arguments. The form of the function
+ // should be as follows:
+ //    itemdata *newItemData()
+ //
+ // delete should take in the datastructure used for holding data assocciated
+ // with the item type, and free it all from memory. The function should take
+ // a form as follows:
+ //    void deleteItemData(itemdata *data)
+ //
+ // copyTo should take a pointer from one itemdata and copy all of its
+ // information over to a pointer to another itemdata. The function should take
+ // a form as follows:
+ //    void itemDataCopyTo(itemdata *from, itemdata *to)
+ //
+ // copy should return a deep copy (newly allocated memory) of the supplied
+ // itemdata. The function should take a form as follows:
+ //    itemdata *itemDataCopy(itemdata *data)
+ //
+ // store should return a storage set for storing data assocciated with the
+ // item type for the object to disk. The function should take a form as
+ // follows:
+ //    STORAGE_SET *itemDataStore(itemdata *data)
+ //
+ // read should take in a storage set and, from it, parse a new instance
+ // of itemdata. The function should take a form as follows:
+ //    itemdata *itemDataRead(STORAGE_SET *set)
+ void item_add_type(const char *type, 
+ 		   void *new,    void *delete,
+ 		   void *copyTo, void *copy, 
+ 		   void *store,  void *read);
+ 
+ //
+ // Build a list of all the current item types. Item types are listed in
+ // alphabetical order. This list and all its contents must be deleted after 
+ // use. For a quick one-line deletion, try: 
+ //   deleteListWith(list, free)
+ LIST *itemTypeList(void);
+ 
+ //
+ // returns the item data with the specified type for the object. 
+ // if the object is not of type item, return NULL.
+ void *objGetTypeData(OBJ_DATA *obj, const char *type);
+ 
+ //
+ // Set the item to be of the specified type. 
+ // A new datastructure for the type data is created.
+ void objSetType(OBJ_DATA *obj, const char *type);
+ 
+ //
+ // If an object was of the specified type, no longer have the object
+ // be of that type.
+ void objDeleteType(OBJ_DATA *obj, const char *type);
+ 
+ //
+ // returns TRUE if the object is the specified type of object
+ bool objIsType(OBJ_DATA *obj, const char *type);
+ 
+ //
+ // returns a comma-separated list of the item types this object currently
+ // has. the list is written to a static buffer, so players don't have to
+ // worry about freeing the string after use
+ const char *objGetTypes(OBJ_DATA *obj);
+ 
+ #endif // ITEMS_H
diff -crN nakedmudv1.5/src/items/module.mk nakedmudv2.0/src/items/module.mk
*** nakedmudv1.5/src/items/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ SRC  += items/items.c items/portal.c items/iedit.c items/container.c \
+ 	items/furniture.c items/worn.c
diff -crN nakedmudv1.5/src/items/#portal.c# nakedmudv2.0/src/items/#portal.c#
*** nakedmudv1.5/src/items/#portal.c#	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/#portal.c#	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,194 ----
+ //*****************************************************************************
+ //
+ // portal.c
+ //
+ // handles all of the functioning of the portal item type. Stores data about 
+ // the destination vnums of a portal, and does all the legwork for retreiving 
+ // destinations when someone wants to interact with a portal.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../storage.h"
+ #include "../character.h"
+ #include "../socket.h"
+ #include "../room.h"
+ #include "../world.h"
+ #include "../movement.h"
+ #include "../inform.h"
+ #include "../handler.h"
+ #include "items.h"
+ 
+ #include "../olc2/olc.h"
+ #include "iedit.h"
+ 
+ 
+ //*****************************************************************************
+ // item data for portals
+ //*****************************************************************************
+ typedef struct portal_data {
+   int dest;
+ } PORTAL_DATA;
+ 
+ PORTAL_DATA *newPortalData() {
+   PORTAL_DATA *data = malloc(sizeof(PORTAL_DATA));
+   data->dest = NOWHERE;
+   return data;
+ }
+ 
+ void deletePortalData(PORTAL_DATA *data) {
+   free(data);
+ }
+ 
+ void portalDataCopyTo(PORTAL_DATA *from, PORTAL_DATA *to) {
+   to->dest = from->dest;
+ }
+ 
+ PORTAL_DATA *portalDataCopy(PORTAL_DATA *data) {
+   PORTAL_DATA *new_data = newPortalData();
+   portalDataCopyTo(data, new_data);
+   return new_data;
+ }
+ 
+ STORAGE_SET *portalDataStore(PORTAL_DATA *data) {
+   STORAGE_SET *set = new_storage_set();
+   store_int(set, "dest", data->dest);
+   return set;
+ }
+ 
+ PORTAL_DATA *portalDataRead(STORAGE_SET *set) {
+   PORTAL_DATA *data = newPortalData();
+   data->dest = read_int(set, "dest");
+   return data;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for interacting with portals
+ //*****************************************************************************
+ int portalGetDest(OBJ_DATA *obj) {
+   PORTAL_DATA *data = objGetTypeData(obj, "portal");
+   return data->dest;
+ }
+ 
+ void portalSetDest(OBJ_DATA *obj, int dest) {
+   PORTAL_DATA *data = objGetTypeData(obj, "portal");
+   data->dest = dest;
+ }
+ 
+ 
+ //
+ // cmd_enter is used to go through portals
+ //   usage: enter [object]
+ //
+ //   examples:
+ //     enter portal         enter the thing called "portal" in your room
+ COMMAND(cmd_enter) {
+   if(!arg || !*arg)
+     send_to_char(ch, "What did you want to enter?\r\n");
+   else {
+     int found_type = FOUND_NONE;
+     void *found = generic_find(ch, arg,
+ 			       FIND_TYPE_OBJ | FIND_TYPE_EXIT,
+ 			       FIND_SCOPE_IMMEDIATE,
+ 			       FALSE, &found_type);
+ 
+ 
+     // we're trying to enter an exit
+     if(found && found_type == FOUND_EXIT)
+       try_exit(ch, found, DIR_NONE);
+ 
+     // we're trying to enter a portal
+     else if(found && found_type == FOUND_OBJ) {
+       if(!objIsType(found, "portal"))
+ 	send_to_char(ch, "You cannot seem to find an enterance.\r\n");
+       else {
+ 	ROOM_DATA *dest = worldGetRoom(gameworld, portalGetDest(found));
+ 	if(!dest)
+ 	  send_to_char(ch, 
+ 		       "You go to enter the portal, "
+ 		       "but dark forces prevent you!\r\n");
+ 	else {
+ 	  send_to_char(ch, "You step through %s.\r\n", see_obj_as(ch, found));
+ 	  message(ch, NULL, found, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
+ 		  "$n steps through $o.");
+ 	  char_from_room(ch);
+ 	  char_to_room(ch, dest);
+ 	  look_at_room(ch, dest);
+ 	  message(ch, NULL, found, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
+ 		  "$n arrives after travelling through $o.");
+ 	}
+       }
+     }
+     else
+       send_to_char(ch, "What were you trying to enter?\r\n");
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // portal olc
+ //*****************************************************************************
+ #define IEDIT_PORTAL_DEST      1
+ 
+ // the resedit olc needs these declared
+ void iedit_portal_menu   (SOCKET_DATA *sock, PORTAL_DATA *data) {
+   ROOM_DATA *dest = worldGetRoom(gameworld, data->dest);
+   send_to_socket(sock, "{g1) Destination: {c%d (%s)\r\n", data->dest,
+ 		 (dest ? roomGetName(dest) : "nowhere"));
+ }
+ 
+ int  iedit_portal_chooser(SOCKET_DATA *sock, PORTAL_DATA *data, char option) {
+   switch(toupper(option)) {
+   case '1': 
+     text_to_buffer(sock, "Enter new destination (-1 for none): ");
+     return IEDIT_PORTAL_DEST;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool iedit_portal_parser (SOCKET_DATA *sock, PORTAL_DATA *data, int choice, 
+ 			  const char *arg) {
+   switch(choice) {
+   case IEDIT_PORTAL_DEST: {
+     int dest = atoi(arg);
+     // ugh... ugly logic. Clean this up one day?
+     //   Make sure what we're getting is a positive number or make sure it is
+     //   the NOWHERE number (-1). Also make sure that, if it's not NOWHERE, it
+     //   corresponds to a vnum of a room already created.
+     if((dest != NOWHERE && !worldGetRoom(gameworld, dest)) ||
+        (dest != NOWHERE && !isdigit(*arg)))
+       return FALSE;
+     data->dest = dest;
+     return TRUE;
+   }
+   default:
+     return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // install the portal item type
+ //*****************************************************************************
+ 
+ //
+ // this will need to be called by init_items() in items/items.c
+ void init_portal(void) {
+   item_add_type("portal", 
+ 		newPortalData, deletePortalData,
+ 		portalDataCopyTo, portalDataCopy, 
+ 		portalDataStore, portalDataRead);
+ 
+   // set up the portal OLC too
+   item_add_olc("portal", iedit_portal_menu, iedit_portal_chooser, 
+ 	       iedit_portal_parser);
+ 
+   add_cmd("enter", NULL, cmd_enter, 0, POS_STANDING, POS_FLYING,
+ 	  LEVEL_PLAYER, TRUE, TRUE);
+ }
diff -crN nakedmudv1.5/src/items/portal.c nakedmudv2.0/src/items/portal.c
*** nakedmudv1.5/src/items/portal.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/portal.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,194 ----
+ //*****************************************************************************
+ //
+ // portal.c
+ //
+ // handles all of the functioning of the portal item type. Stores data about 
+ // the destination vnums of a portal, and does all the legwork for retreiving 
+ // destinations when someone wants to interact with a portal.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../storage.h"
+ #include "../character.h"
+ #include "../socket.h"
+ #include "../room.h"
+ #include "../world.h"
+ #include "../movement.h"
+ #include "../inform.h"
+ #include "../handler.h"
+ #include "items.h"
+ 
+ #include "../olc2/olc.h"
+ #include "iedit.h"
+ 
+ 
+ //*****************************************************************************
+ // item data for portals
+ //*****************************************************************************
+ typedef struct portal_data {
+   int dest;
+ } PORTAL_DATA;
+ 
+ PORTAL_DATA *newPortalData() {
+   PORTAL_DATA *data = malloc(sizeof(PORTAL_DATA));
+   data->dest = NOWHERE;
+   return data;
+ }
+ 
+ void deletePortalData(PORTAL_DATA *data) {
+   free(data);
+ }
+ 
+ void portalDataCopyTo(PORTAL_DATA *from, PORTAL_DATA *to) {
+   to->dest = from->dest;
+ }
+ 
+ PORTAL_DATA *portalDataCopy(PORTAL_DATA *data) {
+   PORTAL_DATA *new_data = newPortalData();
+   portalDataCopyTo(data, new_data);
+   return new_data;
+ }
+ 
+ STORAGE_SET *portalDataStore(PORTAL_DATA *data) {
+   STORAGE_SET *set = new_storage_set();
+   store_int(set, "dest", data->dest);
+   return set;
+ }
+ 
+ PORTAL_DATA *portalDataRead(STORAGE_SET *set) {
+   PORTAL_DATA *data = newPortalData();
+   data->dest = read_int(set, "dest");
+   return data;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for interacting with portals
+ //*****************************************************************************
+ int portalGetDest(OBJ_DATA *obj) {
+   PORTAL_DATA *data = objGetTypeData(obj, "portal");
+   return data->dest;
+ }
+ 
+ void portalSetDest(OBJ_DATA *obj, int dest) {
+   PORTAL_DATA *data = objGetTypeData(obj, "portal");
+   data->dest = dest;
+ }
+ 
+ 
+ //
+ // cmd_enter is used to go through portals
+ //   usage: enter [object]
+ //
+ //   examples:
+ //     enter portal         enter the thing called "portal" in your room
+ COMMAND(cmd_enter) {
+   if(!arg || !*arg)
+     send_to_char(ch, "What did you want to enter?\r\n");
+   else {
+     int found_type = FOUND_NONE;
+     void *found = generic_find(ch, arg,
+ 			       FIND_TYPE_OBJ | FIND_TYPE_EXIT,
+ 			       FIND_SCOPE_IMMEDIATE,
+ 			       FALSE, &found_type);
+ 
+ 
+     // we're trying to enter an exit
+     if(found && found_type == FOUND_EXIT)
+       try_exit(ch, found, DIR_NONE);
+ 
+     // we're trying to enter a portal
+     else if(found && found_type == FOUND_OBJ) {
+       if(!objIsType(found, "portal"))
+ 	send_to_char(ch, "You cannot seem to find an enterance.\r\n");
+       else {
+ 	ROOM_DATA *dest = worldGetRoom(gameworld, portalGetDest(found));
+ 	if(!dest)
+ 	  send_to_char(ch, 
+ 		       "You go to enter the portal, "
+ 		       "but dark forces prevent you!\r\n");
+ 	else {
+ 	  send_to_char(ch, "You step through %s.\r\n", see_obj_as(ch, found));
+ 	  message(ch, NULL, found, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
+ 		  "$n steps through $o.");
+ 	  char_from_room(ch);
+ 	  char_to_room(ch, dest);
+ 	  look_at_room(ch, dest);
+ 	  message(ch, NULL, found, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
+ 		  "$n arrives after travelling through $o.");
+ 	}
+       }
+     }
+     else
+       send_to_char(ch, "What were you trying to enter?\r\n");
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // portal olc
+ //*****************************************************************************
+ #define IEDIT_PORTAL_DEST      1
+ 
+ // the resedit olc needs these declared
+ void iedit_portal_menu   (SOCKET_DATA *sock, PORTAL_DATA *data) {
+   ROOM_DATA *dest = worldGetRoom(gameworld, data->dest);
+   send_to_socket(sock, "{g1) Destination: {c%d (%s)\r\n", data->dest,
+ 		 (dest ? roomGetName(dest) : "nowhere"));
+ }
+ 
+ int  iedit_portal_chooser(SOCKET_DATA *sock, PORTAL_DATA *data, char option) {
+   switch(toupper(option)) {
+   case '1': 
+     text_to_buffer(sock, "Enter new destination (-1 for none): ");
+     return IEDIT_PORTAL_DEST;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool iedit_portal_parser (SOCKET_DATA *sock, PORTAL_DATA *data, int choice, 
+ 			  const char *arg) {
+   switch(choice) {
+   case IEDIT_PORTAL_DEST: {
+     int dest = atoi(arg);
+     // ugh... ugly logic. Clean this up one day?
+     //   Make sure what we're getting is a positive number or make sure it is
+     //   the NOWHERE number (-1). Also make sure that, if it's not NOWHERE, it
+     //   corresponds to a vnum of a room already created.
+     if((dest != NOWHERE && !worldGetRoom(gameworld, dest)) ||
+        (dest != NOWHERE && !isdigit(*arg)))
+       return FALSE;
+     data->dest = dest;
+     return TRUE;
+   }
+   default:
+     return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // install the portal item type
+ //*****************************************************************************
+ 
+ //
+ // this will need to be called by init_items() in items/items.c
+ void init_portal(void) {
+   item_add_type("portal", 
+ 		newPortalData, deletePortalData,
+ 		portalDataCopyTo, portalDataCopy, 
+ 		portalDataStore, portalDataRead);
+ 
+   // set up the portal OLC too
+   item_add_olc("portal", iedit_portal_menu, iedit_portal_chooser, 
+ 	       iedit_portal_parser);
+ 
+   add_cmd("enter", NULL, cmd_enter, 0, POS_STANDING, POS_FLYING,
+ 	  LEVEL_PLAYER, TRUE, TRUE);
+ }
diff -crN nakedmudv1.5/src/items/portal.d nakedmudv2.0/src/items/portal.d
*** nakedmudv1.5/src/items/portal.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/portal.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ items/portal.d items/portal.o: items/portal.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h storage.h character.h \
+   socket.h room.h world.h movement.h inform.h handler.h items/items.h \
+   olc2/olc.h items/iedit.h
diff -crN nakedmudv1.5/src/items/portal.h nakedmudv2.0/src/items/portal.h
*** nakedmudv1.5/src/items/portal.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/portal.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,21 ----
+ #ifndef PORTAL_H
+ #define PORTAL_H
+ //*****************************************************************************
+ //
+ // portal.h
+ //
+ // handles all of the functioning of the portal item type. Item keyword type
+ // is "portal". This will be needed for checking if an item is of type portal
+ // with objIsType() from items/items.h
+ //
+ //*****************************************************************************
+ 
+ //
+ // return the vnum of the room that the portal leads to
+ int portalGetDest(OBJ_DATA *obj);
+ 
+ //
+ // set the destination of the portal
+ void portalSetDest(OBJ_DATA *obj, int dest);
+ 
+ #endif // PORTAL_H
diff -crN nakedmudv1.5/src/items/worn.c nakedmudv2.0/src/items/worn.c
*** nakedmudv1.5/src/items/worn.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/worn.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,242 ----
+ //*****************************************************************************
+ //
+ // worn.c
+ //
+ // handles all of the functioning of wearable items. Perhaps this could
+ // eventually be extended to include armors? I think, perhaps, one of the 
+ // weirdest things about (most) DIKUs is that worn items and armors are two
+ // different item types; really, wearable items are just armors that provide
+ // no armor class. Fusing the two item types into one might be a much more
+ // fruitful route to take. Or perhaps another route would be to just make 
+ // another item type called "armor" that only functions if the item is also of
+ // type "worn"; it calculates armor class/protection/whatnot based on the type
+ // of worn item the item is.
+ //
+ // that said, I'm not going to do it. Well, not for NakedMud anyways; I don't
+ // want to burden other developers with my conception of what a good way to do
+ // armor class is. Therefore, if you agree with me, I leave the exercise up to
+ // you :)
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../storage.h"
+ #include "../character.h"
+ #include "../socket.h"
+ #include "../room.h"
+ #include "../world.h"
+ #include "../inform.h"
+ #include "../handler.h"
+ 
+ #include "../olc2/olc.h"
+ #include "iedit.h"
+ #include "items.h"
+ #include "worn.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // local functions, variables, datastructures, and defines
+ //*****************************************************************************
+ 
+ // how big of a table will we need to hold all of the worn data we might have?
+ // optimally, this should be about 120% bigger than the number of worn types
+ // that we have.
+ #define WORN_TABLE_SIZE     50
+ 
+ HASHTABLE *worn_table = NULL;
+ 
+ typedef struct worn_entry {
+   char *type;
+   char *positions;
+ } WORN_ENTRY;  
+ 
+ WORN_ENTRY *newWornEntry(const char *type, const char *positions) {
+   WORN_ENTRY *entry = malloc(sizeof(WORN_ENTRY));
+   entry->type      = strdup(type ? type : "");
+   entry->positions = strdup(positions ? positions : "");
+   return entry;
+ }
+ 
+ void deleteWornEntry(WORN_ENTRY *entry) {
+   if(entry->positions) free(entry->positions);
+   if(entry->type)      free(entry->type);
+   free(entry);
+ }
+ 
+ const char *wornTypeGetPositions(const char *type) {
+   WORN_ENTRY *entry = hashGet(worn_table, type);
+   return (entry ? entry->positions : "");
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // item data for worns
+ //*****************************************************************************
+ typedef struct worn_data {
+   char *type;
+ } WORN_DATA;
+ 
+ WORN_DATA *newWornData() {
+   WORN_DATA *data = malloc(sizeof(WORN_DATA));
+   data->type      = strdup("");
+   return data;
+ }
+ 
+ void deleteWornData(WORN_DATA *data) {
+   if(data->type) free(data->type);
+   free(data);
+ }
+ 
+ void wornDataCopyTo(WORN_DATA *from, WORN_DATA *to) {
+   if(to->type) free(to->type);
+   to->type = strdup(from->type ? from->type : "");
+ }
+ 
+ WORN_DATA *wornDataCopy(WORN_DATA *data) {
+   WORN_DATA *new_data = newWornData();
+   wornDataCopyTo(data, new_data);
+   return new_data;
+ }
+ 
+ STORAGE_SET *wornDataStore(WORN_DATA *data) {
+   STORAGE_SET *set = new_storage_set();
+   store_string(set, "type", data->type);
+   return set;
+ }
+ 
+ WORN_DATA *wornDataRead(STORAGE_SET *set) {
+   WORN_DATA *data = newWornData();
+   data->type = strdup(read_string(set, "type"));
+   return data;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for interacting with worns
+ //*****************************************************************************
+ const char *wornGetType(OBJ_DATA *obj) {
+   WORN_DATA *data = objGetTypeData(obj, "worn");
+   return data->type;
+ }
+ 
+ const char *wornGetPositions(OBJ_DATA *obj) {
+   WORN_DATA *data = objGetTypeData(obj, "worn");
+   return wornTypeGetPositions(data->type);
+ }
+ 
+ void wornSetType(OBJ_DATA *obj, const char *type) {
+   WORN_DATA *data = objGetTypeData(obj, "worn");
+   if(data->type) free(data->type);
+   data->type = strdup(type ? type : "");
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // worn olc
+ //*****************************************************************************
+ #define IEDIT_WORN_TYPE     1
+ 
+ void iedit_worn_show_types(SOCKET_DATA *sock) {
+   // we want to display them all by alphabetical order
+   LIST *types = newList();
+ 
+   HASH_ITERATOR *hash_i = newHashIterator(worn_table);
+   const char       *key = NULL;
+   WORN_ENTRY       *val = NULL;
+ 
+   // collect all of the types
+   ITERATE_HASH(key, val, hash_i)
+     listPutWith(types, strdup(key), strcasecmp);
+   deleteHashIterator(hash_i);
+ 
+   // display all of the types
+   LIST_ITERATOR *type_i = newListIterator(types);
+   int col = 0;
+ 
+   text_to_buffer(sock, "{wEditable item types:\r\n");
+   ITERATE_LIST(key, type_i) {
+     send_to_socket(sock, "  %-14s%s",
+ 		   key, ((col != 0 && col % 3 == 0) ? "\r\n": "   "));
+     col++;
+   }
+   deleteListIterator(type_i);
+   deleteListWith(types, free);
+   if(col % 3 != 0) text_to_buffer(sock, "\r\n");
+ }
+ 
+ 
+ //
+ // the resedit olc needs these declared
+ void iedit_worn_menu   (SOCKET_DATA *sock, WORN_DATA *data) {
+   send_to_socket(sock, 
+ 		 "{g1) type     : {c%s\r\n"
+ 		 "{g   equips to: {c%s\r\n",
+ 		 data->type, wornTypeGetPositions(data->type));
+ }
+ 
+ int  iedit_worn_chooser(SOCKET_DATA *sock, WORN_DATA *data, char option) {
+   switch(toupper(option)) {
+   case '1':
+     iedit_worn_show_types(sock);
+     text_to_buffer(sock, "enter choice: ");
+     return IEDIT_WORN_TYPE;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool iedit_worn_parser (SOCKET_DATA *sock, WORN_DATA *data, int choice, 
+ 			  const char *arg) {
+   switch(choice) {
+   case IEDIT_WORN_TYPE:
+     if(!hashIn(worn_table, arg))
+       return FALSE;
+     if(data->type) free(data->type);
+     data->type = strdup(arg);
+     return TRUE;
+   default:
+     return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // install the worn item type
+ //*****************************************************************************
+ void worn_add_type(const char *type, const char *required_positions) {
+   WORN_ENTRY *entry = NULL;
+ 
+   // make sure we don't currently have an entry
+   if((entry = hashRemove(worn_table, type)) != NULL)
+     deleteWornEntry(entry);
+   hashPut(worn_table, type, newWornEntry(type, required_positions));
+ }
+ 
+ 
+ //
+ // this will need to be called by init_items() in items/items.c
+ void init_worn(void) {
+   worn_table = newHashtable(WORN_TABLE_SIZE);
+   item_add_type("worn", 
+ 		newWornData, deleteWornData,
+ 		wornDataCopyTo, wornDataCopy, 
+ 		wornDataStore, wornDataRead);
+ 
+   // set up the worn OLC too
+   item_add_olc("worn", iedit_worn_menu, iedit_worn_chooser, iedit_worn_parser);
+ 
+   // add in our basic worn types
+   worn_add_type("shirt",                        "torso");
+   worn_add_type("gloves",       "left hand, right hand");
+   worn_add_type("left glove",               "left hand");
+   worn_add_type("right glove",             "right hand");
+   worn_add_type("earrings",                  "ear, ear");
+   worn_add_type("earring",                        "ear");
+   worn_add_type("ring",                        "finger");
+ }
diff -crN nakedmudv1.5/src/items/worn.d nakedmudv2.0/src/items/worn.d
*** nakedmudv1.5/src/items/worn.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/worn.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ items/worn.d items/worn.o: items/worn.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h storage.h character.h \
+   socket.h room.h world.h inform.h handler.h olc2/olc.h items/iedit.h \
+   items/items.h items/worn.h
diff -crN nakedmudv1.5/src/items/worn.h nakedmudv2.0/src/items/worn.h
*** nakedmudv1.5/src/items/worn.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/items/worn.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,35 ----
+ #ifndef WORN_H
+ #define WORN_H
+ //*****************************************************************************
+ //
+ // worn.h
+ //
+ // handles all of the functioning of wearable items. Perhaps this could
+ // eventually be extended to include armors? I think, perhaps, one of the 
+ // weirdest things about (most) DIKUs is that worn items and armors are two
+ // different item types; really, wearable items are just armors that provide
+ // no armor class. Fusing the two item types into one might be a much more
+ // fruitful route to take. Or perhaps another route would be to just make 
+ // another item type called "armor" that only functions if the item is also of
+ // type "worn"; it calculates armor class/protection/whatnot based on the type
+ // of worn item the item is.
+ //
+ // that said, I'm not going to do it. Well, not for NakedMud anyways; I don't
+ // want to burden other developers with my conception of what a good way to do
+ // armor class is. Therefore, if you agree with me, I leave the exercise up to
+ // you :)
+ //
+ //*****************************************************************************
+ 
+ //
+ // what type of a worn item is this object? 
+ const char *wornGetType(OBJ_DATA *obj);
+ const char *wornGetPositions(OBJ_DATA *obj);
+ void wornSetType(OBJ_DATA *obj, const char *type);
+ 
+ //
+ // add a new worn type to our list of possible worn types. A type name and
+ // a list of open positions for equipping the item are required.
+ void worn_add_type(const char *type, const char *required_positions);
+ 
+ #endif // WORN_H
diff -crN nakedmudv1.5/src/items.c nakedmudv2.0/src/items.c
*** nakedmudv1.5/src/items.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/items.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,111 ****
- //*****************************************************************************
- //
- // items.c
- //
- // contains definitional information for various item types. Some of the more
- // elaborate item types (e.g. worn, and weapons) may do well to have their
- // information stored in separate files.
- //
- //*****************************************************************************
- 
- #include "mud.h"
- #include "object.h"
- #include "items.h"
- 
- 
- const char *item_type_names[NUM_ITEM_TYPES] = {
-   "other",
-   "portal",
-   "worn",
-   "weapon",
-   "furniture",
-   "container"
- };
- 
- struct worn_data {
-   char *name;
-   char *positions;
- };
- 
- struct worn_data worn_info[NUM_WORN] = {
-   { "shirt",        "torso",                  },
-   { "gloves",       "left hand, right hand",  },
-   { "left glove",   "left hand",              },
-   { "right glove",  "right hand",             },
-   { "earrings",     "ear, ear",               },
-   { "earring",      "ear",                    },
-   { "ring",         "finger",                 }
- };
- 
- const char *weapon_names[NUM_WEAPONS] = {
-   "dagger",
- };
- 
- const char *furniture_names[NUM_FURNITURES] = {
-   "table furniture",
-   "sitting furniture"
- };
- 
- const char *itemGetType(int item_class) {
-   return item_type_names[item_class];
- }
- 
- const char *itemGetSubtype(int item_class, int subtype) {
-   switch(item_class) {
-   case ITEM_WORN:      return worn_info[subtype].name;
-   case ITEM_WEAPON:    return weapon_names[subtype];
-   case ITEM_FURNITURE: return furniture_names[subtype];
-   // all types with no subtypes
-   default:  return NULL;
-   }
- }
- 
- int numItemTypes() {
-   return NUM_ITEM_TYPES;
- }
- 
- int numItemSubtypes(int item_class) {
-   switch(item_class) {
-   case ITEM_WORN:      return NUM_WORN;
-   case ITEM_WEAPON:    return NUM_WEAPONS;
-   case ITEM_FURNITURE: return NUM_FURNITURES;
-   // all types with no subtypes
-   default:            return 0;
-   }
- }
- 
- const char *wornGetPositions(int worntype) {
-   return worn_info[worntype].positions;
- }
- 
- room_vnum portalGetDestination(OBJ_DATA *portal) {
-   return objGetVal(portal, VAL_PORTAL_DESTINATION);
- }
- 
- int       furnitureGetCapacity(OBJ_DATA *furniture) {
-   return objGetVal(furniture, VAL_FURNITURE_CAPACITY);
- }
- 
- bool      containerIsClosable(OBJ_DATA *container) {
-   return objGetVal(container, VAL_CONTAINER_CLOSABLE);
- }
- 
- bool      containerIsClosed(OBJ_DATA *container) {
-   return objGetVal(container, VAL_CONTAINER_CLOSED);
- }
- 
- bool      containerIsLocked(OBJ_DATA *container) {
-   return objGetVal(container, VAL_CONTAINER_LOCKED);
- }
- 
- obj_vnum  containerGetKey  (OBJ_DATA *container) {
-   return objGetVal(container, VAL_CONTAINER_KEY);
- }
- 
- void      containerSetClosed(OBJ_DATA *container, bool closed) {
-   objSetVal(container, VAL_CONTAINER_CLOSED, closed);
- }
- 
- void      containerSetLocked(OBJ_DATA *container, bool locked) {
-   objSetVal(container, VAL_CONTAINER_LOCKED, locked);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/items.h nakedmudv2.0/src/items.h
*** nakedmudv1.5/src/items.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/items.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,81 ****
- #ifndef __ITEMS_H
- #define __ITEMS_H
- //*****************************************************************************
- //
- // items.h
- //
- // contains numbers of all of the different item types and subtypes. 
- //
- //*****************************************************************************
- #define NUM_OBJ_VALUES          5
- #define VAL_FURNITURE_CAPACITY  0
- 
- #define VAL_PORTAL_DESTINATION  0  // what room does the portal lead to?
- 
- #define VAL_CONTAINER_CLOSABLE  0  // are we closable?
- #define VAL_CONTAINER_KEY       1  // what is the vnum of our key?
- #define VAL_CONTAINER_PICK_DIFF 2  // how hard is it to pick our lock?
- #define VAL_CONTAINER_CLOSED    3  // are we closed currently?
- #define VAL_CONTAINER_LOCKED    4  // are we locked currently?
- 
- #define ITEM_OTHER              0  // anything not specified
- #define ITEM_PORTAL             1  // items for moving around the world
- #define ITEM_WORN               2  // clothes and other protective gear
- #define ITEM_WEAPON             3  // things that hurt people
- #define ITEM_FURNITURE          4  // something people can sit at/on
- #define ITEM_CONTAINER          5  // something for storing other items
- #define NUM_ITEM_TYPES          6
- 
- /* a placeholder for misc items (baubles, trinkets, quest items, etc...) */
- #define NUM_OTHERS            0
- 
- /* a placeholder for all portals */
- #define NUM_PORTALS           0
- 
- /* a placeholder for containers */
- #define NUM_CONTAINERS        0
- 
- /* two main furniture types: those we can sit ON and those we can sit AT */
- #define FURNITURE_AT          0
- #define FURNITURE_ON          1
- #define NUM_FURNITURES        2
- 
- /* worn items: clothes and protective gear */
- #define WORN_SHIRT            0
- #define WORN_GLOVES           1
- #define WORN_LEFT_GLOVE       2
- #define WORN_RIGHT_GLOVE      3
- #define WORN_EARRINGS         4
- #define WORN_EARRING          5
- #define WORN_RING             6
- #define NUM_WORN              7
- 
- /* weapons: stuff that's made to hurt people */
- #define WEAPON_DAGGER         0
- #define NUM_WEAPONS           1
- 
- 
- const char *itemGetType(int item_class);
- const char *itemGetSubtype(int item_class, int subtype);
- 
- int numItemTypes();
- int numItemSubtypes(int item_class);
- 
- const char *wornGetPositions(int worntype);
- 
- 
- //
- // functions for interacting with special item types. Nothing really OLCish,
- // but just stuff to get information about the object.
- //
- room_vnum portalGetDestination(OBJ_DATA *portal);
- int       furnitureGetCapacity(OBJ_DATA *furniture);
- 
- bool      containerIsClosable(OBJ_DATA *container);
- bool      containerIsClosed  (OBJ_DATA *container);
- bool      containerIsLocked  (OBJ_DATA *container);
- obj_vnum  containerGetKey    (OBJ_DATA *container);
- void      containerSetClosed (OBJ_DATA *container, bool closed);
- void      containerSetLocked (OBJ_DATA *container, bool locked);
- 
- #endif // __ ITEMS_H
--- 0 ----
diff -crN nakedmudv1.5/src/list.c nakedmudv2.0/src/list.c
*** nakedmudv1.5/src/list.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/list.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 21,41 ****
  #define TRUE    !(FALSE)
  #endif
  
! struct list_node {
    void *elem;              // the data we contain
    struct list_node *next;  // the next node in the list
    char removed;            // has the item been removed from the list? 
                             // char == bool
! };
  
  struct list_iterator {
    struct list      *L;     // the list we're iterating over
!   struct list_node *curr;  // the current element we're iterating on
  };
  
  struct list {
!   struct list_node *head;  // first element in the list
!   struct list_node *tail;  // last element in the list
    int size;                // how many elements are in the list?
    int iterators;           // how many iterators are going over us?
    int remove_pending;      // do we have to do a remove when the iterators die?
--- 21,41 ----
  #define TRUE    !(FALSE)
  #endif
  
! typedef struct list_node {
    void *elem;              // the data we contain
    struct list_node *next;  // the next node in the list
    char removed;            // has the item been removed from the list? 
                             // char == bool
! } LIST_NODE;
  
  struct list_iterator {
    struct list      *L;     // the list we're iterating over
!   LIST_NODE *curr;         // the current element we're iterating on
  };
  
  struct list {
!   LIST_NODE *head;         // first element in the list
!   LIST_NODE *tail;         // last element in the list
    int size;                // how many elements are in the list?
    int iterators;           // how many iterators are going over us?
    int remove_pending;      // do we have to do a remove when the iterators die?
***************
*** 45,51 ****
  //
  // Delete a list node, and all nodes attached to it
  //
! void deleteListNode(struct list_node *N) {
    if(N->next) deleteListNode(N->next);
    free(N);
  };
--- 45,51 ----
  //
  // Delete a list node, and all nodes attached to it
  //
! void deleteListNode(LIST_NODE *N) {
    if(N->next) deleteListNode(N->next);
    free(N);
  };
***************
*** 53,59 ****
  //
  // delete the list node, plus it's element using the supplied function
  //
! void deleteListNodeWith(struct list_node *N, void (*delete_func)(void *)) {
    if(N->next) deleteListNodeWith(N->next, delete_func);
    // we only want to delete elements that are actually in the list
    if(!N->removed)
--- 53,59 ----
  //
  // delete the list node, plus it's element using the supplied function
  //
! void deleteListNodeWith(LIST_NODE *N, void (*delete_func)(void *)) {
    if(N->next) deleteListNodeWith(N->next, delete_func);
    // we only want to delete elements that are actually in the list
    if(!N->removed)
***************
*** 64,71 ****
  //
  // Create a new list node containing the given element
  //
! struct list_node *newListNode(void *elem) {
!   struct list_node *N = malloc(sizeof(struct list_node));
    N->elem    = elem;
    N->next    = NULL;
    N->removed = FALSE;
--- 64,71 ----
  //
  // Create a new list node containing the given element
  //
! LIST_NODE *newListNode(void *elem) {
!   LIST_NODE *N = malloc(sizeof(LIST_NODE));
    N->elem    = elem;
    N->next    = NULL;
    N->removed = FALSE;
***************
*** 77,86 ****
  // take out all of the nodes that have been flagged as "removed"
  // from the list.
  //
! void listCleanRemoved(struct list *L) {
    // go through and kill all of the elements we removed if removes are pending
    if(L->remove_pending) {
!     struct list_node *node = L->head;
  
      // while our head is a removed element, 
      // pop it off and delete the list node
--- 77,86 ----
  // take out all of the nodes that have been flagged as "removed"
  // from the list.
  //
! void listCleanRemoved(LIST *L) {
    // go through and kill all of the elements we removed if removes are pending
    if(L->remove_pending) {
!     LIST_NODE *node = L->head;
  
      // while our head is a removed element, 
      // pop it off and delete the list node
***************
*** 96,102 ****
        while(node->next != NULL) {
  	// is our next element to be removed?
  	if(node->next->removed) {
! 	  struct list_node *removed = node->next;
  	  node->next = removed->next;
  	  removed->next = NULL;
  	  deleteListNode(removed);
--- 96,102 ----
        while(node->next != NULL) {
  	// is our next element to be removed?
  	if(node->next->removed) {
! 	  LIST_NODE *removed = node->next;
  	  node->next = removed->next;
  	  removed->next = NULL;
  	  deleteListNode(removed);
***************
*** 125,132 ****
  // List interface functions. Documentation in list.h
  //
  //*****************************************************************************
! struct list *newList() {
!   struct list *L    = malloc(sizeof(struct list));
    L->head           = NULL;
    L->tail           = NULL;
    L->size           = 0;
--- 125,132 ----
  // List interface functions. Documentation in list.h
  //
  //*****************************************************************************
! LIST *newList() {
!   LIST *L    = malloc(sizeof(LIST));
    L->head           = NULL;
    L->tail           = NULL;
    L->size           = 0;
***************
*** 136,156 ****
  };
  
  
! void deleteList(struct list *L) {
    if(L->head) deleteListNode(L->head);
    free(L);
  };
  
! void deleteListWith(struct list *L, void *func) {
    if(L->head) deleteListNodeWith(L->head, func);
    free(L);
  }
  
! void listPut(struct list *L, void *elem) {
    if(listIn(L, elem))
      return;
  
!   struct list_node *N = newListNode(elem);
    N->next = L->head;
    L->head = N;
    L->size++;
--- 136,156 ----
  };
  
  
! void deleteList(LIST *L) {
    if(L->head) deleteListNode(L->head);
    free(L);
  };
  
! void deleteListWith(LIST *L, void *func) {
    if(L->head) deleteListNodeWith(L->head, func);
    free(L);
  }
  
! void listPut(LIST *L, void *elem) {
    if(listIn(L, elem))
      return;
  
!   LIST_NODE *N = newListNode(elem);
    N->next = L->head;
    L->head = N;
    L->size++;
***************
*** 159,169 ****
  };
  
  
! void listQueue(struct list *L, void *elem) {
    if(listIn(L, elem))
      return;
  
!   struct list_node *N = newListNode(elem);
  
    if(L->head == NULL) {
      L->head = N;
--- 159,169 ----
  };
  
  
! void listQueue(LIST *L, void *elem) {
    if(listIn(L, elem))
      return;
  
!   LIST_NODE *N = newListNode(elem);
  
    if(L->head == NULL) {
      L->head = N;
***************
*** 177,194 ****
  }
  
  
! void *listPop(struct list *L) {
    return listRemoveNum(L, 0);
  };
  
  
! void listPush(struct list *L, void *elem) {
    listPut(L, elem);
  };
  
  
! int listIn(struct list *L, const void *elem) {
!   struct list_node *N = L->head;
  
    while(N != NULL) {
      if(!N->removed && N->elem == elem)
--- 177,194 ----
  }
  
  
! void *listPop(LIST *L) {
    return listRemoveNum(L, 0);
  };
  
  
! void listPush(LIST *L, void *elem) {
    listPut(L, elem);
  };
  
  
! int listIn(LIST *L, const void *elem) {
!   LIST_NODE *N = L->head;
  
    while(N != NULL) {
      if(!N->removed && N->elem == elem)
***************
*** 200,207 ****
  };
  
  
! int listRemove(struct list *L, const void *elem) {
!   struct list_node *N = L->head;
  
    // we don't have any contents
    if(N == NULL)
--- 200,207 ----
  };
  
  
! int listRemove(LIST *L, const void *elem) {
!   LIST_NODE *N = L->head;
  
    // we don't have any contents
    if(N == NULL)
***************
*** 241,247 ****
  	else {
  	  if(N->next == L->tail)
  	    L->tail = N;
! 	  struct list_node *tmp = N->next;
  	  N->next = tmp->next;
  	  tmp->next = NULL;
  	  deleteListNode(tmp);
--- 241,247 ----
  	else {
  	  if(N->next == L->tail)
  	    L->tail = N;
! 	  LIST_NODE *tmp = N->next;
  	  N->next = tmp->next;
  	  tmp->next = NULL;
  	  deleteListNode(tmp);
***************
*** 256,273 ****
    return FALSE;
  };
  
! void *listRemoveNum(struct list *L, int num) {
    void *elem = listGet(L, num);
    if(elem) listRemove(L, elem);
    return elem;
  }
  
! int listSize(struct list *L) {
    return L->size;
  }
  
! void *listGet(struct list *L, int num) {
!   struct list_node *node = L->head;
    int i;
  
    // move up to our first non-removed node
--- 256,273 ----
    return FALSE;
  };
  
! void *listRemoveNum(LIST *L, int num) {
    void *elem = listGet(L, num);
    if(elem) listRemove(L, elem);
    return elem;
  }
  
! int listSize(LIST *L) {
    return L->size;
  }
  
! void *listGet(LIST *L, int num) {
!   LIST_NODE *node = L->head;
    int i;
  
    // move up to our first non-removed node
***************
*** 283,303 ****
    return (node ? node->elem : NULL);
  }
  
! void *listHead(struct list *L) {
    return L->head;
  }
  
! void *listTail(struct list *L) {
    return L->tail;
  }
  
! int isListEmpty(struct list *L) {
    return (L->size == 0);
  }
  
! void *listGetWith(struct list *L, const void *cmpto, void *func) {
    int (* comparator)(const void *, const void *) = func;
!   struct list_node *node = L->head;
  
    for(node = L->head; node != NULL; node = node->next) {
      if(node->removed)
--- 283,303 ----
    return (node ? node->elem : NULL);
  }
  
! void *listHead(LIST *L) {
    return L->head;
  }
  
! void *listTail(LIST *L) {
    return L->tail;
  }
  
! int isListEmpty(LIST *L) {
    return (L->size == 0);
  }
  
! void *listGetWith(LIST *L, const void *cmpto, void *func) {
    int (* comparator)(const void *, const void *) = func;
!   LIST_NODE *node = L->head;
  
    for(node = L->head; node != NULL; node = node->next) {
      if(node->removed)
***************
*** 308,316 ****
    return NULL;
  }
  
! void *listRemoveWith(struct list *L, const void *cmpto, void *func) {
    int (* comparator)(const void *, const void *) = func;
!   struct list_node *N = L->head;
  
    // we don't have any contents
    if(N == NULL)
--- 308,316 ----
    return NULL;
  }
  
! void *listRemoveWith(LIST *L, const void *cmpto, void *func) {
    int (* comparator)(const void *, const void *) = func;
!   LIST_NODE *N = L->head;
  
    // we don't have any contents
    if(N == NULL)
***************
*** 353,359 ****
  	  void *elem = N->next->elem;
  	  if(N->next == L->tail)
  	    L->tail = N;
! 	  struct list_node *tmp = N->next;
  	  N->next = tmp->next;
  	  tmp->next = NULL;
  	  deleteListNode(tmp);
--- 353,359 ----
  	  void *elem = N->next->elem;
  	  if(N->next == L->tail)
  	    L->tail = N;
! 	  LIST_NODE *tmp = N->next;
  	  N->next = tmp->next;
  	  tmp->next = NULL;
  	  deleteListNode(tmp);
***************
*** 369,377 ****
  }
  
  
! void listPutWith(struct list *L, void *elem, void *func) {
    int (* comparator)(const void *, const void *) = func;
!   struct list_node *N = L->head;
  
    // we don't have any contents, or we're lower than the
    // first list content then just put it at the start
--- 369,377 ----
  }
  
  
! void listPutWith(LIST *L, void *elem, void *func) {
    int (* comparator)(const void *, const void *) = func;
!   LIST_NODE *N = L->head;
  
    // we don't have any contents, or we're lower than the
    // first list content then just put it at the start
***************
*** 386,392 ****
  	int val = comparator(elem, N->next->elem);
  	// we're less than or equal to it... sneak in
  	if(val <= 0) {
! 	  struct list_node *new_node = newListNode(elem);
  	  new_node->next = N->next;
  	  N->next = new_node;
  	  L->size++;
--- 386,392 ----
  	int val = comparator(elem, N->next->elem);
  	// we're less than or equal to it... sneak in
  	if(val <= 0) {
! 	  LIST_NODE *new_node = newListNode(elem);
  	  new_node->next = N->next;
  	  N->next = new_node;
  	  L->size++;
***************
*** 403,412 ****
  }
  
  
! void listSortWith(struct list *L, void *func) {
    // make a new list, and just pop our elements
    // into it while we still have 'em
!   struct list *new_list = newList();
  
    while(listSize(L) > 0)
      listPutWith(new_list, listPop(L), func);
--- 403,412 ----
  }
  
  
! void listSortWith(LIST *L, void *func) {
    // make a new list, and just pop our elements
    // into it while we still have 'em
!   LIST *new_list = newList();
  
    while(listSize(L) > 0)
      listPutWith(new_list, listPop(L), func);
***************
*** 423,433 ****
  }
  
  
! struct list *listCopyWith(struct list *L, void *func) {
    void *(* copy_func)(void *) = func;
!   struct list *newlist = newList();
  
!   struct list_node *N = NULL;
    for(N = L->head; N; N = N->next) {
      if(N->removed) continue;
      listQueue(newlist, copy_func(N->elem));
--- 423,433 ----
  }
  
  
! LIST *listCopyWith(LIST *L, void *func) {
    void *(* copy_func)(void *) = func;
!   LIST *newlist = newList();
  
!   LIST_NODE *N = NULL;
    for(N = L->head; N; N = N->next) {
      if(N->removed) continue;
      listQueue(newlist, copy_func(N->elem));
***************
*** 442,456 ****
  // The functions for the list iterator interface. Documentation is in list.h
  //
  //*****************************************************************************
! struct list_iterator *newListIterator(struct list *L) {
!   struct list_iterator *I = malloc(sizeof(struct list_iterator));
    I->L    = L;
    I->curr = I->L->head;
    L->iterators++;
    return I;
  };
  
! void deleteListIterator(struct list_iterator *I) {
    I->L->iterators--;
    // if we're at 0 iterators, clean the list of all removed elements
    if(I->L->iterators == 0)
--- 442,456 ----
  // The functions for the list iterator interface. Documentation is in list.h
  //
  //*****************************************************************************
! LIST_ITERATOR *newListIterator(LIST *L) {
!   LIST_ITERATOR *I = malloc(sizeof(LIST_ITERATOR));
    I->L    = L;
    I->curr = I->L->head;
    L->iterators++;
    return I;
  };
  
! void deleteListIterator(LIST_ITERATOR *I) {
    I->L->iterators--;
    // if we're at 0 iterators, clean the list of all removed elements
    if(I->L->iterators == 0)
***************
*** 458,464 ****
    free(I);
  };
  
! void *listIteratorNext(struct list_iterator *I) {
    if(I->curr)
      I->curr = I->curr->next;
  
--- 458,464 ----
    free(I);
  };
  
! void *listIteratorNext(LIST_ITERATOR *I) {
    if(I->curr)
      I->curr = I->curr->next;
  
***************
*** 471,477 ****
  
  // hmmm... we should really kill this function. 
  // Just let 'em create a new iterator
! void listIteratorReset(struct list_iterator *I) {
    // if we're the only iterator, take this opportunity to clean the list
    if(I->L->iterators == 1)
      listCleanRemoved(I->L);
--- 471,477 ----
  
  // hmmm... we should really kill this function. 
  // Just let 'em create a new iterator
! void listIteratorReset(LIST_ITERATOR *I) {
    // if we're the only iterator, take this opportunity to clean the list
    if(I->L->iterators == 1)
      listCleanRemoved(I->L);
***************
*** 479,485 ****
    I->curr = I->L->head;
  };
  
! void *listIteratorCurrent(struct list_iterator *I) {
    // hmmm... what if we're on a removed node?
    while(I->curr && I->curr->removed)
      I->curr = I->curr->next;
--- 479,485 ----
    I->curr = I->L->head;
  };
  
! void *listIteratorCurrent(LIST_ITERATOR *I) {
    // hmmm... what if we're on a removed node?
    while(I->curr && I->curr->removed)
      I->curr = I->curr->next;
diff -crN nakedmudv1.5/src/list.d nakedmudv2.0/src/list.d
*** nakedmudv1.5/src/list.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/list.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ list.d list.o: list.c list.h
diff -crN nakedmudv1.5/src/list.h nakedmudv2.0/src/list.h
*** nakedmudv1.5/src/list.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/list.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 13,22 ****
  //
  //*****************************************************************************
  
  //
  // Create a new list
  //
! struct list *newList();
  
  
  //
--- 13,25 ----
  //
  //*****************************************************************************
  
+ typedef struct list                       LIST;
+ typedef struct list_iterator              LIST_ITERATOR;
+ 
  //
  // Create a new list
  //
! LIST *newList();
  
  
  //
***************
*** 30,116 ****
  // that is passed in. The function should take one argument, and should be
  // compatible with the type of data in the list
  //
! void deleteListWith(struct list *L, void *func);
  
  
  //
  // Add an element to the list
  //
! void listPut(struct list *L, void *elem);
  
  
  //
  // Add an element to the end of the list
  //
! void listQueue(struct list *L, void *elem);
  
  
  //
  // Return true if the element is in the list. False otherwise
  //
! int listIn(struct list *L, const void *elem);
  
  
  //
  // Remove all instances of the elem from the list. Return
  // true if successful, and false otherwise.
  //
! int listRemove(struct list *L, const void *elem);
  
  
  //
  // Remove the element in the list at the specified place,
  // and return it
  //
! void *listRemoveNum(struct list *L, int num);
  
  
  //
  // remove the first element in the list, and return it
  //
! void *listPop(struct list *L);
  
  
  //
  // add the item to the head of the list
  //
! void listPush(struct list *L, void *elem);
  
  
  //
  // How many elements does the list have?
  //
! int listSize(struct list *L);
  
  //
  // Is the list empty?
  //
! int isListEmpty(struct list *L);
  
  
  //
  // get the element with the specific number
  //
! void *listGet(struct list *L, int num);
  
  
  //
  // Return the head of the list
  //
! void *listHead(struct list *L);
  
  
  //
  // Return the tail of the list
  //
! void *listTail(struct list *L);
  
  
  //
  // Put the element in the list in an ascending order, based on
  // what the comparator, func, tells us is the order.
  //
! void listPutWith(struct list *L, void *elem, void *func);
  
  
  //
--- 33,119 ----
  // that is passed in. The function should take one argument, and should be
  // compatible with the type of data in the list
  //
! void deleteListWith(LIST *L, void *func);
  
  
  //
  // Add an element to the list
  //
! void listPut(LIST *L, void *elem);
  
  
  //
  // Add an element to the end of the list
  //
! void listQueue(LIST *L, void *elem);
  
  
  //
  // Return true if the element is in the list. False otherwise
  //
! int listIn(LIST *L, const void *elem);
  
  
  //
  // Remove all instances of the elem from the list. Return
  // true if successful, and false otherwise.
  //
! int listRemove(LIST *L, const void *elem);
  
  
  //
  // Remove the element in the list at the specified place,
  // and return it
  //
! void *listRemoveNum(LIST *L, int num);
  
  
  //
  // remove the first element in the list, and return it
  //
! void *listPop(LIST *L);
  
  
  //
  // add the item to the head of the list
  //
! void listPush(LIST *L, void *elem);
  
  
  //
  // How many elements does the list have?
  //
! int listSize(LIST *L);
  
  //
  // Is the list empty?
  //
! int isListEmpty(LIST *L);
  
  
  //
  // get the element with the specific number
  //
! void *listGet(LIST *L, int num);
  
  
  //
  // Return the head of the list
  //
! void *listHead(LIST *L);
  
  
  //
  // Return the tail of the list
  //
! void *listTail(LIST *L);
  
  
  //
  // Put the element in the list in an ascending order, based on
  // what the comparator, func, tells us is the order.
  //
! void listPutWith(LIST *L, void *elem, void *func);
  
  
  //
***************
*** 119,125 ****
  // only take one argument. cmpto must be the thing we are compared against
  // in func.
  //
! void *listGetWith(struct list *L, const void *cmpto, void *func);
  
  
  //
--- 122,128 ----
  // only take one argument. cmpto must be the thing we are compared against
  // in func.
  //
! void *listGetWith(LIST *L, const void *cmpto, void *func);
  
  
  //
***************
*** 127,133 ****
  // TRUE if the item was found and removed. FALSE other wise. Cmpto must
  // be the thing we are compared against in func.
  //
! void *listRemoveWith(struct list *L, const void *cmpto, void *func);
  
  
  //
--- 130,136 ----
  // TRUE if the item was found and removed. FALSE other wise. Cmpto must
  // be the thing we are compared against in func.
  //
! void *listRemoveWith(LIST *L, const void *cmpto, void *func);
  
  
  //
***************
*** 135,179 ****
  // Func takes two arguments, and returns 0 if the two match. -1 is returned
  // if the first is less than the second, and 1 otherwise.
  //
! void listSortWith(struct list *L, void *func);
  
  
  //
  // Make a copy of the list. func is a function that takes one argument (the
  // data that is in the list) and returns a copy of that data.
  //
! struct list *listCopyWith(struct list *L, void *func);
  
  
  //
  // Create an iterator to go over the list
  //
! struct list_iterator *newListIterator(struct list *L);
  
  
  //
  // Delete the list iterator (but not the contents)
  //
! void deleteListIterator(struct list_iterator *I);
  
  
  //
  // Point the list iterator back at the head of the list
  //
! void listIteratorReset(struct list_iterator *I);
  
  
  //
  // Skip to the next element in the list. Return the next element
  // if one exists, and NULL otherwise.
  //
! void *listIteratorNext(struct list_iterator *I);
  
  
  //
  // return a pointer to the current list element
  //
! void *listIteratorCurrent(struct list_iterator *I);
  
  
  #endif // __LIST_H
--- 138,182 ----
  // Func takes two arguments, and returns 0 if the two match. -1 is returned
  // if the first is less than the second, and 1 otherwise.
  //
! void listSortWith(LIST *L, void *func);
  
  
  //
  // Make a copy of the list. func is a function that takes one argument (the
  // data that is in the list) and returns a copy of that data.
  //
! LIST *listCopyWith(LIST *L, void *func);
  
  
  //
  // Create an iterator to go over the list
  //
! LIST_ITERATOR *newListIterator(LIST *L);
  
  
  //
  // Delete the list iterator (but not the contents)
  //
! void deleteListIterator(LIST_ITERATOR *I);
  
  
  //
  // Point the list iterator back at the head of the list
  //
! void listIteratorReset(LIST_ITERATOR *I);
  
  
  //
  // Skip to the next element in the list. Return the next element
  // if one exists, and NULL otherwise.
  //
! void *listIteratorNext(LIST_ITERATOR *I);
  
  
  //
  // return a pointer to the current list element
  //
! void *listIteratorCurrent(LIST_ITERATOR *I);
  
  
  #endif // __LIST_H
diff -crN nakedmudv1.5/src/log.d nakedmudv2.0/src/log.d
*** nakedmudv1.5/src/log.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/log.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ log.d log.o: log.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h utils.h character.h storage.h log.h
diff -crN nakedmudv1.5/src/login.c nakedmudv2.0/src/login.c
*** nakedmudv1.5/src/login.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/login.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,328 ----
+ //*****************************************************************************
+ //
+ // login.c
+ //
+ // Different muds will want to set up the login process in very different ways;
+ // as such, I figured it would be good to localize all of the login details to
+ // a single file for people to tailor to their specific mud. It also makes
+ // updating to newer versions a bit easier. Your login procedure should be laid
+ // out here. A basic framework is given, but it could use lots of work. In fact,
+ // it is crap and could use LOTS of work. I encourage people to write their own
+ // login procedure and submit their designs to me so I can develop a better
+ // general method for later versions of the mud.
+ //
+ //*****************************************************************************
+ 
+ #include "mud.h"
+ #include "utils.h"
+ #include "socket.h"
+ #include "character.h"
+ #include "handler.h"
+ #include "inform.h"
+ #include "world.h"
+ #include "races.h"
+ #include "save.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "scripts/script.h"
+ 
+ 
+ 
+ // mccp support
+ const unsigned char do_echo         [] = { IAC, WONT, TELOPT_ECHO,      '\0' };
+ const unsigned char dont_echo       [] = { IAC, WILL, TELOPT_ECHO,      '\0' };
+ 
+ 
+ // input handlers
+ void state_new_name       (SOCKET_DATA *dsock, char *arg);
+ void state_ask_password   (SOCKET_DATA *dsock, char *arg);
+ void state_new_password   (SOCKET_DATA *dsock, char *arg);
+ void state_verify_password(SOCKET_DATA *dsock, char *arg);
+ void state_ask_sex        (SOCKET_DATA *dsock, char *arg);
+ void state_ask_race       (SOCKET_DATA *dsock, char *arg);
+ 
+ 
+ 
+ //
+ // the head honcho. This is the first handler that a socket enters once it has
+ // connected to the game. You should use this function to get your login 
+ // procedure rolling.
+ void handle_new_connections(SOCKET_DATA *dsock, char *arg) {
+   state_new_name(dsock, arg);
+ }
+ 
+ 
+ 
+ 
+ //*****************************************************************************
+ // Contained blow are the functions required for logging on an old character,
+ // or creating a new character. Hmmm, wouldn't it be nice if players had one 
+ // account where they could have all their multiple characters listed, as
+ // opposed to a bunch of different characters? Perhaps this is something to
+ // consider for later versions of the MUD.
+ //*****************************************************************************
+ 
+ //
+ // Ask a new connection for a name. This is the first thing that is called
+ // whenever a new socket connects to us
+ void state_new_name(SOCKET_DATA *dsock, char *arg) {
+   CHAR_DATA *p_new;
+ 
+   if (socketGetDNSLookupStatus(dsock) != TSTATE_DONE) {
+     text_to_buffer(dsock, 
+ 		   "Making a dns lookup, please have patience.\n\r"
+ 		   "What is your name? ");
+     return;
+   }
+   // check for a legal name
+   if (!check_name(arg)) {
+     text_to_buffer(dsock, 
+ 		   "Sorry, that's not a legal name, please pick another.\n\r"
+ 		   "What is your name? ");
+     return; // break;
+   }
+   arg[0] = toupper(arg[0]);
+   log_string("%s is trying to connect.", arg);
+ 
+ 
+   // Check for a new Player 
+   if ((p_new = load_profile(arg)) == NULL) {
+     p_new = newChar();
+ 
+     // give the player it's name 
+     charSetName(p_new, arg);
+ 
+     // and room description. In the future, we may want
+     // to consider allowing players to set their own rdescs 
+     char rdesc[SMALL_BUFFER];
+     sprintf(rdesc, "%s is here.", arg);
+     charSetRdesc(p_new, rdesc);
+ 
+     // prepare for next step 
+     text_to_buffer(dsock, "Please enter a new password: ");
+     socketReplaceInputHandler(dsock, state_new_password, NULL);
+   }
+   // old player
+   else {
+     // prepare for next step 
+     text_to_buffer(dsock, "What is your password? ");
+     socketReplaceInputHandler(dsock, state_ask_password, NULL);
+   }
+   text_to_buffer(dsock, (char *)dont_echo);
+ 
+   // socket <-> player 
+   charSetSocket(p_new, dsock);
+   socketSetChar(dsock, p_new);
+ }
+ 
+ 
+ //
+ // Ask a character for a password. This is only called once, when
+ // the character first creates.
+ void state_new_password(SOCKET_DATA *dsock, char *arg) {
+   if (strlen(arg) < 5 || strlen(arg) > 12) {
+     text_to_buffer(dsock, 
+ 		   "\r\nBetween 5 and 12 chars please!\n\r"
+ 		   "Please enter a new password: ");
+     return;
+   }
+   charSetPassword(socketGetChar(dsock), 
+ 		  crypt(arg, charGetName(socketGetChar(dsock))));
+ 
+   //
+   // Why is this here? Is this because of old pfiles that terminated strings
+   // with a tilde?
+   //   - Geoff, Mar 21/05
+   if(strchr(charGetPassword(socketGetChar(dsock)), '~') != NULL) {
+       text_to_buffer(dsock, "Illegal password!\n\r"
+ 		            "Please enter a new password: ");
+   }
+   else {
+     text_to_buffer(dsock, "\r\nPlease verify the password: ");
+     socketReplaceInputHandler(dsock, state_verify_password, NULL);
+   }
+ }
+ 
+ 
+ //
+ // Verify that the character's new password is correct. This is
+ // only called once, when the character creates
+ void state_verify_password(SOCKET_DATA *dsock, char *arg) {
+   if (compares(crypt(arg, charGetName(socketGetChar(dsock))), 
+ 	       charGetPassword(socketGetChar(dsock)))) {
+     text_to_buffer(dsock, (char *) do_echo);
+ 
+     // onto the sex check 
+     text_to_buffer(dsock, "\r\nWhat is your sex (M/F/N): ");
+     socketReplaceInputHandler(dsock, state_ask_sex, NULL);
+   }
+   else {
+     charSetPassword(socketGetChar(dsock), NULL);
+     text_to_buffer(dsock, 
+ 		   "\r\nPassword mismatch!\n\r"
+ 		   "Please enter a new password: ");
+     socketReplaceInputHandler(dsock, state_new_password, NULL);
+   }
+ }
+ 
+ void list_races(SOCKET_DATA *sock) {
+   send_to_socket(sock, "Available races are:\r\n");
+   send_to_socket(sock, "%s", raceGetList(TRUE));
+   send_to_socket(sock, "\r\n\r\nPlease enter your choice: ");
+ }
+ 
+ //
+ // Ask for the character's race. Called each time a character is created
+ void state_ask_race(SOCKET_DATA *dsock, char *arg) {
+   if(!arg || !*arg || !raceIsForPC(arg)) {
+     send_to_socket(dsock, "Invalid race! Please try again: ");
+     return;
+   }    
+   else {
+     charSetRace(socketGetChar(dsock), arg);
+     charResetBody(socketGetChar(dsock));
+   }
+ 
+   // give the character a unique id 
+   charSetUID(socketGetChar(dsock), next_char_uid());
+ 
+   // if it's the first player, set him as the highest level 
+   if(charGetUID(socketGetChar(dsock)) == 1)
+     charSetLevel(socketGetChar(dsock), MAX_LEVEL);
+ 
+   // add the character to the game 
+   char_to_game(socketGetChar(dsock));
+ 
+   log_string("New player: %s has entered the game.", 
+ 	     charGetName(socketGetChar(dsock)));
+     
+   // and into the game 
+   // pop the input handler for char creation and add the one for
+   // playing the game
+   socketReplaceInputHandler(dsock, handle_cmd_input, show_prompt);
+   text_to_buffer(dsock, motd);
+ 
+   // we should do some checks here to make sure the start room exists
+   char_to_room(socketGetChar(dsock), worldGetRoom(gameworld, START_ROOM));
+   look_at_room(socketGetChar(dsock), charGetRoom(socketGetChar(dsock)));
+ 
+   // and save him 
+   save_player(socketGetChar(dsock));
+ 
+   // check enterance scripts
+   try_enterance_script(socketGetChar(dsock), charGetRoom(socketGetChar(dsock)), NULL);
+ }
+ 
+ //
+ // Ask for the character's sex. This will be called each time the
+ // character creates
+ void state_ask_sex(SOCKET_DATA *dsock, char *arg) {
+   switch(*arg) {
+   case 'f':
+   case 'F':
+     charSetSex(socketGetChar(dsock), SEX_FEMALE);
+     break;
+   case 'm':
+   case 'M':
+     charSetSex(socketGetChar(dsock), SEX_MALE);
+     break;
+   case 'n':
+   case 'N':
+     charSetSex(socketGetChar(dsock), SEX_NEUTRAL);
+     break;
+   default:
+     text_to_buffer(dsock, "\r\nInvalid sex. Try again (M/F/N) :");
+     return;
+   }
+ 
+   // onto the password check 
+   socketReplaceInputHandler(dsock, state_ask_race, NULL);
+   list_races(dsock);
+ }
+ 
+ 
+ //
+ // Ask the character for his or her password. This will be called
+ // every time the character logs on, after the first time when the
+ // character creates
+ void state_ask_password(SOCKET_DATA *dsock, char *arg) {
+   CHAR_DATA *p_new;
+ 
+   text_to_buffer(dsock, (char *) do_echo);
+   if (compares(crypt(arg, charGetName(socketGetChar(dsock))), 
+ 	       charGetPassword(socketGetChar(dsock))))
+   {
+     if ((p_new = check_reconnect(charGetName(socketGetChar(dsock)))) != NULL) {
+       // we do NOT want to extract, here... the player hasn't even
+       // entered the game yet. We just want to DELETE the profile character
+       deleteChar(socketGetChar(dsock));
+ 
+       // attach the new player 
+       socketSetChar(dsock, p_new);
+       charSetSocket(p_new, dsock);
+ 
+       log_string("%s has reconnected.", charGetName(socketGetChar(dsock)));
+ 
+       // and let him enter the game 
+       // pop the input handler for char creation and add the one for
+       // playing the game
+       socketReplaceInputHandler(dsock, handle_cmd_input, show_prompt);
+       text_to_buffer(dsock, "You take over a body already in use.\n\r");
+     }
+     else if ((p_new = load_player(charGetName(socketGetChar(dsock)))) == NULL) {
+       text_to_socket(dsock, "ERROR: Your pfile is missing!\n\r");
+       // no extract, just delete! We haven't entered the game yet,
+       // so there is no need to extract
+       deleteChar(socketGetChar(dsock));
+ 
+       socketSetChar(dsock, NULL);
+       close_socket(dsock, FALSE);
+       return;
+     }
+     else {
+       // No extract, just delete. We have not entered the game yet,
+       // so there is no need to extract from it.
+       deleteChar(socketGetChar(dsock));
+ 
+       // attach the new player 
+       socketSetChar(dsock, p_new);
+       charSetSocket(p_new, dsock);
+ 
+       // try putting the character into the game.
+       // Close the socket if we fail
+       if(try_enter_game(p_new)) {
+ 	log_string("%s has entered the game.", charGetName(p_new));
+ 	// we're no longer in the creation process... attach the game
+ 	// input handler
+ 	socketReplaceInputHandler(dsock, handle_cmd_input, show_prompt);
+ 
+ 	text_to_buffer(dsock, motd);
+ 	look_at_room(p_new, charGetRoom(p_new));
+ 
+ 	// check enterance scripts
+ 	try_enterance_script(p_new, charGetRoom(p_new), NULL);
+       }
+       else {
+ 	// do not extract, just delete. We failed to enter
+ 	// the game, so there is no need to extract from the game.
+ 	deleteChar(socketGetChar(dsock));
+ 
+ 	socketSetChar(dsock, NULL);
+ 	close_socket(dsock, FALSE);
+       }
+     }
+   }
+   else {
+     text_to_socket(dsock, "Bad password!\n\r");
+     // do not extract, just delete. We have not entered the game
+     // yet, so there is no need to extract from the game.
+     deleteChar(socketGetChar(dsock));
+ 
+     socketSetChar(dsock, NULL);
+     close_socket(dsock, FALSE);
+   }
+ }
diff -crN nakedmudv1.5/src/login.d nakedmudv2.0/src/login.d
*** nakedmudv1.5/src/login.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/login.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ login.d login.o: login.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h character.h \
+   handler.h inform.h world.h races.h save.h scripts/script.h
diff -crN nakedmudv1.5/src/magic.c nakedmudv2.0/src/magic.c
*** nakedmudv1.5/src/magic.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/magic.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,632 ****
- //*****************************************************************************
- //
- // magic.c
- //
- // A little magic system that has similarities to Richard Bartle's Spellbinder
- // (http://www.mud.co.uk/richard/spellbnd.htm). Players chain gestures 
- // together to make magical effects happen. The system is a little bit 
- // different, in that players have to draw on power from different sources 
- // (fire, water, earth, air) before they can cast spells. They can combine
- // powers from different sources to make more elaborate powers (e.g. fire +
- // earth = magma). Other differences exist; for instance, this magic system
- // is realtime, whereas Bartle's is turn-based. Characters have to "spend"
- // and "tap" magic power, whereas in Bartle's game, magic did not have a source
- // one had to draw into, or magic power one had to spend.
- //
- //*****************************************************************************
- 
- #include "mud.h"
- #include "utils.h"
- #include "event.h"
- #include "action.h"
- #include "magic.h"
- #include "character.h"   // send_to_char()
- #include "inform.h"      // message()
- 
- 
- 
- //*****************************************************************************
- //
- // local data, structures, and functions
- //
- //*****************************************************************************
- 
- // how often do we check for mana increases and manaburn?
- #define MAG_EVENT_DELAY      (5 SECONDS)
- #define MAG_ACTION_DELAY      (1 SECOND)
- #define MANABURN_MIN                  5
- 
- 
- //
- // Where all of our characters and their actions are stored
- //
- HASHMAP *mag_map = NULL;
- 
- 
- 
- //
- // All of the info we need for keeping track of the magic
- // status of a character.
- //
- typedef struct mag_data {
-   char *lh_actions;  // the movements we've made with our left hand
-   char *rh_actions;  // and with our right hand
- 
-   char lh_action;    // what action are we taking this time around?
-   char rh_action;    // and in our right hand?
- 
-   char lh_tapping;   // what magic is our left hand tapping?
-   char rh_tapping;   // what magic is our right hand tapping?
- 
-   int mana_fire;     // how much mana have we accumulated for various elements?
-   int mana_water;    
-   int mana_earth;
-   int mana_air;
- 
-   int barrier_fire;  // how protected are we from fire damage?
-   int barrier_water;
-   int barrier_earth;
-   int barrier_air;
- 
- } MAG_DATA;
- 
- 
- //
- // create a new magic entry
- //
- MAG_DATA *newMagic(void) {
-   MAG_DATA *magic = malloc(sizeof(MAG_DATA));
-   bzero(magic, sizeof(MAG_DATA));
-   magic->lh_actions = strdup("");
-   magic->rh_actions = strdup("");
-   magic->lh_action  = MAG_ACTION_NONE;
-   magic->rh_action  = MAG_ACTION_NONE;
-   magic->lh_tapping = MAG_ACTION_NONE;
-   magic->rh_tapping = MAG_ACTION_NONE;
-   return magic;
- }
- 
- 
- //
- // Delete a magic entry
- //
- void deleteMagic(MAG_DATA *magic) {
-   if(magic->lh_actions) free(magic->lh_actions);
-   if(magic->rh_actions) free(magic->rh_actions);
-   free(magic);
- }
- 
- typedef struct mag_action {
-   char      action;
-   int        delay;
-   char    *ch_mssg;
-   char *other_mssg;
- } MAG_ACTION;
- 
- 
- MAG_ACTION mag_actions[] = {
-   { MAG_ACTION_PUSH,   1 SECOND,
-     "You thrust your %s palm out in front of you",
-     "$n thrusts $s %s palm outwards" },
-   { MAG_ACTION_ARC,    1 SECOND,
-     "You raise your %s hand up in a large arc",
-     "$n arcs $s %s high above $s head" },
-   { MAG_ACTION_LOWER,  1 SECOND,
-     "You lower your %s hand",
-     "$n lowers $s hand" },
-   { MAG_ACTION_WIGGLE, 1 SECOND,
-     "You wiggle the fingers on your %s hand",
-     "$n begins wiggling the fingers on $s %s hand" },
-   { MAG_ACTION_SNAP,   1 SECOND,
-     "You snap the thumb and forefinger on your %s hand",
-     "$n snaps the thumb and forefinger on $s %s hand" },
-   { MAG_ACTION_PALM,   1 SECOND,
-     "You slowly begin rising your %s hand, palm upwards",
-     "$n slowly begins rising $s %s palm upwards" },
-   { MAG_ACTION_FINGER, 1 SECOND,
-     "You thrust the finger on your %s hand outwards",
-     "$n thrusts the finger on $s %s hand outwards" },
- 
- 
-   { MAG_ACTION_NONE, 0 SECONDS, "", "" } // sentinel
- };
- 
- 
- typedef struct mag_effect {
-   int   effect;          // what effect does it do?
-   int   cost;            // what's the cost in mana?
-   char *hand_movement;   // what is the hand movement?
- } MAG_EFFECT;
- 
- 
- MAG_EFFECT mag_effects_fire[] = {
-   { MAG_EFFECT_FIREBOLT,    2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- MAG_EFFECT mag_effects_water[] = {
-   { MAG_EFFECT_ACIDBOLT,    2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- MAG_EFFECT mag_effects_earth[] = {
-   { MAG_EFFECT_STONESPEAR,  2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- MAG_EFFECT mag_effects_air[] = {
-   { MAG_EFFECT_SHOCK,       2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- 
- 
- //
- // get the magic table associated with the mana that has been tapped
- //
- MAG_EFFECT *get_mag_table(MAG_DATA *magic) {
-   if(magic->mana_fire > 0 && 
-      magic->mana_water == 0 && magic->mana_earth == 0 && magic->mana_air == 0)
-     return mag_effects_fire;
-   if(magic->mana_water > 0 && 
-      magic->mana_fire == 0 && magic->mana_earth == 0 && magic->mana_air == 0)
-     return mag_effects_water;
-   if(magic->mana_earth > 0 && 
-      magic->mana_water == 0 && magic->mana_fire == 0 && magic->mana_air == 0)
-     return mag_effects_earth;
-   if(magic->mana_air > 0 && 
-      magic->mana_water == 0 && magic->mana_earth == 0 && magic->mana_fire == 0)
-     return mag_effects_air;
- 
-   return NULL;
- }
- 
- 
- //
- // look in the table to see if we've completed any of the actions it has
- //
- int check_for_mag_effect(const MAG_EFFECT *mag_effects, 
- 			 const char *actions) {
-   int i;
-   int act_len = strlen(actions);
- 
-   // go through our list of effects, and search
-   for(i = 0; mag_effects[i].effect != MAG_EFFECT_NONE; i++) {
-     int move_len = strlen(mag_effects[i].hand_movement);
- 
-     // make sure we've performed enough actions
-     if(act_len < move_len)
-       continue;
- 
-     // go in reverse for both of them
-     int j;
-     char *movement = mag_effects[i].hand_movement;
-     for(j = move_len-1; j >= 0; j--)
-       if(movement[j] != actions[act_len-move_len+j])
- 	break;
- 
-     // if we got right to the end, we found a match
-     if(j == -1)
-       break;
-   }
- 
-   return i;
- }
- 
- const char *mag_hand_name(char hand) {
-   return (hand == MAG_HAND_LEFT ? "left" :
- 	  (hand == MAG_HAND_RIGHT ? "right" : "BUG"));
- }
- 
- const char *mag_tap_name(char tap_type) {
-   return (tap_type == MAG_ACTION_TAP_FIRE ? "fire" :
- 	  (tap_type == MAG_ACTION_TAP_WATER ? "water" :
- 	   (tap_type == MAG_ACTION_TAP_EARTH ? "earth" :
- 	    (tap_type == MAG_ACTION_TAP_AIR ? "air" : "BUG"))));
- }
- 
- const char *mag_tap_color(char tap_type) {
-   return (tap_type == MAG_ACTION_TAP_FIRE ? "red" :
- 	  (tap_type == MAG_ACTION_TAP_WATER ? "blue" :
- 	   (tap_type == MAG_ACTION_TAP_EARTH ? "brown" :
- 	    (tap_type == MAG_ACTION_TAP_AIR ? "white" : "BUG"))));
- }
- 
- 
- void do_mag_effect(CHAR_DATA *ch, CHAR_DATA *vict, int effect) {
-   switch(effect) {
-   case MAG_EFFECT_FIREBOLT:
-   case MAG_EFFECT_ACIDBOLT:
-   case MAG_EFFECT_STONESPEAR:
-   case MAG_EFFECT_SHOCK:
-     send_to_char(ch, "You cast a basic spell at %s!\r\n", 
- 		 (vict ? charGetName(vict) : "nobody"));
-     break;
- 
-     // nothing
-   default: 
-     break;
-   }
- }
- 
- 
- //
- // Inform the character (and room) that the character has lost his
- // connection to a mana source
- //
- void magic_stop_message(CHAR_DATA *ch, char tap_type) {
-   send_to_char(ch, "Your connection with the plane of %s is cut short.\r\n",
- 	       mag_tap_name(tap_type));
-   message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR, 
- 	  "The %s aura around $n's body wanes.", mag_tap_color(tap_type));
- }
- 
- 
- //
- // Inform the character (and room) that the character has begun tapping mana
- //
- void tap_start_message(CHAR_DATA *ch, char hand, char tap_type) {
-   send_to_char(ch, 
- 	       "You begin tapping into the plane of %s with your %s hand.\r\n",
- 	       mag_tap_name(tap_type), mag_hand_name(hand));
-   message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 	  "$n upraises $s %s palm, and it becomes shrouded in a %s aura.",
- 	  mag_hand_name(hand), mag_tap_color(tap_type));
- }
- 
- 
- //
- // Inform the character (and room) that the character has begun tapping mana
- //
- void tap_stop_message(CHAR_DATA *ch, char hand, char tap_type) {
-   send_to_char(ch, 
- 	       "You stop tapping into the plane of %s with your %s hand.\r\n",
- 	       mag_tap_name(tap_type), mag_hand_name(hand));
-   message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 	  "$n lowers $s %s palm, and the %s aura around it dims slightly.",
- 	  mag_hand_name(hand), mag_tap_color(tap_type));
- }
- 
- 
- //
- // return true if the action is mana-tapping-oriented
- //
- bool mag_action_is_tap(char action) {
-   return (action == MAG_ACTION_TAP_FIRE  || action == MAG_ACTION_TAP_AIR   ||
- 	  action == MAG_ACTION_TAP_WATER || action == MAG_ACTION_TAP_EARTH);
- }
- 
- 
- //
- // Set a character to start tapping in one hand
- //
- void start_tapping(CHAR_DATA *ch, MAG_DATA *magic, char hand, char action) {
-   if(hand == MAG_HAND_LEFT) {
-     magic->lh_tapping = action;
-     tap_start_message(ch, hand, action);
-   }
-   else if(hand == MAG_HAND_RIGHT) {
-     magic->rh_tapping = action;
-     tap_start_message(ch, hand, action);
-   }
- }
- 
- 
- //
- // Stop a character tapping in one hand
- //
- void stop_tapping(CHAR_DATA *ch, MAG_DATA *magic, char hand) {
-   if(hand == MAG_HAND_LEFT) {
-     tap_stop_message(ch, hand, magic->lh_tapping);
-     magic->lh_tapping = MAG_ACTION_NONE;
-   }
-   else if(hand == MAG_HAND_RIGHT) {
-     tap_stop_message(ch, hand, magic->rh_tapping);
-     magic->rh_tapping = MAG_ACTION_NONE;
-   }
- }
- 
- 
- //
- // Show the message that accompanies a hand gesture
- //
- void show_mag_action_message(CHAR_DATA *ch, char hand, char action) {
-   int i;
-   for(i = 0; mag_actions[i].action != MAG_ACTION_NONE; i++) {
-     if(action == mag_actions[i].action) {
-       message(ch, NULL, NULL, NULL, TRUE, TO_CHAR,
- 	      mag_actions[i].ch_mssg, mag_hand_name(hand));
-       message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 	      mag_actions[i].other_mssg, mag_hand_name(hand));
-       break;
-     }
-   }
- }
- 
- 
- 
- //*****************************************************************************
- //
- // implementation of magic.h
- //
- //*****************************************************************************
- 
- void init_magic() {
-   // use standard hashing function and comparator
-   mag_map = newHashmap(NULL, NULL, 50);
- }
- 
- 
- //
- // Check if the magic is involved in an event. Basically, straight comparison
- //
- int check_mag_event_involvement(void *thing, MAG_DATA *magic) {
-   return (thing == magic);
- }
- 
- 
- //
- // Handle the completion of a magic action, and let everyone know
- //
- void handle_mag_action(CHAR_DATA *ch, MAG_DATA *magic, 
- 		       bitvector_t where, char *arg) {
-   // do something about seeing if we're tapping mana
-   if(mag_action_is_tap(magic->lh_action)) {
-     start_tapping(ch, magic, MAG_HAND_LEFT, magic->lh_action);
-     // now, free our history ... nothing starts with a tap
-     free(magic->lh_actions); magic->lh_actions = strdup("");
-   }
-   if(mag_action_is_tap(magic->rh_action)) {
-     start_tapping(ch, magic, MAG_HAND_RIGHT, magic->rh_action);
-     // now, free our history ... nothing starts with a tap
-     free(magic->rh_actions); magic->rh_actions = strdup("");
-   }
- 
-   if(magic->lh_action != MAG_ACTION_NONE)
-     show_mag_action_message(ch, MAG_HAND_LEFT,  magic->lh_action);
-   if(magic->rh_action != MAG_ACTION_NONE)
-     show_mag_action_message(ch, MAG_HAND_RIGHT, magic->rh_action);
- 
-   // based on the mana we've accumulated, figure out what table to use
-   MAG_EFFECT *table = get_mag_table(magic);
- 
-   // now, see if we've created any magical effects
-   if(table && magic->lh_action != MAG_ACTION_NONE) {
-     int entry = check_for_mag_effect(table, magic->lh_actions);
-     do_mag_effect(ch, NULL, table[entry].effect);
-   }
-   if(table && magic->rh_action != MAG_ACTION_NONE) {
-     int entry = check_for_mag_effect(table, magic->rh_actions);
-     do_mag_effect(ch, NULL, table[entry].effect);
-   }
- 
-   magic->lh_action = MAG_ACTION_NONE;
-   magic->rh_action = MAG_ACTION_NONE;
- }
- 
- 
- //
- // Stop the action prematurely
- //
- void interrupt_mag_action(CHAR_DATA *ch, MAG_DATA *magic, 
- 			  bitvector_t where, char *arg) {
-   if(magic->lh_action != MAG_ACTION_NONE) {
-     send_to_char(ch, "You stop performing your left hand action.\r\n");
-     magic->lh_action = MAG_ACTION_NONE;
-   }
- 
-   if(magic->rh_action != MAG_ACTION_NONE) {
-     send_to_char(ch, "You stop performing your right hand action.\r\n");
-     magic->rh_action = MAG_ACTION_NONE;
-   }
- }
- 
- 
- //
- // Update the magic status (increasing mana, giving manaburn, etc...) and
- // throw it back into the event handler
- //
- void handle_mag_event(CHAR_DATA *ch, MAG_DATA *magic, const char *arg) {
-   // up our mana by 2 and decrease our mana reserves by 1
-   // essentially, this results in +1 mana when we are actively tapping
-   // a manasource (+3 if we are tapping with both hands) and -1 if we
-   // are not tapping.
-   magic->mana_fire  += 2*((magic->lh_tapping == MAG_ACTION_TAP_FIRE) + 
- 			  (magic->rh_tapping == MAG_ACTION_TAP_FIRE));
-   magic->mana_water += 2*((magic->lh_tapping == MAG_ACTION_TAP_WATER) +
- 			  (magic->rh_tapping == MAG_ACTION_TAP_WATER));
-   magic->mana_earth += 2*((magic->lh_tapping == MAG_ACTION_TAP_EARTH) +
- 			  (magic->rh_tapping == MAG_ACTION_TAP_EARTH));
-   magic->mana_air   += 2*((magic->lh_tapping == MAG_ACTION_TAP_AIR) +
- 			  (magic->rh_tapping == MAG_ACTION_TAP_AIR));
- 
-   if(magic->mana_fire > 0) {
-     magic->mana_fire--;
-     if(magic->mana_fire == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_FIRE);
-   }
- 
-   if(magic->mana_water > 0) {
-     magic->mana_water--;
-     if(magic->mana_water == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_WATER);
-   }
- 
-   if(magic->mana_earth > 0) {
-     magic->mana_earth--;
-     if(magic->mana_water == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_EARTH);
-   }
- 
-   if(magic->mana_air > 0) {
-     magic->mana_air--;
-     if(magic->mana_air == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_AIR);
-   }
- 
- 
-   // send increase messages
-   if(magic->lh_tapping == MAG_ACTION_TAP_FIRE || magic->rh_tapping == MAG_ACTION_TAP_FIRE)
-     send_to_char(ch, "You tap into a little bit of fire mana.\r\n");
-   if(magic->lh_tapping == MAG_ACTION_TAP_WATER || magic->rh_tapping == MAG_ACTION_TAP_WATER)
-     send_to_char(ch, "You tap into a little bit of water mana.\r\n");
-   if(magic->lh_tapping == MAG_ACTION_TAP_EARTH || magic->rh_tapping == MAG_ACTION_TAP_EARTH)
-     send_to_char(ch, "You tap into a little bit of earth mana.\r\n");
-   if(magic->lh_tapping == MAG_ACTION_TAP_AIR || magic->rh_tapping == MAG_ACTION_TAP_AIR)
-     send_to_char(ch, "You tap into a little bit of air mana.\r\n");
- 
- 
-   // check for manaburn -> when people accumulate too much mana
-   //***********
-   // FINISH ME
-   //***********
- 
- 
-   // now, put it back in the event queue
-   start_event(ch, MAG_EVENT_DELAY, 
- 	      handle_mag_event, check_mag_event_involvement, 
- 	      magic, NULL);
- }
- 
- 
- void interrupt_magic(CHAR_DATA *ch) {
-   // see if the character has a magic entry.
-   MAG_DATA *magic = mapGet(mag_map, ch);
- 
-   // if he does, interrupt all actions involving this magic entry
-   if(magic) { 
-     interrupt_events_involving(magic);
- 
-     // and let the character know
-     if(magic->mana_fire > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_FIRE);
-     if(magic->mana_water > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_WATER);
-     if(magic->mana_earth > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_EARTH);
-     if(magic->mana_air > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_AIR);
- 
-     // and finally, delete the magic entry
-     deleteMagic(magic);
-   }
- }
- 
- 
- void do_magic_action(CHAR_DATA *ch, CHAR_DATA *vict, const char *action) {
-   char lh_action = MAG_ACTION_NONE;
-   char rh_action = MAG_ACTION_NONE;
-   bool lh_acting = FALSE; // have we made a lh/rh action this turn?
-   bool rh_acting = FALSE;
- 
-   // first, look up our magic information
-   MAG_DATA *magic = mapGet(mag_map, ch);
- 
-   // if one doesn't exist, create it and add it to our magic map
-   // also toss it into the event queue
-   if(magic == NULL) {
-     magic = newMagic();
-     mapPut(mag_map, ch, magic);
-     start_event(ch, MAG_EVENT_DELAY, 
- 		handle_mag_event, check_mag_event_involvement, 
- 		magic, NULL);
-   }
- 
-   // parse our action and add it to the magic data
-   while(*action) {
-     bool one_action_lh = FALSE;
-     bool one_action_rh = FALSE;
-     char act           = '\0';
- 
-     // first, parse the hand(s)
-     if(*action == MAG_HAND_LEFT || *action == MAG_HAND_BOTH)
-       one_action_lh = TRUE;
-     if(*action == MAG_HAND_RIGHT || *action == MAG_HAND_BOTH)
-       one_action_rh = TRUE;
- 
-     // check if the character has tried two actions with one hand
-     if((one_action_lh && lh_acting) || (one_action_rh && rh_acting)) {
-       send_to_char(ch,"You can only perform one action with a hand at a time!\r\n");
-       return;
-     }
- 
-     // we didn't parse a hand ... oops!
-     if(!one_action_lh && !one_action_rh) {
-       send_to_char(ch, "Your hands get all tied, and you fail to us your magic!\r\n");
-       return;
-     }
-     
-     action++;
-     // now parse the action
-     switch(*action) {
-     case MAG_ACTION_TAP:       act = MAG_ACTION_TAP;       break;
-     case MAG_ACTION_DISMISS:   act = MAG_ACTION_NONE;      break;
-     case MAG_ACTION_PUSH:      act = MAG_ACTION_PUSH;      break;
-     case MAG_ACTION_ARC:       act = MAG_ACTION_ARC;       break;
-     case MAG_ACTION_LOWER:     act = MAG_ACTION_LOWER;     break;
-     case MAG_ACTION_WIGGLE:    act = MAG_ACTION_WIGGLE;    break;
-     case MAG_ACTION_SNAP:      act = MAG_ACTION_SNAP;      break;
-     case MAG_ACTION_PALM:      act = MAG_ACTION_PALM;      break;
-     case MAG_ACTION_FINGER:    act = MAG_ACTION_FINGER;    break;
-     case MAG_ACTION_TAP_NONE:  act = MAG_ACTION_NONE;      break;
-     case MAG_ACTION_TAP_FIRE:  act = MAG_ACTION_TAP_FIRE;  break;
-     case MAG_ACTION_TAP_WATER: act = MAG_ACTION_TAP_WATER; break;
-     case MAG_ACTION_TAP_EARTH: act = MAG_ACTION_TAP_EARTH; break;
-     case MAG_ACTION_TAP_AIR:   act = MAG_ACTION_TAP_AIR;   break;
-     default:
-       send_to_char(ch, "You try to make a gesture, but it had no magical significance.\r\n");
-       return;
-     }
-     action++;
- 
-     // if we're trying to tap something, figure out what action it is
-     if(act == MAG_ACTION_TAP) {
-       switch(*action) {
-       case MAG_TAP_NONE:  act = MAG_ACTION_NONE;      break;
-       case MAG_TAP_FIRE:  act = MAG_ACTION_TAP_FIRE;  break;
-       case MAG_TAP_WATER: act = MAG_ACTION_TAP_WATER; break;
-       case MAG_TAP_EARTH: act = MAG_ACTION_TAP_EARTH; break;
-       case MAG_TAP_AIR:   act = MAG_ACTION_TAP_AIR;   break;
-       default:
- 	send_to_char(ch, "You try to tap into a magic source, but fail!\r\n");
- 	break;
-       }
-       action++;
-     }
- 
-     // now that we've got the action, pop it into the hand it belongs in
-     // and note what hand we used to perform the action
-     if(one_action_lh) {
-       char *ptr = magic->lh_actions;
-       magic->lh_actions = malloc(sizeof(char) * (strlen(ptr) + 1));
-       sprintf(magic->lh_actions, "%s%c", ptr, act);
-       free(ptr);
-       lh_acting = TRUE;
-       lh_action = act;
-     }
-     if(one_action_rh) {
-       char *ptr = magic->rh_actions;
-       magic->rh_actions = malloc(sizeof(char) * (strlen(ptr) + 1));
-       sprintf(magic->rh_actions, "%s%c", ptr, act);
-       free(ptr);
-       rh_acting = TRUE;
-       rh_action = act;
-     }
-   }
- 
-   // if we're using a hand that we were tapping with, stop the tapping
-   if(lh_acting && magic->lh_tapping != MAG_ACTION_NONE)
-     stop_tapping(ch, magic, MAG_HAND_LEFT);
-   if(rh_acting && magic->rh_tapping != MAG_ACTION_NONE)
-     stop_tapping(ch, magic, MAG_HAND_RIGHT);
- 
-   magic->lh_action = lh_action;
-   magic->rh_action = rh_action;
- 
-   // set up an action in the action queue
-   if(lh_action != MAG_ACTION_NONE || rh_action != MAG_ACTION_NONE) {
-     send_to_char(ch, "Ok.\r\n");
-     start_action(ch, MAG_ACTION_DELAY, 1/*ACTION_MENTAL*/, handle_mag_action, 
- 		 interrupt_mag_action, magic, NULL);
-   }
- }
--- 0 ----
diff -crN nakedmudv1.5/src/magic.c.bk nakedmudv2.0/src/magic.c.bk
*** nakedmudv1.5/src/magic.c.bk	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/magic.c.bk	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,572 ****
- //*****************************************************************************
- //
- // magic.c
- //
- // A little magic system that has similarities to Richard Bartle's Spellbinder
- // (http://www.mud.co.uk/richard/spellbnd.htm). Players chain gestures 
- // together to make magical effects happen. The system is a little bit 
- // different, in that players have to draw on power from different sources 
- // (fire, water, earth, air) before they can cast spells. They can combine
- // powers from different sources to make more elaborate powers (e.g. fire +
- // earth = magma). Other differences exist; for instance, this magic system
- // is realtime, whereas Bartle's is turn-based. Characters have to "spend"
- // and "tap" magic power, whereas in Bartle's game, magic did not have a source
- // one had to draw into, or magic power one had to spend.
- //
- //*****************************************************************************
- 
- #include "mud.h"
- #include "utils.h"
- #include "event.h"
- #include "magic.h"
- #include "character.h"   // send_to_char()
- #include "handler.h"     // generic_find()
- #include "inform.h"      // message()
- 
- 
- 
- //*****************************************************************************
- //
- // local data, structures, and functions
- //
- //*****************************************************************************
- 
- // how often do we check for mana increases and manaburn?
- #define MAG_EVENT_DELAY      (5 SECONDS)
- #define MANABURN_MIN                 5
- 
- 
- //
- // Where all of our characters and their actions are stored
- //
- HASHMAP *mag_map = NULL;
- 
- 
- 
- //
- // All of the info we need for keeping track of the magic
- // status of a character.
- //
- typedef struct mag_data {
-   char *lh_actions;  // the movements we've made with our left hand
-   char *rh_actions;  // and with our right hand
- 
-   char lh_tapping;   // what magic is our left hand tapping?
-   char rh_tapping;   // what magic is our right hand tapping?
- 
-   int mana_fire;     // how much mana have we accumulated for various elements?
-   int mana_water;    
-   int mana_earth;
-   int mana_air;
- 
-   int barrier_fire;  // how protected are we from fire damage?
-   int barrier_water;
-   int barrier_earth;
-   int barrier_air;
- 
- } MAG_DATA;
- 
- 
- //
- // create a new magic entry
- //
- MAG_DATA *newMagic(void) {
-   MAG_DATA *magic = malloc(sizeof(MAG_DATA));
-   bzero(magic, sizeof(MAG_DATA));
-   magic->lh_actions = strdup("");
-   magic->rh_actions = strdup("");
-   magic->lh_tapping = MAG_ACTION_NONE;
-   magic->rh_tapping = MAG_ACTION_NONE;
-   return magic;
- }
- 
- 
- //
- // Delete a magic entry
- //
- void deleteMagic(MAG_DATA *magic) {
-   if(magic->lh_actions) free(magic->lh_actions);
-   if(magic->rh_actions) free(magic->rh_actions);
-   free(magic);
- }
- 
- 
- typedef struct mag_effect {
-   int   effect;          // what effect does it do?
-   int   cost;            // what's the cost in mana?
-   char *hand_movement;   // what is the hand movement?
- } MAG_EFFECT;
- 
- 
- MAG_EFFECT mag_effects_fire[] = {
-   { MAG_EFFECT_FIREBOLT,    2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- MAG_EFFECT mag_effects_water[] = {
-   { MAG_EFFECT_ACIDBOLT,    2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- MAG_EFFECT mag_effects_earth[] = {
-   { MAG_EFFECT_STONESPEAR,  2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- MAG_EFFECT mag_effects_air[] = {
-   { MAG_EFFECT_SHOCK,       2,           "sf" }, // snap, finger (point)
-   { MAG_EFFECT_NONE,        0,           NULL }  // sentinel
- };
- 
- 
- 
- //
- // get the magic table associated with the mana that has been tapped
- //
- MAG_EFFECT *get_mag_table(MAG_DATA *magic) {
-   if(magic->mana_fire > 0 && 
-      magic->mana_water == 0 && magic->mana_earth == 0 && magic->mana_air == 0)
-     return mag_effects_fire;
-   if(magic->mana_water > 0 && 
-      magic->mana_fire == 0 && magic->mana_earth == 0 && magic->mana_air == 0)
-     return mag_effects_water;
-   if(magic->mana_earth > 0 && 
-      magic->mana_water == 0 && magic->mana_fire == 0 && magic->mana_air == 0)
-     return mag_effects_earth;
-   if(magic->mana_air > 0 && 
-      magic->mana_water == 0 && magic->mana_earth == 0 && magic->mana_fire == 0)
-     return mag_effects_air;
- 
-   return NULL;
- }
- 
- 
- //
- // look in the table to see if we've completed any of the actions it has
- //
- int check_for_mag_effect(const MAG_EFFECT *mag_effects, 
- 			 const char *actions) {
-   int i;
-   int act_len = strlen(actions);
- 
-   // go through our list of effects, and search
-   for(i = 0; mag_effects[i].effect != MAG_EFFECT_NONE; i++) {
-     int move_len = strlen(mag_effects[i].hand_movement);
- 
-     // make sure we've performed enough actions
-     if(act_len < move_len)
-       continue;
- 
-     // go in reverse for both of them
-     int j;
-     char *movement = mag_effects[i].hand_movement;
-     for(j = move_len-1; j >= 0; j--)
-       if(movement[j] != actions[act_len-move_len+j])
- 	break;
- 
-     // if we got right to the end, we found a match
-     if(j == -1)
-       break;
-   }
- 
-   return i;
- }
- 
- const char *mag_hand_name(char hand) {
-   return (hand == MAG_HAND_LEFT ? "left" :
- 	  (hand == MAG_HAND_RIGHT ? "right" : "BUG"));
- }
- 
- const char *mag_tap_name(char tap_type) {
-   return (tap_type == MAG_ACTION_TAP_FIRE ? "fire" :
- 	  (tap_type == MAG_ACTION_TAP_WATER ? "water" :
- 	   (tap_type == MAG_ACTION_TAP_EARTH ? "earth" :
- 	    (tap_type == MAG_ACTION_TAP_AIR ? "air" : "BUG"))));
- }
- 
- const char *mag_tap_color(char tap_type) {
-   return (tap_type == MAG_ACTION_TAP_FIRE ? "red" :
- 	  (tap_type == MAG_ACTION_TAP_WATER ? "blue" :
- 	   (tap_type == MAG_ACTION_TAP_EARTH ? "brown" :
- 	    (tap_type == MAG_ACTION_TAP_AIR ? "white" : "BUG"))));
- }
- 
- 
- 
- //*****************************************************************************
- //
- // implementation of magic.h
- //
- //*****************************************************************************
- 
- void init_magic() {
-   // use standard hashing function and comparator
-   mag_map = newHashmap(NULL, NULL, 50);
- }
- 
- 
- //
- // Check if the magic is involved in an event. Basically, straight comparison
- //
- int check_mag_event_involvement(void *thing, MAG_DATA *magic) {
-   return (thing == magic);
- }
- 
- 
- //
- // Inform the character (and room) that the character has lost his
- // connection to a mana source
- //
- void magic_stop_message(CHAR_DATA *ch, char tap_type) {
-   send_to_char(ch, "Your connection with the plane of %s is cut short.\r\n",
- 	       mag_tap_name(tap_type));
-   message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR, 
- 	  "The %s aura around $n's body wanes.", mag_tap_color(tap_type));
- }
- 
- 
- //
- // Inform the character (and room) that the character has begun tapping mana
- //
- void tap_start_message(CHAR_DATA *ch, char hand, char tap_type) {
-   send_to_char(ch, 
- 	       "You begin tapping into the plane of %s with your %s hand.\r\n",
- 	       mag_tap_name(tap_type), mag_hand_name(hand));
-   message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 	  "$n upraises $s %s palm, and it becomes shrouded in a %s aura.",
- 	  mag_hand_name(hand), mag_tap_color(tap_type));
- }
- 
- 
- //
- // Inform the character (and room) that the character has begun tapping mana
- //
- void tap_stop_message(CHAR_DATA *ch, char hand, char tap_type) {
-   send_to_char(ch, 
- 	       "You stop tapping into the plane of %s with your %s hand.\r\n",
- 	       mag_tap_name(tap_type), mag_hand_name(hand));
-   message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 	  "$n lowers $s %s palm, and the %s aura around it dims slightly.",
- 	  mag_hand_name(hand), mag_tap_color(tap_type));
- }
- 
- 
- //
- // Update the magic status (increasing mana, giving manaburn, etc...) and
- // throw it back into the event handler
- //
- void handle_mag_event(CHAR_DATA *ch, MAG_DATA *magic, const char *arg) {
-   // up our mana by 2 and decrease our mana reserves by 1
-   // essentially, this results in +1 mana when we are actively tapping
-   // a manasource (+3 if we are tapping with both hands) and -1 if we
-   // are not tapping.
-   magic->mana_fire  += 2*((magic->lh_tapping == MAG_ACTION_TAP_FIRE) + 
- 			  (magic->rh_tapping == MAG_ACTION_TAP_FIRE));
-   magic->mana_water += 2*((magic->lh_tapping == MAG_ACTION_TAP_WATER) +
- 			  (magic->rh_tapping == MAG_ACTION_TAP_WATER));
-   magic->mana_earth += 2*((magic->lh_tapping == MAG_ACTION_TAP_EARTH) +
- 			  (magic->rh_tapping == MAG_ACTION_TAP_EARTH));
-   magic->mana_air   += 2*((magic->lh_tapping == MAG_ACTION_TAP_AIR) +
- 			  (magic->rh_tapping == MAG_ACTION_TAP_AIR));
- 
-   if(magic->mana_fire > 0) {
-     magic->mana_fire--;
-     if(magic->mana_fire == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_FIRE);
-   }
- 
-   if(magic->mana_water > 0) {
-     magic->mana_water--;
-     if(magic->mana_water == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_WATER);
-   }
- 
-   if(magic->mana_earth > 0) {
-     magic->mana_earth--;
-     if(magic->mana_water == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_EARTH);
-   }
- 
-   if(magic->mana_air > 0) {
-     magic->mana_air--;
-     if(magic->mana_air == 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_AIR);
-   }
- 
- 
-   // send increase messages
-   if(magic->lh_tapping == MAG_ACTION_TAP_FIRE || magic->rh_tapping == MAG_ACTION_TAP_FIRE)
-     send_to_char(ch, "You tap into a little bit of fire mana.\r\n");
-   if(magic->lh_tapping == MAG_ACTION_TAP_WATER || magic->rh_tapping == MAG_ACTION_TAP_WATER)
-     send_to_char(ch, "You tap into a little bit of water mana.\r\n");
-   if(magic->lh_tapping == MAG_ACTION_TAP_EARTH || magic->rh_tapping == MAG_ACTION_TAP_EARTH)
-     send_to_char(ch, "You tap into a little bit of earth mana.\r\n");
-   if(magic->lh_tapping == MAG_ACTION_TAP_AIR || magic->rh_tapping == MAG_ACTION_TAP_AIR)
-     send_to_char(ch, "You tap into a little bit of air mana.\r\n");
- 
- 
-   // check for manaburn -> when people accumulate too much mana
-   //***********
-   // FINISH ME
-   //***********
- 
- 
-   // now, put it back in the event queue
-   start_event(ch, MAG_EVENT_DELAY, 
- 	      handle_mag_event, check_mag_event_involvement, 
- 	      magic, NULL);
- }
- 
- 
- void interrupt_magic(CHAR_DATA *ch) {
-   // see if the character has a magic entry.
-   MAG_DATA *magic = mapGet(mag_map, ch);
- 
-   // if he does, interrupt all actions involving this magic entry
-   if(magic) { 
-     interrupt_events_involving(magic);
- 
-     // and let the character know
-     if(magic->mana_fire > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_FIRE);
-     if(magic->mana_water > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_WATER);
-     if(magic->mana_earth > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_EARTH);
-     if(magic->mana_air > 0)
-       magic_stop_message(ch, MAG_ACTION_TAP_AIR);
- 
-     // and finally, delete the magic entry
-     deleteMagic(magic);
-   }
- }
- 
- 
- //
- // return true if the action is mana-tapping-oriented
- //
- bool mag_action_is_tap(char action) {
-   return (action == MAG_ACTION_TAP_FIRE  || action == MAG_ACTION_TAP_AIR   ||
- 	  action == MAG_ACTION_TAP_WATER || action == MAG_ACTION_TAP_EARTH);
- }
- 
- 
- //
- // Set a character to start tapping in one hand
- //
- void start_tapping(CHAR_DATA *ch, MAG_DATA *magic, char hand, char action) {
-   if(hand == MAG_HAND_LEFT) {
-     magic->lh_tapping = action;
-     tap_start_message(ch, hand, action);
-   }
-   else if(hand == MAG_HAND_RIGHT) {
-     magic->rh_tapping = action;
-     tap_start_message(ch, hand, action);
-   }
- }
- 
- 
- //
- // Stop a character tapping in one hand
- //
- void stop_tapping(CHAR_DATA *ch, MAG_DATA *magic, char hand) {
-   if(hand == MAG_HAND_LEFT) {
-     tap_stop_message(ch, hand, magic->lh_tapping);
-     magic->lh_tapping = MAG_ACTION_NONE;
-   }
-   else if(hand == MAG_HAND_RIGHT) {
-     tap_stop_message(ch, hand, magic->rh_tapping);
-     magic->rh_tapping = MAG_ACTION_NONE;
-   }
- }
- 
- 
- //
- // Show the message that accompanies a hand gesture
- //
- void show_mag_action_message(CHAR_DATA *ch, char hand, char action) {
-   if(mag_action_is_tap(action))
-     tap_start_message(ch, hand, action);
-   else {
- 
-   }
- }
- 
- 
- void do_mag_effect(CHAR_DATA *ch, CHAR_DATA *vict, int effect) {
-   switch(effect) {
-   case MAG_EFFECT_FIREBOLT:
-   case MAG_EFFECT_ACIDBOLT:
-   case MAG_EFFECT_STONESPEAR:
-   case MAG_EFFECT_SHOCK:
-     send_to_char(ch, "You cast a basic spell at %s!\r\n", 
- 		 (vict ? charGetName(vict) : "nobody"));
-     break;
- 
-     // nothing
-   default: 
-     break;
-   }
- }
- 
- 
- void do_magic_action(CHAR_DATA *ch, CHAR_DATA *vict, const char *action) {
-   char lh_action = MAG_ACTION_NONE;
-   char rh_action = MAG_ACTION_NONE;
-   bool lh_acting = FALSE; // have we made a lh/rh action this turn?
-   bool rh_acting = FALSE;
- 
-   // first, look up our magic information
-   MAG_DATA *magic = mapGet(mag_map, ch);
- 
-   // if one doesn't exist, create it and add it to our magic map
-   // also toss it into the event queue
-   if(magic == NULL) {
-     magic = newMagic();
-     mapPut(mag_map, ch, magic);
-     start_event(ch, MAG_EVENT_DELAY, 
- 		handle_mag_event, check_mag_event_involvement, 
- 		magic, NULL);
-   }
- 
-   // parse our action and add it to the magic data
-   while(*action) {
-     bool one_action_lh = FALSE;
-     bool one_action_rh = FALSE;
-     char act           = '\0';
- 
-     // first, parse the hand(s)
-     if(*action == MAG_HAND_LEFT || *action == MAG_HAND_BOTH)
-       one_action_lh = TRUE;
-     if(*action == MAG_HAND_RIGHT || *action == MAG_HAND_BOTH)
-       one_action_rh = TRUE;
- 
-     // check if the character has tried two actions with one hand
-     if((one_action_lh && lh_acting) || (one_action_rh && rh_acting)) {
-       send_to_char(ch,"You can only perform one action with a hand at a time!\r\n");
-       return;
-     }
- 
-     // we didn't parse a hand ... oops!
-     if(!one_action_lh && !one_action_rh) {
-       send_to_char(ch, "Your hands get all tied, and you fail to us your magic!\r\n");
-       return;
-     }
-     
-     action++;
-     // now parse the action
-     switch(*action) {
-     case MAG_ACTION_TAP:       act = MAG_ACTION_TAP;       break;
-     case MAG_ACTION_DISMISS:   act = MAG_ACTION_NONE;      break;
-     case MAG_ACTION_PUSH:      act = MAG_ACTION_PUSH;      break;
-     case MAG_ACTION_ARC:       act = MAG_ACTION_ARC;       break;
-     case MAG_ACTION_LOWER:     act = MAG_ACTION_LOWER;     break;
-     case MAG_ACTION_WIGGLE:    act = MAG_ACTION_WIGGLE;    break;
-     case MAG_ACTION_SNAP:      act = MAG_ACTION_SNAP;      break;
-     case MAG_ACTION_PALM:      act = MAG_ACTION_PALM;      break;
-     case MAG_ACTION_FINGER:    act = MAG_ACTION_FINGER;    break;
-     case MAG_ACTION_TAP_NONE:  act = MAG_ACTION_NONE;      break;
-     case MAG_ACTION_TAP_FIRE:  act = MAG_ACTION_TAP_FIRE;  break;
-     case MAG_ACTION_TAP_WATER: act = MAG_ACTION_TAP_WATER; break;
-     case MAG_ACTION_TAP_EARTH: act = MAG_ACTION_TAP_EARTH; break;
-     case MAG_ACTION_TAP_AIR:   act = MAG_ACTION_TAP_AIR;   break;
-     default:
-       send_to_char(ch, "You try to make a gesture, but it had no magical significance.\r\n");
-       return;
-     }
-     action++;
- 
-     // if we're trying to tap something, figure out what action it is
-     if(act == MAG_ACTION_TAP) {
-       switch(*action) {
-       case MAG_TAP_NONE:  act = MAG_ACTION_NONE;      break;
-       case MAG_TAP_FIRE:  act = MAG_ACTION_TAP_FIRE;  break;
-       case MAG_TAP_WATER: act = MAG_ACTION_TAP_WATER; break;
-       case MAG_TAP_EARTH: act = MAG_ACTION_TAP_EARTH; break;
-       case MAG_TAP_AIR:   act = MAG_ACTION_TAP_AIR;   break;
-       default:
- 	send_to_char(ch, "You try to tap into a magic source, but fail!\r\n");
- 	break;
-       }
-       action++;
-     }
- 
-     // now that we've got the action, pop it into the hand it belongs in
-     // and note what hand we used to perform the action
-     if(one_action_lh) {
-       char *ptr = magic->lh_actions;
-       magic->lh_actions = malloc(sizeof(char) * (strlen(ptr) + 1));
-       sprintf(magic->lh_actions, "%s%c", ptr, act);
-       free(ptr);
-       lh_acting = TRUE;
-       lh_action = act;
-     }
-     if(one_action_rh) {
-       char *ptr = magic->rh_actions;
-       magic->rh_actions = malloc(sizeof(char) * (strlen(ptr) + 1));
-       sprintf(magic->rh_actions, "%s%c", ptr, act);
-       free(ptr);
-       rh_acting = TRUE;
-       rh_action = act;
-     }
-   }
- 
- 
-   // if we're using a hand that we were tapping with, stop the tapping
-   if(lh_acting && magic->lh_tapping != MAG_ACTION_NONE)
-     stop_tapping(ch, magic, MAG_HAND_LEFT);
-   if(rh_acting && magic->rh_tapping != MAG_ACTION_NONE)
-     stop_tapping(ch, magic, MAG_HAND_RIGHT);
- 
- 
-   // do something about seeing if we're tapping mana
-   if(lh_acting && mag_action_is_tap(lh_action)) {
-     start_tapping(ch, magic, MAG_HAND_LEFT, lh_action);
-     lh_acting = FALSE;
-     // now, free our history ... nothing starts with a tap
-     free(magic->lh_actions); magic->lh_actions = strdup("");
-   }
-   if(rh_acting && mag_action_is_tap(rh_action)) {
-     start_tapping(ch, magic, MAG_HAND_RIGHT, rh_action);
-     rh_acting = FALSE;
-     // now, free our history ... nothing starts with a tap
-     free(magic->rh_actions); magic->rh_actions = strdup("");
-   }
- 
-   // based on the mana we've accumulated, figure out what table to use
-   MAG_EFFECT *table = get_mag_table(magic);
- 
-   // now, see if we've created any magical effects
-   if(table && lh_acting) {
-     int entry = check_for_mag_effect(table, magic->lh_actions);
-     do_mag_effect(ch, vict, table[entry].effect);
-   }
-   if(table && rh_acting) {
-     int entry = check_for_mag_effect(table, magic->rh_actions);
-     do_mag_effect(ch, vict, table[entry].effect);
-   }
- }
- 
- 
- COMMAND(cmd_cast) {
-   char action[SMALL_BUFFER];
- 
-   trim(arg);
-   // make sure it's not white space
-   if(!arg || !*arg) {
-     send_to_char(ch, "What were you trying to do?\r\n");
-     return;
-   }
- 
-   // separate the action from the target
-   arg = one_arg(arg, action);
- 
-   // look for a target if we need to
-   int found_type = FOUND_NONE;
-   CHAR_DATA *vict = NULL;
-   if(*arg)
-       vict = generic_find(ch, arg, FIND_TYPE_CHAR, 
- 			  FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
- 			  FALSE, &found_type);
-   do_magic_action(ch, vict, action);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/magic.h nakedmudv2.0/src/magic.h
*** nakedmudv1.5/src/magic.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/magic.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,102 ****
- #ifndef __MAGIC_H
- #define __MAGIC_H
- //*****************************************************************************
- //
- // magic.h
- //
- // A little magic system that has similarities to Richard Bartle's Spellbinder
- // (http://www.mud.co.uk/richard/spellbnd.htm). Players chain gestures 
- // together to make magical effects happen. The system is a little bit 
- // different, in that players have to draw on power from different sources 
- // (fire, water, earth, air) before they can cast spells. They can combine
- // powers from different sources to make more elaborate powers (e.g. fire +
- // earth = magma). Other differences exist; for instance, this magic system
- // is realtime, whereas Bartle's is turn-based. Characters have to "spend"
- // and "tap" magic power, whereas in Bartle's game, magic did not have a source
- // one had to draw into, or magic power one had to spend.
- //
- //*****************************************************************************
- 
- #define MAG_ACTION_NONE       '\0' // used to signify that no action is taken
- 
- #define MAG_HAND_LEFT         'l'  // perform action with left hand
- #define MAG_HAND_RIGHT        'r'  // perform action with right hand
- #define MAG_HAND_BOTH         'b'  // perform action with both hands
- #define MAG_HAND_CLAP         'c'  // special marker - clap hands together
- 
- #define MAG_ACTION_TAP        't'  // tap into a specified energy source
- #define MAG_ACTION_TAP_NONE   'N'  // tap nothing (dismiss)
- #define MAG_ACTION_TAP_FIRE   'F'  // tap fire
- #define MAG_ACTION_TAP_WATER  'W'  // tap water
- #define MAG_ACTION_TAP_EARTH  'E'  // tap earth
- #define MAG_ACTION_TAP_AIR    'A'  // tap air
- 
- #define MAG_ACTION_DISMISS    'd'  // dismiss the magic being tapped in hand
- #define MAG_ACTION_PUSH       'p'  // push hand outward
- #define MAG_ACTION_ARC        'a'  // raise hand upwards
- #define MAG_ACTION_LOWER      'l'  // lower hand downwards
- #define MAG_ACTION_WIGGLE     'w'  // wiggle fingers
- #define MAG_ACTION_SNAP       's'  // snap fingers
- #define MAG_ACTION_PALM       'u'  // upraised palm
- #define MAG_ACTION_FINGER     'f'  // pointed finger
- 
- #define MAG_TAP_NONE          'n'
- #define MAG_TAP_FIRE          'f'  
- #define MAG_TAP_WATER         'w'
- #define MAG_TAP_EARTH         'e'  
- #define MAG_TAP_AIR           'a'
- 
- 
- //      EFFECT                                 HAND MOVEMENT      WHEN TAPPING
- #define MAG_EFFECT_NONE               (-1)
- #define MAG_EFFECT_FIREBOLT             0   // s-f                fire
- #define MAG_EFFECT_ACIDBOLT             1   // s-f                water
- #define MAG_EFFECT_STONESPEAR           2   // s-f                earth
- #define MAG_EFFECT_SHOCK                3   // s-f                air
- 
- 
- //
- // initialize the magic system
- //
- void init_magic();
- 
- 
- //
- // Interrupt the character's magic info
- //
- void interrupt_magic(CHAR_DATA *ch);
- 
- 
- //
- // perform an action. If an effect results, then return which effect it is.
- // Actions have a syntax to them which must be followed. It goes:
- //   hand, action, element (if the action is to tap).
- //
- // More than one action can be performed at a time, if they were done on
- // separate hands.
- //
- // Here are some example, valid actions:
- //   lw                           wiggle left fingers
- //   rtf                          tap into fire with the right hand
- //   ba                           arc both hands upwards
- //   lara                         arc both hands upwards
- //   ltwru                        tap water with left hand, raise right palm up
- //   ltwrd                        tap water w/ left hand, dismiss magic in right
- //   ltwrtn                       same as above
- //
- //int do_magic_action(CHAR_DATA *ch, const char *action);
- 
- 
- 
- //
- // Make the character perform the specified action on the victim
- //
- //void do_mag_effect(CHAR_DATA *ch, CHAR_DATA *vict, int effect);
- 
- 
- //
- // The entrypoint into the magic system
- //
- COMMAND(cmd_cast);
- 
- #endif // __MAGIC_H
--- 0 ----
diff -crN nakedmudv1.5/src/Makefile nakedmudv2.0/src/Makefile
*** nakedmudv1.5/src/Makefile	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/Makefile	2010-11-01 15:54:18.000000000 -0500
***************
*** 13,20 ****
  # compiler to use
  CC = gcc
  
! # the modules we have installed
! MODULES := time alias char_vars socials olc scripts help
  
  # flags to use during compilation
  C_FLAGS := -Wall -g -ggdb -O2
--- 13,24 ----
  # compiler to use
  CC = gcc
  
! # the modules we have installed -- mandatory modules go here
! MODULES := char_vars set_val olc2 editor items scripts
! 
! # optional modules go on this line
! MODULES += time socials alias help
! 
  
  # flags to use during compilation
  C_FLAGS := -Wall -g -ggdb -O2
***************
*** 22,41 ****
  # extra libraries if required
  LIBS    := -lz -lpthread -lcrypt
  
  # each module will add to this from its module.mk file
  SRC     := gameloop.c mud.c utils.c interpret.c handler.c inform.c movement.c \
  	   action.c mccp.c save.c socket.c io.c strings.c event.c \
  	   \
  	   cmd_comm.c cmd_manip.c cmd_misc.c cmd_admin.c cmd_builder.c \
  	   \
! 	   text_editor.c races.c \
  	   \
! 	   items.c log.c auxiliary.c \
  	   \
  	   world.c character.c room.c exit.c extra_descs.c object.c body.c \
  	   zone.c dialog.c room_reset.c \
  	   \
! 	   list.c property_table.c hashtable.c hashmap.c storage.c set.c
  
  
  # include the description for each module. These will add to SRC
--- 26,47 ----
  # extra libraries if required
  LIBS    := -lz -lpthread -lcrypt
  
+ 
  # each module will add to this from its module.mk file
  SRC     := gameloop.c mud.c utils.c interpret.c handler.c inform.c movement.c \
  	   action.c mccp.c save.c socket.c io.c strings.c event.c \
  	   \
  	   cmd_comm.c cmd_manip.c cmd_misc.c cmd_admin.c cmd_builder.c \
  	   \
! 	   races.c \
  	   \
! 	   log.c auxiliary.c login.c \
  	   \
  	   world.c character.c room.c exit.c extra_descs.c object.c body.c \
  	   zone.c dialog.c room_reset.c \
  	   \
! 	   list.c property_table.c hashtable.c map.c storage.c set.c \
! 	   buffer.c bitvector.c
  
  
  # include the description for each module. These will add to SRC
***************
*** 48,56 ****
  
  
  ################################################################################
- #
  # make commands
- #
  ################################################################################
  all: $(O_FILES)
  	$(CC) -o NakedMud $(O_FILES) $(LIBS)
--- 54,60 ----
***************
*** 62,73 ****
  # say where the .o files need to go
  .c.o: all
  	$(CC) -c $(C_FLAGS) -o $(patsubst %.c,%.o, $<) $<
- #	$(CC) -c $(C_FLAGS) $<
- 
- 
- # make dependancies for all of the files
- depend:
- 	$(CC) -MM $(filter %.c, $(SRC)) > .depend
  
  # clear all of the .o files and all of the save files that emacs makes
  clean:
--- 66,71 ----
***************
*** 77,80 ****
  	rm -f *~
  	rm -f */*~
  
! include .depend
--- 75,83 ----
  	rm -f *~
  	rm -f */*~
  
! # include all of our dependencies
! include $(patsubst %.c,%.d, $(SRC))
! 
! # calculate all of our dependencies
! %.d: %.c
! 	./depend.sh $(patsubst %.d,%.c, $@) > $@
diff -crN nakedmudv1.5/src/map.c nakedmudv2.0/src/map.c
*** nakedmudv1.5/src/map.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/map.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,263 ----
+ //*****************************************************************************
+ //
+ // map.c
+ //
+ // similar to a hashtable, but keys as well as values can be can be anything.
+ //
+ //*****************************************************************************
+ 
+ #include <stdlib.h>
+ #include "list.h"
+ #include "map.h"
+ 
+ int gen_hash_cmp(const void *key1, const void *key2) {
+   int val = (key2 - key1);
+   if(val < 0)      return -1;
+   else if(val > 0) return  1;
+   else             return  0;
+   return val;
+ }
+ 
+ int gen_hash_func(const void *key) {
+   int val = (int)key;
+   if(val < 0) return -val;
+   else        return  val;
+ }
+ 
+ struct map_iterator {
+   int curr_bucket;
+   MAP *map;
+   LIST_ITERATOR *bucket_i;
+ };
+ 
+ typedef struct map_entry {
+   void *key;
+   void *val;
+ } MAP_ENTRY;
+ 
+ struct map_data {
+   int num_buckets;
+   struct list **buckets;
+   int (* hash_func)(const void *key);
+   int (*  compares)(const void *key1, const void *key2);
+ };
+ 
+ 
+ //
+ // an internal form of hashGet that returns the entire entry (key and val)
+ //
+ MAP_ENTRY *mapGetEntry(MAP *map, void *key) {
+   int bucket = map->hash_func(key) % map->num_buckets;
+ 
+   if(map->buckets[bucket] == NULL)
+     return NULL;
+   else {
+     struct list_iterator *list_i = newListIterator(map->buckets[bucket]);
+     MAP_ENTRY *elem   = NULL;
+ 
+     for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
+       if(!map->compares(key, elem->key))
+ 	break;
+     deleteListIterator(list_i);
+ 
+     return elem;
+   }
+ }
+ 
+ 
+ MAP_ENTRY *newMapEntry(void *key, void *val) {
+   MAP_ENTRY *entry = malloc(sizeof(MAP_ENTRY));
+   entry->key = key;
+   entry->val = val;
+   return entry;
+ }
+ 
+ void deleteMapEntry(MAP_ENTRY *entry) {
+   free(entry);
+ }
+ 
+ 
+ //*****************************************************************************
+ //
+ // implementation of hashmap.h
+ // documentation in hashmap.h
+ //
+ //*****************************************************************************
+ MAP *newMap(void *hash_func, void *compares, int num_buckets) {
+   int i;
+   MAP *map = malloc(sizeof(MAP));
+   map->num_buckets = num_buckets;
+   map->hash_func   = (hash_func ? hash_func : gen_hash_func);
+   map->compares    = (compares  ? compares  : gen_hash_cmp);
+   map->buckets = malloc(sizeof(struct list *) * num_buckets);
+   for(i = 0; i < num_buckets; i++)
+     map->buckets[i] = NULL;
+   return map;
+ }
+ 
+ void  deleteMap(MAP *map) {
+   int i;
+   for(i = 0; i < map->num_buckets; i++) {
+     if(map->buckets[i]) {
+       MAP_ENTRY *entry = NULL;
+       while((entry=(MAP_ENTRY *)listPop(map->buckets[i])) !=NULL)
+ 	deleteMapEntry(entry);
+       deleteList(map->buckets[i]);
+     }
+   }
+   free(map->buckets);
+   free(map);
+ }
+ 
+ int  mapPut    (MAP *map, void *key, void *val) {
+   MAP_ENTRY *elem = mapGetEntry(map, key);
+ 
+   // update the val if it's already here
+   if(elem) {
+     elem->val = val;
+     return 1;
+   }
+   else {
+     int bucket = map->hash_func(key) % map->num_buckets;
+ 
+     // if the bucket doesn't exist yet, create it
+     if(map->buckets[bucket] == NULL)
+       map->buckets[bucket] = newList();
+ 
+     MAP_ENTRY *entry = newMapEntry(key, val);
+     listPut(map->buckets[bucket], entry);
+     return 1;
+   }
+ }
+ 
+ void *mapGet    (MAP *map, void *key) {
+   MAP_ENTRY *elem = mapGetEntry(map, key);
+   if(elem)
+     return elem->val;
+   else
+     return NULL;
+ }
+ 
+ void *mapRemove (MAP *map, void *key) {
+   int bucket = map->hash_func(key) % map->num_buckets;
+ 
+   if(map->buckets[bucket] == NULL)
+     return NULL;
+   else {
+     struct list_iterator *list_i = newListIterator(map->buckets[bucket]);
+     MAP_ENTRY *elem   = NULL;
+ 
+     for(;(elem = listIteratorCurrent(list_i)) != NULL; listIteratorNext(list_i))
+       if(!map->compares(key, elem->key))
+ 	break;
+     deleteListIterator(list_i);
+ 
+     if(elem) {
+       void *val = elem->val;
+       listRemove(map->buckets[bucket], elem);
+       deleteMapEntry(elem);
+       return val;
+     }
+     else
+       return NULL;
+   }
+ }
+ 
+ int   mapIn     (MAP *map, void *key) {
+   return (mapGet(map, key) != NULL);
+ }
+ 
+ int   mapSize   (MAP *map) {
+   int i;
+   int size = 0;
+ 
+   for(i = 0; i < map->num_buckets; i++)
+     if(map->buckets[i])
+       size += listSize(map->buckets[i]);
+ 
+   return size;
+ }
+ 
+ 
+ //*****************************************************************************
+ //
+ // implementation of the hashmap iterator
+ // documentation in hashmap.h
+ //
+ //*****************************************************************************
+ MAP_ITERATOR *newMapIterator(MAP *map) {
+   MAP_ITERATOR *I = malloc(sizeof(MAP_ITERATOR));
+   I->map = map;
+   I->bucket_i = NULL;
+   mapIteratorReset(I);
+ 
+   return I;
+ }
+ 
+ void        deleteMapIterator     (MAP_ITERATOR *I) {
+   if(I->bucket_i) deleteListIterator(I->bucket_i);
+   free(I);
+ }
+ 
+ void        mapIteratorReset      (MAP_ITERATOR *I) {
+   int i;
+ 
+   if(I->bucket_i) deleteListIterator(I->bucket_i);
+   I->bucket_i = NULL;
+   I->curr_bucket = 0;
+ 
+   // bucket_i will be NULL if there are no elements
+   for(i = 0; i < I->map->num_buckets; i++) {
+     if(I->map->buckets[i] != NULL &&
+        listSize(I->map->buckets[i]) > 0) {
+       I->curr_bucket = i;
+       I->bucket_i = newListIterator(I->map->buckets[i]);
+       break;
+     }
+   }
+ }
+ 
+ 
+ void        mapIteratorNext       (MAP_ITERATOR *I) {
+   // no elements in the hashmap
+   if(I->bucket_i == NULL)
+     return;
+   // we're at the end of our list
+   else if(listIteratorNext(I->bucket_i) == NULL) {
+     deleteListIterator(I->bucket_i);
+     I->bucket_i = NULL;
+     I->curr_bucket++;
+     
+     for(; I->curr_bucket < I->map->num_buckets; I->curr_bucket++) {
+       if(I->map->buckets[I->curr_bucket] != NULL &&
+ 	 listSize(I->map->buckets[I->curr_bucket]) > 0) {
+ 	I->bucket_i = newListIterator(I->map->buckets[I->curr_bucket]);
+ 	break;
+       }
+     }
+   }
+ }
+ 
+ void *mapIteratorCurrentKey (MAP_ITERATOR *I) {
+   if(!I->bucket_i)
+     return NULL;
+   else {
+     MAP_ENTRY *entry = ((MAP_ENTRY *) listIteratorCurrent(I->bucket_i));
+     if(entry)
+       return entry->key;
+     else
+       return NULL;
+   }
+ }
+ 
+ void       *mapIteratorCurrentVal (MAP_ITERATOR *I) {
+   if(!I->bucket_i) 
+     return NULL;
+   else {
+     MAP_ENTRY *entry = ((MAP_ENTRY *) listIteratorCurrent(I->bucket_i));
+     if(entry)
+       return entry->val;
+     else
+       return NULL;
+   }
+ }
diff -crN nakedmudv1.5/src/map.d nakedmudv2.0/src/map.d
*** nakedmudv1.5/src/map.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/map.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ map.d map.o: map.c list.h map.h
diff -crN nakedmudv1.5/src/map.h nakedmudv2.0/src/map.h
*** nakedmudv1.5/src/map.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/map.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,42 ----
+ #ifndef __MAP_H
+ #define __MAP_H
+ //*****************************************************************************
+ //
+ // map.h
+ //
+ // similar to a hashtable, but keys as well as values can be can be anything.
+ //
+ //*****************************************************************************
+ 
+ typedef struct map_data                   MAP;
+ typedef struct map_iterator               MAP_ITERATOR;
+ 
+ //
+ // if hash_func and/or compares are null, generic hashing and comparing
+ // functions are used.
+ //
+ // hash_func is expected to be a function that takes the key type used in
+ // this map, and returns an integer based on that key.
+ //
+ // compares is expected to be a function that takes two keys and compares
+ // them togher. If they are equal, 0 is returned. if key1 is less than key2,
+ // -1 is returned. otherwise, 1 is returned.
+ //
+ MAP *newMap(void *hash_func, void *compares, int num_buckets);
+ void deleteMap(MAP *map);
+ 
+ int   mapPut    (MAP *map, void *key, void *val);
+ void *mapGet    (MAP *map, void *key);
+ void *mapRemove (MAP *map, void *key);
+ int   mapIn     (MAP *map, void *key);
+ int   mapSize   (MAP *map);
+ 
+ MAP_ITERATOR *newMapIterator(MAP *map);
+ void          deleteMapIterator(MAP_ITERATOR *I);
+ 
+ void  mapIteratorReset      (MAP_ITERATOR *I);
+ void  mapIteratorNext       (MAP_ITERATOR *I);
+ void *mapIteratorCurrentKey (MAP_ITERATOR *I);
+ void *mapIteratorCurrentVal (MAP_ITERATOR *I);
+ 
+ #endif // __MAP_H
diff -crN nakedmudv1.5/src/mccp.c nakedmudv2.0/src/mccp.c
*** nakedmudv1.5/src/mccp.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/mccp.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,164 ****
- /*
-  * mccp.c - support functions for the Mud Client Compression Protocol
-  *
-  * see http://www.randomly.org/projects/MCCP/
-  *
-  * Copyright (c) 1999, Oliver Jowett <oliver@randomly.org>
-  *
-  * This code may be freely distributed and used if this copyright
-  * notice is retained intact.
-  */
- 
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- 
- #include "mud.h"
- #include "socket.h"
- #include "utils.h"
- 
- /* local functions */
- bool  processCompressed       ( SOCKET_DATA *dsock );
- 
- const unsigned char enable_compress  [] = { IAC, SB, TELOPT_COMPRESS, WILL, SE, 0 };
- const unsigned char enable_compress2 [] = { IAC, SB, TELOPT_COMPRESS2, IAC, SE, 0 };
- 
- /*
-  * Memory management - zlib uses these hooks to allocate and free memory
-  * it needs
-  */
- void *zlib_alloc(void *opaque, unsigned int items, unsigned int size)
- {
-   return calloc(items, size);
- }
- 
- void zlib_free(void *opaque, void *address)
- {
-   free(address);
- }
- 
- /*
-  * Begin compressing data on `desc'
-  */
- bool compressStart(SOCKET_DATA *dsock, unsigned char teleopt)
- {
-   z_stream *s;
- 
-   /* already compressing */
-   if (dsock->out_compress)
-     return TRUE;
- 
-   /* allocate and init stream, buffer */
-   s = (z_stream *) malloc(sizeof(*s));
-   dsock->out_compress_buf = (unsigned char *) malloc(COMPRESS_BUF_SIZE);
- 
-   s->next_in    =  NULL;
-   s->avail_in   =  0;
-   s->next_out   =  dsock->out_compress_buf;
-   s->avail_out  =  COMPRESS_BUF_SIZE;
-   s->zalloc     =  zlib_alloc;
-   s->zfree      =  zlib_free;
-   s->opaque     =  NULL;
- 
-   if (deflateInit(s, 9) != Z_OK)
-   {
-     free(dsock->out_compress_buf);
-     free(s);
-     return FALSE;
-   }
- 
-   /* version 1 or 2 support */
-   if (teleopt == TELOPT_COMPRESS)
-     text_to_socket(dsock, (char *) enable_compress);
-   else if (teleopt == TELOPT_COMPRESS2)
-     text_to_socket(dsock, (char *) enable_compress2);
-   else
-   {
-     bug("Bad teleoption %d passed", teleopt);
-     free(dsock->out_compress_buf);
-     free(s);
-     return FALSE;
-   }
- 
-   /* now we're compressing */
-   dsock->compressing = teleopt;
-   dsock->out_compress = s;
- 
-   /* success */
-   return TRUE;
- }
- 
- /* Cleanly shut down compression on `desc' */
- bool compressEnd(SOCKET_DATA *dsock, unsigned char teleopt, bool forced)
- {
-   unsigned char dummy[1];
- 
-   if (!dsock->out_compress)
-     return TRUE;
- 
-   if (dsock->compressing != teleopt)
-     return FALSE;
- 
-   dsock->out_compress->avail_in = 0;
-   dsock->out_compress->next_in = dummy;
-   dsock->top_output = 0;
- 
-   /* No terminating signature is needed - receiver will get Z_STREAM_END */
-   if (deflate(dsock->out_compress, Z_FINISH) != Z_STREAM_END && !forced)
-     return FALSE;
- 
-   /* try to send any residual data */
-   if (!processCompressed(dsock) && !forced)
-     return FALSE;
- 
-   /* reset compression values */
-   deflateEnd(dsock->out_compress);
-   free(dsock->out_compress_buf);
-   free(dsock->out_compress);
-   dsock->compressing      = 0;
-   dsock->out_compress     = NULL;
-   dsock->out_compress_buf = NULL;
- 
-   /* success */
-   return TRUE;
- }
- 
- /* Try to send any pending compressed-but-not-sent data in `desc' */
- bool processCompressed(SOCKET_DATA *dsock)
- {
-   int iStart, nBlock, nWrite, len;
- 
-   if (!dsock->out_compress)
-     return TRUE;
-     
-   len = dsock->out_compress->next_out - dsock->out_compress_buf;
-   if (len > 0)
-   {
-     for (iStart = 0; iStart < len; iStart += nWrite)
-     {
-       nBlock = UMIN (len - iStart, 4096);
-       if ((nWrite = write(dsock->control, dsock->out_compress_buf + iStart, nBlock)) < 0)
-       {
-         if (errno == EAGAIN/* || errno == ENOSR*/)
-           break;
- 
-         /* write error */
-         return FALSE;
-       }
-       if (nWrite <= 0)
-         break;
-     }
- 
-     if (iStart)
-     {
-       if (iStart < len)
-         memmove(dsock->out_compress_buf, dsock->out_compress_buf+iStart, len - iStart);
- 
-       dsock->out_compress->next_out = dsock->out_compress_buf + len - iStart;
-     }
-   }
- 
-   /* success */
-   return TRUE;
- }
--- 0 ----
diff -crN nakedmudv1.5/src/mccp.d nakedmudv2.0/src/mccp.d
*** nakedmudv1.5/src/mccp.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/mccp.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ mccp.d mccp.o: mccp.c
diff -crN nakedmudv1.5/src/module.mk nakedmudv2.0/src/module.mk
*** nakedmudv1.5/src/module.mk	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/module.mk	1969-12-31 18:00:00.000000000 -0600
***************
*** 1 ****
- SRC += races/races.c
--- 0 ----
diff -crN nakedmudv1.5/src/movement.c nakedmudv2.0/src/movement.c
*** nakedmudv1.5/src/movement.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/movement.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,28 ****
  #include "handler.h"
  #include "inform.h"
  #include "utils.h"
- #include "items.h"
  #include "object.h"
  
! // optional modules
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
! #endif
  
  
  bool try_exit(CHAR_DATA *ch, EXIT_DATA *exit, int dir) {
--- 16,32 ----
  #include "handler.h"
  #include "inform.h"
  #include "utils.h"
  #include "object.h"
  
! 
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
! #include "items/items.h"
! #include "items/furniture.h"
! 
  
  
  bool try_exit(CHAR_DATA *ch, EXIT_DATA *exit, int dir) {
***************
*** 114,120 ****
  
    if(exit == NULL || !can_see_exit(ch, exit)) {
      // see if we can buildwalk a new room
!     if(charIsBitSet(ch, BITFIELD_PRFS, PRF_BUILDWALK))
        return try_buildwalk(ch, dir);
      else
        send_to_char(ch, "Alas, there is no exit in that direction.\r\n");
--- 118,124 ----
  
    if(exit == NULL || !can_see_exit(ch, exit)) {
      // see if we can buildwalk a new room
!     if(bitIsOneSet(charGetPrfs(ch), "buildwalk"))
        return try_buildwalk(ch, dir);
      else
        send_to_char(ch, "Alas, there is no exit in that direction.\r\n");
***************
*** 122,128 ****
    }
  
    else {
- #ifdef MODULE_SCRIPTS
      ROOM_DATA *old_room = charGetRoom(ch);
      bool success = try_exit(ch, exit, dir);
      if(success) {
--- 126,131 ----
***************
*** 132,140 ****
  			   (dir != DIR_NONE ? dirGetName(dir) : specdir));
      }
      return success;
- #else
-     return try_exit(ch, exit, dir);
- #endif
    }
  }
  
--- 135,140 ----
***************
*** 150,204 ****
    };
  
    try_move(ch, subcmd, NULL);
- };
- 
- 
- //
- // cmd_enter is used to go through portals
- //   usage: enter [object]
- //
- //   examples:
- //     enter portal         enter the thing called "portal" in your room
- //
- COMMAND(cmd_enter) {
-   if(!arg || !*arg)
-     send_to_char(ch, "What did you want to enter?\r\n");
-   else {
-     int found_type = FOUND_NONE;
-     void *found = generic_find(ch, arg,
- 			       FIND_TYPE_OBJ | FIND_TYPE_EXIT,
- 			       FIND_SCOPE_IMMEDIATE,
- 			       FALSE, &found_type);
- 
-     // we're trying to enter a portal
-     if(found && found_type == FOUND_OBJ) {
-       if(objGetType(found) != ITEM_PORTAL)
- 	send_to_char(ch, "You can only enter portals.\r\n");
-       else {
- 	ROOM_DATA *dest = worldGetRoom(gameworld, portalGetDestination(found));
- 	if(!dest)
- 	  send_to_char(ch, 
- 		       "You go to enter the portal, "
- 		       "but dark forces prevent you!\r\n");
- 	else {
- 	  send_to_char(ch, "You step through %s.\r\n", objGetName(found));
- 	  message(ch, NULL, found, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 		  "$n steps through $o.");
- 	  char_from_room(ch);
- 	  char_to_room(ch, dest);
- 	  look_at_room(ch, dest);
- 	  message(ch, NULL, found, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 		  "$n arrives after travelling through $o.");
- 	}
-       }
-     }
- 
-     // we're trying to enter an exit
-     else if(found && found_type == FOUND_EXIT)
-       try_exit(ch, found, DIR_NONE);
-     else
-       send_to_char(ch, "What were you trying to enter?\r\n");
-   }
  }
  
  
--- 150,155 ----
***************
*** 235,246 ****
    
    if(furniture == NULL)
      send_to_char(ch, "Where did you want to %s?\r\n", posGetActionSelf(pos));
!   else if(objGetType(furniture) != ITEM_FURNITURE)
      send_to_char(ch, "But that's not furniture!\r\n");
    // make sure we found something we might be able to sit on
    else if(charGetFurniture(ch) == furniture)
      send_to_char(ch, "You're already %s %s.\r\n",
! 		 (objGetSubtype(furniture) == FURNITURE_ON ? "on" : "at"),
  		 objGetName(furniture));
  
    else if(furnitureGetCapacity(furniture) <= listSize(objGetUsers(furniture)))
--- 186,197 ----
    
    if(furniture == NULL)
      send_to_char(ch, "Where did you want to %s?\r\n", posGetActionSelf(pos));
!   else if(!objIsType(furniture, "furniture"))
      send_to_char(ch, "But that's not furniture!\r\n");
    // make sure we found something we might be able to sit on
    else if(charGetFurniture(ch) == furniture)
      send_to_char(ch, "You're already %s %s.\r\n",
! 		 (furnitureGetType(furniture) == FURNITURE_ON ? "on" : "at"),
  		 objGetName(furniture));
  
    else if(furnitureGetCapacity(furniture) <= listSize(objGetUsers(furniture)))
***************
*** 260,271 ****
      char other_buf[SMALL_BUFFER];
      sprintf(other_buf, "$n %s %s $o.",	
  	    posGetActionOther(pos),
! 	    (objGetSubtype(furniture) == FURNITURE_ON ? "on" : "at"));
      message(ch, NULL, furniture, NULL, TRUE, TO_ROOM | TO_NOTCHAR, other_buf);
  
      send_to_char(ch, "You %s %s %s.\r\n",
  		 posGetActionSelf(pos),
! 		 (objGetSubtype(furniture) == FURNITURE_ON ? "on" : "at"),
  		 objGetName(furniture));
  
      // now sit down on the new thing
--- 211,222 ----
      char other_buf[SMALL_BUFFER];
      sprintf(other_buf, "$n %s %s $o.",	
  	    posGetActionOther(pos),
! 	    (furnitureGetType(furniture) == FURNITURE_ON ? "on" : "at"));
      message(ch, NULL, furniture, NULL, TRUE, TO_ROOM | TO_NOTCHAR, other_buf);
  
      send_to_char(ch, "You %s %s %s.\r\n",
  		 posGetActionSelf(pos),
! 		 (furnitureGetType(furniture) == FURNITURE_ON ? "on" : "at"),
  		 objGetName(furniture));
  
      // now sit down on the new thing
diff -crN nakedmudv1.5/src/movement.d nakedmudv2.0/src/movement.d
*** nakedmudv1.5/src/movement.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/movement.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ movement.d movement.o: movement.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h character.h world.h zone.h \
+   room.h exit.h movement.h handler.h inform.h utils.h object.h \
+   scripts/script.h items/items.h items/furniture.h
diff -crN nakedmudv1.5/src/mud.d nakedmudv2.0/src/mud.d
*** nakedmudv1.5/src/mud.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/mud.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ mud.d mud.o: mud.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h utils.h storage.h
diff -crN nakedmudv1.5/src/mud.h nakedmudv2.0/src/mud.h
*** nakedmudv1.5/src/mud.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/mud.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,39 ****
  
  
  //*****************************************************************************
! //
! // if you've installed a new module, you  need to put a define in here to let
  // the rest of the MUD know that you've installed the module.
- //
  //*****************************************************************************
! #define MODULE_OLC
! #define MODULE_TIME
  #define MODULE_SCRIPTS
- #define MODULE_ALIAS
  #define MODULE_CHAR_VARS
  #define MODULE_SOCIALS
  #define MODULE_HELP
  
  
  
  //*****************************************************************************
  //
! // To avoid having to write some bulky structure names, we've typedefed a
  // bunch of shortforms for commonly used datatypes. If you make a new datatype
  // that is used lots, put a typedef for it in here.
  //
--- 16,45 ----
  
  
  //*****************************************************************************
! // if you've installed a newmodule, you  need to put a define in here to let
  // the rest of the MUD know that you've installed the module.
  //*****************************************************************************
! 
! // mandatory modules. These are modules that the NakedMud core REQUIRES to run.
! // They have simply been made modules for organizational ease.
! #define MODULE_ITEMS
! #define MODULE_OLC2
  #define MODULE_SCRIPTS
  #define MODULE_CHAR_VARS
+ #define MODULE_SET_VAL
+ #define MODULE_EDITOR
+ 
+ // here is where your optional modules will go
+ #define MODULE_ALIAS
  #define MODULE_SOCIALS
  #define MODULE_HELP
+ #define MODULE_TIME
  
  
  
  //*****************************************************************************
  //
! // To avoid having to write some bulky structure names, we've typedef'd a
  // bunch of shortforms for commonly used datatypes. If you make a new datatype
  // that is used lots, put a typedef for it in here.
  //
***************
*** 41,63 ****
  typedef struct socket_data                SOCKET_DATA;
  typedef struct char_data                  CHAR_DATA;  
  typedef struct lookup_data                LOOKUP_DATA;
- typedef struct list                       LIST;
- typedef struct list_iterator              LIST_ITERATOR;
- typedef struct hashtable                  HASHTABLE;
- typedef struct hashtable_iterator         HASH_ITERATOR;
- typedef struct hashmap                    HASHMAP;
- typedef struct map_iterator               MAP_ITERATOR;
- typedef struct set_data                   SET;
- typedef struct set_iterator               SET_ITERATOR;
  typedef struct datatable                  DATATABLE;
  typedef struct storage_set                STORAGE_SET;
  typedef struct storage_set_list           STORAGE_SET_LIST;
  
- typedef struct property_table             PROPERTY_TABLE;
- typedef struct property_table_iterator    PROPERTY_TABLE_ITERATOR;
- 
- typedef struct buffer_type                BUFFER;
- 
  typedef struct script_set_data            SCRIPT_SET;
  typedef struct edesc_data                 EDESC_DATA;
  typedef struct edesc_set_data             EDESC_SET;
--- 47,56 ----
***************
*** 73,79 ****
  typedef struct shop_data                  SHOP_DATA;
  typedef struct body_data                  BODY_DATA;
  typedef struct reset_data                 RESET_DATA;
- typedef struct olc_data                   OLC_DATA;
  
  typedef int                               shop_vnum;
  typedef int                               room_vnum;
--- 66,71 ----
***************
*** 98,113 ****
  // the typedefs.
  #include "property_table.h"
  #include "list.h"
! #include "hashmap.h"
  #include "hashtable.h"
  #include "set.h"
  
  
  
! 
! /************************
!  * Standard definitions *
!  ************************/
  
  /* define TRUE and FALSE */
  #ifndef FALSE
--- 90,106 ----
  // the typedefs.
  #include "property_table.h"
  #include "list.h"
! #include "map.h"
  #include "hashtable.h"
  #include "set.h"
+ #include "buffer.h"
+ #include "bitvector.h"
  
  
  
! //*****************************************************************************
! // Standard definitions
! //*****************************************************************************
  
  /* define TRUE and FALSE */
  #ifndef FALSE
***************
*** 132,138 ****
  #define MAX_SCRIPT         16384                  /* max length of a script */
  #define MAX_OUTPUT         8192                   /* well shoot me if it isn't enough   */
  #define FILE_TERMINATOR    "EOF"                  /* end of file marker                 */
! #define COPYOVER_FILE      "../txt/copyover.dat"  /* tempfile to store copyover data    */
  #define EXE_FILE           "../src/NakedMud"      /* the name of the mud binary         */
  #define DEFAULT_PORT       4000                   /* the default port we run on */
  
--- 125,131 ----
  #define MAX_SCRIPT         16384                  /* max length of a script */
  #define MAX_OUTPUT         8192                   /* well shoot me if it isn't enough   */
  #define FILE_TERMINATOR    "EOF"                  /* end of file marker                 */
! #define COPYOVER_FILE      "../.copyover.dat"     /* tempfile to store copyover data    */
  #define EXE_FILE           "../src/NakedMud"      /* the name of the mud binary         */
  #define DEFAULT_PORT       4000                   /* the default port we run on */
  
***************
*** 142,161 ****
  // this line
  //#define MUD_THREADABLE
  
- /* Connection States */
- #define STATE_CLOSED           0  /* should always be the last state
-                                      The above comment is incorrect. GH */
- #define STATE_PLAYING          1
- #define STATE_OLC              2
- #define STATE_TEXT_EDITOR      3 
- #define STATE_NEW_NAME         4
- #define STATE_NEW_PASSWORD     5
- #define STATE_VERIFY_PASSWORD  6
- #define STATE_ASK_PASSWORD     7
- #define STATE_ASK_SEX          8
- #define STATE_ASK_RACE         9
- 
- 
  /* Thread States */
  #define TSTATE_LOOKUP          0  /* Socket is in host_lookup        */
  #define TSTATE_DONE            1  /* The lookup is done.             */
--- 135,140 ----
***************
*** 188,204 ****
  
  #define WORLD_PATH     "../lib/world"
  
- /******************************
-  * End of standard definitons *
-  ******************************/
- 
  
  
! /******************************
!  * New structures             *
!  ******************************/
  
! /* the actual structures */
  struct lookup_data
  {
    SOCKET_DATA       * dsock;   /* the socket we wish to do a hostlookup on */
--- 167,179 ----
  
  #define WORLD_PATH     "../lib/world"
  
  
  
! //*****************************************************************************
! // New structures
! //*****************************************************************************
  
! // required for looking up a socket's IP in a new thread
  struct lookup_data
  {
    SOCKET_DATA       * dsock;   /* the socket we wish to do a hostlookup on */
***************
*** 206,211 ****
--- 181,190 ----
  };
  
  
+ 
+ //*****************************************************************************
+ // core functions for working with new commands
+ //*****************************************************************************
  #define CMD_PTR(name)      void (* name)(CHAR_DATA *ch, const char *cmd, \
  					 int subcmd, char *arg)
  #define COMMAND(name)      void name(CHAR_DATA *ch, const char *cmd, \
***************
*** 216,247 ****
  void add_cmd      (const char *cmd, const char *sort_by, void *func, 
  	           int subcmd, int min_pos, int max_pos,
  	           int min_level, bool mob_ok, bool interrupts);
! void remove_cmd   (const char *cmd);
! 
! 
! struct buffer_type
! {
!   char   * data;        /* The data                      */
!   int      len;         /* The current len of the buffer */
!   int      size;        /* The allocated size of data    */
! };
! 
! /******************************
!  * End of new structures      *
!  ******************************/
  
  
  
! /***************************
!  * Global Variables        *
!  ***************************/
! 
  extern  LIST           *object_list;
  extern  PROPERTY_TABLE *obj_table;      /* same contents as object_list, but
  					   arranged by uid (unique ID)        */
  extern  LIST           *socket_list;
- extern  LIST           *socket_free;
  extern  LIST           *mobile_list;
  extern  PROPERTY_TABLE *mob_table;      /* same contents as mobile_list, but
  					   arranged by uid (unique ID)        */
  extern  const struct    typCmd tabCmd[];/* the command table                  */
--- 195,214 ----
  void add_cmd      (const char *cmd, const char *sort_by, void *func, 
  	           int subcmd, int min_pos, int max_pos,
  	           int min_level, bool mob_ok, bool interrupts);
! bool cmd_exists   (const char *cmd);
  
  
  
! //*****************************************************************************
! // Global Variables
! //*****************************************************************************
  extern  LIST           *object_list;
  extern  PROPERTY_TABLE *obj_table;      /* same contents as object_list, but
  					   arranged by uid (unique ID)        */
  extern  LIST           *socket_list;
  extern  LIST           *mobile_list;
+ extern  LIST           *extract_obj_funcs; // functions called on obj extraction
+ extern  LIST           *extract_mob_funcs; // functions called on mob extraction
  extern  PROPERTY_TABLE *mob_table;      /* same contents as mobile_list, but
  					   arranged by uid (unique ID)        */
  extern  const struct    typCmd tabCmd[];/* the command table                  */
***************
*** 254,269 ****
  
  extern WORLD_DATA    *   gameworld;     // the world of the game
  
- /*************************** 
-  * End of Global Variables *
-  ***************************/
- 
- 
  
- /***********************
-  *    MCCP support     *
-  ***********************/
  
  extern const unsigned char compress_will[];
  extern const unsigned char compress_will2[];
  
--- 221,231 ----
  
  extern WORLD_DATA    *   gameworld;     // the world of the game
  
  
  
+ //*****************************************************************************
+ // MCCP support
+ //*****************************************************************************
  extern const unsigned char compress_will[];
  extern const unsigned char compress_will2[];
  
***************
*** 271,289 ****
  #define TELOPT_COMPRESS2      86
  #define COMPRESS_BUF_SIZE   8192
  
- /***********************
-  * End of MCCP support *
-  ***********************/
- 
- 
- 
- /***********************************
-  * Prototype function declerations *
-  ***********************************/
  
- #define  buffer_new(size)             __buffer_new     ( size)
- #define  buffer_strcat(buffer,text)   __buffer_strcat  ( buffer, text )
  
  char  *crypt                  ( const char *key, const char *salt );
  
  
--- 233,243 ----
  #define TELOPT_COMPRESS2      86
  #define COMPRESS_BUF_SIZE   8192
  
  
  
+ //*****************************************************************************
+ // Prototype function declerations
+ //*****************************************************************************
  char  *crypt                  ( const char *key, const char *salt );
  
  
***************
*** 294,300 ****
  // Some command scripts may want to re-force a character to
  // perform the command. In that case, scripts_ok can be
  // set to FALSE so that the command script doesn't re-run
- //
  void  do_cmd                  ( CHAR_DATA *ch, char *arg, 
  				bool scripts_ok, bool aliases_ok);
  
--- 248,253 ----
***************
*** 310,327 ****
  
  /* strings.c */
  char   *one_arg               ( char *fStr, char *bStr );
  void    arg_num               ( const char *from, char *to, int num); 
  bool    compares              ( const char *aStr, const char *bStr );
  bool    is_prefix             ( const char *aStr, const char *bStr );
  char   *capitalize            ( char *txt );
  char   *strfind               (char *txt, char *sub);
- BUFFER *__buffer_new          ( int size );
- void    __buffer_strcat       ( BUFFER *buffer, const char *text );
- void    buffer_free           ( BUFFER *buffer );
- void    buffer_clear          ( BUFFER *buffer );
- int     bprintf               ( BUFFER *buffer, char *fmt, ... ) __attribute__ ((format (printf, 2, 3)));
- const char *buffer_string     ( BUFFER *buffer );
- void    buffer_format         ( BUFFER *buffer, bool indent );
  
  /* mccp.c */
  bool  compressStart     ( SOCKET_DATA *dsock, unsigned char teleopt );
--- 263,274 ----
  
  /* strings.c */
  char   *one_arg               ( char *fStr, char *bStr );
+ char   *two_args              ( char *from, char *arg1, char *arg2);
  void    arg_num               ( const char *from, char *to, int num); 
  bool    compares              ( const char *aStr, const char *bStr );
  bool    is_prefix             ( const char *aStr, const char *bStr );
  char   *capitalize            ( char *txt );
  char   *strfind               (char *txt, char *sub);
  
  /* mccp.c */
  bool  compressStart     ( SOCKET_DATA *dsock, unsigned char teleopt );
***************
*** 338,346 ****
  void  page_continue         ( SOCKET_DATA *dsock);
  void  page_back             ( SOCKET_DATA *dsock);
  
- 
- /*******************************
-  * End of prototype declartion *
-  *******************************/
- 
  #endif  /* MUD_H */
--- 285,288 ----
diff -crN nakedmudv1.5/src/object.c nakedmudv2.0/src/object.c
*** nakedmudv1.5/src/object.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/object.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 14,20 ****
  #include "mud.h"
  #include "extra_descs.h"
  #include "utils.h"
- #include "items.h"
  #include "body.h"
  #include "handler.h"
  #include "storage.h"
--- 14,19 ----
***************
*** 29,48 ****
  
  struct object_data {
    obj_vnum vnum;                 // our number for builders
!   int type, subtype;             // e.g. clothing/shirt
!   int         uid;               // our unique identifier
!   bitvector_t bits;              // bits that have to do with our current state
!   double      weight;            // how much do we weigh, minus contents
!   double      capacity;          // how much weight can we hold?
! 
!   int values[NUM_OBJ_VALUES];    // special values used by items.h
    
    char *name;                    // our name - e.g. "a shirt"
    char *keywords;                // words to reference us by
    char *rdesc;                   // our room description
-   char *desc;                    // the description when we are looked at
    char *multi_name;              // our name when more than 1 appears
    char *multi_rdesc;             // our rdesc when more than 1 appears
  
    // only one of these should be set at a time
    OBJ_DATA  *container;          // the thing we are in
--- 28,43 ----
  
  struct object_data {
    obj_vnum vnum;                 // our number for builders
!   int      uid;                  // our unique identifier
!   double   weight;               // how much do we weigh, minus contents
    
    char *name;                    // our name - e.g. "a shirt"
    char *keywords;                // words to reference us by
    char *rdesc;                   // our room description
    char *multi_name;              // our name when more than 1 appears
    char *multi_rdesc;             // our rdesc when more than 1 appears
+   BUFFER *desc;                  // the description when we are looked at
+   BITVECTOR *bits;               // the object bits we have turned on
  
    // only one of these should be set at a time
    OBJ_DATA  *container;          // the thing we are in
***************
*** 65,82 ****
    obj->uid            = next_obj_uid++;
    obj->vnum           = NOTHING;
  
-   obj->type           = ITEM_OTHER;
-   obj->subtype        = 0;
-   obj->bits           = 0;
    obj->weight         = 0.1;
-   obj->capacity       = 0;
  
    obj->name           = strdup("");
    obj->keywords       = strdup("");
    obj->rdesc          = strdup("");
-   obj->desc           = strdup("");
    obj->multi_name     = strdup("");
    obj->multi_rdesc    = strdup("");
  
    obj->contents       = newList();
    obj->users          = newList();
--- 60,74 ----
    obj->uid            = next_obj_uid++;
    obj->vnum           = NOTHING;
  
    obj->weight         = 0.1;
  
+   obj->bits           = bitvectorInstanceOf("obj_bits");
    obj->name           = strdup("");
    obj->keywords       = strdup("");
    obj->rdesc          = strdup("");
    obj->multi_name     = strdup("");
    obj->multi_rdesc    = strdup("");
+   obj->desc           = newBuffer(1);
  
    obj->contents       = newList();
    obj->users          = newList();
***************
*** 98,107 ****
    if(obj->name)       free(obj->name);
    if(obj->keywords)   free(obj->keywords);
    if(obj->rdesc)      free(obj->rdesc);
!   if(obj->desc)       free(obj->desc);
    if(obj->multi_name) free(obj->multi_name);
    if(obj->multi_rdesc)free(obj->multi_rdesc);
! 
    if(obj->edescs)   deleteEdescSet(obj->edescs);
    deleteAuxiliaryData(obj->auxiliary_data);
  
--- 90,99 ----
    if(obj->name)       free(obj->name);
    if(obj->keywords)   free(obj->keywords);
    if(obj->rdesc)      free(obj->rdesc);
!   if(obj->desc)       deleteBuffer(obj->desc);
    if(obj->multi_name) free(obj->multi_name);
    if(obj->multi_rdesc)free(obj->multi_rdesc);
!   if(obj->bits)     deleteBitvector(obj->bits);
    if(obj->edescs)   deleteEdescSet(obj->edescs);
    deleteAuxiliaryData(obj->auxiliary_data);
  
***************
*** 110,134 ****
  
  
  OBJ_DATA *objRead(STORAGE_SET *set) {
!   OBJ_DATA *obj = newObj(NOTHING);
    objSetVnum(obj,               read_int(set, "vnum"));
-   objSetType(obj,               read_int(set, "type"));
-   objSetSubtype(obj,            read_int(set, "subtype"));
-   objSetVal(obj, 0,             read_int(set, "value 0"));
-   objSetVal(obj, 1,             read_int(set, "value 1"));
-   objSetVal(obj, 2,             read_int(set, "value 2"));
-   objSetVal(obj, 3,             read_int(set, "value 3"));
-   objSetVal(obj, 4,             read_int(set, "value 4"));
    objSetWeightRaw(obj,       read_double(set, "weight"));
-   objSetCapacity(obj,        read_double(set, "capacity"));
    objSetName(obj,            read_string(set, "name"));
    objSetKeywords(obj,        read_string(set, "keywords"));
    objSetRdesc(obj,           read_string(set, "rdesc"));
    objSetDesc(obj,            read_string(set, "desc"));
    objSetMultiName(obj,       read_string(set, "multiname"));
    objSetMultiRdesc(obj,      read_string(set, "multirdesc"));
-   obj->bits =     parse_bits(read_string(set, "bits"));
    objSetEdescs(obj,   edescSetRead(read_set(set, "edescs")));
    deleteAuxiliaryData(obj->auxiliary_data);
    obj->auxiliary_data = auxiliaryDataRead(read_set(set, "auxiliary"), 
  					  AUXILIARY_TYPE_OBJ);
--- 102,118 ----
  
  
  OBJ_DATA *objRead(STORAGE_SET *set) {
!   OBJ_DATA *obj = newObj();
    objSetVnum(obj,               read_int(set, "vnum"));
    objSetWeightRaw(obj,       read_double(set, "weight"));
    objSetName(obj,            read_string(set, "name"));
    objSetKeywords(obj,        read_string(set, "keywords"));
    objSetRdesc(obj,           read_string(set, "rdesc"));
    objSetDesc(obj,            read_string(set, "desc"));
    objSetMultiName(obj,       read_string(set, "multiname"));
    objSetMultiRdesc(obj,      read_string(set, "multirdesc"));
    objSetEdescs(obj,   edescSetRead(read_set(set, "edescs")));
+   bitSet(obj->bits,read_string(set, "obj_bits"));
    deleteAuxiliaryData(obj->auxiliary_data);
    obj->auxiliary_data = auxiliaryDataRead(read_set(set, "auxiliary"), 
  					  AUXILIARY_TYPE_OBJ);
***************
*** 149,185 ****
  STORAGE_SET *objStore(OBJ_DATA *obj) {
    STORAGE_SET *set = new_storage_set();
    store_int   (set, "vnum",      obj->vnum);
-   store_int   (set, "type",      obj->type);
-   store_int   (set, "subtype",   obj->subtype);
-   store_int   (set, "value 0",   objGetVal(obj, 0));
-   store_int   (set, "value 1",   objGetVal(obj, 1));
-   store_int   (set, "value 2",   objGetVal(obj, 2));
-   store_int   (set, "value 3",   objGetVal(obj, 3));
-   store_int   (set, "value 4",   objGetVal(obj, 4));
    store_double(set, "weight",    obj->weight);
-   store_double(set, "capacity",  obj->capacity);
    store_string(set, "name",      obj->name);
    store_string(set, "keywords",  obj->keywords);
    store_string(set, "rdesc",     obj->rdesc);
!   store_string(set, "desc",      obj->desc);
    store_string(set, "multiname", obj->multi_name);
    store_string(set, "multirdesc",obj->multi_rdesc);
-   store_string(set, "bits",      write_bits(obj->bits));
    store_set   (set, "edescs",    edescSetStore(obj->edescs));
    store_set   (set, "auxiliary", auxiliaryDataStore(obj->auxiliary_data));
    store_list  (set, "contents",  gen_store_list(obj->contents, objStore));
    return set;
  }
  
  
  void objCopyTo(OBJ_DATA *from, OBJ_DATA *to) {
-   int i;
-   for(i = 0; i < NUM_OBJ_VALUES; i++)
-     objSetVal(to, i, objGetVal(from, i));
- 
-   to->bits = from->bits;
- 
-   objSetCapacity  (to, objGetCapacity(from));
    objSetWeightRaw (to, objGetWeightRaw(from));
    objSetVnum      (to, objGetVnum(from));
    objSetName      (to, objGetName(from));
--- 133,155 ----
  STORAGE_SET *objStore(OBJ_DATA *obj) {
    STORAGE_SET *set = new_storage_set();
    store_int   (set, "vnum",      obj->vnum);
    store_double(set, "weight",    obj->weight);
    store_string(set, "name",      obj->name);
    store_string(set, "keywords",  obj->keywords);
    store_string(set, "rdesc",     obj->rdesc);
!   store_string(set, "desc",      bufferString(obj->desc));
    store_string(set, "multiname", obj->multi_name);
    store_string(set, "multirdesc",obj->multi_rdesc);
    store_set   (set, "edescs",    edescSetStore(obj->edescs));
+   store_string(set, "obj_bits",  bitvectorGetBits(obj->bits));
    store_set   (set, "auxiliary", auxiliaryDataStore(obj->auxiliary_data));
    store_list  (set, "contents",  gen_store_list(obj->contents, objStore));
+ 
    return set;
  }
  
  
  void objCopyTo(OBJ_DATA *from, OBJ_DATA *to) {
    objSetWeightRaw (to, objGetWeightRaw(from));
    objSetVnum      (to, objGetVnum(from));
    objSetName      (to, objGetName(from));
***************
*** 188,207 ****
    objSetDesc      (to, objGetDesc(from));
    objSetMultiName (to, objGetMultiName(from));
    objSetMultiRdesc(to, objGetMultiRdesc(from));
!   objSetType     (to, objGetType(from));
!   objSetSubtype  (to, objGetSubtype(from));
!   copyEdescSetTo (objGetEdescs(from), objGetEdescs(to));
    auxiliaryDataCopyTo(from->auxiliary_data, to->auxiliary_data);
  }
  
- 
  OBJ_DATA *objCopy(OBJ_DATA *obj) {
    OBJ_DATA *newobj = newObj();
    objCopyTo(obj, newobj);
    return newobj;
  }
  
- 
  bool objIsName(OBJ_DATA *obj, const char *name) {
    return is_keyword(obj->keywords, name, TRUE);
  }
--- 158,174 ----
    objSetDesc      (to, objGetDesc(from));
    objSetMultiName (to, objGetMultiName(from));
    objSetMultiRdesc(to, objGetMultiRdesc(from));
!   edescSetCopyTo  (objGetEdescs(from), objGetEdescs(to));
!   bitvectorCopyTo (from->bits, to->bits);
    auxiliaryDataCopyTo(from->auxiliary_data, to->auxiliary_data);
  }
  
  OBJ_DATA *objCopy(OBJ_DATA *obj) {
    OBJ_DATA *newobj = newObj();
    objCopyTo(obj, newobj);
    return newobj;
  }
  
  bool objIsName(OBJ_DATA *obj, const char *name) {
    return is_keyword(obj->keywords, name, TRUE);
  }
***************
*** 211,222 ****
    listPut(obj->users, ch);
  }
  
- 
  void objRemoveChar(OBJ_DATA *obj, CHAR_DATA *ch) {
    listRemove(obj->users, ch);
  }
  
  
  //*****************************************************************************
  //
  // set and get functions
--- 178,189 ----
    listPut(obj->users, ch);
  }
  
  void objRemoveChar(OBJ_DATA *obj, CHAR_DATA *ch) {
    listRemove(obj->users, ch);
  }
  
  
+ 
  //*****************************************************************************
  //
  // set and get functions
***************
*** 234,251 ****
    return obj->vnum;
  }
  
- int objGetVal(OBJ_DATA *obj, int num) {
-   return obj->values[num];
- }
- 
- int objGetType(OBJ_DATA *obj) {
-   return obj->type;
- }
- 
- int objGetSubtype(OBJ_DATA *obj) {
-   return obj->subtype;
- }
- 
  const char *objGetName(OBJ_DATA *obj) {
    return obj->name;
  }
--- 201,206 ----
***************
*** 259,277 ****
  }
  
  const char  *objGetDesc    (OBJ_DATA *obj) {
!   return obj->desc;
  }
  
  const char  *objGetMultiName(OBJ_DATA *obj) {
    return obj->multi_name;
  }
  
! const char  *objGetMultiRdesc(OBJ_DATA *obj) {
!   return obj->multi_rdesc;
  }
  
! char **objGetDescPtr(OBJ_DATA *obj) {
!   return &(obj->desc);
  }
  
  EDESC_SET *objGetEdescs(OBJ_DATA *obj) {
--- 214,232 ----
  }
  
  const char  *objGetDesc    (OBJ_DATA *obj) {
!   return bufferString(obj->desc);
  }
  
  const char  *objGetMultiName(OBJ_DATA *obj) {
    return obj->multi_name;
  }
  
! BUFFER *objGetDescBuffer(OBJ_DATA *obj) {
!   return obj->desc;
  }
  
! const char  *objGetMultiRdesc(OBJ_DATA *obj) {
!   return obj->multi_rdesc;
  }
  
  EDESC_SET *objGetEdescs(OBJ_DATA *obj) {
***************
*** 279,286 ****
  }
  
  const char *objGetEdesc(OBJ_DATA *obj, const char *keyword) {
!   EDESC_DATA *edesc = getEdesc(obj->edescs, keyword);
!   if(edesc) return getEdescDescription(edesc);
    else return NULL;
  }
  
--- 234,241 ----
  }
  
  const char *objGetEdesc(OBJ_DATA *obj, const char *keyword) {
!   EDESC_DATA *edesc = edescSetGet(obj->edescs, keyword);
!   if(edesc) return edescSetGetDesc(edesc);
    else return NULL;
  }
  
***************
*** 304,313 ****
    return obj->uid;
  }
  
- double objGetCapacity(OBJ_DATA *obj) {
-   return obj->capacity;
- }
- 
  double objGetWeightRaw(OBJ_DATA *obj) {
    return obj->weight;
  }
--- 259,264 ----
***************
*** 325,330 ****
--- 276,285 ----
    return tot_weight;
  }
  
+ BITVECTOR *objGetBits(OBJ_DATA *obj) {
+   return obj->bits;
+ }
+ 
  void *objGetAuxiliaryData(const OBJ_DATA *obj, const char *name) {
    return hashGet(obj->auxiliary_data, name);
  }
***************
*** 333,355 ****
    obj->vnum = vnum;
  }
  
- void objSetVal(OBJ_DATA *obj, int num, int val) {
-   obj->values[num] = val;
- }
- 
- void objSetType(OBJ_DATA *obj, int type) {
-   obj->type = type;
- }
- 
- void objSetSubtype(OBJ_DATA *obj, int subtype) {
-   obj->subtype = subtype;
- }
- 
- void objSetName(OBJ_DATA *obj, const char *name) {
-   if(obj->name) free(obj->name);
-   obj->name = strdup(name ? name : "");
- }
- 
  void objSetKeywords(OBJ_DATA *obj, const char *keywords) {
    if(obj->keywords) free(obj->keywords);
    obj->keywords = strdup(keywords ? keywords : "");
--- 288,293 ----
***************
*** 360,368 ****
    obj->rdesc = strdup(rdesc ? rdesc : "");
  }
  
  void objSetDesc(OBJ_DATA *obj, const char *desc) {
!   if(obj->desc) free(obj->desc);
!   obj->desc = strdup(desc ? desc : "");
  }
  
  void objSetMultiName(OBJ_DATA *obj, const char *multi_name) {
--- 298,311 ----
    obj->rdesc = strdup(rdesc ? rdesc : "");
  }
  
+ void objSetName(OBJ_DATA *obj, const char *name) {
+   if(obj->name) free(obj->name);
+   obj->name = strdup(name ? name : "");
+ }
+ 
  void objSetDesc(OBJ_DATA *obj, const char *desc) {
!   bufferClear(obj->desc);
!   bufferCat(obj->desc, (desc ? desc : ""));
  }
  
  void objSetMultiName(OBJ_DATA *obj, const char *multi_name) {
***************
*** 396,451 ****
    obj->room = room;
  }
  
- void objSetCapacity(OBJ_DATA *obj, double capacity) {
-   obj->capacity = capacity;
- }
- 
  void objSetWeightRaw(OBJ_DATA *obj, double weight) {
    obj->weight = weight;
  }
- 
- 
- 
- //*****************************************************************************
- //
- // object bits
- //
- //*****************************************************************************
- 
- const char *obj_bits[NUM_OBJ_BITS] = {
-   "notake"
- };
- 
- const char  *objBitGetName    (int field, int bit) {
-   if(field == BITFIELD_OBJ)
-     return obj_bits[bit];
-   return NULL;
- }
- 
- void         objSetBit       ( OBJ_DATA *obj, int field, int bit) {
-   if(field == BITFIELD_OBJ)
-     SET_BIT(obj->bits, (1 << bit));
- }
- 
- void         objRemoveBit    ( OBJ_DATA *obj, int field, int bit) {
-   if(field == BITFIELD_OBJ)
-     REMOVE_BIT(obj->bits, (1 << bit));
- }
- 
- void         objToggleBit    ( OBJ_DATA *obj, int field, int bit) {
-   if(field == BITFIELD_OBJ)
-     TOGGLE_BIT(obj->bits, (1 << bit));
- }
- 
- bool         objIsBitSet     ( OBJ_DATA *obj, int field, int bit) {
-   if(field == BITFIELD_OBJ && IS_SET(obj->bits, (1 << bit)))
-     return TRUE;
-   return FALSE;
- }
- 
- void         objPrintBits   ( OBJ_DATA *obj, int field, char *buf) {
-   if(field == BITFIELD_OBJ)
-     print_bits(obj->bits, obj_bits, buf);
-   else
-     *buf = '\0';
- }
--- 339,344 ----
diff -crN nakedmudv1.5/src/object.d nakedmudv2.0/src/object.d
*** nakedmudv1.5/src/object.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/object.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ object.d object.o: object.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h extra_descs.h utils.h body.h \
+   handler.h storage.h auxiliary.h object.h
diff -crN nakedmudv1.5/src/object.h nakedmudv2.0/src/object.h
*** nakedmudv1.5/src/object.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/object.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 43,63 ****
  const char  *objGetMultiRdesc(OBJ_DATA *obj);
  EDESC_SET   *objGetEdescs    (OBJ_DATA *obj);
  const char  *objGetEdesc     (OBJ_DATA *obj, const char *keyword);
! char       **objGetDescPtr   (OBJ_DATA *obj);
  CHAR_DATA   *objGetCarrier   (OBJ_DATA *obj);
  CHAR_DATA   *objGetWearer    (OBJ_DATA *obj);
  OBJ_DATA    *objGetContainer (OBJ_DATA *obj);
  ROOM_DATA   *objGetRoom      (OBJ_DATA *obj);
  LIST        *objGetContents  (OBJ_DATA *obj);
  LIST        *objGetUsers     (OBJ_DATA *obj);
- int          objGetType      (OBJ_DATA *obj);
- int          objGetSubtype   (OBJ_DATA *obj);
  int          objGetUID       (OBJ_DATA *obj);
- int          objGetVal       (OBJ_DATA *obj, int num);
  double       objGetWeight    (OBJ_DATA *obj);
  double       objGetWeightRaw (OBJ_DATA *obj);
- double       objGetCapacity  (OBJ_DATA *obj);
  void        *objGetAuxiliaryData(const OBJ_DATA *obj, const char *name);
  
  void         objSetVnum      (OBJ_DATA *obj, obj_vnum vnum);
  void         objSetName      (OBJ_DATA *obj, const char *name);
--- 43,60 ----
  const char  *objGetMultiRdesc(OBJ_DATA *obj);
  EDESC_SET   *objGetEdescs    (OBJ_DATA *obj);
  const char  *objGetEdesc     (OBJ_DATA *obj, const char *keyword);
! BUFFER      *objGetDescBuffer(OBJ_DATA *obj);
  CHAR_DATA   *objGetCarrier   (OBJ_DATA *obj);
  CHAR_DATA   *objGetWearer    (OBJ_DATA *obj);
  OBJ_DATA    *objGetContainer (OBJ_DATA *obj);
  ROOM_DATA   *objGetRoom      (OBJ_DATA *obj);
  LIST        *objGetContents  (OBJ_DATA *obj);
  LIST        *objGetUsers     (OBJ_DATA *obj);
  int          objGetUID       (OBJ_DATA *obj);
  double       objGetWeight    (OBJ_DATA *obj);
  double       objGetWeightRaw (OBJ_DATA *obj);
  void        *objGetAuxiliaryData(const OBJ_DATA *obj, const char *name);
+ BITVECTOR   *objGetBits      (OBJ_DATA *obj);
  
  void         objSetVnum      (OBJ_DATA *obj, obj_vnum vnum);
  void         objSetName      (OBJ_DATA *obj, const char *name);
***************
*** 71,103 ****
  void         objSetWearer    (OBJ_DATA *obj, CHAR_DATA *ch);
  void         objSetContainer (OBJ_DATA *obj, OBJ_DATA  *cont);
  void         objSetRoom      (OBJ_DATA *obj, ROOM_DATA *room);
- void         objSetType      (OBJ_DATA *obj, int type);
- void         objSetSubtype   (OBJ_DATA *obj, int subtype);
- void         objSetVal       (OBJ_DATA *obj, int num, int val);
  void         objSetWeightRaw (OBJ_DATA *obj, double weight);
- void         objSetCapacity  (OBJ_DATA *obj, double capacity);
- 
- void         objToggleBit     (OBJ_DATA *obj, int field, int bit);
- void         objSetBit        (OBJ_DATA *obj, int field, int bit);
- void         objRemoveBit     (OBJ_DATA *obj, int field, int bit);
- bool         objIsBitSet      (OBJ_DATA *obj, int field, int bit);
- void         objPrintBits     (OBJ_DATA *obj, int field, char *buf);
- const char  *objBitGetName    (int field, int bit);
- 
- 
- //*****************************************************************************
- //
- // Bitfields and their bits
- //
- //*****************************************************************************
- #define BITFIELD_OBJ              0
- #define OBJ_NOTAKE                0  // (1 << 0)
- #define NUM_OBJ_BITS              1
- 
- #define BITFIELD_WEAP             1
- #define NUM_WEAP_BITS             0
- 
- #define BITFIELD_WORN             2
- #define NUM_WORN_BITS             0
  
  #endif // __OBJECT_H
--- 68,73 ----
diff -crN nakedmudv1.5/src/olc/dedit.c nakedmudv2.0/src/olc/dedit.c
*** nakedmudv1.5/src/olc/dedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/dedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,326 ****
- //*****************************************************************************
- //
- // dialog_edit.c
- //
- // the functions needed for dialog editing in olc.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../socket.h"
- #include "../utils.h"
- #include "../dialog.h"
- 
- #include "olc.h"
- 
- 
- #define EDITING_NEW_RESPONSE      "new_response"
- 
- 
- //*****************************************************************************
- //
- // extra description sets
- //
- //*****************************************************************************
- void dedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   DIALOG_DATA *dialog = olcGetData(olc);
-   int i, entries = dialogGetSize(dialog);
-   int half_entries = entries/2 + (entries % 2 == 1);
-   // entries are printed side by side... these are used to hold 'em
-   char left_buf[SMALL_BUFFER];
-   char right_buf[SMALL_BUFFER];
- 
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{gN) Dialog name\r\n"
- 		 "{c%s\r\n"
- 		 "{gG) Greet/Approach message\r\n"
- 		 "{c%s\r\n"
- 		 "\r\n"
- 		 "{gResponse Entries: {c%d\r\n", 
- 		 dialogGetName(dialog), 
- 		 (*dialogGetGreet(dialog) ? dialogGetGreet(dialog) : "<NONE>"), 
- 		 entries);
- 
-   // print out responses, two to a line
-   for(i = 0; i < half_entries; i++) {
-     RESPONSE_DATA *left_entry = dialogGetNum(dialog, i);
-     sprintf(left_buf, "  {g%2d) {c%s", i, responseGetKeywords(left_entry));
-     if(i + half_entries < entries) {
-       RESPONSE_DATA *right_entry = dialogGetNum(dialog, i + half_entries);
-       sprintf(right_buf, "  {g%2d) {c%s", 
- 	      i + half_entries, responseGetKeywords(right_entry));
-     }
-     else
-       *right_buf = '\0';
- 
-     send_to_socket(sock, "%-35s %s\r\n", left_buf, right_buf);
-   }
- 
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "{gA) Add response\r\n"
- 		 "{gR) Remove response\r\n"
- 		 "Enter number to edit a specific entry\r\n"
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : "
- 		 );
- }
- 
- 
- void dedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = DEDIT_MAIN;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = DEDIT_CONFIRM_SAVE;
-     break;
- 
-   case 'A': {
-     olcSetNext(olc, newOLC(OLC_RESPEDIT, RESPEDIT_MAIN,
- 			   newResponse("", ""), strdup(EDITING_NEW_RESPONSE)));
-     next_substate = DEDIT_ENTRY;
-     break;
-   }
- 
-   case 'R':
-     send_to_socket(sock, "Which response do you want to delete : ");
-     next_substate = DEDIT_DELETE;
-     break;
- 
-   case 'N':
-     send_to_socket(sock, "Enter new name : ");
-     next_substate = DEDIT_NAME;
-     break;
- 
-   case 'G':
-     send_to_socket(sock, "Enter new greeting : ");
-     next_substate = DEDIT_GREET;
-     break;
- 
-   default:
-     // see if maybe they're trying to choose a description to edit
-     if(!isdigit(*arg))
-       dedit_menu(sock, olc);
-     else {
-       int num = atoi(arg);
-       RESPONSE_DATA *resp = dialogGetNum((DIALOG_DATA *)olcGetData(olc), num);
-       // if the one found is null, just show the menu
-       if(resp == NULL)
- 	dedit_menu(sock, olc);
-       else {
- 	olcSetNext(olc, newOLC(OLC_RESPEDIT, RESPEDIT_MAIN, 
- 			       responseCopy(resp), strdup(arg)));
- 	next_substate = DEDIT_ENTRY;
- 	break;
-       }
-     }
-     break;
-   }
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- void dedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = DEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case DEDIT_MAIN:
-     dedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case DEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = DEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case DEDIT_ENTRY:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       DIALOG_DATA  *dialog   = (DIALOG_DATA *)olcGetData(olc);
-       RESPONSE_DATA *entry   = (RESPONSE_DATA *)olcGetData(olcGetNext(olc));
- 
-       if(!strcmp(EDITING_NEW_RESPONSE, (olcGetArgument(olcGetNext(olc)))))
- 	dialogPut(dialog, responseCopy(entry));
-       else {
- 	int num = atoi(olcGetArgument(olcGetNext(olc)));
- 	responseCopyTo(entry, dialogGetNum(dialog, num));
-       }
-     }
-     olcSetNext(olc, NULL);
-     next_substate = DEDIT_MAIN;
-     break;
- 
-   case DEDIT_DELETE: {
-     int num = atoi(arg);
-     RESPONSE_DATA *entry = ((RESPONSE_DATA *)
- 			    dialogGetNum((DIALOG_DATA *)olcGetData(olc), num));
-     if(entry) {
-       dialogRemove((DIALOG_DATA *)olcGetData(olc), entry);
-       deleteResponse(entry);
-     }
-     next_substate = DEDIT_MAIN;
-     break;
-   }
- 
-   case DEDIT_NAME:
-     dialogSetName((DIALOG_DATA *)olcGetData(olc), arg);
-     next_substate = DEDIT_MAIN;
-     break;
- 
-   case DEDIT_GREET:
-     dialogSetGreet((DIALOG_DATA *)olcGetData(olc), arg);
-     next_substate = DEDIT_MAIN;
-     break;
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing dedit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == DEDIT_MAIN)
-     dedit_menu(sock, olc);
- }
- 
- 
- //*****************************************************************************
- //
- // single response editing
- //
- //*****************************************************************************
- void respedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   RESPONSE_DATA *response = (RESPONSE_DATA *)olcGetData(olc);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g1) Keywords\r\n"
- 		 "{c%s\r\n"
- 		 "{g2) Message\r\n"
- 		 "{c%s\r\n"
- 		 "{gEnter choice (Q to quit) : ",
- 		 responseGetKeywords(response), 
- 		 responseGetMessage(response)
- 		 );
- }
- 
- 
- void respedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = RESPEDIT_MAIN;
- 
-   switch(*arg) {
-   case 'q':
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = RESPEDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter new keywords : ");
-     next_substate = RESPEDIT_KEYWORDS;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "Enter new message : ");
-     next_substate = RESPEDIT_MESSAGE;
-     break;
- 
-   default:
-     respedit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- void respedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = RESPEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case RESPEDIT_MAIN:
-     respedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case RESPEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = RESPEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case RESPEDIT_KEYWORDS:
-     responseSetKeywords((RESPONSE_DATA *)olcGetData(olc), arg);
-     break;
-   case RESPEDIT_MESSAGE:
-     responseSetMessage((RESPONSE_DATA *)olcGetData(olc), arg);
-     break;
- 
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing redit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == RESPEDIT_MAIN)
-     respedit_menu(sock, olc);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc/.depend nakedmudv2.0/src/olc/.depend
*** nakedmudv1.5/src/olc/.depend	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/.depend	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,11 ****
- dedit.o: dedit.c olc.h
- edesc_edit.o: edesc_edit.c olc.h
- exedit.o: exedit.c olc.h
- medit.o: medit.c olc.h
- oedit.o: oedit.c olc.h
- olc.o: olc.c olc.h
- redit.o: redit.c olc.h
- resedit.o: resedit.c olc.h
- scedit.o: scedit.c olc.h
- ssedit.o: ssedit.c olc.h
- zedit.o: zedit.c olc.h
--- 0 ----
diff -crN nakedmudv1.5/src/olc/edesc_edit.c nakedmudv2.0/src/olc/edesc_edit.c
*** nakedmudv1.5/src/olc/edesc_edit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/edesc_edit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,290 ****
- //*****************************************************************************
- //
- // edesc_edit.c
- //
- // the functions needed for extra description/extra description set editing
- // in olc.
- //
- //***************************************************************************** 
- 
- #include "../mud.h"
- #include "../socket.h"
- #include "../utils.h"
- #include "../extra_descs.h"
- 
- #include "olc.h"
- 
- 
- #define EDITING_NEW_EDESC      "new_edesc"
- 
- 
- //*****************************************************************************
- //
- // extra description sets
- //
- //*****************************************************************************
- void edsedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   EDESC_SET *set = (EDESC_SET *)olcGetData(olc);
-   int i, entries = getEdescSetSize(set);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{gEntries: {c%d\r\n", entries);
- 
-   // print out each one
-   for(i = 0; i < entries; i++) {
-     EDESC_DATA *entry = getEdescNum(set, i);
-     send_to_socket(sock,
- 		   "  {g%2d) {c%s\r\n", i, getEdescKeywords(entry));
-   }
- 
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "{gN) new entry\r\n"
- 		 "{gD) delete entry\r\n"
- 		 "Enter number to edit a specific entry\r\n"
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : "
- 		 );
- }
- 
- 
- void edsedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = EDSEDIT_MAIN;
- 
-   switch(*arg) {
-   case 'q':
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = EDSEDIT_CONFIRM_SAVE;
-     break;
- 
- 
-   case 'n':
-   case 'N': {
-     olcSetNext(olc, newOLC(OLC_EDEDIT, EDEDIT_MAIN,
- 			   newEdesc("", ""), strdup(EDITING_NEW_EDESC)));
-     next_substate = EDSEDIT_ENTRY;
-     break;
-   }
- 
-   case 'd':
-   case 'D':
-     send_to_socket(sock, "Which extra description do you want to delete : ");
-     next_substate = EDSEDIT_DELETE;
-     break;
- 
-   default:
-     // see if maybe they're trying to choose a description to edit
-     if(!isdigit(*arg))
-       edsedit_menu(sock, olc);
-     else {
-       int num = atoi(arg);
-       EDESC_DATA *edesc = getEdescNum((EDESC_SET *)olcGetData(olc), num);
-       // if the one found is null, just show the menu
-       if(edesc == NULL)
- 	edsedit_menu(sock, olc);
-       else {
- 	olcSetNext(olc, newOLC(OLC_EDEDIT, EDEDIT_MAIN, 
- 			       copyEdesc(edesc), strdup(arg)));
- 	next_substate = EDSEDIT_ENTRY;
- 	break;
-       }
-     }
-     break;
-   }
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- void edsedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = EDSEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case EDSEDIT_MAIN:
-     edsedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case EDSEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = EDSEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case EDSEDIT_ENTRY:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       EDESC_SET  *set   = (EDESC_SET  *)olcGetData(olc);
-       EDESC_DATA *entry = (EDESC_DATA *)olcGetData(olcGetNext(olc));
- 
-       if(!strcmp(EDITING_NEW_EDESC, (olcGetArgument(olcGetNext(olc)))))
- 	edescSetPut(set, copyEdesc(entry));
-       else {
- 	int num = atoi(olcGetArgument(olcGetNext(olc)));
- 	copyEdescTo(entry, getEdescNum(set, num));
-       }
-     }
-     olcSetNext(olc, NULL);
-     next_substate = EDSEDIT_MAIN;
-     break;
- 
-   case EDSEDIT_DELETE: {
-     int num = atoi(arg);
-     EDESC_DATA *entry = ((EDESC_DATA *)
- 			 getEdescNum((EDESC_SET *)olcGetData(olc), num));
-     if(entry) {
-       removeEdesc((EDESC_SET *)olcGetData(olc), entry);
-       deleteEdesc(entry);
-     }
-     next_substate = EDSEDIT_MAIN;
-     break;
-   }
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing edesc edit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == EDSEDIT_MAIN)
-     edsedit_menu(sock, olc);
- }
- 
- 
- //*****************************************************************************
- //
- // single extra descriptions
- //
- //*****************************************************************************
- void ededit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   EDESC_DATA *edesc = (EDESC_DATA *)olcGetData(olc);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g1) Keywords\r\n"
- 		 "{c%s\r\n"
- 		 "{g2) Description\r\n"
- 		 "{c%s\r\n"
- 		 "{gEnter choice (Q to quit) : ",
- 		 getEdescKeywords(edesc), 
- 		 getEdescDescription(edesc)
- 		 );
- }
- 
- 
- void ededit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = EDEDIT_MAIN;
- 
-   switch(*arg) {
-   case 'q':
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = EDEDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter new keywords : ");
-     next_substate = EDEDIT_KEYWORDS;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "Enter new description\r\n");
-     start_text_editor(sock, 
- 		      getEdescPtr((EDESC_DATA *)olcGetData(olc)),
- 		      MAX_BUFFER, EDITOR_MODE_NORMAL);
-     next_substate = REDIT_MAIN;
-     break;
- 
-   default:
-     ededit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- void ededit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = EDEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case EDEDIT_MAIN:
-     ededit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case EDEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = EDEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case EDEDIT_KEYWORDS:
-     setEdescKeywords((EDESC_DATA *)olcGetData(olc), arg);
-     break;
- 
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing redit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == EDEDIT_MAIN)
-     ededit_menu(sock, olc);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc/exedit.c nakedmudv2.0/src/olc/exedit.c
*** nakedmudv1.5/src/olc/exedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/exedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,254 ****
- //*****************************************************************************
- //
- // exedit.c
- //
- // contains all of the functions needed for editing exits.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../exit.h"
- #include "../socket.h"
- #include "../utils.h"
- 
- #include "olc.h"
- 
- 
- void exedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   EXIT_DATA *exit = (EXIT_DATA *)olcGetData(olc);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g[{c%s{g]\r\n"
- 		 "{g1) Door name\r\n"
- 		 "{c%s\r\n"
- 		 "{g2) Door keywords\r\n"
- 		 "{c%s\r\n"
- 		 "{g3) Leave message\r\n"
- 		 "{c%s\r\n"
- 		 "{g4) Enter message\r\n"
- 		 "{c%s\r\n"
- 		 "{g5) Description\r\n"
- 		 "{c%s\r\n"
- 		 "{g6) Exits to:   {y[{c%6d{y]\r\n"
- 		 "{g7) Closable:   {y[{c%6s{y]\r\n"
- 		 "{g8) Key vnum:   {y[{c%6d{y]\r\n"
- 		 "{g9) Pick diff:  {y[{c%6d{y]\r\n"
- 		 "{g0) Spot diff:  {y[{c%6d{y]\r\n"
- 		 "\r\n"
- 		 "{gD) Delete exit\r\n"
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n",
- 		 olcGetArgument(olc),
- 		 (*exitGetName(exit) ? exitGetName(exit) : "<NONE>"),
- 		 (*exitGetKeywords(exit) ? exitGetKeywords(exit) : "<NONE>"),
- 		 (*exitGetSpecLeave(exit) ? exitGetSpecLeave(exit):"<DEFAULT>"),
- 		 (*exitGetSpecEnter(exit) ? exitGetSpecEnter(exit):"<DEFAULT>"),
- 		 exitGetDesc(exit),
- 		 exitGetTo(exit),
- 		 (exitIsClosable(exit) ? "Yes" : "No" ),
- 		 exitGetKey(exit),
- 		 exitGetPickLev(exit),
- 		 exitGetHidden(exit)
- 		 );
- }
- 
- 
- 
- void exedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = EXEDIT_MAIN;
-   EXIT_DATA *exit = (EXIT_DATA *)olcGetData(olc);
- 
-   switch(toupper(*arg)) {
-   case 'q':
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = EXEDIT_CONFIRM_SAVE;
-     break;
- 
-   case 'd':
-   case 'D':
-     send_to_socket(sock, "Are you sure you want to delete this exit (Y/N) : ");
-     next_substate = EXEDIT_CONFIRM_DELETE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter new name : ");
-     next_substate = EXEDIT_NAME;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "Enter new keywords : ");
-     next_substate = EXEDIT_KEYWORDS;
-     break;
- 
-   case '3':
-     send_to_socket(sock,"Enter new leave message ($n for character's name) : ");
-     next_substate = EXEDIT_LEAVE;
-     break;
- 
-   case '4':
-     send_to_socket(sock,"Enter new enter message ($n for character's name) : ");
-     next_substate = EXEDIT_ENTER;
-     break;
- 
-   case '5':
-     send_to_socket(sock, "Enter new description\r\n");
-     start_text_editor(sock,
- 		      exitGetDescPtr(exit),
- 		      MAX_BUFFER, EDITOR_MODE_NORMAL);
-     break;
- 
-   case '6':
-     send_to_socket(sock, "Where does this exit lead to : ");
-     next_substate = EXEDIT_TO;
-     break;
- 
-   case '7':
-     // just toggle it instead of prompting
-     exitSetClosable(exit, (exitIsClosable(exit) ? FALSE : TRUE));
-     next_substate = EXEDIT_MAIN;
-     // since it's normally assumed we show a prompt, 
-     // we have to redisplay the main menu
-     exedit_menu(sock, olc);
- 
-     //    send_to_socket(sock, "Is the exit openable and closable (Y/N) : ");
-     //    next_substate = EXEDIT_CLOSABLE;
-     break;
- 
-   case '8':
-     send_to_socket(sock, "Enter the vnum of the key (-1 for none) : ");
-     next_substate = EXEDIT_KEY;
-     break;
- 
-   case '9':
-     send_to_socket(sock, "How difficult is the lock to pick : ");
-     next_substate = EXEDIT_PICK_DIFF;
-     break;
- 
-   case '0':
-     send_to_socket(sock, "How difficult is the exit to spot : ");
-     next_substate = EXEDIT_SPOT_DIFF;
-     break;
- 
-   default:
-     exedit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- 
- 
- //
- // The entry loop for exedit. Figures out what substate we're
- // in, and then enters into the appropriate subloop if possible,
- // or sets a value based on arg if there is no subloop
- //
- void exedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   EXIT_DATA *exit = (EXIT_DATA *)olcGetData(olc);
-   int next_substate = EXEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case EXEDIT_MAIN:
-     exedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case EXEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = EXEDIT_CONFIRM_SAVE;
-       break;
-     }
- 
- 
-     /******************************************************/
-     /*                   CONFIRM DELETE                   */
-     /******************************************************/
-   case EXEDIT_CONFIRM_DELETE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetData(olc, NULL);
-       olcSetSave(olc, TRUE);
-       olcSetComplete(olc, TRUE);
-       return;
-     case 'n':
-     case 'N':
-       break;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = EXEDIT_CONFIRM_DELETE;
-       break;
-     }
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case EXEDIT_NAME:
-     exitSetName(exit, arg);
-     break;
-   case EXEDIT_KEYWORDS:
-     exitSetKeywords(exit, arg);
-     break;
-   case EXEDIT_LEAVE:
-     exitSetSpecLeave(exit, arg);
-     break;
-   case EXEDIT_ENTER:
-     exitSetSpecEnter(exit, arg);
-     break;
-   case EXEDIT_TO:
-     exitSetTo(exit, atoi(arg));
-     break;
-   case EXEDIT_SPOT_DIFF:
-     exitSetHidden(exit, MAX(0, atoi(arg)));
-     break;
-   case EXEDIT_PICK_DIFF:
-     exitSetPickLev(exit, MAX(0, atoi(arg)));
-     break;
-   case EXEDIT_KEY:
-     exitSetKey(exit, MAX(-1, atoi(arg)));
-     break;
-     /*
-      * closable is now just toggled when
-      * we choose to edit its closable status
-      *
-   case EXEDIT_CLOSABLE:
-     exitSetClosable(exit, (toupper(*arg) == 'Y'));
-     break;
-     */
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing redit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == EXEDIT_MAIN)
-     exedit_menu(sock, olc);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc/medit.c nakedmudv2.0/src/olc/medit.c
*** nakedmudv1.5/src/olc/medit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/medit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,273 ****
- //*****************************************************************************
- //
- // medit.c
- //
- // Contains all of the functions needed for online editing of mobiles.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../world.h"
- #include "../character.h"
- #include "../socket.h"
- #include "../utils.h"
- #include "../races.h"
- #include "../dialog.h"
- 
- #include "olc.h"
- 
- #ifdef MODULE_SCRIPTS
- #include "../scripts/script_set.h"
- #include "../scripts/script.h"
- #endif
- 
- 
- void medit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   CHAR_DATA *mob = (CHAR_DATA *)olcGetData(olc);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g[{c%d{g]\r\n"
- 		 "{g1) Name\r\n"
- 		 "{c%s\r\n"
- 		 "{g2) Name for multiple occurances\r\n"
- 		 "{c%s\r\n"
- 		 "{g3) Keywords\r\n"
- 		 "{c%s\r\n"
- 		 "{g4) Room description\r\n"
- 		 "{c%s\r\n"
- 		 "{g5) Room description for multiple occurances\r\n"
- 		 "{c%s\r\n"
- 		 "{g6) Description\r\n"
- 		 "{c%s\r\n"
- #ifdef MODULE_SCRIPTS
- 		 "{gS) Script menu\r\n"
- #endif
- 		 "{gR) Change race   {y[{c%8s{y]\r\n"
- 		 "{gG) Change Gender {y[{c%8s{y]\r\n"
- 		 "{gD) Dialog        {y[{c%8d{y]  {w%s\r\n",
- 		 charGetVnum(mob),
- 		 charGetName(mob),
- 		 charGetMultiName(mob),
- 		 charGetKeywords(mob),
- 		 charGetRdesc(mob),
- 		 charGetMultiRdesc(mob),
- 		 charGetDesc(mob),
- 		 charGetRace(mob),
- 		 sexGetName(charGetSex(mob)),
- 		 charGetDialog(mob),
- 		 (worldGetDialog(gameworld, charGetDialog(mob)) ?
- 		  dialogGetName(worldGetDialog(gameworld, 
- 					       charGetDialog(mob))) : "")
- 		 );
- 
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n"
- 		 );
- }
- 
- void medit_sex_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   int i;
-   for(i = 0; i < NUM_SEXES; i++)
-     send_to_socket(sock, "%2d) %s\r\n", i, sexGetName(i));
- }
- 
- void medit_race_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   send_to_socket(sock, "%s\r\n\r\n", raceGetList(FALSE));
-   send_to_socket(sock, "Please select a race: ");
- }
- 
- void medit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = MEDIT_MAIN;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = MEDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter name : ");
-     next_substate = MEDIT_NAME;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "Enter name for multiple occurances : ");
-     next_substate = MEDIT_MULTI_NAME;
-     break;
- 
-   case '3':
-     send_to_socket(sock, "Enter keywords : ");
-     next_substate = MEDIT_KEYWORDS;
-     break;
- 
-   case '4':
-     send_to_socket(sock, "Enter room description : ");
-     next_substate = MEDIT_RDESC;
-     break;
- 
-   case '5':
-     send_to_socket(sock, "Enter room description for multiple occurances : ");
-     next_substate = MEDIT_MULTI_RDESC;
-     break;
- 
-   case '6':
-     send_to_socket(sock, "Enter description\r\n");
-     start_text_editor(sock, 
- 		      charGetDescPtr((CHAR_DATA *)olcGetData(olc)),
- 		      MAX_BUFFER, EDITOR_MODE_NORMAL);
-     next_substate = MEDIT_MAIN;
-     break;
- 
-   case 'R':
-     medit_race_menu(sock, olc);
-     next_substate = MEDIT_RACE;
-     break;
- 
-   case 'G':
-     medit_sex_menu(sock, olc);
-     next_substate = MEDIT_SEX;
-     break;
- 
-   case 'D':
-     send_to_socket(sock, "Enter new dialog vnum (-1 for none) : ");
-     next_substate = MEDIT_DIALOG;
-     break;
- 
- #ifdef MODULE_SCRIPTS
-   case 'S':
-     olcSetNext(olc, newOLC(OLC_SSEDIT, SSEDIT_MAIN,
- 			   copyScriptSet(charGetScripts((CHAR_DATA *)olcGetData(olc))), charGetName((CHAR_DATA *)olcGetData(olc))));
-     next_substate = MEDIT_SCRIPTS;
-     break;
- #endif
- 
-   default:
-     medit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- 
- void medit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   CHAR_DATA *mob = (CHAR_DATA *)olcGetData(olc);
-   int next_substate = MEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case MEDIT_MAIN:
-     medit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case MEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = MEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case MEDIT_NAME:
-     charSetName(mob, arg);
-     break;
- 
-   case MEDIT_MULTI_NAME:
-     charSetMultiName(mob, arg);
-     break;
- 
-   case MEDIT_KEYWORDS:
-     charSetKeywords(mob, arg);
-     break;
- 
-   case MEDIT_RDESC:
-     charSetRdesc(mob, arg);
-     break;
- 
-   case MEDIT_MULTI_RDESC:
-     charSetMultiRdesc(mob, arg);
-     break;
- 
-   case MEDIT_RACE: {
-     if(!isRace(arg)) {
-       send_to_socket(sock, "Invalid race! Try again: ");
-       next_substate = MEDIT_RACE;
-     }
-     else {
-       charSetRace(mob, arg);
-       charResetBody(mob);
-     }
-     break;
-   }
- 
-   case MEDIT_SEX: {
-     int sex = SEX_NONE;
-     if(isdigit(*arg)) sex = atoi(arg);
-     else              sex = sexGetNum(arg);
-     if(sex == SEX_NONE) {
-       send_to_socket(sock, "Invalid gender! Try again: ");
-       next_substate = MEDIT_SEX;
-     }
-     else
-       charSetSex(mob, sex);
-     break;
-   }
- 
-   case MEDIT_DIALOG: {
-     int vnum = (*arg ? atoi(arg) : NOTHING);
-     DIALOG_DATA *dialog = worldGetDialog(gameworld, vnum);
-     if(dialog || vnum == NOTHING)
-       charSetDialog(mob, vnum);
-     next_substate = MEDIT_MAIN;
-     break;
-   }
- 
- #ifdef MODULE_SCRIPTS
-   case MEDIT_SCRIPTS:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       SCRIPT_SET *scripts = (SCRIPT_SET *)olcGetData(olcGetNext(olc));
-       charSetScripts(mob, (scripts ? copyScriptSet(scripts) : newScriptSet()));
-     }
-     olcSetNext(olc, NULL);
-     next_substate = MEDIT_MAIN;
-     break;
- #endif
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing medit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == MEDIT_MAIN)
-     medit_menu(sock, olc);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc/module.mk nakedmudv2.0/src/olc/module.mk
*** nakedmudv1.5/src/olc/module.mk	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/module.mk	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,4 ****
- # source files we contain
- SRC  += olc/dedit.c olc/edesc_edit.c olc/exedit.c olc/medit.c olc/oedit.c \
- 	olc/redit.c olc/zedit.c olc/ssedit.c olc/scedit.c olc/resedit.c \
- 	olc/socedit.c olc/olc.c
--- 0 ----
diff -crN nakedmudv1.5/src/olc/oedit.c nakedmudv2.0/src/olc/oedit.c
*** nakedmudv1.5/src/olc/oedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/oedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,519 ****
- //*****************************************************************************
- //
- // oedit.c
- //
- // Contains all of the functions needed for online editing of objects.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../world.h"
- #include "../object.h"
- #include "../extra_descs.h"
- #include "../socket.h"
- #include "../utils.h"
- #include "../body.h"
- #include "../items.h"
- 
- #include "olc.h"
- 
- #ifdef MODULE_SCRIPTS
- #include "../scripts/script_set.h"
- #include "../scripts/script.h"
- #endif
- 
- 
- //
- // a quick little utility to assert that a number is within a given
- // range (max inclusive, min not). If it isn't, make sure the next 
- // state we go to is the same one we're currently in.
- //
- #define ASSERT_VAL_RANGE(num, min, max)                     \
-   if(num < min || num > max) {                              \
-     oedit_val_menu(sock, olc, olcGetSubstate(olc));         \
-     next_substate = olcGetSubstate(olc);                    \
-   }                                                         \
-   else {                                                    \
-     objSetVal(obj, olcGetSubstate(olc) - OEDIT_VAL_0, num); \
-     next_substate = olcGetSubstate(olc) + 1;                \
-     if(next_substate > OEDIT_VAL_0 + NUM_OBJ_VALUES)        \
-       next_substate = OEDIT_MAIN;                           \
-   }
- 
- 
- void oedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   OBJ_DATA *obj = (OBJ_DATA *)olcGetData(olc);
-   char bitbuf[SMALL_BUFFER] = "";
-   char valbuf[MAX_BUFFER] = "";
-   int i;
- 
-   for(i = 0; i < NUM_OBJ_VALUES; i++)
-     sprintf(valbuf, "%s%d ", valbuf, objGetVal(obj, i));
- 
-   objPrintBits(obj, BITFIELD_OBJ, bitbuf);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g[{c%d{g]\r\n"
- 		 "{g1) Name\r\n"
- 		 "{c%s\r\n"
- 		 "{g2) Name for multiple occurances\r\n"
- 		 "{c%s\r\n"
- 		 "{g3) Keywords\r\n"
- 		 "{c%s\r\n"
- 		 "{g4) Room description\r\n"
- 		 "{c%s\r\n"
- 		 "{g5) Room description for multiple occurances\r\n"
- 		 "{c%s\r\n"
- 		 "{g6) Description\r\n"
- 		 "{c%s\r\n"
- 		 "{gW) Weight:    {c%1.3lf\r\n"
- 		 "{gC) Capacity:  {c%1.3lf\r\n"
- 		 "{gB) Edit bits: {c%s\r\n"
- 		 "{gX) Extra Descriptions menu\r\n"
- #ifdef MODULE_SCRIPTS
- 		 "{gS) Script menu\r\n"
- #endif
- 		 "{gT)    Type: {c%s\r\n"
- 		 "{g   Subtype: {c%s\r\n"
- 		 "{g    Values: {c%s\r\n",
- 		 objGetVnum(obj),
- 		 objGetName(obj),
- 		 objGetMultiName(obj),
- 		 objGetKeywords(obj),
- 		 objGetRdesc(obj),
- 		 objGetMultiRdesc(obj),
- 		 objGetDesc(obj),
- 		 objGetWeightRaw(obj),
- 		 objGetCapacity(obj),
- 		 bitbuf,
- 		 itemGetType(objGetType(obj)),
- 		 (numItemSubtypes(objGetType(obj)) > 0 ?
- 		  itemGetSubtype(objGetType(obj), objGetSubtype(obj)) : "none"),
- 		 valbuf
- 		 );
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n"
- 		 );
- }
- 
- 
- //
- // lists all of the item types available
- //
- void show_item_type_menu(SOCKET_DATA *sock) {
-   int i;
- 
-   send_to_socket(sock, "Item types:\r\n");
-   for(i = 0; i < NUM_ITEM_TYPES; i++)
-     send_to_socket(sock, "{c%4d{g) %-14s%s",
- 		   i, itemGetType(i), (i % 3 == 2 ? "\r\n" : "    "));
-   if(i % 3 != 0)
-     send_to_socket(sock, "\r\n");
- 
-   send_to_socket(sock, "\r\nEnter your choice: ");
- }
- 
- 
- //
- // lists all of the subtypes of a particular item type
- //
- void show_item_subtype_menu(SOCKET_DATA *sock, int type) {
-   int i;
-   int num_subtypes = numItemSubtypes(type);
- 
-   if(num_subtypes == 0)
-     return;
-   send_to_socket(sock, "Item subtypes:\r\n");
-   for(i = 0; i < num_subtypes; i++)
-     send_to_socket(sock, "{c%4d{g) %-14s%s",
- 		   i, itemGetSubtype(type, i), (i % 3 == 2 ? "\r\n" : "    "));
-   if(i % 3 != 0)
-     send_to_socket(sock, "\r\n");
-   send_to_socket(sock, "\r\nEnter your choice: ");
- }
- 
- 
- //
- // Show all of the bits
- //
- void show_obj_bits(SOCKET_DATA *sock, OLC_DATA *olc) {
-   OBJ_DATA *obj = olcGetData(olc);
-   char buf[SMALL_BUFFER];
-   int i = 0;
-   
-   send_to_socket(sock, CLEAR_SCREEN);
-   for(i = 0; i < NUM_OBJ_BITS; i++)
-     send_to_socket(sock, "{c%4d{g) %-14s%s",
- 		   i, objBitGetName(BITFIELD_OBJ, i), 
- 		   (i % 3 == 2 ? "\r\n" : "    "));
-   if(i % 3 != 0)
-     send_to_socket(sock, "\r\n");
- 
-   objPrintBits(obj, BITFIELD_OBJ, buf);
-   send_to_socket(sock, 
- 		 "\r\n"
- 		 "Current bits: {c%s{g\r\n"
- 		 "Enter your choice (Q to quit) : ", buf);
- }
- 
- 
- //
- // Returns the state that we should be in right now, if we're trying
- // to edit an olc value with editing state olc_state
- //
- int oedit_val_menu(SOCKET_DATA *sock, OLC_DATA *olc, int olc_state) {
-   int type = objGetType((OBJ_DATA *)olcGetData(olc));
-   switch(olc_state) {
-     /*************/
-     /* OBJ VAL 0 */
-     /*************/
-   case OEDIT_VAL_0:
-     switch(type) {
-     case ITEM_PORTAL:
-       send_to_socket(sock, "Enter a destination (-1, 1000000) : ");
-       break;
-     case ITEM_FURNITURE:
-       send_to_socket(sock, "What is the seating capacity (1, 100) : ");
-       break;
-     case ITEM_CONTAINER:
-       send_to_socket(sock, "Is the container closable (0 = no, 1 = yes) : ");
-       break;
-     default: 
-       return oedit_val_menu(sock, olc, olc_state+1);
-     }
-     break;
- 
- 
-     /*************/
-     /* OBJ VAL 1 */
-     /*************/
-   case OEDIT_VAL_1:
-     switch(type) {
-     case ITEM_CONTAINER:
-       send_to_socket(sock, "What is the key vnum (-1 for none) : ");
-       break;
-     default: 
-       return oedit_val_menu(sock, olc, olc_state+1);
-     }
-     break;
- 
- 
-     /*************/
-     /* OBJ VAL 2 */
-     /*************/
-   case OEDIT_VAL_2:
-     switch(type) {
-     case ITEM_CONTAINER:
-       send_to_socket(sock, "What is the lock picking difficulty : ");
-       break;
-     default: 
-       return oedit_val_menu(sock, olc, olc_state+1);
-     }
-     break;
- 
- 
-     /*************/
-     /* OBJ VAL 3 */
-     /*************/
-   case OEDIT_VAL_3:
-     switch(type) {
-     default: 
-       return oedit_val_menu(sock, olc, olc_state+1);
-     }
-     break;
- 
-   default: 
-     oedit_menu(sock, olc);
-     return OEDIT_MAIN;
-   }
- 
-   // this is reached when we've actually printed a prompt
-   return olc_state;
- }
- 
- 
- 
- void oedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = OEDIT_MAIN;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = OEDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter name : ");
-     next_substate = OEDIT_NAME;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "Enter name for multiple occurances : ");
-     next_substate = OEDIT_MULTI_NAME;
-     break;
- 
-   case '3':
-     send_to_socket(sock, "Enter keywords : ");
-     next_substate = OEDIT_KEYWORDS;
-     break;
- 
-   case '4':
-     send_to_socket(sock, "Enter room description : ");
-     next_substate = OEDIT_RDESC;
-     break;
- 
-   case '5':
-     send_to_socket(sock, "Enter room description for multiple occurances : ");
-     next_substate = OEDIT_MULTI_RDESC;
-     break;
- 
-   case '6':
-     send_to_socket(sock, "Enter description\r\n");
-     start_text_editor(sock, 
- 		      objGetDescPtr((OBJ_DATA *)olcGetData(olc)),
- 		      MAX_BUFFER, EDITOR_MODE_NORMAL);
-     next_substate = OEDIT_MAIN;
-     break;
- 
-   case 'W':
-     send_to_socket(sock, "Enter new weight : ");
-     next_substate = OEDIT_WEIGHT;
-     break;
- 
-   case 'C':
-     send_to_socket(sock, "Enter new carrying capacity : ");
-     next_substate = OEDIT_CAPACITY;
-     break;
- 
-   case 'B':
-     show_obj_bits(sock, olc);
-     next_substate = OEDIT_BITS;
-     break;
- 
-   case 'X':
-     olcSetNext(olc, newOLC(OLC_EDSEDIT, EDSEDIT_MAIN, 
- 			   copyEdescSet(objGetEdescs((OBJ_DATA *)olcGetData(olc))), NULL));
-     next_substate = OEDIT_EDESCS;
-     break;
- 
- #ifdef MODULE_SCRIPTS
-   case 'S':
-     olcSetNext(olc, newOLC(OLC_SSEDIT, SSEDIT_MAIN,
- 			   copyScriptSet(objGetScripts((OBJ_DATA *)olcGetData(olc))), objGetName((OBJ_DATA *)olcGetData(olc))));
-     next_substate = OEDIT_SCRIPTS;
-     break;
- #endif
- 
-   case 'T':
-     show_item_type_menu(sock);
-     next_substate = OEDIT_TYPE;
-     break;
- 
-   default:
-     oedit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- 
- void oedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   OBJ_DATA *obj = (OBJ_DATA *)olcGetData(olc);
-   int next_substate = OEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case OEDIT_MAIN:
-     oedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case OEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = OEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case OEDIT_NAME:
-     objSetName(obj, arg);
-     break;
- 
-   case OEDIT_MULTI_NAME:
-     objSetMultiName(obj, arg);
-     break;
- 
-   case OEDIT_KEYWORDS:
-     objSetKeywords(obj, arg);
-     break;
- 
-   case OEDIT_RDESC:
-     objSetRdesc(obj, arg);
-     break;
- 
-   case OEDIT_MULTI_RDESC:
-     objSetMultiRdesc(obj, arg);
-     break;
- 
-   case OEDIT_WEIGHT:
-     objSetWeightRaw(obj, atof(arg));
-     break;
- 
-   case OEDIT_CAPACITY:
-     objSetCapacity(obj, atof(arg));
-     break;
- 
-   case OEDIT_EDESCS:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       EDESC_SET *edescs = (EDESC_SET *)olcGetData(olcGetNext(olc));
-       objSetEdescs(obj, (edescs ? copyEdescSet(edescs) : newEdescSet()));
-     }
- 
-     olcSetNext(olc, NULL);
-     next_substate = OEDIT_MAIN;
-     break;
- 
- #ifdef MODULE_SCRIPTS
-   case OEDIT_SCRIPTS:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       SCRIPT_SET *scripts = (SCRIPT_SET *)olcGetData(olcGetNext(olc));
-       objSetScripts(obj, (scripts ? copyScriptSet(scripts) : newScriptSet()));
-     }
-     olcSetNext(olc, NULL);
-     next_substate = OEDIT_MAIN;
-     break;
- #endif
- 
-   case OEDIT_BITS:
-     if(toupper(*arg) == 'Q')
-       next_substate = OEDIT_MAIN;
-     else {
-       int bit = atoi(arg);
-       if(bit >= 0 && bit < NUM_OBJ_BITS)
- 	objToggleBit(obj, BITFIELD_OBJ, bit);
-       next_substate = OEDIT_BITS;
-     }
-     break;
- 
-   case OEDIT_TYPE: {
-     int num = atoi(arg);
-     if(num < 0 || num >= NUM_ITEM_TYPES) {
-       show_item_type_menu(sock);
-       next_substate = OEDIT_TYPE;
-     }
-     else {
-       // if we're not of the same type, reset all of our values
-       if(num != objGetType(obj)) {
- 	int i;
- 	for(i = 0; i < NUM_OBJ_VALUES; i++)
- 	  objSetVal(obj, i, 0);
-       }
- 
-       objSetType(obj, num);
-       if(numItemSubtypes(num) > 0) {
- 	show_item_subtype_menu(sock, num);
- 	next_substate = OEDIT_SUBTYPE;
-       }
-       else
- 	next_substate = OEDIT_VAL_0;
-     }
-     break;
-   }
- 
-   case OEDIT_SUBTYPE: {
-     int num = atoi(arg);
-     if(num < 0 || num >= numItemSubtypes(objGetType(obj))) {
-       show_item_subtype_menu(sock, objGetType(obj));
-       next_substate = OEDIT_SUBTYPE;
-     }
-     else {
-       objSetSubtype(obj, num);
-       next_substate = OEDIT_VAL_0;
-     }
-     break;
-   }
- 
-   case OEDIT_VAL_0:
-     switch(objGetType(obj)) {
-     case ITEM_PORTAL:    ASSERT_VAL_RANGE(atoi(arg), -1, 1000000);  break;
-     case ITEM_FURNITURE: ASSERT_VAL_RANGE(atoi(arg), -1, 100);      break;
-     case ITEM_CONTAINER: ASSERT_VAL_RANGE(atoi(arg),  0, 1);        break;
-     default: break;
-     }
-     next_substate = OEDIT_VAL_1;
-     break;
- 
-   case OEDIT_VAL_1:
-     switch(objGetType(obj)) {
-     case ITEM_CONTAINER: ASSERT_VAL_RANGE(atoi(arg), -1, 1000000); break;
-     default: break;
-     }
-     next_substate = OEDIT_VAL_2;
-     break;
- 
-   case OEDIT_VAL_2:
-     switch(objGetType(obj)) {
-     case ITEM_CONTAINER: ASSERT_VAL_RANGE(atoi(arg), 0, 1000000); break;
-     default: break;
-     }
-     next_substate = OEDIT_VAL_3;
-     break;
- 
-   case OEDIT_VAL_3:
-     switch(objGetType(obj)) {
-     default: break;
-     }
-     next_substate = OEDIT_MAIN;
-     break;
- 
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing oedit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
- 
-   /********************************************************/
-   /*                 DISPLAY NEXT MENU HERE               */
-   /********************************************************/
-   if(next_substate == OEDIT_MAIN)
-     oedit_menu(sock, olc);
-   else if(next_substate >= OEDIT_VAL_0 && 
- 	  next_substate <  OEDIT_VAL_0 + NUM_OBJ_VALUES)
-     next_substate = oedit_val_menu(sock, olc, next_substate);
-   else if(next_substate == OEDIT_BITS)
-     show_obj_bits(sock, olc);
- 
-   olcSetSubstate(olc, next_substate);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc/olc.c nakedmudv2.0/src/olc/olc.c
*** nakedmudv1.5/src/olc/olc.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/olc.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,879 ****
- //*****************************************************************************
- //
- // olc.c
- //
- // Contains all of the functions neccessary for online editing.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../socket.h"
- #include "../object.h"
- #include "../character.h"
- #include "../world.h"
- #include "../zone.h"
- #include "../room.h"
- #include "../room_reset.h"
- #include "../exit.h"
- #include "../extra_descs.h"
- #include "../dialog.h"
- 
- #include "olc.h"
- 
- // optional modules
- #ifdef MODULE_SCRIPTS
- #include "../scripts/script.h"
- #include "../scripts/script_set.h"
- #endif
- #ifdef MODULE_SOCIALS
- #include "../socials/socials.h"
- #endif
- 
- 
- /* sucks to have to do this, but I'm declaring some
-    external functions to avoid having to make some
-    more header files. */
- void dedit_loop   (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void dedit_menu   (SOCKET_DATA *sock, OLC_DATA *olc);
- void respedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void respedit_menu(SOCKET_DATA *sock, OLC_DATA *olc);
- void edsedit_loop (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void edsedit_menu (SOCKET_DATA *sock, OLC_DATA *olc);
- void ededit_loop  (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void ededit_menu  (SOCKET_DATA *sock, OLC_DATA *olc);
- void redit_loop   (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void redit_menu   (SOCKET_DATA *sock, OLC_DATA *olc);
- void medit_loop   (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void medit_menu   (SOCKET_DATA *sock, OLC_DATA *olc);
- void exedit_loop  (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void exedit_menu  (SOCKET_DATA *sock, OLC_DATA *olc);
- void zedit_loop   (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void zedit_menu   (SOCKET_DATA *sock, OLC_DATA *olc);
- void wedit_loop   (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void wedit_menu   (SOCKET_DATA *sock, OLC_DATA *olc);
- void oedit_loop   (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void oedit_menu   (SOCKET_DATA *sock, OLC_DATA *olc);
- void resedit_loop (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void resedit_menu (SOCKET_DATA *sock, OLC_DATA *olc);
- #ifdef MODULE_SCRIPTS
- void scedit_loop  (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void scedit_menu  (SOCKET_DATA *sock, OLC_DATA *olc);
- void ssedit_loop  (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void ssedit_menu  (SOCKET_DATA *sock, OLC_DATA *olc);
- #endif
- #ifdef MODULE_SOCIALS
- void socedit_loop (SOCKET_DATA *sock, OLC_DATA *olc, char *arg);
- void socedit_menu (SOCKET_DATA *sock, OLC_DATA *olc);
- #endif
- 
- 
- 
- struct olc_data {
-   bool complete;
-   bool save;
- 
-   int state;
-   int substate;
- 
-   char *arg;
-   void *data;
- 
-   OLC_DATA *next;
- };
- 
- void init_olc() {
-   // add all of our commands
-   add_cmd("dedit",      NULL, cmd_dedit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, FALSE, TRUE );
-   add_cmd("medit",      NULL, cmd_medit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, FALSE, TRUE );
-   add_cmd("oedit",      NULL, cmd_oedit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, FALSE, TRUE );
-   add_cmd("redit",      NULL, cmd_redit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, FALSE, TRUE );
-   add_cmd("wedit",      NULL, cmd_wedit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, FALSE, TRUE );
-   add_cmd("zedit",      NULL, cmd_zedit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, FALSE, TRUE );
- #ifdef MODULE_SCRIPTS
-   add_cmd("scedit",     NULL, cmd_scedit,   0, POS_SITTING, POS_FLYING,
- 	  LEVEL_SCRIPTER, FALSE, TRUE );
- #endif
- #ifdef MODULE_SOCIALS
-   add_cmd("socedit",    NULL, cmd_socedit,  0, POS_SITTING, POS_FLYING,
- 	  LEVEL_BUILDER,  FALSE, TRUE );
- #endif
- }
- 
- 
- OLC_DATA *newOLC(int state, int substate, void *data, const char *arg) {
-   OLC_DATA *olc = malloc(sizeof(OLC_DATA));
-   olc->data     = data;
-   olc->arg      = strdup(arg ? arg : "");
-   olc->complete = FALSE;
-   olc->save     = FALSE;
-   olc->state    = state;
-   olc->substate = substate;
-   olc->next     = NULL;
-   return olc;
- }
- 
- void deleteOLC(OLC_DATA *olc) {
-   if(olc->next) 
-     deleteOLC(olc->next);
- 
-   if(olc->data) {
-     switch(olc->state) {
-     case OLC_DEDIT:   deleteDialog(olc->data);    break;
-     case OLC_RESPEDIT:deleteResponse(olc->data);  break;
-     case OLC_EDSEDIT: deleteEdescSet(olc->data);  break;
-     case OLC_EDEDIT:  deleteEdesc(olc->data);     break;
-     case OLC_REDIT:   deleteRoom(olc->data);      break;
-     case OLC_OEDIT:   deleteObj(olc->data);       break;
-     case OLC_MEDIT:   deleteChar(olc->data);      break;
-     case OLC_ZEDIT:   deleteZone(olc->data);      break;
-     case OLC_EXEDIT:  deleteExit(olc->data);      break;
-     case OLC_WEDIT:   deleteWorld(olc->data);     break;
-     case OLC_RESEDIT: deleteReset(olc->data);     break;
- #ifdef MODULE_SCRIPTS
-     case OLC_SCEDIT:  deleteScript(olc->data);    break;
-     case OLC_SSEDIT:  deleteScriptSet(olc->data); break;
- #endif
- #ifdef MODULE_SOCIALS
-     case OLC_SOCEDIT: deleteSocial(olc->data);    break;
- #endif
-     }
-   }
- 
-   if(olc->arg) 
-     free(olc->arg);
-   free(olc);
- }
- 
- int       olcGetState   (OLC_DATA *olc) {
-   return olc->state;
- }
- 
- int       olcGetSubstate(OLC_DATA *olc) {
-   return olc->substate;
- }
- 
- void      olcSetState   (OLC_DATA *olc, int state) {
-   olc->state = state;
- }
- 
- void      olcSetSubstate(OLC_DATA *olc, int substate) {
-   olc->substate = substate;
- }
- 
- void  *olcGetData    (OLC_DATA *olc) {
-   return olc->data;
- }
- 
- const char *olcGetArgument(OLC_DATA *olc) {
-   return olc->arg;
- }
- 
- void olcSetArgument(OLC_DATA *olc, char *arg) {
-   if(olc->arg) free(olc->arg);
-   olc->arg = (arg ? strdup(arg) : NULL);
- }
- 
- void olcSetData(OLC_DATA *olc, void  *data) {
-   if(olc->data) {
-     switch(olc->state) {
-     case OLC_DEDIT:    deleteDialog(olc->data);      break;
-     case OLC_RESPEDIT: deleteResponse(olc->data);    break;
-     case OLC_EDSEDIT:  deleteEdescSet(olc->data);    break;
-     case OLC_EDEDIT:   deleteEdesc(olc->data);       break;
-     case OLC_MEDIT:    deleteChar(olc->data);      break;
-     case OLC_REDIT:    deleteRoom(olc->data);        break;
-     case OLC_OEDIT:    deleteObj(olc->data);         break;
-     case OLC_ZEDIT:    deleteZone(olc->data);        break;
-     case OLC_EXEDIT:   deleteExit(olc->data);        break;
-     case OLC_WEDIT:    deleteWorld(olc->data);       break;
-     case OLC_RESEDIT:  deleteReset(olc->data);       break;
- #ifdef MODULE_SCRIPTS
-     case OLC_SCEDIT:   deleteScript(olc->data);      break;
-     case OLC_SSEDIT:   deleteScriptSet(olc->data);   break;
- #endif
- #ifdef MODULE_SOCIALS
-     case OLC_SOCEDIT:  deleteSocial(olc->data);      break;
- #endif
-     }
-   }
-   olc->data = data;
- }
- 
- bool        isOLCComplete (OLC_DATA *olc) {
-   return olc->complete;
- }
- 
- bool        olcGetSave    (OLC_DATA *olc) {
-   return olc->save;
- }
- 
- OLC_DATA   *olcGetNext    (OLC_DATA *olc) {
-   return olc->next;
- }
- 
- void        olcSetNext    (OLC_DATA *olc, OLC_DATA *next) {
-   if(olc->next) deleteOLC(olc->next);
-   olc->next = next;
- }
- 
- void        olcSetComplete(OLC_DATA *olc, bool complete) {
-   olc->complete = complete;
- }
- 
- void        olcSetSave    (OLC_DATA *olc, bool save) {
-   olc->save = save;
- }
- 
- 
- //
- // Save all of the changes made in the OLC to the game world
- //
- void save_olc(OLC_DATA *olc) {
-   int state = olcGetState(olc);
-   switch(state) {
-   case OLC_MEDIT: {
-     CHAR_DATA *mob = olcGetData(olc);
-     CHAR_DATA *old = worldGetMob(gameworld, charGetVnum(mob));
-     // if the mob already exists, just copy over the changes
-     if(old) charCopyTo(mob, old);
-     // otherwise, put a new copy of the mob into the world. We can't
-     // put this copy in, because it will be deleted when the OLC is
-     // deleted.
-     else    worldPutMob(gameworld, charCopy(mob));
-     break;
-   }
- 
-   case OLC_OEDIT: {
-     OBJ_DATA *obj = olcGetData(olc);
-     OBJ_DATA *old = worldGetObj(gameworld, objGetVnum(obj));
-     // if the obj already exists, just copy over the changes
-     if(old) objCopyTo(obj, old);
-     // otherwise, put a new copy of the obj into the world. We can't
-     // put this copy in, because it will be deleted when the OLC is
-     // deleted.
-     else    worldPutObj(gameworld, objCopy(obj));
-     break;
-   }
- 
-   case OLC_ZEDIT: {
-     ZONE_DATA *zone = olcGetData(olc);
-     ZONE_DATA *old  = worldGetZone(gameworld, zoneGetVnum(zone));
-     // if the obj already exists, just copy over the changes
-     if(old) zoneCopyTo(zone, old);
-     // otherwise, put a new copy of the obj into the world. We can't
-     // put this copy in, because it will be deleted when the OLC is
-     // deleted.
-     else    worldPutZone(gameworld, zoneCopy(zone));
-     break;
-   }
- 
-   case OLC_REDIT: {
-     ROOM_DATA *room = olcGetData(olc);
-     ROOM_DATA *old  = worldGetRoom(gameworld, roomGetVnum(room));
-     // if the room already exists, just copy over the changes
-     if(old) roomCopyTo(room, old);
-     // otherwise, put a new copy of the room into the world. We can't
-     // put this copy in, because it will be deleted when the OLC is
-     // deleted.
-     else    worldPutRoom(gameworld, roomCopy(room));
-     break;
-   }
- 
-   case OLC_DEDIT: {
-     DIALOG_DATA *dialog = olcGetData(olc);
-     DIALOG_DATA *old    = worldGetDialog(gameworld, dialogGetVnum(dialog));
-     // if the dialog already exists, just copy over the changes
-     if(old) dialogCopyTo(dialog, old);
-     // otherwise, put a new copy of the dialog into the world. We can't
-     // put this copy in, because it will be deleted when the OLC is
-     // deleted.
-     else    worldPutDialog(gameworld, dialogCopy(dialog));
-     break;
-   }
- 
- #ifdef MODULE_SCRIPTS
-   case OLC_SCEDIT: {
-     SCRIPT_DATA *script = olcGetData(olc);
-     SCRIPT_DATA *old    = worldGetScript(gameworld, scriptGetVnum(script));
-     // if the script already exists, just copy over the changes
-     if(old) scriptCopyTo(script, old);
-     // otherwise, put a new copy of the script into the world. We can't
-     // put this copy in, because it will be deleted when the OLC is
-     // deleted.
-     else    worldPutScript(gameworld, scriptCopy(script));
-     break;
-   }
- #endif
- 
- #ifdef MODULE_SOCIALS
-   case OLC_SOCEDIT: {
-     SOCIAL_DATA *social = olcGetData(olc);
-     SOCIAL_DATA *old    = get_social(olcGetArgument(olc));
-     // if the social already exists, copy it over
-     if(old) socialCopyTo(social, old);
-     // otherwise, put in a new social
-     else add_social(socialCopy(social));
-     break;
-   }
- #endif
- 
- 
-   case OLC_RESEDIT:
-   case OLC_RESPEDIT:
-   case OLC_SSEDIT:
-   case OLC_EDEDIT:
-   case OLC_EDSEDIT:
-   case OLC_EXEDIT: {
-     char buf[SMALL_BUFFER];
-     // print the type of error that is being made
-     sprintf(buf, "%s",
- 	    (state == OLC_SSEDIT ? "script set" :
- 	     (state == OLC_EDEDIT ? "extra description" :
- 	      (state == OLC_EDSEDIT ? "extra desc set" :
- 	       (state == OLC_EXEDIT ? "exit" : 
- 		(state == OLC_RESPEDIT ? "dialog response":
- 		 (state == OLC_RESEDIT ? "reset data" : "unknown type")))))));
- 
-     log_string("ERROR: %s edit was bottom-level OLC edit. Cannot save "
- 	       "%s without a corresponding datastructure!", buf, buf);
-     break;
-   }
- 
-   default:
-     log_string("ERROR: tried to save OLC, but type was unknown.");
-     break;
-   }
- }
- 
- 
- //
- // Find the deepest OLC project that hasn't been finished
- //
- OLC_DATA *olcGetCurrent(OLC_DATA *olc) {
-   if(isOLCComplete(olc))
-     return NULL;
-   if(olcGetNext(olc) && !isOLCComplete(olcGetNext(olc)))
-     return olcGetCurrent(olcGetNext(olc));
-   else
-     return olc;
- }
- 
- 
- //*****************************************************************************
- //
- // The main loops and entrypoints for OLC
- //
- //*****************************************************************************
- void olc_loop(SOCKET_DATA *sock, char *arg) {
-   OLC_DATA *olc = socketGetOLC(sock);
- 
-   if(olc == NULL) {
-     socketSetState(sock, STATE_PLAYING);
-     log_string("ERROR: socket in OLC with no OLC data structure.");
-     return;
-   }
- 
-   olc = olcGetCurrent(socketGetOLC(sock));
- 
-   // everything has been completed... this should never happen
-   if(olc == NULL) {
-     socketSetState(sock, STATE_PLAYING);
-     log_string("ERROR: entered OLC, but had no olc work left.");
-     return;
-   }
- 
-   switch(olcGetState(olc)) {
-   case OLC_MEDIT:
-     medit_loop(sock, olc, arg);
-     break;
-   case OLC_OEDIT:
-     oedit_loop(sock, olc, arg);
-     break;
-   case OLC_REDIT:
-     redit_loop(sock, olc, arg);
-     break;
-   case OLC_EXEDIT:
-     exedit_loop(sock, olc, arg);
-     break;
-   case OLC_EDSEDIT:
-     edsedit_loop(sock, olc, arg);
-     break;
-   case OLC_EDEDIT:
-     ededit_loop(sock, olc, arg);
-     break;
-   case OLC_DEDIT:
-     dedit_loop(sock, olc, arg);
-     break;
-   case OLC_RESPEDIT:
-     respedit_loop(sock, olc, arg);
-     break;
-   case OLC_RESEDIT:
-     resedit_loop(sock, olc, arg);
-     break;
-   case OLC_WEDIT:
-     //    wedit_loop(sock, olc, arg);
-     break;
-   case OLC_ZEDIT:
-     zedit_loop(sock, olc, arg);
-     break;
- #ifdef MODULE_SCRIPTS
-   case OLC_SCEDIT:
-     scedit_loop(sock, olc, arg);
-     break;
-   case OLC_SSEDIT:
-     ssedit_loop(sock, olc, arg);
-     break;
- #endif
- #ifdef MODULE_SOCIALS
-   case OLC_SOCEDIT:
-     socedit_loop(sock, olc, arg);
-     break;
- #endif
- 
-   default:
-     log_string("ERROR: socket in OLC without an appropriate substate.");
-     socketSetOLC(sock, NULL); // this deletes olc as well
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   // clear up all of our completed OLC projects
-   if(isOLCComplete(olc)) {
-     // it's the first OLC project. We have to save to world
-     if(olc == socketGetOLC(sock)) {
-       if(olcGetSave(socketGetOLC(sock)))
- 	save_olc(socketGetOLC(sock));
-       socketSetOLC(sock, NULL); // deletes olc automatically
-       socketSetState(sock, STATE_PLAYING);
-       
-       // do we save changes to disk?
-       if(OLC_AUTOSAVE) {
- 	switch(olcGetState(olc)) {
- 	case OLC_OEDIT:
- 	case OLC_MEDIT:
- 	case OLC_REDIT:
- 	case OLC_ZEDIT:
- 	case OLC_WEDIT:
- 	case OLC_DEDIT:
- #ifdef MODULE_SCRIPTS
- 	case OLC_SCEDIT:
- #endif
- 	  worldSave(gameworld, WORLD_PATH);
- 	  break;
- 	case OLC_SOCEDIT:
- 	  save_socials();
- 	  break;
- 	default:
- 	  log_string("ERROR: Tried to auto-save OLC changes to disk, but state %d was not recognized.", olcGetState(olc));
- 	  break;
- 	}
-       }
-     }
- 
-     // otherwise, save to the previous OLC project. It is expecting
-     // to be completed, so we can just send an empty buffer for input
-     else {
-       char buf[1] = "\0";
-       olc_loop(sock, buf);
-     }
-   }
- 
-   // we added another subproject ... show the menu for it
-   else if(olcGetCurrent(olc) != olc)
-     olc_menu(sock);
- }
- 
- 
- void olc_menu(SOCKET_DATA *sock) {
-   OLC_DATA *olc = socketGetOLC(sock);
- 
-   // we have no OLC, or we've finished editing
-   if(olc == NULL || isOLCComplete(olc))
-     return;
- 
-   // go to the deepest olc project we have not completed working on
-   olc = olcGetCurrent(olc);
- 
-   switch(olcGetState(olc)) {
-   case OLC_MEDIT:
-     medit_menu(sock, olc);
-     break;
-   case OLC_OEDIT:
-     oedit_menu(sock, olc);
-     break;
-   case OLC_REDIT:
-     redit_menu(sock, olc);
-     break;
-   case OLC_EXEDIT:
-     exedit_menu(sock, olc);
-     break;
-   case OLC_EDSEDIT:
-     edsedit_menu(sock, olc);
-     break;
-   case OLC_EDEDIT:
-     ededit_menu(sock, olc);
-     break;
-   case OLC_DEDIT:
-     dedit_menu(sock, olc);
-     break;
-   case OLC_RESPEDIT:
-     respedit_menu(sock, olc);
-     break;
-   case OLC_RESEDIT:
-     resedit_menu(sock, olc);
-     break;
-   case OLC_WEDIT:
-     //    wedit_menu(sock, olc);
-     break;
-   case OLC_ZEDIT:
-     zedit_menu(sock, olc);
-     break;
- #ifdef MODULE_SCRIPTS
-   case OLC_SCEDIT:
-     scedit_menu(sock, olc);
-     break;
-   case OLC_SSEDIT:
-     ssedit_menu(sock, olc);
-     break;
- #endif
- #ifdef MODULE_SOCIALS
-   case OLC_SOCEDIT:
-     socedit_menu(sock, olc);
-     break;
- #endif
-   default:
-       break;
-   }
- }
- 
- 
- COMMAND(cmd_redit) {
-   ZONE_DATA *zone;
-   ROOM_DATA *room;
-   ROOM_DATA *tgt;
-   room_vnum vnum;
- 
-   // if no argument is supplied, default to the current room
-   if(!arg || !*arg)
-     vnum = roomGetVnum(charGetRoom(ch));
-   else
-     vnum = atoi(arg);
- 
- 
-   // make sure there is a corresponding zone ...
-   if((zone = worldZoneBounding(gameworld, vnum)) == NULL) {
-     send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
-     return;
-   }
-   if(!canEditZone(zone, ch)) {
-     send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
-     return;
-   }
- 
-   // find the room
-   tgt = worldGetRoom(gameworld, vnum);
- 
-   // make our room
-   if(tgt == NULL) {
-     room = newRoom();
-     roomSetVnum(room, vnum);
-     roomSetName(room, "An Unfinished Room");
-     roomSetDesc(room, "   You are in an unfinished room.\r\n");
-   }
-   else
-     room = roomCopy(tgt);
-   OLC_DATA *olc = newOLC(OLC_REDIT, REDIT_MAIN, (void *)room, NULL);
-   socketSetOLC(charGetSocket(ch), olc);
-   socketSetState(charGetSocket(ch), STATE_OLC);
-   olc_menu(charGetSocket(ch));
- }
- 
- 
- COMMAND(cmd_medit) {
-   ZONE_DATA *zone;
-   CHAR_DATA *mob;
-   CHAR_DATA *tgt;
-   mob_vnum vnum;
- 
-   // if no argument is supplied, default to the current mob
-   if(!arg || !*arg) {
-     send_to_char(ch, "Please supply the vnum of a mob you wish to edit.\r\n");
-     return;
-   }
-   else
-     vnum = atoi(arg);
- 
- 
-   // make sure there is a corresponding zone ...
-   if((zone = worldZoneBounding(gameworld, vnum)) == NULL) {
-     send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
-     return;
-   }
-   else if(!canEditZone(zone, ch)) {
-     send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
-     return;
-   }
- 
-   // find the mob
-   tgt = worldGetMob(gameworld, vnum);
- 
-   // make our mob
-   if(tgt == NULL) {
-     mob = newMobile(vnum);
-     charSetVnum(mob, vnum);
-     charSetName   (mob, "an unfinished mobile");
-     charSetKeywords(mob, "mobile, unfinshed");
-     charSetRdesc  (mob, "an unfinished mobile is standing here.");
-     charSetDesc   (mob, "it looks unfinished.\r\n");
-     charSetMultiName(mob, "%d unfinished mobiles");
-     charSetMultiRdesc(mob, "A group of %d mobiles are here, looking unfinished.");
-   }
-   else
-     mob = charCopy(tgt);
-   OLC_DATA *olc = newOLC(OLC_MEDIT, MEDIT_MAIN, (void *)mob, NULL);
-   socketSetOLC(charGetSocket(ch), olc);
-   socketSetState(charGetSocket(ch), STATE_OLC);
-   olc_menu(charGetSocket(ch));
- }
- 
- 
- COMMAND(cmd_oedit) {
-   ZONE_DATA *zone;
-   OBJ_DATA *obj;
-   OBJ_DATA *tgt;
-   obj_vnum vnum;
- 
-   // if no argument is supplied, default to the current obj
-   if(!arg || !*arg) {
-     send_to_char(ch, "Please supply the vnum of a obj you wish to edit.\r\n");
-     return;
-   }
-   else
-     vnum = atoi(arg);
- 
- 
-   // make sure there is a corresponding zone ...
-   if((zone = worldZoneBounding(gameworld, vnum)) == NULL) {
-     send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
-     return;
-   }
-   else if(!canEditZone(zone, ch)) {
-     send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
-     return;
-   }
- 
-   // find the obj
-   tgt = worldGetObj(gameworld, vnum);
- 
-   // make our obj
-   if(tgt == NULL) {
-     obj = newObj(vnum);
-     objSetVnum(obj, vnum);
-     objSetName      (obj, "an unfinished object");
-     objSetKeywords  (obj, "object, unfinshed");
-     objSetRdesc     (obj, "an unfinished object is lying here.");
-     objSetDesc      (obj, "it looks unfinished.\r\n");
-     objSetMultiName (obj, "a group of %d unfinished objects");
-     objSetMultiRdesc(obj, "%d objects lay here, all unfinished.");
-   }
-   else
-     obj = objCopy(tgt);
-   OLC_DATA *olc = newOLC(OLC_OEDIT, OEDIT_MAIN, (void *)obj, NULL);
-   socketSetOLC(charGetSocket(ch), olc);
-   socketSetState(charGetSocket(ch), STATE_OLC);
-   olc_menu(charGetSocket(ch));
- }
- 
- 
- COMMAND(cmd_zedit) {
-   /*
-   if(!arg || !*arg) {
-     send_to_char(ch, "Edit we must, but edit what?\r\n");
-     return;
-   }
-   */
-   // we want to create a new zone?
-   if(!strncasecmp(arg, "new ", 4)) {
-     char new[20];
-     zone_vnum vnum = 0;
-     room_vnum min = 0, max = 0;
- 
-     // scan for the parameters
-     sscanf(arg, "%s %d %d %d", new, &vnum, &min, &max);
- 
-     if(worldGetZone(gameworld, vnum))
-       send_to_char(ch, "A zone already exists with that vnum.\r\n");
-     else if(worldZoneBounding(gameworld, min) || worldZoneBounding(gameworld, max))
-       send_to_char(ch, "There is already a zone bounding that vnum range.\r\n");
-     else {
-       ZONE_DATA *zone = newZone(vnum, min, max);
-       char buf[MAX_BUFFER];
-       sprintf(buf, "%s's zone", charGetName(ch));
-       zoneSetName(zone, buf);
-       sprintf(buf, "A new zone created by %s\r\n", charGetName(ch));
-       zoneSetDescription(zone, buf);
-       zoneSetEditors(zone, charGetName(ch));
- 
-       worldPutZone(gameworld, zone);
-       send_to_char(ch, "You create a new zone (vnum %d).\r\n", vnum);
- 
-       // save the changes... this will get costly as our world gets bigger.
-       // But that should be alright once we make zone saving a bit smarter
-       worldSave(gameworld, WORLD_PATH);
-     }
-   }
- 
-   // we want to edit a preexisting zone
-   else {
-     ZONE_DATA *zone = NULL;
-     zone_vnum vnum   = (!*arg ? 
- 			zoneGetVnum(worldZoneBounding(gameworld, roomGetVnum(charGetRoom(ch)))) : atoi(arg));
-  
-     // make sure there is a corresponding zone ...
-     if((zone = worldGetZone(gameworld, vnum)) == NULL) {
-       send_to_char(ch, 
- 		   "No such zone exists. To create a new one, use "
- 		   "zedit new <vnum> <min> <max>\r\n");
-       return;
-     }
-     else if(!canEditZone(zone, ch)) {
-       send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
-       return;
-     }
- 
-     OLC_DATA *olc = newOLC(OLC_ZEDIT, ZEDIT_MAIN, (void *)zoneCopy(zone), NULL);
-     socketSetOLC(charGetSocket(ch), olc);
-     socketSetState(charGetSocket(ch), STATE_OLC);
-     olc_menu(charGetSocket(ch));
-   }
- }
- 
- 
- COMMAND(cmd_dedit) {
-   ZONE_DATA *zone;
-   DIALOG_DATA *dialog;
-   DIALOG_DATA *tgt;
-   dialog_vnum vnum;
- 
-   // if no argument is supplied, default to the current dialog
-   if(!arg || !*arg) {
-     send_to_char(ch, "Please supply the vnum of a dialog you wish to edit.\r\n");
-     return;
-   }
-   else
-     vnum = atoi(arg);
- 
- 
-   // make sure there is a corresponding zone ...
-   if((zone = worldZoneBounding(gameworld, vnum)) == NULL) {
-     send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
-     return;
-   }
-   else if(!canEditZone(zone, ch)) {
-     send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
-     return;
-   }
- 
-   // find the dialog
-   tgt = worldGetDialog(gameworld, vnum);
- 
-   // make our dialog
-   if(tgt == NULL) {
-     dialog = newDialog();
-     dialogSetVnum(dialog, vnum);
-   }
-   else
-     dialog = dialogCopy(tgt);
-   OLC_DATA *olc = newOLC(OLC_DEDIT, DEDIT_MAIN, (void *)dialog, NULL);
-   socketSetOLC(charGetSocket(ch), olc);
-   socketSetState(charGetSocket(ch), STATE_OLC);
-   olc_menu(charGetSocket(ch));
- }
- 
- 
- COMMAND(cmd_wedit) {
-   send_to_char(ch, "Wedit has not been completed yet.\r\n");
- }
- 
- 
- #ifdef MODULE_SCRIPTS
- COMMAND(cmd_scedit) {
-   ZONE_DATA *zone;
-   SCRIPT_DATA *script;
-   SCRIPT_DATA *tgt;
-   script_vnum vnum;
- 
-   // if no argument is supplied, default to the current script
-   if(!arg || !*arg) {
-     send_to_char(ch, "Please supply the vnum of a script you wish to edit.\r\n");
-     return;
-   }
-   else
-     vnum = atoi(arg);
- 
- 
-   // make sure there is a corresponding zone ...
-   if((zone = worldZoneBounding(gameworld, vnum)) == NULL) {
-     send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
-     return;
-   }
-   else if(!canEditZone(zone, ch)) {
-     send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
-     return;
-   }
- 
-   // find the script
-   tgt = worldGetScript(gameworld, vnum);
- 
-   // make our script
-   if(tgt == NULL) {
-     script = newScript();
-     scriptSetVnum(script, vnum);
-     scriptSetName(script, "An Unfinished Script");
-     scriptSetCode(script, "# script code goes here\n"
- 		          "# make sure to comment it with pounds (#)\n");
- 
-   }
-   else
-     script = scriptCopy(tgt);
-   OLC_DATA *olc = newOLC(OLC_SCEDIT, SCEDIT_MAIN, (void *)script, NULL);
-   socketSetOLC(charGetSocket(ch), olc);
-   socketSetState(charGetSocket(ch), STATE_OLC);
-   olc_menu(charGetSocket(ch));
- }
- #endif
- 
- 
- #ifdef MODULE_SOCIALS
- COMMAND(cmd_socedit) {
-   SOCIAL_DATA *social;
-   SOCIAL_DATA *tgt;
- 
-   if(!arg || !*arg) {
-     send_to_char(ch, "Which social are you trying to edit?\r\n");
-     return;
-   }
- 
-   // find the social
-   tgt = get_social(arg);
- 
-   // make a new one
-   if(tgt == NULL)
-     social = newSocial(arg, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- 		       POS_STANDING, POS_STANDING);
-   else
-     social = socialCopy(tgt);
- 
-   // set up the olc
-   OLC_DATA *olc = newOLC(OLC_SOCEDIT, SOCEDIT_MAIN, social, arg);
-   socketSetOLC(charGetSocket(ch), olc);
-   socketSetState(charGetSocket(ch), STATE_OLC);
-   olc_menu(charGetSocket(ch));
- }
- #endif
--- 0 ----
diff -crN nakedmudv1.5/src/olc/olc.h nakedmudv2.0/src/olc/olc.h
*** nakedmudv1.5/src/olc/olc.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/olc.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,213 ****
- #ifndef __OLC_H
- #define __OLC_H
- //*****************************************************************************
- //
- // olc.h
- //
- // Contains all of the functions neccessary for online editing.
- //
- //*****************************************************************************
- 
- #define OLC_AUTOSAVE                (TRUE)
- 
- COMMAND(cmd_oedit);  // object editing
- COMMAND(cmd_medit);  // mobile editing
- COMMAND(cmd_redit);  // room editing
- COMMAND(cmd_zedit);  // zone editing
- COMMAND(cmd_wedit);  // world editing
- COMMAND(cmd_dedit);  // dialog editing
- #ifdef MODULE_SCRIPTS
- COMMAND(cmd_scedit); // script editing
- #endif
- #ifdef MODULE_SOCIALS
- COMMAND(cmd_socedit); // social editing
- #endif
- 
- // initialize OLC. Must be called when the MUD starts up
- void init_olc();
- 
- // enter the olc loop with the specified argument and olc data
- void olc_loop(SOCKET_DATA *sock, char *arg);
- void olc_menu(SOCKET_DATA *sock);
- 
- 
- //
- // writes the reset info to a buffer and returns it. 
- // This is used by redit and resedit. If indent_first is false, the first
- // line is not indented. This can be useful for displaying menus.
- //
- const char *write_reset(RESET_DATA *reset, int indent, bool indent_first);
- 
- 
- //*****************************************************************************
- //
- // olc datastructure
- //
- // contains all of the information about what a socket is currently editing
- //
- //*****************************************************************************
- #define OLC_MAIN                 0 // general OLC menu
- #define OLC_REDIT                1 // room edit
- #define OLC_ZEDIT                2 // zone edit
- #define OLC_WEDIT                3 // world edit
- #define OLC_EXEDIT               4 // exit edit
- #define OLC_EDSEDIT              5 // edesc set edit
- #define OLC_EDEDIT               6 // edesc edit
- #define OLC_MEDIT                7 // mobile editing
- #define OLC_OEDIT                8 // object editing
- #define OLC_SCEDIT               9 // script editing
- #define OLC_SSEDIT              10 // script set editing
- #define OLC_DEDIT               11 // dialog editing
- #define OLC_RESPEDIT            12 // dialog response editing
- #define OLC_RESEDIT             13 // room reset editing
- #define OLC_SOCEDIT             14 // social editing
- 
- #define ZEDIT_MAIN               0
- #define ZEDIT_CONFIRM_SAVE       1
- #define ZEDIT_NAME               2
- #define ZEDIT_EDITORS            3
- #define ZEDIT_MIN                4
- #define ZEDIT_MAX                5
- #define ZEDIT_RESET              6
- 
- #define SSEDIT_MAIN              0
- #define SSEDIT_CONFIRM_SAVE      1
- #define SSEDIT_ADD               2
- #define SSEDIT_REMOVE            4
- 
- #define SCEDIT_MAIN              0
- #define SCEDIT_CONFIRM_SAVE      1
- #define SCEDIT_NAME              2
- #define SCEDIT_TYPE              3
- #define SCEDIT_ARGS              4
- #define SCEDIT_NARG              5
- 
- #define OEDIT_MAIN               0
- #define OEDIT_CONFIRM_SAVE       1
- #define OEDIT_NAME               2
- #define OEDIT_KEYWORDS           3
- #define OEDIT_RDESC              4
- #define OEDIT_EDESCS             5
- #define OEDIT_TYPE               6
- #define OEDIT_SUBTYPE            7
- #define OEDIT_SCRIPTS            8
- #define OEDIT_BITS               9
- #define OEDIT_MULTI_NAME        10
- #define OEDIT_MULTI_RDESC       11
- #define OEDIT_WEIGHT            12
- #define OEDIT_CAPACITY          13
- 
- #define OEDIT_VAL_0             20
- #define OEDIT_VAL_1             21
- #define OEDIT_VAL_2             22
- #define OEDIT_VAL_3             23
- 
- #define MEDIT_MAIN               0
- #define MEDIT_CONFIRM_SAVE       1
- #define MEDIT_NAME               2
- #define MEDIT_KEYWORDS           3
- #define MEDIT_RDESC              4
- #define MEDIT_SEX                5
- #define MEDIT_DIALOG             6
- #define MEDIT_RACE               7
- #define MEDIT_SCRIPTS            8
- #define MEDIT_MULTI_NAME         9
- #define MEDIT_MULTI_RDESC       10
- 
- #define REDIT_MAIN               0
- #define REDIT_CONFIRM_SAVE       1
- #define REDIT_NAME               2
- #define REDIT_CHOOSE_EXIT        3
- #define REDIT_EXIT               4
- #define REDIT_TERRAIN            5
- #define REDIT_EDESCS             6
- #define REDIT_SCRIPTS            7
- #define REDIT_RESET              8
- #define REDIT_DELETE_RESET       9
- #define REDIT_EDIT_RESET        10
- 
- #define RESEDIT_MAIN             0
- #define RESEDIT_CONFIRM_SAVE     1
- #define RESEDIT_TYPE             2
- #define RESEDIT_TIMES            3
- #define RESEDIT_CHANCE           4
- #define RESEDIT_MAX              5
- #define RESEDIT_ROOM_MAX         6
- #define RESEDIT_ARG              7
- #define RESEDIT_IN               8
- #define RESEDIT_ON               9
- #define RESEDIT_THEN            10
- #define RESEDIT_EDIT_IN         11
- #define RESEDIT_EDIT_ON         12
- #define RESEDIT_EDIT_THEN       13
- #define RESEDIT_DELETE_IN       14
- #define RESEDIT_DELETE_ON       15
- #define RESEDIT_DELETE_THEN     16
- 
- #define EDSEDIT_MAIN             0
- #define EDSEDIT_CONFIRM_SAVE     1
- #define EDSEDIT_ENTRY            2
- #define EDSEDIT_DELETE           3
- 
- #define EDEDIT_MAIN              0
- #define EDEDIT_CONFIRM_SAVE      1
- #define EDEDIT_KEYWORDS          2
- 
- #define DEDIT_MAIN               0
- #define DEDIT_CONFIRM_SAVE       1
- #define DEDIT_NAME               2
- #define DEDIT_GREET              3
- #define DEDIT_ENTRY              4
- #define DEDIT_DELETE             5
- 
- #define RESPEDIT_MAIN            0
- #define RESPEDIT_CONFIRM_SAVE    1
- #define RESPEDIT_KEYWORDS        2
- #define RESPEDIT_MESSAGE         3
- 
- #define EXEDIT_MAIN              0
- #define EXEDIT_CONFIRM_SAVE      1
- #define EXEDIT_TO                2
- #define EXEDIT_SPOT_DIFF         3
- #define EXEDIT_PICK_DIFF         4
- #define EXEDIT_KEY               5
- #define EXEDIT_CLOSABLE          6
- #define EXEDIT_LEAVE             7
- #define EXEDIT_ENTER             8
- #define EXEDIT_CONFIRM_DELETE    9
- #define EXEDIT_NAME             10
- #define EXEDIT_KEYWORDS         11
- 
- #define SOCEDIT_MAIN             0
- #define SOCEDIT_CONFIRM_SAVE     1
- #define SOCEDIT_CHAR_NOTGT       2
- #define SOCEDIT_ROOM_NOTGT       3
- #define SOCEDIT_CHAR_SELF        4
- #define SOCEDIT_ROOM_SELF        5
- #define SOCEDIT_CHAR_TGT         6
- #define SOCEDIT_VICT_TGT         7
- #define SOCEDIT_ROOM_TGT         8
- #define SOCEDIT_MIN_POS          9
- #define SOCEDIT_MAX_POS         10
- 
- 
- OLC_DATA   *newOLC        (int state, int substate, void *data,const char *arg);
- void        deleteOLC     (OLC_DATA *olc);
- 
- bool        isOLCComplete (OLC_DATA *olc);
- bool        olcGetSave    (OLC_DATA *olc);
- int         olcGetState   (OLC_DATA *olc);
- int         olcGetSubstate(OLC_DATA *olc);
- void       *olcGetData    (OLC_DATA *olc);
- const char *olcGetArgument(OLC_DATA *olc);
- OLC_DATA   *olcGetNext    (OLC_DATA *olc);
- 
- void        olcSetSave    (OLC_DATA *olc, bool save);
- void        olcSetData    (OLC_DATA *olc, void  *data);
- void        olcSetArgument(OLC_DATA *olc, char *arg);
- void        olcSetState   (OLC_DATA *olc, int state);
- void        olcSetSubstate(OLC_DATA *olc, int substate);
- void        olcSetNext    (OLC_DATA *olc, OLC_DATA *next);
- void        olcSetComplete(OLC_DATA *olc, bool complete);
- 
- #endif // __OLC_H
--- 0 ----
diff -crN nakedmudv1.5/src/olc/redit.c nakedmudv2.0/src/olc/redit.c
*** nakedmudv1.5/src/olc/redit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/redit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,459 ****
- //*****************************************************************************
- //
- // redit.c
- //
- // Contains all of the functions needed for online editing of rooms.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../world.h"
- #include "../room.h"
- #include "../exit.h"
- #include "../room_reset.h"
- #include "../extra_descs.h"
- #include "../socket.h"
- #include "../utils.h"
- 
- #include "olc.h"
- 
- #ifdef MODULE_SCRIPTS
- #include "../scripts/script_set.h"
- #include "../scripts/script.h"
- #endif
- #ifdef MODULE_TIME
- #include "../time/mudtime.h"
- #endif
- 
- // if we're in the reset menu and we want to make
- // a new entry, this needs to be used, instead of
- // the position in the list the entry is
- #define EDITING_NEW_RESET  "new_reset"
- 
- 
- //
- // Display a list of available terrains
- //
- void redit_terrain_menu(SOCKET_DATA *sock) {
-   int i;
- 
-   for(i = 0; i < NUM_TERRAINS; i++)
-     send_to_socket(sock, "  {c%2d{y) {g%-15s%s",
- 		   i, terrainGetName(i), (i % 3 == 2 ? "\r\n" : "    "));
- 
-   if(i % 3 != 0)
-     send_to_socket(sock, "\r\n");
- }
- 
- 
- //
- // display the room reset menu to the character
- //
- void redit_reset_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   LIST *list           = roomGetResets(olcGetData(olc));
-   LIST_ITERATOR *res_i = newListIterator(list);
-   RESET_DATA    *reset = NULL;
-   int count = 0;
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{wCurrent reset commands:\r\n");
- 
-   while( (reset = listIteratorCurrent(res_i)) != NULL) {
-     listIteratorNext(res_i);
-     send_to_socket(sock, " {g%2d) %s", count, write_reset(reset, 5, FALSE));
-     count++;
-   }
-   deleteListIterator(res_i);
- 
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "  {gN) new entry\r\n"
- 		 "  D) delete entry\r\n"
- 		 "  Use number to edit specific entry\r\n"
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n"
- 		 );
- }
- 
- 
- //
- // Display the exits the socket can edit
- //
- void redit_exit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   int i;
-   ROOM_DATA *room = (ROOM_DATA *)olcGetData(olc);
- 
-   // normal exits first
-   for(i = 0; i < NUM_DIRS; i++) {
-     EXIT_DATA *exit = roomGetExit(room, i);
-     send_to_socket(sock, "   {g%-10s : {y[%s%6d{y]%s",
- 		   dirGetName(i), 
- 		   (exit ? "{c" : "{y" ),
- 		   (exit ? exitGetTo(exit) : -1),
- 		   (!(i % 2) ? "   " : "\r\n"));
-   }
- 
-   // now special exits
-   int num_spec_exits = 0;
-   const char **room_names = roomGetExitNames(room, &num_spec_exits);
-   for(i = 0; i < num_spec_exits; i++) {
-     EXIT_DATA *exit = roomGetExitSpecial(room, room_names[i]);
-     send_to_socket(sock, "   {g%-10s : {y[{c%6d{y]%s",
- 		   room_names[i],
- 		   exitGetTo(exit),
- 		   (!(i % 2) ? "   " : "\r\n"));
-   }
- 
-   // make sure we've printed the last newline if needed
-   if(i % 2 == 1)
-     send_to_socket(sock, "\r\n");
- 
-   // clean up our mess
-   free(room_names);
- }
- 
- 
- void redit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   ROOM_DATA *room = (ROOM_DATA *)olcGetData(olc);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g[{c%d{g]\r\n"
- 		 "{g1) Name\r\n"
- 		 "{c%s\r\n"
- 		 "{g2) Description\r\n"
- 		 "{c%s\r\n"
- #ifdef MODULE_TIME
- 		 "{g3) Night Description (optional)\r\n"
- 		 "{c%s\r\n"
- #endif
- 		 "{gT) Terrain type {y[{c%s{y]\r\n"
- 		 "{gX) Extra descriptions menu\r\n"
- 		 "{gR) Reset menu\r\n"
- #ifdef MODULE_SCRIPTS
- 		 "{gS) Script menu\r\n"
- #endif
- 		 "{gE) Exit menu\r\n",
- 		 roomGetVnum(room),
- 		 roomGetName(room),
- 		 roomGetDesc(room),
- #ifdef MODULE_TIME
- 		 roomGetNightDesc(room),
- #endif
- 		 terrainGetName(roomGetTerrain(room))
- 		 );
- 
-   redit_exit_menu(sock, olc);
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n"
- 		 );
- }
- 
- 
- //
- // the room reset main loop
- //
- void redit_reset_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = REDIT_RESET;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     next_substate = REDIT_MAIN;
-     break;
- 
-   case 'N':
-     olcSetNext(olc, newOLC(OLC_RESEDIT, RESEDIT_MAIN,
- 			   newReset(), strdup(EDITING_NEW_RESET)));
-     next_substate = REDIT_EDIT_RESET;
-     break;
- 
-   case 'D':
-     next_substate = REDIT_DELETE_RESET;
-     send_to_socket(sock, "Which entry would you like to delete : ");
-     break;
- 
-   default:
-     // see if maybe they're trying to choose a description to edit
-     if(!isdigit(*arg))
-       redit_reset_menu(sock, olc);
-     else {
-       int num = atoi(arg);
-       RESET_DATA *reset = listGet(roomGetResets(olcGetData(olc)), num);
-       // if the one found is null, just show the menu
-       if(reset == NULL)
- 	redit_reset_menu(sock, olc);
-       else {
- 	olcSetNext(olc, newOLC(OLC_RESEDIT, RESEDIT_MAIN, 
- 			       resetCopy(reset), strdup(arg)));
- 	next_substate = REDIT_EDIT_RESET;
- 	break;
-       }
-     }
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == REDIT_MAIN)
-     redit_menu(sock, olc);
- }
- 
- 
- 
- //
- // The main loop for editing rooms
- //
- void redit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = REDIT_MAIN;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = REDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter new name : ");
-     next_substate = REDIT_NAME;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "Enter new description\r\n");
-     start_text_editor(sock, 
- 		      roomGetDescPtr((ROOM_DATA *)olcGetData(olc)),
- 		      MAX_BUFFER, EDITOR_MODE_NORMAL);
-     next_substate = REDIT_MAIN;
-     break;
- 
-   case 'T':
-     redit_terrain_menu(sock);
-     send_to_socket(sock, "Pick a new terrain number : ");
-     next_substate = REDIT_TERRAIN;
-     break;
- 
-   case 'R':
-     redit_reset_menu(sock, olc);
-     next_substate = REDIT_RESET;
-     break;
- 
-   case 'E':
-     send_to_socket(sock, "Which exit do you want to edit : ");
-     next_substate = REDIT_CHOOSE_EXIT;
-     break;
- 
-   case 'X':
-     olcSetNext(olc, newOLC(OLC_EDSEDIT, EDSEDIT_MAIN, 
- 			   copyEdescSet(roomGetEdescs((ROOM_DATA *)olcGetData(olc))), NULL));
-     next_substate = REDIT_EDESCS;
-     break;
- 
- #ifdef MODULE_SCRIPTS
-   case 's':
-   case 'S':
-     olcSetNext(olc, newOLC(OLC_SSEDIT, SSEDIT_MAIN,
- 			   copyScriptSet(roomGetScripts((ROOM_DATA *)olcGetData(olc))), roomGetName((ROOM_DATA *)olcGetData(olc))));
-     next_substate = REDIT_SCRIPTS;
-     break;
- #endif
- 
- #ifdef MODULE_TIME
-   case '3':
-     send_to_socket(sock, "Enter new description\r\n");
-     start_text_editor(sock, 
- 		      roomGetNightDescPtr((ROOM_DATA *)olcGetData(olc)),
- 		      MAX_BUFFER, EDITOR_MODE_NORMAL);
-     next_substate = REDIT_MAIN;
-     break;
- #endif
- 
-   default:
-     redit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- 
- //
- // The entry loop for redit. Figures out what substate we're
- // in, and then enters into the appropriate subloop if possible,
- // or sets a value based on arg if there is no subloop
- //
- void redit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   ROOM_DATA *room = (ROOM_DATA *)olcGetData(olc);
-   int next_substate = REDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case REDIT_MAIN:
-     redit_main_loop(sock, olc, arg);
-     return;
- 
-   case REDIT_RESET:
-     redit_reset_loop(sock, olc, arg);
-     return;
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case REDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = REDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case REDIT_NAME:
-     roomSetName(room, arg);
-     break;
-   case REDIT_TERRAIN:
-     roomSetTerrain(room, 
- 		   MIN(NUM_TERRAINS - 1,
- 		       MAX(TERRAIN_NONE + 1, atoi(arg))));
-     break;
- 
-   case REDIT_EDESCS:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       EDESC_SET *edescs = (EDESC_SET *)olcGetData(olcGetNext(olc));
-       roomSetEdescs(room, (edescs ? copyEdescSet(edescs) : newEdescSet()));
-     }
- 
-     olcSetNext(olc, NULL);
-     next_substate = REDIT_MAIN;
-     break;
- 
- #ifdef MODULE_SCRIPTS
-   case REDIT_SCRIPTS:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       SCRIPT_SET *scripts = (SCRIPT_SET *)olcGetData(olcGetNext(olc));
-       roomSetScripts(room, (scripts ? copyScriptSet(scripts) : newScriptSet()));
-     }
-     olcSetNext(olc, NULL);
-     next_substate = REDIT_MAIN;
-     break;
- #endif
- 
- 
-     /******************************************************/
-     /*                    RESET EDITOR                    */
-     /******************************************************/
-   case REDIT_DELETE_RESET: {
-     RESET_DATA *reset = (isdigit(*arg)? listGet(roomGetResets(room),atoi(arg)) :
- 			 NULL);
-     if(reset != NULL) {
-       listRemove(roomGetResets(room), reset);
-       deleteReset(reset);
-     }
-     next_substate = REDIT_RESET;
-     break;
-   }
- 
-   case REDIT_EDIT_RESET: {
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       RESET_DATA *reset = olcGetData(olcGetNext(olc));
-       if(!strcmp(EDITING_NEW_RESET, olcGetArgument(olcGetNext(olc))))
- 	listQueue(roomGetResets(room), resetCopy(reset));
-       else {
- 	int num = atoi(olcGetArgument(olcGetNext(olc)));
- 	resetCopyTo(reset, listGet(roomGetResets(room), num));
-       }
-     }
-     next_substate = REDIT_RESET;
-     break;
-   }
- 
- 
-     /******************************************************/
-     /*                     EXIT EDITOR                    */
-     /******************************************************/
-   case REDIT_EXIT: {
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       EXIT_DATA *exit = (EXIT_DATA *)olcGetData(olcGetNext(olc));
-       const char *dirName = olcGetArgument(olcGetNext(olc));
-       int dir = dirGetNum(dirName);
-       // special exit
-       if(dir == DIR_NONE)
- 	roomSetExitSpecial(room, dirName, (exit ? exitCopy(exit) : NULL));
-       // normal dir
-       else
- 	roomSetExit(room, dir, (exit ? exitCopy(exit) : NULL));
-     }
- 
-     olcSetNext(olc, NULL);
-     next_substate = REDIT_MAIN;
-     break;
-   }
- 
-   case REDIT_CHOOSE_EXIT: {
-     EXIT_DATA *exit = NULL;
-     int dir = dirGetNum(arg);
-     char *dirName = NULL;
- 
-     if(dir == DIR_NONE)
-       dir = dirGetAbbrevNum(arg);
- 
-     // find the exit we're editing
-     if(dir != DIR_NONE) {
-       if(roomGetExit((ROOM_DATA *)olcGetData(olc), dir))
- 	exit = exitCopy(roomGetExit((ROOM_DATA *)olcGetData(olc), dir));
-       dirName = strdup(dirGetName(dir));
-     }
-     else if(roomGetExitSpecial((ROOM_DATA *)olcGetData(olc), arg)) {
-       if(roomGetExitSpecial((ROOM_DATA *)olcGetData(olc), arg))
- 	exit = exitCopy(roomGetExitSpecial((ROOM_DATA *)olcGetData(olc), arg));
-       dirName = strdup(arg);
-     }
-     else
-       dirName = strdup(arg);
- 
-     // if the exit didn't exist already, create it
-     if(exit == NULL)
-       exit = newExit();
- 
-     olcSetNext(olc, newOLC(OLC_EXEDIT, EXEDIT_MAIN, exit, dirName));
-     next_substate = REDIT_EXIT;
-     free(dirName);
-     break;
-   }
- 
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing redit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == REDIT_MAIN)
-     redit_menu(sock, olc);
-   else if(next_substate == REDIT_RESET)
-     redit_reset_menu(sock, olc);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc/resedit.c nakedmudv2.0/src/olc/resedit.c
*** nakedmudv1.5/src/olc/resedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/resedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,504 ****
- //*****************************************************************************
- //
- // resedit.c
- //
- // the functions needed for editing room reset data in OLC
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../socket.h"
- #include "../utils.h"
- #include "../world.h"
- #include "../object.h"
- #include "../character.h"
- #include "../room_reset.h"
- 
- #include "olc.h"
- 
- // if we are editing a new on/in/then, as opposed 
- // to editing one that we already have
- #define EDITING_NEW_RESET      "new_reset"
- 
- 
- const char *write_reset_arg(int type, const char *arg) {
-   static char buf[SMALL_BUFFER];
-   OBJ_DATA *obj  = worldGetObj(gameworld, atoi(arg));
-   CHAR_DATA *mob = worldGetMob(gameworld, atoi(arg));
-   int pos        = atoi(arg);
-   switch(type) { 
-   case RESET_LOAD_OBJECT:
-     sprintf(buf, "load %s", (obj ? objGetName(obj) : "{RNOTHING{c"));
-     break;
-   case RESET_LOAD_MOBILE:
-     sprintf(buf, "load %s", (mob ? charGetName(mob) : "{RNOBODY{c"));
-     break;
-   case RESET_POSITION:
-     sprintf(buf, "change position to %s", 
- 	    (pos < 0 || pos >= NUM_POSITIONS ? "{RNOTHING{c":posGetName(pos)));
-     break;
-   case RESET_FIND_MOBILE:
-     sprintf(buf, "find %s", (mob ? charGetName(mob) : "{RNOBODY{c"));
-     break;
-   case RESET_FIND_OBJECT:
-     sprintf(buf, "find %s", (obj ? objGetName(obj) : "{RNOTHING{c"));
-     break;
-   case RESET_PURGE_MOBILE:
-     sprintf(buf, "purge %s", (mob ? charGetName(mob) : "{RNOBODY{c"));
-     break;
-   case RESET_PURGE_OBJECT:
-     sprintf(buf, "purge %s", (obj ? objGetName(obj) : "{RNOTHING{c"));
-     break;
-   case RESET_OPEN:
-     sprintf(buf, "open/unlock dir %s or container", arg);
-     break;
-   case RESET_CLOSE:
-     sprintf(buf, "close/unlock dir %s or container", arg);
-     break;
-   case RESET_LOCK:
-     sprintf(buf, "close/lock dir %s or container", arg);
-     break;
-   default:
-     sprintf(buf, "UNFINISHED OLC");
-     break;
-   }
-   return buf;
- }
- 
- 
- int indent_line(char *buf, int buflen, int indent) {
-   if(indent > 0) {
-     char fmt[20];
-     sprintf(fmt, "%%-%ds", indent);
-     return snprintf(buf, buflen, fmt, " ");
-   }
-   return 0;
- }
- 
- 
- int write_reset_buf(RESET_DATA *reset, char *buf, int buflen, int indent,
- 		    bool indent_first) {
-   int i = 0;
- 
-   if(indent_first)
-     i += indent_line(buf, buflen, indent);
-   i += snprintf(buf+i, buflen-i,
- 		"{c%s with {w%d%% {cchance {w%d {ctime%s (max {w%d{c, rm. {w%d{c)\r\n",
- 		write_reset_arg(resetGetType(reset), resetGetArg(reset)),
- 		resetGetChance(reset),
- 		resetGetTimes(reset),
- 		(resetGetTimes(reset) == 1 ? "" : "s"),
- 		resetGetMax(reset),
- 		resetGetRoomMax(reset));
- 
-   // if we've got ONs, then print 'em all out as well
-   if(listSize(resetGetOn(reset)) > 0) {
-     i += indent_line(buf+i, buflen-i, indent);
-     i += snprintf(buf+i, buflen-i, "{yon it: \r\n");
-     LIST_ITERATOR *list_i = newListIterator(resetGetOn(reset));
-     RESET_DATA     *next  = NULL;
-     ITERATE_LIST(next, list_i)
-       i += write_reset_buf(next, buf+i, buflen-i, indent+2, TRUE);
-     deleteListIterator(list_i);
-   }
- 
-   // if we've got INs, then print 'em all out as well
-   if(listSize(resetGetIn(reset)) > 0) {
-     i += indent_line(buf+i, buflen-i, indent);
-     i += snprintf(buf+i, buflen-i, "{yin it: \r\n");
-     LIST_ITERATOR *list_i = newListIterator(resetGetIn(reset));
-     RESET_DATA     *next  = NULL;
-     ITERATE_LIST(next, list_i)
-       i += write_reset_buf(next, buf+i, buflen-i, indent+2, TRUE);
-     deleteListIterator(list_i);
-   }
- 
-   // if we've got THENs, print 'em all out as well
-   if(listSize(resetGetThen(reset)) > 0) {
-     i += indent_line(buf+i, buflen-i, indent);
-     i += snprintf(buf+i, buflen-i, "{ywhen successful, also: \r\n");
-     LIST_ITERATOR *list_i = newListIterator(resetGetThen(reset));
-     RESET_DATA     *next  = NULL;
-     ITERATE_LIST(next, list_i)
-       i += write_reset_buf(next, buf+i, buflen-i, indent+2, TRUE);
-     deleteListIterator(list_i);
-   }
-   return i;
- }
- 
- 
- const char *write_reset(RESET_DATA *reset, int indent, bool indent_first) {
-   static char buf[MAX_BUFFER];
-   write_reset_buf(reset, buf, MAX_BUFFER, indent, indent_first);
-   return buf;
- }
- 
- 
- //
- // returns the list of resets we're trying to edit, based on the substate
- //
- LIST *resedit_next_list(OLC_DATA *olc, int substate) {
-   if(substate == RESEDIT_IN)
-     return resetGetIn(olcGetData(olc));
-   if(substate == RESEDIT_ON)
-     return resetGetOn(olcGetData(olc));
-   if(substate == RESEDIT_THEN)
-     return resetGetThen(olcGetData(olc));
-   // should never get this far
-   return NULL;
- }
- 
- 
- //
- // What is the state that we got here from?
- //
- int resedit_prev_state(int substate) {
-   if(substate == RESEDIT_DELETE_IN || substate == RESEDIT_EDIT_IN)
-     return RESEDIT_IN;
-   if(substate == RESEDIT_DELETE_ON || substate == RESEDIT_EDIT_ON)
-     return RESEDIT_ON;
-   if(substate == RESEDIT_DELETE_THEN || substate == RESEDIT_EDIT_THEN)
-     return RESEDIT_THEN;
-   // should never get this far
-   return RESEDIT_MAIN;
- }
- 
- 
- //
- // returns the next editing state, after our current substate
- //
- int resedit_next_edit_substate(int substate) {
-   if(substate == RESEDIT_IN)
-     return RESEDIT_EDIT_IN;
-   if(substate == RESEDIT_ON)
-     return RESEDIT_EDIT_ON;
-   if(substate == RESEDIT_THEN)
-     return RESEDIT_EDIT_THEN;
-   // we shouldn't get this far
-   return RESEDIT_MAIN;
- }
- 
- 
- //
- // returns the proper delete substate
- //
- int resedit_next_delete_substate(int substate) {
-   if(substate == RESEDIT_IN)
-     return RESEDIT_DELETE_IN;
-   if(substate == RESEDIT_ON)
-     return RESEDIT_DELETE_ON;
-   if(substate == RESEDIT_THEN)
-     return RESEDIT_DELETE_THEN;
-   // we shouldn't get this far
-   return RESEDIT_MAIN;
- }
- 
- 
- void resedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   RESET_DATA *reset = olcGetData(olc);
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g1) Type:       {c%s\r\n"
- 		 "{g2) Times:      {c%d\r\n"
- 		 "{g3) Chance:     {c%d\r\n"
- 		 "{g4) Max:        {c%d\r\n"
- 		 "{g5) Room Max:   {c%d\r\n"
- 		 "{g6) Argument:   {c%s\r\n"
- 		 "{g7) Load on menu\r\n"
- 		 "{g8) Load in menu\r\n"
- 		 "{g9) Success menu\r\n"
- 		 "---------------------------------------------------------\r\n"
- 		 "%s",
- 		 resetTypeGetName(resetGetType(reset)),
- 		 resetGetTimes(reset),
- 		 resetGetChance(reset),
- 		 resetGetMax(reset),
- 		 resetGetRoomMax(reset),
- 		 resetGetArg(reset),
- 		 write_reset(reset, 0, FALSE)
- 		 );
- 
-   send_to_socket(sock, "\r\n{gEnter choice (Q to quit) : {n");
- }
- 
- 
- //
- // display one of the child reset lists
- //
- void resedit_next_menu(SOCKET_DATA *sock, OLC_DATA *olc, int substate) {
-   LIST *list           = resedit_next_list(olc, substate);
-   LIST_ITERATOR *res_i = newListIterator(list);
-   RESET_DATA    *reset = NULL;
-   int count = 0;
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{wCurrent reset commands:\r\n");
- 
-   ITERATE_LIST(reset, res_i) {
-     send_to_socket(sock, " {g%2d) %s", count, write_reset(reset, 5, FALSE));
-     count++;
-   }
-   deleteListIterator(res_i);
- 
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "  {gN) new entry\r\n"
- 		 "  D) delete entry\r\n"
- 		 "  Use number to edit specific entry\r\n"
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n"
- 		 );
- }
- 
- 
- 
- void show_reset_type_menu(SOCKET_DATA *sock) {
-   int i;
-   for(i = 0; i < NUM_RESETS; i++)
-     send_to_socket(sock, "  %2d) %s\r\n", i, resetTypeGetName(i));
-   send_to_socket(sock, "\r\nEnter choice : ");
- }
- 
- 
- //
- // parse a command for editing one of our lists of reset commands
- //
- void resedit_next_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg, int substate) {
-   int next_substate = substate;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     next_substate = RESEDIT_MAIN;
-     break;
- 
-   case 'N':
-     olcSetNext(olc, newOLC(OLC_RESEDIT, RESEDIT_MAIN,
- 			   newReset(), strdup(EDITING_NEW_RESET)));
-     next_substate = resedit_next_edit_substate(substate);
-     break;
- 
-   case 'D':
-     next_substate = resedit_next_delete_substate(substate);
-     send_to_socket(sock, "Which entry would you like to delete : ");
-     break;
- 
-   default:
-     // see if maybe they're trying to choose a description to edit
-     if(!isdigit(*arg))
-       resedit_next_menu(sock, olc, substate);
-     else {
-       int num = atoi(arg);
-       LIST *list = resedit_next_list(olc, substate);
-       RESET_DATA *reset = listGet(list, num);
-       // if the one found is null, just show the menu
-       if(reset == NULL)
- 	resedit_next_menu(sock, olc, substate);
-       else {
- 	olcSetNext(olc, newOLC(OLC_RESEDIT, RESEDIT_MAIN, 
- 			       resetCopy(reset), strdup(arg)));
- 	next_substate = resedit_next_edit_substate(substate);
- 	break;
-       }
-     }
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == RESEDIT_MAIN)
-     resedit_menu(sock, olc);
- }
- 
- 
- 
- void resedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = RESEDIT_MAIN;
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = RESEDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     show_reset_type_menu(sock);
-     next_substate = RESEDIT_TYPE;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "How many times should it run (1 - 10) : ");
-     next_substate = RESEDIT_TIMES;
-     break;
- 
-   case '3':
-     send_to_socket(sock, "What is its chance to happen (0 - 100) : ");
-     next_substate = RESEDIT_CHANCE;
-     break;
- 
-   case '4':
-     send_to_socket(sock, "What is the max that can exist in game (0 = no limit) : ");
-     next_substate = RESEDIT_MAX;
-     break;
- 
-   case '5':
-     send_to_socket(sock, "What is the max that can exist in room (0 = no limit) : ");
-     next_substate = RESEDIT_ROOM_MAX;
-     break;
- 
-   case '6':
-     send_to_socket(sock, "What is your argument : ");
-     next_substate = RESEDIT_ARG;
-     break;
- 
-   case '7':
-     next_substate = RESEDIT_ON;
-     resedit_next_menu(sock, olc, next_substate);
-     break;
- 
-   case '8':
-     next_substate = RESEDIT_IN;
-     resedit_next_menu(sock, olc, next_substate);
-     break;
- 
-   case '9':
-     next_substate = RESEDIT_THEN;
-     resedit_next_menu(sock, olc, next_substate);
-     break;
- 
-   default:
-     resedit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- void resedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = RESEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case RESEDIT_MAIN:
-     resedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*               SUBSTATE LOOPS MENU                  */
-     /******************************************************/
-   case RESEDIT_ON:
-   case RESEDIT_IN:
-   case RESEDIT_THEN:
-     resedit_next_loop(sock, olc, arg, olcGetSubstate(olc));
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case RESEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = RESEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case RESEDIT_TYPE:
-     resetSetType(olcGetData(olc), MAX(0, MIN(NUM_RESETS, atoi(arg))));
-     // reset all of the data to defaults
-     resetSetArg(olcGetData(olc), "");
-     resetSetChance(olcGetData(olc), 100);
-     resetSetMax(olcGetData(olc), 0);
-     resetSetRoomMax(olcGetData(olc), 0);
-     resetSetTimes(olcGetData(olc), 1);
-     break;
- 
-   case RESEDIT_TIMES:
-     resetSetTimes(olcGetData(olc), MAX(1, MIN(10, atoi(arg))));
-     break;
- 
-   case RESEDIT_CHANCE:
-     resetSetChance(olcGetData(olc), MAX(1, MIN(100, atoi(arg))));
-     break;
- 
-   case RESEDIT_MAX:
-     resetSetMax(olcGetData(olc), MAX(0, MIN(1000, atoi(arg))));
-     break;
- 
-   case RESEDIT_ROOM_MAX:
-     resetSetRoomMax(olcGetData(olc), MAX(0, MIN(1000, atoi(arg))));
-     break;
- 
-   case RESEDIT_ARG:
-     resetSetArg(olcGetData(olc), arg);
-     break;
- 
- 
-     /******************************************************/
-     /*                  EDIT CHILD LISTS                  */
-     /******************************************************/
-   case RESEDIT_EDIT_ON:
-   case RESEDIT_EDIT_IN:
-   case RESEDIT_EDIT_THEN:
-     // save the changes we made
-     if(olcGetSave(olcGetNext(olc))) {
-       LIST*list =resedit_next_list(olc,resedit_prev_state(olcGetSubstate(olc)));
-       RESET_DATA *reset = olcGetData(olcGetNext(olc));
-       if(!strcmp(EDITING_NEW_RESET, olcGetArgument(olcGetNext(olc))))
- 	listQueue(list, resetCopy(reset));
-       else {
- 	int num = atoi(olcGetArgument(olcGetNext(olc)));
- 	resetCopyTo(reset, listGet(list, num));
-       }
-     }
-     next_substate = resedit_prev_state(olcGetSubstate(olc));
-     break;
- 
-   case RESEDIT_DELETE_ON:
-   case RESEDIT_DELETE_IN:
-   case RESEDIT_DELETE_THEN: {
-     LIST *list = resedit_next_list(olc,resedit_prev_state(olcGetSubstate(olc)));
-     RESET_DATA *reset = (isdigit(*arg) ? listGet(list, atoi(arg)) : NULL);
-     if(reset != NULL) {
-       listRemove(list, reset);
-       deleteReset(reset);
-     }
-     next_substate = resedit_prev_state(olcGetSubstate(olc));
-     break;
-   }
- 
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing resedit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == RESEDIT_MAIN)
-     resedit_menu(sock, olc);
-   else if(next_substate == RESEDIT_ON || next_substate == RESEDIT_IN ||
- 	  next_substate == RESEDIT_THEN)
-     resedit_next_menu(sock, olc, next_substate);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc/scedit.c nakedmudv2.0/src/olc/scedit.c
*** nakedmudv1.5/src/olc/scedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/scedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,233 ****
- //*****************************************************************************
- //
- // scedit.c
- //
- // These are the functions used for editing scripts online
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../socket.h"
- #include "../utils.h"
- 
- #include "olc.h"
- 
- #ifdef MODULE_SCRIPTS
- #include "../scripts/script.h"
- 
- void scedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   SCRIPT_DATA *script = (SCRIPT_DATA *)olcGetData(olc);
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g[{c%d{g]\r\n"
- 		 "{g1) Name         : {c%s\r\n"
- 		 "{g2) Script type  : {c%s\r\n"
- 		 "{g3) Arguments    : {c%s\r\n"
- 		 "{g4) Num. Argument: {c%d\r\n"
- 		 "{g5) Script Code\r\n",
- 		 scriptGetVnum(script),
- 		 scriptGetName(script),
- 		 scriptTypeName(scriptGetType(script)),
- 		 (*scriptGetArgs(script) ? scriptGetArgs(script) : "<NONE>"),
- 		 scriptGetNumArg(script));
- 
-   script_display(sock, scriptGetCode(script), FALSE);
- 
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n");
- 
- }
- 
- 
- //
- // Show the different script types to the character
- //
- void show_script_type_menu(SOCKET_DATA *sock) {
-   int i;
-   for(i = 0; i < NUM_SCRIPTS; i++)
-     send_to_socket(sock, "  {c%2d{g) %s\r\n", i, scriptTypeName(i));
-   send_to_socket(sock, "\r\n");
- }
- 
- 
- void scedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = SCEDIT_MAIN;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = SCEDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter new name : ");
-     next_substate = SCEDIT_NAME;
-     break;
- 
-   case '2':
-     show_script_type_menu(sock);
-     send_to_socket(sock, "Enter new type : ");
-     next_substate = SCEDIT_TYPE;
-     break;
- 
-   case '3':
-     send_to_socket(sock, "Enter new arguments : ");
-     next_substate = SCEDIT_ARGS;
-     break;
- 
-   case '4':
-     next_substate = SCEDIT_NARG;
-     switch(scriptGetType(olcGetData(olc))) {
-       // 0 = triggers always
-       // 1 = triggers if the scriptor can see the char
-     case SCRIPT_TYPE_GIVE:
-     case SCRIPT_TYPE_ENTER:
-     case SCRIPT_TYPE_EXIT:
-       next_substate = SCEDIT_NARG;
-       send_to_socket(sock,
- 		     "If the scriptor is a mob:\r\n"
- 		     "  0 = always triggers\r\n"
- 		     "  1 = triggers if the scriptor can see the char\r\n"
- 		     "\r\n"
- 		     "Enter choice : ");
-       break;
- 
-     case SCRIPT_TYPE_COMMAND:
-       next_substate = SCEDIT_NARG;
-       send_to_socket(sock,
- 		     "Control for the actual MUD command:\r\n"
- 		     "  0 = follow through with the MUD command\r\n"
- 		     "  1 = cancel the MUD command.\r\n"
- 		     "\r\n"
- 		     "Enter choice : ");
-       break;
- 
-     default:
-       next_substate = SCEDIT_MAIN;
-       send_to_socket(sock, 
- 		     "This script type does not use numeric arguments.\r\n"
- 		     "Enter choice (Q to quit) : ");
-       break;
-     }
-     break;
- 
-   case '5':
-     send_to_socket(sock, "Editing the script code\r\n");
-     start_text_editor(sock, 
- 		      scriptGetCodePtr((SCRIPT_DATA *)olcGetData(olc)),
- 		      MAX_SCRIPT, EDITOR_MODE_SCRIPT);
-     break;
- 
-   default:
-     scedit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- 
- void scedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   SCRIPT_DATA *script = (SCRIPT_DATA *)olcGetData(olc);
-   int next_substate = SCEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case SCEDIT_MAIN:
-     scedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case SCEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = SCEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case SCEDIT_NAME:
-     scriptSetName(script, arg);
-     break;
- 
-   case SCEDIT_ARGS:
-     scriptSetArgs(script, arg);
-     break;
- 
-   case SCEDIT_NARG:
-     switch(scriptGetType(script)) {
-       // 0 = triggers always
-       // 1 = triggers if the scriptor can see the char
-     case SCRIPT_TYPE_GIVE:
-     case SCRIPT_TYPE_ENTER:
-     case SCRIPT_TYPE_EXIT:
-       scriptSetNumArg(script, MIN(1, MAX(0, atoi(arg))));
-       break;
- 
-       // 0 = follow through with normal command
-       // 1 = cancel normal command
-     case SCRIPT_TYPE_COMMAND:
-       scriptSetNumArg(script, MIN(1, MAX(0, atoi(arg))));
-       break;
- 
-     default:
-       break;
-     }
-     break;
- 
-   case SCEDIT_TYPE: {
-     int num = atoi(arg);
-     if(num < 0 || num >= NUM_SCRIPTS) {
-       show_script_type_menu(sock);
-       next_substate = SCEDIT_TYPE;
-     }
-     else {
-       scriptSetType(script, num);
-       // reset arguments
-       if(scriptGetArgs(script))
- 	scriptSetArgs(script, "");
-       scriptSetNumArg(script, 0);
-     }
-     break;
-   }
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing scedit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
- 
-   /********************************************************/
-   /*                 DISPLAY NEXT MENU HERE               */
-   /********************************************************/
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == SCEDIT_MAIN)
-     scedit_menu(sock, olc);
- }
- #endif // MODULE_SCRIPTS
--- 0 ----
diff -crN nakedmudv1.5/src/olc/socedit.c nakedmudv2.0/src/olc/socedit.c
*** nakedmudv1.5/src/olc/socedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/socedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,219 ****
- //*****************************************************************************
- //
- // socedit.c
- //
- // contains all of the menus and OLC loops for editing socials.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- 
- #ifdef MODULE_SOCIALS
- #include "../socket.h"
- #include "../utils.h"
- #include "../character.h"
- #include "../socials/socials.h"
- 
- #include "olc.h"
- 
- 
- void socedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   SOCIAL_DATA *social = olcGetData(olc);
-   send_to_socket(sock,
- 		 CLEAR_SCREEN
- 		 "{y[{c%s{y]\r\n"
- 		 "{g1) to char notgt: {c%s\r\n"
- 		 "{g2) to room notgt: {c%s\r\n"
- 		 "{g3) to char self : {c%s\r\n"
- 		 "{g4) to room self : {c%s\r\n"
- 		 "{g5) to char tgt  : {c%s\r\n"
- 		 "{g6) to vict tgt  : {c%s\r\n"
- 		 "{g7) to room tgt  : {c%s\r\n"
- 		 "{g8) minimum pos  : {c%s\r\n"
- 		 "{g9) maximum pos  : {c%s\r\n"
- 		 "\r\n"
- 		 "{gTo assocciate/unassociate commands, use soclink and socunlink\r\n"
- 		 "\r\n"
- 		 "{gEnter command (Q to quit) : ",
- 		 socialGetCmds(social),
- 		 socialGetCharNotgt(social),
- 		 socialGetRoomNotgt(social),
- 		 socialGetCharSelf(social),
- 		 socialGetRoomSelf(social),
- 		 socialGetCharTgt(social),
- 		 socialGetVictTgt(social),
- 		 socialGetRoomTgt(social),
- 		 posGetName(socialGetMinPos(social)),
- 		 posGetName(socialGetMaxPos(social))
- 		 );
- }
- 
- 
- //
- // Display the list of positions a social can be completed from
- //
- void socedit_pos_menu(SOCKET_DATA *sock) {
-   int i = 0;
-   for(i = 0; i < NUM_POSITIONS; i++)
-     send_to_socket(sock, "{g%2d) {c%s\r\n", i, posGetName(i));
-   send_to_socket(sock, 
- 		 "\r\n"
- 		 "Enter the number of the new position : ");
- }
- 
- 
- void socedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = SOCEDIT_MAIN;
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N)? ");
-     next_substate = SOCEDIT_CONFIRM_SAVE;
-     break;
-   case '1':
-     send_to_socket(sock, 
- 		   "The message to character when no target is supplied : ");
-     next_substate = SOCEDIT_CHAR_NOTGT;
-     break;
-   case '2':
-     send_to_socket(sock, 
- 		   "The message to room when no target is supplied : ");
-     next_substate = SOCEDIT_ROOM_NOTGT;
-     break;
-   case '3':
-     send_to_socket(sock, 
- 		   "The message to character when target is self : ");
-     next_substate = SOCEDIT_CHAR_SELF;
-     break;
-   case '4':
-     send_to_socket(sock, 
- 		   "The message to room when target is self : ");
-     next_substate = SOCEDIT_ROOM_SELF;
-     break;
-   case '5':
-     send_to_socket(sock, 
- 		   "The message to character when a target is found : ");
-     next_substate = SOCEDIT_CHAR_TGT;
-     break;
-   case '6':
-     send_to_socket(sock, 
- 		   "The message to target when a target is found : ");
-     next_substate = SOCEDIT_VICT_TGT;
-     break;
-   case '7':
-     send_to_socket(sock, 
- 		   "The message to room when a target is found : ");
-     next_substate = SOCEDIT_ROOM_TGT;
-     break;
-   case '8':
-     socedit_pos_menu(sock);
-     next_substate = SOCEDIT_MIN_POS;
-     break;
-   case '9':
-     socedit_pos_menu(sock);
-     next_substate = SOCEDIT_MAX_POS;
-     break;
-   default:
-     break;
-   }
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- void socedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = SOCEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case SOCEDIT_MAIN:
-     socedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case SOCEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = SOCEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case SOCEDIT_CHAR_NOTGT:
-     socialSetCharNotgt(olcGetData(olc), arg);
-     break;
-   case SOCEDIT_ROOM_NOTGT:
-     socialSetRoomNotgt(olcGetData(olc), arg);
-     break;
-   case SOCEDIT_CHAR_SELF:
-     socialSetCharSelf(olcGetData(olc), arg);
-     break;
-   case SOCEDIT_ROOM_SELF:
-     socialSetRoomSelf(olcGetData(olc), arg);
-     break;
-   case SOCEDIT_CHAR_TGT:
-     socialSetCharTgt(olcGetData(olc), arg);
-     break;
-   case SOCEDIT_VICT_TGT:
-     socialSetVictTgt(olcGetData(olc), arg);
-     break;
-   case SOCEDIT_ROOM_TGT:
-     socialSetRoomTgt(olcGetData(olc), arg);
-     break;
- 
-   case SOCEDIT_MIN_POS:
-     if(!isdigit(*arg))
-       break;
-     else {
-       int pos = atoi(arg);
-       if(pos < 0 || pos >= NUM_POSITIONS)
- 	break;
-       socialSetMinPos(olcGetData(olc), pos);
-     }
-     break;
- 
-   case SOCEDIT_MAX_POS:
-     if(!isdigit(*arg))
-       break;
-     else {
-       int pos = atoi(arg);
-       if(pos < 0 || pos >= NUM_POSITIONS)
- 	break;
-       socialSetMaxPos(olcGetData(olc), pos);
-     }
-     break;
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing socedit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   // display the menu if we need to
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == SOCEDIT_MAIN)
-     socedit_menu(sock, olc);
- }
- 
- #endif // MODULE_SOCIALS
--- 0 ----
diff -crN nakedmudv1.5/src/olc/ssedit.c nakedmudv2.0/src/olc/ssedit.c
*** nakedmudv1.5/src/olc/ssedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/ssedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,150 ****
- //*****************************************************************************
- //
- // ssedit.c
- //
- // the functions used for editing room/obj/mob script sets.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../socket.h"
- #include "../world.h"
- #include "../utils.h"
- 
- #include "olc.h"
- 
- 
- #ifdef MODULE_SCRIPTS
- #include "../scripts/script.h"
- #include "../scripts/script_set.h"
- 
- 
- void ssedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   LIST *scripts = scriptSetList((SCRIPT_SET *)olcGetData(olc), SCRIPT_TYPE_ANY);
-   SCRIPT_DATA *script = NULL;
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g[{c%s{g]\r\n\r\n", 
- 		 olcGetArgument(olc));
- 
-   // show all the scripts attached
-   while((script = listPop(scripts)) != NULL)
-     send_to_socket(sock,
- 		   "  {y[{c%4d{y]{w %-20s {c%s\r\n",
- 		   scriptGetVnum(script), 
- 		   scriptTypeName(scriptGetType(script)),
- 		   scriptGetName(script));
-   deleteList(scripts);
- 
-   send_to_socket(sock,
- 		 "\r\n"
- 		 "{cA{g) add new script\r\n"
- 		 "{cR{g) remove script\r\n"
- 		 "\r\n"
- 		 "Enter your choice (Q to quit) : ");
- }
- 
- 
- 
- void ssedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = SSEDIT_MAIN;
- 
-   switch(toupper(*arg)) {
-   case 'q':
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = SSEDIT_CONFIRM_SAVE;
-     break;
- 
-   case 'a':
-   case 'A':
-     send_to_socket(sock, "Which script would you like to add (-1 for none) : ");
-     next_substate = SSEDIT_ADD;
-     break;
- 
-   case 'r':
-   case 'R':
-     send_to_socket(sock, "Which script would you like to remove (-1 for none) : ");
-     next_substate = SSEDIT_REMOVE;
-     break;
- 
-   default:
-     ssedit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- void ssedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   SCRIPT_SET *set = (SCRIPT_SET *)olcGetData(olc);
-   int next_substate = SSEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case SSEDIT_MAIN:
-     ssedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case SSEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = SSEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case SSEDIT_ADD: {
-     // check to make sure the script exists
-     SCRIPT_DATA *script = worldGetScript(gameworld, atoi(arg));
-     if(script)
-       scriptSetAdd(set, scriptGetVnum(script)); 
-   }
-     break;
- 
-   case SSEDIT_REMOVE:
-     scriptSetRemove(set, atoi(arg));
-     break;
- 
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing ssedit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
- 
-   /********************************************************/
-   /*                 DISPLAY NEXT MENU HERE               */
-   /********************************************************/
-   ssedit_menu(sock, olc);
-   olcSetSubstate(olc, next_substate);
- }
- 
- #endif // MODULE_SCRIPTS
--- 0 ----
diff -crN nakedmudv1.5/src/olc/zedit.c nakedmudv2.0/src/olc/zedit.c
*** nakedmudv1.5/src/olc/zedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/olc/zedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,147 ****
- //*****************************************************************************
- //
- // zedit.c
- //
- // Contains all of the functions needed for online editing of zones.
- //
- //*****************************************************************************
- 
- #include "../mud.h"
- #include "../world.h"
- #include "../zone.h"
- #include "../socket.h"
- #include "../utils.h"
- 
- #include "olc.h"
- 
- 
- void zedit_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   ZONE_DATA *zone = (ZONE_DATA *)olcGetData(olc);
- 
-   send_to_socket(sock,
-                  "\033[H\033[J"
- 		 "{g[{c%d{g]\r\n"
- 		 "{g1) Name\r\n"
- 		 "{c%s\r\n"
- 		 "{g2) Editors\r\n"
- 		 "{c%s\r\n"
- 		 "{g3) Reset timer: {c%d {gmins\r\n"
- 		 "{g4) Description\r\n"
- 		 "{c%s\r\n"
- 		 "\r\n"
- 		 "{gEnter choice (Q to quit) : {n",
- 		 zoneGetVnum(zone),
- 		 zoneGetName(zone),
- 		 zoneGetEditors(zone),
- 		 zoneGetPulseTimer(zone),
- 		 zoneGetDesc(zone)
- 		 );
- }
- 
- 
- void zedit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = ZEDIT_MAIN;
- 
-   switch(toupper(*arg)) {
-   case 'Q':
-     send_to_socket(sock, "Save changes (Y/N) : ");
-     next_substate = ZEDIT_CONFIRM_SAVE;
-     break;
- 
-   case '1':
-     send_to_socket(sock, "Enter new name : ");
-     next_substate = ZEDIT_NAME;
-     break;
- 
-   case '2':
-     send_to_socket(sock, "Enter a new list of editors : ");
-     next_substate = ZEDIT_EDITORS;
-     break;
- 
-   case '3':
-     send_to_socket(sock, "Enter reset timer (-1 for no resets) : ");
-     next_substate = ZEDIT_RESET;
-     break;
- 
-   case '4':
-     send_to_socket(sock, "Enter new description\r\n");
-     start_text_editor(sock, 
- 		      zoneGetDescPtr((ZONE_DATA *)olcGetData(olc)),
- 		      MAX_BUFFER, EDITOR_MODE_NORMAL);
-     next_substate = ZEDIT_MAIN;
-     break;
- 
-   default:
-     zedit_menu(sock, olc);
-     break;
-   }
- 
-   olcSetSubstate(olc, next_substate);
- }
- 
- 
- 
- void zedit_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   ZONE_DATA *zone = (ZONE_DATA *)olcGetData(olc);
-   int next_substate = ZEDIT_MAIN;
- 
-   switch(olcGetSubstate(olc)) {
-     /******************************************************/
-     /*                     MAIN MENU                      */
-     /******************************************************/
-   case ZEDIT_MAIN:
-     zedit_main_loop(sock, olc, arg);
-     return;
- 
- 
-     /******************************************************/
-     /*                    CONFIRM SAVE                    */
-     /******************************************************/
-   case ZEDIT_CONFIRM_SAVE:
-     switch(*arg) {
-     case 'y':
-     case 'Y':
-       olcSetSave(olc, TRUE);
-       // fall through
-     case 'n':
-     case 'N':
-       olcSetComplete(olc, TRUE);
-       return;
-     default:
-       send_to_socket(sock, "Please enter Y or N : ");
-       next_substate = ZEDIT_CONFIRM_SAVE;
-       break;
-     }
-     break;
- 
- 
-     /******************************************************/
-     /*                      SET VALUES                    */
-     /******************************************************/
-   case ZEDIT_NAME:
-     zoneSetName(zone, arg);
-     break;
- 
-   case ZEDIT_EDITORS:
-     zoneSetEditors(zone, arg);
-     break;
- 
-   case ZEDIT_RESET:
-     zoneSetPulseTimer(zone, atoi(arg));
-     break;
- 
-     /******************************************************/
-     /*                        DEFAULT                     */
-     /******************************************************/
-   default:
-     log_string("ERROR: Performing zedit with invalid substate.");
-     send_to_socket(sock, "An error occured while you were in OLC.\r\n");
-     socketSetOLC(sock, NULL);
-     socketSetState(sock, STATE_PLAYING);
-     return;
-   }
- 
-   olcSetSubstate(olc, next_substate);
-   if(next_substate == ZEDIT_MAIN)
-     zedit_menu(sock, olc);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/olc2/dedit.c nakedmudv2.0/src/olc2/dedit.c
*** nakedmudv1.5/src/olc2/dedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/dedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,201 ----
+ //*****************************************************************************
+ //
+ // dedit.c
+ //
+ // Dialogs are sets of reactions to speech that NPCs can have tagged onto them.
+ // This is these are the utilities for editing dialogs in OLC.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../dialog.h"
+ #include "../world.h"
+ #include "../zone.h"
+ #include "../socket.h"
+ #include "../character.h"
+ 
+ #include "../editor/editor.h"
+ 
+ #include "olc.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // olc for response data
+ //*****************************************************************************
+ #define RESPEDIT_KEYWORDS 1
+ 
+ void respedit_menu(SOCKET_DATA *sock, RESPONSE_DATA *response) {
+   send_to_socket(sock,
+ 		 "{g1) Keywords\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g2) Message\r\n"
+ 		 "{c%s\r\n",
+ 		 responseGetKeywords(response), 
+ 		 responseGetMessage(response)
+ 		 );
+ }
+ 
+ int respedit_chooser(SOCKET_DATA *sock, RESPONSE_DATA *response, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter a new list of keywords: ");
+     return RESPEDIT_KEYWORDS;
+   case '2':
+     socketStartEditor(sock, dialog_editor, responseGetMessageBuffer(response));
+     return MENU_NOCHOICE;
+   default: return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool respedit_parser(SOCKET_DATA *sock, RESPONSE_DATA *response, int choice, 
+ 		     const char *arg) {
+   switch(choice) {
+   case RESPEDIT_KEYWORDS:
+     responseSetKeywords(response, arg);
+     return TRUE;
+   default: return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // olc for dialog data
+ //*****************************************************************************
+ #define DEDIT_TITLE      1
+ #define DEDIT_EDIT       2
+ #define DEDIT_DELETE     3
+ 
+ void dedit_menu(SOCKET_DATA *sock, DIALOG_DATA *dialog) {
+   int i, entries = dialogGetSize(dialog);
+   int half_entries = entries/2 + (entries % 2 == 1);
+   // entries are printed side by side... these are used to hold 'em
+   char left_buf[SMALL_BUFFER];
+   char right_buf[SMALL_BUFFER];
+ 
+   send_to_socket(sock,
+ 		 "{gT) Dialog title\r\n"
+ 		 "{c%s\r\n"
+ 		 "{gG) Greet/Approach message\r\n"
+ 		 "{c%s\r\n"
+ 		 "\r\n"
+ 		 "{gResponse Entries: {c%d\r\n", 
+ 		 dialogGetName(dialog), 
+ 		 (*dialogGetGreet(dialog) ? dialogGetGreet(dialog) : "<NONE>"), 
+ 		 entries);
+ 
+   // print out responses, two to a line
+   for(i = 0; i < half_entries; i++) {
+     RESPONSE_DATA *left_entry = dialogGetNum(dialog, i);
+     sprintf(left_buf, "  {g%2d) {c%s", i, responseGetKeywords(left_entry));
+     if(i + half_entries >= entries)
+       *right_buf = '\0';
+     else {
+       RESPONSE_DATA *right_entry = dialogGetNum(dialog, i + half_entries);
+       sprintf(right_buf, "  {g%2d) {c%s", 
+ 	      i + half_entries, responseGetKeywords(right_entry));
+     }
+     send_to_socket(sock, "%-35s %s\r\n", left_buf, right_buf);
+   }
+ 
+   send_to_socket(sock, "\r\n"
+ 		 "  {gE) edit entry\r\n"
+ 		 "  {gN) new entry\r\n"
+ 		 "  {gD) delete entry\r\n");
+ }
+ 
+ 
+ int dedit_chooser(SOCKET_DATA *sock, DIALOG_DATA *dialog, char option) {
+   switch(toupper(option)) {
+   case 'T':
+     text_to_buffer(sock, "Enter a new title for the dialog: ");
+     return DEDIT_TITLE;
+   case 'G':
+     socketStartEditor(sock, dialog_editor, dialogGetGreetBuffer(dialog));
+     return MENU_NOCHOICE;
+   case 'E':
+     text_to_buffer(sock, "Which response would you like to edit: ");
+     return DEDIT_EDIT;
+   case 'N': {
+     RESPONSE_DATA *response = newResponse();
+     dialogPut(dialog, response);
+     do_olc(sock, respedit_menu, respedit_chooser, respedit_parser, NULL, NULL,
+ 	   NULL, NULL, response);
+     return MENU_NOCHOICE;
+   case 'D':
+     text_to_buffer(sock, "Which response would you like to delete: ");
+     return DEDIT_DELETE;
+   default: return MENU_CHOICE_INVALID;
+   }
+   }
+ }
+ 
+ 
+ bool dedit_parser(SOCKET_DATA *sock, DIALOG_DATA *dialog, int choice, 
+ 		  const char *arg) {
+   switch(choice) {
+   case DEDIT_TITLE:
+     dialogSetName(dialog, arg);
+     return TRUE;
+ 
+   case DEDIT_EDIT: {
+     if(!isdigit(*arg))
+       return FALSE;
+     RESPONSE_DATA *response = dialogGetNum(dialog, atoi(arg));
+     if(response) {
+       do_olc(sock, respedit_menu, respedit_chooser, respedit_parser, NULL, NULL,
+ 	     NULL, NULL, response);
+     }
+     return TRUE;
+   }
+ 
+   case DEDIT_DELETE: {
+     if(!isdigit(*arg))
+       return FALSE;
+     RESPONSE_DATA *response = dialogGetNum(dialog, atoi(arg));
+     if(response) {
+       dialogRemove(dialog, response);
+       deleteResponse(response);
+     }
+     return TRUE;
+   }
+ 
+   default: return FALSE;
+   }
+ }
+ 
+ COMMAND(cmd_dedit) {
+   ZONE_DATA *zone;
+   DIALOG_DATA *dialog;
+   int vnum;
+ 
+   // we need to know which dialog...
+   if(!arg || !*arg || !isdigit(*arg))
+     send_to_char(ch, "Which dialog did you want to edit?\r\n");
+   else {
+     vnum = atoi(arg);
+ 
+     // make sure there is a corresponding zone ...
+     if((zone = worldZoneBounding(gameworld, vnum)) == NULL)
+       send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
+     else if(!canEditZone(zone, ch))
+       send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
+     else {
+       // find the dialog
+       dialog = zoneGetDialog(zone, vnum);
+ 
+       // make our dialog
+       if(dialog == NULL) {
+ 	dialog = newDialog();
+ 	dialogSetVnum (dialog, vnum);
+ 	dialogSetName (dialog, "An Unfinished Dialog");
+ 	dialogSetGreet(dialog, "Hi! This dialog is unfinished.");
+ 	zoneAddDialog(zone, dialog);
+       }
+       
+       do_olc(charGetSocket(ch), dedit_menu, dedit_chooser, dedit_parser,
+ 	     dialogCopy, dialogCopyTo, deleteDialog, save_world, dialog);
+     }
+   }
+ }
diff -crN nakedmudv1.5/src/olc2/dedit.d nakedmudv2.0/src/olc2/dedit.d
*** nakedmudv1.5/src/olc2/dedit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/dedit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ olc2/dedit.d olc2/dedit.o: olc2/dedit.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h dialog.h world.h zone.h socket.h \
+   character.h editor/editor.h olc2/olc.h
diff -crN nakedmudv1.5/src/olc2/esedit.c nakedmudv2.0/src/olc2/esedit.c
*** nakedmudv1.5/src/olc2/esedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/esedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,128 ----
+ //*****************************************************************************
+ //
+ // esedit.c
+ //
+ // Contains all of the functions for doing the olc editing of extra description
+ // sets. Used by rooms, objects (and mobiles?)
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../socket.h"
+ #include "../extra_descs.h"
+ #include "../editor/editor.h"
+ 
+ #include "olc.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for editing a single extra description
+ //*****************************************************************************
+ #define EDEDIT_KEYWORD     1
+ 
+ void edesc_menu(SOCKET_DATA *sock, EDESC_DATA *edesc) {
+   send_to_socket(sock,
+ 		 "{g1) Keywords\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g2) Description\r\n"
+ 		 "{c%s\r\n",
+ 		 edescSetGetKeywords(edesc), 
+ 		 edescSetGetDesc(edesc)
+ 		 );
+ }
+ 
+ int  edesc_chooser(SOCKET_DATA *sock, EDESC_DATA *edesc, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter a new list of keywords: ");
+     return EDEDIT_KEYWORD;
+   case '2':
+     socketStartEditor(sock, text_editor, edescGetDescBuffer(edesc));
+     return MENU_NOCHOICE;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool edesc_parser(SOCKET_DATA *sock, EDESC_DATA *edesc, int choice, 
+ 		  const char *arg) {
+   switch(choice) {
+   case EDEDIT_KEYWORD:
+     edescSetKeywords(edesc, arg);
+     return TRUE;
+   default:
+     return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for editing an extra description set
+ //*****************************************************************************
+ #define ESEDIT_DELETE     1
+ #define ESEDIT_EDIT       2
+ 
+ void edesc_set_menu(SOCKET_DATA *sock, EDESC_SET *set) {
+   int i, entries = edescGetSetSize(set);
+ 
+   send_to_socket(sock,
+ 		 "{gEntries: {c%d\r\n", entries);
+   // print out each one
+   for(i = 0; i < entries; i++)
+     send_to_socket(sock, "  {g%2d) {c%s\r\n", i, 
+ 		   edescSetGetKeywords(edescSetGetNum(set, i)));
+   send_to_socket(sock,
+ 		 "\r\n"
+ 		 "{gE) edit entry\r\n"
+ 		 "{gN) new entry\r\n"
+ 		 "{gD) delete entry\r\n"
+ 		 );
+ }
+ 
+ int  edesc_set_chooser(SOCKET_DATA *sock, EDESC_SET *set, char option) {
+   switch(toupper(option)) {
+   case 'E':
+     text_to_buffer(sock, "Enter the number of the edesc to edit: ");
+     return ESEDIT_EDIT;
+   case 'N': {
+     // create a new edesc
+     EDESC_DATA *edesc = newEdesc("", "");
+     edescSetPut(set, edesc);
+     do_olc(sock, edesc_menu, edesc_chooser, edesc_parser, NULL, NULL, NULL,
+ 	   NULL, edesc);
+     return MENU_NOCHOICE;
+   }
+   case 'D':
+     text_to_buffer(sock, "Enter the number of the edesc to delete: ");
+     return ESEDIT_DELETE;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ 
+ bool edesc_set_parser(SOCKET_DATA *sock, EDESC_SET *set, int choice,
+ 		       const char *arg) {
+   switch(choice) {
+   case ESEDIT_EDIT: {
+     EDESC_DATA *edesc = edescSetGetNum(set, atoi(arg));
+     if(edesc == NULL)
+       return FALSE;
+     do_olc(sock, edesc_menu, edesc_chooser, edesc_parser, NULL, NULL, NULL,
+ 	   NULL, edesc);
+     return TRUE;
+   }
+   case ESEDIT_DELETE: {
+     EDESC_DATA *edesc = edescSetGetNum(set, atoi(arg));
+     if(edesc) {
+       removeEdesc(set, edesc);
+       deleteEdesc(edesc);
+     }
+     return TRUE;
+   }
+   default:
+     return FALSE;
+   }
+ }
diff -crN nakedmudv1.5/src/olc2/esedit.d nakedmudv2.0/src/olc2/esedit.d
*** nakedmudv1.5/src/olc2/esedit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/esedit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ olc2/esedit.d olc2/esedit.o: olc2/esedit.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h socket.h extra_descs.h \
+   editor/editor.h olc2/olc.h
diff -crN nakedmudv1.5/src/olc2/medit.c nakedmudv2.0/src/olc2/medit.c
*** nakedmudv1.5/src/olc2/medit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/medit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,194 ----
+ //*****************************************************************************
+ //
+ // medit.c
+ //
+ // The functions needed for doing online editing of mobiles.
+ //
+ //*****************************************************************************
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "../races.h"
+ #include "../world.h"
+ #include "../dialog.h"
+ #include "../zone.h"
+ 
+ #include "olc.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "../scripts/script.h"
+ #include "../editor/editor.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // mobile editing
+ //*****************************************************************************
+ #define MEDIT_NAME          1
+ #define MEDIT_MULTI_NAME    2
+ #define MEDIT_KEYWORDS      3
+ #define MEDIT_RDESC         4
+ #define MEDIT_MULTI_RDESC   5
+ #define MEDIT_RACE          6
+ #define MEDIT_SEX           7
+ #define MEDIT_DIALOG        8
+ 
+ void medit_menu(SOCKET_DATA *sock, CHAR_DATA *mob) {
+   send_to_socket(sock,
+ 		 "{g[{c%d{g]\r\n"
+ 		 "{g1) Name\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g2) Name for multiple occurences\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g3) Keywords\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g4) Room description\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g5) Room description for multiple occurences\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g6) Description\r\n"
+ 		 "{c%s\r\n"
+ 		 "{gS) Script menu\r\n"
+ 		 "{gR) Change race   {y[{c%8s{y]\r\n"
+ 		 "{gG) Change Gender {y[{c%8s{y]\r\n"
+ 		 "{gD) Dialog        {y[{c%8d{y]  {w%s\r\n",
+ 		 charGetVnum(mob),
+ 		 charGetName(mob),
+ 		 charGetMultiName(mob),
+ 		 charGetKeywords(mob),
+ 		 charGetRdesc(mob),
+ 		 charGetMultiRdesc(mob),
+ 		 charGetDesc(mob),
+ 		 charGetRace(mob),
+ 		 sexGetName(charGetSex(mob)),
+ 		 charGetDialog(mob),
+ 		 (worldGetDialog(gameworld, charGetDialog(mob)) ?
+ 		  dialogGetName(worldGetDialog(gameworld, 
+ 					       charGetDialog(mob))) : "")
+ 		 );
+ }
+ 
+ int  medit_chooser(SOCKET_DATA *sock, CHAR_DATA *mob, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter name: ");
+     return MEDIT_NAME;
+   case '2':
+     text_to_buffer(sock, "Enter name for multiple occurences: ");
+     return MEDIT_MULTI_NAME;
+   case '3':
+     text_to_buffer(sock, "Enter keywords: ");
+     return MEDIT_KEYWORDS;
+   case '4':
+     text_to_buffer(sock, "Enter room description: ");
+     return MEDIT_RDESC;
+   case '5':
+     text_to_buffer(sock, "Enter room description for multiple occurences: ");
+     return MEDIT_MULTI_RDESC;
+   case '6':
+     text_to_buffer(sock, "Enter description\r\n");
+     socketStartEditor(sock, text_editor, charGetDescBuffer(mob));
+     return MENU_NOCHOICE;
+   case 'R':
+     send_to_socket(sock, "%s\r\n\r\n", raceGetList(FALSE));
+     send_to_socket(sock, "Please select a race: ");
+     return MEDIT_RACE;
+   case 'G':
+     olc_display_table(sock, sexGetName, NUM_SEXES, 1);
+     return MEDIT_SEX;
+   case 'D':
+     text_to_buffer(sock, "Enter the dialog vnum (-1 for none): ");
+     return MEDIT_DIALOG;
+   case 'S':
+     do_olc(sock, ssedit_menu, ssedit_chooser, ssedit_parser,
+ 	   NULL, NULL, NULL, NULL, charGetScripts(mob));
+     return MENU_NOCHOICE;
+   default: return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool medit_parser(SOCKET_DATA *sock, CHAR_DATA *mob, int choice, 
+ 		  const char *arg) {
+   switch(choice) {
+   case MEDIT_NAME:
+     charSetName(mob, arg);
+     return TRUE;
+   case MEDIT_MULTI_NAME:
+     charSetMultiName(mob, arg);
+     return TRUE;
+   case MEDIT_KEYWORDS:
+     charSetKeywords(mob, arg);
+     return TRUE;
+   case MEDIT_RDESC:
+     charSetRdesc(mob, arg);
+     return TRUE;
+   case MEDIT_MULTI_RDESC:
+     charSetMultiRdesc(mob, arg);
+     return TRUE;
+   case MEDIT_RACE:
+     if(!isRace(arg))
+       return FALSE;
+     charSetRace(mob, arg);
+     return TRUE;
+   case MEDIT_SEX: {
+     int val = atoi(arg);
+     if(!isdigit(*arg) || val < 0 || val >= NUM_SEXES)
+       return FALSE;
+     charSetSex(mob, val);
+     return TRUE;
+   }
+   case MEDIT_DIALOG: {
+     int vnum = (isdigit(*arg) ? atoi(arg) : NOTHING);
+     DIALOG_DATA *dialog = worldGetDialog(gameworld, vnum);
+     if(!dialog && vnum != NOTHING)
+       return FALSE;
+     else {
+       charSetDialog(mob, vnum);    
+       return TRUE;
+     }
+   }
+   default: return FALSE;
+   }
+ }
+ 
+ COMMAND(cmd_medit) {
+   ZONE_DATA *zone;
+   CHAR_DATA *mob;
+   mob_vnum vnum;
+ 
+   if(!arg || !*arg || !isdigit(*arg))
+     send_to_char(ch, "Invalid vnum! Try again.\r\n");
+   else {
+     vnum = atoi(arg);
+ 
+     // make sure there is a corresponding zone ...
+     if((zone = worldZoneBounding(gameworld, vnum)) == NULL)
+       send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
+     else if(!canEditZone(zone, ch))
+       send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
+     else {
+       // find the mobile
+       mob = zoneGetMob(zone, vnum);
+ 
+       // make our mobile
+       if(mob == NULL) {
+ 	mob = newMobile(vnum);
+ 	zoneAddMob(zone, mob);
+ 	charSetName(mob, "an unfinished mobile");
+ 	charSetKeywords(mob, "mobile, unfinshed");
+ 	charSetRdesc(mob, "an unfinished mobile is standing here.");
+ 	charSetDesc(mob, "it looks unfinished.\r\n");
+ 	charSetMultiName(mob, "%d unfinished mobiles");
+ 	charSetMultiRdesc(mob, "A group of %d mobiles are here, looking unfinished.");
+       }
+ 
+       do_olc(charGetSocket(ch), medit_menu, medit_chooser, medit_parser,
+ 	     charCopy, charCopyTo, deleteChar, save_world, mob);
+     }
+   }
+ }
diff -crN nakedmudv1.5/src/olc2/medit.d nakedmudv2.0/src/olc2/medit.d
*** nakedmudv1.5/src/olc2/medit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/medit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ olc2/medit.d olc2/medit.o: olc2/medit.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h character.h \
+   races.h world.h dialog.h zone.h olc2/olc.h scripts/script.h \
+   editor/editor.h
diff -crN nakedmudv1.5/src/olc2/module.mk nakedmudv2.0/src/olc2/module.mk
*** nakedmudv1.5/src/olc2/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ SRC  += olc2/olc.c olc2/redit.c olc2/zedit.c olc2/esedit.c olc2/dedit.c \
+ 	olc2/medit.c olc2/oedit.c
diff -crN nakedmudv1.5/src/olc2/oedit.c nakedmudv2.0/src/olc2/oedit.c
*** nakedmudv1.5/src/olc2/oedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/oedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,177 ----
+ //*****************************************************************************
+ //
+ // oedit.c
+ //
+ // The functions needed for doing online editing of objects
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "../object.h"
+ #include "../world.h"
+ #include "../zone.h"
+ 
+ #include "olc.h"
+ #include "olc_submenus.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "../scripts/script.h"
+ #include "../editor/editor.h"
+ #include "../items/iedit.h"
+ #include "../items/items.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // object editing
+ //*****************************************************************************
+ #define OEDIT_NAME          1
+ #define OEDIT_MULTI_NAME    2
+ #define OEDIT_KEYWORDS      3
+ #define OEDIT_RDESC         4
+ #define OEDIT_MULTI_RDESC   5
+ #define OEDIT_WEIGHT        6
+ 
+ void oedit_menu(SOCKET_DATA *sock, OBJ_DATA *obj) {
+   send_to_socket(sock,
+ 		 "{g[{c%d{g]\r\n"
+ 		 "{g1) Name\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g2) Name for multiple occurences\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g3) Keywords\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g4) Room description\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g5) Room description for multiple occurences\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g6) Description\r\n"
+ 		 "{c%s\r\n"
+ 		 "{gW) Weight:    {c%1.3lf\r\n"
+ 		 "{gT) Edit item types: {c%s\r\n"
+ 		 "{gS) Script menu\r\n"
+ 		 "{gX) Extra Descriptions menu\r\n",
+ 		 objGetVnum(obj),
+ 		 objGetName(obj),
+ 		 objGetMultiName(obj),
+ 		 objGetKeywords(obj),
+ 		 objGetRdesc(obj),
+ 		 objGetMultiRdesc(obj),
+ 		 objGetDesc(obj),
+ 		 objGetWeightRaw(obj),
+ 		 objGetTypes(obj)
+ 		 );
+ }
+ 
+ int  oedit_chooser(SOCKET_DATA *sock, OBJ_DATA *obj, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter name: ");
+     return OEDIT_NAME;
+   case '2':
+     text_to_buffer(sock, "Enter name for multiple occurences: ");
+     return OEDIT_MULTI_NAME;
+   case '3':
+     text_to_buffer(sock, "Enter keywords: ");
+     return OEDIT_KEYWORDS;
+   case '4':
+     text_to_buffer(sock, "Enter room description: ");
+     return OEDIT_RDESC;
+   case '5':
+     text_to_buffer(sock, "Enter room description for multiple occurences: ");
+     return OEDIT_MULTI_RDESC;
+   case '6':
+     text_to_buffer(sock, "Enter description\r\n");
+     socketStartEditor(sock, text_editor, objGetDescBuffer(obj));
+     return MENU_NOCHOICE;
+   case 'W':
+     text_to_buffer(sock, "Enter new weight: ");
+     return OEDIT_WEIGHT;
+   case 'X':
+     do_olc(sock, edesc_set_menu, edesc_set_chooser, edesc_set_parser, NULL,NULL,
+ 	   NULL, NULL, objGetEdescs(obj));
+     return MENU_NOCHOICE;
+   case 'T':
+     do_olc(sock, iedit_menu, iedit_chooser, iedit_parser, NULL, NULL, NULL,
+ 	   NULL, obj);
+     return MENU_NOCHOICE;
+   case 'S':
+     do_olc(sock, ssedit_menu, ssedit_chooser, ssedit_parser,
+ 	   NULL, NULL, NULL, NULL, objGetScripts(obj));
+     return MENU_NOCHOICE;
+   default: return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool oedit_parser(SOCKET_DATA *sock, OBJ_DATA *obj, int choice, 
+ 		  const char *arg){
+   switch(choice) {
+   case OEDIT_NAME:
+     objSetName(obj, arg);
+     return TRUE;
+   case OEDIT_MULTI_NAME:
+     objSetMultiName(obj, arg);
+     return TRUE;
+   case OEDIT_KEYWORDS:
+     objSetKeywords(obj, arg);
+     return TRUE;
+   case OEDIT_RDESC:
+     objSetRdesc(obj, arg);
+     return TRUE;
+   case OEDIT_MULTI_RDESC:
+     objSetMultiRdesc(obj, arg);
+     return TRUE;
+   case OEDIT_WEIGHT: {
+     double val = atof(arg);
+     if(val < 0) return FALSE;
+     objSetWeightRaw(obj, val);
+     return TRUE;
+   }
+   default: return FALSE;
+   }
+ }
+ 
+ COMMAND(cmd_oedit) {
+   ZONE_DATA *zone;
+   OBJ_DATA *obj;
+   obj_vnum vnum;
+ 
+   // if no argument is supplied, default to the current obj
+   if(!arg || !*arg)
+     send_to_char(ch, "Please supply the vnum of a obj you wish to edit.\r\n");
+   else {
+     vnum = atoi(arg);
+ 
+     // make sure there is a corresponding zone ...
+     if((zone = worldZoneBounding(gameworld, vnum)) == NULL)
+       send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
+     else if(!canEditZone(zone, ch))
+       send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
+     else {
+       // find the obj
+       obj = worldGetObj(gameworld, vnum);
+ 
+       // make our obj
+       if(obj == NULL) {
+ 	obj = newObj(vnum);
+ 	objSetVnum(obj, vnum);
+ 	objSetName      (obj, "an unfinished object");
+ 	objSetKeywords  (obj, "object, unfinshed");
+ 	objSetRdesc     (obj, "an unfinished object is lying here.");
+ 	objSetDesc      (obj, "it looks unfinished.\r\n");
+ 	objSetMultiName (obj, "a group of %d unfinished objects");
+ 	objSetMultiRdesc(obj, "%d objects lay here, all unfinished.");
+       }
+ 
+       do_olc(charGetSocket(ch), oedit_menu, oedit_chooser, oedit_parser,
+ 	     objCopy, objCopyTo, deleteObj, save_world, obj);
+     }
+   }
+ }
diff -crN nakedmudv1.5/src/olc2/oedit.d nakedmudv2.0/src/olc2/oedit.d
*** nakedmudv1.5/src/olc2/oedit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/oedit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ olc2/oedit.d olc2/oedit.o: olc2/oedit.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h character.h \
+   object.h world.h zone.h olc2/olc.h olc2/olc_submenus.h scripts/script.h \
+   editor/editor.h items/iedit.h items/items.h
diff -crN nakedmudv1.5/src/olc2/olc.c nakedmudv2.0/src/olc2/olc.c
*** nakedmudv1.5/src/olc2/olc.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/olc.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,291 ----
+ //*****************************************************************************
+ //
+ // olc.c
+ //
+ // My first go at OLC was during the pre-module time, and it really wasn't all
+ // that well put together in the first place. This is the second go at it...
+ // this time, OLC is more like some general functions that make it easy to do
+ // online editing, rather than a full system. It will be amenable to adding
+ // new extentions to the general OLC framework from other modules, and it will
+ // essentially just be a bunch spiffier.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "../world.h"
+ #include "../character.h"  // for POS_XXX <-- we should change the place of this
+ #include "../auxiliary.h"
+ #include "olc.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // local data structures, defines, and functions
+ //
+ //*****************************************************************************
+ typedef struct olc_data {
+   void    (* menu)(SOCKET_DATA *, void *);
+   int  (* chooser)(SOCKET_DATA *, void *, char);
+   bool  (* parser)(SOCKET_DATA *, void *, int, const char *);
+   void *(* copier)(void *);
+   void  (* copyto)(void *, void *);
+   void (* deleter)(void *);
+   void   (* saver)(void *); 
+   void *data;
+   void *working_copy;
+   int  cmd;
+ } OLC_DATA;
+ 
+ OLC_DATA *newOLC(void    (* menu)(SOCKET_DATA *, void *),
+ 		 int  (* chooser)(SOCKET_DATA *, void *, char),
+ 		 bool  (* parser)(SOCKET_DATA *, void *, int, const char *),
+ 		 void *(* copier)(void *),
+ 		 void  (* copyto)(void *, void *),
+ 		 void (* deleter)(void *),
+ 		 void   (* saver)(void *),
+ 		 void *data) {
+   OLC_DATA *olc     = malloc(sizeof(OLC_DATA));
+   olc->menu         = menu;
+   olc->chooser      = chooser;
+   olc->parser       = parser;
+   olc->copier       = copier;
+   olc->copyto       = copyto;
+   olc->deleter      = deleter;
+   olc->saver        = saver;
+   olc->data         = data;
+   olc->working_copy = (copier ? copier(data) : data);
+   olc->cmd          = MENU_NOCHOICE;
+   return olc;
+ }
+ 
+ void deleteOLC(OLC_DATA *olc) {
+   if(olc->deleter) olc->deleter(olc->working_copy);
+   free(olc);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // auxiliary data we put on the socket
+ //
+ //*****************************************************************************
+ typedef struct olc_aux_data {
+   LIST *olc_stack; // the list of OLCs we have opened
+ } OLC_AUX_DATA;
+ 
+ OLC_AUX_DATA *
+ newOLCAuxData() {
+   OLC_AUX_DATA *data = malloc(sizeof(OLC_AUX_DATA));
+   data->olc_stack = newList();
+   return data;
+ }
+ 
+ void
+ deleteOLCAuxData(OLC_AUX_DATA *data) {
+   if(data->olc_stack) deleteListWith(data->olc_stack, deleteOLC);
+   free(data);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // Implementation of the OLC framework
+ //
+ //*****************************************************************************
+ 
+ //
+ // display the current menu to the socket, as well as the generic prompt
+ //
+ void olc_menu(SOCKET_DATA *sock) {
+   // send the current menu
+   OLC_AUX_DATA *aux_olc = socketGetAuxiliaryData(sock, "olc_aux_data");
+   OLC_DATA         *olc = listGet(aux_olc->olc_stack, 0);
+   // don't display then menu if we've made a menu choice
+   if(olc->cmd == MENU_NOCHOICE) {
+     text_to_buffer(sock, CLEAR_SCREEN);
+     olc->menu(sock, olc->working_copy);
+     text_to_buffer(sock, "\r\nEnter choice, or Q to quit: ");
+   }
+ }
+ 
+ 
+ //
+ // handle the cleanup process for exiting OLC; pop the top handler off of
+ // the OLC stack and delete it. Save changes if neccessary. Exit the OLC handler
+ // if we have no more OLC work to do. Return the new and improved version of
+ // whatever it was we were editing.
+ //
+ void *olc_exit(SOCKET_DATA *sock, bool save) {
+   // pull up the OLC data to manipulate
+   OLC_AUX_DATA *aux_olc = socketGetAuxiliaryData(sock, "olc_aux_data");
+   OLC_DATA         *olc = listGet(aux_olc->olc_stack, 0);
+   void            *data = olc->data;
+ 
+   // pop our OLC off of the OLC stack
+   listPop(aux_olc->olc_stack);
+ 
+   // if we need to do any saving, do it now
+   if(save) {
+     // first, save the changes on the item
+     if(olc->working_copy != olc->data && olc->copyto)
+       olc->copyto(olc->working_copy, olc->data);
+     // now, make sure the changes go to disk
+     if(olc->saver)
+       olc->saver(olc->data);
+   }
+ 
+   // delete our OLC data (this also deletes our working copy 
+   // if it's not the same as our main copy)
+   deleteOLC(olc);
+ 
+   // if our OLC stack is empty, pop the OLC input handler
+   if(listSize(aux_olc->olc_stack) == 0)
+     socketPopInputHandler(sock);
+   return data;
+ }
+ 
+ 
+ //
+ // Handle input while in OLC
+ //
+ void olc_handler(SOCKET_DATA *sock, char *arg) {
+   // pull up the OLC data. Are we entering a new command, or are
+   // we entering in an argument from a menu choice?
+   OLC_AUX_DATA *aux_olc = socketGetAuxiliaryData(sock, "olc_aux_data");
+   OLC_DATA         *olc = listGet(aux_olc->olc_stack, 0);
+ 
+   // we're giving an argument for a menu choice we've already selected
+   if(olc->cmd > MENU_NOCHOICE) {
+     // the change went alright. Re-display the menu
+     if(olc->parser(sock, olc->working_copy, olc->cmd, arg)) {
+       olc->cmd = MENU_NOCHOICE;
+       olc_menu(sock);
+     }
+     else
+       text_to_buffer(sock, "Invalid choice!\r\nTry again: ");
+   }
+ 
+   // we're being prompted if we want to save our changes or not before quitting
+   else if(olc->cmd == MENU_CHOICE_CONFIRM_SAVE) {
+     switch(toupper(*arg)) {
+     case 'Y':
+     case 'N':
+       olc_exit(sock, (toupper(*arg) == 'Y' ? TRUE : FALSE));
+       break;
+     default:
+       text_to_buffer(sock, "Invalid choice!\r\nTry again: ");
+       break;
+     }
+   }
+ 
+   // we're entering a new choice from our current menu
+   else {
+     switch(*arg) {
+       // we're quitting
+     case 'q':
+     case 'Q':
+       // if our working copy is different from our actual data, prompt to
+       // see if we want to save our changes or not
+       if(olc->working_copy != olc->data) {
+ 	text_to_buffer(sock, "Save changes (Y/N): ");
+ 	olc->cmd = MENU_CHOICE_CONFIRM_SAVE;
+       }
+       else {
+ 	olc_exit(sock, TRUE);
+       }
+       break;
+ 
+     default: {
+       int cmd = olc->chooser(sock, olc->working_copy, *arg);
+       // the menu choice we entered wasn't a valid one. redisplay the menu
+       if(cmd == MENU_CHOICE_INVALID)
+ 	olc_menu(sock);
+       // the menu choice was acceptable. Note this in our data
+       else if(cmd > MENU_NOCHOICE)
+ 	olc->cmd = cmd;
+       break;
+     }
+     }
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // implementation of olc.h
+ //
+ //*****************************************************************************
+ 
+ void init_olc2() {
+   // install our auxiliary data on the socket so 
+   // we can keep track of our olc data
+   auxiliariesInstall("olc_aux_data",
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_SOCKET,
+ 				       newOLCAuxData, deleteOLCAuxData,
+ 				       NULL, NULL, NULL, NULL));
+ 
+   // initialize all of our basic OLC commands
+   extern COMMAND(cmd_redit);
+   extern COMMAND(cmd_zedit);
+   extern COMMAND(cmd_dedit);
+   extern COMMAND(cmd_medit);
+   extern COMMAND(cmd_oedit);
+   add_cmd("zedit", NULL, cmd_zedit, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, TRUE);
+   add_cmd("redit", NULL, cmd_redit, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, TRUE);
+   add_cmd("dedit", NULL, cmd_dedit, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, TRUE);
+   add_cmd("medit", NULL, cmd_medit, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, TRUE);
+   add_cmd("oedit", NULL, cmd_oedit, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, TRUE);
+ }
+ 
+ void do_olc(SOCKET_DATA *sock,
+ 	    void *menu,
+ 	    void *chooser,
+ 	    void *parser,
+ 	    void *copier,
+ 	    void *copyto,
+ 	    void *deleter,
+ 	    void *saver,
+ 	    void *data) {
+   // first, we create a new OLC data structure, and then push it onto the stack
+   OLC_DATA *olc = newOLC(menu, chooser, parser, copier, copyto, deleter,
+ 			 saver, data);
+   OLC_AUX_DATA *aux_olc = socketGetAuxiliaryData(sock, "olc_aux_data");
+   listPush(aux_olc->olc_stack, olc);
+ 
+   // if this is the only olc data on the stack, then enter the OLC handler
+   if(listSize(aux_olc->olc_stack) == 1)
+     socketPushInputHandler(sock, olc_handler, olc_menu);
+ }
+ 
+ void save_world(void *olc_data) {
+   worldSave(gameworld, WORLD_PATH);
+ }
+ 
+ void olc_display_table(SOCKET_DATA *sock, const char *getName(int val),
+ 		       int num_vals, int num_cols) {
+   int i, print_room;
+   static char fmt[SMALL_BUFFER];
+ 
+   print_room = (80 - 10*num_cols)/num_cols;
+   sprintf(fmt, "  {c%%2d{y) {g%%-%ds%%s", print_room);
+ 
+   for(i = 0; i < num_vals; i++)
+     send_to_socket(sock, fmt, i, getName(i), 
+ 		   (i % num_cols == (num_cols - 1) ? "\r\n" : "   "));
+ 
+   if(i % num_cols != 0)
+     send_to_socket(sock, "\r\n");
+ 
+   text_to_buffer(sock, "Pick an option: ");
+ }
diff -crN nakedmudv1.5/src/olc2/olc.d nakedmudv2.0/src/olc2/olc.d
*** nakedmudv1.5/src/olc2/olc.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/olc.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ olc2/olc.d olc2/olc.o: olc2/olc.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h world.h \
+   character.h auxiliary.h olc2/olc.h
diff -crN nakedmudv1.5/src/olc2/olc.h nakedmudv2.0/src/olc2/olc.h
*** nakedmudv1.5/src/olc2/olc.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/olc.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,111 ----
+ #ifndef OLC2_H
+ #define OLC2_H
+ //*****************************************************************************
+ //
+ // olc.h
+ //
+ // My first go at OLC was during the pre-module time, and it really wasn't all
+ // that well put together in the first place. This is the second go at it...
+ // this time, OLC is more like some general functions that make it easy to do
+ // online editing, rather than a full system. It will be amenable to adding
+ // new extentions to the general OLC framework from other modules, and it will
+ // essentially just be a bunch spiffier.
+ //
+ //*****************************************************************************
+ 
+ //
+ // prepare the OLC framework for use
+ void init_olc2();
+ 
+ //
+ // Set up a new OLC. OLCs can be stacked on top of eachother (e.g. room edit
+ // could call extra description edit. After the extra description edit is
+ // exited, room edit will continue). If this is the only OLC in use, OLC mode
+ // will automatically be entered. Below are descriptions of the paramaters the
+ // following function takes, and the form they should be:
+ //
+ // menu: This is a function that displays the current OLC menu to the socket.
+ //       void menu(SOCKET_DATA *sock, datatype *to_display)
+ //
+ // chooser: This is a function that takes in the menu option that the socket 
+ //       wishes to select. The values q and Q are reserved by the OLC handler
+ //       for quitting. The chooser is responsible for prompting the socket for 
+ //       appropriate arguments after a menu option has been selected. There are
+ //       three types of values that can be returned:
+ //          -1     invalid option
+ //           0     Valid choice, but we do not need to enter the parser. This
+ //                 would be returned, for instance, if a new do_olc was called,
+ //                 or if a toggle on/off menu option was selected.
+ //         >= 1    a numeric value representing the field we are editing. This
+ //                 will be passed to the modifier() function to perform changes
+ //                 after an argument is passed in.
+ //       the chooser function is of the form:
+ //       int chooser(SOCKET_DATA *sock, datatype *to_edit, char option)
+ //
+ // parser: This function is used to parse an argument, given a choice from the
+ //       menu. The choice is provided by the chooser() function, and an argument
+ //       is supplied afterwards. TRUE should be returned if the argument was
+ //       valid and the command was a success, and FALSE if it was not. 
+ //       The parser takes the form:
+ //       bool parser(SOCKET_DATA *sock, datatype *to_edit, int choice, 
+ //                   const char *arg)
+ //
+ // copier: This is a function that returns a deep copy of the data we are
+ //       editing. The data is not worked on, directly. Rather, a copy of it
+ //       is made and edited. If the changes are accepted at the end of OLC, they
+ //       are copied back over to the thing we were editing. This parameter can
+ //       be NULL if the data is to be worked on directly. The function is of
+ //       the form: void copier(datatype *thing_to_copy)
+ //
+ // copyto: This copies the data of one thing over to another datastructure of
+ //       the same type. This parameter can be NULL if the data is to be worked
+ //       on directly. This function takes the form:
+ //       void copyto(datatype *thing_to_copy_from, datatype *thing_to_copy_to)
+ //
+ // saver: After OLC is exited, we'll typically need to save the changes to disk.
+ //       this is the function that should be called to save all of the changes
+ //       that have been made. Saver can be null if changes are not to be saved
+ //       to disk after they have been made. This function takes the form:
+ //       void saver(datatype *working_copy)
+ //
+ // deleter: this is a function that will delete the working copy of our data.
+ //       This parameter can be NULL if the data is to be worked on directly.
+ //       This function takes the form:
+ //       void delete(datatype *working_copy)
+ #define MENU_CHOICE_CONFIRM_SAVE   (-2) // this define for internal use only!
+ #define MENU_CHOICE_INVALID        (-1)
+ #define MENU_NOCHOICE               (0)
+ 
+ void do_olc(SOCKET_DATA *sock,
+ 	    void *menu,
+ 	    void *chooser,
+ 	    void *parser,
+ 	    void *copier,
+ 	    void *copyto,
+ 	    void *deleter,
+ 	    void *saver,
+ 	    void *data);
+ 
+ 
+ 
+ //*****************************************************************************
+ // To keep a general "look and feel" to OLCs, a couple functions have been
+ // provided to display some features of an OLC in a standard manner.
+ //*****************************************************************************
+ 
+ //
+ // Okay, so I'm lazy. I don't want to write a saver() function for each type of
+ // thing that can be edited in OLC. Here is a function that will save any
+ // change, whether it's to a mob proto, an obj proto, or a room proto. It will
+ // be slow for a large mud, since it basically saves the -entire- world to disk,
+ // but you can work on changing that if your world gets big enough ;)
+ void save_world(void *olc_data);
+ 
+ 
+ //
+ // Display a bunch of options in a tabular form. The table will have num_vals
+ // elements, and num_cols of those elements will be displayed per row.
+ void olc_display_table(SOCKET_DATA *sock, const char *getName(int val),
+ 		       int num_vals, int num_cols);
+ 
+ #endif // OLC2_H
diff -crN nakedmudv1.5/src/olc2/olc_submenus.h nakedmudv2.0/src/olc2/olc_submenus.h
*** nakedmudv1.5/src/olc2/olc_submenus.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/olc_submenus.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,21 ----
+ #ifndef OLC_SUBMENUS_H
+ #define OLC_SUBMENUS_H
+ //*****************************************************************************
+ //
+ // olc_submenus.h
+ //
+ // There's some OLC editors that will only ever be called from within another
+ // olc editor (e.g. the extra description editor inside the room editor). They
+ // may need to be called by multiple editors (e.g. extra descs in rooms, and
+ // for objects), so we have to give them access to all of the olc-related
+ // functions. That's what this header provides.
+ //
+ //*****************************************************************************
+ 
+ // extra description sets
+ void edesc_set_menu   (SOCKET_DATA *sock, EDESC_SET *set);
+ bool edesc_set_parser (SOCKET_DATA *sock, EDESC_SET *set, int choice,
+ 		       const char *arg);
+ int  edesc_set_chooser(SOCKET_DATA *sock, char option, EDESC_SET *set);
+ 
+ #endif // OLC_SUBMENUS_H
diff -crN nakedmudv1.5/src/olc2/redit.c nakedmudv2.0/src/olc2/redit.c
*** nakedmudv1.5/src/olc2/redit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/redit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,668 ----
+ //*****************************************************************************
+ //
+ // redit.c
+ //
+ // redit (room edit) is a utility to allow builders to edit rooms within the
+ // game. Contains the functions for editing datastructures specific to rooms
+ // (rooms, exits, room resets).
+ //
+ //*****************************************************************************
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "../world.h"
+ #include "../zone.h"
+ #include "../room.h"
+ #include "../exit.h"
+ #include "../room_reset.h"
+ #include "../object.h"
+ 
+ #include "olc.h"
+ #include "olc_submenus.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "../scripts/script.h"
+ #include "../editor/editor.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // optional modules
+ //*****************************************************************************
+ #ifdef MODULE_TIME
+ #include "../time/mudtime.h"
+ #endif
+ 
+ 
+ 
+ //*****************************************************************************
+ // functions for printing room reset data
+ //*****************************************************************************
+ 
+ // the resedit olc needs these declared
+ void rrledit_menu(SOCKET_DATA *sock, LIST *list);
+ int  rrledit_chooser(SOCKET_DATA *sock, LIST *list, char option);
+ bool rrledit_parser(SOCKET_DATA *sock, LIST *list, int choice, const char *arg);
+ 
+ const char *write_reset_arg(int type, const char *arg) {
+   static char buf[SMALL_BUFFER];
+   OBJ_DATA *obj  = worldGetObj(gameworld, atoi(arg));
+   CHAR_DATA *mob = worldGetMob(gameworld, atoi(arg));
+   int pos        = atoi(arg);
+   switch(type) { 
+   case RESET_LOAD_OBJECT:
+     sprintf(buf, "load %s", (obj ? objGetName(obj) : "{RNOTHING{c"));
+     break;
+   case RESET_LOAD_MOBILE:
+     sprintf(buf, "load %s", (mob ? charGetName(mob) : "{RNOBODY{c"));
+     break;
+   case RESET_POSITION:
+     sprintf(buf, "change position to %s", 
+ 	    (pos < 0 || pos >= NUM_POSITIONS ? "{RNOTHING{c":posGetName(pos)));
+     break;
+   case RESET_FIND_MOBILE:
+     sprintf(buf, "find %s", (mob ? charGetName(mob) : "{RNOBODY{c"));
+     break;
+   case RESET_FIND_OBJECT:
+     sprintf(buf, "find %s", (obj ? objGetName(obj) : "{RNOTHING{c"));
+     break;
+   case RESET_PURGE_MOBILE:
+     sprintf(buf, "purge %s", (mob ? charGetName(mob) : "{RNOBODY{c"));
+     break;
+   case RESET_PURGE_OBJECT:
+     sprintf(buf, "purge %s", (obj ? objGetName(obj) : "{RNOTHING{c"));
+     break;
+   case RESET_OPEN:
+     sprintf(buf, "open/unlock dir %s or container", arg);
+     break;
+   case RESET_CLOSE:
+     sprintf(buf, "close/unlock dir %s or container", arg);
+     break;
+   case RESET_LOCK:
+     sprintf(buf, "close/lock dir %s or container", arg);
+     break;
+   default:
+     sprintf(buf, "UNFINISHED OLC");
+     break;
+   }
+   return buf;
+ }
+ 
+ int indent_line(char *buf, int buflen, int indent) {
+   if(indent > 0) {
+     char fmt[20];
+     sprintf(fmt, "%%-%ds", indent);
+     return snprintf(buf, buflen, fmt, " ");
+   }
+   return 0;
+ }
+ 
+ int write_reset_buf(RESET_DATA *reset, char *buf, int buflen, int indent,
+ 		    bool indent_first) {
+   int i = 0;
+ 
+   if(indent_first)
+     i += indent_line(buf, buflen, indent);
+   i += snprintf(buf+i, buflen-i,
+ 		"{c%s with {w%d%% {cchance {w%d {ctime%s (max {w%d{c, rm. {w%d{c)\r\n",
+ 		write_reset_arg(resetGetType(reset), resetGetArg(reset)),
+ 		resetGetChance(reset),
+ 		resetGetTimes(reset),
+ 		(resetGetTimes(reset) == 1 ? "" : "s"),
+ 		resetGetMax(reset),
+ 		resetGetRoomMax(reset));
+ 
+   // if we've got ONs, then print 'em all out as well
+   if(listSize(resetGetOn(reset)) > 0) {
+     i += indent_line(buf+i, buflen-i, indent);
+     i += snprintf(buf+i, buflen-i, "{yon it: \r\n");
+     LIST_ITERATOR *list_i = newListIterator(resetGetOn(reset));
+     RESET_DATA     *next  = NULL;
+     ITERATE_LIST(next, list_i)
+       i += write_reset_buf(next, buf+i, buflen-i, indent+2, TRUE);
+     deleteListIterator(list_i);
+   }
+ 
+   // if we've got INs, then print 'em all out as well
+   if(listSize(resetGetIn(reset)) > 0) {
+     i += indent_line(buf+i, buflen-i, indent);
+     i += snprintf(buf+i, buflen-i, "{yin it: \r\n");
+     LIST_ITERATOR *list_i = newListIterator(resetGetIn(reset));
+     RESET_DATA     *next  = NULL;
+     ITERATE_LIST(next, list_i)
+       i += write_reset_buf(next, buf+i, buflen-i, indent+2, TRUE);
+     deleteListIterator(list_i);
+   }
+ 
+   // if we've got THENs, print 'em all out as well
+   if(listSize(resetGetThen(reset)) > 0) {
+     i += indent_line(buf+i, buflen-i, indent);
+     i += snprintf(buf+i, buflen-i, "{ywhen successful, also: \r\n");
+     LIST_ITERATOR *list_i = newListIterator(resetGetThen(reset));
+     RESET_DATA     *next  = NULL;
+     ITERATE_LIST(next, list_i)
+       i += write_reset_buf(next, buf+i, buflen-i, indent+2, TRUE);
+     deleteListIterator(list_i);
+   }
+   return i;
+ }
+ 
+ const char *write_reset(RESET_DATA *reset, int indent, bool indent_first) {
+   static char buf[MAX_BUFFER];
+   write_reset_buf(reset, buf, MAX_BUFFER, indent, indent_first);
+   return buf;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // room reset editing
+ //*****************************************************************************
+ #define RESEDIT_TYPE       1
+ #define RESEDIT_TIMES      2
+ #define RESEDIT_CHANCE     3
+ #define RESEDIT_MAX        4
+ #define RESEDIT_ROOM_MAX   5
+ #define RESEDIT_ARGUMENT   6
+ 
+ void resedit_menu(SOCKET_DATA *sock, RESET_DATA *data) {
+   send_to_socket(sock,
+ 		 "{g1) Type:       {c%s\r\n"
+ 		 "{g2) Times:      {c%d\r\n"
+ 		 "{g3) Chance:     {c%d\r\n"
+ 		 "{g4) Max:        {c%d\r\n"
+ 		 "{g5) Room Max:   {c%d\r\n"
+ 		 "{g6) Argument:   {c%s\r\n"
+ 		 "{g7) Load on menu\r\n"
+ 		 "{g8) Load in menu\r\n"
+ 		 "{g9) Success menu\r\n"
+ 		 "---------------------------------------------------------\r\n"
+ 		 "%s",
+ 		 resetTypeGetName(resetGetType(data)),
+ 		 resetGetTimes(data),
+ 		 resetGetChance(data),
+ 		 resetGetMax(data),
+ 		 resetGetRoomMax(data),
+ 		 resetGetArg(data),
+ 		 write_reset(data, 0, FALSE)
+ 		 );
+ }
+ 
+ int resedit_chooser(SOCKET_DATA *sock, RESET_DATA *data, char option) {
+   switch(toupper(option)) {
+   case '1':
+     olc_display_table(sock, resetTypeGetName, NUM_RESETS, 1);
+     return RESEDIT_TYPE;
+   case '2':
+     text_to_buffer(sock, "How many times should the reset execute: ");
+     return RESEDIT_TIMES;
+   case '3':
+     text_to_buffer(sock, "What is the success chance of the reset: ");
+     return RESEDIT_CHANCE;
+   case '4':
+     text_to_buffer(sock, "What is the max that can exit in game (0 = no limit): ");
+     return RESEDIT_MAX;
+   case '5':
+     text_to_buffer(sock, "What is the max that can exit in room (0 = no limit): ");
+     return RESEDIT_ROOM_MAX;
+   case '6':
+     text_to_buffer(sock, "What is the reset argument (i.e. obj vnum, direction, etc...): ");
+     return RESEDIT_ARGUMENT;
+   case '7':
+     do_olc(sock, rrledit_menu, rrledit_chooser, rrledit_parser, 
+ 	   NULL, NULL, NULL, NULL, resetGetOn(data));
+     return MENU_NOCHOICE;
+   case '8':
+     do_olc(sock, rrledit_menu, rrledit_chooser, rrledit_parser, 
+ 	   NULL, NULL, NULL, NULL, resetGetIn(data));
+     return MENU_NOCHOICE;
+   case '9':
+     do_olc(sock, rrledit_menu, rrledit_chooser, rrledit_parser, 
+ 	   NULL, NULL, NULL, NULL, resetGetThen(data));
+     return MENU_NOCHOICE;
+   default: return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool resedit_parser(SOCKET_DATA *sock, RESET_DATA *data, int choice, 
+ 		    const char *arg){
+   switch(choice) {
+   case RESEDIT_TYPE: {
+     int type = atoi(arg);
+     if(type < 0 || type >= NUM_RESETS)
+       return FALSE;
+     resetSetType(data, type);
+     // set all of the data to defaults
+     resetSetArg(data, "");
+     resetSetChance(data, 100);
+     resetSetMax(data, 0);
+     resetSetRoomMax(data, 0);
+     resetSetTimes(data, 1);
+     return TRUE;
+   }
+ 
+   case RESEDIT_TIMES: {
+     int times = atoi(arg);
+     if(times < 1)
+       return FALSE;
+     resetSetTimes(data, times);
+     return TRUE;
+   }
+ 
+   case RESEDIT_CHANCE: {
+     int chance = atoi(arg);
+     if(chance < 1 || chance > 100)
+       return FALSE;
+     resetSetChance(data, chance);
+     return TRUE;
+   }
+ 
+   case RESEDIT_MAX: {
+     int max = atoi(arg);
+     if(max < 0)
+       return FALSE;
+     resetSetMax(data, max);
+     return TRUE;
+   }
+ 
+   case RESEDIT_ROOM_MAX: {
+     int rmax = atoi(arg);
+     if(rmax < 0)
+       return FALSE;
+     resetSetRoomMax(data, rmax);
+     return TRUE;
+   }
+ 
+   case RESEDIT_ARGUMENT:
+     resetSetArg(data, arg);
+     return TRUE;
+ 
+   default: return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // room reset list editing
+ //*****************************************************************************
+ #define RRLEDIT_EDIT       1
+ #define RRLEDIT_DELETE     2
+ 
+ 
+ void rrledit_menu(SOCKET_DATA *sock, LIST *list) {
+   LIST_ITERATOR *res_i = newListIterator(list);
+   RESET_DATA    *reset = NULL;
+   int count = 0;
+ 
+   send_to_socket(sock,
+ 		 "{wCurrent resets:\r\n");
+   ITERATE_LIST(reset, res_i) {
+     send_to_socket(sock, " {g%2d) %s", count, write_reset(reset, 5, FALSE));
+     count++;
+   }
+   deleteListIterator(res_i);
+ 
+   send_to_socket(sock, "\r\n"
+ 		 "  {gE) edit entry\r\n"
+ 		 "  {gN) new entry\r\n"
+ 		 "  {gD) delete entry\r\n"
+ 		 );
+ }
+ 
+ 
+ int rrledit_chooser(SOCKET_DATA *sock, LIST *list, char option) {
+   switch(toupper(option)) {
+   case 'N': {
+     RESET_DATA *data = newReset();
+     listQueue(list, data);
+     do_olc(sock, resedit_menu, resedit_chooser, resedit_parser, 
+ 	   NULL, NULL, NULL, NULL, data);
+     return MENU_NOCHOICE;
+   }
+   case 'E':
+     text_to_buffer(sock, "Which entry do you want to edit: ");
+     return RRLEDIT_EDIT;
+   case 'D':
+     text_to_buffer(sock, "Which entry do you want to delete: ");
+     return RRLEDIT_DELETE;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ 
+ bool rrledit_parser(SOCKET_DATA *sock, LIST *list, int choice, const char *arg){
+   switch(choice) {
+   case RRLEDIT_EDIT: {
+     RESET_DATA *reset = NULL;
+     if(!isdigit(*arg) || (reset = listGet(list, atoi(arg))) == NULL)
+       return FALSE;
+     do_olc(sock, resedit_menu, resedit_chooser, resedit_parser, 
+ 	   NULL, NULL, NULL, NULL, reset);
+     return TRUE;
+   }
+   case RRLEDIT_DELETE: {
+     RESET_DATA *reset = NULL;
+     if(!isdigit(*arg) || (reset = listGet(list, atoi(arg))) == NULL)
+       return FALSE;
+     listRemove(list, reset);
+     deleteReset(reset);
+     return TRUE;
+   }
+   default: return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // exit editing functions
+ //*****************************************************************************
+ #define EXEDIT_KEYWORDS    1
+ #define EXEDIT_LEAVE       2
+ #define EXEDIT_ENTER       3
+ #define EXEDIT_TO          4
+ #define EXEDIT_KEY         5
+ #define EXEDIT_PICK        6
+ #define EXEDIT_SPOT        7
+ #define EXEDIT_NAME        8
+ 
+ void exedit_menu(SOCKET_DATA *sock, EXIT_DATA *exit) {
+   send_to_socket(sock,
+ 		 "{g1) Door name\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g2) Door keywords\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g3) Leave message\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g4) Enter message\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g5) Description\r\n"
+ 		 "{c%s\r\n"
+ 		 "{g6) Exits to:   {y[{c%6d{y]\r\n"
+ 		 "{g7) Closable:   {y[{c%6s{y]\r\n"
+ 		 "{g8) Key vnum:   {y[{c%6d{y]\r\n"
+ 		 "{g9) Pick diff:  {y[{c%6d{y]\r\n"
+ 		 "{g0) Spot diff:  {y[{c%6d{y]\r\n",
+ 		 (*exitGetName(exit) ? exitGetName(exit) : "<NONE>"),
+ 		 (*exitGetKeywords(exit) ? exitGetKeywords(exit) : "<NONE>"),
+ 		 (*exitGetSpecLeave(exit) ? exitGetSpecLeave(exit):"<DEFAULT>"),
+ 		 (*exitGetSpecEnter(exit) ? exitGetSpecEnter(exit):"<DEFAULT>"),
+ 		 exitGetDesc(exit),
+ 		 exitGetTo(exit),
+ 		 (exitIsClosable(exit) ? "Yes" : "No" ),
+ 		 exitGetKey(exit),
+ 		 exitGetPickLev(exit),
+ 		 exitGetHidden(exit)
+ 		 );
+ }
+ 
+ int exedit_chooser(SOCKET_DATA *sock, EXIT_DATA *exit, char option) {
+   switch(option) {
+   case '1':
+     text_to_buffer(sock, "Enter a new name: ");
+     return EXEDIT_NAME;
+   case '2':
+     text_to_buffer(sock, "Enter a new list of keywords: ");
+     return EXEDIT_KEYWORDS;
+   case '3':
+     text_to_buffer(sock, "Enter a new leave message: ");
+     return EXEDIT_LEAVE;
+   case '4':
+     text_to_buffer(sock, "Enter a new enterance message: ");
+     return EXEDIT_ENTER;
+   case '5':
+     socketStartEditor(sock, text_editor, exitGetDescBuffer(exit));
+     return MENU_NOCHOICE;
+   case '6':
+     text_to_buffer(sock, "Enter a new destination: ");
+     return EXEDIT_TO;
+   case '7':
+     exitSetClosable(exit, (exitIsClosable(exit) ? FALSE : TRUE));
+     return MENU_NOCHOICE;
+   case '8':
+     text_to_buffer(sock, "Enter a new key vnum: ");
+     return EXEDIT_KEY;
+   case '9':
+     text_to_buffer(sock, "Enter a new lock difficulty: ");
+     return EXEDIT_PICK;
+   case '0':
+     text_to_buffer(sock, "Enter a new spot difficulty: ");
+     return EXEDIT_SPOT;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool exedit_parser(SOCKET_DATA *sock, EXIT_DATA *exit, int choice, 
+ 		   const char *arg) {
+   switch(choice) {
+   case EXEDIT_NAME:
+     exitSetName(exit, arg);
+     return TRUE;
+   case EXEDIT_KEYWORDS:
+     exitSetKeywords(exit, arg);
+     return TRUE;
+   case EXEDIT_LEAVE:
+     exitSetSpecLeave(exit, arg);
+     return TRUE;
+   case EXEDIT_ENTER:
+     exitSetSpecEnter(exit, arg);
+     return TRUE;
+   case EXEDIT_TO:
+     exitSetTo(exit, MAX(NOWHERE, atoi(arg)));
+     return TRUE;
+   case EXEDIT_KEY:
+     exitSetKey(exit, MAX(NOTHING, atoi(arg)));
+     return TRUE;
+   case EXEDIT_PICK:
+     exitSetPickLev(exit, MAX(0, atoi(arg)));
+     return TRUE;
+   case EXEDIT_SPOT:
+     exitSetHidden(exit, MAX(0, atoi(arg)));
+     return TRUE;
+   default:
+     return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // room editing functions
+ //*****************************************************************************
+ 
+ // the different fields of a room we can edit
+ #define REDIT_NAME       1
+ #define REDIT_TERRAIN    2
+ #define REDIT_EXIT       3
+ #define REDIT_FILL_EXIT  4
+ 
+ 
+ //
+ // Display the exits the socket can edit
+ //
+ void redit_exit_menu(SOCKET_DATA *sock, ROOM_DATA *room) {
+   int i;
+ 
+   // normal exits first
+   for(i = 0; i < NUM_DIRS; i++) {
+     EXIT_DATA *exit = roomGetExit(room, i);
+     send_to_socket(sock, "   {g%-10s : {y[%s%6d{y]%s",
+ 		   dirGetName(i), 
+ 		   (exit ? "{c" : "{y" ),
+ 		   (exit ? exitGetTo(exit) : -1),
+ 		   (!(i % 2) ? "   " : "\r\n"));
+   }
+ 
+   // now special exits
+   int num_spec_exits = 0;
+   const char **room_names = roomGetExitNames(room, &num_spec_exits);
+   for(i = 0; i < num_spec_exits; i++) {
+     EXIT_DATA *exit = roomGetExitSpecial(room, room_names[i]);
+     send_to_socket(sock, "   {g%-10s : {y[{c%6d{y]%s",
+ 		   room_names[i],
+ 		   exitGetTo(exit),
+ 		   (!(i % 2) ? "   " : "\r\n"));
+   }
+ 
+   // make sure we've printed the last newline if needed
+   if(i % 2 == 1)
+     send_to_socket(sock, "\r\n");
+ 
+   // clean up our mess
+   free(room_names);
+ }
+ 
+ 
+ void redit_menu(SOCKET_DATA *sock, ROOM_DATA *room) {
+   send_to_socket(sock,
+ 		 "{y[{c%d{y]\r\n"
+ 		 "{g1) Name\r\n{c%s\r\n"
+ 		 "{g2) Description\r\n{c%s\r\n"
+ #ifdef MODULE_TIME
+ 		 "{g3) Night description (optional)\r\n{c%s\r\n"
+ #endif
+ 		 "{gT) Terrain type {y[{c%s{y]\r\n"
+ 		 "{gX) Extra descriptions menu\r\n"
+ 		 "{gR) Room reset menu\r\n"
+ 		 "{gS) Script menu\r\n"
+ 		 "{gE) Edit exit\r\n"
+ 		 "{gF) Fill exit\r\n"
+ 		 ,
+ 		 roomGetVnum(room), roomGetName(room), roomGetDesc(room),
+ #ifdef MODULE_TIME
+ 		 roomGetNightDesc(room),
+ #endif
+ 		 terrainGetName(roomGetTerrain(room)));
+   redit_exit_menu(sock, room);
+ }
+ 
+ 
+ int redit_chooser(SOCKET_DATA *sock, ROOM_DATA *room, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter a new room name: ");
+     return REDIT_NAME;
+   case '2':
+     text_to_buffer(sock, "Enter a new room description:\r\n");
+     socketStartEditor(sock, text_editor, roomGetDescBuffer(room));
+     return MENU_NOCHOICE;
+ #ifdef MODULE_TIME
+   case '3':
+     text_to_buffer(sock, "Enter a new night description:\r\n");
+     socketStartEditor(sock, text_editor, roomGetNightDescBuffer(room));
+     return MENU_NOCHOICE;
+ #endif
+   case 'T':
+     olc_display_table(sock, terrainGetName, NUM_TERRAINS, 3);
+     return REDIT_TERRAIN;
+   case 'F':
+     text_to_buffer(sock, "What is the name of the exit you wish to fill: ");
+     return REDIT_FILL_EXIT;
+   case 'E':
+     text_to_buffer(sock, "What is the name of the exit you wish to edit: ");
+     return REDIT_EXIT;
+   case 'X':
+     do_olc(sock, edesc_set_menu, edesc_set_chooser, edesc_set_parser, NULL,NULL,
+ 	   NULL, NULL, roomGetEdescs(room));
+     return MENU_NOCHOICE;
+   case 'R':
+     do_olc(sock, rrledit_menu, rrledit_chooser, rrledit_parser, 
+ 	   NULL, NULL, NULL, NULL, roomGetResets(room));
+     return MENU_NOCHOICE;
+   case 'S':
+     do_olc(sock, ssedit_menu, ssedit_chooser, ssedit_parser,
+ 	   NULL, NULL, NULL, NULL, roomGetScripts(room));
+     return MENU_NOCHOICE;
+     
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ 
+ bool redit_parser(SOCKET_DATA *sock, ROOM_DATA *room, int choice, 
+ 		  const char *arg) {
+   switch(choice) {
+   case REDIT_NAME:
+     roomSetName(room, arg);
+     return TRUE;
+   case REDIT_TERRAIN: {
+     int val = atoi(arg);
+     if(val < 0 || val >= NUM_TERRAINS)
+       return FALSE;
+     roomSetTerrain(room, val);
+     return TRUE;
+   }
+   case REDIT_FILL_EXIT: {
+     int dir = dirGetNum(arg);
+     if(dir != DIR_NONE)
+       roomSetExit(room, dir, NULL);
+     else
+       roomSetExitSpecial(room, arg, NULL);
+     return TRUE;
+   }
+ 
+   case REDIT_EXIT: {
+     EXIT_DATA *exit = NULL;
+     int dir = dirGetNum(arg);
+     // find the exit. Create a new one if none exists
+     if(dir != DIR_NONE) {
+       if((exit = roomGetExit(room, dir)) == NULL)
+ 	roomSetExit(room, dir, (exit = newExit()));
+     }
+     else if((exit = roomGetExitSpecial(room, arg)) == NULL)
+       roomSetExitSpecial(room, arg, (exit = newExit()));
+ 
+     // enter the exit editor
+     do_olc(sock, exedit_menu, exedit_chooser, exedit_parser, NULL, NULL,
+ 	   NULL, NULL, exit);
+     return TRUE;
+   }
+     
+   default:
+     return FALSE;
+   }
+ }
+ 
+ 
+ COMMAND(cmd_redit) {
+   ZONE_DATA *zone;
+   ROOM_DATA *room;
+   room_vnum vnum;
+ 
+   // if no argument is supplied, default to the current room
+   if(!arg || !*arg)
+     vnum = roomGetVnum(charGetRoom(ch));
+   else
+     vnum = atoi(arg);
+ 
+   // make sure there is a corresponding zone ...
+   if((zone = worldZoneBounding(gameworld, vnum)) == NULL)
+     send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
+   else if(!canEditZone(zone, ch))
+     send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
+   else {
+     // find the room
+     room = zoneGetRoom(zone, vnum);
+ 
+     // make our room
+     if(room == NULL) {
+       room = newRoom();
+       roomSetVnum(room, vnum);
+       roomSetName(room, "An Unfinished Room");
+       roomSetDesc(room, "   You are in an unfinished room.\r\n");
+       zoneAddRoom(zone, room);
+     }
+ 
+     do_olc(charGetSocket(ch), redit_menu, redit_chooser, redit_parser,
+ 	   roomCopy, roomCopyTo, deleteRoom, save_world, room);
+   }
+ }
diff -crN nakedmudv1.5/src/olc2/redit.d nakedmudv2.0/src/olc2/redit.d
*** nakedmudv1.5/src/olc2/redit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/redit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ olc2/redit.d olc2/redit.o: olc2/redit.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h character.h \
+   world.h zone.h room.h exit.h room_reset.h object.h olc2/olc.h \
+   olc2/olc_submenus.h scripts/script.h editor/editor.h time/mudtime.h
diff -crN nakedmudv1.5/src/olc2/zedit.c nakedmudv2.0/src/olc2/zedit.c
*** nakedmudv1.5/src/olc2/zedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/zedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,133 ----
+ //*****************************************************************************
+ //
+ // zedit.c
+ //
+ // zedit (zone edit) is a utility to allow builders to edit zone data within the
+ // game. Contains all the functions for editing zones.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "../room.h"
+ #include "../world.h"
+ #include "../zone.h"
+ #include "../editor/editor.h"
+ 
+ #include "olc.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // room editing functions
+ //*****************************************************************************
+ // the different fields of a room we can edit
+ #define ZEDIT_NAME       1
+ #define ZEDIT_EDITORS    2
+ #define ZEDIT_TIMER      3
+ 
+ void zedit_menu(SOCKET_DATA *sock, ZONE_DATA *zone) {
+   send_to_socket(sock,
+ 		 "{y[{c%d{y]\r\n"
+ 		 "{g1) Name\r\n{c%s\r\n"
+ 		 "{g2) Editors\r\n{c%s\r\n"
+ 		 "{g3) Reset timer: {c%d{g min%s\r\n"
+ 		 "{g4) Description\r\n{c%s\r\n"
+ 		 ,
+ 		 zoneGetVnum(zone), zoneGetName(zone), zoneGetEditors(zone),
+ 		 zoneGetPulseTimer(zone), (zoneGetPulseTimer(zone)==1 ? "":"s"),
+ 		 zoneGetDesc(zone));
+ }
+ 
+ 
+ int zedit_chooser(SOCKET_DATA *sock, ZONE_DATA *zone, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter a new zone name: ");
+     return ZEDIT_NAME;
+   case '2':
+     text_to_buffer(sock, "Enter a new list of editors: ");
+     return ZEDIT_EDITORS;
+   case '3':
+     text_to_buffer(sock, "Enter a new reset timer: ");
+     return ZEDIT_TIMER;
+   case '4':
+     text_to_buffer(sock, "Enter a new description:\r\n");
+     socketStartEditor(sock, text_editor, zoneGetDescBuffer(zone));
+     return MENU_NOCHOICE;
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool zedit_parser(SOCKET_DATA *sock, ZONE_DATA *zone, int choice, 
+ 		  const char *arg) {
+   switch(choice) {
+   case ZEDIT_NAME:
+     zoneSetName(zone, arg);
+     return TRUE;
+   case ZEDIT_EDITORS:
+     zoneSetEditors(zone, arg);
+     return TRUE;
+   case ZEDIT_TIMER:
+     zoneSetPulseTimer(zone, MAX(-1, atoi(arg)));
+     return TRUE;
+   default:
+     return FALSE;
+   }
+ }
+ 
+ 
+ COMMAND(cmd_zedit) {
+   // we want to create a new zone?
+   if(!strncasecmp(arg, "new ", 4)) {
+     zone_vnum vnum = 0;
+     room_vnum min = 0, max = 0;
+ 
+     // scan for the parameters
+     sscanf(arg+4, "%d %d %d", &vnum, &min, &max);
+ 
+     if(worldGetZone(gameworld, vnum))
+       send_to_char(ch, "A zone already exists with that vnum.\r\n");
+     else if(worldZoneBounding(gameworld, min) || worldZoneBounding(gameworld, max))
+       send_to_char(ch, "There is already a zone bounding that vnum range.\r\n");
+     else {
+       ZONE_DATA *zone = newZone(vnum, min, max);
+       char buf[MAX_BUFFER];
+       sprintf(buf, "%s's zone", charGetName(ch));
+       zoneSetName(zone, buf);
+       sprintf(buf, "A new zone created by %s\r\n", charGetName(ch));
+       zoneSetDesc(zone, buf);
+       zoneSetEditors(zone, charGetName(ch));
+ 
+       worldPutZone(gameworld, zone);
+       send_to_char(ch, "You create a new zone (vnum %d).\r\n", vnum);
+ 
+       // save the changes... this will get costly as our world gets bigger.
+       // But that should be alright once we make zone saving a bit smarter
+       worldSave(gameworld, WORLD_PATH);
+     }
+   }
+ 
+   // we want to edit a preexisting zone
+   else {
+     ZONE_DATA *zone = NULL;
+     zone_vnum vnum   = (!*arg ? 
+ 			zoneGetVnum(worldZoneBounding(gameworld, roomGetVnum(charGetRoom(ch)))) : atoi(arg));
+  
+     // make sure there is a corresponding zone ...
+     if((zone = worldGetZone(gameworld, vnum)) == NULL)
+       send_to_char(ch, 
+ 		   "No such zone exists. To create a new one, use "
+ 		   "zedit new <vnum> <min> <max>\r\n");
+     else if(!canEditZone(zone, ch))
+       send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
+     else {
+       do_olc(charGetSocket(ch), zedit_menu, zedit_chooser, zedit_parser,
+ 	     zoneCopy, zoneCopyTo, deleteZone, save_world,
+ 	     worldZoneBounding(gameworld, roomGetVnum(charGetRoom(ch))));
+     }
+   }
+ }
diff -crN nakedmudv1.5/src/olc2/zedit.d nakedmudv2.0/src/olc2/zedit.d
*** nakedmudv1.5/src/olc2/zedit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/olc2/zedit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ olc2/zedit.d olc2/zedit.o: olc2/zedit.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h character.h \
+   room.h world.h zone.h editor/editor.h olc2/olc.h
diff -crN nakedmudv1.5/src/property_table.c nakedmudv2.0/src/property_table.c
*** nakedmudv1.5/src/property_table.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/property_table.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 44,50 ****
  // Find the bucket the key belongs to
  //
  int find_bucket(int key, int num_buckets) {
-   if(key < 0) key *= -1;
    // simple for now: just take the modulo
    return key % num_buckets;
  };
--- 44,49 ----
diff -crN nakedmudv1.5/src/property_table.d nakedmudv2.0/src/property_table.d
*** nakedmudv1.5/src/property_table.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/property_table.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ property_table.d property_table.o: property_table.c mud.h wrapsock.h property_table.h \
+   list.h map.h hashtable.h set.h buffer.h bitvector.h utils.h
diff -crN nakedmudv1.5/src/property_table.h nakedmudv2.0/src/property_table.h
*** nakedmudv1.5/src/property_table.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/property_table.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 18,23 ****
--- 18,27 ----
  //
  //*****************************************************************************
  
+ typedef struct property_table             PROPERTY_TABLE;
+ typedef struct property_table_iterator    PROPERTY_TABLE_ITERATOR;
+ 
+ 
  //
  // Create a new property table with the specified number of buckets
  // (more buckets = faster lookup, but more memory). The key function must
diff -crN nakedmudv1.5/src/races.d nakedmudv2.0/src/races.d
*** nakedmudv1.5/src/races.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/races.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ races.d races.o: races.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h body.h utils.h races.h
diff -crN nakedmudv1.5/src/room.c nakedmudv2.0/src/room.c
*** nakedmudv1.5/src/room.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/room.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 23,31 ****
  #include "room.h"
  
  
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
! #endif
  
  
  // how many special exits do we expect to have?
--- 23,34 ----
  #include "room.h"
  
  
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
! 
  
  
  // how many special exits do we expect to have?
***************
*** 38,44 ****
  
    int         terrain;           // what kind of terrain do we have?
    char       *name;              // what is the name of our room?
!   char       *desc;              // our description
  
    EDESC_SET  *edescs;            // the extra descriptions in the room
    EXIT_DATA **exits;             // the normal exists
--- 41,47 ----
  
    int         terrain;           // what kind of terrain do we have?
    char       *name;              // what is the name of our room?
!   BUFFER     *desc;              // our description
  
    EDESC_SET  *edescs;            // the extra descriptions in the room
    EXIT_DATA **exits;             // the normal exists
***************
*** 64,70 ****
    room->vnum = NOWHERE;
  
    room->name      = strdup("");
!   room->desc      = strdup("");
  
  
    room->terrain = TERRAIN_INDOORS;
--- 67,73 ----
    room->vnum = NOWHERE;
  
    room->name      = strdup("");
!   room->desc      = newBuffer(1);
  
  
    room->terrain = TERRAIN_INDOORS;
***************
*** 117,123 ****
  
    // delete strings
    if(room->name)        free(room->name);
!   if(room->desc)        free(room->desc);
    deleteAuxiliaryData(room->auxiliary_data);
  
    free(room);
--- 120,126 ----
  
    // delete strings
    if(room->name)        free(room->name);
!   if(room->desc)        deleteBuffer(room->desc);
    deleteAuxiliaryData(room->auxiliary_data);
  
    free(room);
***************
*** 127,133 ****
  STORAGE_SET *roomStore(ROOM_DATA *room) {
    STORAGE_SET *set = new_storage_set();
    store_string(set, "name",    room->name);
!   store_string(set, "desc",    room->desc);
    store_int   (set, "vnum",    room->vnum);
    store_int   (set, "terrain", room->terrain);
    store_set   (set, "edescs",  edescSetStore(room->edescs));
--- 130,136 ----
  STORAGE_SET *roomStore(ROOM_DATA *room) {
    STORAGE_SET *set = new_storage_set();
    store_string(set, "name",    room->name);
!   store_string(set, "desc",    bufferString(room->desc));
    store_int   (set, "vnum",    room->vnum);
    store_int   (set, "terrain", room->terrain);
    store_set   (set, "edescs",  edescSetStore(room->edescs));
***************
*** 212,218 ****
    roomSetTerrain (to, roomGetTerrain(from));
  
    // set our edescs
!   roomSetEdescs(to, copyEdescSet(from->edescs));
  
    // set our normal exits
    for(i = 0; i < NUM_DIRS; i++)
--- 215,221 ----
    roomSetTerrain (to, roomGetTerrain(from));
  
    // set our edescs
!   roomSetEdescs(to, edescSetCopy(from->edescs));
  
    // set our normal exits
    for(i = 0; i < NUM_DIRS; i++)
***************
*** 275,285 ****
  
  void roomReset(ROOM_DATA *room) {
    resetRunOn(room->reset, room, INITIATOR_ROOM);
- #ifdef MODULE_SCRIPTS
    try_scripts(SCRIPT_TYPE_INIT,
  	      room, SCRIPTOR_ROOM,
  	      NULL, NULL, room, NULL, NULL, 0);
- #endif
  }
  
  
--- 278,286 ----
***************
*** 340,351 ****
  };
  
  const char *roomGetDesc        (const ROOM_DATA *room) {
!   return room->desc;
  };
  
! char      **roomGetDescPtr     (ROOM_DATA *room) {
!   return &(room->desc);
! };
  
  int         roomGetTerrain     (const ROOM_DATA *room) {
    return room->terrain;
--- 341,352 ----
  };
  
  const char *roomGetDesc        (const ROOM_DATA *room) {
!   return bufferString(room->desc);
  };
  
! BUFFER *roomGetDescBuffer(const ROOM_DATA *room) {
!   return room->desc;
! }
  
  int         roomGetTerrain     (const ROOM_DATA *room) {
    return room->terrain;
***************
*** 378,385 ****
  }
  
  const char *roomGetEdesc       (const ROOM_DATA *room, const char *keyword) {
!   EDESC_DATA *edesc = getEdesc(room->edescs, keyword);
!   if(edesc) return getEdescDescription(edesc);
    else return NULL;
  }
  
--- 379,386 ----
  }
  
  const char *roomGetEdesc       (const ROOM_DATA *room, const char *keyword) {
!   EDESC_DATA *edesc = edescSetGet(room->edescs, keyword);
!   if(edesc) return edescSetGetDesc(edesc);
    else return NULL;
  }
  
***************
*** 402,409 ****
  };
  
  void        roomSetDesc (ROOM_DATA *room, const char *desc) {
!   if(room->desc) free(room->desc);
!   room->desc = strdup(desc ? desc : "");
  };
  
  void        roomSetTerrain     (ROOM_DATA *room, int terrain_type) {
--- 403,410 ----
  };
  
  void        roomSetDesc (ROOM_DATA *room, const char *desc) {
!   bufferClear(room->desc);
!   bufferCat(room->desc, (desc ? desc : ""));
  };
  
  void        roomSetTerrain     (ROOM_DATA *room, int terrain_type) {
diff -crN nakedmudv1.5/src/room.d nakedmudv2.0/src/room.d
*** nakedmudv1.5/src/room.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/room.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ room.d room.o: room.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h exit.h extra_descs.h utils.h handler.h \
+   character.h auxiliary.h storage.h room_reset.h room.h scripts/script.h
diff -crN nakedmudv1.5/src/room.h nakedmudv2.0/src/room.h
*** nakedmudv1.5/src/room.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/room.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 118,125 ****
  const char *roomGetName        (const ROOM_DATA *room);
  const char *roomGetDesc        (const ROOM_DATA *room);
  int         roomGetTerrain     (const ROOM_DATA *room);
!  // used for editing room descs with the text editor
! char      **roomGetDescPtr     (ROOM_DATA *room);
  
  EXIT_DATA  *roomGetExit         (const ROOM_DATA *room, int dir);
  EXIT_DATA  *roomGetExitSpecial  (const ROOM_DATA *room, const char *dir);
--- 118,124 ----
  const char *roomGetName        (const ROOM_DATA *room);
  const char *roomGetDesc        (const ROOM_DATA *room);
  int         roomGetTerrain     (const ROOM_DATA *room);
! BUFFER     *roomGetDescBuffer  (const ROOM_DATA *room);
  
  EXIT_DATA  *roomGetExit         (const ROOM_DATA *room, int dir);
  EXIT_DATA  *roomGetExitSpecial  (const ROOM_DATA *room, const char *dir);
diff -crN nakedmudv1.5/src/room_reset.c nakedmudv2.0/src/room_reset.c
*** nakedmudv1.5/src/room_reset.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/room_reset.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 19,28 ****
  #include "object.h"
  #include "exit.h"
  #include "handler.h"
- #include "items.h"
  #include "room_reset.h"
  
  
  struct reset_data {
    int        type; // what kind of reset are we?
    int       times; // how many times should it be executed?
--- 19,37 ----
  #include "object.h"
  #include "exit.h"
  #include "handler.h"
  #include "room_reset.h"
  
  
+ 
+ //*****************************************************************************
+ // mandatory modules
+ //*****************************************************************************
+ #include "items/items.h"
+ #include "items/container.h"
+ #include "items/furniture.h"
+ 
+ 
+ 
  struct reset_data {
    int        type; // what kind of reset are we?
    int       times; // how many times should it be executed?
***************
*** 336,342 ****
      char_to_room(mob, initiator);
    // to a seat
    else if(initiator_type == INITIATOR_ON_OBJ) {
!     if(objGetType(initiator) != ITEM_FURNITURE || objGetRoom(initiator)==NULL) {
        extract_mobile(mob);
        return FALSE;
      }
--- 345,351 ----
      char_to_room(mob, initiator);
    // to a seat
    else if(initiator_type == INITIATOR_ON_OBJ) {
!     if(!objIsType(initiator, "furniture") || objGetRoom(initiator)==NULL) {
        extract_mobile(mob);
        return FALSE;
      }
***************
*** 526,532 ****
      return TRUE;
    }
    else if(initiator_type == INITIATOR_THEN_OBJ) {
!     if(objGetType(initiator) != ITEM_CONTAINER)
        return FALSE;
      containerSetLocked(initiator, locked);
      containerSetClosed(initiator, closed);
--- 535,541 ----
      return TRUE;
    }
    else if(initiator_type == INITIATOR_THEN_OBJ) {
!     if(!objIsType(initiator, "container"))
        return FALSE;
      containerSetLocked(initiator, locked);
      containerSetClosed(initiator, closed);
diff -crN nakedmudv1.5/src/room_reset.d nakedmudv2.0/src/room_reset.d
*** nakedmudv1.5/src/room_reset.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/room_reset.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ room_reset.d room_reset.o: room_reset.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h storage.h room.h world.h \
+   character.h body.h object.h exit.h handler.h room_reset.h items/items.h \
+   items/container.h items/furniture.h
diff -crN nakedmudv1.5/src/save.d nakedmudv2.0/src/save.d
*** nakedmudv1.5/src/save.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/save.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ save.d save.o: save.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h character.h world.h utils.h handler.h body.h \
+   object.h room.h storage.h
diff -crN nakedmudv1.5/src/scripts/pychar.c nakedmudv2.0/src/scripts/pychar.c
*** nakedmudv1.5/src/scripts/pychar.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/scripts/pychar.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 15,21 ****
  #include "../room.h"
  #include "../character.h"
  #include "../object.h"
- #include "../items.h"
  #include "../races.h"
  #include "../handler.h"
  #include "../utils.h"
--- 15,20 ----
***************
*** 25,34 ****
  #include "pyroom.h"
  #include "pyobj.h"
  
! // optional modules
! #ifdef MODULE_CHAR_VARS
  #include "../char_vars/char_vars.h"
! #endif
  
  
  typedef struct {
--- 24,35 ----
  #include "pyroom.h"
  #include "pyobj.h"
  
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "../char_vars/char_vars.h"
! #include "../items/items.h"
  
  
  typedef struct {
***************
*** 115,120 ****
--- 116,147 ----
  
  
  //
+ // Send a newline-tagged message to everyone around the character
+ //
+ static PyObject *
+ PyChar_sendaround(PyChar *self, PyObject *value) {
+   char *mssg = NULL;
+   if (!PyArg_ParseTuple(value, "s", &mssg)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Characters may only be sent strings");
+     return NULL;
+   }
+ 
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch) {
+     send_around_char(ch, FALSE, "%s\r\n", mssg);
+     return Py_BuildValue("i", 1);
+   }
+   else {
+     PyErr_Format(PyExc_TypeError, 
+                     "Tried to send message to nonexistant character, %d.", 
+ 		    self->uid);
+     return NULL;
+   }
+ }
+ 
+ 
+ //
  // make the character perform an action
  //
  static PyObject *
***************
*** 141,147 ****
  }
  
  
- #ifdef MODULE_CHAR_VARS
  //
  // Get the value of a variable stored on the character
  //
--- 168,173 ----
***************
*** 213,233 ****
      return NULL;
    }
  }
- #endif
  
  
  
  static PyMethodDef PyChar_methods[] = {
      {"send", (PyCFunction)PyChar_send, METH_VARARGS,
       "send a message to the character." },
      {"act", (PyCFunction)PyChar_act, METH_VARARGS,
       "make the character perform an action." },
- #ifdef MODULE_CHAR_VARS
      {"getvar", (PyCFunction)PyChar_getvar, METH_VARARGS,
       "get the value of a special variable the character has."},
      {"setvar", (PyCFunction)PyChar_setvar, METH_VARARGS,
       "set the value of a special variable."},
- #endif
      {NULL}  /* Sentinel */
  };
  
--- 239,258 ----
      return NULL;
    }
  }
  
  
  
  static PyMethodDef PyChar_methods[] = {
      {"send", (PyCFunction)PyChar_send, METH_VARARGS,
       "send a message to the character." },
+     {"sendaround", (PyCFunction)PyChar_sendaround, METH_VARARGS,
+      "send a message to everyone around a character."},
      {"act", (PyCFunction)PyChar_act, METH_VARARGS,
       "make the character perform an action." },
      {"getvar", (PyCFunction)PyChar_getvar, METH_VARARGS,
       "get the value of a special variable the character has."},
      {"setvar", (PyCFunction)PyChar_setvar, METH_VARARGS,
       "set the value of a special variable."},
      {NULL}  /* Sentinel */
  };
  
***************
*** 470,476 ****
  		   charGetName(ch));
        return -1;
      }
!     else if(objGetType(obj) == ITEM_FURNITURE) {
        if(charGetFurniture(ch))
  	char_from_furniture(ch);
        char_to_furniture(ch, obj);
--- 495,501 ----
  		   charGetName(ch));
        return -1;
      }
!     else if(objIsType(obj, "furniture")) {
        if(charGetFurniture(ch))
  	char_from_furniture(ch);
        char_to_furniture(ch, obj);
diff -crN nakedmudv1.5/src/scripts/pychar.d nakedmudv2.0/src/scripts/pychar.d
*** nakedmudv1.5/src/scripts/pychar.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/pychar.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ scripts/pychar.d scripts/pychar.o: scripts/pychar.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h world.h room.h character.h \
+   object.h races.h handler.h utils.h scripts/script.h scripts/pychar.h \
+   scripts/pyroom.h scripts/pyobj.h char_vars/char_vars.h items/items.h
diff -crN nakedmudv1.5/src/scripts/pymud.d nakedmudv2.0/src/scripts/pymud.d
*** nakedmudv1.5/src/scripts/pymud.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/pymud.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ scripts/pymud.d scripts/pymud.o: scripts/pymud.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h scripts/script.h \
+   scripts/pyroom.h scripts/pychar.h scripts/pyobj.h
diff -crN nakedmudv1.5/src/scripts/pyobj.d nakedmudv2.0/src/scripts/pyobj.d
*** nakedmudv1.5/src/scripts/pyobj.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/pyobj.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ scripts/pyobj.d scripts/pyobj.o: scripts/pyobj.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h world.h room.h character.h \
+   object.h races.h handler.h utils.h scripts/script.h scripts/pychar.h \
+   scripts/pyroom.h scripts/pyobj.h
diff -crN nakedmudv1.5/src/scripts/pyroom.c nakedmudv2.0/src/scripts/pyroom.c
*** nakedmudv1.5/src/scripts/pyroom.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/scripts/pyroom.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 81,86 ****
--- 81,112 ----
  //*****************************************************************************
  
  //
+ // Send a newline-tagged message to everyone in the room
+ //
+ static PyObject *
+ PyRoom_send(PyRoom *self, PyObject *value) {
+   char *mssg = NULL;
+   if (!PyArg_ParseTuple(value, "s", &mssg)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Characters may only be sent strings");
+     return NULL;
+   }
+ 
+   ROOM_DATA *room = worldGetRoom(gameworld, self->vnum);
+   if(room) {
+     send_to_list(roomGetCharacters(room), "%s\r\n", mssg);
+     return Py_BuildValue("i", 1);
+   }
+   else {
+     PyErr_Format(PyExc_TypeError, 
+                     "Tried to send message to nonexistant room, %d.", 
+ 		    self->vnum);
+     return NULL;
+   }
+ }
+ 
+ 
+ //
  // close a door in the specified direction
  //
  static PyObject *
***************
*** 309,314 ****
--- 335,342 ----
       "lock a door in the specified direction, closing it if it is open." },
      {"unlock", (PyCFunction)PyRoom_unlock, METH_VARARGS,
       "unlocks the door in the specified direction." },
+     {"send", (PyCFunction)PyRoom_send, METH_VARARGS,
+      "send a message to everyone in the room."},
      {NULL}  /* Sentinel */
  };
  
diff -crN nakedmudv1.5/src/scripts/pyroom.d nakedmudv2.0/src/scripts/pyroom.d
*** nakedmudv1.5/src/scripts/pyroom.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/pyroom.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ scripts/pyroom.d scripts/pyroom.o: scripts/pyroom.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h world.h room.h exit.h \
+   character.h races.h handler.h utils.h scripts/script.h scripts/pyroom.h \
+   scripts/pychar.h scripts/pyobj.h
diff -crN nakedmudv1.5/src/scripts/script.c nakedmudv2.0/src/scripts/script.c
*** nakedmudv1.5/src/scripts/script.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/scripts/script.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 10,15 ****
--- 10,19 ----
  // script stuff
  #include <Python.h>
  #include <structmember.h>
+ #include <compile.h>
+ #include <eval.h>
+ #include <node.h>
+ //PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *);
  
  // mud stuff
  #include "../mud.h"
***************
*** 28,33 ****
--- 32,42 ----
  #include "pyobj.h"
  #include "pymud.h"
  
+ // online editor stuff
+ #include "../editor/editor.h"
+ #include "script_editor.h"
+ #include "../olc2/olc.h"
+ 
  
  
  //*****************************************************************************
***************
*** 144,150 ****
    char       *name;
    char       *args;
    int      num_arg;
!   char       *code;
  };
  
  const char *script_type_info[NUM_SCRIPTS] = {
--- 153,159 ----
    char       *name;
    char       *args;
    int      num_arg;
!   BUFFER     *code;
  };
  
  const char *script_type_info[NUM_SCRIPTS] = {
***************
*** 171,197 ****
    script->num_arg = 0;
    script->name    = strdup("");
    script->args    = strdup("");
!   script->code    = strdup("");
    return script;
  }
  
  void         deleteScript(SCRIPT_DATA *script) {
    if(script->name) free(script->name);
    if(script->args) free(script->args);
!   if(script->code) free(script->code);
    free(script);
  }
  
  SCRIPT_DATA *scriptRead(STORAGE_SET *set) {
!   SCRIPT_DATA *script = malloc(sizeof(SCRIPT_DATA));
!   script->vnum    = read_int(set, "vnum");
!   script->type    = read_int(set, "type");
!   script->num_arg = read_int(set, "narg");
!   script->name    = strdup(read_string(set, "name"));
!   script->args    = strdup(read_string(set, "args"));
!   script->code    = strdup(read_string(set, "code"));
    // python chokes on carraige returns. Strip 'em
!   format_script(&script->code, MAX_SCRIPT);
    return script;
  }
  
--- 180,206 ----
    script->num_arg = 0;
    script->name    = strdup("");
    script->args    = strdup("");
!   script->code    = newBuffer(1);
    return script;
  }
  
  void         deleteScript(SCRIPT_DATA *script) {
    if(script->name) free(script->name);
    if(script->args) free(script->args);
!   if(script->code) deleteBuffer(script->code);
    free(script);
  }
  
  SCRIPT_DATA *scriptRead(STORAGE_SET *set) {
!   SCRIPT_DATA *script = newScript();
!   scriptSetVnum(script, read_int(set, "vnum"));
!   scriptSetType(script, read_int(set, "type"));
!   scriptSetNumArg(script, read_int(set, "narg"));
!   scriptSetName(script, read_string(set, "name"));
!   scriptSetArgs(script, read_string(set, "args"));
!   scriptSetCode(script, read_string(set, "code"));
    // python chokes on carraige returns. Strip 'em
!   bufferReplace(script->code, "\r", "", TRUE);
    return script;
  }
  
***************
*** 202,208 ****
    store_int   (set, "narg", script->num_arg);
    store_string(set, "name", script->name);
    store_string(set, "args", script->args);
!   store_string(set, "code", script->code);
    return set;
  }
  
--- 211,217 ----
    store_int   (set, "narg", script->num_arg);
    store_string(set, "name", script->name);
    store_string(set, "args", script->args);
!   store_string(set, "code", bufferString(script->code));
    return set;
  }
  
***************
*** 216,226 ****
  void         scriptCopyTo(SCRIPT_DATA *from, SCRIPT_DATA *to) {
    if(to->name) free(to->name);
    if(to->args) free(to->args);
-   if(to->code) free(to->code);
  
    to->name = strdup(from->name ? from->name : "");
    to->args = strdup(from->args ? from->args : "");
!   to->code = strdup(from->code ? from->code : "");
    
    to->vnum    = from->vnum;
    to->type    = from->type;
--- 225,234 ----
  void         scriptCopyTo(SCRIPT_DATA *from, SCRIPT_DATA *to) {
    if(to->name) free(to->name);
    if(to->args) free(to->args);
  
    to->name = strdup(from->name ? from->name : "");
    to->args = strdup(from->args ? from->args : "");
!   bufferCopyTo(from->code, to->code);
    
    to->vnum    = from->vnum;
    to->type    = from->type;
***************
*** 248,258 ****
  }
  
  const char *scriptGetCode(SCRIPT_DATA *script) {
!   return script->code;
  }
  
! char      **scriptGetCodePtr(SCRIPT_DATA *script) {
!   return &(script->code);
  }
  
  void scriptSetVnum(SCRIPT_DATA *script, script_vnum vnum) {
--- 256,266 ----
  }
  
  const char *scriptGetCode(SCRIPT_DATA *script) {
!   return bufferString(script->code);
  }
  
! BUFFER *scriptGetCodeBuffer(SCRIPT_DATA *script) {
!   return script->code;
  }
  
  void scriptSetVnum(SCRIPT_DATA *script, script_vnum vnum) {
***************
*** 278,285 ****
  }
  
  void scriptSetCode(SCRIPT_DATA *script, const char *code) {
!   if(script->code) free(script->code);
!   script->code = strdup(code ? code : "");
  }
  
  
--- 286,293 ----
  }
  
  void scriptSetCode(SCRIPT_DATA *script, const char *code) {
!   bufferClear(script->code);
!   bufferCat(script->code, code);
  }
  
  
***************
*** 295,318 ****
  // eachother, we could get tossed into an infinite loop. He suggested a
  // check for loop depth before each script is run. If we are deeper than
  // some maximum depth, do not run the script.
- // 
  #define MAX_LOOP_DEPTH   30
  int script_loop_depth   = 0;
  
  
  //
! // Toss a script into Python and let it run
  //
! void start_script(char *script) {
!   script_loop_depth++;
!   // we exited with an error! Log it
!   if(script_loop_depth <= MAX_LOOP_DEPTH && PyRun_SimpleString(script) < 0) {
!     // hmmmm... there's gotta be a way we can get 
!     // the termination messages generated from running
!     log_string("script terminated with an error:\r\n"
! 	       "%s\r\n", script);
    }
-   script_loop_depth--;
  }
  
  
--- 303,436 ----
  // eachother, we could get tossed into an infinite loop. He suggested a
  // check for loop depth before each script is run. If we are deeper than
  // some maximum depth, do not run the script.
  #define MAX_LOOP_DEPTH   30
  int script_loop_depth   = 0;
  
  
  //
! // Python makes it overly complicated (IMO) to get traceback information when
! // running in C. I spent some time hunting around, and came across a lovely
! // site that provided me with this function for getting a traceback of an error.
! // The site that provided this piece of code to me is located here:
! //   http://stompstompstomp.com/weblog/technical/2004-03-29
! char* getPythonTraceback()
! {
!     // Python equivilant:
!     // import traceback, sys
!     // return "".join(traceback.format_exception(sys.exc_type, 
!     //    sys.exc_value, sys.exc_traceback))
! 
!     PyObject *type, *value, *traceback;
!     PyObject *tracebackModule;
!     char *chrRetval;
! 
!     PyErr_Fetch(&type, &value, &traceback);
! 
!     tracebackModule = PyImport_ImportModule("traceback");
!     if (tracebackModule != NULL)
!     {
!         PyObject *tbList, *emptyString, *strRetval;
! 
!         tbList = PyObject_CallMethod(
!             tracebackModule, 
!             "format_exception", 
!             "OOO",
!             type,
!             value == NULL ? Py_None : value,
!             traceback == NULL ? Py_None : traceback);
! 
!         emptyString = PyString_FromString("");
!         strRetval = PyObject_CallMethod(emptyString, "join", 
!             "O", tbList);
! 
!         chrRetval = strdup(PyString_AsString(strRetval));
! 
!         Py_DECREF(tbList);
!         Py_DECREF(emptyString);
!         Py_DECREF(strRetval);
!         Py_DECREF(tracebackModule);
!     }
!     else
!     {
!         chrRetval = strdup("Unable to import traceback module.");
!     }
! 
!     Py_DECREF(type);
!     Py_XDECREF(value);
!     Py_XDECREF(traceback);
! 
!     return chrRetval;
! }
! 
! 
  //
! // Return a new dictionary with all the basic modules imported
! PyObject *newScriptDict() {
!   PyObject* dict = PyDict_New();
!   
!   // Check for __builtins__...
!   if (PyDict_GetItemString(dict, "__builtins__") == NULL) {
!     // Hm... no __builtins__ eh?
!     PyObject* builtinMod = PyImport_ImportModule("__builtin__");
!     if (builtinMod == NULL || 
! 	PyDict_SetItemString(dict, "__builtins__", builtinMod) != 0) {
!       Py_DECREF(dict);
!       Py_XDECREF(dict);
!       // error handling
!       return NULL;
!     }
!     Py_DECREF(builtinMod);
!   }
! 
!   PyObject *sys = PyImport_ImportModule("sys");
!   if(sys != NULL) {
!     PyObject *exit = PyDict_GetItemString(PyModule_GetDict(sys), "exit");
!     if(exit != NULL)
!       PyDict_SetItemString(dict, "exit", exit);
!     Py_DECREF(sys);
!   }
!   
!   // merge all of the mud module contents with our current dict
!   PyObject *mudmod = PyImport_ImportModule("mud");
!   PyDict_Update(dict, PyModule_GetDict(mudmod));
!   Py_DECREF(mudmod);
!   mudmod = PyImport_ImportModule("char");
!   PyDict_Update(dict, PyModule_GetDict(mudmod));
!   Py_DECREF(mudmod);
!   mudmod = PyImport_ImportModule("room");
!   PyDict_Update(dict, PyModule_GetDict(mudmod));
!   Py_DECREF(mudmod);
!   mudmod = PyImport_ImportModule("obj");
!   PyDict_Update(dict, PyModule_GetDict(mudmod));
!   Py_DECREF(mudmod);
! 
!   return dict;
! }
! 
! 
! //
! // Decrement the reference count of the dictionary
! void deleteScriptDict(PyObject *dict) {
!   Py_DECREF(dict);
! }
! 
! 
! //
! // Toss a script into Python and let it run
! void start_script(PyObject *dict, const char *script) {
!   if(script_loop_depth < MAX_LOOP_DEPTH) {
!     script_loop_depth++;
!     PyObject* compileRetval = PyRun_String(script, Py_file_input, dict, dict);
!     script_loop_depth--;
!     // we threw an error and it wasn't an intentional
!     // system exit error. Now print the backtrace
!     if(compileRetval == NULL && PyErr_Occurred() != PyExc_SystemExit) {
!       char *tb = getPythonTraceback();
!       log_string("script terminated with an error:\r\n%s\r\n"
! 		 "\r\nTraceback is:\r\n%s\r\n", script, tb);
!       free(tb);
!     }
    }
  }
  
  
***************
*** 334,339 ****
--- 452,463 ----
  				       newScriptAuxData, deleteScriptAuxData,
  				       scriptAuxDataCopyTo, scriptAuxDataCopy,
  				       scriptAuxDataStore, scriptAuxDataRead));
+ 
+   extern COMMAND(cmd_scedit); // define the command
+   add_cmd("scedit", NULL, cmd_scedit, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_SCRIPTER, FALSE, TRUE);
+ 
+   init_script_editor();
  }
  
  
***************
*** 345,388 ****
  void run_script(const char *script, void *me, int me_type,
  		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, 
  		const char *cmd, const char *arg, int narg) {
!   static char buf[MAX_SCRIPT];
!   *buf = '\0';
!   int i = 0;
! 
!   // cat all of the headers
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "from mud import *\n");
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "from char import *\n");
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "from room import *\n");
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "from obj import *\n");
! 
!   // print the different variables
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "cmd = '%s'\n", (cmd ? cmd : ""));
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "arg = '%s'\n", (arg ? arg : ""));
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "narg = %d\n", narg);
! 
!   // print me
!   if(me_type == SCRIPTOR_CHAR)
!     i += snprintf(buf+i, MAX_SCRIPT - i - 1, "me = Char(%d)\n", charGetUID(me));
!   else if(me_type == SCRIPTOR_OBJ)
!     i += snprintf(buf+i, MAX_SCRIPT - i - 1, "me = Obj(%d)\n", objGetUID(me));
!   else if(me_type == SCRIPTOR_ROOM)
!     i += snprintf(buf+i, MAX_SCRIPT - i - 1, "me = Room(%d)\n",roomGetVnum(me));
! 
!   // print all of the other things involved
!   if(ch)
!     i += snprintf(buf+i, MAX_SCRIPT - i - 1, "ch = Char(%d)\n", charGetUID(ch));
!   if(obj)
!     i += snprintf(buf+i, MAX_SCRIPT - i - 1, "obj = Obj(%d)\n", objGetUID(obj));
!   if(room)
!     i += snprintf(buf+i, MAX_SCRIPT - i - 1, "room = Room(%d)\n", roomGetVnum(room));
!   if(exit)
!     ;
  
!   // cat the code
!   i += snprintf(buf+i, MAX_SCRIPT - i - 1, "%s", script);
  
    // start the script
!   start_script(buf);
  }
  
  
--- 469,522 ----
  void run_script(const char *script, void *me, int me_type,
  		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, 
  		const char *cmd, const char *arg, int narg) {
!   PyObject *dict = newScriptDict();
!   // now, import all of our command and argument variables
!   if(cmd) {
!     PyObject *pycmd = PyString_FromString(cmd);
!     PyDict_SetItemString(dict, "cmd", pycmd);
!     Py_DECREF(pycmd);
!   }
!   if(arg) {
!     PyObject *pyarg = PyString_FromString(arg);
!     PyDict_SetItemString(dict, "arg", pyarg);
!     Py_DECREF(pyarg);
!   }
!   if(TRUE) {
!     PyObject *pynarg = PyInt_FromLong(narg);
!     PyDict_SetItemString(dict, "narg", pynarg);
!     Py_DECREF(pynarg);
!   }
  
!   // now import everyone who is involved
!   if(me) {
!     PyObject *pyme = NULL;
!     switch(me_type) {
!     case SCRIPTOR_CHAR:  pyme = newPyChar(me); break;
!     case SCRIPTOR_OBJ:   pyme = newPyObj(me);  break;
!     case SCRIPTOR_ROOM:  pyme = newPyRoom(me); break;
!     }
!     PyDict_SetItemString(dict, "me", pyme);
!     Py_DECREF(pyme);
!   }
!   if(ch) {
!     PyObject *pych = newPyChar(ch);
!     PyDict_SetItemString(dict, "ch", pych);
!     Py_DECREF(pych);
!   }
!   if(room) {
!     PyObject *pyroom = newPyRoom(room);
!     PyDict_SetItemString(dict, "room", pyroom);
!     Py_DECREF(pyroom);
!   }    
!   if(obj) {
!     PyObject *pyobj = newPyObj(obj);
!     PyDict_SetItemString(dict, "obj", pyobj);
!     Py_DECREF(pyobj);
!   }    
  
    // start the script
!   start_script(dict, script);
!   deleteScriptDict(dict);
  }
  
  
diff -crN nakedmudv1.5/src/scripts/script.d nakedmudv2.0/src/scripts/script.d
*** nakedmudv1.5/src/scripts/script.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/script.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,5 ----
+ scripts/script.d scripts/script.o: scripts/script.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h socket.h character.h \
+   room.h object.h storage.h auxiliary.h scripts/script.h \
+   scripts/script_set.h scripts/pychar.h scripts/pyroom.h scripts/pyobj.h \
+   scripts/pymud.h editor/editor.h scripts/script_editor.h olc2/olc.h
diff -crN nakedmudv1.5/src/scripts/script_edit.c nakedmudv2.0/src/scripts/script_edit.c
*** nakedmudv1.5/src/scripts/script_edit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/script_edit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,240 ----
+ //*****************************************************************************
+ //
+ // script_edit.c
+ //
+ // This is a set of functions that come with scripts to allow them to be edited
+ // online in an OLC style. The functions for editing both scripts and script
+ // sets are included in here.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "../world.h"
+ #include "../zone.h"
+ 
+ #include "../olc2/olc.h"
+ #include "script.h"
+ #include "script_set.h"
+ #include "../editor/editor.h"
+ #include "script_editor.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // script set editing
+ //*****************************************************************************
+ #define SSEDIT_NEW      1
+ #define SSEDIT_DELETE   2
+ 
+ 
+ void ssedit_menu   (SOCKET_DATA *sock, SCRIPT_SET *set) {
+   LIST *scripts = scriptSetList(set, SCRIPT_TYPE_ANY);
+   SCRIPT_DATA *script = NULL;
+ 
+   // show all the scripts attached
+   text_to_buffer(sock, "Attached scripts:\r\n");
+   while((script = listPop(scripts)) != NULL)
+     send_to_socket(sock,
+ 		   "  {y[{c%4d{y]{w %-20s {c%s\r\n",
+ 		   scriptGetVnum(script), 
+ 		   scriptTypeName(scriptGetType(script)),
+ 		   scriptGetName(script));
+   deleteList(scripts);
+ 
+   send_to_socket(sock,
+ 		 "\r\n"
+ 		 "{cN{g) Attach new script\r\n"
+ 		 "{cD{g) Delete script\r\n"
+ 		 );
+ }
+ 
+ int  ssedit_chooser(SOCKET_DATA *sock, SCRIPT_SET *set, char option) {
+   switch(toupper(option)) {
+   case 'N':
+     text_to_buffer(sock, "Which script would you like to add (-1 for none): ");
+     return SSEDIT_NEW;
+   case 'D':
+     text_to_buffer(sock, "Which script would you like to delete (-1 for none): ");
+     return SSEDIT_DELETE;
+   default: return FALSE;
+   }
+ }
+ 
+ bool ssedit_parser (SOCKET_DATA *sock, SCRIPT_SET *set, int choice, 
+ 		    const char *arg) {
+   switch(choice) {
+   case SSEDIT_NEW: {
+     SCRIPT_DATA *script = worldGetScript(gameworld, atoi(arg));
+     if(script == NULL)
+       return FALSE;
+     scriptSetAdd(set, scriptGetVnum(script)); 
+     return TRUE;
+   }
+   case SSEDIT_DELETE:
+     scriptSetRemove(set, atoi(arg));
+     return TRUE;
+   default: return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // script editing
+ //*****************************************************************************
+ #define SCEDIT_NAME        1
+ #define SCEDIT_TYPE        2
+ #define SCEDIT_ARGS        3
+ #define SCEDIT_NARG        4
+ 
+ void scedit_menu   (SOCKET_DATA *sock, SCRIPT_DATA *script) {
+   send_to_socket(sock,
+ 		 "{g[{c%d{g]\r\n"
+ 		 "{g1) Name         : {c%s\r\n"
+ 		 "{g2) Script type  : {c%s\r\n"
+ 		 "{g3) Arguments    : {c%s\r\n"
+ 		 "{g4) Num. Argument: {c%d\r\n"
+ 		 "{g5) Script Code\r\n",
+ 		 scriptGetVnum(script),
+ 		 scriptGetName(script),
+ 		 scriptTypeName(scriptGetType(script)),
+ 		 (*scriptGetArgs(script) ? scriptGetArgs(script) : "<NONE>"),
+ 		 scriptGetNumArg(script));
+   script_display(sock, scriptGetCode(script), FALSE);
+ }
+ 
+ int  scedit_chooser(SOCKET_DATA *sock, SCRIPT_DATA *script, char option) {
+   switch(toupper(option)) {
+   case '1':
+     text_to_buffer(sock, "Enter a new name for the script: ");
+     return SCEDIT_NAME;
+   case '2':
+     olc_display_table(sock, scriptTypeName, NUM_SCRIPTS, 1);
+     return SCEDIT_TYPE;
+   case '3':
+     text_to_buffer(sock, "Enter new arguments: ");
+     return SCEDIT_ARGS;
+   case '5':
+     socketStartEditor(sock, script_editor,scriptGetCodeBuffer(script));
+     return MENU_NOCHOICE;
+   case '4':
+     switch(scriptGetType(script)) {
+       // 0 = triggers always
+       // 1 = triggers if the scriptor can see the char
+     case SCRIPT_TYPE_GIVE:
+     case SCRIPT_TYPE_ENTER:
+       send_to_socket(sock,
+ 		     "If the scriptor is a mob:\r\n"
+ 		     "  0 = always triggers\r\n"
+ 		     "  1 = triggers if the scriptor can see the char\r\n"
+ 		     "\r\n"
+ 		     "Enter choice : ");
+       return SCEDIT_NARG;
+ 
+     case SCRIPT_TYPE_COMMAND:
+       send_to_socket(sock,
+ 		     "Control for the actual MUD command:\r\n"
+ 		     "  0 = follow through with the MUD command\r\n"
+ 		     "  1 = cancel the MUD command.\r\n"
+ 		     "\r\n"
+ 		     "Enter choice : ");
+       return SCEDIT_NARG;
+ 
+     default:
+       send_to_socket(sock, 
+ 		     "This script type does not use numeric arguments.\r\n"
+ 		     "Enter choice (Q to quit) : ");
+       return MENU_NOCHOICE;
+     }
+ 
+   default:
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool scedit_parser (SOCKET_DATA *sock, SCRIPT_DATA *script, int choice, 
+ 		    const char *arg) {
+   switch(choice) {
+   case SCEDIT_NAME:
+     scriptSetName(script, arg);
+     return TRUE;
+ 
+   case SCEDIT_ARGS:
+     scriptSetArgs(script, arg);
+     return TRUE;
+ 
+   case SCEDIT_NARG:
+     switch(scriptGetType(script)) {
+       // 0 = triggers always
+       // 1 = triggers if the scriptor can see the char
+     case SCRIPT_TYPE_GIVE:
+     case SCRIPT_TYPE_ENTER:
+     case SCRIPT_TYPE_EXIT:
+       scriptSetNumArg(script, MIN(1, MAX(0, atoi(arg))));
+       break;
+       // 0 = follow through with normal command
+       // 1 = cancel normal command
+     case SCRIPT_TYPE_COMMAND:
+       scriptSetNumArg(script, MIN(1, MAX(0, atoi(arg))));
+       break;
+     }
+     return TRUE;
+ 
+   case SCEDIT_TYPE: {
+     int num = atoi(arg);
+     if(num < 0 || num >= NUM_SCRIPTS)
+       return FALSE;
+     else {
+       scriptSetType(script, num);
+       // reset arguments
+       if(scriptGetArgs(script))
+ 	scriptSetArgs(script, "");
+       scriptSetNumArg(script, 0);
+       return TRUE;
+     }
+   }
+ 
+   default: 
+     return FALSE;
+   }
+ }
+ 
+ 
+ COMMAND(cmd_scedit) {
+   ZONE_DATA *zone;
+   SCRIPT_DATA *script;
+   script_vnum vnum;
+ 
+   // we need a vnum
+   if(!arg || !*arg)
+     send_to_char(ch, "Please supply the vnum of a script you wish to edit.\r\n");
+   else {
+     vnum = atoi(arg);
+ 
+     // make sure there is a corresponding zone ...
+     if((zone = worldZoneBounding(gameworld, vnum)) == NULL)
+       send_to_char(ch, "No zone exists that contains the given vnum.\r\n");
+     else if(!canEditZone(zone, ch))
+       send_to_char(ch, "You are not authorized to edit this zone.\r\n");  
+     else {
+       // find the script
+       script = zoneGetScript(zone, vnum);
+ 
+       // make our script
+       if(script == NULL) {
+ 	script = newScript();
+ 	scriptSetVnum(script, vnum);
+ 	scriptSetName(script, "An Unfinished Script");
+ 	scriptSetCode(script, "# script code goes here\n"
+ 		              "# make sure to comment it with pounds (#)\n");
+ 	zoneAddScript(zone, script);
+       }
+ 
+       do_olc(charGetSocket(ch), scedit_menu, scedit_chooser, scedit_parser,
+ 	     scriptCopy, scriptCopyTo, deleteScript, save_world, script);
+     }
+   }
+ }
diff -crN nakedmudv1.5/src/scripts/script_edit.d nakedmudv2.0/src/scripts/script_edit.d
*** nakedmudv1.5/src/scripts/script_edit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/script_edit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ scripts/script_edit.d scripts/script_edit.o: scripts/script_edit.c mud.h wrapsock.h property_table.h \
+   list.h map.h hashtable.h set.h buffer.h bitvector.h utils.h socket.h \
+   character.h world.h zone.h olc2/olc.h scripts/script.h \
+   scripts/script_set.h editor/editor.h scripts/script_editor.h
diff -crN nakedmudv1.5/src/scripts/script_editor.c nakedmudv2.0/src/scripts/script_editor.c
*** nakedmudv1.5/src/scripts/script_editor.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/script_editor.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,137 ----
+ //*****************************************************************************
+ //
+ // script_editor.c
+ //
+ // this is an extention of the basic script editor (/src/editor/editor.h) to
+ // be tailored for script editing. Provides syntax coloring and line number
+ // display, and auto indenting.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../socket.h"
+ #include "../auxiliary.h"
+ 
+ #include "../editor/editor.h"
+ #include "script_editor.h"
+ #include "script.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // auxiliary data and functions
+ //*****************************************************************************
+ typedef struct script_editor_aux_data {
+   int indent; // how far are we indented for our next line of code?
+ } SCRIPT_EDITOR_AUX_DATA;
+ 
+ SCRIPT_EDITOR_AUX_DATA *
+ newScriptEditorAuxData() {
+   SCRIPT_EDITOR_AUX_DATA *data = malloc(sizeof(SCRIPT_EDITOR_AUX_DATA));
+   data->indent = 0;
+   return data;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // local functions and data structures
+ //*****************************************************************************
+ EDITOR *script_editor = NULL;
+ 
+ 
+ //
+ // increase the indentation in our script by 2
+ void scriptEditorIndent(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
+   data->indent += 2;
+ }
+ 
+ //
+ // decrease the indentation in our script by 2
+ void scriptEditorUndent(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
+   data->indent -= 2;
+   if(data->indent < 0)
+     data->indent = 0;
+ }
+ 
+ //
+ // return what our current level of indenting is
+ int socketGetScriptEditorIndent(SOCKET_DATA *sock) {
+   SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
+   return data->indent;
+ }
+ 
+ //
+ // append new text to the script editor. Make sure we add the appropriate amount
+ // of spaces before the addition, and increment/decrement our indent as needed
+ void scriptEditorAppend(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   // if we're playing with else/elif/case, take down the input a notch
+   if(!strncmp(arg, "else:", 5) ||
+      !strncmp(arg, "elif ", 5) ||
+      !strncmp(arg, "case ", 5))
+     scriptEditorUndent(sock, NULL, NULL);
+ 
+   // add in our indents if neccessary
+   int indent = socketGetScriptEditorIndent(sock);
+   if(indent > 0) {
+     char fmt[20];
+     sprintf(fmt, "%%%ds", indent);
+     bprintf(buf, fmt, " ");
+   }
+ 
+   // cat the new line of code
+   bufferCat(buf, arg);
+   bufferCat(buf, "\n");
+ 
+   // see if we need to change our indent
+   int len = strlen(arg);
+   if(len > 0 && arg[len-1] == ':')
+     scriptEditorIndent(sock, NULL, NULL);
+ }
+ 
+ 
+ //
+ // list the script buffer to the socket, but do all of our syntax highlighting
+ void scriptEditorList(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   script_display(sock, bufferString(buf), TRUE);
+ }
+ 
+ 
+ //
+ // \r really screws up python; this function makes sure they're all stripped out
+ void scriptEditorFormat(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
+   bufferReplace(buf, "\r", "", TRUE);
+ }
+ 
+ //
+ // prepare our socket to use the script editor
+ void socketInitScriptEditor(SOCKET_DATA *sock) {
+   SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
+   data->indent = 0;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // implementation of script_editor.h
+ //*****************************************************************************
+ void init_script_editor() {
+   script_editor = newEditor();
+   editorSetAppend(script_editor, scriptEditorAppend);
+   editorSetInit(script_editor, socketInitScriptEditor);
+   editorAddCommand(script_editor, "v", "        Indent down the script editor",
+ 		   scriptEditorUndent);
+   editorAddCommand(script_editor, "^", "        Indent up the script editor",
+ 		   scriptEditorIndent);
+   editorAddCommand(script_editor, "l", "        List the current buffer contents",
+ 		   scriptEditorList);
+   editorAddCommand(script_editor, "f", "        Strips all bad characters out of the script",
+ 		   scriptEditorFormat);
+ 
+   auxiliariesInstall("script_editor_aux_data", 
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_SOCKET,
+ 				       newScriptEditorAuxData, free,
+ 				       NULL, NULL, NULL, NULL));
+ }
diff -crN nakedmudv1.5/src/scripts/script_editor.d nakedmudv2.0/src/scripts/script_editor.d
*** nakedmudv1.5/src/scripts/script_editor.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/script_editor.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ scripts/script_editor.d scripts/script_editor.o: scripts/script_editor.c mud.h wrapsock.h \
+   property_table.h list.h map.h hashtable.h set.h buffer.h bitvector.h \
+   socket.h auxiliary.h editor/editor.h scripts/script_editor.h \
+   scripts/script.h
diff -crN nakedmudv1.5/src/scripts/script_editor.h nakedmudv2.0/src/scripts/script_editor.h
*** nakedmudv1.5/src/scripts/script_editor.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/script_editor.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,20 ----
+ #ifndef SCRIPT_EDITOR_H
+ #define SCRIPT_EDITOR_H
+ //*****************************************************************************
+ //
+ // script_editor.h
+ //
+ // this is an extention of the basic script editor (/src/editor/editor.h) to
+ // be tailored for script editing. Provides syntax coloring and line number
+ // display, and auto indenting.
+ //
+ //*****************************************************************************
+ 
+ extern EDITOR *script_editor;
+ 
+ //
+ // prepare the script editor for use
+ //
+ void init_script_editor();
+ 
+ #endif // SCRIPT_EDITOR_H
diff -crN nakedmudv1.5/src/scripts/script.h nakedmudv2.0/src/scripts/script.h
*** nakedmudv1.5/src/scripts/script.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/scripts/script.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 164,170 ****
  const char *scriptGetArgs(SCRIPT_DATA *script);
  const char *scriptGetName(SCRIPT_DATA *script);
  const char *scriptGetCode(SCRIPT_DATA *script);
! char      **scriptGetCodePtr(SCRIPT_DATA *script); // for text editing in olc
  
  void scriptSetVnum(SCRIPT_DATA *script, script_vnum vnum);
  void scriptSetType(SCRIPT_DATA *script, int type);
--- 164,170 ----
  const char *scriptGetArgs(SCRIPT_DATA *script);
  const char *scriptGetName(SCRIPT_DATA *script);
  const char *scriptGetCode(SCRIPT_DATA *script);
! BUFFER     *scriptGetCodeBuffer(SCRIPT_DATA *script);
  
  void scriptSetVnum(SCRIPT_DATA *script, script_vnum vnum);
  void scriptSetType(SCRIPT_DATA *script, int type);
***************
*** 186,191 ****
--- 186,207 ----
  void        charSetScripts(CHAR_DATA *mob, SCRIPT_SET *scripts);
  
  
+ //
+ // If OLC2 is installed, we'll want to be able to edit which scripts are
+ // on mobiles, objects, rooms, etc... that's what ssedit is for. scedit is
+ // used internally by CMD_SCEDIT to start up an online editor for scripts
+ //
+ #ifdef MODULE_OLC2
+ void ssedit_menu   (SOCKET_DATA *sock, SCRIPT_SET *set);
+ int  ssedit_chooser(SOCKET_DATA *sock, SCRIPT_SET *set, char option);
+ bool ssedit_parser (SOCKET_DATA *sock, SCRIPT_SET *set, int choice, 
+ 		    const char *arg);
+ void scedit_menu   (SOCKET_DATA *sock, SCRIPT_DATA *script);
+ int  scedit_chooser(SOCKET_DATA *sock, SCRIPT_DATA *script, char option);
+ bool scedit_parser (SOCKET_DATA *sock, SCRIPT_DATA *script, int choice, 
+ 		    const char *arg);
+ #endif // MODULE_OLC2
+ 
  
  
  //*****************************************************************************
diff -crN nakedmudv1.5/src/scripts/script_set.d nakedmudv2.0/src/scripts/script_set.d
*** nakedmudv1.5/src/scripts/script_set.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/scripts/script_set.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ scripts/script_set.d scripts/script_set.o: scripts/script_set.c mud.h wrapsock.h property_table.h \
+   list.h map.h hashtable.h set.h buffer.h bitvector.h utils.h world.h \
+   scripts/script_set.h scripts/script.h
diff -crN nakedmudv1.5/src/set.c nakedmudv2.0/src/set.c
*** nakedmudv1.5/src/set.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/set.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 11,24 ****
  #include "set.h"
  
  struct set_data {
!   int       num_buckets;
!   struct list **buckets;
  };
  
  struct set_iterator {
    int                curr_bucket; // the bucket number we're currently on
    struct set_data           *set; // the set we're iterating over
!   struct list_iterator *bucket_i; // the iterator for our current bucket
  };
  
  
--- 11,24 ----
  #include "set.h"
  
  struct set_data {
!   int    num_buckets;
!   LIST **buckets;
  };
  
  struct set_iterator {
    int                curr_bucket; // the bucket number we're currently on
    struct set_data           *set; // the set we're iterating over
!   LIST_ITERATOR *bucket_i;        // the iterator for our current bucket
  };
  
  
***************
*** 43,53 ****
  // implementation of set.h
  //
  //*****************************************************************************
! struct set_data *newSet(int num_buckets) {
    int i;
  
!   struct set_data *set = malloc(sizeof(struct set_data));
!   set->buckets = malloc(sizeof(struct list *) * num_buckets);
  
    // all NULL until they actually get a content
    for(i = 0; i < num_buckets; i++)
--- 43,53 ----
  // implementation of set.h
  //
  //*****************************************************************************
! SET *newSet(int num_buckets) {
    int i;
  
!   SET *set = malloc(sizeof(SET));
!   set->buckets = malloc(sizeof(LIST *) * num_buckets);
  
    // all NULL until they actually get a content
    for(i = 0; i < num_buckets; i++)
***************
*** 58,64 ****
  };
  
  
! void deleteSet(struct set_data *set) {
    int i;
  
    for(i = 0; i < set->num_buckets; i++)
--- 58,64 ----
  };
  
  
! void deleteSet(SET *set) {
    int i;
  
    for(i = 0; i < set->num_buckets; i++)
***************
*** 70,76 ****
  };
  
  
! void setPut(struct set_data *set, void *elem) {
    // find out what bucket we belong to
    int hash_bucket = set_elem_bucket(elem, set->num_buckets);
  
--- 70,76 ----
  };
  
  
! void setPut(SET *set, void *elem) {
    // find out what bucket we belong to
    int hash_bucket = set_elem_bucket(elem, set->num_buckets);
  
***************
*** 82,88 ****
  };
  
  
! void setRemove(struct set_data *set, void *elem) {
    // find out what bucket we belong to
    int hash_bucket = set_elem_bucket(elem, set->num_buckets);
  
--- 82,88 ----
  };
  
  
! void setRemove(SET *set, void *elem) {
    // find out what bucket we belong to
    int hash_bucket = set_elem_bucket(elem, set->num_buckets);
  
***************
*** 92,98 ****
  };
  
  
! int setIn(struct set_data *set, void *elem) {
    // find out what bucket we belong to
    int hash_bucket = set_elem_bucket(elem, set->num_buckets);
  
--- 92,98 ----
  };
  
  
! int setIn(SET *set, void *elem) {
    // find out what bucket we belong to
    int hash_bucket = set_elem_bucket(elem, set->num_buckets);
  
***************
*** 111,118 ****
  // this lets us do so.
  //
  //*****************************************************************************
! struct set_iterator *newSetIterator(struct set_data *S) {
!   struct set_iterator *I = malloc(sizeof(struct set_iterator));
  
    I->set = S;
    I->curr_bucket = 0;
--- 111,118 ----
  // this lets us do so.
  //
  //*****************************************************************************
! SET_ITERATOR *newSetIterator(SET *S) {
!   SET_ITERATOR *I = malloc(sizeof(SET_ITERATOR));
  
    I->set = S;
    I->curr_bucket = 0;
***************
*** 123,135 ****
  }
  
  
! void deleteSetIterator(struct set_iterator *I) {
    if(I->bucket_i) deleteListIterator(I->bucket_i);
    free(I);
  }
  
  
! void setIteratorReset(struct set_iterator *I) {
    int i;
  
    if(I->bucket_i) 
--- 123,135 ----
  }
  
  
! void deleteSetIterator(SET_ITERATOR *I) {
    if(I->bucket_i) deleteListIterator(I->bucket_i);
    free(I);
  }
  
  
! void setIteratorReset(SET_ITERATOR *I) {
    int i;
  
    if(I->bucket_i) 
***************
*** 151,157 ****
  }
  
  
! void *setIteratorNext(struct set_iterator *I) {
    // we have no iterator ... we have no elements left to iterate over!
    if(I->bucket_i == NULL)
      return NULL;
--- 151,157 ----
  }
  
  
! void *setIteratorNext(SET_ITERATOR *I) {
    // we have no iterator ... we have no elements left to iterate over!
    if(I->bucket_i == NULL)
      return NULL;
***************
*** 186,192 ****
  }
  
  
! void *setIteratorCurrent(struct set_iterator *I) {
    // we have no elements!
    if(I->bucket_i == NULL)
      return NULL;
--- 186,192 ----
  }
  
  
! void *setIteratorCurrent(SET_ITERATOR *I) {
    // we have no elements!
    if(I->bucket_i == NULL)
      return NULL;
diff -crN nakedmudv1.5/src/set.d nakedmudv2.0/src/set.d
*** nakedmudv1.5/src/set.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/set.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ set.d set.o: set.c list.h set.h
diff -crN nakedmudv1.5/src/set.h nakedmudv2.0/src/set.h
*** nakedmudv1.5/src/set.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/set.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 8,19 ****
  //
  //*****************************************************************************
  
! struct set_data  *newSet(int buckets);
! void           deleteSet(struct set_data *set);
! void              setPut(struct set_data *set, void *elem);
! void           setRemove(struct set_data *set, void *elem);
! int                setIn(struct set_data *set, void *elem);
  
  
  
  //*****************************************************************************
--- 8,21 ----
  //
  //*****************************************************************************
  
! typedef struct set_data                   SET;
! typedef struct set_iterator               SET_ITERATOR;
  
+ SET  *newSet   (int buckets);
+ void  deleteSet(SET *set);
+ void  setPut   (SET *set, void *elem);
+ void  setRemove(SET *set, void *elem);
+ int   setIn    (SET *set, void *elem);
  
  
  //*****************************************************************************
***************
*** 25,34 ****
  //
  //*****************************************************************************
  
! struct set_iterator *newSetIterator(struct set_data *S);
! void              deleteSetIterator(struct set_iterator *I);
! void               setIteratorReset(struct set_iterator *I);
! void               *setIteratorNext(struct set_iterator *I);
! void            *setIteratorCurrent(struct set_iterator *I);
  
  #endif // SET_H
--- 27,36 ----
  //
  //*****************************************************************************
  
! SET_ITERATOR *newSetIterator    (SET *S);
! void          deleteSetIterator (SET_ITERATOR *I);
! void          setIteratorReset  (SET_ITERATOR *I);
! void         *setIteratorNext   (SET_ITERATOR *I);
! void         *setIteratorCurrent(SET_ITERATOR *I);
  
  #endif // SET_H
diff -crN nakedmudv1.5/src/set_val/intallation nakedmudv2.0/src/set_val/intallation
*** nakedmudv1.5/src/set_val/intallation	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/set_val/intallation	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,5 ----
+ installation of the set_val module:
+ 
+ Install the module in the same way you would install any other module. However,
+ make sure that the set_val module is initialized before any other module that
+ tries to add a new set command!!
diff -crN nakedmudv1.5/src/set_val/module.mk nakedmudv2.0/src/set_val/module.mk
*** nakedmudv1.5/src/set_val/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/set_val/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ SRC += set_val/set_val.c
diff -crN nakedmudv1.5/src/set_val/set_val.c nakedmudv2.0/src/set_val/set_val.c
*** nakedmudv1.5/src/set_val/set_val.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/set_val/set_val.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,245 ----
+ //*****************************************************************************
+ //
+ // set_val.c
+ //
+ // There are often times in-game when we will want to change the values of a
+ // field in a character or object; most DIKU muds do this via a "set" command
+ // that simply has a list of all of the fields, and how to handle performing
+ // the set. However, because of our modular nature, it would be fairly 
+ // cumbersome to have all of the possible things to set in one big list. 
+ // Instead, we provide a way that modules can install new fields that can be
+ // set for rooms, objects, and mobiles.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../world.h"
+ #include "../zone.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "../object.h"
+ #include "../room.h"
+ #include "../races.h"
+ #include "../handler.h"
+ 
+ #include "set_val.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // local defines, datastructures, functions, and commands
+ //
+ //*****************************************************************************
+ #define SET_TABLE_SIZE        10
+ HASHTABLE *char_set_table = NULL;
+ HASHTABLE *obj_set_table  = NULL;
+ HASHTABLE *room_set_table = NULL;
+ 
+ typedef struct set_val_data {
+   int   type;    // the type of data (int, double, long, string, etc...)
+   void *setter;  // the function to do the setting
+   void *checker; // make sure the new value is an acceptable value
+ } SET_VAL_DATA;
+ 
+ 
+ SET_VAL_DATA *newSetValData(int type, void *setter, void *checker) {
+   SET_VAL_DATA *data = malloc(sizeof(SET_VAL_DATA));
+   data->type    = type;
+   data->setter  = setter;
+   data->checker = checker;
+   return data;
+ }
+ 
+ void deleteSetValData(SET_VAL_DATA *data) {
+   free(data);
+ }
+ 
+ 
+ void try_set(CHAR_DATA *ch, void *tgt, HASHTABLE *table, 
+ 	     const char *field, const char *val) {
+   SET_VAL_DATA *data = hashGet(table, field);
+   if(data == NULL)
+     send_to_char(ch, "You cannot set that field!\r\n");
+   else {
+     // make sure this is an acceptable value
+     bool set_ok = TRUE;
+     if(data->checker != NULL) {
+       if(data->type == SET_TYPE_INT)
+ 	set_ok = ((bool (*)(int)) data->checker)(atoi(val));
+       else if(data->type == SET_TYPE_LONG)
+ 	set_ok = ((bool (*)(long)) data->checker)(atol(val));
+       else if(data->type == SET_TYPE_DOUBLE)
+ 	set_ok = ((bool (*)(double)) data->checker)(atof(val));
+       else if(data->type == SET_TYPE_STRING)
+ 	set_ok = ((bool (*)(const char *)) data->checker)(val);
+     }
+ 
+     // make sure the set is ok
+     if(set_ok == FALSE) {
+       send_to_char(ch, "'%s' is not an acceptable value!\r\n", val);
+       return;
+     }
+     
+     // perform the change
+     if(data->type == SET_TYPE_INT)
+       ((void (*)(void *, int)) data->setter)(tgt, atoi(val));
+     else if(data->type == SET_TYPE_LONG)
+       ((void (*)(void *, long)) data->setter)(tgt, atol(val));
+     else if(data->type == SET_TYPE_DOUBLE)
+       ((void (*)(void *, double)) data->setter)(tgt, atof(val));
+     else if(data->type == SET_TYPE_STRING)
+       ((void (*)(void *, const char *)) data->setter)(tgt, val);
+     send_to_char(ch, "Ok.\r\n");
+   }
+ }
+ 
+ 
+ //
+ // used for setting; make sure the value we're trying to set is in an
+ // acceptable range.
+ //
+ bool isLevel(int level) {
+   return (level >= LEVEL_PLAYER && level <= MAX_LEVEL);
+ }
+ 
+ // are we trying to set a value from an argument, or from our notepad?
+ #define SET_SUBCMD_SET        0
+ #define SET_SUBCMD_SETPAD     1
+ 
+ //
+ // The entrypoint to the set utility for players in the MUD
+ //   usage: set [thing] [field] [value]
+ //
+ // thing is expected to be a character's name, an object's name, a room's
+ // vnum, or simply "room" for the current room. Optionally, the function can
+ // take a value from the player's notepad instead of from the command line (this
+ // is useful for if you need to write long lengths of formatted text).
+ //
+ COMMAND(cmd_set) {
+   char name [SMALL_BUFFER];
+   char field[SMALL_BUFFER];
+   arg = two_args(arg, name, field);
+ 
+   // check to see if we're trying to set from our notepad. Also, make sure
+   // we have a socket and CAN access our notepad.
+   /*
+   if(subcmd == SET_SUBCMD_SETPAD) {
+     if(charGetSocket(ch) && *socketGetNotepadPtr(charGetSocket(ch)) != NULL)
+       arg = *socketGetNotepadPtr(charGetSocket(ch));
+     else {
+       send_to_char(ch, "Your notepad currently has no contents.\r\n");
+       return;
+     }
+   }
+   */
+   if(!*arg || !*name || !*field)
+     send_to_char(ch, "Set which value on what?\r\n");
+   // are we trying to set a field on a room?
+   else if(!strcasecmp("room", name)) {
+     if(!canEditZone(worldZoneBounding(gameworld, roomGetVnum(charGetRoom(ch))),
+ 		    ch))
+       send_to_char(ch, "You are not authorized to edit this zone.\r\n");
+     else
+       try_set(ch, charGetRoom(ch), room_set_table, field, arg);
+   }
+   else if(isdigit(*name) && worldGetRoom(gameworld, atoi(name))) {
+     if(!canEditZone(worldZoneBounding(gameworld, atoi(name)), ch))
+       send_to_char(ch, "You are not authorized to edit this zone.\r\n");
+     else
+       try_set(ch, worldGetRoom(gameworld, atoi(name)),room_set_table,field,arg);
+   }
+   else {
+     int found = FOUND_NONE;
+     void *tgt = NULL;
+     tgt = generic_find(ch, name, FIND_TYPE_CHAR | FIND_TYPE_OBJ,
+ 		       FIND_SCOPE_ALL | FIND_SCOPE_VISIBLE, FALSE, &found);
+ 
+     if(found == FOUND_CHAR) {
+       if(charGetLevel(ch) <= charGetLevel(tgt) && ch != tgt)
+ 	send_to_char(ch, "Sorry, %s is too high a level!\r\n", 
+ 		     see_char_as(ch, tgt));
+       else
+ 	try_set(ch, tgt, char_set_table, field, arg);
+     }
+     else if(found == FOUND_OBJ)
+       try_set(ch, tgt, obj_set_table, field, arg);
+     else
+       send_to_char(ch, "What was the target you were trying to modify?\r\n");
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // implementation of set_val.h
+ //
+ //*****************************************************************************
+ void init_set() {
+   // build all of our tables
+   char_set_table = newHashtable(SET_TABLE_SIZE);
+   obj_set_table  = newHashtable(SET_TABLE_SIZE);
+   room_set_table = newHashtable(SET_TABLE_SIZE);
+ 
+   // add in the default sets for the core of the MUD
+   /************************************************************/
+   /*                         WARNING                          */
+   /*                                                          */
+   /* If you are wanting to add new "set" fields to the set    */
+   /* module, you are best off adding them with whatever module*/
+   /* the new data is included in. If the term "module" is not */
+   /* making any sense to you, READ THE DOCUMENTATION!         */
+   /************************************************************/
+ 
+   // PLAYER SETS
+   add_set("desc",  LEVEL_BUILDER, SET_CHAR, SET_TYPE_STRING, charSetDesc, NULL);
+   add_set("rdesc", LEVEL_BUILDER, SET_CHAR, SET_TYPE_STRING, charSetRdesc,NULL);
+   add_set("name",  LEVEL_BUILDER, SET_CHAR, SET_TYPE_STRING, charSetName, NULL);
+   add_set("mrdesc",LEVEL_BUILDER, SET_CHAR, SET_TYPE_STRING, charSetMultiRdesc, NULL);
+   add_set("mname", LEVEL_BUILDER, SET_CHAR, SET_TYPE_STRING, charSetMultiName, NULL);
+   add_set("keywords",LEVEL_BUILDER,SET_CHAR,SET_TYPE_STRING, charSetKeywords, NULL);
+   add_set("dialog",LEVEL_BUILDER, SET_CHAR, SET_TYPE_INT, charSetDialog,  NULL);
+   add_set("level", LEVEL_ADMIN,   SET_CHAR, SET_TYPE_INT, charSetLevel,isLevel);
+   add_set("race",  LEVEL_BUILDER, SET_CHAR, SET_TYPE_STRING,charSetRace,isRace);
+ 
+   // ROOM SETS
+   add_set("name", LEVEL_BUILDER, SET_ROOM, SET_TYPE_STRING, roomSetName, NULL);
+   add_set("desc", LEVEL_BUILDER, SET_ROOM, SET_TYPE_STRING, roomSetDesc, NULL);
+ 
+   // OBJECT SETS
+   add_set("name",    LEVEL_BUILDER,SET_OBJECT,SET_TYPE_STRING,objSetName, NULL);
+   add_set("desc",    LEVEL_BUILDER,SET_OBJECT,SET_TYPE_STRING,objSetDesc, NULL);
+   add_set("rdesc",   LEVEL_BUILDER,SET_OBJECT,SET_TYPE_STRING,objSetRdesc,NULL);
+   add_set("name",    LEVEL_BUILDER,SET_OBJECT,SET_TYPE_STRING,objSetName, NULL);
+   add_set("mrdesc",  LEVEL_BUILDER,SET_OBJECT,SET_TYPE_STRING,objSetMultiRdesc, NULL);
+   add_set("mname",   LEVEL_BUILDER,SET_OBJECT,SET_TYPE_STRING,objSetMultiName, NULL);
+   add_set("keywords",LEVEL_BUILDER,SET_OBJECT,SET_TYPE_STRING,objSetKeywords, NULL);
+ 
+   // now, add the admin commands for working with set
+   add_cmd("set", NULL, cmd_set, SET_SUBCMD_SET, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_ADMIN, FALSE, FALSE);
+   add_cmd("setpad", NULL, cmd_set, SET_SUBCMD_SETPAD, POS_UNCONCIOUS,POS_FLYING,
+ 	  LEVEL_ADMIN, FALSE, FALSE);
+ }
+ 
+ 
+ void add_set(const char *name, int min_lev, int set_for, int type, void *setter, void *checker) {
+   HASHTABLE *table = NULL;
+   // first, find our table
+   if     (set_for == SET_CHAR)   table = char_set_table;
+   else if(set_for == SET_OBJECT) table = obj_set_table;
+   else if(set_for == SET_ROOM)   table = room_set_table;
+ 
+   // if there was no table, we can't do anything
+   if(table == NULL) return;
+ 
+   // If old data exists, remove it
+   SET_VAL_DATA *old_set = hashRemove(table, name);
+   if(old_set) deleteSetValData(old_set);
+ 
+   // now, build our new data and add it to the table
+   SET_VAL_DATA *new_set = newSetValData(type, setter, checker);
+   hashPut(table, name, new_set);
+ }
diff -crN nakedmudv1.5/src/set_val/set_val.d nakedmudv2.0/src/set_val/set_val.d
*** nakedmudv1.5/src/set_val/set_val.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/set_val/set_val.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ set_val/set_val.d set_val/set_val.o: set_val/set_val.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h utils.h world.h zone.h \
+   socket.h character.h object.h room.h races.h handler.h \
+   set_val/set_val.h
diff -crN nakedmudv1.5/src/set_val/set_val.h nakedmudv2.0/src/set_val/set_val.h
*** nakedmudv1.5/src/set_val/set_val.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/set_val/set_val.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,44 ----
+ #ifndef SET_VAL_H
+ #define SET_VAL_H
+ //*****************************************************************************
+ //
+ // set_val.h
+ //
+ // There are often times in-game when we will want to change the values of a
+ // field in a character or object; most DIKU muds do this via a "set" command
+ // that simply has a list of all of the fields, and how to handle performing
+ // the set. However, because of our modular nature, it would be fairly 
+ // cumbersome to have all of the possible things to set in one big list. 
+ // Instead, we provide a way that modules can install new fields that can be
+ // set for rooms, objects, and mobiles.
+ //
+ //*****************************************************************************
+ 
+ #define SET_TYPE_INT       0
+ #define SET_TYPE_DOUBLE    1
+ #define SET_TYPE_LONG      2
+ #define SET_TYPE_STRING    3
+ 
+ #define SET_CHAR           0
+ #define SET_OBJECT         1
+ #define SET_ROOM           2
+ 
+ 
+ //
+ // prepare the set utility for use
+ //
+ void init_set();
+ 
+ 
+ //
+ // Adds a new field that can be set for the type of thing we are trying to
+ // modify. type is the datatype we're modifying (int, double, long, string)
+ // and setter is the function that takes the thing to be set (char, obj, room)
+ // and the new value. If there are constraints on the applicable values that
+ // can be set, checker should be provided. It takes in the to-be-set value and
+ // makes sure it is OK, returning TRUE if it is and FALSE if it is not. The
+ // checker function should be of the form:
+ //
+ void add_set(const char *name, int min_lev, int set_for, int type, void *setter, void *checker);
+ 
+ #endif // SET_VAL_H
diff -crN nakedmudv1.5/src/shop.c nakedmudv2.0/src/shop.c
*** nakedmudv1.5/src/shop.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/shop.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,14 ****
- //*****************************************************************************
- //
- // shop.c
- //
- // Shops allow mobs or containers to act as stores for selling and buying
- // other objects.
- //
- //*****************************************************************************
- 
- struct shop_data {
- 
- };
- 
- 
--- 0 ----
diff -crN nakedmudv1.5/src/shop.h nakedmudv2.0/src/shop.h
*** nakedmudv1.5/src/shop.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/shop.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,23 ****
- #ifndef __SHOP_H
- #define __SHOP_H
- 
- //*****************************************************************************
- //
- // shop.h
- //
- // Shops allow mobs or containers to act as stores for selling and buying
- // other objects.
- //
- //*****************************************************************************
- 
- 
- 
- SHOP_DATA *newShop   (shop_vnum vnum);
- void       deleteShop(SHOP_DATA *shop);
- 
- void       shopCopyTo(SHOP_DATA *from, SHOP_DATA *to);
- SHOP_DATA *shopCopy  (SHOP_DATA *shop);
- 
- 
- 
- #endif // __SHOP_H
--- 0 ----
diff -crN nakedmudv1.5/src/socials/module.mk nakedmudv2.0/src/socials/module.mk
*** nakedmudv1.5/src/socials/module.mk	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/socials/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,2 ****
  # source files we contain
! SRC += socials/socials.c
--- 1,2 ----
  # source files we contain
! SRC += socials/socials.c socials/socedit.c
diff -crN nakedmudv1.5/src/socials/socedit.c nakedmudv2.0/src/socials/socedit.c
*** nakedmudv1.5/src/socials/socedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/socials/socedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,190 ----
+ //*****************************************************************************
+ //
+ // socedit.c
+ //
+ // socedit is a set of tools for editing socials online. Socedit requires that
+ // olc2 be installed.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../character.h"
+ #include "../socket.h"
+ #include "../olc2/olc.h"
+ 
+ #include "socials.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ // the functions needed by olc2
+ //*****************************************************************************
+ #define SOCEDIT_CHAR_NOTGT      1
+ #define SOCEDIT_ROOM_NOTGT      2
+ #define SOCEDIT_CHAR_SELF       3
+ #define SOCEDIT_ROOM_SELF       4
+ #define SOCEDIT_CHAR_TGT        5
+ #define SOCEDIT_VICT_TGT        6
+ #define SOCEDIT_ROOM_TGT        7
+ #define SOCEDIT_MIN_POS         8
+ #define SOCEDIT_MAX_POS         9
+ 
+ void socedit_menu(SOCKET_DATA *sock, SOCIAL_DATA *social) {
+   send_to_socket(sock,
+ 		 "{y[{c%s{y]\r\n"
+ 		 "{g1) to char notgt: {c%s\r\n"
+ 		 "{g2) to room notgt: {c%s\r\n"
+ 		 "{g3) to char self : {c%s\r\n"
+ 		 "{g4) to room self : {c%s\r\n"
+ 		 "{g5) to char tgt  : {c%s\r\n"
+ 		 "{g6) to vict tgt  : {c%s\r\n"
+ 		 "{g7) to room tgt  : {c%s\r\n"
+ 		 "{g8) minimum pos  : {c%s\r\n"
+ 		 "{g9) maximum pos  : {c%s\r\n"
+ 		 "\r\n"
+ 		 "{gTo assocciate/unassociate commands, use soclink and socunlink\r\n",
+ 		 socialGetCmds(social),
+ 		 socialGetCharNotgt(social),
+ 		 socialGetRoomNotgt(social),
+ 		 socialGetCharSelf(social),
+ 		 socialGetRoomSelf(social),
+ 		 socialGetCharTgt(social),
+ 		 socialGetVictTgt(social),
+ 		 socialGetRoomTgt(social),
+ 		 posGetName(socialGetMinPos(social)),
+ 		 posGetName(socialGetMaxPos(social))
+ 		 );
+ }
+ 
+ int  socedit_chooser(SOCKET_DATA *sock, SOCIAL_DATA *social, char option) {
+   switch(toupper(option)) {
+   case '1':
+     send_to_socket(sock, 
+ 		   "The message to character when no target is supplied : ");
+     return SOCEDIT_CHAR_NOTGT;
+   case '2':
+     send_to_socket(sock, 
+ 		   "The message to room when no target is supplied : ");
+     return SOCEDIT_ROOM_NOTGT;
+   case '3':
+     send_to_socket(sock, 
+ 		   "The message to character when target is self : ");
+     return SOCEDIT_CHAR_SELF;
+   case '4':
+     send_to_socket(sock, 
+ 		   "The message to room when target is self : ");
+     return SOCEDIT_ROOM_SELF;
+   case '5':
+     send_to_socket(sock, 
+ 		   "The message to character when a target is found : ");
+     return SOCEDIT_CHAR_TGT;
+   case '6':
+     send_to_socket(sock, 
+ 		   "The message to target when a target is found : ");
+     return SOCEDIT_VICT_TGT;
+   case '7':
+     send_to_socket(sock, 
+ 		   "The message to room when a target is found : ");
+     return SOCEDIT_ROOM_TGT;
+   case '8':
+     olc_display_table(sock, posGetName, NUM_POSITIONS, 2);
+     return SOCEDIT_MIN_POS;
+   case '9':
+     olc_display_table(sock, posGetName, NUM_POSITIONS, 2);
+     return SOCEDIT_MAX_POS;
+   default: 
+     return MENU_CHOICE_INVALID;
+   }
+ }
+ 
+ bool socedit_parser(SOCKET_DATA *sock, SOCIAL_DATA *social, int choice, 
+ 		    const char *arg){
+   switch(choice) {
+   case SOCEDIT_CHAR_NOTGT:
+     socialSetCharNotgt(social, arg);
+     return TRUE;
+   case SOCEDIT_ROOM_NOTGT:
+     socialSetRoomNotgt(social, arg);
+     return TRUE;
+   case SOCEDIT_CHAR_SELF:
+     socialSetCharSelf(social, arg);
+     return TRUE;
+   case SOCEDIT_ROOM_SELF:
+     socialSetRoomSelf(social, arg);
+     return TRUE;
+   case SOCEDIT_CHAR_TGT:
+     socialSetCharTgt(social, arg);
+     return TRUE;
+   case SOCEDIT_VICT_TGT:
+     socialSetVictTgt(social, arg);
+     return TRUE;
+   case SOCEDIT_ROOM_TGT:
+     socialSetRoomTgt(social, arg);
+     return TRUE;
+   case SOCEDIT_MIN_POS: {
+     int val = atoi(arg);
+     if(!isdigit(*arg) || val < 0 || val >= NUM_POSITIONS)
+       return FALSE;
+     socialSetMinPos(social, val);
+     return TRUE;
+   }
+   case SOCEDIT_MAX_POS: {
+     int val = atoi(arg);
+     if(!isdigit(*arg) || val < 0 || val >= NUM_POSITIONS)
+       return FALSE;
+     socialSetMaxPos(social, val);
+     return TRUE;
+   }
+   default: 
+     return FALSE;
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // commands for entering socedit
+ //*****************************************************************************
+ void save_social(SOCIAL_DATA *social) {
+   save_socials();
+ }
+ 
+ COMMAND(cmd_socedit) {
+   SOCIAL_DATA *social;
+ 
+   if(!arg || !*arg)
+     send_to_char(ch, "Which social are you trying to edit?\r\n");
+   else {
+     // strip down to one argument
+     one_arg(arg, arg);
+ 
+     // find the social
+     social = get_social(arg);
+ 
+     // make sure we're not trying to edit a command
+     if(social == NULL && cmd_exists(arg))
+       send_to_char(ch, "But that is already a command!\r\n");
+     else {
+       // make a new one
+       if(social == NULL) {
+ 	social = newSocial(arg, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ 			   POS_STANDING, POS_STANDING);
+ 	add_social(social);
+       }
+ 
+       // set up the OLC
+       do_olc(charGetSocket(ch), socedit_menu, socedit_chooser, socedit_parser,
+ 	     socialCopy, socialCopyTo, deleteSocial, save_social, social);
+     }
+   }
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ // implementation of socedit.h
+ //*****************************************************************************
+ void init_socedit(void) {
+   add_cmd("socedit", NULL, cmd_socedit, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, TRUE);
+ }
diff -crN nakedmudv1.5/src/socials/socedit.d nakedmudv2.0/src/socials/socedit.d
*** nakedmudv1.5/src/socials/socedit.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/socials/socedit.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ socials/socedit.d socials/socedit.o: socials/socedit.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h character.h socket.h \
+   olc2/olc.h socials/socials.h
diff -crN nakedmudv1.5/src/socials/socedit.h nakedmudv2.0/src/socials/socedit.h
*** nakedmudv1.5/src/socials/socedit.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/socials/socedit.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,16 ----
+ #ifndef SOCEDIT_H
+ #define SOCEDIT_H
+ //*****************************************************************************
+ //
+ // socedit.h
+ //
+ // socedit is a set of tools for editing socials online. Socedit requires that
+ // olc2 be installed.
+ //
+ //*****************************************************************************
+ 
+ //
+ // prepare socedit for use. should be called by init_socials()
+ void init_socedit(void);
+ 
+ #endif // SOCEDIT_H
diff -crN nakedmudv1.5/src/socials/socials.c nakedmudv2.0/src/socials/socials.c
*** nakedmudv1.5/src/socials/socials.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/socials/socials.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,21 ****
--- 16,22 ----
  #include "../inform.h"
  #include "../character.h"
  
+ #include "socedit.h"
  #include "socials.h"
  
  
***************
*** 458,464 ****
    SOCIAL_DATA     *data = NULL;
  
    ITERATE_HASH(cmd, data, hash_i)
!     add_cmd(cmd, NULL, cmd_social, 0, POS_STANDING, POS_STANDING,
  	    LEVEL_PLAYER, TRUE, FALSE);
    deleteHashIterator(hash_i);
  
--- 459,465 ----
    SOCIAL_DATA     *data = NULL;
  
    ITERATE_HASH(cmd, data, hash_i)
!     add_cmd(cmd, NULL, cmd_social, 0, data->min_pos, data->max_pos, 
  	    LEVEL_PLAYER, TRUE, FALSE);
    deleteHashIterator(hash_i);
  
***************
*** 472,477 ****
--- 473,480 ----
  
    // let add_social know it can start saving again
    in_social_init = FALSE;
+ 
+   init_socedit();
  }
  
  
diff -crN nakedmudv1.5/src/socials/socials.d nakedmudv2.0/src/socials/socials.d
*** nakedmudv1.5/src/socials/socials.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/socials/socials.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ socials/socials.d socials/socials.o: socials/socials.c mud.h wrapsock.h property_table.h list.h \
+   map.h hashtable.h set.h buffer.h bitvector.h utils.h storage.h \
+   handler.h inform.h character.h socials/socedit.h socials/socials.h
diff -crN nakedmudv1.5/src/socket.c nakedmudv2.0/src/socket.c
*** nakedmudv1.5/src/socket.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/socket.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 11,28 ****
  /* including main header file */
  #include "mud.h"
  #include "character.h"
  #include "utils.h"
  #include "socket.h"
  
- #ifdef MODULE_OLC
- #include "olc/olc.h"
- #endif
  
  
  
  /* global variables */
  fd_set        fSet;             /* the socket list for polling       */
! 
  
  /* mccp support */
  const unsigned char compress_will   [] = { IAC, WILL, TELOPT_COMPRESS,  '\0' };
--- 11,68 ----
  /* including main header file */
  #include "mud.h"
  #include "character.h"
+ #include "save.h"
  #include "utils.h"
  #include "socket.h"
+ #include "auxiliary.h"
  
  
+ //
+ // Here it is... the big ol' datastructure for sockets. Yum.
+ //
+ struct socket_data {
+   CHAR_DATA     * player;
+   char          * hostname;
+   char            inbuf[MAX_INPUT_LEN];
+   char            outbuf[MAX_OUTPUT];
+   char            next_command[MAX_BUFFER];
+   bool            cmd_read;
+   bool            bust_prompt;
+   bool            closed;
+   sh_int          lookup_status;
+   sh_int          control;
+   sh_int          top_output;
+ 
+   char          * page_string;   // the string that has been paged to us
+   int             curr_page;     // the current page we're on
+   int             tot_pages;     // the total number of pages the string has
+   
+   BUFFER        * text_editor;   // where we do our actual work
+   char         ** text_pointer;  // where the work will go to
+ 
+   LIST          * input_handlers;// a stack of our input handlers and prompts
+ 
+   unsigned char   compressing;                 /* MCCP support */
+   z_stream      * out_compress;                /* MCCP support */
+   unsigned char * out_compress_buf;            /* MCCP support */
+ 
+   HASHTABLE     * auxiliary;     // auxiliary data installed by other modules
+ };
+ 
+ 
+ //
+ // contains an input handler and the socket prompt in one structure, so they
+ // can be stored together in the socket_data
+ //
+ typedef struct input_handler_data {
+   void (* handler)(SOCKET_DATA *, char *);
+   void (*  prompt)(SOCKET_DATA *);
+ } IH_PAIR;
  
  
  /* global variables */
  fd_set        fSet;             /* the socket list for polling       */
! fd_set        rFd;
  
  /* mccp support */
  const unsigned char compress_will   [] = { IAC, WILL, TELOPT_COMPRESS,  '\0' };
***************
*** 86,110 ****
    pthread_attr_init(&attr);   
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  
!   /*
!    * allocate some memory for a new socket if
!    * there is no free socket in the free_list
!    */
!   if( (sock_new = listPop(socket_free)) == NULL) {
!     if ((sock_new = malloc(sizeof(*sock_new))) == NULL)
!     {
!       bug("New_socket: Cannot allocate memory for socket.");
!       abort();
!     }
!     bzero(sock_new, sizeof(*sock_new));    
!   }
! 
  
    /* attach the new connection to the socket list */
    FD_SET(sock, &fSet);
  
    /* clear out the socket */
    clear_socket(sock_new, sock);
  
    /* set the socket as non-blocking */
    ioctl(sock, FIONBIO, &argp);
--- 126,141 ----
    pthread_attr_init(&attr);   
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  
!   /* create and clear the socket */
!   sock_new = malloc(sizeof(*sock_new));
!   bzero(sock_new, sizeof(*sock_new));
  
    /* attach the new connection to the socket list */
    FD_SET(sock, &fSet);
  
    /* clear out the socket */
    clear_socket(sock_new, sock);
+   sock_new->closed = FALSE;
  
    /* set the socket as non-blocking */
    ioctl(sock, FIONBIO, &argp);
***************
*** 199,205 ****
    }
  
    /* set the closed state */
!   dsock->state = STATE_CLOSED;
  }
  
  
--- 230,237 ----
    }
  
    /* set the closed state */
!   dsock->closed = TRUE;
!   //  dsock->state = STATE_CLOSED;
  }
  
  
***************
*** 391,402 ****
      return;
    }
  
-   // always start with a leading space if we don't need to bust a prompt
-   if(dsock->state == STATE_PLAYING && dsock->bust_prompt == FALSE) {
-     dsock->outbuf[0] = '\r';
-     dsock->outbuf[1] = '\n';
-     dsock->top_output = 2;
-   }
  
    while (*txt != '\0' && i++ < length)
    {
--- 423,428 ----
***************
*** 549,555 ****
    /* check to see if the socket can accept that much data */
    if (dsock->top_output + iPtr >= MAX_OUTPUT)
    {
!     bug("Text_to_buffer: ouput overflow on %s.", dsock->hostname);
      return;
    }
  
--- 575,587 ----
    /* check to see if the socket can accept that much data */
    if (dsock->top_output + iPtr >= MAX_OUTPUT)
    {
!     //
!     // what happens if the buffer overflow is on an immortal who can see the
!     // logs? We get tossed into an infinite loop... this really isn't too big
!     // of a deal to have to report. Let's just leave it out.
!     //   - Geoff, Mar 22/05
!     //
!     //    bug("Text_to_buffer: ouput overflow on %s.", dsock->hostname);
      return;
    }
  
***************
*** 640,662 ****
  
  bool flush_output(SOCKET_DATA *dsock)
  {
!   /* nothing to send */
!   if (dsock->top_output <= 0 && 
!       !((dsock->bust_prompt && 
! 	 (dsock->state == STATE_PLAYING || dsock->state == STATE_TEXT_EDITOR))))
      return TRUE;
  
!   /* bust a prompt */
!   if (dsock->state == STATE_PLAYING && dsock->bust_prompt) {
!     text_to_buffer(dsock, custom_prompt(dsock->player));
!     dsock->bust_prompt = FALSE;
!   }
!   else if(dsock->state == STATE_TEXT_EDITOR && dsock->bust_prompt) {
!     text_to_buffer(dsock, "] ");
      dsock->bust_prompt = FALSE;
    }
  
!   /* reset the top pointer */
    dsock->top_output = 0;
  
    /*
--- 672,689 ----
  
  bool flush_output(SOCKET_DATA *dsock)
  {
!   void (* prompt_func)(SOCKET_DATA *) = ((IH_PAIR *)listGet(dsock->input_handlers, 0))->prompt;
! 
!   // quit if we have no output and don't need/can't have a prompt
!   if(dsock->top_output <= 0 && (!dsock->bust_prompt || !prompt_func))
      return TRUE;
  
!   if(dsock->bust_prompt && prompt_func) {
!     prompt_func(dsock);
      dsock->bust_prompt = FALSE;
    }
  
!   // reset the top pointer
    dsock->top_output = 0;
  
    /*
***************
*** 666,672 ****
    if (!text_to_socket(dsock, dsock->outbuf))
      return FALSE;
  
!   /* Success */
    return TRUE;
  }
  
--- 693,699 ----
    if (!text_to_socket(dsock, dsock->outbuf))
      return FALSE;
  
!   // Success
    return TRUE;
  }
  
***************
*** 682,710 ****
  // getting their addresses, etc...)
  //
  //*****************************************************************************
  
  void clear_socket(SOCKET_DATA *sock_new, int sock)
  {
!   if(sock_new->page_string) free(sock_new->page_string);
!   if(sock_new->text_editor) buffer_free(sock_new->text_editor);
!   if(sock_new->notepad)     free(sock_new->notepad);
  
    bzero(sock_new, sizeof(*sock_new));
!   sock_new->control        =  sock;
!   sock_new->state          =  STATE_NEW_NAME;
!   sock_new->lookup_status  =  TSTATE_LOOKUP;
!   sock_new->player         =  NULL;
!   sock_new->top_output     =  0;
  
!   sock_new->text_editor    = NULL;
    sock_new->text_pointer   = NULL;
!   sock_new->notepad        = NULL;
!   sock_new->in_text_edit   = FALSE;
!   sock_new->max_text_len   = 0;
! 
! #ifdef MODULE_OLC
!   socketSetOLC(sock_new, NULL);
! #endif
  }
  
  
--- 709,742 ----
  // getting their addresses, etc...)
  //
  //*****************************************************************************
+ void deleteSocket(SOCKET_DATA *sock) {
+   if(sock->hostname)       free(sock->hostname);
+   if(sock->page_string)    free(sock->page_string);
+   if(sock->text_editor)    deleteBuffer(sock->text_editor);
+   if(sock->input_handlers) deleteListWith(sock->input_handlers, free);
+   if(sock->auxiliary)      deleteAuxiliaryData(sock->auxiliary);
+   free(sock);
+ }
  
  void clear_socket(SOCKET_DATA *sock_new, int sock)
  {
!   if(sock_new->page_string)    free(sock_new->page_string);
!   if(sock_new->text_editor)    deleteBuffer(sock_new->text_editor);
!   if(sock_new->input_handlers) deleteListWith(sock_new->input_handlers, free);
!   if(sock_new->auxiliary)      deleteAuxiliaryData(sock_new->auxiliary);
  
    bzero(sock_new, sizeof(*sock_new));
!   sock_new->auxiliary = newAuxiliaryData(AUXILIARY_TYPE_SOCKET);
!   sock_new->input_handlers = newList();
!   socketPushInputHandler(sock_new, handle_new_connections, NULL);
!   sock_new->control        = sock;
!   sock_new->lookup_status  = TSTATE_LOOKUP;
!   sock_new->player         = NULL;
!   sock_new->top_output     = 0;
  
!   sock_new->text_editor    = newBuffer(MAX_BUFFER);
    sock_new->text_pointer   = NULL;
!   //  sock_new->in_text_edit   = FALSE;
  }
  
  
***************
*** 736,741 ****
--- 768,774 ----
  
    /* and kill the thread */
    pthread_exit(0);
+   return NULL;
  }
  
  
***************
*** 754,767 ****
      /* close the socket */
      close(dsock->control);
  
-     /* free the memory */
-     free(dsock->hostname);
- 
      /* stop compression */
      compressEnd(dsock, dsock->compressing, TRUE);
  
!     /* put the socket in the free_list */
!     listPut(socket_free, dsock);
    }
    deleteListIterator(sock_i);
  }
--- 787,913 ----
      /* close the socket */
      close(dsock->control);
  
      /* stop compression */
      compressEnd(dsock, dsock->compressing, TRUE);
  
!     /* delete the socket from memory */
!     deleteSocket(dsock);
!   }
!   deleteListIterator(sock_i);
! }
! 
! 
! /* reset all of the sockets' control values */
! void reconnect_copyover_sockets() {
!   LIST_ITERATOR *sock_i = newListIterator(socket_list);
!   SOCKET_DATA     *sock = NULL; 
!   ITERATE_LIST(sock, sock_i)
!     FD_SET(sock->control, &fSet);
!   deleteListIterator(sock_i);
! }
! 
! 
! /* Recover from a copyover - load players */
! void copyover_recover()
! {     
!   CHAR_DATA *dMob;
!   SOCKET_DATA *dsock;
!   FILE *fp;
!   char name [100];
!   char host[MAX_BUFFER];
!   int desc;
!       
!   log_string("Copyover recovery initiated");
!    
!   if ((fp = fopen(COPYOVER_FILE, "r")) == NULL) {  
!     log_string("Copyover file not found. Exitting.");
!     exit (1);
!   }
!       
!   /* In case something crashes - doesn't prevent reading */
!   unlink(COPYOVER_FILE);
!     
!   for (;;) {  
!     fscanf(fp, "%d %s %s\n", &desc, name, host);
!     if (desc == -1)
!       break;
! 
!     dsock = malloc(sizeof(*dsock));
!     clear_socket(dsock, desc);
! 
!     dsock->hostname = strdup(host);
!     listPut(socket_list, dsock);
!  
!     /* load player data */
!     if ((dMob = load_player(name)) != NULL)
!     {
!       /* attach to socket */
!       charSetSocket(dMob, dsock);
!       socketSetChar(dsock, dMob);
! 
!       // try putting the character into the game
!       // close the socket if we fail.
!       try_enter_game(dMob);
!     }
!     else /* ah bugger */
!     {
!       close_socket(dsock, FALSE);
!       continue;
!     }
!    
!     /* Write something, and check if it goes error-free */
!     if (!text_to_socket(dsock, "\n\r <*>  And before you know it, everything has changed  <*>\n\r"))
!     { 
!       close_socket(dsock, FALSE);
!       continue;
!     }
!   
!     /* make sure the socket can be used */
!     dsock->bust_prompt    =  TRUE;
!     dsock->lookup_status  =  TSTATE_DONE;
!     socketReplaceInputHandler(dsock, handle_cmd_input, show_prompt);
! 
!     /* negotiate compression */
!     text_to_buffer(dsock, (char *) compress_will2);
!     text_to_buffer(dsock, (char *) compress_will);
!   }
!   fclose(fp);
! 
!   // now, set all of the sockets' control to the new fSet
!   reconnect_copyover_sockets();
! }     
! 
! void socket_handler() {
!   LIST_ITERATOR *sock_i = newListIterator(socket_list);
!   SOCKET_DATA     *sock = NULL; 
! 
!   ITERATE_LIST(sock, sock_i) {
!     /*
!      * Close sockects we are unable to read from, or if we have no handler
!      * to take in input
!      */
!     if ((FD_ISSET(sock->control, &rFd) && !read_from_socket(sock)) ||
! 	socketGetInputHandler(sock) == NULL) {
!       close_socket(sock, FALSE);
!       continue;
!     }
! 
!     /* Ok, check for a new command */
!     next_cmd_from_buffer(sock);
!     
!     /* Is there a new command pending ? */
!     if (sock->cmd_read) {
!       socketGetInputHandler(sock)(sock, sock->next_command);
!       sock->next_command[0] = '\0';
!       sock->cmd_read = FALSE;
!     }
!     
!     /* if the player quits or get's disconnected */
!     if(sock->closed) continue;
!     
!     /* Send all new data to the socket and close it if any errors occour */
!     if (!flush_output(sock))
!       close_socket(sock, FALSE);
    }
    deleteListIterator(sock_i);
  }
***************
*** 855,889 ****
    */
  }
  
  
  //*****************************************************************************
  //
  // get and set functions
  //
  //*****************************************************************************
- sh_int socketGetState       ( SOCKET_DATA *dsock) {
-   return dsock->state;
- }
- 
  CHAR_DATA *socketGetChar     ( SOCKET_DATA *dsock) {
    return dsock->player;
  }
  
! #ifdef MODULE_OLC
! OLC_DATA *socketGetOLC      ( SOCKET_DATA *dsock) {
!   return dsock->olc;
  }
  
! void socketSetOLC           ( SOCKET_DATA *dsock, OLC_DATA *olc) {
!   if(dsock->olc) deleteOLC(dsock->olc);
!   dsock->olc = olc;
  }
- #endif
  
! void socketSetState         ( SOCKET_DATA *dsock, sh_int state) {
!   dsock->state = state;
  }
  
! void       socketSetChar     ( SOCKET_DATA *dsock, CHAR_DATA *ch) {
!   dsock->player = ch;
  }
--- 1001,1330 ----
    */
  }
  
+ void do_copyover(CHAR_DATA *ch) {
+ 
+   FILE *fp;
+   SOCKET_DATA *dsock;
+   char buf[100];
+   char control_buf[20];
+   char port_buf[20];
+   LIST_ITERATOR *sock_i = newListIterator(socket_list);
+ 
+   if ((fp = fopen(COPYOVER_FILE, "w+")) == NULL)
+   {
+     text_to_char(ch, "Copyover file not writeable, aborted.\n\r");
+     return;
+   }
+ 
+   sprintf(buf, "\n\r <*>            The world starts spinning             <*>\n\r");
+ 
+   /* For each playing descriptor, save its state */
+   ITERATE_LIST(dsock, sock_i) {
+     compressEnd(dsock, dsock->compressing, FALSE);
+     if (!socketGetChar(dsock) || !charGetRoom(socketGetChar(dsock))) {
+       //(dsock->state != STATE_PLAYING) {
+       text_to_socket(dsock, "\r\nSorry, we are rebooting. Come back in a few minutes.\r\n");
+       close_socket(dsock, FALSE);
+     }
+     else {
+       fprintf(fp, "%d %s %s\n",
+ 	      dsock->control, charGetName(dsock->player), dsock->hostname);
+       /* save the player */
+       save_player(dsock->player);
+       text_to_socket(dsock, buf);
+     }
+   }
+   deleteListIterator(sock_i);
+   
+   fprintf (fp, "-1\n");
+   fclose (fp);
+ 
+ 
+   /* close any pending sockets */
+   recycle_sockets();
+   
+   /* exec - descriptors are inherited */
+   sprintf(control_buf, "%d", control);
+   sprintf(port_buf, "%d", mudport);
+   execl(EXE_FILE, "NakedMud", "-copyover", control_buf, port_buf, NULL);
+ 
+   /* Failed - sucessful exec will not return */
+   text_to_char(ch, "Copyover FAILED!\n\r");
+ }
+ 
  
  //*****************************************************************************
  //
  // get and set functions
  //
  //*****************************************************************************
  CHAR_DATA *socketGetChar     ( SOCKET_DATA *dsock) {
    return dsock->player;
  }
  
! void       socketSetChar     ( SOCKET_DATA *dsock, CHAR_DATA *ch) {
!   dsock->player = ch;
! }
! 
! char **socketGetTextPointer   ( SOCKET_DATA *sock) {
!   return sock->text_pointer;
  }
  
! void socketSetTextPointer (SOCKET_DATA *sock, char **ptr) {
!   sock->text_pointer = ptr;
  }
  
! BUFFER *socketGetTextEditor   ( SOCKET_DATA *sock) {
!   return sock->text_editor;
  }
  
! void socketPushInputHandler  ( SOCKET_DATA *socket, 
! 			       void handler(SOCKET_DATA *socket, char *input),
! 			       void prompt (SOCKET_DATA *socket)) {
!   IH_PAIR *pair = malloc(sizeof(IH_PAIR));
!   pair->handler = handler;
!   pair->prompt  = prompt;
!   listPush(socket->input_handlers, pair);
! }
! 
! void socketPopInputHandler   ( SOCKET_DATA *socket) {
!   IH_PAIR *pair = listPop(socket->input_handlers);
!   free(pair);
! }
! 
! void socketReplaceInputHandler( SOCKET_DATA *socket,
! 				void handler(SOCKET_DATA *socket, char *input),
! 				void prompt (SOCKET_DATA *socket)) {
!   socketPopInputHandler(socket);
!   socketPushInputHandler(socket, handler, prompt);
! }
! 
! void (*socketGetInputHandler ( SOCKET_DATA *socket))(SOCKET_DATA *, char *) {
!   return ((IH_PAIR *)listGet(socket->input_handlers, 0))->handler;
! }
! 
! void socketShowPrompt( SOCKET_DATA *sock) {
!   ((IH_PAIR *)listGet(sock->input_handlers, 0))->prompt(sock);
! }
! 
! void *socketGetAuxiliaryData  ( SOCKET_DATA *sock, const char *name) {
!   return hashGet(sock->auxiliary, name);
! }
! 
! const char *socketGetHostname(SOCKET_DATA *sock) {
!   return sock->hostname;
! }
! 
! sh_int socketGetDNSLookupStatus(SOCKET_DATA *sock) {
!   return sock->lookup_status;
! }
! 
! void socketBustPrompt(SOCKET_DATA *sock) {
!   sock->bust_prompt = TRUE;
  }
+ 
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // MCCP SUPPORT IS BELOW THIS LINE. NOTHING BUT MCCP SUPPORT SHOULD GO BELOW
+ // THIS LINE.
+ //
+ //*****************************************************************************
+ /*
+  * mccp.c - support functions for the Mud Client Compression Protocol
+  *
+  * see http://www.randomly.org/projects/MCCP/
+  *
+  * Copyright (c) 1999, Oliver Jowett <oliver@randomly.org>
+  *
+  * This code may be freely distributed and used if this copyright
+  * notice is retained intact.
+  */
+ /*
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ 
+ #include "mud.h"
+ #include "socket.h"
+ #include "utils.h"
+ */
+ 
+ /* local functions */
+ bool  processCompressed       ( SOCKET_DATA *dsock );
+ 
+ const unsigned char enable_compress  [] = { IAC, SB, TELOPT_COMPRESS, WILL, SE, 0 };
+ const unsigned char enable_compress2 [] = { IAC, SB, TELOPT_COMPRESS2, IAC, SE, 0 };
+ 
+ /*
+  * Memory management - zlib uses these hooks to allocate and free memory
+  * it needs
+  */
+ void *zlib_alloc(void *opaque, unsigned int items, unsigned int size)
+ {
+   return calloc(items, size);
+ }
+ 
+ void zlib_free(void *opaque, void *address)
+ {
+   free(address);
+ }
+ 
+ /*
+  * Begin compressing data on `desc'
+  */
+ bool compressStart(SOCKET_DATA *dsock, unsigned char teleopt)
+ {
+   z_stream *s;
+ 
+   /* already compressing */
+   if (dsock->out_compress)
+     return TRUE;
+ 
+   /* allocate and init stream, buffer */
+   s = (z_stream *) malloc(sizeof(*s));
+   dsock->out_compress_buf = (unsigned char *) malloc(COMPRESS_BUF_SIZE);
+ 
+   s->next_in    =  NULL;
+   s->avail_in   =  0;
+   s->next_out   =  dsock->out_compress_buf;
+   s->avail_out  =  COMPRESS_BUF_SIZE;
+   s->zalloc     =  zlib_alloc;
+   s->zfree      =  zlib_free;
+   s->opaque     =  NULL;
+ 
+   if (deflateInit(s, 9) != Z_OK)
+   {
+     free(dsock->out_compress_buf);
+     free(s);
+     return FALSE;
+   }
+ 
+   /* version 1 or 2 support */
+   if (teleopt == TELOPT_COMPRESS)
+     text_to_socket(dsock, (char *) enable_compress);
+   else if (teleopt == TELOPT_COMPRESS2)
+     text_to_socket(dsock, (char *) enable_compress2);
+   else
+   {
+     bug("Bad teleoption %d passed", teleopt);
+     free(dsock->out_compress_buf);
+     free(s);
+     return FALSE;
+   }
+ 
+   /* now we're compressing */
+   dsock->compressing = teleopt;
+   dsock->out_compress = s;
+ 
+   /* success */
+   return TRUE;
+ }
+ 
+ /* Cleanly shut down compression on `desc' */
+ bool compressEnd(SOCKET_DATA *dsock, unsigned char teleopt, bool forced)
+ {
+   unsigned char dummy[1];
+ 
+   if (!dsock->out_compress)
+     return TRUE;
+ 
+   if (dsock->compressing != teleopt)
+     return FALSE;
+ 
+   dsock->out_compress->avail_in = 0;
+   dsock->out_compress->next_in = dummy;
+   dsock->top_output = 0;
+ 
+   /* No terminating signature is needed - receiver will get Z_STREAM_END */
+   if (deflate(dsock->out_compress, Z_FINISH) != Z_STREAM_END && !forced)
+     return FALSE;
+ 
+   /* try to send any residual data */
+   if (!processCompressed(dsock) && !forced)
+     return FALSE;
+ 
+   /* reset compression values */
+   deflateEnd(dsock->out_compress);
+   free(dsock->out_compress_buf);
+   free(dsock->out_compress);
+   dsock->compressing      = 0;
+   dsock->out_compress     = NULL;
+   dsock->out_compress_buf = NULL;
+ 
+   /* success */
+   return TRUE;
+ }
+ 
+ /* Try to send any pending compressed-but-not-sent data in `desc' */
+ bool processCompressed(SOCKET_DATA *dsock)
+ {
+   int iStart, nBlock, nWrite, len;
+ 
+   if (!dsock->out_compress)
+     return TRUE;
+     
+   len = dsock->out_compress->next_out - dsock->out_compress_buf;
+   if (len > 0)
+   {
+     for (iStart = 0; iStart < len; iStart += nWrite)
+     {
+       nBlock = UMIN (len - iStart, 4096);
+       if ((nWrite = write(dsock->control, dsock->out_compress_buf + iStart, nBlock)) < 0)
+       {
+         if (errno == EAGAIN/* || errno == ENOSR*/)
+           break;
+ 
+         /* write error */
+         return FALSE;
+       }
+       if (nWrite <= 0)
+         break;
+     }
+ 
+     if (iStart)
+     {
+       if (iStart < len)
+         memmove(dsock->out_compress_buf, dsock->out_compress_buf+iStart, len - iStart);
+ 
+       dsock->out_compress->next_out = dsock->out_compress_buf + len - iStart;
+     }
+   }
+ 
+   /* success */
+   return TRUE;
+ }
+ 
+ 
+ //
+ // compress output
+ //
+ COMMAND(cmd_compress)
+ {
+   /* no socket, no compression */
+   if (!charGetSocket(ch))
+     return;
+ 
+   /* enable compression */
+   if (!charGetSocket(ch)->out_compress) {
+     text_to_char(ch, "Trying compression.\n\r");
+     text_to_buffer(charGetSocket(ch), (char *) compress_will2);
+     text_to_buffer(charGetSocket(ch), (char *) compress_will);
+   }
+   else /* disable compression */ {
+     if (!compressEnd(charGetSocket(ch), charGetSocket(ch)->compressing, FALSE)){
+       text_to_char(ch, "Failed.\n\r");
+       return;
+     }
+     text_to_char(ch, "Compression disabled.\n\r");
+   }
+ }
+ //*****************************************************************************
+ //
+ // IF YOU ARE PUTTING ANYTHING BELOW THIS LINE, YOU ARE PUTTING IT IN THE WRONG
+ // PLACE!! ALL SOCKET-RELATED STUFF SHOULD GO UP ABOVE THE MCCP SUPPORT STUFF!
+ //
+ //*****************************************************************************
diff -crN nakedmudv1.5/src/socket.d nakedmudv2.0/src/socket.d
*** nakedmudv1.5/src/socket.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/socket.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ socket.d socket.o: socket.c wrapsock.h mud.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h character.h save.h utils.h \
+   socket.h auxiliary.h
diff -crN nakedmudv1.5/src/socket.h nakedmudv2.0/src/socket.h
*** nakedmudv1.5/src/socket.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/socket.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,6 ****
! #ifndef __SOCKET_H
! #define __SOCKET_H
! 
  //*****************************************************************************
  //
  // socket.h
--- 1,5 ----
! #ifndef SOCKET_H
! #define SOCKET_H
  //*****************************************************************************
  //
  // socket.h
***************
*** 9,59 ****
  //
  //*****************************************************************************
  
- 
- 
- /* I'd be much happier of we hid this datastructure in a
-    separate file at some point */
- struct socket_data
- {
-   CHAR_DATA     * player;
-   char          * hostname;
-   char            inbuf[MAX_INPUT_LEN];
-   char            outbuf[MAX_OUTPUT];
-   char            next_command[MAX_BUFFER];
-   bool            cmd_read;
-   bool            bust_prompt;
-   sh_int          lookup_status;
-   sh_int          state;
-   sh_int          control;
-   sh_int          top_output;
- 
-   char          * page_string;   // the string that has been paged to us
-   int             curr_page;     // the current page we're on
-   int             tot_pages;     // the total number of pages the string has
-   
-   bool            in_text_edit;  // are we doing text editing?
-   BUFFER        * text_editor;   // where we do our actual work
-   char         ** text_pointer;  // where the work will go to
-   char          * notepad;       // a buffer for writing messages of any type
-   int             max_text_len;  // the max length we are allowed
-   int             editor_mode;   // what mode are we running the editor under?
-   int             indent;        // how far do we indent (script editing)
-   sh_int          old_state;     // the state we were in before text editing
- 
-   unsigned char   compressing;                 /* MCCP support */
-   z_stream      * out_compress;                /* MCCP support */
-   unsigned char * out_compress_buf;            /* MCCP support */
- 
- #ifdef MODULE_OLC
-   OLC_DATA      * olc;
- #endif
- };
- 
- 
  int   init_socket           ( void );
  bool  new_socket            ( int sock );
  void  close_socket          ( SOCKET_DATA *dsock, bool reconnect );
  bool  read_from_socket      ( SOCKET_DATA *dsock );
  
  /* sends the output directly */
  bool  text_to_socket        ( SOCKET_DATA *dsock, const char *txt );
--- 8,20 ----
  //
  //*****************************************************************************
  
  int   init_socket           ( void );
  bool  new_socket            ( int sock );
  void  close_socket          ( SOCKET_DATA *dsock, bool reconnect );
  bool  read_from_socket      ( SOCKET_DATA *dsock );
+ void  socket_handler        ( void );
+ void  copyover_recover      ( void );
+ void  do_copyover           ( CHAR_DATA *ch);
  
  /* sends the output directly */
  bool  text_to_socket        ( SOCKET_DATA *dsock, const char *txt );
***************
*** 61,67 ****
  
  /* buffers the output        */
  void  text_to_buffer        ( SOCKET_DATA *dsock, const char *txt );
- 
  void  next_cmd_from_buffer  ( SOCKET_DATA *dsock );
  bool  flush_output          ( SOCKET_DATA *dsock );
  void  handle_new_connections( SOCKET_DATA *dsock, char *arg );
--- 22,27 ----
***************
*** 75,91 ****
  // set and get functions
  //
  //*****************************************************************************
! #ifdef MODULE_OLC
! OLC_DATA  *socketGetOLC      ( SOCKET_DATA *dsock);
! #endif
! sh_int     socketGetState    ( SOCKET_DATA *dsock);
! CHAR_DATA *socketGetChar     ( SOCKET_DATA *dsock);
  
! #ifdef MODULE_OLC
! void       socketSetOLC      ( SOCKET_DATA *dsock, OLC_DATA *olc);
! #endif
! void       socketSetState    ( SOCKET_DATA *dsock, sh_int state);
  void       socketSetChar     ( SOCKET_DATA *dsock, CHAR_DATA *ch);
  
  
! #endif // __SOCKET_H
--- 35,60 ----
  // set and get functions
  //
  //*****************************************************************************
! sh_int socketGetDNSLookupStatus( SOCKET_DATA *sock);
  
! CHAR_DATA *socketGetChar     ( SOCKET_DATA *dsock);
  void       socketSetChar     ( SOCKET_DATA *dsock, CHAR_DATA *ch);
  
+ void socketPushInputHandler   ( SOCKET_DATA *socket, 
+ 			        void handler(SOCKET_DATA *socket, char *input),
+ 				void prompt (SOCKET_DATA *socket));
+ void socketReplaceInputHandler( SOCKET_DATA *socket,
+ 				void handler(SOCKET_DATA *socket, char *input),
+ 				void prompt (SOCKET_DATA *socket));
+ void socketPopInputHandler    ( SOCKET_DATA *socket);
+ void (*socketGetInputHandler  ( SOCKET_DATA *socket))(SOCKET_DATA *, char *);
+ void socketShowPrompt         ( SOCKET_DATA *sock);
+ void *socketGetAuxiliaryData  ( SOCKET_DATA *sock, const char *name);
+ const char *socketGetHostname ( SOCKET_DATA *sock);
+ BUFFER *socketGetTextEditor   ( SOCKET_DATA *sock);
+ char **socketGetTextPointer   ( SOCKET_DATA *sock);
+ void socketSetTextPointer     ( SOCKET_DATA *sock, char **ptr);
+ 
+ void socketBustPrompt         ( SOCKET_DATA *sock);
  
! #endif // SOCKET_H
diff -crN nakedmudv1.5/src/storage.d nakedmudv2.0/src/storage.d
*** nakedmudv1.5/src/storage.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/storage.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ storage.d storage.o: storage.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h storage.h
diff -crN nakedmudv1.5/src/strings.c nakedmudv2.0/src/strings.c
*** nakedmudv1.5/src/strings.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/strings.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 87,92 ****
--- 87,95 ----
    return fStr;
  }
  
+ char *two_args(char *from, char *arg1, char *arg2) {
+   return one_arg(one_arg(from, arg1), arg2);
+ }
  
  //
  // pull out the argument of the specified number
***************
*** 155,257 ****
  
    return NULL;
  }
- 
- /*  
-  * Create a new buffer.
-  */
- BUFFER *__buffer_new(int size)
- {
-   BUFFER *buffer;
-     
-   buffer = malloc(sizeof(BUFFER));
-   buffer->size = size;
-   buffer->data = malloc(size); *(buffer->data) = '\0';
-   buffer->len = 0;
-   return buffer;
- }
- 
- /*
-  * Add a string to a buffer. Expand if necessary
-  */
- void __buffer_strcat(BUFFER *buffer, const char *text)  
- {
-   int new_size;
-   int text_len;
-   char *new_data;
-  
-   /* Adding NULL string ? */
-   if (!text)
-     return;
- 
-   text_len = strlen(text);
-     
-   /* Adding empty string ? */ 
-   if (text_len == 0)
-     return;
- 
-   /* Will the combined len of the added text and the current text exceed our buffer? */
-   if ((text_len + buffer->len + 1) > buffer->size)
-   { 
-     new_size = buffer->size + text_len + 1;
-    
-     /* Allocate the new buffer */
-     new_data = malloc(new_size);
-   
-     /* Copy the current buffer to the new buffer */
-     memcpy(new_data, buffer->data, buffer->len);
-     free(buffer->data);
-     buffer->data = new_data;  
-     buffer->size = new_size;
-   }
-   memcpy(buffer->data + buffer->len, text, text_len);
-   buffer->len += text_len;
-   buffer->data[buffer->len] = '\0';
- }
- 
- /* free a buffer */
- void buffer_free(BUFFER *buffer)
- {
-   /* Free data */
-   free(buffer->data);
-  
-   /* Free buffer */
-   free(buffer);
- }
- 
- /* Clear a buffer's contents, but do not deallocate anything */
- void buffer_clear(BUFFER *buffer)
- {
-   buffer->len = 0;  
-   *buffer->data = '\0';
- }
- 
- /* print stuff, append to buffer. safe. */
- int bprintf(BUFFER *buffer, char *fmt, ...)
- {  
-   char buf[MAX_BUFFER];
-   va_list va;
-   int res;
-     
-   va_start(va, fmt);
-   res = vsnprintf(buf, MAX_BUFFER, fmt, va);
-   va_end(va);
-     
-   if (res >= MAX_BUFFER - 1)  
-   {
-     buf[0] = '\0';
-     bug("Overflow when printing string %s", fmt);
-   }
-   else
-     buffer_strcat(buffer, buf);
-    
-   return res;
- }
- 
- /* return a pointer to the buffer data */
- const char *buffer_string(BUFFER *buffer) {
-   return buffer->data;
- }
- 
- void buffer_format(BUFFER *buffer, bool indent) {
-   format_string(&buffer->data, 80, buffer->size, indent);
- }
--- 158,160 ----
diff -crN nakedmudv1.5/src/strings.d nakedmudv2.0/src/strings.d
*** nakedmudv1.5/src/strings.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/strings.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ strings.d strings.o: strings.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h
diff -crN nakedmudv1.5/src/text_editor.c nakedmudv2.0/src/text_editor.c
*** nakedmudv1.5/src/text_editor.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/text_editor.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,439 ****
- //*****************************************************************************
- //
- // text_editor.c
- //
- // a small online text editor for people to use. Good for editing room
- // descriptions, board messages, notes, and other long strings.
- //
- //*****************************************************************************
- 
- #include <strings.h>
- 
- #include "mud.h"
- #include "socket.h"
- #include "text_editor.h"
- #include "utils.h"
- 
- // optional modules
- #ifdef MODULE_SCRIPTS
- #include "scripts/script.h"
- #endif
- #ifdef MODULE_OLC
- #include "olc/olc.h"
- #endif
- 
- 
- // different formatting types
- #define FORMAT_INDENT     (1 << 0)
- #define FORMAT_SCRIPT     (1 << 1)
- 
- //
- // sends a list of the control options to the socket
- //
- void show_text_editor_help( SOCKET_DATA *sock) {
-   send_to_socket(sock,
- 	"Text Editor Options:\r\n"
- 	"  /s   /q       save and quit\r\n"
- 	"  /h   /?       bring up the editor options\r\n"
- 	"  /a            abort without saving changes\r\n"  
- 	"  /l            list the current buffer\r\n"
- 	"  /c            clear the buffer\r\n"
- 	"  /n            insert a new line\r\n"
- 	"  /d#           delete line with the specified number\r\n"
- 	"  /i# [text]    insert text at the specified line number\r\n"
- 	"  /e# [text]    changes the text at line # with the new text\r\n"
- 	"  /r  'a' 'b'   replace the first occurance of 'a' with 'b'\r\n"
- 	"  /ra 'a' 'b'   replace all occurances of 'a' with 'b'\r\n"
- 	"  /f            formats the text\r\n"
- 	"  /fi           formats the text with an indent\r\n"
- 	"  /v            drop indentation down (used for script editing)\r\n"
- 	"  /^            push indentation up (used for script editing\r\n\r\n"
- 		 );
- }
- 
- 
- 
- //
- // replace occurances of a with b
- //
- void text_editor_replace(SOCKET_DATA *sock, char *a, char *b, bool all) {
-   char *text = strdup(buffer_string(sock->text_editor));
-   int found = replace_string(&text, a, b, all);
- 
-   buffer_clear(sock->text_editor);
-   buffer_strcat(sock->text_editor, text);
-   free(text);
-   send_to_socket(sock, "Replacing '%s' with '%s'. %d occurances replaced.\r\n",
- 		 a, b, found);
- }
- 
- 
- //
- // Doubles as delete when newline == NULL
- //
- void text_editor_insert(SOCKET_DATA *sock,
- 			char *newline, int line) {
-   char buf[MAX_BUFFER];
-   const char *ptr = buffer_string(sock->text_editor);
-   int curr_line = 1;
-   int i = 0;
- 
-   for(i = 0; curr_line < line; i++) {
-     // we've hit the end before we found our line
-     if(ptr[i] == '\0') {
-       send_to_socket(sock, "Line %d not found.\r\n", line);
-       return;
-     }
- 
-     if(ptr[i] == '\n')
-       curr_line++;
-     buf[i] = ptr[i];
-   }
- 
-   // copy it all over
-   sprintf(buf+i, "%s%s", newline, (sock->editor_mode == EDITOR_MODE_SCRIPT ?
- 				   "\n" : "\r\n"));
-   strcat(buf, ptr+i);
- 
-   // set the new text editor's values
-   buffer_clear(sock->text_editor);
-   buffer_strcat(sock->text_editor, buf);
-   send_to_socket(sock, "Line inserted.\r\n");
- }
- 
- 
- //
- // replace the line number with the new value
- //
- void text_editor_edit(SOCKET_DATA *sock, char *newline, char line) {
-   char buf[MAX_BUFFER];
-   const char *ptr = buffer_string(sock->text_editor);
-   int curr_line = 1;
-   int i = 0;
- 
-   for(i = 0; curr_line < line; i++) {
-     // we've hit the end before we found our line
-     if(ptr[i] == '\0') {
-       send_to_socket(sock, "Line %d not found.\r\n", line);
-       return;
-     }
- 
-     buf[i] = ptr[i];
-     if(ptr[i] == '\n')
-       curr_line++;
-   }
- 
-   // copy it all over
-   snprintf(&buf[i], MAX_BUFFER - i - 1, "%s%s", 
- 	   (newline == NULL ? "" : newline), 
- 	   // don't add returns to the very end of the buffer, or
- 	   // when we are deleting a line (newline == NULL)
- 	   ((ptr[i] == '\0' || newline == NULL) ? "" : 
- 	    (sock->editor_mode == EDITOR_MODE_SCRIPT ? "\n" :"\r\n")));
- 
- 
-   // skip the next line
-   for(; ptr[i] != '\0'; i++) {
-     if(ptr[i] == '\n') {
-       i++;
-       break;
-     }
-   }
- 
-   // copy the remaining data over
-   strncat(buf, &ptr[i], MAX_BUFFER - i - 1);
- 
-   // set the new text editor's values
-   buffer_clear(sock->text_editor);
-   buffer_strcat(sock->text_editor, buf);
-   send_to_socket(sock, "%d Line replaced.\r\n", line);
- }
- 
- 
- //
- // format the string of text
- //
- void text_editor_format(SOCKET_DATA *sock, bitvector_t options) {
-   char *buf = strdup(buffer_string(sock->text_editor));
- 
- #ifdef MODULE_SCRIPTS
-   if(IS_SET(options, FORMAT_SCRIPT))
-     format_script(&(buf), MAX_BUFFER);
-   else
- #endif
-     format_string(&(buf), 80, MAX_BUFFER, IS_SET(options, FORMAT_INDENT));
- 
-   buffer_clear(sock->text_editor);
-   buffer_strcat(sock->text_editor, buf);
-   free(buf);
- 
-   send_to_socket(sock, "Buffer formatted%s.\r\n", 
- 		 (IS_SET(options, FORMAT_INDENT) ? " with indent" : 
- 		  (IS_SET(options, FORMAT_SCRIPT) ? " as script" : "")));
- }
- 
- 
- //
- // Display the text editor to the socket
- //
- void text_editor_display(SOCKET_DATA *sock, int mode, bool show_line_nums) {
-   // just print the buffer if we don't need line nums
-   if(!*buffer_string(sock->text_editor))
-     send_to_socket(sock, "The buffer is empty.\r\n");
- #ifdef MODULE_SCRIPTS
-   // check if it's a script
-   else if(mode == EDITOR_MODE_SCRIPT)
-     script_display(sock, buffer_string(sock->text_editor), show_line_nums);
-   // otherwise just cat the buffer
- #endif
-   else
-     send_to_socket(sock, "%s\r\n", buffer_string(sock->text_editor));
- 
- }
- 
- 
- void text_editor_loop (SOCKET_DATA *sock, char *arg) {
-   // control command
-   if(*arg == '/') {
-     switch(*(arg+1)) {
-     case 's':
-     case 'S':
-     case 'q':
-     case 'Q':
-       if(*(sock->text_pointer))
- 	free(*(sock->text_pointer));
-       *(sock->text_pointer) = strdup(buffer_string(sock->text_editor));
-       // fall through
-     case 'a':
-     case 'A':
-       buffer_free(sock->text_editor);
-       //      free(sock->text_pointer);
-       sock->text_pointer = NULL;
-       sock->state = sock->old_state;
-       sock->in_text_edit = FALSE;
- 
- #ifdef MODULE_OLC
-       // OLC is annoying, in that is uses the text editor for certain things
-       // (e.g. room descriptions) but doesn't really have a way of
-       // re-displaying the menu once the editing is done, in the game. So
-       // here we have to put a little hack to make it display whenever we
-       // exit OLC.
-       if(sock->state == STATE_OLC)
- 	olc_menu(sock);
- #endif
-       break;
- 
-     case 'i':
-     case 'I': {
-       int line = 0;
-       sscanf((arg+2), "%d", &line);
- 
-       // skip the number and the first space
-       while(isdigit(*(arg+2)))
- 	arg++;
-       if(isspace(*(arg+2))) arg++;
- 
-       text_editor_insert(sock, (arg+2), line);
-       break;
-     }
- 
-     case 'e':
-     case 'E': {
-       int line = 0;
-       sscanf((arg+2), "%d", &line);
- 
-       // skip the number and the first space
-       while(isdigit(*(arg+2)))
- 	arg++;
-       if(isspace(*(arg+2))) arg++;
- 
-       text_editor_edit(sock, (arg+2), line);
-       break;
-     }
- 
-     case 'd':
-     case 'D': {
-       int line = 0;
-       sscanf((arg+2), "%d", &line);
- 
-       // skip the number
-       while(isdigit(*(arg+2)))
- 	arg++;
- 
-       text_editor_edit(sock, NULL, line);
-       break;
-     }
- 
-     case 'n':
-     case 'N':
-       send_to_socket(sock, "New line inserted.\r\n");
-       if(sock->editor_mode == EDITOR_MODE_NORMAL)
- 	buffer_strcat(sock->text_editor, "\r\n");
-       else if(sock->editor_mode == EDITOR_MODE_SCRIPT)
- 	buffer_strcat(sock->text_editor, "\n");
-       break;
- 
-     case 'l':
-     case 'L': {
-       text_editor_display(sock, sock->editor_mode, TRUE);
-       if(sock->editor_mode == EDITOR_MODE_NORMAL) {
- 	int linecount = 0;
- 	if(buffer_string(sock->text_editor))
- 	  linecount = count_letters(buffer_string(sock->text_editor), '\n', 
- 				    strlen(buffer_string(sock->text_editor)));
- 	send_to_socket(sock, "%d line%s displayed.\r\n", linecount,
- 		       (linecount == 1 ? "" : "s"));
-       }
-       break;
-     }
- 
-     case 'f':
-     case 'F':
-       text_editor_format(sock, toupper(*(arg+2)) == 'I' ? FORMAT_INDENT : 0);
-       break;
- 
-     case 'r':
-     case 'R': {
-       bool all = FALSE;
-       char *a;
-       char *b;
- 
-       if(count_letters(arg, '\'', strlen(arg)) != 4) {
- 	send_to_socket(sock, "format is: /r[a] 'to replace' 'replacement'\r\n");
- 	break;	
-       }
- 
-       if(toupper(*(arg+2)) == 'A')
- 	all = TRUE;
- 
-       // kill everything before the first '
-       strtok(arg, "\'");
- 
-       a = strtok(NULL, "\'");
-       if(a == NULL) {
- 	send_to_socket(sock, "format is: /r[a] 'to replace' 'replacement'\r\n");
- 	break;
-       }
- 
-       // kill the leading the leading ' of b
-       strtok(NULL, "\'");
- 
-       b = strtok(NULL, "\'");
-       if(b == NULL)
- 	b = "\0"; // "\0" will get deleted at the end of this block
- 
-       text_editor_replace(sock, a, b, all);
-       break;
-     }
- 
-     case 'v':
-     case 'V':
-       sock->indent -= 2;
-       if(sock->indent < 0) sock->indent = 0;
-       send_to_socket(sock, "Dropped indent to %d spaces.\r\n", sock->indent);
-       break;
- 
-     case '^':
-       sock->indent += 2;
-       if(sock->indent < 0) sock->indent = 0;
-       send_to_socket(sock, "Upped indent to %d spaces.\r\n", sock->indent);
-       break;
- 
-     case 'c':
-     case 'C':
-       sock->indent = 0;
-       buffer_clear(sock->text_editor);
-       send_to_socket(sock, "Buffer cleared.\r\n");
-       break;
- 
-     case 'h':
-     case 'H':
-     case '?':
-     default:
-       show_text_editor_help(sock);
-       break;
-     }
-   }
-   else {
-     // no newline on the first line
-     //
-     // bprintf was removed, because it causes problems if the
-     // text we're editing has any %d's or %s's or whatnot in it
-     // (e.g. when we're editing a script).
-     // 
-     if(sock->editor_mode == EDITOR_MODE_NORMAL) {
-       // print our text
-       buffer_strcat(sock->text_editor, arg);
- 
-       // print the newline
-       buffer_strcat(sock->text_editor, "\r\n");      
-     }
- 
-     else if(sock->editor_mode == EDITOR_MODE_SCRIPT) {
-       // get rid of all trailing and leading white spaces
-       trim(arg);
- 
-       // print spaces for our indent
-       if(sock->indent > 0) {
- 	char fmt[8] = "%%-%ds\0";
- 	sprintf(fmt, fmt, sock->indent);
- 	bprintf(sock->text_editor, fmt, " ");
-       }
- 
-       // print our text
-       buffer_strcat(sock->text_editor, arg);
- 
-       // print the newline
-       // python chokes on carraige returns, so we only have a newline here
-       buffer_strcat(sock->text_editor, "\n");
- 
-       // if the last character is a colon, we need to up our indent
-       if(arg[strlen(arg)-1] == ':')
- 	sock->indent += 2;
-     }
- 
- 
-     else {
-       log_string("ERROR: Socket in invalid editor mode, %d", sock->editor_mode);
-       send_to_socket(sock, 
- 		     "You are in an invalid editor mode, and your last line "
- 		     "was not appended.\r\n");
-     }
-   }
- }
- 
- void start_notepad(SOCKET_DATA *sock, const char *txt, int max_len, 
- 		   int mode) {
-   if(sock->notepad) free(sock->notepad);
-   sock->notepad = strdup(txt ? txt : "");
-   start_text_editor(sock, &sock->notepad, max_len, mode);
- }
- 
- void start_text_editor( SOCKET_DATA *sock, char **text, int max_len, int mode) {
-   // we're already in edit mode ... don't mess around
-   if(sock->state == STATE_TEXT_EDITOR)
-     return;
- 
-   sock->old_state = sock->state;
-   sock->state     = STATE_TEXT_EDITOR;
- 
-   sock->text_editor  = buffer_new(max_len);
- 
-   
-   buffer_strcat(sock->text_editor, (text ? *text : ""));
-   // bprintf has been canned! Screws up if we have %d or %s (e.g. for scripts)
-   // in there.
-   //  bprintf(sock->text_editor, (text ? *text : "\0"));
-   sock->text_pointer = text;
-   sock->max_text_len = max_len;
-   sock->in_text_edit = TRUE;
-   sock->editor_mode  = mode;
-   sock->indent       = 0;
- 
-   send_to_socket(sock,
- "========================================================================\r\n"
- "Begin text editing. /s on a new line to save, /a to abort. /h for help  \r\n"
- "========================================================================\r\n"
- 	 );
-   text_editor_display(sock, sock->editor_mode, TRUE);
- }
--- 0 ----
diff -crN nakedmudv1.5/src/text_editor.h nakedmudv2.0/src/text_editor.h
*** nakedmudv1.5/src/text_editor.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/text_editor.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,22 ****
- #ifndef __TEXT_EDITOR_H
- #define __TEXT_EDITOR_H
- //*****************************************************************************
- //
- // text_editor.h
- //
- // a small online text editor for people to use. Good for editing room
- // descriptions, board messages, notes, and other long strings.
- //
- //*****************************************************************************
- 
- 
- 
- #define EDITOR_MODE_NORMAL        0
- #define EDITOR_MODE_SCRIPT        1
- 
- void start_text_editor(SOCKET_DATA *sock, char **text, int max_len, int mode);
- void text_editor_loop (SOCKET_DATA *sock, char *arg);
- void start_notepad    (SOCKET_DATA *sock, const char *txt, int max_len, 
- 		       int mode);
- 
- #endif //__TEXT_EDITOR_H
--- 0 ----
diff -crN nakedmudv1.5/src/time/mudtime.h nakedmudv2.0/src/time/mudtime.h
*** nakedmudv1.5/src/time/mudtime.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/time/mudtime.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 4,10 ****
  //
  // mudtime.h
  //
! // We can't use time.c, because it is a standard C header. A small module for
  // handling time of day in the MUD.
  //
  //*****************************************************************************
--- 4,10 ----
  //
  // mudtime.h
  //
! // We can't use time.h, because it is a standard C header. A small module for
  // handling time of day in the MUD.
  //
  //*****************************************************************************
***************
*** 15,20 ****
--- 15,25 ----
  // #define MODULE_TIME
  //
  
+ #define MUD_HOUR       * 5 MINUTES
+ #define MUD_HOURS      * 5 MINUTES
+ 
+ 
+ 
  //
  // Set up the time module
  //
***************
*** 55,73 ****
  
  
  //
- // Tell the character information about the time
- // 
- COMMAND(cmd_time);
- 
- 
- //
  // If we have the time module installed, there is the option of
  // supplying a night description for the room, that will be shifted
  // to when it becomes evening/night time.
  //
! const char *roomGetNightDesc   (ROOM_DATA *room);
! char      **roomGetNightDescPtr(ROOM_DATA *room);
! void        roomSetNightDesc   (ROOM_DATA *room, const char *desc);
  
  
  #endif // __MUDTIME_H
--- 60,72 ----
  
  
  //
  // If we have the time module installed, there is the option of
  // supplying a night description for the room, that will be shifted
  // to when it becomes evening/night time.
  //
! const char *roomGetNightDesc      (ROOM_DATA *room);
! BUFFER     *roomGetNightDescBuffer(ROOM_DATA *room);
! void        roomSetNightDesc      (ROOM_DATA *room, const char *desc);
  
  
  #endif // __MUDTIME_H
diff -crN nakedmudv1.5/src/time/time.c nakedmudv2.0/src/time/time.c
*** nakedmudv1.5/src/time/time.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/time/time.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 19,30 ****
  
  
  #define TIME_FILE   "../lib/misc/time"  // where do we keep time data?
! #define TIME_UPDATE_DELAY    5 MINUTES  // how long is an in-game hour?
  #define HOURS_PER_DAY               24  // how many hours are in a day?
  #define NUM_MONTHS                   4  // how many months are in a year?
  #define DAYS_PER_WEEK                3  // how many days are in a week?
  #define USE_AMPM                  TRUE  // do we use the am/pm system?
  
  
  struct month_data {
    char *name;             // what is the name of the month?
--- 19,32 ----
  
  
  #define TIME_FILE   "../lib/misc/time"  // where do we keep time data?
! #define TIME_UPDATE_DELAY   1 MUD_HOUR  // how long is an in-game hour?
  #define HOURS_PER_DAY               24  // how many hours are in a day?
  #define NUM_MONTHS                   4  // how many months are in a year?
  #define DAYS_PER_WEEK                3  // how many days are in a week?
  #define USE_AMPM                  TRUE  // do we use the am/pm system?
  
+ COMMAND(cmd_time);                      // a player command for seeing the time
+ 
  
  struct month_data {
    char *name;             // what is the name of the month?
***************
*** 71,96 ****
  //
  //*****************************************************************************
  typedef struct time_aux_data {
!   char *night_desc;        // our description at night time
  } TIME_AUX_DATA;
  
  TIME_AUX_DATA *
  newTimeAuxData() {
    TIME_AUX_DATA *data = malloc(sizeof(TIME_AUX_DATA));
!   data->night_desc = strdup("");
    return data;
  }
  
  void
  deleteTimeAuxData(TIME_AUX_DATA *data) {
!   if(data->night_desc) free(data->night_desc);
    free(data);
  }
  
  void
  timeAuxDataCopyTo(TIME_AUX_DATA *from, TIME_AUX_DATA *to) {
!   if(to->night_desc) free(to->night_desc);
!   to->night_desc = strdup(from->night_desc ? from->night_desc : "");
  }
  
  TIME_AUX_DATA *
--- 73,97 ----
  //
  //*****************************************************************************
  typedef struct time_aux_data {
!   BUFFER *night_desc;        // our description at night time
  } TIME_AUX_DATA;
  
  TIME_AUX_DATA *
  newTimeAuxData() {
    TIME_AUX_DATA *data = malloc(sizeof(TIME_AUX_DATA));
!   data->night_desc = newBuffer(1);
    return data;
  }
  
  void
  deleteTimeAuxData(TIME_AUX_DATA *data) {
!   if(data->night_desc) deleteBuffer(data->night_desc);
    free(data);
  }
  
  void
  timeAuxDataCopyTo(TIME_AUX_DATA *from, TIME_AUX_DATA *to) {
!   bufferCopyTo(from->night_desc, to->night_desc);
  }
  
  TIME_AUX_DATA *
***************
*** 102,135 ****
  
  STORAGE_SET *timeAuxDataStore(TIME_AUX_DATA *data) {
    STORAGE_SET *set = new_storage_set();
!   store_string(set, "night_desc", data->night_desc);
    return set;
  }
  
  TIME_AUX_DATA *timeAuxDataRead(STORAGE_SET *set) {
!   TIME_AUX_DATA *data = malloc(sizeof(TIME_AUX_DATA));
!   data->night_desc = strdup(read_string(set, "night_desc"));
    return data;
  }
  
  const char *roomGetNightDesc(ROOM_DATA *room) {
    TIME_AUX_DATA *data = roomGetAuxiliaryData(room, "time_aux_data");
!   return data->night_desc;
  }
  
! char **roomGetNightDescPtr(ROOM_DATA *room) {
    TIME_AUX_DATA *data = roomGetAuxiliaryData(room, "time_aux_data");
!   return &(data->night_desc);
  }
  
  void roomSetNightDesc(ROOM_DATA *room, const char *desc) {
    TIME_AUX_DATA *data = roomGetAuxiliaryData(room, "time_aux_data");
!   if(data->night_desc) free(data->night_desc);
!   data->night_desc = strdup(desc ? desc : "");
  }
  
  
- 
  //*****************************************************************************
  //
  // time handling functions
--- 103,135 ----
  
  STORAGE_SET *timeAuxDataStore(TIME_AUX_DATA *data) {
    STORAGE_SET *set = new_storage_set();
!   store_string(set, "night_desc", bufferString(data->night_desc));
    return set;
  }
  
  TIME_AUX_DATA *timeAuxDataRead(STORAGE_SET *set) {
!   TIME_AUX_DATA *data = newTimeAuxData();
!   bufferCat(data->night_desc, read_string(set, "night_desc"));
    return data;
  }
  
  const char *roomGetNightDesc(ROOM_DATA *room) {
    TIME_AUX_DATA *data = roomGetAuxiliaryData(room, "time_aux_data");
!   return bufferString(data->night_desc);
  }
  
! BUFFER *roomGetNightDescBuffer(ROOM_DATA *room) {
    TIME_AUX_DATA *data = roomGetAuxiliaryData(room, "time_aux_data");
!   return data->night_desc;
  }
  
  void roomSetNightDesc(ROOM_DATA *room, const char *desc) {
    TIME_AUX_DATA *data = roomGetAuxiliaryData(room, "time_aux_data");
!   bufferClear(data->night_desc);
!   bufferCat(data->night_desc, (desc ? desc : ""));
  }
  
  
  //*****************************************************************************
  //
  // time handling functions
diff -crN nakedmudv1.5/src/time/time.d nakedmudv2.0/src/time/time.d
*** nakedmudv1.5/src/time/time.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/time/time.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ time/time.d time/time.o: time/time.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h utils.h inform.h character.h \
+   room.h event.h storage.h auxiliary.h time/mudtime.h
diff -crN nakedmudv1.5/src/utils.c nakedmudv2.0/src/utils.c
*** nakedmudv1.5/src/utils.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/utils.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 27,36 ****
  #include "action.h"
  
  
! // optional modules
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
! #endif
  
  
  /*
--- 27,38 ----
  #include "action.h"
  
  
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
! 
  
  
  /*
***************
*** 51,59 ****
    return TRUE;
  }
  
  void extract_obj(OBJ_DATA *obj) {
!   // make sure there's no events going that involve us
!   interrupt_events_involving(obj);
  
    // make sure we're not attached to anything
    CHAR_DATA *sitter = NULL;
--- 53,74 ----
    return TRUE;
  }
  
+ 
+ void  add_extract_obj_func (void (* func)(OBJ_DATA *)) {
+   listQueue(extract_obj_funcs, func);
+ }
+ 
+ void  add_extract_mob_func (void (* func)(CHAR_DATA *)) {
+   listQueue(extract_mob_funcs, func);
+ }
+ 
  void extract_obj(OBJ_DATA *obj) {
!   // go through all of our extraction functions
!   LIST_ITERATOR *ex_i = newListIterator(extract_obj_funcs);
!   void (* ex_func)(OBJ_DATA *) = NULL;
!   ITERATE_LIST(ex_func, ex_i)
!     ex_func(obj);
!   deleteListIterator(ex_i);
  
    // make sure we're not attached to anything
    CHAR_DATA *sitter = NULL;
***************
*** 81,94 ****
  
  
  void extract_mobile(CHAR_DATA *ch) {
!   // interrupt actions and events associated with us
! #ifdef MODULE_FACULTY
!   interrupt_action(ch, FACULTY_ALL);
!   clear_faculties(ch);
! #else
!   interrupt_action(ch, 1);
! #endif
!   interrupt_events_involving(ch);
  
    // unequip everything the character is wearing
    // and send it to inventory
--- 96,107 ----
  
  
  void extract_mobile(CHAR_DATA *ch) {
!   // go through all of our extraction functions
!   LIST_ITERATOR *ex_i = newListIterator(extract_mob_funcs);
!   void (* ex_func)(CHAR_DATA *) = NULL;
!   ITERATE_LIST(ex_func, ex_i)
!     ex_func(ch);
!   deleteListIterator(ex_i);
  
    // unequip everything the character is wearing
    // and send it to inventory
***************
*** 129,137 ****
      send_to_char(dMob, "{yYou say, '%s'{n\r\n", txt);
      message(dMob, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR, other_buf);
      try_dialog_all(dMob, roomGetCharacters(charGetRoom(dMob)), txt);
- #ifdef MODULE_SCRIPTS
      try_speech_script(dMob, NULL, txt);
- #endif
      break;
    }
  
--- 142,148 ----
***************
*** 153,159 ****
  /*
   * load the world and its inhabitants, as well as other misc game data
   */
! void load_muddata(bool fCopyOver) {  
    gameworld = worldLoad(WORLD_PATH);
    if(gameworld == NULL) {
      log_string("ERROR: Could not boot game world.");
--- 164,170 ----
  /*
   * load the world and its inhabitants, as well as other misc game data
   */
! void load_muddata() {  
    gameworld = worldLoad(WORLD_PATH);
    if(gameworld == NULL) {
      log_string("ERROR: Could not boot game world.");
***************
*** 162,171 ****
  
    greeting = read_file("../lib/txt/greeting");
    motd     = read_file("../lib/txt/motd");
- 
-   /* copyover */
-   if (fCopyOver)
-     copyover_recover();
  }
  
  
--- 173,178 ----
***************
*** 220,295 ****
    }
  }
  
- 
- /* Recover from a copyover - load players */
- void copyover_recover()
- {     
-   CHAR_DATA *dMob;
-   SOCKET_DATA *dsock;
-   FILE *fp;
-   char name [100];
-   char host[MAX_BUFFER];
-   int desc;
-       
-   log_string("Copyover recovery initiated");
-    
-   if ((fp = fopen(COPYOVER_FILE, "r")) == NULL)
-   {  
-     log_string("Copyover file not found. Exitting.");
-     exit (1);
-   }
-       
-   /* In case something crashes - doesn't prevent reading */
-   unlink(COPYOVER_FILE);
-     
-   for (;;)
-   {  
-     fscanf(fp, "%d %s %s\n", &desc, name, host);
-     if (desc == -1)
-       break;
- 
-     dsock = malloc(sizeof(*dsock));
-     clear_socket(dsock, desc);
-   
-     dsock->hostname     =  strdup(host);
-     listPut(socket_list, dsock);
-  
-     /* load player data */
-     if ((dMob = load_player(name)) != NULL)
-     {
-       /* attach to socket */
-       charSetSocket(dMob, dsock);
-       dsock->player    =  dMob;
- 
-       // try putting the character into the game
-       // close the socket if we fail.
-       try_enter_game(dMob);
-     }
-     else /* ah bugger */
-     {
-       close_socket(dsock, FALSE);
-       continue;
-     }
-    
-     /* Write something, and check if it goes error-free */
-     if (!text_to_socket(dsock, "\n\r <*>  And before you know it, everything has changed  <*>\n\r"))
-     { 
-       close_socket(dsock, FALSE);
-       continue;
-     }
-   
-     /* make sure the socket can be used */
-     dsock->bust_prompt    =  TRUE;
-     dsock->lookup_status  =  TSTATE_DONE;
-     dsock->state          =  STATE_PLAYING;
- 
-     /* negotiate compression */
-     text_to_buffer(dsock, (char *) compress_will2);
-     text_to_buffer(dsock, (char *) compress_will);
-   }
-   fclose(fp);
- }     
- 
  CHAR_DATA *check_reconnect(const char *player)
  {
    CHAR_DATA *dMob;
--- 227,232 ----
***************
*** 677,682 ****
--- 614,655 ----
  }
  
  //
+ // counts how many times word occurs in string. Assumes strlen(word) >= 1
+ //
+ int count_occurences(const char *string, const char *word) {
+   int count = 0, i = 0, word_len = strlen(word);
+   for(; string[i] != '\0'; i++) {
+     if(!strncmp(string, word, word_len)) {
+       count++;
+       i += word_len - 1;
+     }
+   }
+   return count;
+ }
+ 
+ //
+ // return a pointer to the start of the line num (lines are ended with \n's).
+ // return NULL if the line does not exist
+ //
+ char *line_start(char *string, int line) {
+   // skip forward to the appropriate line
+   int i, count = 1;
+ 
+   // are we looking for the start?
+   if(line == 1) return string;
+ 
+   for(i = 0; string[i] != '\0'; i++) {
+     if(string[i] == '\n')
+       count++;
+     if(count == line)
+       return string+i+1;
+   }
+ 
+   return NULL;
+ }
+ 
+ 
+ //
  // trim trailing and leading whitespace
  //
  void trim(char *string) {
***************
*** 1301,1308 ****
  }
  
  
  const char *custom_prompt(CHAR_DATA *ch) {
    static char prompt[MAX_BUFFER];
!   sprintf(prompt, "\r\nprompt> ");
    return prompt;
  }
--- 1274,1286 ----
  }
  
  
+ void show_prompt(SOCKET_DATA *socket) {
+   text_to_buffer(socket, custom_prompt(socketGetChar(socket)));
+ }
+ 
  const char *custom_prompt(CHAR_DATA *ch) {
    static char prompt[MAX_BUFFER];
!   *prompt = '\0';
!   strcat(prompt, "\r\nprompt> ");    
    return prompt;
  }
diff -crN nakedmudv1.5/src/utils.d nakedmudv2.0/src/utils.d
*** nakedmudv1.5/src/utils.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/utils.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,4 ----
+ utils.d utils.o: utils.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h character.h object.h world.h \
+   zone.h room.h exit.h socket.h utils.h save.h handler.h inform.h \
+   dialog.h event.h action.h scripts/script.h
diff -crN nakedmudv1.5/src/utils.h nakedmudv2.0/src/utils.h
*** nakedmudv1.5/src/utils.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/utils.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 9,16 ****
  //*****************************************************************************
  
  
- #include "text_editor.h"
- 
  
  //*****************************************************************************
  //
--- 9,14 ----
***************
*** 59,64 ****
--- 57,63 ----
  bool  try_dialog          (CHAR_DATA *ch, CHAR_DATA *listener,const char *mssg);
  void  try_dialog_all      (CHAR_DATA *ch, LIST *listeners, const char *mssg);
  
+ void     show_prompt(SOCKET_DATA *socket);
  const char *custom_prompt (CHAR_DATA *ch);
  
  //*****************************************************************************
***************
*** 101,111 ****
  void format_string        (char **ptr_string, int max_width, 
  		          unsigned int maxlen, bool indent);
  int  count_letters        (const char *string, const char ch, const int strlen);
  int  fgetline             (FILE *file, char *p, int maxlen);
  void center_string        (char *buf, const char *string, int linelen, 
  			   int buflen, bool border);
! 
! 
  
  
  //*****************************************************************************
--- 100,112 ----
  void format_string        (char **ptr_string, int max_width, 
  		          unsigned int maxlen, bool indent);
  int  count_letters        (const char *string, const char ch, const int strlen);
+ int  count_occurences     (const char *string, const char *word);
+ char *line_start          (char *string, int line);
  int  fgetline             (FILE *file, char *p, int maxlen);
  void center_string        (char *buf, const char *string, int linelen, 
  			   int buflen, bool border);
! int next_space_in         (char *string);
! int next_letter_in        (const char *string, char marker);
  
  
  //*****************************************************************************
***************
*** 113,125 ****
  // utilities for game functioning
  //
  //*****************************************************************************
- char *get_time             ( void );
  void  extract_obj          ( OBJ_DATA *obj);
  void  extract_mobile       ( CHAR_DATA *ch );
  bool  check_name           ( const char *name );
  void  communicate          ( CHAR_DATA *dMob, char *txt, int range );
! void  load_muddata         ( bool fCopyOver );
! void  copyover_recover     ( void );
  CHAR_DATA  *check_reconnect( const char *player );
  
  // iterate across all the elements in a list
--- 114,130 ----
  // utilities for game functioning
  //
  //*****************************************************************************
  void  extract_obj          ( OBJ_DATA *obj);
  void  extract_mobile       ( CHAR_DATA *ch );
+ 
+ // Make sure a certain procedure is called when we are extracting an npc/char
+ void  add_extract_obj_func ( void (* func)(OBJ_DATA *));
+ void  add_extract_mob_func ( void (* func)(CHAR_DATA *));
+ 
+ char *get_time             ( void );
  bool  check_name           ( const char *name );
  void  communicate          ( CHAR_DATA *dMob, char *txt, int range );
! void  load_muddata         ( void );
  CHAR_DATA  *check_reconnect( const char *player );
  
  // iterate across all the elements in a list
diff -crN nakedmudv1.5/src/world.c nakedmudv2.0/src/world.c
*** nakedmudv1.5/src/world.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/world.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 24,32 ****
  #include "storage.h"
  #include "world.h"
  
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
! #endif
  
  
  // the number of rooms we would expect, in different sized worlds
--- 24,36 ----
  #include "storage.h"
  #include "world.h"
  
! 
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
! 
  
  
  // the number of rooms we would expect, in different sized worlds
***************
*** 117,127 ****
    return worldRemoveVnum(world, zoneRemoveObj, vnum);
  };
  
- #ifdef MODULE_SCRIPTS
  SCRIPT_DATA *worldRemoveScriptVnum(WORLD_DATA *world, script_vnum vnum) {
    return worldRemoveVnum(world, zoneRemoveScript, vnum);
  };
- #endif
  
  DIALOG_DATA *worldRemoveDialogVnum(WORLD_DATA *world, dialog_vnum vnum) {
    return worldRemoveVnum(world, zoneRemoveDialog, vnum);
--- 121,129 ----
***************
*** 139,149 ****
    return (worldRemoveObjVnum(world, objGetVnum(obj)) != NULL);
  };
  
- #ifdef MODULE_SCRIPTS
  bool worldRemoveScript(WORLD_DATA *world, SCRIPT_DATA *script) {
    return (worldRemoveScriptVnum(world, scriptGetVnum(script)) != NULL);
  };
- #endif
  
  bool worldRemoveDialog(WORLD_DATA *world, DIALOG_DATA *dialog) {
    return (worldRemoveDialogVnum(world, dialogGetVnum(dialog)) != NULL);
--- 141,149 ----
***************
*** 329,339 ****
    return worldGet(world, zoneGetObj, vnum);
  };
  
- #ifdef MODULE_SCRIPTS
  SCRIPT_DATA  *worldGetScript(WORLD_DATA *world, script_vnum vnum) {
    return worldGet(world, zoneGetScript, vnum);
  };
- #endif
  
  DIALOG_DATA  *worldGetDialog(WORLD_DATA *world, dialog_vnum vnum) {
    return worldGet(world, zoneGetDialog, vnum);
--- 329,337 ----
***************
*** 395,405 ****
    worldPut(world, zoneAddObj, obj, objGetVnum(obj));
  };
  
- #ifdef MODULE_SCRIPTS
  void worldPutScript(WORLD_DATA *world, SCRIPT_DATA *script) {
    worldPut(world, zoneAddScript, script, scriptGetVnum(script));
  };
- #endif
  
  void worldPutDialog(WORLD_DATA *world, DIALOG_DATA *dialog) {
    worldPut(world, zoneAddDialog, dialog, dialogGetVnum(dialog));
--- 393,401 ----
diff -crN nakedmudv1.5/src/world.d nakedmudv2.0/src/world.d
*** nakedmudv1.5/src/world.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/world.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ world.d world.o: world.c mud.h wrapsock.h property_table.h list.h map.h \
+   hashtable.h set.h buffer.h bitvector.h zone.h room.h character.h \
+   object.h dialog.h utils.h storage.h world.h scripts/script.h
diff -crN nakedmudv1.5/src/world.h nakedmudv2.0/src/world.h
*** nakedmudv1.5/src/world.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/world.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 9,16 ****
  //*****************************************************************************
  
  
- 
- 
  //
  // Create a new world from the path. The path is the directory the world
  // data is stored in.
--- 9,14 ----
***************
*** 65,70 ****
--- 63,70 ----
  void worldPulse(WORLD_DATA *world);
  void worldForceReset(WORLD_DATA *world);
  
+ 
+ 
  //*****************************************************************************
  //
  // set and get functions
diff -crN nakedmudv1.5/src/wrapsock.h nakedmudv2.0/src/wrapsock.h
*** nakedmudv1.5/src/wrapsock.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/wrapsock.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 55,61 ****
--- 55,63 ----
  
  /* Defines */
  /* defined before the right type get a chance to be defined */
+ #ifndef socklen_t
  #define socklen_t unsigned int
+ #endif
  /* port to handle all requests */
  #define SERV_PORT1 9877 
  /* port to handle numeric requests */
diff -crN nakedmudv1.5/src/zone.c nakedmudv2.0/src/zone.c
*** nakedmudv1.5/src/zone.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/zone.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 18,32 ****
  #include "dialog.h"
  #include "zone.h"
  
! #ifdef MODULE_SCRIPTS
  #include "scripts/script.h"
- #endif
  
  
  struct zone_data {
!   char *name;
!   char *desc;
!   char *editors;
  
    WORLD_DATA     *world;
    PROPERTY_TABLE *rooms;
--- 18,34 ----
  #include "dialog.h"
  #include "zone.h"
  
! 
! //*****************************************************************************
! // mandatory modules
! //*****************************************************************************
  #include "scripts/script.h"
  
  
  struct zone_data {
!   char   *name;
!   char   *editors;
!   BUFFER *desc;
  
    WORLD_DATA     *world;
    PROPERTY_TABLE *rooms;
***************
*** 49,55 ****
  ZONE_DATA *newZone(zone_vnum vnum, room_vnum min, room_vnum max) {
    ZONE_DATA *zone = malloc(sizeof(ZONE_DATA));
    zone->name    = strdup("");
!   zone->desc    = strdup("");
    zone->editors = strdup("");
    zone->vnum    = vnum;
    zone->min     = min;
--- 51,57 ----
  ZONE_DATA *newZone(zone_vnum vnum, room_vnum min, room_vnum max) {
    ZONE_DATA *zone = malloc(sizeof(ZONE_DATA));
    zone->name    = strdup("");
!   zone->desc    = newBuffer(1);
    zone->editors = strdup("");
    zone->vnum    = vnum;
    zone->min     = min;
***************
*** 61,69 ****
    zone->world = NULL;
    // maximum of about 5 rooms/bucket
    zone->rooms      = newPropertyTable(roomGetVnum,   1 + (max-min)/5);
- #ifdef MODULE_SCRIPTS
    zone->scripts    = newPropertyTable(scriptGetVnum, 1 + (max-min)/5);  
- #endif
    zone->dialogs    = newPropertyTable(dialogGetVnum, 1 + (max-min)/5);
    zone->mob_protos = newPropertyTable(charGetVnum,    1 + (max-min)/5);
    zone->obj_protos = newPropertyTable(objGetVnum,    1 + (max-min)/5);
--- 63,69 ----
***************
*** 81,87 ****
  
  void zoneCopyTo(ZONE_DATA *from, ZONE_DATA *to) {
    zoneSetName(to, zoneGetName(from));
!   zoneSetDescription(to, zoneGetDesc(from));
    zoneSetEditors(to, zoneGetEditors(from));
    to->vnum = from->vnum;
    to->min  = from->min;
--- 81,87 ----
  
  void zoneCopyTo(ZONE_DATA *from, ZONE_DATA *to) {
    zoneSetName(to, zoneGetName(from));
!   zoneSetDesc(to, zoneGetDesc(from));
    zoneSetEditors(to, zoneGetEditors(from));
    to->vnum = from->vnum;
    to->min  = from->min;
***************
*** 93,99 ****
  
  void deleteZone(ZONE_DATA *zone){ 
    if(zone->name)    free(zone->name);
!   if(zone->desc)    free(zone->desc);
    if(zone->editors) free(zone->editors);
  
    deletePropertyTable(zone->rooms);
--- 93,99 ----
  
  void deleteZone(ZONE_DATA *zone){ 
    if(zone->name)    free(zone->name);
!   if(zone->desc)    deleteBuffer(zone->desc);
    if(zone->editors) free(zone->editors);
  
    deletePropertyTable(zone->rooms);
***************
*** 165,171 ****
    zone->max         = read_int(set, "max");
    zone->pulse_timer = read_int(set, "pulse_timer");
    zoneSetName(zone,   read_string(set, "name"));
!   zoneSetDescription(zone,   read_string(set, "desc"));
    zoneSetEditors(zone,read_string(set, "editors"));
  
    deleteAuxiliaryData(zone->auxiliary_data);
--- 165,171 ----
    zone->max         = read_int(set, "max");
    zone->pulse_timer = read_int(set, "pulse_timer");
    zoneSetName(zone,   read_string(set, "name"));
!   zoneSetDesc(zone,   read_string(set, "desc"));
    zoneSetEditors(zone,read_string(set, "editors"));
  
    deleteAuxiliaryData(zone->auxiliary_data);
***************
*** 195,206 ****
    zoneReadData(zone, set, zoneAddDialog, dialogRead);
    storage_close(set);
  
- #ifdef MODULE_SCRIPTS
    sprintf(fname, "%s/scripts", dirpath);
    set = storage_read(fname);
    zoneReadData(zone, set, zoneAddScript, scriptRead);
    storage_close(set);
- #endif
    return zone;
  }
  
--- 195,204 ----
***************
*** 244,250 ****
    store_int   (set, "max",         zone->max);
    store_int   (set, "pulse_timer", zone->pulse_timer);
    store_string(set, "name",        zone->name);
!   store_string(set, "desc",        zone->desc);
    store_string(set, "editors",     zone->editors);
    store_set   (set, "auxiliary",   auxiliaryDataStore(zone->auxiliary_data));
    storage_write(set, fname);
--- 242,248 ----
    store_int   (set, "max",         zone->max);
    store_int   (set, "pulse_timer", zone->pulse_timer);
    store_string(set, "name",        zone->name);
!   store_string(set, "desc",        bufferString(zone->desc));
    store_string(set, "editors",     zone->editors);
    store_set   (set, "auxiliary",   auxiliaryDataStore(zone->auxiliary_data));
    storage_write(set, fname);
***************
*** 266,276 ****
    sprintf(fname, "%s/dialogs", dirpath);
    storage_write(set, fname);
  
- #ifdef MODULE_SCRIPTS
    set = zoneStoreData(zone, zoneGetScript, scriptStore);
    sprintf(fname, "%s/scripts", dirpath);
    storage_write(set, fname);
- #endif
  
    return TRUE;
  }
--- 264,272 ----
***************
*** 314,324 ****
    zoneAdd(zone, zone->obj_protos, "object", obj, objGetVnum(obj));
  }
  
- #ifdef MODULE_SCRIPTS
  void zoneAddScript(ZONE_DATA *zone, SCRIPT_DATA *script) {
    zoneAdd(zone, zone->scripts, "script", script, scriptGetVnum(script));
  }
- #endif
  
  void zoneAddDialog(ZONE_DATA *zone, DIALOG_DATA *dialog) {
    zoneAdd(zone, zone->dialogs, "dialog", dialog, dialogGetVnum(dialog));
--- 310,318 ----
***************
*** 351,361 ****
    return zoneRemove(zone, zone->obj_protos, "obj", obj);
  }
  
- #ifdef MODULE_SCRIPTS
  SCRIPT_DATA *zoneRemoveScript(ZONE_DATA *zone, script_vnum script) { 
    return zoneRemove(zone, zone->scripts, "script", script);
  }
- #endif
  
  DIALOG_DATA *zoneRemoveDialog(ZONE_DATA *zone, dialog_vnum dialog) { 
    return zoneRemove(zone, zone->dialogs, "dialog", dialog);
--- 345,353 ----
***************
*** 415,429 ****
  }
  
  const char *zoneGetDesc(ZONE_DATA *zone) { 
!   return zone->desc;
  }
  
  const char *zoneGetEditors(ZONE_DATA *zone) {
    return zone->editors;
  }
  
! char **zoneGetDescPtr(ZONE_DATA *zone) {
!   return &(zone->desc);
  }
  
  //
--- 407,421 ----
  }
  
  const char *zoneGetDesc(ZONE_DATA *zone) { 
!   return bufferString(zone->desc);
  }
  
  const char *zoneGetEditors(ZONE_DATA *zone) {
    return zone->editors;
  }
  
! BUFFER *zoneGetDescBuffer(ZONE_DATA *zone) {
!   return zone->desc;
  }
  
  //
***************
*** 453,463 ****
    return zoneGet(zone, zone->obj_protos, "obj", obj);
  }
  
- #ifdef MODULE_SCRIPTS
  SCRIPT_DATA *zoneGetScript(ZONE_DATA *zone, script_vnum script) {
    return zoneGet(zone, zone->scripts, "script", script);
  };
- #endif
  
  DIALOG_DATA *zoneGetDialog(ZONE_DATA *zone, dialog_vnum dialog) {
    return zoneGet(zone, zone->dialogs, "dialog", dialog);
--- 445,453 ----
***************
*** 495,503 ****
    zone->name = (name ? strdup(name) : strdup("\0"));
  }
  
! void zoneSetDescription(ZONE_DATA *zone, const char *description) { 
!   if(zone->desc) free(zone->desc);
!   zone->desc = (description ? strdup(description) : strdup("\0"));
  }
  
  void zoneSetEditors(ZONE_DATA *zone, const char *names) {
--- 485,493 ----
    zone->name = (name ? strdup(name) : strdup("\0"));
  }
  
! void zoneSetDesc(ZONE_DATA *zone, const char *desc) { 
!   bufferClear(zone->desc);
!   bufferCat(zone->desc, desc);
  }
  
  void zoneSetEditors(ZONE_DATA *zone, const char *names) {
diff -crN nakedmudv1.5/src/zone.d nakedmudv2.0/src/zone.d
*** nakedmudv1.5/src/zone.d	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv2.0/src/zone.d	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,3 ----
+ zone.d zone.o: zone.c mud.h wrapsock.h property_table.h list.h map.h hashtable.h \
+   set.h buffer.h bitvector.h storage.h object.h character.h room.h \
+   utils.h auxiliary.h dialog.h zone.h scripts/script.h
diff -crN nakedmudv1.5/src/zone.h nakedmudv2.0/src/zone.h
*** nakedmudv1.5/src/zone.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/src/zone.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 92,104 ****
  const char *zoneGetName(ZONE_DATA *zone);
  const char *zoneGetDesc(ZONE_DATA *zone);
  const char *zoneGetEditors(ZONE_DATA *zone);
! char      **zoneGetDescPtr(ZONE_DATA *zone);
  bool        canEditZone(ZONE_DATA *zone, CHAR_DATA *ch);
  ROOM_DATA  *zoneGetRoom(ZONE_DATA *zone, room_vnum room);
  CHAR_DATA   *zoneGetMob(ZONE_DATA *zone, mob_vnum room);
  OBJ_DATA   *zoneGetObj(ZONE_DATA *zone, obj_vnum obj);
  SCRIPT_DATA *zoneGetScript(ZONE_DATA *zone, script_vnum script);
! DIALOG_DATA *zoneGetDialog(ZONE_DATA *zone, dialog_vnum script);
  void        *zoneGetAuxiliaryData(const ZONE_DATA *zone, char *name);
  
  void zoneSetVnum(ZONE_DATA *zone, zone_vnum vnum);
--- 92,104 ----
  const char *zoneGetName(ZONE_DATA *zone);
  const char *zoneGetDesc(ZONE_DATA *zone);
  const char *zoneGetEditors(ZONE_DATA *zone);
! BUFFER     *zoneGetDescBuffer(ZONE_DATA *zone);
  bool        canEditZone(ZONE_DATA *zone, CHAR_DATA *ch);
  ROOM_DATA  *zoneGetRoom(ZONE_DATA *zone, room_vnum room);
  CHAR_DATA   *zoneGetMob(ZONE_DATA *zone, mob_vnum room);
  OBJ_DATA   *zoneGetObj(ZONE_DATA *zone, obj_vnum obj);
  SCRIPT_DATA *zoneGetScript(ZONE_DATA *zone, script_vnum script);
! DIALOG_DATA *zoneGetDialog(ZONE_DATA *zone, dialog_vnum dialog);
  void        *zoneGetAuxiliaryData(const ZONE_DATA *zone, char *name);
  
  void zoneSetVnum(ZONE_DATA *zone, zone_vnum vnum);
***************
*** 108,114 ****
  void zoneSetPulse(ZONE_DATA *zone, int pulse_left);
  void zoneSetWorld(ZONE_DATA *zone, WORLD_DATA *world);
  void zoneSetName(ZONE_DATA *zone, const char *name);
! void zoneSetDescription(ZONE_DATA *zone, const char *description);
  void zoneSetEditors(ZONE_DATA *zone, const char *names);
  //*****************************************************************************
  //
--- 108,114 ----
  void zoneSetPulse(ZONE_DATA *zone, int pulse_left);
  void zoneSetWorld(ZONE_DATA *zone, WORLD_DATA *world);
  void zoneSetName(ZONE_DATA *zone, const char *name);
! void zoneSetDesc(ZONE_DATA *zone, const char *description);
  void zoneSetEditors(ZONE_DATA *zone, const char *names);
  //*****************************************************************************
  //
diff -crN nakedmudv1.5/TODO nakedmudv2.0/TODO
*** nakedmudv1.5/TODO	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv2.0/TODO	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,32 ****
  GEOFF'S TO DO LIST
  +-- KNOWN BUGS
    * moving via tracking will not trigger enter/exit scripts
  
- 
  +-- NOT COMPLETE
!   * spellchecking in the text editor
!   * Redo OLC so that if a module uses OLC, it can add the relevant functions
!     from its own module.
!   * Devise something to replace bitvectors that is a bit more amenable to
!     keeping things modular.
!   * condense normal and special exits in rooms
!   * soft-code chat channels
!   * random dungeon generator
!   * mounts and vehicles
!   * being able to stream music would be cool...
!   * clean up and document resedit in the olc module
!   * shops (for mobiles and players)
!   * customized prompts
!   * DOCUMENT DOCUMENT DOCUMENT!! Most of the major headers need full
!     documentation still.
!   * character positions and changing of positions is a bit of a hack.
!     it could really do with some cleaning up. Move their defines to mud.h
!     too, so that modules wanting to add new commands don't need to include
!     character.h
!   * Mysty's Dialog
!     * Betta
!     * Oren
! 
  
  +-- NEEDS EXTRA WORK
    * write helpfiles, create a better helpfile system, and do hedit
--- 1,41 ----
  GEOFF'S TO DO LIST
+ +-- CONSIDERATIONS FOR THE FUTURE
+   * vnums: do we even need them? Objects and NPCs: inheritance, like OOP?
+ 
  +-- KNOWN BUGS
    * moving via tracking will not trigger enter/exit scripts
  
  +-- NOT COMPLETE
!  +-- HIGH PRIORITY
!    * bedit -> bitvector edit
!    * create an insert function for the script editor that kills carraige returns
!    * redo sets to be in a tree form rather than a table form
!    * redo hashtables so that they will auto-enlarge themselves
!    * Rewrite the character creation input handling stuff; it's kludgy
!    * character positions and changing of positions is a bit of a hack.
!      it could really do with some cleaning up. Move their defines to mud.h
!      too, so that modules wanting to add new commands don't need to include
!      character.h
!    * condense normal and special exits in rooms
!    * clean up everything related to sockets... the entire socket.c file is a
!      mess. Emphasis on the MCCP stuff (put it in its own file), and the text
!      editing stuff (it's a hack...).
! 
!  +-- LOW PRIORITY
!    * Mysty's Dialog
!      * Betta
!      * Oren
!    * make tracking use BFS instead of DFS
!    * Bulletin board/forum system
!    * soft-code chat channels
!    * spellchecking in the text editor
!    * mounts and vehicles
!    * shops (for mobiles and players)
!    * customized prompts
!    * DOCUMENT DOCUMENT DOCUMENT!! Most of the major headers need full
!      documentation still.
!    * random dungeon generator
!    * being able to stream music would be cool...
  
  +-- NEEDS EXTRA WORK
    * write helpfiles, create a better helpfile system, and do hedit
***************
*** 36,41 ****
    * debug dialogs. Also have a new addition, STORY for temporally extended
      responses
  
- 
  +-- NEEDS DEBUGGING
-   * text editor
--- 45,48 ----
