diff -crN nakedmudv1.0/.depend nakedmudv1.4/.depend
*** nakedmudv1.0/.depend	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,182 ----
+ gameloop.o: gameloop.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h socket.h world.h character.h object.h utils.h text_editor.h \
+   save.h handler.h inform.h log.h races.h action.h event.h auxiliary.h \
+   storage.h time/mudtime.h scripts/script.h olc/olc.h alias/alias.h \
+   char_vars/char_vars.h socials/socials.h fight/fight.h
+ mud.o: mud.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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 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 help.h fight/stats.h fight/fight.h scripts/script.h
+ interpret.o: interpret.c mud.h wrapsock.h property_table.h list.h \
+   hashmap.h hashtable.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 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 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 character.h world.h room.h exit.h movement.h handler.h \
+   inform.h builder.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 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 socket.h utils.h text_editor.h
+ save.o: save.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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 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 \
+   utils.h text_editor.h
+ strings.o: strings.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h utils.h text_editor.h
+ event.o: event.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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 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 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 character.h socket.h utils.h text_editor.h save.h event.h \
+   handler.h
+ text_editor.o: text_editor.c mud.h wrapsock.h property_table.h list.h \
+   hashmap.h hashtable.h socket.h text_editor.h utils.h scripts/script.h \
+   olc/olc.h
+ builder.o: builder.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h world.h zone.h room.h exit.h movement.h builder.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
+ admin.o: admin.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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
+ help.o: help.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h character.h help.h
+ items.o: items.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h object.h items.h
+ races.o: races.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h races.h body.h utils.h text_editor.h
+ log.o: log.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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 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 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 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 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 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 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 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 body.h utils.h text_editor.h
+ zone.o: zone.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h storage.h object.h character.h room.h zone.h utils.h \
+   text_editor.h dialog.h scripts/script.h
+ dialog.o: dialog.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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 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 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 utils.h text_editor.h storage.h
+ time.o: time/time.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
+ stats.o: fight/stats.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h utils.h text_editor.h character.h storage.h auxiliary.h \
+   handler.h event.h fight/stats.h fight/fight.h
+ fight.o: fight/fight.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h utils.h text_editor.h world.h handler.h character.h \
+   inform.h event.h action.h body.h fight/fight.h fight/stats.h
+ cmd_fight.o: fight/cmd_fight.c mud.h wrapsock.h property_table.h list.h \
+   hashmap.h hashtable.h utils.h text_editor.h handler.h inform.h \
+   character.h body.h object.h fight/stats.h fight/fight.h
+ mob_fight.o: fight/mob_fight.c mud.h wrapsock.h property_table.h list.h \
+   hashmap.h hashtable.h utils.h text_editor.h fight/fight.h fight/stats.h
diff -crN nakedmudv1.0/doc/modules.txt nakedmudv1.4/doc/modules.txt
*** nakedmudv1.0/doc/modules.txt	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/doc/modules.txt	2010-11-01 15:54:18.000000000 -0500
***************
*** 14,30 ****
  
  I will not provide very explicit directions on how to implement new modules
  (really, I think they're flexible enough that you can do whatever you want with
! a little bit of imagination), but I will give some basic directions and a couple
! examples to help you going.
  
  
  BASIC DIRECTIONS - INSTALLING A NEW MODULE
  
  There are 5 basic steps to setting up a module
  
! 1) make a directory and makefile for it in src/modules. A template makefile
!    is provided in src/modules/example
! 2) add its directory to the bottom of the Makefile in the main src directory
  3) write all of you code
  4) put a define in mud.h to let the rest of the MUD know it is installed, incase
     other modules will need to interact with yours in the future
--- 14,32 ----
  
  I will not provide very explicit directions on how to implement new modules
  (really, I think they're flexible enough that you can do whatever you want with
! a little bit of imagination, and the concept is simple enough that anyone with
! a smidge of programming experience will grasp it), but I will give some basic
! directions and a couple examples to help you going.
  
  
  BASIC DIRECTIONS - INSTALLING A NEW MODULE
  
  There are 5 basic steps to setting up a module
  
! 1) make a directory and module.mk file for it in the src directory. A template 
!    module.mk is provided in src/example_module
! 2) add its directory to the MODULES variable in the top of the Makefile within 
!    the main src directory
  3) write all of you code
  4) put a define in mud.h to let the rest of the MUD know it is installed, incase
     other modules will need to interact with yours in the future
***************
*** 33,46 ****
  I think all of these are completely straightforward except for 3. That one's the
  (slightly) tricky part. I've provided a few example modules with the normal
  distribution that I suggest you look over. The best one to get a basic 
! understanding from is probably the time module (src/modules/time). It has
! some straightforward examples of how to get modules to create new commands,
! add new data to a datastructure without editing the datastructure directly,
! how to set up a new event loop without having to edit the gameloop, and a bunch
! of other really useful information. There are two other modules that come stock
! with NakedMud - the OLC module (src/modules/olc) and the scripts module
! (src/modules/scripts), but the time module is by far the best one as as an
! examplar of how I thought modules should work.
  
  
  THINGS TO CONSIDER WHEN IMPLEMENTING MODULES
--- 35,52 ----
  I think all of these are completely straightforward except for 3. That one's the
  (slightly) tricky part. I've provided a few example modules with the normal
  distribution that I suggest you look over. The best one to get a basic 
! understanding from is probably the time module (src/time). It has some 
! straightforward examples of how to get modules to create new commands, add new 
! data to a datastructure without editing the datastructure directly, how to set 
! up a new event loop without having to edit the gameloop, and a bunch of other 
! really useful information. Many other modules come default with the core of
! NakedMud, and they might be worth your time to look over (e.g. the socials
! module would be a good intro to how modules can add/remove commands to the MUD,
! and the OLC may be useful in getting ideas of how to design a large-scale
! module without touching any of the core code. The scripts module may also be
! worth your time looking over - especially if you ever intend on extending
! scripts). However, the time module is by far the best one as as an examplar of 
! how I thought modules should work.
  
  
  THINGS TO CONSIDER WHEN IMPLEMENTING MODULES
diff -crN nakedmudv1.0/doc/scripts.txt nakedmudv1.4/doc/scripts.txt
*** nakedmudv1.0/doc/scripts.txt	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/doc/scripts.txt	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,6 ****
  If you are having problems installing scripts, you will want to read the 
! documentation in src/modules/scripts/Makefile. This file is an explanation of
! how to interact with scripts.
  
  Scripting is a powerful method for adding character to your MUD. It essentially
  allows you to edit (simple) code that will modify the way rooms, players, and
--- 1,6 ----
  If you are having problems installing scripts, you will want to read the 
! documentation in src/scripts/module.mk. The file you are currently reading is 
! an explanation of how to interact with scripts.
  
  Scripting is a powerful method for adding character to your MUD. It essentially
  allows you to edit (simple) code that will modify the way rooms, players, and
***************
*** 60,66 ****
  example: ch.setvar('blackjack_winnings', 100)
  Allows you to store information on a character, regarding stuff that happened
  during the script. These variables save over reboots and crashes. The only
! restriction is that the variables must be integer values.
  
  RETRIEVING SCRIPT DATA
  ch.getvar('varname')
--- 60,66 ----
  example: ch.setvar('blackjack_winnings', 100)
  Allows you to store information on a character, regarding stuff that happened
  during the script. These variables save over reboots and crashes. The only
! restriction is that the variables must be numeric values, or strings.
  
  RETRIEVING SCRIPT DATA
  ch.getvar('varname')
diff -crN nakedmudv1.0/doc/startup.txt nakedmudv1.4/doc/startup.txt
*** nakedmudv1.0/doc/startup.txt	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/doc/startup.txt	2010-11-01 15:54:18.000000000 -0500
***************
*** 4,10 ****
  start up on port 4000 by default.
  
  If you're having troubles compiling when it gets to the scripts, you will want
! to read src/modules/scripts/Makefile
  
  If you've got other problems and cannot figure out what to do, you can try
  giving me a description of your problem, and I'll see if I can help you out. No
--- 4,10 ----
  start up on port 4000 by default.
  
  If you're having troubles compiling when it gets to the scripts, you will want
! to read src/scripts/module.mk
  
  If you've got other problems and cannot figure out what to do, you can try
  giving me a description of your problem, and I'll see if I can help you out. No
Binary files nakedmudv1.0/.DS_Store and nakedmudv1.4/.DS_Store differ
diff -crN nakedmudv1.0/.gdb_history nakedmudv1.4/.gdb_history
*** nakedmudv1.0/.gdb_history	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/.gdb_history	2010-11-01 15:54:18.000000000 -0500
***************
*** 1 ****
--- 1,256 ----
+ down
+ up
+ up
+ up
+ print room->auxiliary_data
+ down
+ print line
+ print data
+ info local
+ bt
+ quit
+ run
+ quit
+ run
+ bt
+ print line
+ quit
+ run
+ print line
+ quit
+ run
+ bt
+ quit
+ run
+ bt
+ down
+ up
+ up
+ up
+ up
+ print world
+ bt
+ quit
+ run
+ quit
+ run
+ bt
+ quit
+ run
+ quit
+ run
+ quit
+ run
+ quit
+ 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
+ quit
+ run
+ bt
+ 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
+ run
+ 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
diff -crN nakedmudv1.0/help/GREETING nakedmudv1.4/help/GREETING
*** nakedmudv1.0/help/GREETING	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/help/GREETING	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,10 ****
- {n
-                     NakedMud(tm), content-less MUD engine.
- 
-                                   Created By
-                                  Geoff Hollis
-                               hollis@ualberta.ca
- 
-                           Based on SocketMud(tm) by
-                                Brian Graversen
- 
--- 0 ----
diff -crN nakedmudv1.0/help/MOTD nakedmudv1.4/help/MOTD
*** nakedmudv1.0/help/MOTD	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/help/MOTD	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,12 ****
- Welcome to NakedMud(tm)
- 
- Glad you could get it up and running! Zone 100 is a proof of concept
- for the various building utilities, such as dialogs, scripts, and zone
- reset commands. Look around, and try HELP OLC if you are wanting to
- look at anything in detail.
- 
- Comments, questions, and concerns should be addressed to:
- Geoff Hollis
- hollis@ualberta.ca
- http://www.ualberta.ca/~hollis/
- 
--- 0 ----
diff -crN nakedmudv1.0/lib/misc/socials nakedmudv1.4/lib/misc/socials
*** nakedmudv1.0/lib/misc/socials	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/lib/misc/socials	2010-11-01 15:54:17.000000000 -0500
***************
*** 0 ****
--- 1,135 ----
+ socials:=
+   cmds         : twiddle
+   to_char_notgt: You idly twiddle your thumbs.
+   to_room_notgt: $n idly twiddles $s thumbs.
+   to_char_tgt  : You reach for $N's thumbs and begin twiddling with them.
+   to_vict_tgt  : $n reaches for your thumbs and starts twiddling them.
+   to_room_tgt  : $n reaches for $N's thumbs and begins twiddling with them.
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : dance
+   to_char_notgt: You do a little dance.
+   to_room_notgt: $n does a little dance.
+   to_char_self : You get down with your bad self.
+   to_room_self : $n can't find anyone else to dance with, so $e dances with $mself.
+   to_char_tgt  : You sweep $N across the dancefloor.
+   to_vict_tgt  : $n sweeps you across the dancefloor! How romantic!
+   to_room_tgt  : $n sweeps $N across the dancefloor! How romantic!
+   min_pos      : standing
+   max_pos      : standing
+   -
+   cmds         : snicker
+   to_char_notgt: You snicker softly.
+   to_room_notgt: $n snickers softly.
+   to_char_tgt  : You snicker at $N.
+   to_vict_tgt  : $n snickers at you.
+   to_room_tgt  : $n snickers at $N.
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : smile
+   to_char_notgt: You smile happily.
+   to_room_notgt: A happy smile forms on $n's face.
+   to_char_self : You smile privately with yourself.
+   to_room_self : $n gets a faint hint of a smile on $s face.
+   to_char_tgt  : You smile happily at $N.
+   to_vict_tgt  : $n smiles happily at you.
+   to_room_tgt  : $n smiles happily at $N.
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : ruffle
+   to_char_notgt: Who are you trying to ruffle?
+   to_char_self : You mess up your hair.
+   to_room_self : $n makes $s hair all messy.
+   to_char_tgt  : You playfully ruffle $N's hair.
+   to_vict_tgt  : $n playfully ruffles your hair.
+   to_room_tgt  : $n playfully ruffles $N's hair.
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : grin
+   to_char_notgt: You grin evilly.
+   to_room_notgt: $n grins evilly.
+   to_char_tgt  : You flash $N an evil grin.
+   to_vict_tgt  : $n flashes you an evil grin.
+   to_room_tgt  : $n flashes $N an evil grin.
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : jig
+   to_char_notgt: You do a little jig.
+   to_room_notgt: $n performs a little jig.
+   to_char_tgt  : To jig with another is not to jig at all.
+   min_pos      : standing
+   max_pos      : standing
+   -
+   cmds         : wiggle
+   to_char_notgt: You wiggle your bottom.
+   to_room_notgt: $n wiggles $s bottom.
+   to_char_tgt  : You wiggle your bottom at $N.
+   to_vict_tgt  : $n wiggles $s bottom at you.
+   to_room_tgt  : $n wiggles $s bottom at $N.
+   min_pos      : standing
+   max_pos      : flying
+   -
+   cmds         : tip
+   to_char_notgt: You gallantly tip your hat.
+   to_room_notgt: $n gallantly tips his hat.
+   to_char_tgt  : You gallantly tip your hat towards $N.
+   to_vict_tgt  : $n gallantly tips $s hat in your direction.
+   to_room_tgt  : $n gallantly tips $s hat in $N's direction.
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : tackle
+   to_char_notgt: You jump up into the air and tackle... who?
+   to_room_notgt: $n jumps wildly into the air and... falls flat on $s face.
+   to_char_self : Pow! You knock yourself to the ground! I bet you didn't see that one coming, eh?
+   to_room_self : $n suddenly wraps $s arms around $mself, and heaves $mself to the ground.
+   to_char_tgt  : You playfully tackle $n, and you both go rolling to the ground.
+   to_vict_tgt  : $n playfully tackles you, and you both go rolling to the ground.
+   to_room_tgt  : $n playfully tackles $N, and they both go rolling to the ground.
+   min_pos      : standing
+   max_pos      : flying
+   -
+   cmds         : giggle
+   to_char_notgt: You let out a giggle.
+   to_room_notgt: $n lets out a giggle.
+   to_char_self : It was funny, wasn't it?
+   to_room_self : $n shares a little giggle with $mself.
+   to_char_tgt  : $E is funny, isn't $E?
+   to_vict_tgt  : $n giggles at you.
+   to_room_tgt  : $n giggles at $N.
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : laugh, lol
+   to_char_notgt: You give out a loud, hearty laugh.
+   to_room_notgt: A loud, hearty laugh bursts from $n's mouth.
+   to_char_self : It was funny, wasn't it?
+   to_room_self : $n seems to be having a private laugh with $mself.
+   to_char_tgt  : You burst out laughing at $N.
+   to_vict_tgt  : $n bursts out laughing at you!
+   to_room_tgt  : $n bursts out laughing at $N!
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : faint
+   to_char_notgt: You suddenly feel very lightheaded.
+   to_room_notgt: $n suddenly goes very pale, and faints!
+   min_pos      : sitting
+   max_pos      : flying
+   -
+   cmds         : tango
+   to_char_notgt: But it takes two to tango!
+   to_char_self : You passionately grab your left hand in your right hand, and dance seductively with yourself. 
+   to_room_self : $n passionately grabs $s left hand with $s right hand, and dances seductively with $mself. How bizarre.
+   to_char_tgt  : You pull $N up close to you, and perform a seductive tango.
+   to_vict_tgt  : $n pulls you up close to $m, and dances a seductive tango with you.
+   to_room_tgt  : $n pulls $N up close to $m and dances a seductive tango.
+   min_pos      : standing
+   max_pos      : standing
+   -
+ -
diff -crN nakedmudv1.0/lib/misc/time nakedmudv1.4/lib/misc/time
*** nakedmudv1.0/lib/misc/time	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/lib/misc/time	2010-11-01 15:54:17.000000000 -0500
***************
*** 1 ****
--- 1,6 ----
+ hour        : 20
+ day_of_week : 2
+ day_of_month: 2
+ month       : 1
+ year        : 0
  -
diff -crN nakedmudv1.0/lib/txt/greeting nakedmudv1.4/lib/txt/greeting
*** nakedmudv1.0/lib/txt/greeting	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/lib/txt/greeting	2010-11-01 15:54:17.000000000 -0500
***************
*** 0 ****
--- 1,10 ----
+ {n
+                     NakedMud(tm), content-less MUD engine.
+ 
+                                   Created By
+                                  Geoff Hollis
+                               hollis@ualberta.ca
+ 
+                           Based on SocketMud(tm) by
+                                Brian Graversen
+ 
diff -crN nakedmudv1.0/lib/txt/motd nakedmudv1.4/lib/txt/motd
*** nakedmudv1.0/lib/txt/motd	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/lib/txt/motd	2010-11-01 15:54:17.000000000 -0500
***************
*** 0 ****
--- 1,12 ----
+ Welcome to NakedMud(tm)
+ 
+ Glad you could get it up and running! Zone 100 is a proof of concept
+ for the various building utilities, such as dialogs, scripts, and zone
+ reset commands. Look around, and try HELP OLC if you are wanting to
+ look at anything in detail.
+ 
+ Comments, questions, and concerns should be addressed to:
+ Geoff Hollis
+ hollis@ualberta.ca
+ http://www.ualberta.ca/~hollis/
+ 
diff -crN nakedmudv1.0/lib/world/0/rooms~ nakedmudv1.4/lib/world/0/rooms~
*** nakedmudv1.0/lib/world/0/rooms~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/lib/world/1/mobs nakedmudv1.4/lib/world/1/mobs
*** nakedmudv1.0/lib/world/1/mobs	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/lib/world/1/mobs	2010-11-01 15:54:17.000000000 -0500
***************
*** 15,21 ****
    race      : 0
    dialog    : 100
    auxiliary :-
!     script_aux_data:-
        scripts:=
          vnum: 140
          -
--- 15,43 ----
    race      : 0
    dialog    : 100
    auxiliary :-
!     stat_data        :-
!       health          : 5
!       curr_health     : 5
!       endurance       : 5
!       curr_endurance  : 0
!       power           : 5
!       curr_power      : 0
!       balance         : 5
!       curr_balance    : 0
!       courage         : 5
!       curr_courage    : 0
!       speed           : 5
!       curr_speed      : 0
!       control         : 5
!       curr_control    : 0
!       awareness       : 5
!       curr_awareness  : 0
!       personality     : 5
!       curr_personality: 0
!       luck            : 5
!       curr_luck       : 0
!       -
!     script_aux_data  :-
        scripts:=
          vnum: 140
          -
***************
*** 38,44 ****
    race      : 0
    dialog    : 101
    auxiliary :-
!     script_aux_data:-
        scripts:=
          vnum: 151
          -
--- 60,88 ----
    race      : 0
    dialog    : 101
    auxiliary :-
!     stat_data        :-
!       health          : 5
!       curr_health     : 5
!       endurance       : 5
!       curr_endurance  : 0
!       power           : 5
!       curr_power      : 0
!       balance         : 5
!       curr_balance    : 0
!       courage         : 5
!       curr_courage    : 0
!       speed           : 5
!       curr_speed      : 0
!       control         : 5
!       curr_control    : 0
!       awareness       : 5
!       curr_awareness  : 0
!       personality     : 5
!       curr_personality: 0
!       luck            : 5
!       curr_luck       : 0
!       -
!     script_aux_data  :-
        scripts:=
          vnum: 151
          -
***************
*** 60,65 ****
--- 104,133 ----
    sex       : 0
    race      : 0
    dialog    : 102
+   auxiliary :-
+     stat_data        :-
+       health          : 5
+       curr_health     : 5
+       endurance       : 5
+       curr_endurance  : 0
+       power           : 5
+       curr_power      : 0
+       balance         : 5
+       curr_balance    : 0
+       courage         : 5
+       curr_courage    : 0
+       speed           : 5
+       curr_speed      : 0
+       control         : 5
+       curr_control    : 0
+       awareness       : 5
+       curr_awareness  : 0
+       personality     : 5
+       curr_personality: 0
+       luck            : 5
+       curr_luck       : 0
+       -
+     -
    -
    vnum      : 130
    name      : a barfly
***************
*** 77,81 ****
--- 145,173 ----
    sex       : 0
    race      : 0
    dialog    : -1
+   auxiliary :-
+     stat_data        :-
+       health          : 5
+       curr_health     : 5
+       endurance       : 5
+       curr_endurance  : 0
+       power           : 5
+       curr_power      : 0
+       balance         : 5
+       curr_balance    : 0
+       courage         : 5
+       curr_courage    : 0
+       speed           : 5
+       curr_speed      : 0
+       control         : 5
+       curr_control    : 0
+       awareness       : 5
+       curr_awareness  : 0
+       personality     : 5
+       curr_personality: 0
+       luck            : 5
+       curr_luck       : 0
+       -
+     -
    -
  -
diff -crN nakedmudv1.0/lib/world/1/mobs~ nakedmudv1.4/lib/world/1/mobs~
*** nakedmudv1.0/lib/world/1/mobs~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/lib/world/1/mobs~	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,77 ****
- list:=
-   race      : 0
-   rdesc     : A small, buxom blonde is here, serving the tavern patrons.
-   dialog    : 100
-   position  : 3
-   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.

-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-         vnum: 150
-         -
-         vnum: 140
-         -
-       -
-     -
-   sex       : 0
-   multirdesc: 
-   level     : 2
-   name      : Mysty
-   vnum      : 100
-   multiname : 
-   keywords  : mysty, blonde, waitress
-   -
-   race      : 0
-   rdesc     : A handsome, darkhaired man is here, standing behind the bar.
-   dialog    : -1
-   position  : 3
-   desc      :~
-        He is about average height, with short black hair and peircing 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.

-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-         vnum: 141
-         -
-       -
-     -
-   sex       : 0
-   multirdesc: 
-   level     : 2
-   name      : Julesz
-   vnum      : 101
-   multiname : 
-   keywords  : Julesz, bartender, man
-   -
-   race      : 0
-   rdesc     : A barfly is here, mulling about.
-   dialog    : -1
-   position  : 3
-   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.

-   auxiliary :-
-     script_aux_data:-
-       scripts:=
-       -
-     -
-   sex       : 0
-   multirdesc: A group of %d barflies are here, mulling about.
-   level     : 2
-   name      : a barfly
-   vnum      : 130
-   multiname : a group of %d bar flies
-   keywords  : barfly
-   -
- -
--- 0 ----
diff -crN nakedmudv1.0/lib/world/1/objs nakedmudv1.4/lib/world/1/objs
*** nakedmudv1.0/lib/world/1/objs	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/lib/world/1/objs	2010-11-01 15:54:17.000000000 -0500
***************
*** 56,62 ****
      the ground, and has a few chairs seated around it.  It looks like it 
      could seat about four or five people at it.
    multiname : %d wooden tables
!   multirdesc: There are %d empty tables scattered around here.
    bits      : a
    -
    vnum      : 130
--- 56,62 ----
      the ground, and has a few chairs seated around it.  It looks like it 
      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
diff -crN nakedmudv1.0/lib/world/1/objs~ nakedmudv1.4/lib/world/1/objs~
*** nakedmudv1.0/lib/world/1/objs~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/lib/world/1/rooms~ nakedmudv1.4/lib/world/1/rooms~
*** nakedmudv1.0/lib/world/1/rooms~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/lib/world/1/scripts nakedmudv1.4/lib/world/1/scripts
*** nakedmudv1.0/lib/world/1/scripts	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/lib/world/1/scripts	2010-11-01 15:54:17.000000000 -0500
***************
*** 162,167 ****
--- 162,179 ----
      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: 196
+   type: 1
+   narg: 0
+   name: depth check
+   args: check
+   code:~
+     # Scripts will sometimes trigger off of eachother, sending us into an
+     # infinite loop. As of version 1.1, we have added a "depth check" in to
+     # prevent such problems from arising. This is just a check to make sure
+     # that the depth check is working properly
+     me.act("say check")
+   -
    vnum: 197
    type: 4
    narg: 0
diff -crN nakedmudv1.0/lib/world/1/zone~ nakedmudv1.4/lib/world/1/zone~
*** nakedmudv1.0/lib/world/1/zone~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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 ----
diff -crN nakedmudv1.0/lib/world/world~ nakedmudv1.4/lib/world/world~
*** nakedmudv1.0/lib/world/world~	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/lib/world/world~	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,2 ****
- vnum : 0
- -
--- 0 ----
diff -crN nakedmudv1.0/src/action.c nakedmudv1.4/src/action.c
*** nakedmudv1.0/src/action.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/action.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 111,117 ****
  
    // add in our example delayed action
    add_cmd("dsay", NULL, cmd_dsay, 0, POS_SITTING, POS_FLYING, 
! 	  LEVEL_ADMIN, FALSE);
  }
  
  void interrupt_action(void *ch, bitvector_t where) {
--- 111,139 ----
  
    // 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) {
!   LIST *actions = mapGet(actors, ch);
!   if(actions == NULL || listSize(actions) == 0)
!     return FALSE;
! 
!   bool action_found    = FALSE;
!   LIST_ITERATOR *act_i = newListIterator(actions);
!   ACTION_DATA  *action = NULL;
! 
!   // iterate across all of our current actions and see if any
!   // involve the faculties of "where"
!   ITERATE_LIST(action, act_i) {
!     if(IS_SET(action->where, where)) {
!       action_found = TRUE;
!       break;
!     }
!   }
!   deleteListIterator(act_i);
! 
!   return action_found;
  }
  
  void interrupt_action(void *ch, bitvector_t where) {
***************
*** 125,138 ****
      LIST_ITERATOR *act_i = newListIterator(actions);
      ACTION_DATA *action  = NULL;
  
!     // we can't use ITERATE_LIST here because we are possibly
!     // removing the current element while we are on it, which
!     // makes it kinda hard to move onto the next element afterwards ;)
!     while((action = listIteratorCurrent(act_i)) != NULL) {
!       listIteratorNext(act_i);
! 
        // check to see if we've found an action that needs interruption
!       if(IS_SET(where, action->where)) {
  	if(action->on_interrupt)
  	  action->on_interrupt(ch, action->data, action->where, action->arg);
  	listRemove(actions, action);
--- 147,155 ----
      LIST_ITERATOR *act_i = newListIterator(actions);
      ACTION_DATA *action  = NULL;
  
!     ITERATE_LIST(action, act_i) {
        // check to see if we've found an action that needs interruption
!       if(IS_SET(action->where, where)) {
  	if(action->on_interrupt)
  	  action->on_interrupt(ch, action->data, action->where, action->arg);
  	listRemove(actions, action);
***************
*** 186,196 ****
      if(listSize(actions) > 0) {
        act_i = newListIterator(actions);
  
!       // we can't use ITERATE_LIST here because we are possibly
!       // removing the current element while we are on it, which
!       // makes it kinda hard to move onto the next element afterwards ;)
!       while((action = listIteratorCurrent(act_i)) != NULL) {
! 	listIteratorNext(act_i);
  	// decrement the delay
  	action->delay -= time;
  	// pop the action from the list, and run it
--- 203,209 ----
      if(listSize(actions) > 0) {
        act_i = newListIterator(actions);
  
!       ITERATE_LIST(action, act_i) {
  	// decrement the delay
  	action->delay -= time;
  	// pop the action from the list, and run it
diff -crN nakedmudv1.0/src/action.h nakedmudv1.4/src/action.h
*** nakedmudv1.0/src/action.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/action.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 36,41 ****
--- 36,48 ----
  
  
  //
+ // Returns TRUE if the character is performing an action with "where". If
+ // the faculty module is not installed, "where" should be 1.
+ //
+ bool is_acting(void *ch, bitvector_t where);
+ 
+ 
+ //
  // Start a character performing an action. If the delay reaches 0, on_complete
  // is run. If the action is terminated prematurely, on_interrupt is run.
  //
diff -crN nakedmudv1.0/src/action_safe.c nakedmudv1.4/src/action_safe.c
*** nakedmudv1.0/src/action_safe.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/action_safe.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,129 ****
- //*****************************************************************************
- //
- // cmd_misc.c
- //
- // a collection of miscellaneous commands that come with NakedMud(tm)
- //
- //*****************************************************************************
- #include "mud.h"
- #include "character.h"
- #include "socket.h"
- #include "utils.h"
- #include "save.h"
- #include "handler.h"
- 
- 
- //
- // Various preference bits that can be turned on and off
- //
- COMMAND(cmd_tog_prf) {
-   switch(subcmd) {
-   case SUBCMD_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));
-   }
- }
- 
- 
- //
- // Set or delete an alias. If no argument is supplied, all aliases are listed.
- //
- COMMAND(cmd_alias) {
-   // list off all of the aliases
-   if(!arg || !*arg) {
-     send_to_char(ch, "Current aliases:\r\n");
-     if(hashSize(charGetAliases(ch)) == 0)
-       send_to_char(ch, "none\r\n");
-     else {
-       HASH_ITERATOR *alias_i = newHashIterator(charGetAliases(ch));
-       const char      *alias = NULL;
-       while( (alias = hashIteratorCurrentKey(alias_i)) != NULL) {
- 	send_to_char(ch, "%-20s %s\r\n", alias, hashIteratorCurrentVal(alias_i));
- 	hashIteratorNext(alias_i);
-       }
-       deleteHashIterator(alias_i);
-     }
-   }
-   // otherwise, modify a specific one
-   else {
-     char alias[SMALL_BUFFER];
-     arg = one_arg(arg, alias);
-     charSetAlias(ch, alias, arg);
-     send_to_char(ch, "Alias %s.\r\n", (arg && *arg ? "set" : "deleted"));
-   }
- }
- 
- 
- //
- // clear the screen
- //
- COMMAND(cmd_clear) {
-   send_to_char(ch, "\033[H\033[J");
- }
- 
- 
- //
- // quit the game
- //
- COMMAND(cmd_quit)
- {
-   char buf[MAX_BUFFER];
- 
-   /* log the attempt */
-   sprintf(buf, "%s has left the game.", charGetName(ch));
-   log_string(buf);
- 
-   save_player(ch);
- 
-   /* make sure we're no longer in the world */
-   if(charGetRoom(ch))
-     char_from_room(ch);
- 
-   charGetSocket(ch)->player = NULL;
-   close_socket(charGetSocket(ch), FALSE);
-   extract_mobile(ch);
- }
- 
- 
- //
- // save the character
- //
- COMMAND(cmd_save)
- {
-   save_player(ch);
-   text_to_char(ch, "Saved.\r\n");
- }
- 
- 
- //
- // 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");
-   }
- }
--- 0 ----
diff -crN nakedmudv1.0/src/admin.c nakedmudv1.4/src/admin.c
*** nakedmudv1.0/src/admin.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/admin.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 19,29 ****
  #include "action.h"
  #include "storage.h"
  
- // optional modules
- #ifdef MODULE_FACULTY
- #include "modules/faculty/faculty.h"
- #endif
- 
  
  //
  // BOOM! Shut down the MUD
--- 19,24 ----
***************
*** 94,101 ****
  //
  // Perform a copyover
  //
! COMMAND(cmd_copyover)
! { 
    FILE *fp;
    SOCKET_DATA *dsock;
    char buf[100];
--- 89,95 ----
  //
  // Perform a copyover
  //
! COMMAND(cmd_copyover) { 
    FILE *fp;
    SOCKET_DATA *dsock;
    char buf[100];
***************
*** 149,156 ****
  //
  // show a list of all the PCs who are linkdead
  //
! COMMAND(cmd_linkdead)
! {
    CHAR_DATA *xMob;
    char buf[MAX_BUFFER];
    bool found = FALSE;
--- 143,149 ----
  //
  // show a list of all the PCs who are linkdead
  //
! COMMAND(cmd_linkdead) {
    CHAR_DATA *xMob;
    char buf[MAX_BUFFER];
    bool found = FALSE;
***************
*** 168,170 ****
--- 161,171 ----
    if (!found)
      text_to_char(ch, "Noone is currently linkdead.\n\r");
  }
+ 
+ 
+ //
+ // List all of the non-player commands the character has access to
+ //
+ COMMAND(cmd_wizhelp) {
+   show_commands(ch, LEVEL_BUILDER, charGetLevel(ch));
+ }
diff -crN nakedmudv1.0/src/alias/alias.c nakedmudv1.4/src/alias/alias.c
*** nakedmudv1.0/src/alias/alias.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/alias/alias.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,224 ----
+ //*****************************************************************************
+ //
+ // alias.c
+ //
+ // Aliases allow a player to set up one command as another (e.g. "eat bread"
+ // as "food").
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../auxiliary.h"
+ #include "../storage.h"
+ #include "../character.h"
+ 
+ #include "alias.h"
+ 
+ // how many buckets are in the alias hashtable?
+ #define ALIAS_TABLE_SIZE           10
+ 
+ 
+ //*****************************************************************************
+ //
+ // auxiliary data
+ //
+ //*****************************************************************************
+ typedef struct alias_aux_data {
+   HASHTABLE *aliases;
+ } ALIAS_AUX_DATA;
+ 
+ 
+ ALIAS_AUX_DATA *
+ newAliasAuxData() {
+   ALIAS_AUX_DATA *data = malloc(sizeof(ALIAS_AUX_DATA));
+   //
+   // Hashtables can take up lots of storage space. Because of this, let's
+   // not create any tables until it's actually needed. This will cut down
+   // on lots of memory usage w.r.t. NPCs who do not use aliases
+   //  data->aliases        = newHashtable(ALIAS_TABLE_SIZE);
+   //
+   data->aliases        = NULL;
+   return data;
+ }
+ 
+ 
+ void
+ deleteAliasAuxData(ALIAS_AUX_DATA *data) {
+   if(data->aliases) {
+     HASH_ITERATOR *hash_i = newHashIterator(data->aliases);
+     const char     *alias = NULL;
+     char             *cmd = NULL;
+ 
+     ITERATE_HASH(alias, cmd, hash_i) 
+       free(cmd);
+     deleteHashIterator(hash_i);
+     deleteHashtable(data->aliases);
+   }
+   free(data);
+ }
+ 
+ 
+ void
+ aliasAuxDataCopyTo(ALIAS_AUX_DATA *from, ALIAS_AUX_DATA *to) {
+   // aliases are for personal use, and it is doubtful we would
+   // ever have a motivation for copying them over. Thus, we shall
+   // not do any copying here.
+ }
+ 
+ 
+ ALIAS_AUX_DATA *
+ aliasAuxDataCopy(ALIAS_AUX_DATA *data) {
+   // as with aliasAuxDataCopyTo, there seems to be little reason
+   // why we would ever want to copy aliases. They are personal,
+   // and have no reason for being copied. Thus, let us just return
+   // a new datastructure.
+   return newAliasAuxData();
+ }
+ 
+ 
+ STORAGE_SET *aliasAuxDataStore(ALIAS_AUX_DATA *data) {
+   // if we have no hashtable, return an empty set
+   if(data->aliases == NULL || hashSize(data->aliases) == 0)
+     return new_storage_set();
+ 
+   STORAGE_SET *set       = new_storage_set();
+   STORAGE_SET_LIST *list = new_storage_list();
+   HASH_ITERATOR  *hash_i = newHashIterator(data->aliases);
+   const char       *name = NULL;
+   const char        *cmd = NULL;
+ 
+   store_list(set, "aliases", list, NULL);
+   ITERATE_HASH(name, cmd, hash_i) {
+     STORAGE_SET *alias_set = new_storage_set();
+     store_string(alias_set, "key", name, NULL);
+     store_string(alias_set, "val", hashIteratorCurrentVal(hash_i), NULL);
+     storage_list_put(list, alias_set);
+   }
+   deleteHashIterator(hash_i);
+   return set;
+ }
+ 
+ 
+ ALIAS_AUX_DATA *aliasAuxDataRead(STORAGE_SET *set) {
+   // if the file contains no alias data, then don't load any
+   if(!storage_contains(set, "aliases"))
+     return newAliasAuxData();
+ 
+   ALIAS_AUX_DATA *data   = newAliasAuxData();
+   data->aliases          = newHashtable(ALIAS_TABLE_SIZE);
+   STORAGE_SET_LIST *list = read_list(set, "aliases");
+   STORAGE_SET *var       = NULL;
+ 
+   while( (var = storage_list_next(list)) != NULL)
+     hashPut(data->aliases, read_string(var, "key"), 
+ 	    strdup(read_string(var, "val")));
+   return data;
+ }
+ 
+ 
+ void init_aliases() {
+   // install aliases on the character datastructure
+   auxiliariesInstall("alias_aux_data",
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_CHAR,
+ 				       newAliasAuxData, deleteAliasAuxData,
+ 				       aliasAuxDataCopyTo, aliasAuxDataCopy,
+ 				       aliasAuxDataStore, aliasAuxDataRead));
+ 
+   // allow people to view their aliases
+   add_cmd("alias", NULL, cmd_alias, 0, POS_UNCONCIOUS, POS_FLYING, 
+ 	  LEVEL_PLAYER, FALSE, TRUE);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // functions for interacting with character aliases
+ //
+ //*****************************************************************************
+ const char *charGetAlias(CHAR_DATA *ch, const char *alias) {
+   ALIAS_AUX_DATA *data = charGetAuxiliaryData(ch, "alias_aux_data");
+   if(data->aliases == NULL)
+     return NULL;
+   return hashGet(data->aliases, alias);
+ }
+ 
+ 
+ void charSetAlias(CHAR_DATA *ch, const char *alias, const char *cmd){
+   ALIAS_AUX_DATA *data = charGetAuxiliaryData(ch, "alias_aux_data");
+   // if our alias table is NULL, create a new one
+   if(data->aliases == NULL)
+     data->aliases = newHashtable(ALIAS_TABLE_SIZE);
+ 
+   // pull out the last one
+   char *oldcmd = hashRemove(data->aliases, alias);
+   if(oldcmd != NULL)
+     free(oldcmd);
+   // put in the new one if it exists
+   if(cmd && *cmd)
+     hashPut(data->aliases, alias, strdup(cmd));
+ }
+ 
+ 
+ char *expand_alias(const char *alias, const char *arg) {
+   char *cmd = strdup(alias);
+ 
+   // first, we replace all occurances of the numeric parameters
+   int i;
+   for(i = 1; i < 10; i++) {
+     char param[3];
+     char one_arg[SMALL_BUFFER];
+     sprintf(param, "$%d", i);
+     arg_num(arg, one_arg, i);
+     replace_string(&cmd, param, one_arg, TRUE);
+   }
+ 
+   // then we replace the wildcard
+   replace_string(&cmd, "$*", arg, TRUE);
+   return cmd;
+ }
+ 
+ 
+ //
+ // Set or delete an alias. If no argument is supplied, all aliases are listed.
+ //
+ COMMAND(cmd_alias) {
+   // list off all of the aliases
+   if(!arg || !*arg) {
+     ALIAS_AUX_DATA *data = charGetAuxiliaryData(ch, "alias_aux_data");
+     send_to_char(ch, "Current aliases:\r\n");
+     if(data->aliases == NULL || hashSize(data->aliases) == 0)
+       send_to_char(ch, "  none\r\n");
+     else {
+       HASH_ITERATOR *alias_i = newHashIterator(data->aliases);
+       const char      *alias = NULL;
+       const char        *cmd = NULL;
+ 
+       ITERATE_HASH(alias, cmd, alias_i)
+ 	send_to_char(ch, "  %-20s %s\r\n", alias, cmd);
+       deleteHashIterator(alias_i);
+     }
+   }
+   else {
+     char alias[SMALL_BUFFER];
+     arg = one_arg(arg, alias);
+ 
+     // try to delete an alias
+     if(!arg || !*arg) {
+       const char *curr_cmd = charGetAlias(ch, alias);
+       if(!curr_cmd)
+ 	send_to_char(ch, "You do not have such an alias.\r\n");
+       else {
+ 	charSetAlias(ch, alias, arg);
+ 	send_to_char(ch, "Alias deleted.\r\n");
+       }
+     }
+ 
+     // try to set an alias
+     else {
+       charSetAlias(ch, alias, arg);
+       send_to_char(ch, "Alias set.\r\n");
+     }
+   }
+ }
diff -crN nakedmudv1.0/src/alias/alias.h nakedmudv1.4/src/alias/alias.h
*** nakedmudv1.0/src/alias/alias.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/alias/alias.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,38 ----
+ #ifndef __ALIAS_H
+ #define __ALIAS_H
+ //*****************************************************************************
+ //
+ // alias.h
+ //
+ // Aliases allow a player to set up one command as another (e.g. "eat bread"
+ // as "food").
+ //
+ //*****************************************************************************
+ 
+ //
+ // This must be put at the top of mud.h so the rest of the MUD knows that
+ // we've got the alias module installed
+ // #define MODULE_ALIAS
+ //
+ 
+ //
+ // prepare aliases for use
+ //
+ void init_aliases();
+ 
+ const char  *charGetAlias  (CHAR_DATA *ch, const char *alias);
+ void         charSetAlias  (CHAR_DATA *ch, const char *alias, const char *cmd);
+ 
+ //
+ // expand an alias's parameters with the arguments provided. Returned
+ // string must be freed after being used.
+ //
+ char *expand_alias(const char *alias, const char *arg);
+ 
+ //
+ // list all of a character's aliases to him
+ //
+ COMMAND(cmd_alias);
+ 
+ 
+ #endif // __ALIAS_H
diff -crN nakedmudv1.0/src/alias/.depend nakedmudv1.4/src/alias/.depend
*** nakedmudv1.0/src/alias/.depend	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/alias/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ alias.o: alias.c alias.h
diff -crN nakedmudv1.0/src/alias/module.mk nakedmudv1.4/src/alias/module.mk
*** nakedmudv1.0/src/alias/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/alias/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ # src files we have
+ SRC   += alias/alias.c
diff -crN nakedmudv1.0/src/autorun.pl nakedmudv1.4/src/autorun.pl
*** nakedmudv1.0/src/autorun.pl	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/autorun.pl	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,9 ****
- while (1) {
-     print "Autorun started", `date`;
-     open (SERVER, "NakedMud");
-     while(<SERVER>) {
- 	
-     }
-     print "Game exited", `date`;
-     sleep 5;
- }
--- 0 ----
diff -crN nakedmudv1.0/src/body.c nakedmudv1.4/src/body.c
*** nakedmudv1.0/src/body.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/body.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 22,28 ****
  typedef struct bodypart_data   BODYPART;
  
  struct body_data {
!   LIST *parts;               // a list of all the parts on the body
  };
  
  
--- 22,29 ----
  typedef struct bodypart_data   BODYPART;
  
  struct body_data {
!   LIST   *parts;             // a list of all the parts on the body
!   int      size;             // how big is our body?
  };
  
  
***************
*** 61,66 ****
--- 62,79 ----
    "dragon",
  };
  
+ const char *bodysize_list[NUM_BODYSIZES] = {
+   "diminuitive",
+   "tiny",
+   "small",
+   "medium",
+   "large",
+   "huge",
+   "gargantuan",
+   "collosal"
+ };
+ 
+ 
  /**
   * Create a new bodypart_data
   */
***************
*** 100,105 ****
--- 113,119 ----
   */
  BODY_DATA *newDragonBody() {
    BODY_DATA *body = newBody();
+   body->size = BODYSIZE_COLLOSAL;
    bodyAddPosition(body, "left hind claw",          BODYPOS_CLAW,          1);
    bodyAddPosition(body, "right hind claw",         BODYPOS_CLAW,          1);
    bodyAddPosition(body, "left front claw",         BODYPOS_CLAW,          1);
***************
*** 126,131 ****
--- 140,146 ----
   */
  BODY_DATA *newHumanoidBody() {
    BODY_DATA *body = newBody();
+   body->size = BODYSIZE_MEDIUM;
    bodyAddPosition(body, "right grip",              BODYPOS_HELD,          0);
    bodyAddPosition(body, "left grip",               BODYPOS_HELD,          0);
    bodyAddPosition(body, "right foot",              BODYPOS_RIGHT_FOOT,    2);
***************
*** 193,198 ****
--- 208,225 ----
    return BODYTYPE_NONE;
  }
  
+ const char *bodysizeGetName(int size) {
+   return bodysize_list[size];
+ }
+ 
+ int bodysizeGetNum(const char *size) {
+   int i;
+   for(i = 0; i < NUM_BODYSIZES; i++)
+     if(!strcasecmp(size, bodysize_list[i]))
+       return i;
+   return BODYSIZE_NONE;
+ }
+ 
  const char *bodyposGetName(int bodypos) {
    return bodypos_list[bodypos];
  }
***************
*** 232,241 ****
--- 259,273 ----
    BODY_DATA *Bnew = newBody();
    deleteListWith(Bnew->parts, deleteBodypart);
    Bnew->parts = listCopyWith(B->parts, bodypartCopy);
+   Bnew->size  = B->size;
  
    return Bnew;
  }
  
+ int bodyGetSize(const BODY_DATA *B) {
+   return B->size;
+ }
+ 
  //
  // Find a bodypart on the body with the given name
  //
diff -crN nakedmudv1.0/src/body.h nakedmudv1.4/src/body.h
*** nakedmudv1.0/src/body.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/body.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 44,49 ****
--- 44,59 ----
  
  #define NUM_BODYTYPES             2
  
+ #define BODYSIZE_NONE            -1
+ #define BODYSIZE_DIMINUITIVE      0
+ #define BODYSIZE_TINY             1
+ #define BODYSIZE_SMALL            2
+ #define BODYSIZE_MEDIUM           3
+ #define BODYSIZE_LARGE            4
+ #define BODYSIZE_HUGE             5
+ #define BODYSIZE_GARGANTUAN       6
+ #define BODYSIZE_COLLOSAL         7
+ #define NUM_BODYSIZES             8
  
  /**
   * Return a list of the postypes for a list of posnames (comma-separated)
***************
*** 70,75 ****
--- 80,97 ----
  
  
  /**
+  * return the name of the specified bodysize
+  */
+ const char *bodysizeGetName(int size);
+ 
+ 
+ /**
+  * return the number assocciated with the bodysize
+  */
+ int bodysizeGetNum(const char *size);
+ 
+ 
+ /**
   * returns the number of the bodyposition
   */
  int bodyposGetNum(const char *bodypos);
***************
*** 101,106 ****
--- 123,134 ----
  
  
  /**
+  * Return the size of the body
+  */
+ int bodyGetSize(const BODY_DATA *B);
+ 
+ 
+ /**
   * Add a new position to the body. <type> is one of the basic
   * position types listed at the start of this header, and
   * <weight> is how much of the body's mass the piece takes up,
diff -crN nakedmudv1.0/src/builder.c nakedmudv1.4/src/builder.c
*** nakedmudv1.0/src/builder.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/builder.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 26,33 ****
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
! #include "modules/scripts/script_set.h"
  #endif
  
  
--- 26,33 ----
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
! #include "scripts/script_set.h"
  #endif
  
  
***************
*** 268,286 ****
      message(ch, NULL, NULL, NULL, FALSE, TO_NOTCHAR,
  	    "$n raises $s arms, and white flames engulf the entire room.");
  
!     // purge all the objects. We can't use ITERATE_LIST because
!     // we extract the current list element
!     obj = listIteratorCurrent(list_i);
!     while( (obj = listIteratorCurrent(list_i)) != NULL) {
!       listIteratorNext(list_i);
        extract_obj(obj);
-     }
      deleteListIterator(list_i);
  
      // and now all of the non-characters
      list_i = newListIterator(roomGetCharacters(charGetRoom(ch)));
!     while( (vict = listIteratorCurrent(list_i)) != NULL) {
!       listIteratorNext(list_i);
        if(vict == ch || !charIsNPC(vict)) 
  	continue;
        char_from_room(vict);
--- 268,281 ----
      message(ch, NULL, NULL, NULL, FALSE, TO_NOTCHAR,
  	    "$n raises $s arms, and white flames engulf the entire room.");
  
!     // purge all the objects. 
!     ITERATE_LIST(obj, list_i)
        extract_obj(obj);
      deleteListIterator(list_i);
  
      // and now all of the non-characters
      list_i = newListIterator(roomGetCharacters(charGetRoom(ch)));
!     ITERATE_LIST(vict, list_i) {
        if(vict == ch || !charIsNPC(vict)) 
  	continue;
        char_from_room(vict);
***************
*** 391,396 ****
--- 386,392 ----
    }
  }
  
+ 
  #ifdef MODULE_SCRIPTS
  COMMAND(cmd_sclist) {
    do_list(ch, zoneGetScript, scriptGetName, scriptGetType, scriptTypeName,
diff -crN nakedmudv1.0/src/builder.h nakedmudv1.4/src/builder.h
*** nakedmudv1.0/src/builder.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/builder.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 35,39 ****
  //
  bool try_buildwalk(CHAR_DATA *ch, int dir);
  
- 
  #endif // __BUILDER_H
--- 35,38 ----
diff -crN nakedmudv1.0/src/character.c nakedmudv1.4/src/character.c
*** nakedmudv1.0/src/character.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/character.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 2,16 ****
  //
  // character.c
  //
! // implementation of the character datastructure (PCs and NPCs)
  //
  //*****************************************************************************
- 
  #include "mud.h"
- #include "socket.h"
  #include "utils.h"
  #include "body.h"
- #include "log.h"
  #include "races.h"
  #include "handler.h"
  #include "auxiliary.h"
--- 2,19 ----
  //
  // character.c
  //
! // Basic implementation of the character datastructure (PCs and NPCs). Includes
! // data for storing room, inventory, body, equipment, and other "essential"
! // information. If you plan on adding any other information to characters, it
! // is strongly suggested you do so through auxiliary data (see auxiliary.h).
! //
! // For a recap, IF YOU PLAN ON ADDING ANY OTHER INFORMATION TO CHARACTERS, IT
! // IS STRONGLY SUGGESTED YOU DO SO THROUGH AUXILIARY DATA (see auxiliary.h).
  //
  //*****************************************************************************
  #include "mud.h"
  #include "utils.h"
  #include "body.h"
  #include "races.h"
  #include "handler.h"
  #include "auxiliary.h"
***************
*** 19,31 ****
  #include "character.h"
  
  
- // probably good to increase this if your MUD relies heavily on spec_vars
- #define SPEC_VAR_TABLE_SIZE      10
- 
  // mob UIDs (unique IDs) start at a million and go 
  // up by one every time a new NPC is created
! #define START_MOB_UID   (1000000)
! int next_mob_uid  = START_MOB_UID;
  
  const char *sex_names[NUM_SEXES] = {
    "male",
--- 22,31 ----
  #include "character.h"
  
  
  // mob UIDs (unique IDs) start at a million and go 
  // up by one every time a new NPC is created
! #define START_MOB_UID       1000000
! int next_mob_uid  =   START_MOB_UID;
  
  const char *sex_names[NUM_SEXES] = {
    "male",
***************
*** 110,117 ****
    int                    position;
  
    LIST                 * inventory;
-   HASHTABLE            * spec_vars;
-   HASHTABLE            * aliases;
    HASHTABLE            * auxiliary_data;
  
    // data for NPCs only
--- 110,115 ----
***************
*** 153,160 ****
    ch->dialog        = NOTHING;
    ch->vnum          = NOBODY;
  
-   ch->spec_vars      = newHashtable(SPEC_VAR_TABLE_SIZE);
-   ch->aliases        = newHashtable(10);
    ch->auxiliary_data = newAuxiliaryData(AUXILIARY_TYPE_CHAR);
  
    return ch;
--- 151,156 ----
***************
*** 167,215 ****
  // utility functions
  //
  //*****************************************************************************
- void text_to_char(CHAR_DATA *ch, const char *txt)
- {
-   if (ch->socket && socketGetState(ch->socket) == STATE_PLAYING && txt && *txt){
-     text_to_buffer(ch->socket, txt);
-     ch->socket->bust_prompt = TRUE;
-   }
- 
-   // if it's a PC or we are not in game, then
-   // don't send the mesage to us
-   if(!charIsNPC(ch))
-     try_log(charGetName(ch), txt);
- }
- 
- void send_to_char(CHAR_DATA *ch, const char *format, ...) {
-   if(ch->socket && format && *format) {
-     static char buf[MAX_BUFFER];
-     va_list args;
-     va_start(args, format);
-     vsprintf(buf, format, args);
-     va_end(args);
-     text_to_char(ch, buf);
-     return;
-   }
- };
- 
- void send_to_list(LIST *list, const char *format, ...) {
-   if(format && *format) {
-     // form the message
-     static char buf[MAX_BUFFER];
-     va_list args;
-     va_start(args, format);
-     vsprintf(buf, format, args);
-     va_end(args);
- 
-     // send it out to everyone
-     LIST_ITERATOR *list_i = newListIterator(list);
-     CHAR_DATA *ch = NULL;
-     ITERATE_LIST(ch, list_i)
-       text_to_char(ch, buf);
-     deleteListIterator(list_i);
-   }
- };
- 
  void charSetRdesc(CHAR_DATA *ch, const char *rdesc) {
    if(ch->rdesc) free(ch->rdesc);
    ch->rdesc =   strdup(rdesc ? rdesc : "");
--- 163,168 ----
***************
*** 340,357 ****
    return ch->loadroom;
  }
  
- HASHTABLE   *charGetVars  ( CHAR_DATA *ch) {
-   return ch->spec_vars;
- }
- 
- HASHTABLE   *charGetAliases  ( CHAR_DATA *ch) {
-   return ch->aliases;
- }
- 
- const char   *charGetAlias  ( CHAR_DATA *ch, const char *alias) {
-   return hashGet(ch->aliases, alias);
- }
- 
  void *charGetAuxiliaryData(const CHAR_DATA *ch, const char *name) {
    return hashGet(ch->auxiliary_data, name);
  }
--- 293,298 ----
***************
*** 360,369 ****
    return ch->furniture;
  }
  
- int          charGetVarVal( CHAR_DATA *ch, const char *var) {
-   return (int)hashGet(ch->spec_vars, var);
- }
- 
  void         charSetSocket    ( CHAR_DATA *ch, SOCKET_DATA *socket) {
    ch->socket = socket;
  };
--- 301,306 ----
***************
*** 415,430 ****
    ch->uid = uid;
  }
  
- void         charSetAlias  (CHAR_DATA *ch, const char *alias, const char *cmd){
-   // pull out the last one
-   char *oldcmd = hashRemove(ch->aliases, alias);
-   if(oldcmd != NULL)
-     free(oldcmd);
-   // put in the new one if it exists
-   if(cmd && *cmd)
-     hashPut(ch->aliases, alias, strdup(cmd));
- }
- 
  void         charResetBody(CHAR_DATA *ch) {
    charSetBody(ch, raceCreateBody(ch->race));
  }
--- 352,357 ----
***************
*** 437,455 ****
    ch->furniture = furniture;
  }
  
- void charSetVar( CHAR_DATA *ch, const char *var, int val) {
-   // make sure the varname has no spaces
-   if(strstr(var, " ") != NULL) {
-     log_string("ERROR: On %s, attempted to edit a variable with a space, '%s'",
- 	       charGetName(ch), var);
-     return;
-   }
- 
-   if(val == 0)
-     hashRemove(ch->spec_vars, var);
-   else
-     hashPut(ch->spec_vars, var, (void *)val);
- }
  
  
  //*****************************************************************************
--- 364,369 ----
***************
*** 480,558 ****
    if(mob->keywords)    free(mob->keywords);
    deleteAuxiliaryData(mob->auxiliary_data);
  
-   if(mob->spec_vars)   deleteHashtable(mob->spec_vars);
-   if(mob->aliases) {
-     HASH_ITERATOR *hash_i = newHashIterator(mob->aliases);
-     const char     *alias = NULL;
-     char             *cmd = NULL;
-     while( (alias = hashIteratorCurrentKey(hash_i)) != NULL) {
-       hashIteratorNext(hash_i);
-       cmd = hashRemove(mob->aliases, alias);
-       free(cmd);
-     }
-     deleteHashIterator(hash_i);
-     deleteHashtable(mob->aliases);
-   }
    free(mob);
  }
  
- STORAGE_SET *aliasStore(HASHTABLE *table) {
-   STORAGE_SET *set       = new_storage_set();
-   HASH_ITERATOR *hash_i  = newHashIterator(table);
-   STORAGE_SET_LIST *list = new_storage_list();
-   const char  *aliasname = NULL;
- 
-   store_list(set, "list", list, NULL);
-   while( (aliasname = hashIteratorCurrentKey(hash_i)) != NULL) {
-     STORAGE_SET *aliasset = new_storage_set();
-     store_string(aliasset, "key", aliasname, NULL);
-     store_string(aliasset, "val", hashIteratorCurrentVal(hash_i), NULL);
-     hashIteratorNext(hash_i);
-     storage_list_put(list, aliasset);
-   }
-   deleteHashIterator(hash_i);
-   return set;
- }
- 
- HASHTABLE *aliasRead(STORAGE_SET *set) {
-   HASHTABLE *table       = newHashtable(10);
-   STORAGE_SET_LIST *list = read_list(set, "list");
-   STORAGE_SET *var       = NULL;
- 
-   while( (var = storage_list_next(list)) != NULL)
-     hashPut(table, read_string(var, "key"), strdup(read_string(var, "val")));
-   return table;
- }
- 
- 
- STORAGE_SET *variableStore(HASHTABLE *table) {
-   STORAGE_SET *set       = new_storage_set();
-   HASH_ITERATOR *hash_i  = newHashIterator(table);
-   STORAGE_SET_LIST *list = new_storage_list();
-   const char    *varname = NULL;
- 
-   store_list(set, "list", list, NULL);
-   while( (varname = hashIteratorCurrentKey(hash_i)) != NULL) {
-     STORAGE_SET *varset = new_storage_set();
-     store_string(varset, "key", varname, NULL);
-     store_int   (varset, "val", (int)hashIteratorCurrentVal(hash_i), NULL);
-     hashIteratorNext(hash_i);
-     storage_list_put(list, varset);
-   }
-   deleteHashIterator(hash_i);
-   return set;
- }
- 
- HASHTABLE *variableRead(STORAGE_SET *set) {
-   HASHTABLE *table       = newHashtable(SPEC_VAR_TABLE_SIZE);
-   STORAGE_SET_LIST *list = read_list(set, "list");
-   STORAGE_SET *var       = NULL;
- 
-   while( (var = storage_list_next(list)) != NULL)
-     hashPut(table, read_string(var, "key"), (void *)read_int(var, "val"));
-   return table;
- }
- 
  
  CHAR_DATA *charRead(STORAGE_SET *set) {
    CHAR_DATA *mob = newMobile();
--- 394,402 ----
***************
*** 575,584 ****
      charSetLoadroom(mob,   read_int   (set, "loadroom"));
      charSetPos(mob,        read_int   (set, "position"));
      mob->prfs = parse_bits(read_string(set, "prfs"));
-     deleteHashtable(mob->spec_vars);
-     mob->spec_vars = variableRead(read_set(set, "variables"));
-     deleteHashtable(mob->aliases);
-     mob->aliases  = aliasRead(read_set(set, "aliases"));
    }
    // and NPC data
    else
--- 419,424 ----
***************
*** 587,592 ****
--- 427,436 ----
    deleteAuxiliaryData(mob->auxiliary_data);
    mob->auxiliary_data = auxiliaryDataRead(read_set(set, "auxiliary"), 
  					  AUXILIARY_TYPE_CHAR);
+ 
+   // reset our body to the default for our race
+   charResetBody(mob);
+ 
    return mob;
  }
  
***************
*** 611,618 ****
      store_string(set, "password",   mob->password,                 NULL);
      store_int   (set, "uid",        mob->uid,                      NULL);
      store_int   (set, "loadroom",   roomGetVnum(charGetRoom(mob)), NULL);
-     store_set   (set, "variables",  variableStore(mob->spec_vars), NULL);
-     store_set   (set, "aliases",    aliasStore(mob->aliases),      NULL);
    }
    // NPC-only data
    else
--- 455,460 ----
diff -crN nakedmudv1.0/src/character.h nakedmudv1.4/src/character.h
*** nakedmudv1.0/src/character.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/character.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 4,35 ****
  //
  // character.h
  //
! // the structures and functions needed for working with PCs and NPCs
  //
  //*****************************************************************************
  
  
- 
- 
  //
  // the difference between newChar and newMobile is that newMobile
  // assigned a new UID whereas newChar does not.
  //
! CHAR_DATA   *newChar           ();
! CHAR_DATA    *newMobile         ();
! void         deleteChar      (CHAR_DATA *mob);
  
! CHAR_DATA    *charRead          (STORAGE_SET *set);
! STORAGE_SET *charStore         (CHAR_DATA *mob);
  
- CHAR_DATA    *charCopy          (CHAR_DATA *mob);
- void         charCopyTo        (CHAR_DATA *from, CHAR_DATA *to);
  
  
- bool         charIsNPC        ( CHAR_DATA *ch);
- bool         charIsName       ( CHAR_DATA *ch, const char *name);
- void         putCharInventory ( CHAR_DATA *ch, OBJ_DATA *obj);
- void         charResetBody    ( CHAR_DATA *ch);
  
  //*****************************************************************************
  //
--- 4,40 ----
  //
  // character.h
  //
! // Basic implementation of the character datastructure (PCs and NPCs). Includes
! // data for storing room, inventory, body, equipment, and other "essential"
! // information. If you plan on adding any other information to characters, it
! // is strongly suggested you do so through auxiliary data (see auxiliary.h).
! //
! // For a recap, IF YOU PLAN ON ADDING ANY OTHER INFORMATION TO CHARACTERS, IT
! // IS STRONGLY SUGGESTED YOU DO SO THROUGH AUXILIARY DATA (see auxiliary.h).
  //
  //*****************************************************************************
  
  
  //
  // the difference between newChar and newMobile is that newMobile
  // assigned a new UID whereas newChar does not.
  //
! CHAR_DATA   *newChar          ();
! CHAR_DATA    *newMobile       ();
! void         deleteChar       (CHAR_DATA *mob);
! 
! CHAR_DATA    *charRead        (STORAGE_SET *set);
! STORAGE_SET *charStore        (CHAR_DATA *mob);
  
! CHAR_DATA    *charCopy        (CHAR_DATA *mob);
! void         charCopyTo       (CHAR_DATA *from, CHAR_DATA *to);
  
  
+ bool         charIsNPC        (CHAR_DATA *ch);
+ bool         charIsName       (CHAR_DATA *ch, const char *name);
+ void         putCharInventory (CHAR_DATA *ch, OBJ_DATA *obj);
+ void         charResetBody    (CHAR_DATA *ch);
  
  
  //*****************************************************************************
  //
***************
*** 38,46 ****
  //*****************************************************************************
  
  /* buffers the output        */
! void  text_to_char        ( CHAR_DATA *dMob, const char *txt );
! void  send_to_char          ( CHAR_DATA *ch, const char *format, ...);
! void  send_to_list          ( LIST *list, const char *format, ...);
  
  
  //*****************************************************************************
--- 43,53 ----
  //*****************************************************************************
  
  /* buffers the output        */
! void  text_to_char          (CHAR_DATA *dMob, const char *txt );
! void  send_to_char          (CHAR_DATA *ch, const char *format, ...) 
! __attribute__ ((format (printf, 2, 3)));
! void  send_to_list          (LIST *list, const char *format, ...) 
! __attribute__ ((format (printf, 2, 3)));
  
  
  //*****************************************************************************
***************
*** 56,62 ****
  const char  *charGetRdesc     ( CHAR_DATA *ch);
  const char  *charGetMultiRdesc( CHAR_DATA *ch);
  const char  *charGetMultiName ( CHAR_DATA *ch);
- const char  *charGetAlias     ( CHAR_DATA *ch, const char *alias);
  int          charGetLevel     ( CHAR_DATA *ch);
  int          charGetSex       ( CHAR_DATA *ch);
  bitvector_t  charGetBits      ( CHAR_DATA *ch, int field);
--- 63,68 ----
***************
*** 67,77 ****
  int          charGetRace      ( CHAR_DATA *ch);
  int          charGetUID       ( CHAR_DATA *ch);
  room_vnum    charGetLoadroom  ( CHAR_DATA *ch);
- HASHTABLE   *charGetVars      ( CHAR_DATA *ch);
- HASHTABLE   *charGetAliases   ( CHAR_DATA *ch);
  OBJ_DATA    *charGetFurniture ( CHAR_DATA *ch);
  int          charGetPos       ( CHAR_DATA *ch);
- int          charGetVarVal    ( CHAR_DATA *ch, const char *var);
  void        *charGetAuxiliaryData(const CHAR_DATA *ch, const char *name);
  
  void         charSetSocket    ( CHAR_DATA *ch, SOCKET_DATA *socket);
--- 73,80 ----
***************
*** 88,97 ****
  void         charSetRace      ( CHAR_DATA *ch, int race);
  void         charSetUID       ( CHAR_DATA *ch, int uid);
  void         charSetLoadroom  ( CHAR_DATA *ch, room_vnum loadroom);
- void         charSetVar       ( CHAR_DATA *ch, const char *var, int val);
  void         charSetFurniture ( CHAR_DATA *ch, OBJ_DATA *furniture);
  void         charSetPos       ( CHAR_DATA *ch, int pos);
- void         charSetAlias     ( CHAR_DATA *ch, const char *alias, const char *cmd);
  
  
  //*****************************************************************************
--- 91,98 ----
diff -crN nakedmudv1.0/src/char_vars/char_vars.c nakedmudv1.4/src/char_vars/char_vars.c
*** nakedmudv1.0/src/char_vars/char_vars.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/char_vars/char_vars.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,336 ----
+ //*****************************************************************************
+ //
+ // char_vars.c
+ //
+ // This module allows key/value pairs to be stored on a character. The values
+ // can be strings, integers, or doubles. If a value is called for in the wrong
+ // type (e.g. you're trying to get a string as an integer) the module will
+ // automagically handle the conversion. Variable types default to ints.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../character.h"
+ #include "../storage.h"
+ #include "../auxiliary.h"
+ 
+ #include "char_vars.h"
+ 
+ 
+ //*****************************************************************************
+ //
+ // local functions and datastructurs
+ //
+ //*****************************************************************************
+ 
+ // the size of the hashtable we store char vars in
+ #define CHAR_VAR_TABLE_SIZE   10
+ 
+ // used in storage_sets to keep track of what kind of data we're saving
+ const char *char_var_types[] = {
+   "string",
+   "int",
+   "long",
+   "double"
+ };
+ 
+ 
+ typedef struct char_var {
+   char *str_val;
+   int   type;
+ } CHAR_VAR;
+ 
+ 
+ CHAR_VAR *newCharVarString(const char *str) {
+   CHAR_VAR *data = malloc(sizeof(CHAR_VAR));
+   data->str_val  = strdup(str ? str : "");
+   data->type     = CHAR_VAR_STRING;
+   return data;
+ }
+ 
+ CHAR_VAR *newCharVarInt(int val) {
+   CHAR_VAR *data = malloc(sizeof(CHAR_VAR));
+   char str_val[20]; sprintf(str_val, "%d", val);
+   data->str_val  = strdup(str_val);
+   data->type     = CHAR_VAR_INT;
+   return data;
+ }
+ 
+ CHAR_VAR *newCharVarLong(long val) {
+   CHAR_VAR *data = malloc(sizeof(CHAR_VAR));
+   char str_val[20]; sprintf(str_val, "%ld", val);
+   data->str_val  = strdup(str_val);
+   data->type     = CHAR_VAR_LONG;
+   return data;
+ }
+ 
+ CHAR_VAR *newCharVarDouble(double val) {
+   CHAR_VAR *data = malloc(sizeof(CHAR_VAR));
+   char str_val[20]; sprintf(str_val, "%lf", val);
+   data->str_val  = strdup(str_val);
+   data->type     = CHAR_VAR_DOUBLE;
+   return data;
+ }
+ 
+ void deleteCharVar(CHAR_VAR *data) {
+   if(data->str_val) free(data->str_val);
+   free(data);
+ }
+ 
+ CHAR_VAR *charVarCopy(CHAR_VAR *data) {
+   CHAR_VAR *new_data = malloc(sizeof(CHAR_VAR));
+   new_data->str_val = strdup(data->str_val);
+   new_data->type    = data->type;
+   return new_data;
+ }
+ 
+ //
+ // delete a hashtable of char vars
+ //
+ void deleteCharVarTable(HASHTABLE *table) {
+   HASH_ITERATOR *hash_i = newHashIterator(table);
+   const char       *key = NULL;
+   CHAR_VAR         *val = NULL;
+   
+   ITERATE_HASH(key, val, hash_i)
+     deleteCharVar(val);
+   deleteHashIterator(hash_i);
+   deleteHashtable(table);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // char_var auxiliary data
+ //
+ //*****************************************************************************
+ typedef struct char_var_aux_data {
+   HASHTABLE *char_vars;
+ } CHAR_VAR_AUX_DATA;
+ 
+ 
+ CHAR_VAR_AUX_DATA *
+ newCharVarAuxData() {
+   CHAR_VAR_AUX_DATA *data = malloc(sizeof(CHAR_VAR_AUX_DATA));
+   // Hashtables can take up lots of storage space. Because of this, let's
+   // not create any tables until it's actually needed. This will cut down
+   // on lots of memory usage w.r.t. NPCs who do not use character variables
+   //  data->char_vars        = newHashtable(CHAR_VAR_TABLE_SIZE);
+   data->char_vars         = NULL;
+   return data;
+ }
+ 
+ 
+ void
+ deleteCharVarAuxData(CHAR_VAR_AUX_DATA *data) {
+   if(data->char_vars)
+     deleteCharVarTable(data->char_vars);
+   free(data);
+ }
+ 
+ 
+ void
+ charVarAuxDataCopyTo(CHAR_VAR_AUX_DATA *from, CHAR_VAR_AUX_DATA *to) {
+   int from_size = (from->char_vars ? hashSize(from->char_vars) : 0);
+   int to_size   = (to->char_vars   ? hashSize(to->char_vars)   : 0);
+ 
+   // clear out our current data
+   if(to_size > 0) {
+     deleteCharVarTable(to->char_vars);
+     to->char_vars = NULL;
+   }
+ 
+   // check to see if the "from" table exists
+   if(from_size > 0) {
+     // make sure the "to" table exists
+     if(to->char_vars == NULL)
+       to->char_vars = newHashtable(CHAR_VAR_TABLE_SIZE);
+ 
+     // copy everything over
+     HASH_ITERATOR *from_i = newHashIterator(from->char_vars);
+     const char       *key = NULL;
+     CHAR_VAR         *val = NULL;
+ 
+     ITERATE_HASH(key, val, from_i)
+       hashPut(to->char_vars, key, charVarCopy(val));
+     deleteHashIterator(from_i);
+   }
+ }
+ 
+ 
+ CHAR_VAR_AUX_DATA *
+ charVarAuxDataCopy(CHAR_VAR_AUX_DATA *data) {
+   CHAR_VAR_AUX_DATA *new_data = newCharVarAuxData();
+   charVarAuxDataCopyTo(data, new_data);
+   return new_data;
+ }
+ 
+ 
+ STORAGE_SET *charVarAuxDataStore(CHAR_VAR_AUX_DATA *data) {
+   // first, check if the table even exists
+   if(data->char_vars == NULL || hashSize(data->char_vars) == 0)
+     return new_storage_set();
+ 
+   STORAGE_SET       *set = new_storage_set();
+   HASH_ITERATOR  *hash_i = newHashIterator(data->char_vars);
+   STORAGE_SET_LIST *list = new_storage_list();
+   const char        *key = NULL;
+   CHAR_VAR          *val = NULL;
+ 
+   store_list(set, "variables", list, NULL);
+   // iterate across all the entries and add them
+   ITERATE_HASH(key, val, hash_i) {
+     STORAGE_SET *var_set = new_storage_set();
+     store_string(var_set, "key",  key,                       NULL);
+     store_string(var_set, "val",  val->str_val,              NULL);
+     store_string(var_set, "type", char_var_types[val->type], NULL);
+     storage_list_put(list, var_set);
+   }
+   deleteHashIterator(hash_i);
+   return set;
+ }
+ 
+ 
+ HASHTABLE *variableRead(STORAGE_SET *set) {
+   HASHTABLE *table       = newHashtable(CHAR_VAR_TABLE_SIZE);
+   STORAGE_SET_LIST *list = read_list(set, "list");
+   STORAGE_SET *var       = NULL;
+ 
+   while( (var = storage_list_next(list)) != NULL)
+     hashPut(table, read_string(var, "key"), (void *)read_int(var, "val"));
+   return table;
+ }
+ 
+ 
+ CHAR_VAR_AUX_DATA *charVarAuxDataRead(STORAGE_SET *set) {
+   // if the set doesn't contain any entries, don't bother trying to parse
+   if(!storage_contains(set, "variables"))
+     return newCharVarAuxData();
+ 
+   CHAR_VAR_AUX_DATA *data = newCharVarAuxData();
+   STORAGE_SET_LIST  *list = read_list(set, "variables");
+   STORAGE_SET    *var_set = NULL;
+   data->char_vars         = newHashtable(CHAR_VAR_TABLE_SIZE);
+   
+   while( (var_set = storage_list_next(list)) != NULL) {
+     const char *var_type = read_string(var_set, "type");
+     if(!strcasecmp(var_type, "int"))
+       hashPut(data->char_vars, read_string(var_set, "key"),
+ 	      newCharVarInt(read_int(var_set, "val")));
+     else if(!strcasecmp(var_type, "long"))
+       hashPut(data->char_vars, read_string(var_set, "key"),
+ 	      newCharVarLong(read_long(var_set, "val")));
+     else if(!strcasecmp(var_type, "double"))
+       hashPut(data->char_vars, read_string(var_set, "key"),
+ 	      newCharVarDouble(read_double(var_set, "val")));
+     else if(!strcasecmp(var_type, "string"))
+       hashPut(data->char_vars, read_string(var_set, "key"),
+ 	      newCharVarString(read_string(var_set, "val")));
+     else
+       log_string("ERROR: Tried to read unknown char_var type, %s.", var_type);
+   }
+     
+   return data;
+ }
+ 
+ 
+ void init_char_vars() {
+   // install char vars on the character datastructure
+   auxiliariesInstall("char_var_aux_data",
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_CHAR,
+ 				       newCharVarAuxData, deleteCharVarAuxData,
+ 				       charVarAuxDataCopyTo, charVarAuxDataCopy,
+ 				       charVarAuxDataStore,charVarAuxDataRead));
+ }
+ 
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // functions for interacting with char_vars
+ //
+ //*****************************************************************************
+ int charGetVarType(CHAR_DATA *ch, const char *key) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *var = (data->char_vars ? hashGet(data->char_vars, key) : NULL);
+   return (var ? var->type : CHAR_VAR_INT);
+ }
+ 
+ 
+ int charGetInt(CHAR_DATA *ch, const char *key) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *var = (data->char_vars ? hashGet(data->char_vars, key) : NULL);
+   return (var ? atoi(var->str_val) : 0);
+ }
+ 
+ 
+ long charGetLong(CHAR_DATA *ch, const char *key) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *var = (data->char_vars ? hashGet(data->char_vars, key) : NULL);
+   return (var ? atol(var->str_val) : 0);
+ }
+ 
+ 
+ double charGetDouble(CHAR_DATA *ch, const char *key) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *var = (data->char_vars ? hashGet(data->char_vars, key) : NULL);
+   return (var ? atof(var->str_val) : 0);
+ }
+ 
+ 
+ const char *charGetString(CHAR_DATA *ch, const char *key) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *var = (data->char_vars ? hashGet(data->char_vars, key) : NULL);
+   return (var ? var->str_val : "");
+ }
+ 
+ 
+ void charSetInt(CHAR_DATA *ch, const char *key, int val) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *old = (data->char_vars ? hashRemove(data->char_vars, key) : NULL);
+   if(data->char_vars == NULL && val != 0)
+     data->char_vars = newHashtable(CHAR_VAR_TABLE_SIZE);
+   if(old != NULL) 
+     deleteCharVar(old);
+   if(val != 0)
+     hashPut(data->char_vars, key, newCharVarInt(val));
+ }
+ 
+ 
+ void charSetLong(CHAR_DATA *ch, const char *key, long val) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *old = (data->char_vars ? hashRemove(data->char_vars, key) : NULL);
+   if(data->char_vars == NULL && val != 0)
+     data->char_vars = newHashtable(CHAR_VAR_TABLE_SIZE);
+   if(old != NULL) 
+     deleteCharVar(old);
+   if(val != 0)
+     hashPut(data->char_vars, key, newCharVarLong(val));
+ }
+ 
+ 
+ void charSetDouble(CHAR_DATA *ch, const char *key, double val) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *old = (data->char_vars ? hashRemove(data->char_vars, key) : NULL);
+   if(data->char_vars == NULL && val != 0)
+     data->char_vars = newHashtable(CHAR_VAR_TABLE_SIZE);
+   if(old != NULL) 
+     deleteCharVar(old);
+   if(val != 0)
+     hashPut(data->char_vars, key, newCharVarDouble(val));
+ }
+ 
+ 
+ void charSetString(CHAR_DATA *ch, const char *key, const char *val) {
+   CHAR_VAR_AUX_DATA *data = charGetAuxiliaryData(ch, "char_var_aux_data");
+   CHAR_VAR *old = (data->char_vars ? hashRemove(data->char_vars, key) : NULL);
+   if(data->char_vars == NULL && *val != '\0') 
+     data->char_vars = newHashtable(CHAR_VAR_TABLE_SIZE);
+   if(old != NULL) 
+     deleteCharVar(old);
+   if(*val != '\0')
+     hashPut(data->char_vars, key, newCharVarString(val));
+ }
diff -crN nakedmudv1.0/src/char_vars/char_vars.h nakedmudv1.4/src/char_vars/char_vars.h
*** nakedmudv1.0/src/char_vars/char_vars.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/char_vars/char_vars.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,47 ----
+ #ifndef __CHAR_VARS_H
+ #define __CHAR_VARS_H
+ //*****************************************************************************
+ //
+ // char_vars.h
+ //
+ // This module allows key/value pairs to be stored on a character. The values
+ // can be strings, integers, or doubles. If a value is called for in the wrong
+ // type (e.g. you're trying to get a string as an integer) the module will
+ // automagically handle the conversion. Variable types default to ints.
+ //
+ //*****************************************************************************
+ 
+ 
+ //
+ // This must be put at the top of mud.h so the rest of the MUD knows that
+ // we've got the alias module installed
+ // #define MODULE_CHAR_VARS
+ //
+ 
+ 
+ // the different types of data we can store
+ #define CHAR_VAR_STRING        0
+ #define CHAR_VAR_INT           1
+ #define CHAR_VAR_LONG          2
+ #define CHAR_VAR_DOUBLE        3
+ 
+ 
+ 
+ //
+ // prepare char_vars for use
+ //
+ void         init_char_vars   ();
+ 
+ int          charGetVarType   (CHAR_DATA *ch, const char *key);
+ 
+ int          charGetInt       (CHAR_DATA *ch, const char *key);
+ long         charGetLong      (CHAR_DATA *ch, const char *key);
+ double       charGetDouble    (CHAR_DATA *ch, const char *key);
+ const char  *charGetString    (CHAR_DATA *ch, const char *key);
+ 
+ void         charSetInt       (CHAR_DATA *ch, const char *key, int val);
+ void         charSetLong      (CHAR_DATA *ch, const char *key, long val);
+ void         charSetDouble    (CHAR_DATA *ch, const char *key, double val);
+ void         charSetString    (CHAR_DATA *ch, const char *key, const char *val);
+ 
+ #endif // __CHAR_VARS_H
diff -crN nakedmudv1.0/src/char_vars/.depend nakedmudv1.4/src/char_vars/.depend
*** nakedmudv1.0/src/char_vars/.depend	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/char_vars/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ char_vars.o: char_vars.c char_vars.h
diff -crN nakedmudv1.0/src/char_vars/module.mk nakedmudv1.4/src/char_vars/module.mk
*** nakedmudv1.0/src/char_vars/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/char_vars/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ # source files we need to add
+ SRC += char_vars/char_vars.c
diff -crN nakedmudv1.0/src/cmd_comm.c nakedmudv1.4/src/cmd_comm.c
*** nakedmudv1.0/src/cmd_comm.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/cmd_comm.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 18,24 ****
  
  // option modules
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  
--- 18,24 ----
  
  // option modules
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  
  
***************
*** 51,71 ****
      if(!*arg)
        send_to_char(ch, "What did you want to ask %s?\r\n", name);
      else {
-       int find_type;
        CHAR_DATA *tgt = generic_find(ch, name,
  				    FIND_TYPE_CHAR,
  				    FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				    FALSE, &find_type);
  
!       if(!tgt || find_type != FOUND_CHAR)
  	send_to_char(ch, "Who were you trying to ask a question?\r\n");
        else if(tgt == ch)
  	send_to_char(ch, "You have a nice conversation with yourself.\r\n");
        else {
! 	message(ch, tgt, NULL, NULL, FALSE, TO_CHAR, 
! 		"{wYou ask $N%s, '%s'", (ask_about ? " about"  : ""), arg);
! 	message(ch, tgt, NULL, NULL, FALSE, TO_VICT, 
! 		"{w$n asks you%s, '%s'", (ask_about ? " about" : ""), arg);
  #ifdef MODULE_SCRIPTS
  	try_speech_script(ch, tgt, arg);
  #endif	
--- 51,74 ----
      if(!*arg)
        send_to_char(ch, "What did you want to ask %s?\r\n", name);
      else {
        CHAR_DATA *tgt = generic_find(ch, name,
  				    FIND_TYPE_CHAR,
  				    FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				    FALSE, NULL);
  
!       if(tgt == NULL)
  	send_to_char(ch, "Who were you trying to ask a question?\r\n");
        else if(tgt == ch)
  	send_to_char(ch, "You have a nice conversation with yourself.\r\n");
        else {
! 	char other_buf[MAX_BUFFER];
! 	sprintf(other_buf, "{w$n asks you%s, '%s'{n",
! 		(ask_about ? " about" : ""), arg);
! 	message(ch, tgt, NULL, NULL, FALSE, TO_VICT, other_buf);	
! 
! 	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	
***************
*** 100,118 ****
      if(!*arg)
        send_to_char(ch, "What did you want to tell %s?\r\n", name);
      else {
-       int find_type;
        CHAR_DATA *tgt = generic_find(ch, name,
  				    FIND_TYPE_CHAR,
  				    FIND_SCOPE_WORLD | FIND_SCOPE_VISIBLE,
! 				    FALSE, &find_type);
  
!       if(!tgt || find_type != FOUND_CHAR)
  	send_to_char(ch, "Who were you trying to talk to?\r\n");
        else if(tgt == ch)
  	send_to_char(ch, "You have a nice conversation with yourself.\r\n");
        else {
! 	message(ch, tgt, NULL, NULL, FALSE, TO_CHAR, 
! 		"{rYou tell $N, '%s'", arg);
  
  	// if we're an NPC, make sure we do colored output
  	char *color_arg = arg;
--- 103,119 ----
      if(!*arg)
        send_to_char(ch, "What did you want to tell %s?\r\n", name);
      else {
        CHAR_DATA *tgt = generic_find(ch, name,
  				    FIND_TYPE_CHAR,
  				    FIND_SCOPE_WORLD | FIND_SCOPE_VISIBLE,
! 				    FALSE, NULL);
  
!       if(tgt == NULL)
  	send_to_char(ch, "Who were you trying to talk to?\r\n");
        else if(tgt == ch)
  	send_to_char(ch, "You have a nice conversation with yourself.\r\n");
        else {
! 	send_to_char(ch, "{rYou tell %s, '%s'{n\r\n", charGetName(tgt), arg);
  
  	// if we're an NPC, make sure we do colored output
  	char *color_arg = arg;
***************
*** 122,131 ****
  	    color_arg = tagResponses(dialog, arg, "{c", "{r");
  	}
  
! 	message(ch, tgt, NULL, NULL, FALSE, TO_VICT, 
! 		"{r$n tells you, '%s'", arg);
! 	  if(color_arg != arg) 
! 	    free(color_arg);
        }
      }
    }
--- 123,134 ----
  	    color_arg = tagResponses(dialog, arg, "{c", "{r");
  	}
  
! 	char other_buf[MAX_BUFFER];
! 	sprintf(other_buf, "{r$n tells you, '%s'{n", arg);
! 	message(ch, tgt, NULL, NULL, FALSE, TO_VICT, other_buf);
! 
! 	if(color_arg != arg) 
! 	  free(color_arg);
        }
      }
    }
***************
*** 186,198 ****
    if(!arg || !*arg)
      send_to_char(ch, "Whom did you want to greet?\r\n");
    else {
-     int find_type;
      CHAR_DATA *tgt = generic_find(ch, arg,
  				  FIND_TYPE_CHAR,
  				  FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				  FALSE, &find_type);
  
!     if(!tgt || find_type != FOUND_CHAR)
        send_to_char(ch, "Who were you trying to greet?\r\n");
      else if(tgt == ch)
        send_to_char(ch, 
--- 189,200 ----
    if(!arg || !*arg)
      send_to_char(ch, "Whom did you want to greet?\r\n");
    else {
      CHAR_DATA *tgt = generic_find(ch, arg,
  				  FIND_TYPE_CHAR,
  				  FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				  FALSE, NULL);
  
!     if(tgt == NULL)
        send_to_char(ch, "Who were you trying to greet?\r\n");
      else if(tgt == ch)
        send_to_char(ch, 
***************
*** 215,228 ****
  	  char *response = tagResponses(dialog,
  					dialogGetGreet(dialog),
  					"{c", "{p");
! 	  message(ch, tgt, NULL, NULL, FALSE, TO_CHAR,
! 		  "{p$N responds, '%s'", response);
  	  free(response);
  	}
  
  	else
! 	  message(ch, tgt, NULL, NULL, TRUE, TO_CHAR,
! 		  "{p$N does not have anything to say.");
        }
      }
    }
--- 217,229 ----
  	  char *response = tagResponses(dialog,
  					dialogGetGreet(dialog),
  					"{c", "{p");
! 	  send_to_char(ch, "{p%s responds, '%s'\r\n",charGetName(tgt),response);
  	  free(response);
  	}
  
  	else
! 	  send_to_char(ch, "{p%s does not have anything to say.\r\n",
! 		       charGetName(tgt));
        }
      }
    }
***************
*** 249,255 ****
      // person put his or her name were it's wanted. Otherwise, tag
      // it onto the front of the message
      if(strfind(arg, "$n"))
!       sprintf(buf, arg);
      else
        sprintf(buf, "$n %s", arg);
  
--- 250,256 ----
      // person put his or her name were it's wanted. Otherwise, tag
      // it onto the front of the message
      if(strfind(arg, "$n"))
!       strcpy(buf, arg);
      else
        sprintf(buf, "$n %s", arg);
  
diff -crN nakedmudv1.0/src/cmd_manip.c nakedmudv1.4/src/cmd_manip.c
*** nakedmudv1.0/src/cmd_manip.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/cmd_manip.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 60,67 ****
        send_to_char(ch, "You cannot seem to find the key.\r\n");
      else {
        send_to_char(ch, "You lock %s.\r\n", exitGetName(found));
!       message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
! 	      "$n locks %s.", exitGetName(found));
        exitSetLocked(found, TRUE);
      }
    }
--- 60,67 ----
        send_to_char(ch, "You cannot seem to find the key.\r\n");
      else {
        send_to_char(ch, "You lock %s.\r\n", exitGetName(found));
!       send_around_char(ch, TRUE, "%s locks %s.\r\n", 
! 		       charGetName(ch), exitGetName(found));
        exitSetLocked(found, TRUE);
      }
    }
***************
*** 118,125 ****
        send_to_char(ch, "You cannot seem to find the key.\r\n");
      else {
        send_to_char(ch, "You unlock %s.\r\n", exitGetName(found));
!       message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
! 	      "$n unlocks %s.", exitGetName(found));
        exitSetLocked(found, FALSE);
      }
    }
--- 118,125 ----
        send_to_char(ch, "You cannot seem to find the key.\r\n");
      else {
        send_to_char(ch, "You unlock %s.\r\n", exitGetName(found));
!       send_around_char(ch, TRUE, "%s unlocks %s.\r\n", 
! 		       charGetName(ch), exitGetName(found));
        exitSetLocked(found, FALSE);
      }
    }
***************
*** 175,184 ****
  				FIND_SCOPE_INV | FIND_SCOPE_VISIBLE,
  				TRUE, &found_type);
  
-   int cont_type  = FOUND_NONE;
    OBJ_DATA *cont = generic_find(ch, arg,
  				FIND_TYPE_OBJ, FIND_SCOPE_IMMEDIATE,
! 				FALSE, &cont_type);
  
    // make sure we've got what we need
    if(!found || !cont) {
--- 175,183 ----
  				FIND_SCOPE_INV | FIND_SCOPE_VISIBLE,
  				TRUE, &found_type);
  
    OBJ_DATA *cont = generic_find(ch, arg,
  				FIND_TYPE_OBJ, FIND_SCOPE_IMMEDIATE,
! 				FALSE, NULL);
  
    // make sure we've got what we need
    if(!found || !cont) {
***************
*** 241,252 ****
        send_to_char(ch, "%s appears to be locked.\r\n",
  		   (*exitGetName(found) ? exitGetName(found) : "It"));
      else {
!       exitSetClosed(found, FALSE);
        send_to_char(ch, "You open %s.\r\n",
  		   (*exitGetName(found) ? exitGetName(found) : "the exit"));
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
! 	      "$n opens %s.", (*exitGetName(found) ?
! 			        exitGetName(found) : "an exit"));
      }
    }
  
--- 240,252 ----
        send_to_char(ch, "%s appears to be locked.\r\n",
  		   (*exitGetName(found) ? exitGetName(found) : "It"));
      else {
!       char other_buf[SMALL_BUFFER];
!       sprintf(other_buf, "$n opens %s.", (*exitGetName(found) ?
! 					  exitGetName(found) : "an exit"));
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR, other_buf);
        send_to_char(ch, "You open %s.\r\n",
  		   (*exitGetName(found) ? exitGetName(found) : "the exit"));
!       exitSetClosed(found, FALSE);
      }
    }
  
***************
*** 302,313 ****
        send_to_char(ch, "It is easy to close something when someone "
  		   "has already done it for you!\r\n");
      else {
!       exitSetClosed(found, TRUE);
        send_to_char(ch, "You close %s.\r\n",
  		   (*exitGetName(found) ? exitGetName(found) : "the exit"));
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
! 	      "$n closes %s.", (*exitGetName(found) ?
! 				exitGetName(found) : "an exit"));
      }
    }
  
--- 302,314 ----
        send_to_char(ch, "It is easy to close something when someone "
  		   "has already done it for you!\r\n");
      else {
!       char other_buf[SMALL_BUFFER];
!       sprintf(other_buf, "$n closes %s.", (*exitGetName(found) ?
! 					   exitGetName(found) : "an exit"));
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR, other_buf);
        send_to_char(ch, "You close %s.\r\n",
  		   (*exitGetName(found) ? exitGetName(found) : "the exit"));
!       exitSetClosed(found, TRUE);
      }
    }
  
***************
*** 350,360 ****
    arg = one_arg(arg, name);
  
    // first check to see if we're trying to get from a container
-   int cont_type  = FOUND_NONE;
    OBJ_DATA *cont = NULL;
    if(*arg) {
      cont = generic_find(ch, arg, FIND_TYPE_OBJ, FIND_SCOPE_IMMEDIATE,
! 			FALSE, &cont_type);
      // were we trying to get something from a container 
      // but couldn't find the container?
      if(cont == NULL) {
--- 351,360 ----
    arg = one_arg(arg, name);
  
    // first check to see if we're trying to get from a container
    OBJ_DATA *cont = NULL;
    if(*arg) {
      cont = generic_find(ch, arg, FIND_TYPE_OBJ, FIND_SCOPE_IMMEDIATE,
! 			FALSE, NULL);
      // were we trying to get something from a container 
      // but couldn't find the container?
      if(cont == NULL) {
***************
*** 438,448 ****
  			     FIND_SCOPE_INV | FIND_SCOPE_VISIBLE, 
  			     TRUE, &found_type);
  
-   int char_type = FOUND_NONE; // redundant, but we need a variable to use
    CHAR_DATA *recv = generic_find(ch, arg,
  				 FIND_TYPE_CHAR,
  				 FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				 FALSE, &char_type);
  
    if(!recv)
      send_to_char(ch, "Whom where you looking for?\r\n");
--- 438,447 ----
  			     FIND_SCOPE_INV | FIND_SCOPE_VISIBLE, 
  			     TRUE, &found_type);
  
    CHAR_DATA *recv = generic_find(ch, arg,
  				 FIND_TYPE_CHAR,
  				 FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				 FALSE, NULL);
  
    if(!recv)
      send_to_char(ch, "Whom where you looking for?\r\n");
diff -crN nakedmudv1.0/src/cmd_misc.c nakedmudv1.4/src/cmd_misc.c
*** nakedmudv1.0/src/cmd_misc.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/cmd_misc.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 33,67 ****
  
  
  //
- // Set or delete an alias. If no argument is supplied, all aliases are listed.
- //
- COMMAND(cmd_alias) {
-   // list off all of the aliases
-   if(!arg || !*arg) {
-     send_to_char(ch, "Current aliases:\r\n");
-     if(hashSize(charGetAliases(ch)) == 0)
-       send_to_char(ch, "none\r\n");
-     else {
-       HASH_ITERATOR *alias_i = newHashIterator(charGetAliases(ch));
-       const char      *alias = NULL;
-       while( (alias = hashIteratorCurrentKey(alias_i)) != NULL) {
- 	send_to_char(ch, "%-20s %s\r\n", alias, hashIteratorCurrentVal(alias_i));
- 	hashIteratorNext(alias_i);
-       }
-       deleteHashIterator(alias_i);
-     }
-   }
-   // otherwise, modify a specific one
-   else {
-     char alias[SMALL_BUFFER];
-     arg = one_arg(arg, alias);
-     charSetAlias(ch, alias, arg);
-     send_to_char(ch, "Alias %s.\r\n", (arg && *arg ? "set" : "deleted"));
-   }
- }
- 
- 
- //
  // clear the screen
  //
  COMMAND(cmd_clear) {
--- 33,38 ----
diff -crN nakedmudv1.0/src/commands.h nakedmudv1.4/src/commands.h
*** nakedmudv1.0/src/commands.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/commands.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 13,18 ****
--- 13,19 ----
  COMMAND(cmd_copyover);
  COMMAND(cmd_shutdown);
  COMMAND(cmd_linkdead);
+ COMMAND(cmd_wizhelp);
  
  
  /* builder.c */
***************
*** 54,60 ****
  
  /* cmd_misc.c */
  COMMAND(cmd_delay);
- COMMAND(cmd_alias);
  COMMAND(cmd_clear);
  COMMAND(cmd_quit);
  COMMAND(cmd_save);
--- 55,60 ----
***************
*** 67,76 ****
  
  /* inform.c */
  COMMAND(cmd_who);
- COMMAND(cmd_help);
  COMMAND(cmd_look);
  COMMAND(cmd_inventory);
  COMMAND(cmd_equipment);
  
  
  /* olc.c */
--- 67,76 ----
  
  /* inform.c */
  COMMAND(cmd_who);
  COMMAND(cmd_look);
  COMMAND(cmd_inventory);
  COMMAND(cmd_equipment);
+ COMMAND(cmd_help);
  
  
  /* olc.c */
diff -crN nakedmudv1.0/src/.depend nakedmudv1.4/src/.depend
*** nakedmudv1.0/src/.depend	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,115 ****
  action.o: action.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.h utils.h text_editor.h character.h action.h
! action_safe.o: action_safe.c mud.h wrapsock.h property_table.h list.h \
!   hashmap.h hashtable.h character.h socket.h utils.h text_editor.h save.h \
!   handler.h
! admin.o: admin.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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
! auxiliary.o: auxiliary.c mud.h wrapsock.h property_table.h list.h \
!   hashmap.h hashtable.h utils.h text_editor.h storage.h auxiliary.h
! body.o: body.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h body.h utils.h text_editor.h
! builder.o: builder.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h world.h zone.h room.h exit.h movement.h builder.h \
!   character.h object.h handler.h inform.h utils.h text_editor.h races.h \
!   items.h dialog.h modules/scripts/script.h modules/scripts/script_set.h
! character.o: character.c mud.h wrapsock.h property_table.h list.h \
!   hashmap.h hashtable.h socket.h utils.h text_editor.h body.h log.h \
!   races.h handler.h auxiliary.h storage.h room.h character.h
  cmd_comm.o: cmd_comm.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.h utils.h text_editor.h handler.h inform.h character.h \
!   world.h dialog.h modules/scripts/script.h
  cmd_manip.o: cmd_manip.c mud.h wrapsock.h property_table.h list.h \
    hashmap.h hashtable.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 character.h socket.h utils.h text_editor.h save.h event.h \
    handler.h
! dialog.o: dialog.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h utils.h text_editor.h dialog.h storage.h
! event.o: event.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h utils.h text_editor.h character.h event.h
! exit.o: exit.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 utils.h text_editor.h storage.h extra_descs.h
! gameloop.o: gameloop.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h socket.h world.h character.h object.h utils.h text_editor.h \
!   save.h handler.h inform.h log.h races.h action.h event.h auxiliary.h \
!   storage.h modules/time/mudtime.h modules/scripts/script.h \
!   modules/olc/olc.h
! handler.o: handler.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 modules/scripts/script.h
! hashmap.o: hashmap.c list.h hashmap.h
! hashtable.o: hashtable.c list.h hashtable.h
  help.o: help.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h character.h
! help_new.o: help_new.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h character.h
! inform.o: inform.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 modules/time/mudtime.h
! interpret.o: interpret.c mud.h wrapsock.h property_table.h list.h \
!   hashmap.h hashtable.h utils.h text_editor.h character.h socket.h room.h \
!   movement.h commands.h action.h modules/scripts/script.h
! io.o: io.c mud.h wrapsock.h property_table.h list.h hashmap.h hashtable.h \
!   utils.h text_editor.h
  items.o: items.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.h object.h items.h
! list.o: list.c list.h
  log.o: log.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.h utils.h text_editor.h character.h storage.h log.h
! magic.o: magic.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h utils.h text_editor.h event.h action.h magic.h character.h \
!   inform.h
! mccp.o: mccp.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h socket.h utils.h text_editor.h
! movement.o: movement.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h character.h world.h room.h exit.h movement.h handler.h \
!   inform.h builder.h utils.h text_editor.h items.h object.h \
!   modules/scripts/script.h
! mud.o: mud.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h utils.h text_editor.h storage.h
  object.o: object.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.h extra_descs.h utils.h text_editor.h items.h body.h \
    handler.h storage.h auxiliary.h object.h
! property_table.o: property_table.c mud.h wrapsock.h property_table.h \
!   list.h hashmap.h hashtable.h utils.h text_editor.h
! races.o: races.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h races.h body.h utils.h text_editor.h
! room.o: room.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h exit.h extra_descs.h utils.h text_editor.h handler.h \
!   character.h auxiliary.h storage.h room_reset.h room.h \
!   modules/scripts/script.h
  room_reset.o: room_reset.c mud.h wrapsock.h property_table.h list.h \
    hashmap.h hashtable.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
! save.o: save.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h character.h world.h utils.h text_editor.h handler.h body.h \
!   object.h room.h storage.h
! shop.o: shop.c
! socket.o: socket.c wrapsock.h mud.h property_table.h list.h hashmap.h \
!   hashtable.h character.h utils.h text_editor.h socket.h \
!   modules/olc/olc.h
  storage.o: storage.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.h utils.h text_editor.h storage.h
! strings.o: strings.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h utils.h text_editor.h
! text_editor.o: text_editor.c mud.h wrapsock.h property_table.h list.h \
!   hashmap.h hashtable.h socket.h text_editor.h utils.h \
!   modules/scripts/script.h modules/olc/olc.h
! update.o: update.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h world.h action.h event.h
! utils.o: utils.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 help.h dialog.h event.h \
!   action.h modules/scripts/script.h
! world.o: world.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h zone.h room.h character.h object.h dialog.h utils.h \
!   text_editor.h storage.h world.h modules/scripts/script.h
! zone.o: zone.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h storage.h object.h character.h room.h zone.h utils.h \
!   text_editor.h dialog.h modules/scripts/script.h
--- 1,171 ----
+ gameloop.o: gameloop.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.h socket.h world.h character.h object.h utils.h text_editor.h \
+   save.h handler.h inform.h log.h races.h action.h event.h auxiliary.h \
+   storage.h time/mudtime.h scripts/script.h olc/olc.h alias/alias.h \
+   char_vars/char_vars.h socials/socials.h
+ mud.o: mud.c mud.h wrapsock.h property_table.h list.h hashmap.h \
+   hashtable.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 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 help.h scripts/script.h
+ interpret.o: interpret.c mud.h wrapsock.h property_table.h list.h \
+   hashmap.h hashtable.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 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 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 character.h world.h room.h exit.h movement.h handler.h \
+   inform.h builder.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 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 socket.h utils.h text_editor.h
! save.o: save.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 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 \
!   utils.h text_editor.h
! strings.o: strings.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h utils.h text_editor.h
! event.o: event.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 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 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 character.h socket.h utils.h text_editor.h save.h event.h \
    handler.h
! text_editor.o: text_editor.c mud.h wrapsock.h property_table.h list.h \
!   hashmap.h hashtable.h socket.h text_editor.h utils.h scripts/script.h \
!   olc/olc.h
! builder.o: builder.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h world.h zone.h room.h exit.h movement.h builder.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
! admin.o: admin.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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
  help.o: help.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h character.h help.h
  items.o: items.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.h object.h items.h
! races.o: races.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h races.h body.h utils.h text_editor.h
  log.o: log.c mud.h wrapsock.h property_table.h list.h hashmap.h \
    hashtable.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 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 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 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 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 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 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 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 body.h utils.h text_editor.h
! zone.o: zone.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.h storage.h object.h character.h room.h zone.h utils.h \
!   text_editor.h dialog.h scripts/script.h
! dialog.o: dialog.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 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 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 utils.h text_editor.h storage.h
! time.o: time/time.c mud.h wrapsock.h property_table.h list.h hashmap.h \
!   hashtable.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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
Binary files nakedmudv1.0/src/.DS_Store and nakedmudv1.4/src/.DS_Store differ
diff -crN nakedmudv1.0/src/event.c nakedmudv1.4/src/event.c
*** nakedmudv1.0/src/event.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/event.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 109,115 ****
  
    // add our proof of concept command
    add_cmd("devent", NULL, cmd_devent, 0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_ADMIN, FALSE);
  }
  
  void interrupt_event(EVENT_DATA *event) {
--- 109,115 ----
  
    // add our proof of concept command
    add_cmd("devent", NULL, cmd_devent, 0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_ADMIN, TRUE, FALSE);
  }
  
  void interrupt_event(EVENT_DATA *event) {
***************
*** 120,131 ****
    LIST_ITERATOR *ev_i = newListIterator(events);
    EVENT_DATA   *event = NULL;
  
!   // we can't use ITERATE_LIST here, because there are times
!   // where we will remove our current element  from the list, 
!   // making it kinda hard to go onto the next one afterwards ;)
!   while( (event = listIteratorCurrent(ev_i)) != NULL) {
!     listIteratorNext(ev_i);
! 
      // if we've found involvement, pop it on out
      if(event->owner == thing ||
         (event->check_involvement != NULL && 
--- 120,126 ----
    LIST_ITERATOR *ev_i = newListIterator(events);
    EVENT_DATA   *event = NULL;
  
!   ITERATE_LIST(event, ev_i) {
      // if we've found involvement, pop it on out
      if(event->owner == thing ||
         (event->check_involvement != NULL && 
***************
*** 154,162 ****
    // we can't use ITERATE_LIST here, because there are times
    // where we will remove our current element  from the list, 
    // making it kinda hard to go onto the next one afterwards ;)
!   while( (event = listIteratorCurrent(ev_i)) != NULL) {
!     listIteratorNext(ev_i);
! 
      // decrement the delay
      event->delay -= time;
      // pop the character from the list, and run the event
--- 149,155 ----
    // we can't use ITERATE_LIST here, because there are times
    // where we will remove our current element  from the list, 
    // making it kinda hard to go onto the next one afterwards ;)
!   ITERATE_LIST(event, ev_i) {
      // decrement the delay
      event->delay -= time;
      // pop the character from the list, and run the event
diff -crN nakedmudv1.0/src/example_module/module.mk nakedmudv1.4/src/example_module/module.mk
*** nakedmudv1.0/src/example_module/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/example_module/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,30 ----
+ ################################################################################
+ #
+ # example_module.mk
+ #
+ # The intent of this makefile is to act as a template makefile for people
+ # creating new modules for NakedMud(tm). The module installation process has
+ # been made as simple as I (Geoff Hollis) can make it; for the make file, all
+ # you really have to do is add a couple lines to SRC so that the main makefile
+ # knows that you have source files you want to compile. You are also able to
+ # add new libraries and includes if you need to. To make sure your module is
+ # compiled, you will have to add an entry for it in the Makefile within src/
+ #
+ # Questions and comments should be directed to Geoff Hollis (hollis@ualberta.ca)
+ #
+ ################################################################################
+ 
+ # If your module has any source files that need to be compiled (it should!
+ # that's what modules are for!) You will want to add their path relative to
+ # the main src directory, here. I have provided an example.
+ SRC     += example_module/foo.c example_module/bar.c
+ 
+ # If your module requires that you use some special flags for compiling, you
+ # can add them here. For example, if you need to include a directory containing
+ # headers your module requires. They will be picked up by the main makefile. 
+ # This line can remain blank if you do not need any flags.
+ C_FLAGS += 
+ 
+ # Does your module need some libraries? If so, add them here. If not, this line
+ # can remain blank.
+ LIBS    += 
diff -crN nakedmudv1.0/src/gameloop.c nakedmudv1.4/src/gameloop.c
*** nakedmudv1.0/src/gameloop.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/gameloop.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 25,45 ****
  
  
  // optional modules
- #ifdef MODULE_FACULTY
- #include "modules/faculty/faculty.h"
- #endif
- #ifdef MODULE_COMBAT
- #include "modules/combat/combat.h"
- #endif
  #ifdef MODULE_TIME
! #include "modules/time/mudtime.h"
  #endif
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  #ifdef MODULE_OLC
! #include "modules/olc/olc.h"
  #endif
  
  
  /* mccp support */
--- 25,52 ----
  
  
  // 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 */
***************
*** 67,72 ****
--- 74,82 ----
  PROPERTY_TABLE *mob_table = NULL;/* a table of mobs by UID, for quick lookup */
  PROPERTY_TABLE *obj_table = NULL;
  
+ char        *   greeting = NULL;
+ char        *   motd     = NULL;
+ 
  
  /*
   * This is where it all starts, nothing special.
***************
*** 170,184 ****
  #endif
  
    /* initialize faculties */
! #ifdef MODULE_FACULTY
!   log_string("Initializing faculties.");
!   init_faculties();
  #endif
  
!   /* initialize combat if we have faculties */
! #ifdef MODULE_COMBAT
!   log_string("Initializing combat.");
!   init_combat();
  #endif
  
    /* initialize the socket */
--- 180,203 ----
  #endif
  
    /* initialize faculties */
! #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();
! #endif
! 
! #ifdef MODULE_HELP
!   log_string("Initializing helpfiles.");
!   init_help();
  #endif
  
    /* initialize the socket */
***************
*** 264,269 ****
--- 283,289 ----
    /* 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)
***************
*** 291,305 ****
      }
  
      /* poll sockets in the socket list */
!     listIteratorReset(sock_i);
! 
!     // We cannot use ITERATE_LIST, because there is a chance we
!     // will remove the current element we are on from the list,
!     // making it impossible to carry on in the iterator.
!     //    ITERATE_LIST(dsock, sock_i) {
!     while( (dsock = listIteratorCurrent(sock_i)) != NULL) {
!       listIteratorNext(sock_i);
  
        /*
         * Close sockects we are unable to read from.
         */
--- 311,320 ----
      }
  
      /* 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.
         */
***************
*** 354,359 ****
--- 369,375 ----
        if (!flush_output(dsock))
          close_socket(dsock, FALSE);
      }
+     deleteListIterator(sock_i);
  
      /* call the top-level update handler */
      update_handler();
diff -crN nakedmudv1.0/src/.gdb_history nakedmudv1.4/src/.gdb_history
*** nakedmudv1.0/src/.gdb_history	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/.gdb_history	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,59 ****
- print N->next->elem
- print ((struct cmd_data *)N->next)->cmd_name
- print ((struct cmd_data *)N->next)->sort_by
- quit
- run
- bt
- bt
  down
  up
! print N
! print ((struct cmd_data *)N)->sort_by
! print ((struct cmd_data *)N)->scmd
! print ((struct cmd_data *)N)->cmd
! print ((struct cmd_data *)N)->cmd_name
! bt
! quit
! run
! quit
! run
  bt
- print obj->multi_name
  quit
  run
  quit
  run
  bt
  quit
  run
! quit
! run
  quit
  run
  bt
  quit
  run
  bt
  up
  up
  up
  up
! up
  quit
  run
- bt
- bt
- up
- info local
- clear
- bt
  quit
  run
  bt
  quit
  run
- bt
  quit
  quit
  run
  quit
--- 1,44 ----
  down
  up
! up
! up
! print room->auxiliary_data
! down
! print line
! print data
! info local
  bt
  quit
  run
  quit
  run
  bt
+ print line
  quit
  run
! print line
  quit
  run
  bt
  quit
  run
  bt
+ down
  up
  up
  up
  up
! print world
! bt
  quit
  run
  quit
  run
  bt
  quit
  run
  quit
+ run
  quit
  run
  quit
***************
*** 61,163 ****
  bt
  quit
  run
  quit
- run
  quit
  run
  quit
  run
  quit
  run
  quit
  run
  bt
! print data
! info local
! down
  up
- info local
- print desc
- print desc->night_desc
- print data
- bt
  up
- down
- down
- info local
- info
- bt
- info local
- down
  up
- info local
  up
! down
! down
! info local
! print room
! print data
! print room
! print room->name
! print room->vnum
! print room
! print room->name
! shutdown
  quit
  run
- print room
- print room->name
- print room->vnum
- print data
  quit
  run
  bt
! up
! down
  quit
  run
! quit
! quit
  quit
  run
  bt
- info local
- print bucket
- print table->num_buckets
- down
- up
- up
- up
- print room->auxiliary_data
- down
- print line
- print data
- info local
  bt
! quit
! run
! quit
  run
  bt
- print line
  quit
  run
- print line
  quit
  run
  bt
  quit
  run
  bt
! down
! up
! up
! up
! up
! print world
! bt
  quit
  run
  quit
  run
  bt
--- 46,115 ----
  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
  quit
  run
  bt
  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
***************
*** 172,256 ****
  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
  quit
  run
  bt
  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
--- 124,256 ----
  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
  run
  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
diff -crN nakedmudv1.0/src/handler.c nakedmudv1.4/src/handler.c
*** nakedmudv1.0/src/handler.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/handler.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 21,27 ****
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  
--- 21,27 ----
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  
  
***************
*** 370,376 ****
  bool try_unequip(CHAR_DATA *ch, OBJ_DATA *obj) {
    if(bodyUnequip(charGetBody(ch), obj)) {
      objSetWearer(obj, NULL);
!      //*******************************
      // remove all of the item affects
      //*******************************
      return TRUE;
--- 370,376 ----
  bool try_unequip(CHAR_DATA *ch, OBJ_DATA *obj) {
    if(bodyUnequip(charGetBody(ch), obj)) {
      objSetWearer(obj, NULL);
!     //*******************************
      // remove all of the item affects
      //*******************************
      return TRUE;
***************
*** 481,487 ****
      count += count_objs(looker, equipment, at, NOTHING,
  			(IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       *found_type = FOUND_OBJ;
        OBJ_DATA *obj = find_obj(looker, equipment, at_count, at, NOTHING, 
  			       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
        deleteList(equipment);
--- 481,488 ----
      count += count_objs(looker, equipment, at, NOTHING,
  			(IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       if(found_type)
! 	*found_type = FOUND_OBJ;
        OBJ_DATA *obj = find_obj(looker, equipment, at_count, at, NOTHING, 
  			       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
        deleteList(equipment);
***************
*** 496,502 ****
    // FINISH ME
    //***********
  
!   *found_type = FOUND_NONE;
    return NULL;
  }
  
--- 497,504 ----
    // FINISH ME
    //***********
  
!   if(found_type)
!     *found_type = FOUND_NONE;
    return NULL;
  }
  
***************
*** 517,523 ****
      count = count_chars(looker, objGetUsers(on), at, NOBODY,
  			(IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       *found_type = FOUND_CHAR;
        return find_char(looker, objGetUsers(on), at_count, at, NOBODY,
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
--- 519,526 ----
      count = count_chars(looker, objGetUsers(on), at, NOBODY,
  			(IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       if(found_type)
! 	*found_type = FOUND_CHAR;
        return find_char(looker, objGetUsers(on), at_count, at, NOBODY,
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
***************
*** 529,542 ****
    if(IS_SET(find_types, FIND_TYPE_EDESC)) {
      count = (objGetEdesc(on, at) != NULL);
      if(count && at_count == 1) {
!       *found_type = FOUND_EDESC;
        return getEdesc(objGetEdescs(on), at);
      }
      else
        at_count--;
    }
! 
!   *found_type = FOUND_NONE;
    return NULL;
  }
  
--- 532,547 ----
    if(IS_SET(find_types, FIND_TYPE_EDESC)) {
      count = (objGetEdesc(on, at) != NULL);
      if(count && at_count == 1) {
!       if(found_type)
! 	*found_type = FOUND_EDESC;
        return getEdesc(objGetEdescs(on), at);
      }
      else
        at_count--;
    }
!  
!   if(found_type)
!     *found_type = FOUND_NONE;
    return NULL;
  }
  
***************
*** 551,557 ****
  		  bitvector_t find_types,
  		  bitvector_t find_scope,
  		  int *found_type) {		  
!   *found_type = FOUND_NONE;
  
    // see if we're looking on anything
    if(on && *on && on_count > 0) {
--- 556,563 ----
  		  bitvector_t find_types,
  		  bitvector_t find_scope,
  		  int *found_type) {		  
!   if(found_type)
!     *found_type = FOUND_NONE;
  
    // see if we're looking on anything
    if(on && *on && on_count > 0) {
***************
*** 567,573 ****
      int count = count_objs(looker, objGetContents(in), at, NOTHING,
  			    (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       *found_type = FOUND_OBJ;
        return find_obj(looker, objGetContents(in), at_count, at, NOTHING,
  		      (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
--- 573,580 ----
      int count = count_objs(looker, objGetContents(in), at, NOTHING,
  			    (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       if(found_type)
! 	*found_type = FOUND_OBJ;
        return find_obj(looker, objGetContents(in), at_count, at, NOTHING,
  		      (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
***************
*** 579,585 ****
  
  LIST *find_all(CHAR_DATA *looker, const char *at, bitvector_t find_types,
  	       bitvector_t find_scope, int *found_type) {
!   *found_type = FOUND_LIST;
  
    /************************************************************/
    /*                        FIND ALL OBJS                     */
--- 586,593 ----
  
  LIST *find_all(CHAR_DATA *looker, const char *at, bitvector_t find_types,
  	       bitvector_t find_scope, int *found_type) {
!   if(found_type)
!     *found_type = FOUND_LIST;
  
    /************************************************************/
    /*                        FIND ALL OBJS                     */
***************
*** 638,644 ****
      // if we didn't find anything, return NULL
      if(listSize(obj_list) < 1) {
        deleteList(obj_list);
!       *found_type = FOUND_NONE;
        return NULL;
      }
      else
--- 646,653 ----
      // if we didn't find anything, return NULL
      if(listSize(obj_list) < 1) {
        deleteList(obj_list);
!       if(found_type)
! 	*found_type = FOUND_NONE;
        return NULL;
      }
      else
***************
*** 650,656 ****
    /*                        FIND ALL CHARS                    */
    /************************************************************/
    else if(find_types == FIND_TYPE_CHAR) {
!     *found_type = FOUND_NONE;
      return NULL;
    }
    
--- 659,666 ----
    /*                        FIND ALL CHARS                    */
    /************************************************************/
    else if(find_types == FIND_TYPE_CHAR) {
!     if(found_type)
!       *found_type = FOUND_NONE;
      return NULL;
    }
    
***************
*** 659,665 ****
    /*                       FIND ALL EDESCS                    */
    /************************************************************/
    else {
!     *found_type = FOUND_NONE;
      return NULL;
    }
  }
--- 669,676 ----
    /*                       FIND ALL EDESCS                    */
    /************************************************************/
    else {
!     if(found_type)
!       *found_type = FOUND_NONE;
      return NULL;
    }
  }
***************
*** 682,688 ****
       at_count >= 1 && !strcasecmp(at, "self")) {
      at_count--;
      if(at_count == 0) {
!       *found_type = FOUND_CHAR;
        return looker;
      }
    }
--- 693,700 ----
       at_count >= 1 && !strcasecmp(at, "self")) {
      at_count--;
      if(at_count == 0) {
!       if(found_type)
! 	*found_type = FOUND_CHAR;
        return looker;
      }
    }
***************
*** 693,699 ****
      count = count_objs(looker, charGetInventory(looker), at, NOTHING, 
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       *found_type = FOUND_OBJ;
        return find_obj(looker, charGetInventory(looker), at_count, at, NOTHING,
  		      (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
--- 705,712 ----
      count = count_objs(looker, charGetInventory(looker), at, NOTHING, 
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       if(found_type)
! 	*found_type = FOUND_OBJ;
        return find_obj(looker, charGetInventory(looker), at_count, at, NOTHING,
  		      (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
***************
*** 708,714 ****
      count = count_objs(looker, equipment, at, NOTHING, 
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       *found_type = FOUND_OBJ;
        OBJ_DATA *obj = find_obj(looker, equipment, at_count, at, NOTHING, 
  			       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
        deleteList(equipment);
--- 721,728 ----
      count = count_objs(looker, equipment, at, NOTHING, 
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       if(found_type)
! 	*found_type = FOUND_OBJ;
        OBJ_DATA *obj = find_obj(looker, equipment, at_count, at, NOTHING, 
  			       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
        deleteList(equipment);
***************
*** 730,736 ****
      count = count_objs(looker, roomGetContents(charGetRoom(looker)), at, 
  		       NOTHING, (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       *found_type = FOUND_OBJ;
        return find_obj(looker, roomGetContents(charGetRoom(looker)), at_count,
  		      at, NOTHING, (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
--- 744,751 ----
      count = count_objs(looker, roomGetContents(charGetRoom(looker)), at, 
  		       NOTHING, (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
!       if(found_type)
! 	*found_type = FOUND_OBJ;
        return find_obj(looker, roomGetContents(charGetRoom(looker)), at_count,
  		      at, NOTHING, (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
***************
*** 744,753 ****
      count = count_chars(looker, roomGetCharacters(charGetRoom(looker)), at,
  		       NOBODY, (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
  	*found_type = FOUND_CHAR;
! 	return find_char(looker, roomGetCharacters(charGetRoom(looker)), 
! 			 at_count, at, NOBODY,
! 			 (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
      else
  	at_count -= count;
--- 759,769 ----
      count = count_chars(looker, roomGetCharacters(charGetRoom(looker)), at,
  		       NOBODY, (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
+       if(found_type)
  	*found_type = FOUND_CHAR;
!       return find_char(looker, roomGetCharacters(charGetRoom(looker)), 
! 		       at_count, at, NOBODY,
! 		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
      else
  	at_count -= count;
***************
*** 778,784 ****
  	  can_see_exit(looker, exit))) {
  	at_count--;
  	if(at_count == 0) {
! 	  *found_type = FOUND_EXIT;
  	  return exit;
  	}
      }
--- 794,801 ----
  	  can_see_exit(looker, exit))) {
  	at_count--;
  	if(at_count == 0) {
! 	  if(found_type)
! 	    *found_type = FOUND_EXIT;
  	  return exit;
  	}
      }
***************
*** 802,808 ****
  	  can_see_exit(looker, exit))) {
  	at_count--;
  	if(at_count == 0) {
! 	  *found_type = FOUND_EXIT;
  	  return exit;
  	}
        }
--- 819,826 ----
  	  can_see_exit(looker, exit))) {
  	at_count--;
  	if(at_count == 0) {
! 	  if(found_type)
! 	    *found_type = FOUND_EXIT;
  	  return exit;
  	}
        }
***************
*** 822,828 ****
  	  can_see_exit(looker, exit))) {
  	at_count--;
  	if(at_count == 0) {
! 	  *found_type = FOUND_EXIT;
  	  // don't return it yet... we need to clean up our mess
  	  break;
  	}
--- 840,847 ----
  	  can_see_exit(looker, exit))) {
  	at_count--;
  	if(at_count == 0) {
! 	  if(found_type)
! 	    *found_type = FOUND_EXIT;
  	  // don't return it yet... we need to clean up our mess
  	  break;
  	}
***************
*** 851,858 ****
       IS_SET(find_types, FIND_TYPE_EDESC)) {
      count = (roomGetEdesc(charGetRoom(looker), at) != NULL);
      if(count && at_count == 1) {
  	*found_type = FOUND_EDESC;
! 	return getEdesc(roomGetEdescs(charGetRoom(looker)), at);
      }
      else
  	at_count--;
--- 870,878 ----
       IS_SET(find_types, FIND_TYPE_EDESC)) {
      count = (roomGetEdesc(charGetRoom(looker), at) != NULL);
      if(count && at_count == 1) {
+       if(found_type)
  	*found_type = FOUND_EDESC;
!       return getEdesc(roomGetEdescs(charGetRoom(looker)), at);
      }
      else
  	at_count--;
***************
*** 868,876 ****
      count = count_objs(looker, object_list, at, NOTHING, 
  			 (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
  	*found_type = FOUND_OBJ;
! 	return find_obj(looker, object_list, at_count, at, NOTHING, 
! 			(IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
      else
  	at_count -= count;
--- 888,897 ----
      count = count_objs(looker, object_list, at, NOTHING, 
  			 (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
+       if(found_type)
  	*found_type = FOUND_OBJ;
!       return find_obj(looker, object_list, at_count, at, NOTHING, 
! 		      (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
      else
  	at_count -= count;
***************
*** 882,897 ****
      count = count_chars(looker, mobile_list, at, NOBODY, 
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
  	*found_type = FOUND_CHAR;
! 	return find_char(looker, mobile_list, at_count, at, NOBODY,
! 			 (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
      else
  	at_count -= count;
    }
  
    // we didn't find anything!
!   *found_type = FOUND_NONE;
    return NULL;
  }
  
--- 903,920 ----
      count = count_chars(looker, mobile_list, at, NOBODY, 
  		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      if(count >= at_count) {
+       if(found_type)
  	*found_type = FOUND_CHAR;
!       return find_char(looker, mobile_list, at_count, at, NOBODY,
! 		       (IS_SET(find_scope, FIND_SCOPE_VISIBLE)));
      }
      else
  	at_count -= count;
    }
  
    // we didn't find anything!
!   if(found_type)
!     *found_type = FOUND_NONE;
    return NULL;
  }
  
***************
*** 964,970 ****
    get_count(in, in, &in_count);
    get_count(on, on, &on_count);
  
!   *found_type = FOUND_NONE;
  
  
    // are we trying to find all of something?
--- 987,994 ----
    get_count(in, in, &in_count);
    get_count(on, on, &on_count);
  
!   if(found_type)
!     *found_type = FOUND_NONE;
  
  
    // are we trying to find all of something?
***************
*** 998,1010 ****
  	return NULL;
        // return what we found
        else {
! 	*found_type = FOUND_IN_OBJ;
  	return tgt;
        }
      }
      // we're just not looking for anything
      else {
!       *found_type = FOUND_NONE;
        return NULL;
      }
    }
--- 1022,1036 ----
  	return NULL;
        // return what we found
        else {
! 	if(found_type)
! 	  *found_type = FOUND_IN_OBJ;
  	return tgt;
        }
      }
      // we're just not looking for anything
      else {
!       if(found_type)
! 	*found_type = FOUND_NONE;
        return NULL;
      }
    }
diff -crN nakedmudv1.0/src/hashtable.c nakedmudv1.4/src/hashtable.c
*** nakedmudv1.0/src/hashtable.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/hashtable.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 8,14 ****
  //*****************************************************************************
  
  #include <stdlib.h>
! #include <strings.h>
  #include "list.h"
  #include "hashtable.h"
  
--- 8,14 ----
  //*****************************************************************************
  
  #include <stdlib.h>
! #include <string.h>
  #include "list.h"
  #include "hashtable.h"
  
diff -crN nakedmudv1.0/src/help.c nakedmudv1.4/src/help.c
*** nakedmudv1.0/src/help.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/help.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,21 ****
--- 16,22 ----
  /* include main header file */
  #include "mud.h"
  #include "character.h"
+ #include "help.h"
  
  HELP_DATA   *   help_list = NULL; /* the linked list of help files     */
  char        *   greeting;         /* the welcome greeting              */
***************
*** 123,133 ****
      new_help->text       =  strdup(s);
      new_help->load_time  =  time(NULL);
      add_help(new_help);
- 
-     if (compares("GREETING", new_help->keyword))
-       greeting = new_help->text;
-     else if (compares("MOTD", new_help->keyword))
-       motd = new_help->text;
    }
    closedir(directory);
  }
--- 124,129 ----
diff -crN nakedmudv1.0/src/inform.c nakedmudv1.4/src/inform.c
*** nakedmudv1.0/src/inform.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/inform.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 22,32 ****
  #include "handler.h"
  #include "socket.h"
  #include "inform.h"
  
  
  // optional module headers
  #ifdef MODULE_TIME
! #include "modules/time/mudtime.h"
  #endif
  
  
--- 22,33 ----
  #include "handler.h"
  #include "socket.h"
  #include "inform.h"
+ #include "log.h"
  
  
  // optional module headers
  #ifdef MODULE_TIME
! #include "time/mudtime.h"
  #endif
  
  
***************
*** 79,85 ****
      // don't show ourself
      if(i == ch && !include_self) continue;
      // check for invis and hidden ...
!     if(!(invis_ok || can_see_person(ch, i)))
        continue;
      // make sure they're not on furniture
      if(charGetFurniture(i))
--- 80,86 ----
      // don't show ourself
      if(i == ch && !include_self) continue;
      // check for invis and hidden ...
!     if(!(invis_ok || can_see_char(ch, i)))
        continue;
      // make sure they're not on furniture
      if(charGetFurniture(i))
***************
*** 315,320 ****
--- 316,410 ----
  }
  
  
+ 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
+   // don't send the mesage to us
+   if(!charIsNPC(ch))
+     try_log(charGetName(ch), txt);
+ }
+ 
+ 
+ void send_to_char(CHAR_DATA *ch, const char *format, ...) {
+   if(charGetSocket(ch) && format && *format) {
+     static char buf[MAX_BUFFER];
+     va_list args;
+     va_start(args, format);
+     vsprintf(buf, format, args);
+     va_end(args);
+     text_to_char(ch, buf);
+     return;
+   }
+ }
+ 
+ 
+ void send_around_char(CHAR_DATA *ch, bool hide_nosee, const char *format, ...) {
+   static char buf[MAX_BUFFER];
+   va_list args;
+   va_start(args, format);
+   vsprintf(buf, format, args);
+   va_end(args);
+ 
+   LIST_ITERATOR *room_i = newListIterator(roomGetCharacters(charGetRoom(ch)));
+   CHAR_DATA       *vict = NULL;
+ 
+   ITERATE_LIST(vict, room_i) {
+     if(ch == vict)
+       continue;
+     if(hide_nosee && !can_see_char(vict, ch))
+       continue;
+     text_to_char(vict, buf);
+   }
+   deleteListIterator(room_i);
+   return;
+ }
+ 
+ 
+ void send_to_level(int level, const char *format, ...) {
+   static char buf[MAX_BUFFER];
+   va_list args;
+   va_start(args, format);
+   vsprintf(buf, format, args);
+   va_end(args);
+ 
+   LIST_ITERATOR *ch_i = newListIterator(mobile_list);
+   CHAR_DATA       *ch = NULL;
+ 
+   ITERATE_LIST(ch, ch_i) {
+     if(!charGetSocket(ch) || charGetLevel(ch) < level)
+       continue;
+     text_to_char(ch, buf);
+   }
+   deleteListIterator(ch_i);
+ }
+ 
+ 
+ void send_to_list(LIST *list, const char *format, ...) {
+   if(format && *format) {
+     // form the message
+     static char buf[MAX_BUFFER];
+     va_list args;
+     va_start(args, format);
+     vsprintf(buf, format, args);
+     va_end(args);
+ 
+     // send it out to everyone
+     LIST_ITERATOR *list_i = newListIterator(list);
+     CHAR_DATA *ch = NULL;
+     ITERATE_LIST(ch, list_i)
+       text_to_char(ch, buf);
+     deleteListIterator(list_i);
+   }
+ };
+ 
+ 
+ 
+ 
  //*****************************************************************************
  //
  // commands included in inform.c
***************
*** 460,466 ****
  // show a list of all commands available to the character
  //
  COMMAND(cmd_commands) {
!   show_commands(ch);
  }
  
  
--- 550,556 ----
  // show a list of all commands available to the character
  //
  COMMAND(cmd_commands) {
!   show_commands(ch, LEVEL_PLAYER, charGetLevel(ch));
  }
  
  
***************
*** 534,540 ****
  }
  
  
- 
  //*****************************************************************************
  //
  // below this line are all of the subfunctions related to the message() 
--- 624,629 ----
***************
*** 583,638 ****
        switch(str[i]) {
        case 'n':
  	if(!ch) break;
! 	sprintf(buf+j, (can_see_person(to, ch)?charGetName(ch):SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'N':
  	if(!vict) break;
! 	sprintf(buf+j, (can_see_person(to, vict)?charGetName(vict):SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'm':
  	if(!ch) break;
! 	sprintf(buf+j, (can_see_person(to, ch) ? HIMHER(ch) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'M':
  	if(!vict) break;
! 	sprintf(buf+j, (can_see_person(to, vict) ? HIMHER(vict) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 's':
  	if(!ch) break;
! 	sprintf(buf+j, (can_see_person(to, ch) ? HISHERS(ch) : SOMEONE"s"));
  	while(buf[j] != '\0') j++;
  	break;
        case 'S':
  	if(!vict) break;
! 	sprintf(buf+j, (can_see_person(to, vict) ? HISHERS(vict) : SOMEONE"s"));
  	while(buf[j] != '\0') j++;
  	break;
        case 'e':
  	if(!ch) break;
! 	sprintf(buf+j, (can_see_person(to, ch) ? HESHE(ch) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'E':
  	if(!vict) break;
! 	sprintf(buf+j, (can_see_person(to, vict) ? HESHE(vict) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'o':
  	if(!obj) break;
! 	sprintf(buf+j, (can_see_obj(to, obj) ? objGetName(obj) : SOMETHING));
  	while(buf[j] != '\0') j++;
  	break;
        case 'O':
  	if(!vobj) break;
! 	sprintf(buf+j, (can_see_obj(to, vobj) ? objGetName(vobj) : SOMETHING));
  	while(buf[j] != '\0') j++;
  	break;
        case 'a':
        case 'A':
        case '$':
  	buf[j] = '$';
  	j++;
--- 672,735 ----
        switch(str[i]) {
        case 'n':
  	if(!ch) break;
! 	sprintf(buf+j, see_char_as(to, ch));
  	while(buf[j] != '\0') j++;
  	break;
        case 'N':
  	if(!vict) break;
! 	sprintf(buf+j, see_char_as(to, vict));
  	while(buf[j] != '\0') j++;
  	break;
        case 'm':
  	if(!ch) break;
! 	sprintf(buf+j, (can_see_char(to, ch) ? HIMHER(ch) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'M':
  	if(!vict) break;
! 	sprintf(buf+j, (can_see_char(to, vict) ? HIMHER(vict) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 's':
  	if(!ch) break;
! 	sprintf(buf+j, (can_see_char(to, ch) ? HISHERS(ch) :SOMEONE"'s"));
  	while(buf[j] != '\0') j++;
  	break;
        case 'S':
  	if(!vict) break;
! 	sprintf(buf+j, (can_see_char(to, vict) ? HISHERS(vict) :SOMEONE"'s"));
  	while(buf[j] != '\0') j++;
  	break;
        case 'e':
  	if(!ch) break;
! 	sprintf(buf+j, (can_see_char(to, ch) ? HESHE(ch) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'E':
  	if(!vict) break;
! 	sprintf(buf+j, (can_see_char(to, vict) ? HESHE(vict) : SOMEONE));
  	while(buf[j] != '\0') j++;
  	break;
        case 'o':
  	if(!obj) break;
! 	sprintf(buf+j, see_obj_as(to, obj));
  	while(buf[j] != '\0') j++;
  	break;
        case 'O':
  	if(!vobj) break;
! 	sprintf(buf+j, see_obj_as(to, vobj));
  	while(buf[j] != '\0') j++;
  	break;
        case 'a':
+ 	if(!obj) break;
+ 	sprintf(buf+j, AN(see_obj_as(to, obj)));
+ 	while(buf[j] != '\0') j++;
+ 	break;
        case 'A':
+ 	if(!vobj) break;
+ 	sprintf(buf+j, AN(see_obj_as(to, vobj)));
+ 	while(buf[j] != '\0') j++;
+ 	break;
        case '$':
  	buf[j] = '$';
  	j++;
***************
*** 645,681 ****
  
    //  buf[0] = toupper(buf[0]);
    sprintf(buf+j, "\r\n");
!   send_to_char(to, buf);
  }
  
  
  void message(CHAR_DATA *ch,  CHAR_DATA *vict,
  	     OBJ_DATA  *obj, OBJ_DATA  *vobj,
  	     int hide_nosee, bitvector_t range, 
! 	     const char *format, ...) {
!   static char buf[MAX_BUFFER];
!   va_list args;
! 
!   if(!format || !*format)
      return;
  
-   va_start(args, format);
-   vsprintf(buf, format, args);
-   va_end(args);
- 
    // what's our scope?
    if(IS_SET(range, TO_VICT) &&
       (!hide_nosee ||
        // make sure the vict can the character, or the
        // object if there is no character
!       ((!ch || can_see_person(vict, ch)) &&
         (ch  || (!obj || can_see_obj(vict, obj))))))
!     send_message(vict, buf, ch, vict, obj, vobj);
    // characters can always see themselves. No need to do checks here
    else if(IS_SET(range, TO_CHAR))
!     send_message(ch, buf, ch, vict, obj, vobj);
    else {
- 
      LIST *recipients = NULL;
      // check if the scope of this message is everyone in the world
      if(IS_SET(range, TO_WORLD))
--- 742,770 ----
  
    //  buf[0] = toupper(buf[0]);
    sprintf(buf+j, "\r\n");
!   text_to_char(to, buf);
  }
  
  
  void message(CHAR_DATA *ch,  CHAR_DATA *vict,
  	     OBJ_DATA  *obj, OBJ_DATA  *vobj,
  	     int hide_nosee, bitvector_t range, 
! 	     const char *mssg) {
!   if(!mssg || !*mssg)
      return;
  
    // what's our scope?
    if(IS_SET(range, TO_VICT) &&
       (!hide_nosee ||
        // make sure the vict can the character, or the
        // object if there is no character
!       ((!ch || can_see_char(vict, ch)) &&
         (ch  || (!obj || can_see_obj(vict, obj))))))
!     send_message(vict, mssg, ch, vict, obj, vobj);
    // characters can always see themselves. No need to do checks here
    else if(IS_SET(range, TO_CHAR))
!     send_message(ch, mssg, ch, vict, obj, vobj);
    else {
      LIST *recipients = NULL;
      // check if the scope of this message is everyone in the world
      if(IS_SET(range, TO_WORLD))
***************
*** 696,704 ****
  	 (!hide_nosee ||
  	  // make sure the vict can see the character, or the
  	  // object if there is no character
! 	  ((!ch || can_see_person(rec, ch)) &&
  	   (ch  || (!obj || can_see_obj(rec, obj))))))
!       send_message(rec, buf, ch, vict, obj, vobj);
      }
      deleteListIterator(rec_i);
    }
--- 785,793 ----
  	 (!hide_nosee ||
  	  // make sure the vict can see the character, or the
  	  // object if there is no character
! 	  ((!ch || can_see_char(rec, ch)) &&
  	   (ch  || (!obj || can_see_obj(rec, obj))))))
!       send_message(rec, mssg, ch, vict, obj, vobj);
      }
      deleteListIterator(rec_i);
    }
diff -crN nakedmudv1.0/src/inform.h nakedmudv1.4/src/inform.h
*** nakedmudv1.0/src/inform.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/inform.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 44,68 ****
  void message(CHAR_DATA *ch,  CHAR_DATA *vict,
  	     OBJ_DATA  *obj, OBJ_DATA  *vobj,
  	     int hide_nosee, bitvector_t range, 
! 	     const char *format, ...);
  
  
  //
  // send a message to everyone outdoors
  //
! void  send_outdoors(const char *format, ...);
  
  
  //
  // send a message to a list of characters
  //
! void  send_to_list (LIST *list, const char *format, ...);
  
  
  //
  // send a message to a specific character
  //
! void  send_to_char (CHAR_DATA *ch, const char *format, ...);
  
  
  //
--- 44,87 ----
  void message(CHAR_DATA *ch,  CHAR_DATA *vict,
  	     OBJ_DATA  *obj, OBJ_DATA  *vobj,
  	     int hide_nosee, bitvector_t range, 
! 	     const char *mssg);
  
  
  //
  // send a message to everyone outdoors
  //
! void  send_outdoors(const char *format, ...)  
! __attribute__ ((format (printf, 1, 2)));
  
  
  //
  // send a message to a list of characters
  //
! void  send_to_list (LIST *list, const char *format, ...) 
! __attribute__ ((format (printf, 2, 3)));
  
  
  //
  // send a message to a specific character
  //
! void  send_to_char (CHAR_DATA *ch, const char *format, ...) 
! __attribute__ ((format (printf, 2, 3)));
! 
! 
! //
! // send a message to everyone at or above the specified level
! //
! void send_to_level(int level, const char *format, ...) 
! __attribute__ ((format (printf, 2, 3)));
! 
! 
! //
! // send a message to everyone in the same room as the character,
! // but not the character himself. If hide_nosee is TRUE, then the message
! // is not sent to people who cannot see the character.
! //
! void send_around_char(CHAR_DATA *ch, bool hide_nosee, const char *format, ...) 
! __attribute__ ((format (printf, 3, 4)));
  
  
  //
***************
*** 123,126 ****
--- 142,146 ----
  //
  void show_body(CHAR_DATA *ch, BODY_DATA *body);
  
+ 
  #endif // __INFORM_H
diff -crN nakedmudv1.0/src/interpret.c nakedmudv1.4/src/interpret.c
*** nakedmudv1.0/src/interpret.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/interpret.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,41 ****
  
  // optional modules
  #ifdef MODULE_FACULTY
! #include "modules/faculty/faculty.h"
  #endif
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  
  // our command table list
  LIST   **cmd_table = NULL;
  
! struct cmd_data {
    char      * cmd_name;
    char      * sort_by;
!   void     (* cmd_funct)(CHAR_DATA *ch, char *arg, int subcmd); // COMMAND()
    int        subcmd;
    int        min_pos;
    int        max_pos;
    int        level;
    bool       interrupts; // does it interrupt actions?
! };
  
  
  void init_commands() {
--- 16,45 ----
  
  // 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
  
  
  // our command table list
  LIST   **cmd_table = NULL;
  
! typedef struct cmd_data {
    char      * cmd_name;
    char      * sort_by;
!   CMD_PTR(cmd_funct);
    int        subcmd;
    int        min_pos;
    int        max_pos;
    int        level;
+   bool       mob_ok;     // can NPCs use this command?
    bool       interrupts; // does it interrupt actions?
! } CMD_DATA;
  
  
  void init_commands() {
***************
*** 50,239 ****
    // associated with your module.
    //***********************************************************************
    add_cmd("north", "n", cmd_move,     DIR_NORTH,    POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("east",  "e", cmd_move,     DIR_EAST,     POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("south", "s", cmd_move,     DIR_SOUTH,    POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("west",  "w", cmd_move,     DIR_WEST,     POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("up",    "u", cmd_move,     DIR_UP,       POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("down",  "d", cmd_move,     DIR_DOWN,     POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("northeast", "na", cmd_move,DIR_NORTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("southeast", "sa",  cmd_move,DIR_SOUTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("southwest", "sb", cmd_move,DIR_SOUTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("northwest", "nb", cmd_move,DIR_NORTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("ne",        "ne", cmd_move,DIR_NORTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("se",        "se", cmd_move,DIR_SOUTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("sw",        "sw", cmd_move,DIR_SOUTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("nw",        "nw", cmd_move,DIR_NORTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
  
    // A
-   add_cmd("alias",      NULL, cmd_alias,    0, POS_UNCONCIOUS, POS_FLYING,
- 	  LEVEL_PLAYER, TRUE );
    add_cmd("approach",   NULL, cmd_greet,    0, POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("ask",        NULL, cmd_ask,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
  
    // B
    add_cmd("back",       NULL, cmd_back,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("buildwalk",  NULL, cmd_tog_prf,  SUBCMD_BUILDWALK, 
! 	  POS_UNCONCIOUS, POS_FLYING, LEVEL_BUILDER, FALSE);
  
    // C
    add_cmd("chat",       NULL, cmd_chat,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("clear",      NULL, cmd_clear,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("close",      NULL, cmd_close,    0, POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("commands",   NULL, cmd_commands, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("compress",   NULL, cmd_compress, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("copyover",   NULL, cmd_copyover, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN,   TRUE);
  
    // D
    add_cmd("delay",      NULL, cmd_delay,    0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER,  FALSE);
!   
    add_cmd("dig",        NULL, cmd_dig,      0, POS_STANDING, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
    add_cmd("dlist",      NULL, cmd_dlist,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE );
    add_cmd("drop",       NULL, cmd_drop,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
  
    // E
    add_cmd("enter",      NULL, cmd_enter,    0, POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("emote",      NULL, cmd_emote,    0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("equipment",  NULL, cmd_equipment,0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
  
    // F
    add_cmd("fill",       NULL, cmd_fill,     0, POS_STANDING, POS_FLYING,
! 	  LEVEL_BUILDER, TRUE );
  
    // G
    add_cmd("gemote",     NULL, cmd_gemote,   0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("give",       NULL, cmd_give,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("gossip",     NULL, cmd_chat,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("greet",      NULL, cmd_greet,    0, POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("get",        NULL, cmd_get,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("goto",       NULL, cmd_goto,     0, POS_STANDING, POS_FLYING,
! 	  LEVEL_BUILDER, TRUE );
  
    // H
    add_cmd("help",       NULL, cmd_help,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
  
    // I
    add_cmd("inventory",  NULL, cmd_inventory,0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
  
    // L
    add_cmd("look",       "l",  cmd_look,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("lock",       NULL,  cmd_lock,    0, POS_STANDING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE);
    add_cmd("land",       NULL, cmd_stand,    0, POS_FLYING,   POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("load",       NULL, cmd_load,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
    add_cmd("linkdead",   NULL, cmd_linkdead, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN, FALSE);
  
    // M
    add_cmd("mlist",      NULL, cmd_mlist,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
    add_cmd("more",       NULL, cmd_more,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
  
    // O
    add_cmd("olist",      NULL, cmd_olist,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
    add_cmd("open",       NULL, cmd_open,     0, POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
  
    // P
    add_cmd("put",        NULL, cmd_put,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER,  TRUE );
    add_cmd("purge",      NULL, cmd_purge,    0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
    
    // Q
    add_cmd("quit",       NULL, cmd_quit,     0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
  
    // R
    add_cmd("remove",     NULL, cmd_remove,   0, POS_SITTING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("rlist",      NULL, cmd_rlist,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
  
    // S
    add_cmd("say",        NULL, cmd_say,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("save",       NULL, cmd_save,     0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
! #ifdef MODULE_SCRIPTS
!   add_cmd("sclist",     NULL, cmd_sclist,   0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
! #endif
    add_cmd("shutdown",   NULL, cmd_shutdown, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN, TRUE );
    add_cmd("sit",        NULL, cmd_sit,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("sleep",      NULL, cmd_sleep,    0, POS_SITTING,  POS_STANDING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("stand",      NULL, cmd_stand,    0, POS_SITTING,  POS_STANDING,
! 	  LEVEL_PLAYER, TRUE );
  
    // T
    add_cmd("take",       NULL, cmd_get,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("tell",       NULL, cmd_tell,     0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
  
    // U
    add_cmd("unlock",       NULL,  cmd_unlock,    0, POS_STANDING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE);
  
    // W
    add_cmd("wake",       NULL, cmd_wake,     0, POS_SLEEPING,  POS_SLEEPING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("wear",       NULL, cmd_wear,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE );
    add_cmd("who",        NULL, cmd_who,      0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
    add_cmd("worn",       NULL, cmd_equipment,0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, FALSE);
  
    // Z
    add_cmd("zlist",      NULL, cmd_zlist,    0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_BUILDER, TRUE);
    add_cmd("zreset",     NULL, cmd_zreset,   0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE);
  }
  
  
--- 54,251 ----
    // associated with your module.
    //***********************************************************************
    add_cmd("north", "n", cmd_move,     DIR_NORTH,    POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("east",  "e", cmd_move,     DIR_EAST,     POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("south", "s", cmd_move,     DIR_SOUTH,    POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("west",  "w", cmd_move,     DIR_WEST,     POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("up",    "u", cmd_move,     DIR_UP,       POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("down",  "d", cmd_move,     DIR_DOWN,     POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("northeast", "na", cmd_move,DIR_NORTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("southeast", "sa",  cmd_move,DIR_SOUTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("southwest", "sb", cmd_move,DIR_SOUTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("northwest", "nb", cmd_move,DIR_NORTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("ne",        "ne", cmd_move,DIR_NORTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("se",        "se", cmd_move,DIR_SOUTHEAST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("sw",        "sw", cmd_move,DIR_SOUTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("nw",        "nw", cmd_move,DIR_NORTHWEST,POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
  
    // A
    add_cmd("approach",   NULL, cmd_greet,    0, POS_STANDING, POS_FLYING,
! 	  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,  SUBCMD_BUILDWALK, 
! 	  POS_UNCONCIOUS, POS_FLYING, LEVEL_BUILDER, FALSE, FALSE);
  
    // C
    add_cmd("chat",       NULL, cmd_chat,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("clear",      NULL, cmd_clear,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("close",      NULL, cmd_close,    0, POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("commands",   NULL, cmd_commands, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("compress",   NULL, cmd_compress, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE, FALSE);
    add_cmd("copyover",   NULL, cmd_copyover, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN,  FALSE, TRUE);
  
    // D
    add_cmd("delay",      NULL, cmd_delay,    0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE,  FALSE);
    add_cmd("dig",        NULL, cmd_dig,      0, POS_STANDING, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, FALSE);
    add_cmd("dlist",      NULL, cmd_dlist,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, FALSE);
    add_cmd("drop",       NULL, cmd_drop,     0, POS_SITTING,  POS_FLYING,
! 	  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,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("equipment",  NULL, cmd_equipment,0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
  
    // F
    add_cmd("fill",       NULL, cmd_fill,     0, POS_STANDING, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, TRUE );
  
    // G
    add_cmd("gemote",     NULL, cmd_gemote,   0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("give",       NULL, cmd_give,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("gossip",     NULL, cmd_chat,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
!   add_cmd("\"",         NULL, cmd_chat,     0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("greet",      NULL, cmd_greet,    0, POS_STANDING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("get",        NULL, cmd_get,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    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);
  
    // L
    add_cmd("look",       "l",  cmd_look,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("lock",       NULL,  cmd_lock,    0, POS_STANDING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE);
    add_cmd("land",       NULL, cmd_stand,    0, POS_FLYING,   POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("load",       NULL, cmd_load,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, FALSE);
    add_cmd("linkdead",   NULL, cmd_linkdead, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN, FALSE, FALSE);
  
    // M
    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,
! 	  LEVEL_PLAYER, TRUE, FALSE);
  
    // O
    add_cmd("olist",      NULL, cmd_olist,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, FALSE);
    add_cmd("open",       NULL, cmd_open,     0, POS_STANDING, POS_FLYING,
! 	  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);
    
    // Q
    add_cmd("quit",       NULL, cmd_quit,     0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE, TRUE );
  
    // R
    add_cmd("remove",     NULL, cmd_remove,   0, POS_SITTING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("rlist",      NULL, cmd_rlist,    0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, FALSE);
  
    // S
    add_cmd("say",        NULL, cmd_say,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
!   add_cmd("'",          NULL, cmd_say,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("save",       NULL, cmd_save,     0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER, FALSE, FALSE);
    add_cmd("shutdown",   NULL, cmd_shutdown, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN, FALSE, TRUE );
    add_cmd("sit",        NULL, cmd_sit,      0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("sleep",      NULL, cmd_sleep,    0, POS_SITTING,  POS_STANDING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
    add_cmd("stand",      NULL, cmd_stand,    0, POS_SITTING,  POS_STANDING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
! #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,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("tell",       NULL, cmd_tell,     0, POS_SLEEPING, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
  
    // U
    add_cmd("unlock",       NULL,  cmd_unlock,    0, POS_STANDING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE);
  
    // W
    add_cmd("wake",       NULL, cmd_wake,     0, POS_SLEEPING,  POS_SLEEPING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("wear",       NULL, cmd_wear,     0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, TRUE );
    add_cmd("who",        NULL, cmd_who,      0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
!   add_cmd("wizhelp",    NULL, cmd_wizhelp,  0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, FALSE);
    add_cmd("worn",       NULL, cmd_equipment,0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_PLAYER, TRUE, FALSE);
  
    // Z
    add_cmd("zlist",      NULL, cmd_zlist,    0, POS_SITTING,  POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, TRUE);
    add_cmd("zreset",     NULL, cmd_zreset,   0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_BUILDER, FALSE, FALSE);
  }
  
  
***************
*** 244,289 ****
  }
  
  // compare two command by their sort_by variable
! int cmdsortbycmp(const struct cmd_data *cmd1, const struct cmd_data *cmd2) {
    return strcasecmp(cmd1->sort_by, cmd2->sort_by);
  }
  
  // compare two commands
! int cmdcmp(const struct cmd_data *cmd1, const struct cmd_data *cmd2) {
    return strcasecmp(cmd1->cmd_name, cmd2->cmd_name);
  }
  
  // check if the cmd matches the command's cmd_name up to the length of cmd
! int is_cmd_abbrev(const char *cmd, const struct cmd_data *entry) {
    return strncasecmp(cmd, entry->cmd_name, strlen(cmd));
  }
  
  // check if the string matches the command's cmd_name
! int is_cmd(const char *cmd, const struct cmd_data *entry) {
    return strcasecmp(cmd, entry->cmd_name);
  }
  
  // find a command
! struct cmd_data *find_cmd(const char *cmd, bool abbrev_ok) {
    if(abbrev_ok)
      return listGetWith(cmd_table[cmdbucket(cmd)], cmd, is_cmd_abbrev);
    else
      return listGetWith(cmd_table[cmdbucket(cmd)], cmd, is_cmd);
  }
  
  void remove_cmd(const char *cmd) {
!   listRemoveWith(cmd_table[cmdbucket(cmd)], cmd, is_cmd);
  }
  
  void add_cmd(const char *cmd, const char *sort_by,
  	     void *func, int subcmd, int min_pos, int max_pos,
! 	     int min_level, bool interrupts) {
    // if we've already got a command named this, remove it
!   if(find_cmd(cmd, FALSE) != NULL)
!     remove_cmd(cmd);
  
    // make our new command data
!   struct cmd_data *new_cmd = malloc(sizeof(struct cmd_data));
    new_cmd->cmd_name   = strdup(cmd);
    new_cmd->sort_by    = strdup(sort_by ? sort_by : cmd);
    new_cmd->cmd_funct  = func;
--- 256,308 ----
  }
  
  // compare two command by their sort_by variable
! int cmdsortbycmp(const CMD_DATA *cmd1, const CMD_DATA *cmd2) {
    return strcasecmp(cmd1->sort_by, cmd2->sort_by);
  }
  
  // compare two commands
! int cmdcmp(const CMD_DATA *cmd1, const CMD_DATA *cmd2) {
    return strcasecmp(cmd1->cmd_name, cmd2->cmd_name);
  }
  
  // check if the cmd matches the command's cmd_name up to the length of cmd
! int is_cmd_abbrev(const char *cmd, const CMD_DATA *entry) {
    return strncasecmp(cmd, entry->cmd_name, strlen(cmd));
  }
  
  // check if the string matches the command's cmd_name
! int is_cmd(const char *cmd, const CMD_DATA *entry) {
    return strcasecmp(cmd, entry->cmd_name);
  }
  
  // find a command
! CMD_DATA *find_cmd(const char *cmd, bool abbrev_ok) {
    if(abbrev_ok)
      return listGetWith(cmd_table[cmdbucket(cmd)], cmd, is_cmd_abbrev);
    else
      return listGetWith(cmd_table[cmdbucket(cmd)], cmd, is_cmd);
  }
  
+ //
+ // remove (and delete) a command
+ //
  void remove_cmd(const char *cmd) {
!   CMD_DATA *removed = listRemoveWith(cmd_table[cmdbucket(cmd)], cmd, is_cmd);
!   if(removed) {
!     if(removed->cmd_name) free(removed->cmd_name);
!     if(removed->sort_by)  free(removed->sort_by);
!     free(removed);
!   }
  }
  
  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) {
    // if we've already got a command named this, remove it
!   remove_cmd(cmd);
  
    // make our new command data
!   CMD_DATA *new_cmd = malloc(sizeof(CMD_DATA));
    new_cmd->cmd_name   = strdup(cmd);
    new_cmd->sort_by    = strdup(sort_by ? sort_by : cmd);
    new_cmd->cmd_funct  = func;
***************
*** 291,296 ****
--- 310,316 ----
    new_cmd->min_pos    = min_pos;
    new_cmd->max_pos    = max_pos;
    new_cmd->level      = min_level;
+   new_cmd->mob_ok     = mob_ok;
    new_cmd->interrupts = interrupts;
  
    // and add it in
***************
*** 299,317 ****
  
  
  // show the character all of the commands he or she can perform
! void show_commands(CHAR_DATA *ch) {
    BUFFER *buf = buffer_new(MAX_BUFFER);
    int i, col = 0;
  
    // go over all of our buckets
    for(i = 0; i < 26; i++) {
      LIST_ITERATOR *buck_i = newListIterator(cmd_table[i]);
!     struct cmd_data *cmd = NULL;
  
      ITERATE_LIST(cmd, buck_i) {
!       if(charGetLevel(ch) < cmd->level)
  	continue;
!       bprintf(buf, " %-16.16s", cmd->cmd_name);
        if (!(++col % 4))
  	bprintf(buf, "\r\n");      
      }
--- 319,337 ----
  
  
  // 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
    for(i = 0; i < 26; i++) {
      LIST_ITERATOR *buck_i = newListIterator(cmd_table[i]);
!     CMD_DATA *cmd = NULL;
  
      ITERATE_LIST(cmd, buck_i) {
!       if(min_lev > cmd->level || max_lev < cmd->level)
  	continue;
!       bprintf(buf, "%-20.20s", cmd->cmd_name);
        if (!(++col % 4))
  	bprintf(buf, "\r\n");      
      }
***************
*** 396,411 ****
  }
  
  
- //
- // expand an alias out, replacing all wildcards with arguments passed in
- //
- char *expand_alias(const char *alias, const char *arg) {
-   char *cmd = strdup(alias);
-   replace_string(&cmd, "$*", arg, TRUE);
-   return cmd;
- }
- 
- 
  void handle_cmd_input(SOCKET_DATA *dsock, char *arg) {
    CHAR_DATA *ch;
    if ((ch = dsock->player) == NULL)
--- 416,421 ----
***************
*** 422,437 ****
    if(!arg || !*arg)
      return;
  
!   arg = one_arg(arg, command);
  
    // see if it's an alias
!   if(aliases_ok && charGetAlias(ch, command)) {
!     char *alias_cmd = expand_alias(charGetAlias(ch, command), arg);
      do_cmd(ch, alias_cmd, scripts_ok, FALSE);
      free(alias_cmd);
      return;
    }
! 
  
    // check to see if it's a faculty command
  #ifdef MODULE_FACULTY
--- 432,461 ----
    if(!arg || !*arg)
      return;
  
!   // if we are leading with a non-character, we are trying to do a short-form
!   // command (e.g. ' for say, " for gossip). Just take the first character
!   // and use the rest as the arg
!   if(isalpha(*arg))
!     arg = one_arg(arg, command);
!   else {
!     *command     = *arg;
!     *(command+1) = '\0';
!     arg++;
!     // and skip all spaces
!     while(isspace(*arg))
!       arg++;
!   }
  
+ #ifdef MODULE_ALIAS
    // see if it's an alias
!   const char *alias = charGetAlias(ch, command);
!   if(aliases_ok && alias) {
!     char *alias_cmd = expand_alias(alias, arg);
      do_cmd(ch, alias_cmd, scripts_ok, FALSE);
      free(alias_cmd);
      return;
    }
! #endif
  
    // check to see if it's a faculty command
  #ifdef MODULE_FACULTY
***************
*** 450,463 ****
    // iterate over the commands that would be in our 
    // bucket and find the one that we are trying to use
    LIST_ITERATOR *cmd_i = newListIterator(cmd_table[cmdbucket(command)]);
!   struct cmd_data *cmd = NULL;
    ITERATE_LIST(cmd, cmd_i) {
      if (cmd->level > charGetLevel(ch))
        continue;
  
      if (is_prefix(command, cmd->cmd_name)) {
        found_cmd = TRUE;
!       if(min_pos_ok(ch, cmd->min_pos) && max_pos_ok(ch,cmd->max_pos)) {
  	if(cmd->interrupts) {
  #ifdef MODULE_FACULTY
  	  interrupt_action(ch, FACULTY_ALL);
--- 474,488 ----
    // iterate over the commands that would be in our 
    // bucket and find the one that we are trying to use
    LIST_ITERATOR *cmd_i = newListIterator(cmd_table[cmdbucket(command)]);
!   CMD_DATA *cmd = NULL;
    ITERATE_LIST(cmd, cmd_i) {
      if (cmd->level > charGetLevel(ch))
        continue;
  
      if (is_prefix(command, cmd->cmd_name)) {
        found_cmd = TRUE;
!       if(min_pos_ok(ch, cmd->min_pos) && max_pos_ok(ch,cmd->max_pos) &&
! 	 (!charIsNPC(ch) || cmd->mob_ok)) {
  	if(cmd->interrupts) {
  #ifdef MODULE_FACULTY
  	  interrupt_action(ch, FACULTY_ALL);
***************
*** 465,471 ****
  	  interrupt_action(ch, 1);
  #endif
  	}
! 	(cmd->cmd_funct)(ch, arg, cmd->subcmd);
        }
        break;
      }
--- 490,496 ----
  	  interrupt_action(ch, 1);
  #endif
  	}
! 	(cmd->cmd_funct)(ch, cmd->cmd_name, cmd->subcmd, arg);
        }
        break;
      }
diff -crN nakedmudv1.0/src/io.c nakedmudv1.4/src/io.c
*** nakedmudv1.0/src/io.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/io.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 98,103 ****
--- 98,121 ----
    return mTime;
  }
  
+ char *read_file(const char *file) {
+   FILE *fl;
+   static char contents[MAX_BUFFER];
+   int i;
+ 
+   if((fl = fopen(file, "r")) == NULL)
+     return NULL;
+ 
+   i = 0;
+   while((contents[i] = getc(fl)) != EOF)
+     i++;
+ 
+   contents[i] = '\0';
+   fclose(fl);
+   return strdup(contents);
+ }
+ 
+ 
  char *read_help_entry(const char *helpfile)
  {
    FILE *fp;
diff -crN nakedmudv1.0/src/list.c nakedmudv1.4/src/list.c
*** nakedmudv1.0/src/list.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/list.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,36 ****
  //*****************************************************************************
  //
! // list.c
  //
! // the implementation of a generic list structure
  //
  //*****************************************************************************
  
  #include <stdlib.h>
  #include "list.h"
  
  
  struct list_node {
!   void *elem;
!   struct list_node *next;
  };
  
  struct list_iterator {
!   struct list      *L;
!   struct list_node *curr;
  };
  
  struct list {
!   struct list_node *head;
!   struct list_node *tail;
!   int size;
  };
  
- #ifndef FALSE
- #define FALSE   0
- #define TRUE    !(FALSE)
- #endif
- 
  
  //
  // Delete a list node, and all nodes attached to it
--- 1,46 ----
  //*****************************************************************************
  //
! // list.c v1.1
  //
! // the implementation of a generic list structure.
! //
! // Jan 15/04:
! //   Removing elements from the list while we're iterating over it can be very
! // dangerous. The latest revision of the list keeps track of how many iterators
! // are currently running overtop of us, and only actually removes items from
! // the list until the iterator count goes down to 0; until then, the items are
! // flagged as removed so they are not touched.
  //
  //*****************************************************************************
  
  #include <stdlib.h>
  #include "list.h"
  
+ #ifndef FALSE
+ #define FALSE   0
+ #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?
  };
  
  
  //
  // Delete a list node, and all nodes attached to it
***************
*** 45,51 ****
  //
  void deleteListNodeWith(struct list_node *N, void (*delete_func)(void *)) {
    if(N->next) deleteListNodeWith(N->next, delete_func);
!   delete_func(N->elem);
    free(N);
  }
  
--- 55,63 ----
  //
  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)
!     delete_func(N->elem);
    free(N);
  }
  
***************
*** 54,65 ****
  //
  struct list_node *newListNode(void *elem) {
    struct list_node *N = malloc(sizeof(struct list_node));
!   N->elem = elem;
!   N->next = NULL;
    return N;
  };
  
  
  
  
  //*****************************************************************************
--- 66,123 ----
  //
  struct list_node *newListNode(void *elem) {
    struct list_node *N = malloc(sizeof(struct list_node));
!   N->elem    = elem;
!   N->next    = NULL;
!   N->removed = FALSE;
    return N;
  };
  
  
+ //
+ // 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
+     while(node && node->removed) {
+       L->head = node->next;
+       node->next = NULL;
+       deleteListNode(node);
+       node = L->head;
+     }
+     
+     // go through the rest of the list
+     if(node != NULL) {
+       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);
+ 	  // if we just removed the last element in the list, our next 
+ 	  // node should be NULL and we cannot keep do our next loop, 
+ 	  // as we'll try to assign NULL to the current node
+ 	  if(node->next == NULL) break;
+ 	}
+ 	node = node->next;
+       }
+     }
+     
+     // reset the tail of our list
+     L->tail = node;
+     
+     // if we have no elements left, clear our head and tail
+     if(L->size == 0)
+       L->head = L->tail = NULL;
+   }
+ }
+ 
  
  
  //*****************************************************************************
***************
*** 68,77 ****
  //
  //*****************************************************************************
  struct list *newList() {
!   struct list *L = malloc(sizeof(struct list));
!   L->head = NULL;
!   L->tail = NULL;
!   L->size = 0;
    return L;
  };
  
--- 126,137 ----
  //
  //*****************************************************************************
  struct list *newList() {
!   struct list *L    = malloc(sizeof(struct list));
!   L->head           = NULL;
!   L->tail           = NULL;
!   L->size           = 0;
!   L->iterators      = 0;
!   L->remove_pending = FALSE;
    return L;
  };
  
***************
*** 94,100 ****
    N->next = L->head;
    L->head = N;
    L->size++;
!   if(L->size == 1)
      L->tail = N;
  };
  
--- 154,160 ----
    N->next = L->head;
    L->head = N;
    L->size++;
!   if(L->tail == NULL)
      L->tail = N;
  };
  
***************
*** 130,137 ****
  int listIn(struct list *L, const void *elem) {
    struct list_node *N = L->head;
  
!   while(N) {
!     if(N->elem == elem)
        return TRUE;
      N = N->next;
    }
--- 190,197 ----
  int listIn(struct list *L, const void *elem) {
    struct list_node *N = L->head;
  
!   while(N != NULL) {
!     if(!N->removed && N->elem == elem)
        return TRUE;
      N = N->next;
    }
***************
*** 148,175 ****
      return FALSE;
  
    // we first have to check if it is the head
!   if(N->elem == elem) {
!     L->head = N->next;
!     N->next = NULL;
!     deleteListNode(N);
!     L->size--;
!     if(L->size == 0)
!       L->tail = NULL;
!     return TRUE;
    }
    // otherwise, we can check if it's another element
    else {
      while(N->next) {
        // we found it ... remove it now
!       if(N->next->elem == elem) {
! 	if(N->next == L->tail)
! 	  L->tail = N;
! 	struct list_node *tmp = N->next;
! 	N->next = tmp->next;
! 	tmp->next = NULL;
! 	deleteListNode(tmp);
! 	L->size--;
! 	return TRUE;
        }
        N = N->next;
      }
--- 208,253 ----
      return FALSE;
  
    // we first have to check if it is the head
!   if(!N->removed && N->elem == elem) {
!     // check to see if there's an iterator on us
!     if(L->iterators > 0) {
!       N->removed = TRUE;
!       L->size--;
!       L->remove_pending = TRUE;
!       return TRUE;
!     }
!     else {
!       L->head = N->next;
!       N->next = NULL;
!       deleteListNode(N);
!       L->size--;
!       if(L->size == 0)
! 	L->tail = NULL;
!       return TRUE;
!     }
    }
    // otherwise, we can check if it's another element
    else {
      while(N->next) {
        // we found it ... remove it now
!       if(!N->next->removed && N->next->elem == elem) {
! 	// check to see if there's an iterator on us
! 	if(L->iterators > 0) {
! 	  N->next->removed = TRUE;
! 	  L->remove_pending = TRUE;
! 	  L->size--;
! 	  return TRUE;
! 	}
! 	else {
! 	  if(N->next == L->tail)
! 	    L->tail = N;
! 	  struct list_node *tmp = N->next;
! 	  N->next = tmp->next;
! 	  tmp->next = NULL;
! 	  deleteListNode(tmp);
! 	  L->size--;
! 	  return TRUE;
! 	}
        }
        N = N->next;
      }
***************
*** 192,255 ****
    struct list_node *node = L->head;
    int i;
  
!   for(i = 0; i < num && node; i++)
      node = node->next;
  
!   if(node) return node->elem;
!   else     return NULL;
  }
  
  int isListEmpty(struct list *L) {
!   return (L->head == NULL);
  }
  
  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(!comparator(cmpto, node->elem))
        return node->elem;
    return NULL;
  }
  
! int 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)
!     return FALSE;
  
    // we first have to check if it is the head
!   if(!comparator(cmpto, N->elem)) {
!     L->head = N->next;
!     N->next = NULL;
!     deleteListNode(N);
!     L->size--;
!     if(L->size == 0)
!       L->tail = NULL;
!     return TRUE;
    }
    // otherwise, we can check if it's another element
    else {
      while(N->next) {
        // we found it ... remove it now
!       if(!comparator(cmpto, 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);
! 	L->size--;
! 	return TRUE;
        }
        N = N->next;
      }
    }
    // we didn't find it
!   return FALSE;
  }
  
  
--- 270,363 ----
    struct list_node *node = L->head;
    int i;
  
!   // move up to our first non-removed node
!   while(node && node->removed)
      node = node->next;
  
!   for(i = 0; i < num && node; node = node->next) {
!     if(node->removed)
!       continue;
!     i++;
!   }
! 
!   return (node ? node->elem : NULL);
  }
  
  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)
!       continue;
      if(!comparator(cmpto, node->elem))
        return node->elem;
+   }
    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)
!     return NULL;
  
    // we first have to check if it is the head
!   if(!N->removed && !comparator(cmpto, N->elem)) {
!     // check to see if there's an iterator on us
!     if(L->iterators > 0) {
!       N->removed = TRUE;
!       L->remove_pending = TRUE;
!       L->size--;
!       return N->elem;
!     }
!     else {
!       void *elem = N->elem;
!       L->head = N->next;
!       N->next = NULL;
!       deleteListNode(N);
!       L->size--;
!       if(L->size == 0)
! 	L->tail = NULL;
!       return elem;
!     }
    }
+ 
    // otherwise, we can check if it's another element
    else {
      while(N->next) {
        // we found it ... remove it now
!       if(!N->next->removed && !comparator(cmpto, N->next->elem)) {
! 	// check to see if there's an iterator on us
! 	if(L->iterators > 0) {
! 	  N->next->removed = TRUE;
! 	  L->remove_pending = TRUE;
! 	  L->size--;
! 	  return N->next->elem;
! 	}
! 	else {
! 	  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);
! 	  L->size--;
! 	  return elem;
! 	}
        }
        N = N->next;
      }
    }
    // we didn't find it
!   return NULL;
  }
  
  
***************
*** 259,282 ****
  
    // we don't have any contents, or we're lower than the
    // first list content then just put it at the start
!   if(N == NULL || comparator(elem, N->elem) < 0)
      listPut(L, elem);
    else {
      // while we've got a next element, compare ourselves to it.
      // if we are smaller than it, then sneak inbetween. Otherwise,
      // skip to the next element
      while(N->next != NULL) {
!       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++;
! 	return;
        }
!       else
! 	N = N->next;
      }
      // if we've gotten this far, then we need to attach ourself to the end
      N->next = newListNode(elem);
--- 367,391 ----
  
    // we don't have any contents, or we're lower than the
    // first list content then just put it at the start
!   if(N == NULL || (!N->removed && comparator(elem, N->elem) < 0))
      listPut(L, elem);
    else {
      // while we've got a next element, compare ourselves to it.
      // if we are smaller than it, then sneak inbetween. Otherwise,
      // skip to the next element
      while(N->next != NULL) {
!       if(!N->next->removed) {
! 	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++;
! 	  return;
! 	}
        }
!       N = N->next;
      }
      // if we've gotten this far, then we need to attach ourself to the end
      N->next = newListNode(elem);
***************
*** 294,299 ****
--- 403,411 ----
    while(listSize(L) > 0)
      listPutWith(new_list, listPop(L), func);
  
+   // kill all of our removed nodes
+   if(L->head) deleteListNode(L->head);
+ 
    L->head = new_list->head;
    L->tail = new_list->tail;
    L->size = new_list->size;
***************
*** 308,315 ****
    struct list *newlist = newList();
  
    struct list_node *N = NULL;
!   for(N = L->head; N; N = N->next)
      listQueue(newlist, copy_func(N->elem));
  
    return newlist;
  }
--- 420,429 ----
    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));
+   }
  
    return newlist;
  }
***************
*** 324,333 ****
--- 438,452 ----
    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)
+     listCleanRemoved(I->L);
    free(I);
  };
  
***************
*** 335,353 ****
    if(I->curr)
      I->curr = I->curr->next;
  
!   if(I->curr)
!     return I->curr->elem;
!   else        
!     return NULL;
  };
  
  void listIteratorReset(struct list_iterator *I) {
    I->curr = I->L->head;
  };
  
  void *listIteratorCurrent(struct list_iterator *I) {
!   if(I->curr)
!     return I->curr->elem;
!   else
!     return NULL;
  };
--- 454,480 ----
    if(I->curr)
      I->curr = I->curr->next;
  
!   // skip all of the removed elements
!   while(I->curr && I->curr->removed)
!     I->curr = I->curr->next;
! 
!   return (I->curr ? I->curr->elem : NULL);
  };
  
+ // 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);
+ 
    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;
! 
!   return (I->curr ? I->curr->elem : NULL);
  };
diff -crN nakedmudv1.0/src/list.h nakedmudv1.4/src/list.h
*** nakedmudv1.0/src/list.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/list.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 115,121 ****
  // TRUE if the item was found and removed. FALSE other wise. Cmpto must
  // be the thing we are compared against in func.
  //
! int listRemoveWith(struct list *L, const void *cmpto, void *func);
  
  
  //
--- 115,121 ----
  // 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);
  
  
  //
diff -crN nakedmudv1.0/src/log.c nakedmudv1.4/src/log.c
*** nakedmudv1.0/src/log.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/log.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 99,105 ****
    }
  
    add_cmd("log", NULL, cmd_log, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN, FALSE);
  }
  
  
--- 99,105 ----
    }
  
    add_cmd("log", NULL, cmd_log, 0, POS_UNCONCIOUS, POS_FLYING,
! 	  LEVEL_ADMIN, FALSE, FALSE);
  }
  
  
diff -crN nakedmudv1.0/src/magic.c nakedmudv1.4/src/magic.c
*** nakedmudv1.0/src/magic.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/src/magic.c.bk nakedmudv1.4/src/magic.c.bk
*** nakedmudv1.0/src/magic.c.bk	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/src/magic.h nakedmudv1.4/src/magic.h
*** nakedmudv1.0/src/magic.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/src/main.mk nakedmudv1.4/src/main.mk
*** nakedmudv1.0/src/main.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/main.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,13 ----
+ 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 \
+ 	  \
+ 	  text_editor.c builder.c admin.c \
+ 	  \
+ 	  items.c races.c log.c help.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
diff -crN nakedmudv1.0/src/Makefile nakedmudv1.4/src/Makefile
*** nakedmudv1.0/src/Makefile	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/Makefile	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,51 ****
  ###############################################################################
! #Makefile for nakedmud
  ###############################################################################
  
  # compiler to use
  CC = gcc
  
! 
! ################################################################################
! #
! # Libraries and compile-time flags
! #
! ################################################################################
  
  # flags to use during compilation
! C_FLAGS = -Wall -g -ggdb -O2
  
! # libraries
! L_FLAGS = -lz -lpthread
  
! # linking requirements for the python scripting module. See
! # src/modules/scripts/makefile
! L_PY     = -u __dummy -u _PyMac_Error -framework Python -framework System \
! 	   -framework CoreServices -framework Foundation
! 
! # the location of the Python .a file, if it is needed. See 
! # src/modules/scripts/Makefile
! PY_LIB   =
  
! 
! ################################################################################
! #
! # object files, and source files for python extentions
! #
! ################################################################################
! O_FILES = gameloop.o mud.o utils.o interpret.o handler.o inform.o movement.o \
! 	  action.o mccp.o save.o socket.o io.o strings.o event.o \
! 	  \
! 	  cmd_comm.o cmd_manip.o cmd_misc.o \
! 	  \
! 	  text_editor.o builder.o admin.o \
! 	  \
! 	  items.o races.o log.o help.o auxiliary.o \
! 	  \
! 	  world.o character.o room.o exit.o extra_descs.o object.o body.o \
! 	  zone.o dialog.o room_reset.o \
! 	  \
! 	  list.o property_table.o hashtable.o hashmap.o storage.o
  
  
  
--- 1,49 ----
  ###############################################################################
! # Makefile for nakedmud
! #
! # Many thanks go out to Tyche for suggesting I read "Recursive Make Considered
! # Harmful" by Peter Miller. Many of the make conventions used in this makefile
! # were taken from Miller's article. The reference is:
! # 
! # Miller, P.A. (1998). Recursive Make Considered Harmful,
! #    AUUGN Journal of AUUG Inc., 19(1), pp. 14-25.
! #
  ###############################################################################
  
  # compiler to use
  CC = gcc
  
! # the modules we have installed
! MODULES := time alias char_vars socials olc scripts
  
  # flags to use during compilation
! C_FLAGS := -Wall -g -ggdb -O2
  
! # 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 \
! 	   \
! 	   text_editor.c builder.c admin.c help.c \
! 	   \
! 	   items.c races.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
! 
! 
! # include the description for each module. These will add to SRC
! # C_FLAGS, LIBS, etc...
! include $(patsubst %,%/module.mk, $(MODULES))
  
! # determine the object files
! O_FILES := $(patsubst %.c,%.o, $(filter %.c, $(SRC)))
  
  
  
***************
*** 55,106 ****
  #
  ################################################################################
  all: $(O_FILES)
! 	make module
! 	rm -f NakedMud
! 	$(CC) -o NakedMud *.o $(PY_LIB) $(L_FLAGS) $(L_PY)
  
! # make the object files
  .c.o: all
! 	$(CC) -c $(C_FLAGS) $<
  
  # make dependancies for all of the files
  depend:
! 	$(CC) -MM *.c > .depend
! 	make moduledepend
  
  clean:
- 	rm -f *.o
- 	rm -f *.o
- 	make moduleclean
  	rm -f NakedMud
! 	rm -f *.*~
! 
  
  include .depend
- 
- 
- ################################################################################
- #
- # when installing new modules, you will need to add the name of your module
- # to the MODULES list
- #
- ################################################################################
- MODULES = time olc scripts
- 
- # compile all of the modules we have installed
- module:
- 	for dir in $(MODULES); do             \
- 	  (cd modules/$$dir; $(MAKE) all);    \
- 	done
- 
- # clean all of our modules out
- moduleclean:
- 	for dir in $(MODULES); do             \
- 	  (cd modules/$$dir; $(MAKE) clean);  \
- 	done
- 
- # make dependancies for all of our modules
- moduledepend:
- 	for dir in $(MODULES); do             \
- 	  (cd modules/$$dir; $(MAKE) depend); \
- 	done
--- 53,80 ----
  #
  ################################################################################
  all: $(O_FILES)
! 	$(CC) -o NakedMud $(O_FILES) $(LIBS)
  
! # make the object files. The modules are sort of annoying, in that 
! # if we do not use -o, the object files will be compiled in this directory,
! # and then every time we re-make, the module .o files will be recompiled
! # because they are not in their home directory. So... we have to explicitly
! # 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:
  	rm -f NakedMud
! 	rm -f *.o
! 	rm -f */*.o
! 	rm -f *~
! 	rm -f */*~
  
  include .depend
diff -crN nakedmudv1.0/src/modules/example/Makefile nakedmudv1.4/src/modules/example/Makefile
*** nakedmudv1.0/src/modules/example/Makefile	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/example/Makefile	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,62 ****
- ################################################################################
- #
- # Generic Makefile
- #
- # The intent of this makefile is to act as a template makefile for people
- # creating new modules for NakedMud(tm). The module installation process has
- # been made as simple as I (Geoff Hollis) can make it; for the make file, all
- # you have to do is set O_FILES to a list of object files your module will
- # generate. For guidelines and instructions on installing new modules into
- # NakeMud(tm), please read the MODULES.txt file in the doc folder, located at
- # the root of the NakedMud directory.
- #
- # Questions and comments should be directed to Geoff Hollis (hollis@ualberta.ca)
- #
- ################################################################################
- 
- #
- # Enter a list of binary files your module will generate. This should be the
- # only variable you will need to modify in this makefile. Everything else
- # will handle itself.
- #
- O_FILES = 
- 
- 
- # compiler to use
- CC = gcc
- 
- 
- # the top level directory of the MUD. We need to define this 
- # so we can include header files found there
- MUDTOP = ../..
- 
- 
- #
- # compile-time flags
- #
- C_FLAGS = -Wall -g -ggdb -O2 -I$(MUDTOP)
- 
- 
- 
- 
- ################################################################################
- #
- # make commands
- #
- ################################################################################
- all: $(O_FILES)
- 	cp *.o $(MUDTOP)
- 
- # make the object files
- .c.o: all
- 	$(CC) -c $(C_FLAGS) $<
- 
- # make dependancies for all of the files
- depend:
- 	$(CC) -MM *.c > .depend
- 
- -include .depend
- 
- clean:
- 	rm -f *.o
- 	rm -f *.*~
--- 0 ----
diff -crN nakedmudv1.0/src/modules/olc/dedit.c nakedmudv1.4/src/modules/olc/dedit.c
*** nakedmudv1.0/src/modules/olc/dedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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 = (DIALOG_DATA *)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.0/src/modules/olc/.depend nakedmudv1.4/src/modules/olc/.depend
*** nakedmudv1.0/src/modules/olc/.depend	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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.0/src/modules/olc/edesc_edit.c nakedmudv1.4/src/modules/olc/edesc_edit.c
*** nakedmudv1.0/src/modules/olc/edesc_edit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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.0/src/modules/olc/exedit.c nakedmudv1.4/src/modules/olc/exedit.c
*** nakedmudv1.0/src/modules/olc/exedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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.0/src/modules/olc/Makefile nakedmudv1.4/src/modules/olc/Makefile
*** nakedmudv1.0/src/modules/olc/Makefile	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/olc/Makefile	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,51 ****
- ################################################################################
- # OLC makefile
- ################################################################################
- 
- #
- # Enter a list of binary files your module will generate. This should be the
- # only variable you will need to modify in this makefile. Everything else
- # will handle itself.
- #
- O_FILES = dedit.o edesc_edit.o exedit.o medit.o oedit.o olc.o redit.o \
- 	  zedit.o ssedit.o scedit.o resedit.o
- 
- 
- # compiler to use
- CC = gcc
- 
- 
- # the top level directory of the MUD. We need to define this 
- # so we can include header files found there
- MUDTOP = ../..
- 
- 
- #
- # compile-time flags
- #
- C_FLAGS = -Wall -g -ggdb -O2 -I$(MUDTOP)
- 
- 
- 
- 
- ################################################################################
- #
- # make commands
- #
- ################################################################################
- all: $(O_FILES)
- 	cp *.o $(MUDTOP)
- 
- # make the object files
- .c.o: all
- 	$(CC) -c $(C_FLAGS) $<
- 
- # make dependancies for all of the files
- depend:
- 	$(CC) -MM *.c > .depend
- 
- -include .depend
- 
- clean:
- 	rm -f *.o
- 	rm -f *.*~
--- 0 ----
diff -crN nakedmudv1.0/src/modules/olc/medit.c nakedmudv1.4/src/modules/olc/medit.c
*** nakedmudv1.0/src/modules/olc/medit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/olc/medit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,260 ****
- //*****************************************************************************
- //
- // 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"
- 		 "{gD) Dialog       {y[{c%8d{y]  {w%s\r\n",
- 		 charGetVnum(mob),
- 		 charGetName(mob),
- 		 charGetMultiName(mob),
- 		 charGetKeywords(mob),
- 		 charGetRdesc(mob),
- 		 charGetMultiRdesc(mob),
- 		 charGetDesc(mob),
- 		 raceGetName(charGetRace(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_race_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
-   int i;
-   for(i = 0; i < NUM_RACES; i++)
-     send_to_socket(sock, "%2d) %-20s%s", 
- 		   i, raceGetName(i), (i % 3 == 2 ?"\r\n":""));
-   if(i % 3 != 0)
-     send_to_socket(sock, "\r\n");
-   send_to_socket(sock,
- 		 "\r\nPlease select a race: ");
- }
- 
- void medit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
-   int next_substate = MEDIT_MAIN;
- 
-   switch(*arg) {
-   case 'q':
-   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':
-   case 'R':
-     medit_race_menu(sock, olc);
-     next_substate = MEDIT_RACE;
-     break;
- 
-   case 'd':
-   case 'D':
-     send_to_socket(sock, "Enter new dialog vnum (-1 for none) : ");
-     next_substate = MEDIT_DIALOG;
-     break;
- 
- #ifdef MODULE_SCRIPTS
-   case 's':
-   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: {
-     int race = RACE_NONE;
-     if(isdigit(*arg)) race = atoi(arg);
-     else              race = raceGetNum(arg);
-     if(race == RACE_NONE) {
-       send_to_socket(sock, "Invalid race! Try again: ");
-       next_substate = MEDIT_RACE;
-     }
-     else {
-       charSetRace(mob, race);
-       charResetBody(mob);
-     }
-     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.0/src/modules/olc/oedit.c nakedmudv1.4/src/modules/olc/oedit.c
*** nakedmudv1.0/src/modules/olc/oedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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.0/src/modules/olc/olc.c nakedmudv1.4/src/modules/olc/olc.c
*** nakedmudv1.0/src/modules/olc/olc.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/olc/olc.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,805 ****
- //*****************************************************************************
- //
- // 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
- 
- 
- /* 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
- 
- 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, TRUE );
-   add_cmd("medit",      NULL, cmd_medit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, TRUE );
-   add_cmd("oedit",      NULL, cmd_oedit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, TRUE );
-   add_cmd("redit",      NULL, cmd_redit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, TRUE );
-   add_cmd("wedit",      NULL, cmd_wedit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, TRUE );
-   add_cmd("zedit",      NULL, cmd_zedit,    0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_BUILDER, TRUE );
- #ifdef MODULE_SCRIPTS
-   add_cmd("scedit",     NULL, cmd_scedit,   0, POS_SITTING, POS_FLYING,
- 	  LEVEL_SCRIPTER, 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
-     }
-   }
- 
-   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
-     }
-   }
-   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 = (CHAR_DATA *)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 = (OBJ_DATA *)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 = (ZONE_DATA *)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 = (ROOM_DATA *)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 = (DIALOG_DATA *)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 = (SCRIPT_DATA *)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
- 
- 
-   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
-   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;
- 	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
-   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) {
- 
- }
- 
- 
- #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
--- 0 ----
diff -crN nakedmudv1.0/src/modules/olc/olc.h nakedmudv1.4/src/modules/olc/olc.h
*** nakedmudv1.0/src/modules/olc/olc.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/olc/olc.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,197 ****
- #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
- 
- // 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 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
- 
- 
- 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.0/src/modules/olc/redit.c nakedmudv1.4/src/modules/olc/redit.c
*** nakedmudv1.0/src/modules/olc/redit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/olc/redit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,461 ****
- //*****************************************************************************
- //
- // 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;
-   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
-   for(i = 0; i < num_spec_exits; i++)
-     free(room_names[i]);
-   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.0/src/modules/olc/resedit.c nakedmudv1.4/src/modules/olc/resedit.c
*** nakedmudv1.0/src/modules/olc/resedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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.0/src/modules/olc/scedit.c nakedmudv1.4/src/modules/olc/scedit.c
*** nakedmudv1.0/src/modules/olc/scedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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 "modules/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.0/src/modules/olc/ssedit.c nakedmudv1.4/src/modules/olc/ssedit.c
*** nakedmudv1.0/src/modules/olc/ssedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/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.0/src/modules/olc/zedit.c nakedmudv1.4/src/modules/olc/zedit.c
*** nakedmudv1.0/src/modules/olc/zedit.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/olc/zedit.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,148 ****
- //*****************************************************************************
- //
- // 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(*arg) {
-   case 'q':
-   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.0/src/modules/scripts/.depend nakedmudv1.4/src/modules/scripts/.depend
*** nakedmudv1.0/src/modules/scripts/.depend	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/.depend	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,7 ****
- pychar.o: pychar.c script.h pychar.h pyroom.h pyobj.h
- pymud.o: pymud.c script.h pyroom.h pychar.h pyobj.h
- pyobj.o: pyobj.c script.h pychar.h pyroom.h pyobj.h
- pyroom.o: pyroom.c script.h pyroom.h pychar.h pyobj.h
- script.o: script.c script.h script_set.h pychar.h pyroom.h pyobj.h \
-   pymud.h
- script_set.o: script_set.c script_set.h script.h
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/Makefile nakedmudv1.4/src/modules/scripts/Makefile
*** nakedmudv1.0/src/modules/scripts/Makefile	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/Makefile	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,127 ****
- ################################################################################
- #
- # Python scripting stuff.
- #
- # To enable python as a scripting language, you have to add a bit of stuff to
- # the make process. I run on Mac OSX, so all of the default stuff is set up
- # for compiling under OSX, but if you are running on a different OS, you will
- # have to change these things. Here is a set of instructions on how to change
- # everything to work for you:
- #
- # STEP 1: Locating Python
- #   Figure out where your python directory is. If you do not know how to do
- #   this, you can do a "find" from your shell:
- #     find / -name "Python.h" -print
- #
- #   wait for the path to Python.h to show up. You'll have to doctor it a bit;
- #   from the path, you will want to figure out the top directory for python, and
- #   where all of the header files are located. If the path looks something like:
- #     /usr/lib/python2.4/include/Python.h
- #
- #   PYTHONTOP should be /usr/lib/python2.4
- #   and PY_INC should be -I$(PYTHONTOP)/include
- #
- #
- # STEP 2: Getting the linking requirements for python.
- #   This is a relatively easy step; start up python (from shell, type "python")
- #   and do this:
- #
- #   >>> import distutils.sysconfig
- #   >>> distutils.sysconfig.get_config_var('LINKFORSHARED')
- #
- #   a string will print that looks something like:
- #   '-Xlinker -export-dynamic'
- #
- #   copy this string (minus the two surrounding ') to the L_PY variable in
- #   the Makefile at the src directory (two directories down).
- #
- #
- # STEP 3: Compiling
- #   Try compiling. If you get a bunch of errors, go onto step 4.
- #
- #
- # STEP 4: Finding the runtime library.
- #   On Mac OSX, you do not need to include the runtime library, but I know
- #   for other platforms (fedora, for example) you will need to. If you're on
- #   this step, it's probably because you're using one of those other operating
- #   systems. You'll need to find the python library and use it during
- #   compilation. This isn't too hard. Change your directory to PYTHONTOP and
- #   type:
- #     find . -name "libpython*a" -print
- #
- #   when it spits out the address to the python library, set this as the
- #   value of PY_LIB in the Makefile at the src directory (two directories down).
- #   Now, go back to STEP 3. If you still get errors, you'll want to move onto 
- #   STEP 5.
- #
- # 
- # STEP 5: Adding neccessary libraries.
- #   Still won't compile? You may need to add some extra libraries that Python
- #   requires. These are pretty easy to find, usually; if you are getting
- #   getting messages like "undefined references to sin", "undefined reference
- #   to pthread_start" etc... you will want to add the libraries that these
- #   functions belong to. for each one that comes up, do a "man XXX" and read
- #   the man file until you figure out which library the function belongs to.
- #   Ones that I found were neccessary for me to include on Fedora were -lm and
- #   -ldl . This, of course, will vary from OS to OS. Add all of the libraries
- #   you need to the end of L_PY in the Makefile at the src directory (two
- #   directories down) and recompile. If things still aren't working for you, 
- #   proceed to STEP 6.
- #
- #
- # STEP 6: On your own, or disabling Python
- #   If you've gotten to this step, I don't really have much help for you. Your
- #   options are a) try to figure the rest out on your own, or disable Python
- #   scripts. To disable python scripts, go into mud.h and comment out the
- #   MODULE_SCRIPTS define near the top of mud.h
- #
- #   You will also want to remove all of the script module-related stuff in the 
- #   makefile at the src directory (the stuff you added in steps 1-5 and three
- #   lines at the very bottom of the makefile). Make clean, and recompile.
- #
- ################################################################################
- 
- # compiler to use
- CC = gcc
- 
- # the top level directory of python
- PYTHONTOP = /System/Library/Frameworks/Python.framework/Versions/Current
- 
- # the folder where python headers are located
- PY_INC    = -I$(PYTHONTOP)/Headers
- 
- # Object files we generate
- O_FILES = script_set.o script.o pychar.o pyobj.o pymud.o pyroom.o
- 
- # the top level directory of the MUD. We need to define this 
- # so we can include header files found there
- MUDTOP = ../..
- 
- #
- # compile-time flags
- #
- C_FLAGS = -Wall -g -ggdb -O2 -I$(MUDTOP) $(PY_INC)
- 
- 
- 
- ################################################################################
- #
- # make commands
- #
- ################################################################################
- all: $(O_FILES)
- 	cp *.o $(MUDTOP)
- 
- # make the object files
- .c.o: all
- 	$(CC) -c $(C_FLAGS) $<
- 
- # make dependancies for all of the files
- depend:
- 	$(CC) -MM *.c > .depend
- 
- -include .depend
- 
- clean:
- 	rm -f *.o
- 	rm -f *.*~
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pychar.c nakedmudv1.4/src/modules/scripts/pychar.c
*** nakedmudv1.0/src/modules/scripts/pychar.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pychar.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,890 ****
- //*****************************************************************************
- //
- // py_char.c
- //
- // A python extention to allow python scripts to treat MUD characters as an
- // object within the script.
- //
- //*****************************************************************************
- 
- #include <Python.h>
- #include <structmember.h>
- 
- #include <mud.h>
- #include <world.h>
- #include <room.h>
- #include <character.h>
- #include <object.h>
- #include <items.h>
- #include <races.h>
- #include <handler.h>
- #include <utils.h>
- 
- #include "script.h"
- #include "pychar.h"
- #include "pyroom.h"
- #include "pyobj.h"
- 
- 
- typedef struct {
-   PyObject_HEAD
-   int uid;
- } PyChar;
- 
- 
- //*****************************************************************************
- //
- // allocation, deallocation, and initialiation
- //
- //*****************************************************************************
- static void
- PyChar_dealloc(PyChar *self) {
-   self->ob_type->tp_free((PyObject*)self);
- }
- 
- static PyObject *
- PyChar_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
-     PyChar *self;
- 
-     self = (PyChar  *)type->tp_alloc(type, 0);
-     self->uid = NOBODY;//NULL;
-     return (PyObject *)self;
- }
- 
- static int
- PyChar_init(PyChar *self, PyObject *args, PyObject *kwds) {
-   static char *kwlist[] = {"uid", NULL};
-   int uid = NOBODY;
- 
-   // get the universal id
-   if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &uid)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Characters may only be created by uid");
-     return -1;
-   }
- 
-   // make sure a character with the UID exists
-   if(!propertyTableGet(mob_table, uid)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character with uid, %d, does not exist", uid);
-     return -1;
-   }
- 
-   self->uid = uid;
-   return 0;
- }
- 
- 
- 
- 
- //*****************************************************************************
- //
- // methods and stuff for building the class
- //
- //*****************************************************************************
- 
- //
- // sends a newline-tagged message to the character
- //
- static PyObject *
- PyChar_send(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_to_char(ch, "%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 *
- PyChar_act(PyChar *self, PyObject *value) {
-   int scripts_ok     = TRUE;
-   char *act          = NULL;
-   if (!PyArg_ParseTuple(value, "s|i", &act, &scripts_ok)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Characters actions must be strings.");
-     return NULL;
-   }
- 
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch) {
-     do_cmd(ch, act, scripts_ok, FALSE);
-     return Py_BuildValue("i", 1);
-   }
-   else {
-     PyErr_Format(PyExc_TypeError, 
-                     "Nonexistant character, %d, tried to perform an action.", 
- 		    self->uid);
-     return NULL;
-   }
- }
- 
- 
- //
- // Get the value of a variable stored on the character
- //
- static PyObject *
- PyChar_getvar(PyChar *self, PyObject *arg) {
-   char *var = NULL;
-   if (!PyArg_ParseTuple(arg, "s", &var)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character variables must have string names.");
-     return NULL;
-   }
- 
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch) {
-     int val = charGetVarVal(ch, var);
-     return Py_BuildValue("i", val);
-   }
-   else {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to get a variable value for nonexistant character, %d",
- 		 self->uid);
-     return NULL;
-   }
- }
- 
- //
- // Set the value of a variable assocciated with the character
- //
- static PyObject *
- PyChar_setvar(PyChar *self, PyObject *args) {  
-   char *var = NULL;
-   int val = 0;
- 
-   if (!PyArg_ParseTuple(args, "si", &var, &val)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Character setvar must be supplied with a var name and integer value.");
-     return NULL;
-   }
- 
- 
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch) {
-     charSetVar(ch, var, val);
-     return Py_BuildValue("i", 1);
-   }
-   else {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to set a variable value for nonexistant character, %d",
- 		 self->uid);
-     return NULL;
-   }
- }
- 
- 
- 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." },
-     {"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 */
- };
- 
- //*****************************************************************************
- //
- // character attributes - mostly get and set
- //
- //*****************************************************************************
- static PyObject *
- PyChar_getname(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("s", charGetName(ch));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getdesc(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("s", charGetDesc(ch));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getrdesc(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("s", charGetRdesc(ch));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getrace(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("s", raceGetName(charGetRace(ch)));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getlevel(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("i", charGetLevel(ch));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getsex(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("s", sexGetName(charGetSex(ch)));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getposition(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("s", posGetName(charGetPos(ch)));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getroom(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("O", newPyRoom(charGetRoom(ch)));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getisnpc(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("i", charIsNPC(ch));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getispc(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("i", !charIsNPC(ch));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_geton(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch == NULL) 
-     return NULL;
-   else if(charGetFurniture(ch) == NULL)
-     return Py_None;
-   else 
-     return Py_BuildValue("i", newPyObj(charGetFurniture(ch)));
- }
- 
- static PyObject *
- PyChar_getuid(PyChar *self, void *closure) {
-   return Py_BuildValue("i", self->uid);
- }
- 
- 
- static PyObject *
- PyChar_getvnum(PyChar *self, void *closure) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch != NULL) return Py_BuildValue("i", charGetVnum(ch));
-   else           return NULL;
- }
- 
- static PyObject *
- PyChar_getinv(PyChar *self, PyObject *args) {
-   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
-   if(ch == NULL) 
-     return NULL;
- 
-   LIST_ITERATOR *inv_i = newListIterator(charGetInventory(ch));
-   PyObject *list = PyList_New(0);
-   OBJ_DATA *obj;
-   
-   // for each obj in the inventory, add it to the Python list
-   ITERATE_LIST(obj, inv_i)
-     PyList_Append(list, newPyObj(obj));
-   deleteListIterator(inv_i);
-   return Py_BuildValue("O", list);
- }
- 
- 
- 
- //
- // Standard check to make sure the character exists when
- // trying to set a value for it. If successful, assign the
- // character to ch. Otherwise, return -1 (error)
- //
- #define PYCHAR_CHECK_CHAR_EXISTS(uid, ch)                                      \
-   ch = propertyTableGet(mob_table, uid);                                       \
-   if(ch == NULL) {                                                             \
-     PyErr_Format(PyExc_TypeError,                                              \
- 		    "Tried to modify nonexistant character, %d", uid);         \
-     return -1;                                                                 \
-   }                                                                            
- 
- 
- static int
- PyChar_setname(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete character's name");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character names must be strings");
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   charSetName(ch, PyString_AsString(value));
-   return 0;
- }
- 
- static int
- PyChar_setdesc(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete character's description");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character descriptions must be strings");
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   charSetDesc(ch, PyString_AsString(value));
-   return 0;
- }
- 
- static int
- PyChar_setrdesc(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete character's rdesc");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character rdescs must be strings");
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   charSetRdesc(ch, PyString_AsString(value));
-   return 0;
- }
- 
- static int
- PyChar_setrace(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete a character's race");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character races must be strings");
-     return -1;
-   }
- 
-   int race = raceGetNum(PyString_AsString(value));
-   if(race == RACE_NONE) {
-     char buf[SMALL_BUFFER];
-     sprintf(buf, "%s is an invalid race type", PyString_AsString(value));
-     PyErr_Format(PyExc_TypeError, buf);
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   charSetRace(ch, race);
-   return 0;
- }
- 
- static int
- PyChar_seton(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete a character's furniture.");
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
- 
-   if (value == Py_None) {
-     char_from_furniture(ch);
-     return 0;
-   }
-   else if(PyObj_Check(value)) {
-     OBJ_DATA *obj = propertyTableGet(obj_table, PyObj_AsUid(value));
-     if(obj == NULL) {
-       PyErr_Format(PyExc_TypeError, 
- 		   "Tried to %s's furniture to a nonexistant object.",
- 		   charGetName(ch));
-       return -1;
-     }
-     else if(objGetType(obj) == ITEM_FURNITURE) {
-       if(charGetFurniture(ch))
- 	char_from_furniture(ch);
-       char_to_furniture(ch, obj);
-       return 0;
-     }
-   }
- 
-   PyErr_Format(PyExc_TypeError, 
- 	       "A Character's furniture may only be set to None or a ."
- 	       "furniture object.");
-   return -1;
- }
- 
- static int
- PyChar_setsex(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete a character's sex");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character sexes must be strings");
-     return -1;
-   }
- 
-   int sex = sexGetNum(PyString_AsString(value));
-   if(sex == SEX_NONE) {
-     char buf[SMALL_BUFFER];
-     sprintf(buf, "%s is an invalid sex type", PyString_AsString(value));
-     PyErr_Format(PyExc_TypeError, buf);
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   charSetSex(ch, sex);
-   return 0;
- }
- 
- static int
- PyChar_setposition(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete a character's position");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character positions must be strings");
-     return -1;
-   }
- 
-   int pos = posGetNum(PyString_AsString(value));
-   if(pos == POS_NONE) {
-     char buf[SMALL_BUFFER];
-     sprintf(buf, "%s is an invalid position type", PyString_AsString(value));
-     PyErr_Format(PyExc_TypeError, buf);
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   charSetPos(ch, pos);
-   // players can't be on furniture if they are standing or flying
-   if(poscmp(charGetPos(ch), POS_STANDING) >= 0 && charGetFurniture(ch))
-     char_from_furniture(ch);
-   return 0;
- }
- 
- static int
- PyChar_setlevel(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete a character's level");
-     return -1;
-   }
-   
-   if (!PyInt_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Character levels must be integers");
-     return -1;
-   }
- 
-   long lvl = PyInt_AsLong(value);
-   if(lvl < 1 || lvl > MAX_LEVEL) {
-     char buf[SMALL_BUFFER];
-     sprintf(buf, "Character levels are bounded between 1 and %d", MAX_LEVEL);
-     PyErr_Format(PyExc_TypeError, buf);
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   charSetLevel(ch, lvl);
-   return 0;
- }
- 
- static int
- PyChar_setroom(PyChar *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete a character's room");
-     return -1;
-   }
- 
-   int vnum = NOWHERE;
- 
-   if(PyRoom_Check(value))
-     vnum = PyRoom_AsVnum(value);
-   else if(PyInt_Check(value))
-     vnum = (int)PyInt_AsLong(value); // hmmm... is this safe?
-   else {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Character's room must be integer an integer value or a "
- 		 "room object.");
-     return -1;
-   }
- 
-   ROOM_DATA *room = worldGetRoom(gameworld, vnum);
-   if(room == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Attempting to move character to nonexistant room, %d.",
- 		 vnum);
-     return -1;
-   }
- 
-   CHAR_DATA *ch;
-   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
-   // only move if we're not already here
-   if(charGetRoom(ch) != room) {
-     char_from_room(ch);
-     char_to_room(ch, room);
- 
-     // if we were on furniture, make sure we dismount it
-     if(charGetFurniture(ch))
-       char_from_furniture(ch);
-   }
- 
-   return 0;
- }
- 
- 
- static PyGetSetDef PyChar_getseters[] = {
-   {"inv", (getter)PyChar_getinv, (setter)NULL,
-    "The objects in the character's inventory", 
-    NULL},
-   {"objs", (getter)PyChar_getinv, (setter)NULL,
-    "The objects in the character's inventory", 
-    NULL},
-   {"name", (getter)PyChar_getname, (setter)PyChar_setname,
-    "the character's name",
-    NULL},
-   {"desc", (getter)PyChar_getdesc, (setter)PyChar_setdesc,
-    "the character's description",
-    NULL},
-   {"rdesc", (getter)PyChar_getrdesc, (setter)PyChar_setrdesc,
-    "the character's room description",
-    NULL},
-   {"level", (getter)PyChar_getlevel, (setter)PyChar_setlevel,
-    "the character's level",
-    NULL},
-   {"sex", (getter)PyChar_getsex, (setter)PyChar_setsex,
-    "the character's sex",
-    NULL},
-   {"race", (getter)PyChar_getrace, (setter)PyChar_setrace,
-    "the character's race",
-    NULL},
-   {"position", (getter)PyChar_getposition, (setter)PyChar_setposition,
-    "the character's position",
-    NULL},
-   {"room", (getter)PyChar_getroom, (setter)PyChar_setroom,
-    "the character's room",
-    NULL},
-   {"on", (getter)PyChar_geton, (setter)PyChar_seton,
-    "The furniture the character is sitting on/at. If the character is not "
-    "on furniture, None is returned. To remove a character from furniture, "
-    "then use None",
-    NULL},
-   {"uid", (getter)PyChar_getuid, (setter)NULL,
-    "the unique identification number",
-    NULL},
-   {"vnum", (getter)PyChar_getvnum, (setter)NULL,
-    "the virtual number for the NPC. Returns -1 for characters.",
-    NULL},
-   {"is_npc", (getter)PyChar_getisnpc, (setter)NULL,
-    "returns 1 if the char is an NPC, and 0 otherwise.",
-    NULL},
-   {"is_pc", (getter)PyChar_getispc, (setter)NULL,
-    "returns 1 if the char is an NPC, and 0 otherwise.",
-    NULL},
- 
-   {NULL}  /* Sentinel */
- };
- 
- 
- 
- //*****************************************************************************
- //
- // comparators, getattr, setattr, and all that other class stuff
- //
- //*****************************************************************************
- 
- //
- // compare one character to another
- //
- static int
- PyChar_compare(PyChar *ch1, PyChar *ch2) {
-   if(ch1->uid == ch2->uid)
-     return 0;
-   else if(ch1->uid < ch2->uid)
-     return -1;
-   else
-     return 1;
- }
- 
- static PyTypeObject PyChar_Type = {
-     PyObject_HEAD_INIT(NULL)
-     0,                         /*ob_size*/
-     "char.Char",               /*tp_name*/
-     sizeof(PyChar),            /*tp_basicsize*/
-     0,                         /*tp_itemsize*/
-     (destructor)PyChar_dealloc,/*tp_dealloc*/
-     0,                         /*tp_print*/
-     0,                         /*tp_getattr*/
-     0,                         /*tp_setattr*/
-     (cmpfunc)PyChar_compare,   /*tp_compare*/
-     0,                         /*tp_repr*/
-     0,                         /*tp_as_number*/
-     0,                         /*tp_as_sequence*/
-     0,                         /*tp_as_mapping*/
-     0,                         /*tp_hash */
-     0,                         /*tp_call*/
-     0,                         /*tp_str*/
-     0,                         /*tp_getattro*/
-     0,                         /*tp_setattro*/
-     0,                         /*tp_as_buffer*/
-     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
-     "Char/Mob objects",        /* tp_doc */
-     0,		               /* tp_traverse */
-     0,		               /* tp_clear */
-     0,		               /* tp_richcompare */
-     0,		               /* tp_weaklistoffset */
-     0,		               /* tp_iter */
-     0,		               /* tp_iternext */
-     PyChar_methods,            /* tp_methods */
-     0,                         /* tp_members */
-     PyChar_getseters,          /* tp_getset */
-     0,                         /* tp_base */
-     0,                         /* tp_dict */
-     0,                         /* tp_descr_get */
-     0,                         /* tp_descr_set */
-     0,                         /* tp_dictoffset */
-     (initproc)PyChar_init,    /* tp_init */
-     0,                         /* tp_alloc */
-     PyChar_new,               /* tp_new */
- };
- 
- 
- 
- //*****************************************************************************
- //
- // the char module
- //
- //*****************************************************************************
- static PyObject *
- PyChar_load_mob(PyObject *self, PyObject *args) {
-   int mob_vnum    = NOBODY, room_vnum = NOWHERE;
-   PyObject *to    = NULL;
- 
-   ROOM_DATA *room  = NULL;
-   OBJ_DATA  *on    = NULL;
-   char  *posname   = NULL;
-   
-   if (!PyArg_ParseTuple(args, "iO|s", &mob_vnum, &to, &posname)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Load char failed - it needs vnum and destination.");
-     return NULL;
-   }
- 
-   // see what we're trying to load to
-   if(PyInt_Check(to))
-     room_vnum = (int)PyInt_AsLong(to);
-   else if(PyRoom_Check(to))
-     room_vnum = (int)PyRoom_AsVnum(to);
-   else if(PyObj_Check(to))
-     on = propertyTableGet(obj_table, PyObj_AsUid(to));
-   else {
-     PyErr_Format(PyExc_TypeError, 
-                     "Load char failed: invalid load-to type.");
-     return NULL;
-   }
- 
-   // check the mob
-   CHAR_DATA *mob_proto = worldGetMob(gameworld, mob_vnum);
-   if(mob_proto == NULL) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Load char failed: mobile number does not exist.");
-     return NULL;
-   }
- 
- 
-   // see if we're loading onto something
-   if(on)
-     room = objGetRoom(on);
-   else
-     room = worldGetRoom(gameworld, room_vnum);
- 
-   if(room == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Load char failed: room does not exist, or furniture is not. "
- 		 "in a room.");
-     return NULL;
-   }
- 
-   // copy the mob, and put it into the game
-   CHAR_DATA *mob = charCopy(mob_proto);
-   char_to_game(mob);
-   char_to_room(mob, room);
- 
-   // now check if we need to put the char onto some furniture
-   // default position is POS_SITTING
-   if(on) {
-     int pos = POS_SITTING;
-     char_to_furniture(mob, on);
-     if(posname)
-       pos = posGetNum(posname);
- 
-     // if the position is none, or greater 
-     // than sitting, default to sitting.
-     if(pos == POS_NONE || poscmp(pos, POS_SITTING) > 0)
-       pos = POS_SITTING;
-     charSetPos(mob, pos);
-   }
-   else if(posname) {
-     int pos = posGetNum(posname);
-     // if it was an invalid name, set it to standing
-     if(pos == POS_NONE)
-       pos = POS_STANDING;
-     charSetPos(mob, pos);
-   }
- 
-   // check for initialization scripts
-   try_scripts(SCRIPT_TYPE_INIT,
- 	      mob, SCRIPTOR_CHAR,
- 	      mob, NULL, room, NULL, NULL, NULL, 0);
- 
-   // create a python object for the new char, and return it
-   PyChar *py_mob = (PyChar *)newPyChar(mob);
-   return Py_BuildValue("O", py_mob);
- }
- 
- 
- static PyObject *
- PyChar_count_mobs(PyObject *self, PyObject *args) {
-   LIST *list = NULL;
-   PyObject *tgt;
-   PyObject *in = NULL;
-   ROOM_DATA *room = NULL;
-   OBJ_DATA  *furniture = NULL;
-   int vnum = NOBODY;
-   char *name = NULL;
- 
-   if (!PyArg_ParseTuple(args, "O|O", &tgt, &in)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "count_mobs failed. No arguments supplied.");
-     return NULL;
-   }
- 
-   // see if we're looking by name or vnum
-   if(PyInt_Check(tgt))
-     vnum = PyInt_AsLong(tgt);
-   else if(PyString_Check(tgt))
-     name = PyString_AsString(tgt);
-   else {
-     PyErr_Format(PyExc_TypeError, 
-                     "count_mobs failed. Invalid target type supplied.");
-     return NULL;
-   }
- 
-   // if we didn't supply something to look in, assume it means the world
-   if(in == NULL)
-     return Py_BuildValue("i", count_chars(NULL, mobile_list,name, vnum, FALSE));
- 
- 
-   // see what we're looking in
-   if(PyInt_Check(in))
-     room = worldGetRoom(gameworld, PyInt_AsLong(in));
-   else if(PyRoom_Check(in))
-     room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
-   else if(PyObj_Check(in))
-     furniture = propertyTableGet(obj_table, PyObj_AsUid(in));
- 
-   // now find the list we're dealing with
-   if(room)      list = roomGetCharacters(room);
-   if(furniture) list = objGetUsers(furniture);
- 
-   if(list == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "count_mobs failed. invalid argument supplied.");
-     return NULL;
-   }
-   
-   return Py_BuildValue("i", count_chars(NULL, list, name, vnum, FALSE));
- }
- 
- 
- static PyMethodDef char_module_methods[] = {
-   { "load_mob", PyChar_load_mob, METH_VARARGS,
-     "load a mobile with the specified vnum to a room." },
-   { "count_mobs", PyChar_count_mobs, METH_VARARGS,
-     "count how many occurances of a mobile there are in the specified scope. "
-     "vnum or name can be used. Vnum -1 counts PCs" },
-   {NULL, NULL, 0, NULL}  /* Sentinel */
- };
- 
- 
- PyMODINIT_FUNC
- init_PyChar(void) 
- {
-     PyObject* m;
- 
-     if (PyType_Ready(&PyChar_Type) < 0)
-         return;
- 
-     m = Py_InitModule3("char", char_module_methods,
-                        "The char module, for all char/mob-related MUD stuff.");
- 
-     if (m == NULL)
-       return;
- 
-     Py_INCREF(&PyChar_Type);
-     PyModule_AddObject(m, "Char", (PyObject *)&PyChar_Type);
- }
- 
- int PyChar_Check(PyObject *value) {
-   return PyObject_TypeCheck(value, &PyChar_Type);
- }
- 
- int PyChar_AsUid(PyObject *ch) {
-   return ((PyChar *)ch)->uid;
- }
- 
- PyObject *
- newPyChar(CHAR_DATA *ch) {
-   PyChar *py_ch = (PyChar *)PyChar_new(&PyChar_Type, NULL, NULL);
-   py_ch->uid = charGetUID(ch);
-   return (PyObject *)py_ch;
- }
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pychar.h nakedmudv1.4/src/modules/scripts/pychar.h
*** nakedmudv1.0/src/modules/scripts/pychar.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pychar.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,21 ****
- #ifndef __PYCHAR_H
- #define __PYCHAR_H
- //*****************************************************************************
- //
- // py_char.h
- //
- // A python extention to allow python scripts to treat MUD characters as an
- // object within the script.
- //
- //*****************************************************************************
- 
- /* initialize characters for use */
- PyMODINIT_FUNC
- init_PyChar(void);
- int PyChar_AsUid(PyObject *ch);
- int PyChar_Check(PyObject *value);
- 
- PyObject *
- newPyChar(CHAR_DATA *ch);
- 
- #endif //__PYCHAR_H
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pymud.c nakedmudv1.4/src/modules/scripts/pymud.c
*** nakedmudv1.0/src/modules/scripts/pymud.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pymud.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,116 ****
- //*****************************************************************************
- //
- // pymud.h
- //
- // a python module that provides some useful utility functions for interacting
- // with the MUD. Includes stuff like global variables, messaging functions,
- // and a whole bunch of other stuff.
- //
- // WORK FOR FUTURE: Our use of Py_INCREF is probably creating a
- //                  memory leak somewhere.
- //
- //*****************************************************************************
- 
- #include <Python.h>
- #include <structmember.h>
- 
- #include <mud.h>
- 
- #include "script.h"
- #include "pyroom.h"
- #include "pychar.h"
- #include "pyobj.h"
- 
- PyObject *globals = NULL;
- 
- 
- //*****************************************************************************
- //
- // GLOBAL VARIABLES
- //
- // the following functions allow scriptors to store/access global variables.
- // globals are stored in a python map, that maps two python objects together.
- // the functions used to interact with globals are:
- //   get_global(key)
- //   set_global(key, val)
- //   erase_global(key)
- //
- //*****************************************************************************
- static PyObject *
- mud_get_global(PyObject *self, PyObject *args) {
-   PyObject *key = NULL;
- 
-   // get the key
-   if (!PyArg_ParseTuple(args, "O", &key)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Could not retrieve global variable - no key provided");
-     return NULL;
-   }
- 
-   PyObject *val = PyDict_GetItem(globals, key);
-   if(val == NULL)
-     val = Py_None;
-   
-   Py_INCREF(val);
-   return val;
- }
- 
- static PyObject *
- mud_set_global(PyObject *self, PyObject *args) {
-   PyObject *key = NULL, *val = NULL;
- 
-   if (!PyArg_ParseTuple(args, "OO", &key, &val)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Could not set global variable - need key and value");
-     return NULL;
-   }
- 
-   //  Py_INCREF(val);
-   PyDict_SetItem(globals, key, val);
-   return Py_BuildValue("i", 1);
- }
- 
- 
- static PyObject *
- mud_erase_global(PyObject *self, PyObject *args) {
-   PyObject *key = NULL;
- 
-   if (!PyArg_ParseTuple(args, "O", &key)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Could not erase global variable - need key");
-     return NULL;
-   }
- 
-   //  Py_INCREF(Py_None);
-   PyDict_SetItem(globals, key, Py_None);
-   return Py_BuildValue("i", 1);
- }
- 
- 
- 
- //*****************************************************************************
- //
- // MUD module
- //
- //*****************************************************************************
- static PyMethodDef mud_module_methods[] = {
-     {"get_global",  mud_get_global, METH_VARARGS,
-      "Get the value of a global variable."},
-     {"set_global",  mud_set_global, METH_VARARGS,
-      "Set the value of a global variable."},
-     {"erase_global",  mud_erase_global, METH_VARARGS,
-      "Erase the value of a global variable."},
-     {NULL, NULL, 0, NULL}        /* Sentinel */
- };
- 
- 
- PyMODINIT_FUNC
- init_PyMud(void) {
-   PyObject *m;
- 
-   globals = PyDict_New();
-   Py_INCREF(globals);
- 
-   m = Py_InitModule3("mud", mud_module_methods,
- 		     "The mud module, for all MUD misc mud utils.");
- }
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pymud.h nakedmudv1.4/src/modules/scripts/pymud.h
*** nakedmudv1.0/src/modules/scripts/pymud.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pymud.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,17 ****
- #ifndef __PYMUD_H
- #define __PYMUD_H
- //*****************************************************************************
- //
- // pymud.h
- //
- // a python module that provides some useful utility functions for interacting
- // with the MUD. Includes stuff like global variables, messaging functions,
- // and a whole bunch of other stuff. Browse pymud.c to see.
- //
- //*****************************************************************************
- 
- /* initialize mud module for use */
- PyMODINIT_FUNC
- init_PyMud(void);
- 
- #endif //__PYMUD_H
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pyobj.c nakedmudv1.4/src/modules/scripts/pyobj.c
*** nakedmudv1.0/src/modules/scripts/pyobj.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pyobj.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,574 ****
- //*****************************************************************************
- //
- // py_char.c
- //
- // A python extention to allow python scripts to treat MUD characters as an
- // object within the script.
- //
- //*****************************************************************************
- 
- #include <Python.h>
- #include <structmember.h>
- 
- #include <mud.h>
- #include <world.h>
- #include <room.h>
- #include <character.h>
- #include <object.h>
- #include <races.h>
- #include <handler.h>
- #include <utils.h>
- 
- #include "script.h"
- #include "pychar.h"
- #include "pyroom.h"
- #include "pyobj.h"
- 
- 
- typedef struct {
-   PyObject_HEAD
-   int uid;
- } PyObj;
- 
- 
- //*****************************************************************************
- //
- // allocation, deallocation, and initialiation
- //
- //*****************************************************************************
- static void
- PyObj_dealloc(PyObj *self) {
-   self->ob_type->tp_free((PyObject*)self);
- }
- 
- static PyObject *
- PyObj_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
-     PyObj *self;
- 
-     self = (PyObj  *)type->tp_alloc(type, 0);
-     self->uid = NOTHING;
-     return (PyObject *)self;
- }
- 
- static int
- PyObj_init(PyObj *self, PyObject *args, PyObject *kwds) {
-   static char *kwlist[] = {"uid", NULL};
-   int uid = NOTHING;
- 
-   // get the universal id
-   if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &uid)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Objects may only be created by uid");
-     return -1;
-   }
- 
-   // make sure a object with the UID exists
-   if(!propertyTableGet(obj_table, uid)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Object with uid, %d, does not exist", uid);
-     return -1;
-   }
- 
-   self->uid = uid;
-   return 0;
- }
- 
- 
- 
- 
- //*****************************************************************************
- //
- // methods and stuff for building the class
- //
- //*****************************************************************************
- static PyMethodDef PyObj_methods[] = {
-     {NULL}  /* Sentinel */
- };
- 
- 
- //*****************************************************************************
- //
- // character attributes - mostly get and set
- //
- //*****************************************************************************
- static PyObject *
- PyObj_getname(PyObj *self, void *closure) {
-   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
-   if(obj != NULL) return Py_BuildValue("s", objGetName(obj));
-   else           return NULL;
- }
- 
- static PyObject *
- PyObj_getdesc(PyObj *self, void *closure) {
-   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
-   if(obj != NULL) return Py_BuildValue("s", objGetDesc(obj));
-   else           return NULL;
- }
- 
- static PyObject *
- PyObj_getrdesc(PyObj *self, void *closure) {
-   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
-   if(obj != NULL) return Py_BuildValue("s", objGetRdesc(obj));
-   else           return NULL;
- }
- 
- static PyObject *
- PyObj_getuid(PyObj *self, void *closure) {
-   return Py_BuildValue("i", self->uid);
- }
- 
- static PyObject *
- PyObj_getvnum(PyObj *self, void *closure) {
-   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
-   if(obj != NULL) return Py_BuildValue("i", objGetVnum(obj));
-   else           return NULL;
- }
- 
- static PyObject *
- PyObj_getcontents(PyObj *self, PyObject *args) {
-   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
-   if(obj == NULL) 
-     return NULL;
- 
-   LIST_ITERATOR *cont_i = newListIterator(objGetContents(obj));
-   PyObject *list = PyList_New(0);
-   OBJ_DATA *cont;
-   
-   // for each obj in the contentory, add it to the Python list
-   ITERATE_LIST(cont, cont_i)
-     PyList_Append(list, newPyObj(cont));
-   deleteListIterator(cont_i);
-   return Py_BuildValue("O", list);
- }
- 
- static PyObject *
- PyObj_getchars(PyObj *self, PyObject *args) {
-   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
-   if(obj == NULL) 
-     return NULL;
- 
-   LIST_ITERATOR *char_i = newListIterator(objGetUsers(obj));
-   PyObject *list = PyList_New(0);
-   CHAR_DATA *ch;
-   
-   // for each obj in the contentory, add it to the Python list
-   ITERATE_LIST(ch, char_i)
-     PyList_Append(list, newPyChar(ch));
-   deleteListIterator(char_i);
-   return Py_BuildValue("O", list);
- }
- 
- 
- //
- // Standard check to make sure the object exists when
- // trying to set a value for it. If successful, assign the
- // object to ch. Otherwise, return -1 (error)
- //
- #define PYOBJ_CHECK_OBJ_EXISTS(uid, obj)                                       \
-   obj = propertyTableGet(obj_table, uid);                                      \
-   if(obj == NULL) {                                                            \
-     PyErr_Format(PyExc_TypeError,                                              \
- 		    "Tried to modify nonexistant object, %d", uid);            \
-     return -1;                                                                 \
-   }                                                                            
- 
- static int
- PyObj_setname(PyObj *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete object's name");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Object names must be strings");
-     return -1;
-   }
- 
-   OBJ_DATA *obj;
-   PYOBJ_CHECK_OBJ_EXISTS(self->uid, obj);
-   objSetName(obj, PyString_AsString(value));
-   return 0;
- }
- 
- static int
- PyObj_setdesc(PyObj *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete object's description");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Object descriptions must be strings");
-     return -1;
-   }
- 
-   OBJ_DATA *obj;
-   PYOBJ_CHECK_OBJ_EXISTS(self->uid, obj);
-   objSetDesc(obj, PyString_AsString(value));
-   return 0;
- }
- 
- static int
- PyObj_setrdesc(PyObj *self, PyObject *value, void *closure) {
-   if (value == NULL) {
-     PyErr_Format(PyExc_TypeError, "Cannot delete object's rdesc");
-     return -1;
-   }
-   
-   if (!PyString_Check(value)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Object rdescs must be strings");
-     return -1;
-   }
- 
-   OBJ_DATA *obj;
-   PYOBJ_CHECK_OBJ_EXISTS(self->uid, obj);
-   objSetRdesc(obj, PyString_AsString(value));
-   return 0;
- }
- 
- 
- static PyGetSetDef PyObj_getseters[] = {
-   {"contents", (getter)PyObj_getcontents, (setter)NULL,
-    "the object's contents",
-    NULL},
-   {"objs", (getter)PyObj_getcontents, (setter)NULL,
-    "the object's contents",
-    NULL},
-   {"chars", (getter)PyObj_getchars, (setter)NULL,
-    "the characters sitting on/riding the object",
-    NULL},
-   {"name", (getter)PyObj_getname, (setter)PyObj_setname,
-    "the object's name",
-    NULL},
-   {"desc", (getter)PyObj_getdesc, (setter)PyObj_setdesc,
-    "the object's description",
-    NULL},
-   {"rdesc", (getter)PyObj_getrdesc, (setter)PyObj_setrdesc,
-    "the object's room description",
-    NULL},
-   {"uid", (getter)PyObj_getuid, (setter)NULL,
-    "the unique identification number",
-    NULL},
-   {"vnum", (getter)PyObj_getvnum, (setter)NULL,
-    "the virtual number for the object.",
-    NULL},
-   {NULL}  /* Sentinel */
- };
- 
- 
- 
- //*****************************************************************************
- //
- // comparators, getattr, setattr, and all that other class stuff
- //
- //*****************************************************************************
- 
- //
- // compare one object to another
- //
- static int
- PyObj_compare(PyObj *obj1, PyObj *obj2) {
-   if(obj1->uid == obj2->uid)
-     return 0;
-   else if(obj1->uid < obj2->uid)
-     return -1;
-   else
-     return 1;
- }
- 
- static PyTypeObject PyObj_Type = {
-     PyObject_HEAD_INIT(NULL)
-     0,                         /*ob_size*/
-     "obj.Obj",                 /*tp_name*/
-     sizeof(PyObj),             /*tp_basicsize*/
-     0,                         /*tp_itemsize*/
-     (destructor)PyObj_dealloc, /*tp_dealloc*/
-     0,                         /*tp_print*/
-     0,                         /*tp_getattr*/
-     0,                         /*tp_setattr*/
-     (cmpfunc)PyObj_compare,    /*tp_compare*/
-     0,                         /*tp_repr*/
-     0,                         /*tp_as_number*/
-     0,                         /*tp_as_sequence*/
-     0,                         /*tp_as_mapping*/
-     0,                         /*tp_hash */
-     0,                         /*tp_call*/
-     0,                         /*tp_str*/
-     0,                         /*tp_getattro*/
-     0,                         /*tp_setattro*/
-     0,                         /*tp_as_buffer*/
-     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
-     "Obj/Obj objects",         /* tp_doc */
-     0,		               /* tp_traverse */
-     0,		               /* tp_clear */
-     0,		               /* tp_richcompare */
-     0,		               /* tp_weaklistoffset */
-     0,		               /* tp_iter */
-     0,		               /* tp_iternext */
-     PyObj_methods,             /* tp_methods */
-     0,                         /* tp_members */
-     PyObj_getseters,           /* tp_getset */
-     0,                         /* tp_base */
-     0,                         /* tp_dict */
-     0,                         /* tp_descr_get */
-     0,                         /* tp_descr_set */
-     0,                         /* tp_dictoffset */
-     (initproc)PyObj_init,      /* tp_init */
-     0,                         /* tp_alloc */
-     PyObj_new,                 /* tp_new */
- };
- 
- 
- 
- //*****************************************************************************
- //
- // the obj module
- //
- //*****************************************************************************
- static PyObject *
- PyObj_load_obj(PyObject *self, PyObject *args) {
-   int obj_vnum = NOBODY;
-   PyObject *in = NULL;
- 
-   ROOM_DATA *room = NULL; // are we loading to a room?
-   OBJ_DATA  *cont = NULL; // are we loading to a container?
-   CHAR_DATA *ch   = NULL; // are we loading to a character?
-   char *equip_to  = NULL; // are we trying to equip the character?
- 
-   if (!PyArg_ParseTuple(args, "iO|s", &obj_vnum, &in, &equip_to)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Load obj failed - it needs a vnum and destination.");
-     return NULL;
-   }
- 
-   // check the obj
-   OBJ_DATA *obj_proto = worldGetObj(gameworld, obj_vnum);
-   if(obj_proto == NULL) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Load obj failed: object number does not exist.");
-     return NULL;
-   }
- 
-   // copy the object
-   OBJ_DATA *obj = objCopy(obj_proto);
- 
- 
-   // figure out what we're trying to load this thing into
-   if(PyInt_Check(in))
-     room = worldGetRoom(gameworld, (int)PyInt_AsLong(in));
-   else if(PyRoom_Check(in))
-     room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
-   else if(PyObj_Check(in))
-     cont = propertyTableGet(obj_table, PyObj_AsUid(in));
-   else if(PyChar_Check(in))
-     ch   = propertyTableGet(mob_table, PyChar_AsUid(in));
- 
- 
-   // figure out where we're trying to load the object to
-   if(room != NULL) {
-     obj_to_game(obj);
-     obj_to_room(obj, room);
-   }
-   else if(cont != NULL) {
-     obj_to_game(obj);
-     obj_to_obj(obj, cont);
-   }
-   else if(ch != NULL) {
-     // see if we're trying to equip the object
-     if(equip_to) {
-       obj_to_game(obj);
-       if(!try_equip(ch, obj, equip_to))
- 	obj_to_char(obj, ch);
-     }
-     else {
-       obj_to_game(obj);
-       obj_to_char(obj, ch);
-     }
-   }
- 
-   // We couldn't figure out the destination!
-   else {
-     PyErr_Format(PyExc_TypeError, 
-                     "Load obj failed: destination does not exist.");
-     return NULL;
-   }
- 
-   // check for initialization scripts
-   try_scripts(SCRIPT_TYPE_INIT,
- 	      obj, SCRIPTOR_OBJ,
- 	      ch, cont, room, NULL, NULL, NULL, 0);
- 
-   // create a python object for the new obj, and return it
-   PyObj *py_obj = (PyObj *)newPyObj(obj);
-   return Py_BuildValue("O", py_obj);
- }
- 
- 
- static PyObject *
- PyObj_count_objs(PyObject *self, PyObject *args) {
-   LIST *list      = NULL;
-   PyObject *tgt;
-   PyObject *in    = NULL;
-   ROOM_DATA *room = NULL;
-   OBJ_DATA  *cont = NULL;
-   CHAR_DATA *ch   = NULL;
-   int vnum = NOTHING;
-   char *name = NULL;
- 
-   if (!PyArg_ParseTuple(args, "O|O", &tgt, &in)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "count_objs failed. No arguments supplied.");
-     return NULL;
-   }
- 
-   // see if we're looking by name or vnum
-   if(PyInt_Check(tgt))
-     vnum = PyInt_AsLong(tgt);
-   else if(PyString_Check(tgt))
-     name = PyString_AsString(tgt);
-   else {
-     PyErr_Format(PyExc_TypeError, 
-                     "count_objs failed. Invalid target type supplied.");
-     return NULL;
-   }
- 
-   // if we didn't supply something to look in, assume it means the world
-   if(in == NULL)
-     return Py_BuildValue("i", count_objs(NULL, object_list, name, vnum, FALSE));
- 
-   // see what we're looking in
-   if(PyInt_Check(in))
-     room = worldGetRoom(gameworld, PyInt_AsLong(in));
-   else if(PyRoom_Check(in))
-     room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
-   else if(PyObj_Check(in))
-     cont = propertyTableGet(obj_table, PyObj_AsUid(in));
-   else if(PyChar_Check(in))
-     ch   = propertyTableGet(mob_table, PyChar_AsUid(in));
- 
-   // now find the list we're dealing with
-   if(room) list = roomGetContents(room);
-   if(cont) list = objGetContents(cont);
-   if(ch)   list = charGetInventory(ch);
- 
-   if(list == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "count_objs failed. invalid argument supplied.");
-     return NULL;
-   }
-   
-   return Py_BuildValue("i", count_objs(NULL, list, name, vnum, FALSE));
- }
- 
- 
- static PyObject *
- PyObj_find_obj(PyObject *self, PyObject *args) {
-   LIST *list           = object_list;
-   PyObject *in         = NULL;
-   ROOM_DATA *room      = NULL;
-   OBJ_DATA  *cont      = NULL;
-   CHAR_DATA *ch        = NULL;
-   CHAR_DATA *looker_ch = NULL;
-   PyObject *looker     = NULL;
-   char *tgt            = NULL;
- 
-   if (!PyArg_ParseTuple(args, "s|OO", &tgt, &in, &looker)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "find_obj failed. No arguments supplied.");
-     return NULL;
-   }
- 
-   // check for scope of search
-   if(in) {
-     if(PyInt_Check(in))
-       room = worldGetRoom(gameworld, PyInt_AsLong(in));
-     else if(PyRoom_Check(in))
-       room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
-     else if(PyObj_Check(in))
-       cont = propertyTableGet(obj_table, PyObj_AsUid(in));
-     else if(PyChar_Check(in))
-       ch   = propertyTableGet(mob_table, PyChar_AsUid(in));
-   }
- 
-   // check to see who's looking
-   if(looker && PyChar_Check(looker))
-     looker_ch = propertyTableGet(mob_table, PyChar_AsUid(looker));
- 
-   // now find the list we're dealing with
-   if(room) list = roomGetContents(room);
-   if(cont) list = objGetContents(cont);
-   if(ch)   list = charGetInventory(ch);
- 
-   // now, do the search
-   int count = 1;
-   char name[SMALL_BUFFER] = "";
-   get_count(tgt, name, &count);
- 
-   // we're just looking for a single item
-   if(count != COUNT_ALL) {
-     OBJ_DATA *obj    = find_obj(looker_ch, list, count, name, NOTHING, 
- 				(looker_ch ? TRUE : FALSE));
-     PyObject *py_obj = Py_None;
-     if(obj) py_obj = newPyObj(obj);
-     return Py_BuildValue("O", py_obj);
-   }
-   // otherwise, return everything that meets our critereon
-   else {
-     //***********
-     // FINISH ME
-     //***********
-     return Py_BuildValue("O", Py_None);
-   }
- }
- 
- 
- 
- static PyMethodDef obj_module_methods[] = {
-   { "load_obj", PyObj_load_obj, METH_VARARGS,
-     "load a object with the specified vnum to a room." },
-   { "count_objs", PyObj_count_objs, METH_VARARGS,
-     "count how many occurances of an object there are in the specified scope. "
-     "vnum or name can be used."},
-   { "find_obj", PyObj_find_obj, METH_VARARGS,
-     "Takes a string argument, and returns the object(s) in the scope that "
-     "correspond to what the string is searching for."},
-   {NULL, NULL, 0, NULL}  /* Sentinel */
- };
- 
- 
- 
- PyMODINIT_FUNC
- init_PyObj(void) 
- {
-     PyObject* m;
- 
-     if (PyType_Ready(&PyObj_Type) < 0)
-         return;
- 
-     m = Py_InitModule3("obj", obj_module_methods,
-                        "The object module, for all object-related MUD stuff.");
- 
-     if (m == NULL)
-       return;
- 
-     Py_INCREF(&PyObj_Type);
-     PyModule_AddObject(m, "Obj", (PyObject *)&PyObj_Type);
- }
- 
- int PyObj_Check(PyObject *value) {
-   return PyObject_TypeCheck(value, &PyObj_Type);
- }
- 
- int PyObj_AsUid(PyObject *obj) {
-   return ((PyObj *)obj)->uid;
- }
- 
- PyObject *
- newPyObj(OBJ_DATA *obj) {
-   PyObj *py_obj = (PyObj *)PyObj_new(&PyObj_Type, NULL, NULL);
-   py_obj->uid = objGetUID(obj);
-   return (PyObject *)py_obj;
- }
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pyobj.h nakedmudv1.4/src/modules/scripts/pyobj.h
*** nakedmudv1.0/src/modules/scripts/pyobj.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pyobj.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,21 ****
- #ifndef __PYOBJ_H
- #define __PYOBJ_H
- //*****************************************************************************
- //
- // pyobj.h
- //
- // A python extention to allow python scripts to treat MUD objects as an
- // object within the script.
- //
- //*****************************************************************************
- 
- /* initialize characters for use */
- PyMODINIT_FUNC
- init_PyObj(void);
- int PyObj_AsUid(PyObject *ch);
- int PyObj_Check(PyObject *value);
- 
- PyObject *
- newPyObj(OBJ_DATA *obj);
- 
- #endif //__PYOBJ_H
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pyroom.c nakedmudv1.4/src/modules/scripts/pyroom.c
*** nakedmudv1.0/src/modules/scripts/pyroom.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pyroom.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,482 ****
- //*****************************************************************************
- //
- // pyroom.c
- //
- // A python extention to allow python scripts to treat MUD characters as an
- // object within the script.
- //
- //*****************************************************************************
- 
- #include <Python.h>
- #include <structmember.h>
- 
- #include <mud.h>
- #include <world.h>
- #include <room.h>
- #include <exit.h>
- #include <character.h>
- #include <races.h>
- #include <handler.h>
- #include <utils.h>
- 
- #include "script.h"
- #include "pyroom.h"
- #include "pychar.h"
- #include "pyobj.h"
- 
- typedef struct {
-   PyObject_HEAD
-   room_vnum vnum;
- } PyRoom;
- 
- 
- //*****************************************************************************
- //
- // allocation, deallocation, and initialiation
- //
- //*****************************************************************************
- static void
- PyRoom_dealloc(PyRoom *self) {
-   self->ob_type->tp_free((PyObject*)self);
- }
- 
- static PyObject *
- PyRoom_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
-     PyRoom *self;
- 
-     self = (PyRoom  *)type->tp_alloc(type, 0);
-     self->vnum = NOWHERE;
-     return (PyObject *)self;
- }
- 
- static int
- PyRoom_init(PyRoom *self, PyObject *args, PyObject *kwds) {
-   static char *kwlist[] = {"vnum", NULL};
-   int vnum = NOWHERE;
- 
-   // get the vnum
-   if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &vnum)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Rooms may only be created using a vnum");
-     return -1;
-   }
- 
-   // make sure a room with the vnum exists
-   if(!worldGetRoom(gameworld, vnum)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Rom with vnum, %d, does not exist", vnum);
-     return -1;
-   }
- 
-   self->vnum = vnum;
-   return 0;
- }
- 
- 
- 
- //*****************************************************************************
- //
- // methods and stuff for building the class
- //
- //*****************************************************************************
- 
- //
- // close a door in the specified direction
- //
- static PyObject *
- PyRoom_close(PyRoom *self, PyObject *value) {
-   ROOM_DATA *room = NULL;
-   EXIT_DATA *exit = NULL;
-   char *dirname = NULL;
-   int dir = DIR_NONE;
- 
-   if (!PyArg_ParseTuple(value, "s", &dirname)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Doornames provided to PyRoom_close must be directions.");
-     return NULL;
-   }
- 
-   room = worldGetRoom(gameworld, self->vnum);
-   if(room == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to close door in non-existant room, %d.", 
- 		 self->vnum);
-     return NULL;
-   }
- 
-   // see if it's a normal exit
-   dir = dirGetNum(dirname);
- 
-   if(dir != DIR_NONE)
-     exit = roomGetExit(room, dir);
-   else
-     exit = roomGetExitSpecial(room, dirname);
- 
-   // make sure the exit exists
-   if(exit == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to close non-existant exit, %s, in room %d.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
- 
-   // make sure the exit can be closed in the first place
-   if(!exitIsClosable(exit)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to close exit, %s, in room %d that is not closable.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
- 
-   exitSetClosed(exit, TRUE);
-   return Py_BuildValue("i", 1);
- }
- 
- 
- //
- // lock a door in the specified direction
- //
- static PyObject *
- PyRoom_lock(PyRoom *self, PyObject *value) {
-   ROOM_DATA *room = NULL;
-   EXIT_DATA *exit = NULL;
-   char *dirname = NULL;
-   int dir = DIR_NONE;
- 
-   if (!PyArg_ParseTuple(value, "s", &dirname)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Doornames provided to PyRoom_lock must be directions.");
-     return NULL;
-   }
- 
-   room = worldGetRoom(gameworld, self->vnum);
-   if(room == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to lock door in non-existant room, %d.", 
- 		 self->vnum);
-     return NULL;
-   }
- 
-   // see if it's a normal exit
-   dir = dirGetNum(dirname);
- 
-   if(dir != DIR_NONE)
-     exit = roomGetExit(room, dir);
-   else
-     exit = roomGetExitSpecial(room, dirname);
- 
-   // make sure the exit exists
-   if(exit == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to lock non-existant exit, %s, in room %d.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
- 
-   // make sure the exit can be closed in the first place
-   if(!exitIsClosable(exit)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to lock exit, %s, in room %d that is not closable.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
-   if(exitGetKey(exit) == NOTHING) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to lock exit, %s, in room %d that is not lockable.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
- 
-   exitSetClosed(exit, TRUE);
-   exitSetLocked(exit, TRUE);
-   return Py_BuildValue("i", 1);
- }
- 
- 
- //
- // lock a door in the specified direction
- //
- static PyObject *
- PyRoom_unlock(PyRoom *self, PyObject *value) {
-   ROOM_DATA *room = NULL;
-   EXIT_DATA *exit = NULL;
-   char *dirname = NULL;
-   int dir = DIR_NONE;
- 
-   if (!PyArg_ParseTuple(value, "s", &dirname)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Doornames provided to PyRoom_unlock must be directions.");
-     return NULL;
-   }
- 
-   room = worldGetRoom(gameworld, self->vnum);
-   if(room == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to unlock door in non-existant room, %d.", 
- 		 self->vnum);
-     return NULL;
-   }
- 
-   // see if it's a normal exit
-   dir = dirGetNum(dirname);
- 
-   if(dir != DIR_NONE)
-     exit = roomGetExit(room, dir);
-   else
-     exit = roomGetExitSpecial(room, dirname);
- 
-   // make sure the exit exists
-   if(exit == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to unlock non-existant exit, %s, in room %d.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
- 
-   // make sure the exit can be closed in the first place
-   if(!exitIsClosable(exit)) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to unlock exit, %s, in room %d that is not closable.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
-   if(exitGetKey(exit) == NOTHING) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to unlock exit, %s, in room %d that is not lockable.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
- 
-   exitSetLocked(exit, FALSE);
-   return Py_BuildValue("i", 1);
- }
- 
- 
- //
- // close a door in the specified direction
- //
- static PyObject *
- PyRoom_open(PyRoom *self, PyObject *value) {
-   ROOM_DATA *room = NULL;
-   EXIT_DATA *exit = NULL;
-   char *dirname = NULL;
-   int dir = DIR_NONE;
- 
-   if (!PyArg_ParseTuple(value, "s", &dirname)) {
-     PyErr_Format(PyExc_TypeError, 
-                     "Doornames provided to PyRoom_open must be directions.");
-     return NULL;
-   }
- 
-   room = worldGetRoom(gameworld, self->vnum);
-   if(room == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to open door in non-existant room, %d.", 
- 		 self->vnum);
-     return NULL;
-   }
- 
- 
-   // see if it's a normal exit
-   dir = dirGetNum(dirname);
- 
-   if(dir != DIR_NONE)
-     exit = roomGetExit(room, dir);
-   else
-     exit = roomGetExitSpecial(room, dirname);
- 
-   // make sure the exit exists
-   if(exit == NULL) {
-     PyErr_Format(PyExc_TypeError, 
- 		 "Tried to open non-existant exit, %s, in room %d.",
- 		 dirname, self->vnum);
-     return NULL;
-   }
- 
-   exitSetClosed(exit, FALSE);
-   exitSetLocked(exit, FALSE);
-   return Py_BuildValue("i", 1);
- }
- 
- 
- 
- static PyMethodDef PyRoom_methods[] = {
-     {"close", (PyCFunction)PyRoom_close, METH_VARARGS,
-      "close a door in the specified direction." },
-     {"open", (PyCFunction)PyRoom_open, METH_VARARGS,
-      "open a door in the specified direction. Unlocks it if neccessary." },
-     {"lock", (PyCFunction)PyRoom_lock, METH_VARARGS,
-      "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." },
-     {NULL}  /* Sentinel */
- };
- 
- 
- //*****************************************************************************
- //
- // character attributes - mostly get and set
- //
- //*****************************************************************************
- static PyObject *
- PyRoom_getvnum(PyRoom *self, void *closure) {
-   ROOM_DATA *room = worldGetRoom(gameworld, self->vnum);
-   if(room != NULL) return Py_BuildValue("i", roomGetVnum(room));
-   else             return NULL;
- }
- 
- static PyObject *
- PyRoom_getcharacters(PyRoom *self, PyObject *args) {
-   ROOM_DATA *room = worldGetRoom(gameworld, self->vnum);
-   if(room == NULL)
-     return NULL;
-   else {
-     LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room));
-     PyObject *list = PyList_New(0);
-     CHAR_DATA *ch;
- 
-     // for each char in the room list, add him to a Python list
-     ITERATE_LIST(ch, char_i)
-       PyList_Append(list, newPyChar(ch));
-     deleteListIterator(char_i);
-     return Py_BuildValue("O", list);
-   }
- }
- 
- static PyObject *
- PyRoom_getcontents(PyRoom *self, PyObject *args) {
-   ROOM_DATA *room = worldGetRoom(gameworld, self->vnum);
-   if(room == NULL)
-     return NULL;
-   else {
-     LIST_ITERATOR *obj_i = newListIterator(roomGetContents(room));
-     PyObject *list = PyList_New(0);
-     OBJ_DATA *obj;
- 
-     // for each obj in the room list, add him to a Python list
-     ITERATE_LIST(obj, obj_i)
-       PyList_Append(list, newPyObj(obj));
-     deleteListIterator(obj_i);
-     return Py_BuildValue("O", list);
-   }
- }
- 
- 
- static PyGetSetDef PyRoom_getseters[] = {
-   {"vnum", (getter)PyRoom_getvnum, (setter)NULL,
-    "The room's vnum", NULL},
-   {"chars", (getter)PyRoom_getcharacters, (setter)NULL,
-    "The characters in the room", NULL},
-   {"objs", (getter)PyRoom_getcontents, (setter)NULL,
-    "The objects in the room", NULL},
-   {"contents", (getter)PyRoom_getcontents, (setter)NULL,
-    "The objects in the room", NULL},
-   {NULL}  /* Sentinel */
- };
- 
- 
- 
- //*****************************************************************************
- //
- // comparators, getattr, setattr, and all that other class stuff
- //
- //*****************************************************************************
- 
- //
- // compare one character to another
- //
- static int
- PyRoom_compare(PyRoom *room1, PyRoom *room2) {
-   if(room1->vnum == room2->vnum)
-     return 0;
-   else if(room1->vnum < room2->vnum)
-     return -1;
-   else
-     return 1;
- }
- 
- static PyTypeObject PyRoom_Type = {
-     PyObject_HEAD_INIT(NULL)
-     0,                         /*ob_size*/
-     "room.Room",               /*tp_name*/
-     sizeof(PyRoom),            /*tp_basicsize*/
-     0,                         /*tp_itemsize*/
-     (destructor)PyRoom_dealloc,/*tp_dealloc*/
-     0,                         /*tp_print*/
-     0,                         /*tp_getattr*/
-     0,                         /*tp_setattr*/
-     (cmpfunc)PyRoom_compare,   /*tp_compare*/
-     0,                         /*tp_repr*/
-     0,                         /*tp_as_number*/
-     0,                         /*tp_as_sequence*/
-     0,                         /*tp_as_mapping*/
-     0,                         /*tp_hash */
-     0,                         /*tp_call*/
-     0,                         /*tp_str*/
-     0,                         /*tp_getattro*/
-     0,                         /*tp_setattro*/
-     0,                         /*tp_as_buffer*/
-     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
-     "Python Room object",      /* tp_doc */
-     0,		               /* tp_traverse */
-     0,		               /* tp_clear */
-     0,		               /* tp_richcompare */
-     0,		               /* tp_weaklistoffset */
-     0,		               /* tp_iter */
-     0,		               /* tp_iternext */
-     PyRoom_methods,            /* tp_methods */
-     0,                         /* tp_members */
-     PyRoom_getseters,          /* tp_getset */
-     0,                         /* tp_base */
-     0,                         /* tp_dict */
-     0,                         /* tp_descr_get */
-     0,                         /* tp_descr_set */
-     0,                         /* tp_dictoffset */
-     (initproc)PyRoom_init,    /* tp_init */
-     0,                         /* tp_alloc */
-     PyRoom_new,               /* tp_new */
- };
- 
- 
- 
- //*****************************************************************************
- //
- // the room module
- //
- //*****************************************************************************
- static PyMethodDef room_module_methods[] = {
-   {NULL, NULL, 0, NULL}  /* Sentinel */
- };
- 
- 
- PyMODINIT_FUNC
- init_PyRoom(void) {
-     PyObject* m;
- 
-     if (PyType_Ready(&PyRoom_Type) < 0)
-         return;
- 
-     m = Py_InitModule3("room", room_module_methods,
-                        "The room module, for all MUD room-related stuff.");
- 
-     if (m == NULL)
-       return;
- 
-     Py_INCREF(&PyRoom_Type);
-     PyModule_AddObject(m, "Room", (PyObject *)&PyRoom_Type);
- }
- 
- int PyRoom_AsVnum(PyObject *room) {
-   return ((PyRoom *)room)->vnum;
- }
- 
- int PyRoom_Check(PyObject *value) {
-   return PyObject_TypeCheck(value, &PyRoom_Type);
- }
- 
- PyObject *
- newPyRoom(ROOM_DATA *room) {
-   PyRoom *py_room = (PyRoom *)PyRoom_new(&PyRoom_Type, NULL, NULL);
-   py_room->vnum = roomGetVnum(room);
-   return (PyObject *)py_room;
- }
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/pyroom.h nakedmudv1.4/src/modules/scripts/pyroom.h
*** nakedmudv1.0/src/modules/scripts/pyroom.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/pyroom.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,22 ****
- #ifndef __PYROOM_H
- #define __PYROOM_H
- //*****************************************************************************
- //
- // pyroom.h
- //
- // A python extention to allow python scripts to treat MUD rooms as an
- // object within the script.
- //
- //*****************************************************************************
- 
- /* initialize characters for use */
- PyMODINIT_FUNC
- init_PyRoom(void);
- 
- int PyRoom_AsVnum(PyObject *room);
- int PyRoom_Check(PyObject *value);
- 
- PyObject *
- newPyRoom(ROOM_DATA *room);
- 
- #endif //__PYROOM_H
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/README nakedmudv1.4/src/modules/scripts/README
*** nakedmudv1.0/src/modules/scripts/README	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/README	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,182 ****
- If you are having problems installing scripts, you will want to read the 
- documentation in src/modules/scripts/Makefile. This file is an explanation of
- how to interact with scripts.
- 
- Scripting is a powerful method for adding character to your MUD. It essentially
- allows you to edit (simple) code that will modify the way rooms, players, and
- objects work. This scripting module uses Python (http://www.python.org) to run
- scripts. It will probably be a good idea to get an understanding of the basic
- python syntax before doing any scripting. Python is a relatively easy language
- to learn - even for non-programmers - and that was why it was chosen as the
- scripting language.
- 
- The scripting module for NakedMud adds a couple things to Python, so that it can
- interact with the different types of data in the MUD (see pychar.c, pyobj.c,
- pyroom.c, and pymud.c). Below is a quick synopsis of the various ways Python
- can work with the MUD's data. For documentation on what specific script types
- are used for, and how, see script.h in this directory.
- 
- 
- 
- ********************************************************************************
- ****************************** PYTHON CHARACTERS *******************************
- ********************************************************************************
- The following variables are accessable on Python characters:
-   ch.inv         return a list of the items in the character's inventory
-   ch.objs        same as ch.inv
-   ch.is_npc      return true or false if the character is an NPC
-   ch.is_pc       return true or false if the character is a PC
-   ch.uid         get the character's unique ID (not settable)
-   ch.name        get/set a character's name
-   ch.desc        get/set a character's description
-   ch.rdesc       get/set a character's room description
-   ch.level       get/set a character's level
-   ch.on          get/set the furniture the character is sitting on
-   ch.vnum        get/set the character's virtual number
-   ch.sex         get/set a character's sex. Sex must be in string form 
-                  (e.g. 'male', 'female', or 'neutral')
-   ch.race        get/set a character's race. Race must be in string form
-                  (e.g. 'human', 'elf', 'dragon')
-   ch.position    get/set a character's position. Position must be in string form
-                  (e.g. 'sitting', 'standing')
-   ch.room        get/set a character's room. When setting, a room, either
-                  a room vnum can be used, or an actual room object (see pyroom).
- 
- 
- The following functions are available for use with Python characters:
-   
- SENDING MESSAGES
- ch.send('message')
- example: ch.send('hello, world!')
- Send a character a text message.
- 
- PERFORMING ACTIONS
- ch.act('command')
- example: ch.act('say hello, world!')
- Force a character to perform a specific action.
- 
- STORING SCRIPT DATA
- ch.setvar('varname', value)
- example: ch.setvar('blackjack_winnings', 100)
- Allows you to store information on a character, regarding stuff that happened
- during the script. These variables save over reboots and crashes. The only
- restriction is that the variables must be integer values.
- 
- RETRIEVING SCRIPT DATA
- ch.getvar('varname')
- example: winnings = ch.getvar('blackjack_winnings')
- Retrieve set data. If the variable has not been set yet, 0 is returned.
- 
- LOADING NEW MOBILES
- load_mob(vnum, to)
- example: new_mob = load_mob(100, 120)
- Load a new mobile to the specified target. The first value is the mob's vnum
- 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
- a vnum if -1 is used, PCs are counted.
- 
- 
- 
- ********************************************************************************
- ******************************** PYTHON OBJECTS ********************************
- ********************************************************************************
- The following variables are accessable on Python mud objects:
-   obj.contents    return a list of the things stored within the object
-   obj.objs        same as obj.contents
-   obj.chars       return the people sitting on the object
-   obj.uid         return the unique ID of the object. Not settable
-   obj.name        get/set the object's name
-   obj.desc        get/set the object's description
-   obj.rdesc       get/set the object's room description
-   obj.vnum        get/set the object's vnum
- 
- 
- The following functions are available for use with Python mud objects:
- LOADING NEW OBJECTS
- load_obj(vnum, where, bodypart = NONE)
- Load an object with the specified vnum to "where". Where can be a container,
- a room, or a character. If a character is provided but a list of bodyparts
- is not, then the object is loaded to inventory. If a list of bodyparts are
- provided, the mobile will try to equip the object to those bodyparts. If, for
- bodyparts, an empty string (e.g. '') is used, then the mobile will try to
- equip the item to the first open, viable slots.
- 
- 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. 
- 
- 
- 
- ********************************************************************************
- ********************************* PYTHON ROOMS *********************************
- ********************************************************************************
- The following variables are accessable on Python rooms:
-   room.chars      return a list of characters in the room
-   room.contents   return a lsit of objects in the room
-   room.objs       same as room.contents
-   room.vnum       return the virtual number of the room
- 
- 
- The following functions are available for use with Python mud objects:
- CLOSING DOORS
- room.close('direction')
- example: room.close('north')
- Try to close the door in a specified direction, if a door and direction exist.
- If the door was previously locked, it is unlocked.
- 
- OPENING DOORS
- room.open('direction')
- example: room.open('east')
- Try to open the door in a specified direction, if a door and direction exist.
- If the door was previously locked, it is unlocked.
- 
- LOCKING DOORS
- room.lock('direction')
- example: room.lock('up')
- Try to lock the door in a specified direction, if a door and direction exist.
- If the door was previously open, it is closed.
- 
- UNLOCKING DOORS
- room.unlock('direction')
- example: room.unlock('down')
- Try to unlock the door in a specified direction, if a door and direction exist.
- 
- 
- 
- ********************************************************************************
- ******************************* GLOBAL VARIABLES *******************************
- ********************************************************************************
- There are times when one might want to save a piece of information, but not
- specifically on a character. Global variables allow for this. In addition,
- global variables can be ANY type of value (string, integer, a character, a
- room, you name it). However, global variables do not save over crashes.
- 
- SETTING GLOBAL VARIABLES
- set_global('key', val)
- example: set_global('bobs_killer', ch)
- Allows you to store the value of a variable globally, which can be accessed
- by other scripts, or by the same script at a later time.
- 
- RETREIVING THE VALUES OF GLOBAL VARIABLES
- get_global('key')
- example: killer = get_global('bobs_killer')
- Retreive the value of a global variable. If the variable has not been set,
- then None is returned.
- 
- ERASING A GLOBAL VARIABLE
- erase_global('key')
- example: erase_global('bobs_killer')
- Erase the value of the global variable. Effectively, this is the same as
- setting the variable's value to None.
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/script.c nakedmudv1.4/src/modules/scripts/script.c
*** nakedmudv1.0/src/modules/scripts/script.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/script.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,690 ****
- //*****************************************************************************
- //
- // script.c
- //
- // All of the information regarding scripts, from the functions to run them
- // and all of the different script types.
- //
- //*****************************************************************************
- 
- // script stuff
- #include <Python.h>
- #include <structmember.h>
- 
- // mud stuff
- #include <mud.h>
- #include <utils.h>
- #include <socket.h>
- #include <character.h>
- #include <room.h>
- #include <object.h>
- #include <storage.h>
- #include <auxiliary.h>
- 
- #include "script.h"
- #include "script_set.h"
- #include "pychar.h"
- #include "pyroom.h"
- #include "pyobj.h"
- #include "pymud.h"
- 
- 
- 
- //*****************************************************************************
- //
- // Auxiliary script data that we need to install into players, objects and
- // rooms. Essentially, this just allows these datastructures to actually have
- // scripts installed on them.
- //
- //*****************************************************************************
- typedef struct script_aux_data {
-   SCRIPT_SET *scripts;    // the set of scripts that we have
- } SCRIPT_AUX_DATA;
- 
- SCRIPT_AUX_DATA *
- newScriptAuxData() {
-   SCRIPT_AUX_DATA *data = malloc(sizeof(SCRIPT_AUX_DATA));
-   data->scripts = newScriptSet();
-   return data;
- }
- 
- void
- deleteScriptAuxData(SCRIPT_AUX_DATA *data) {
-   deleteScriptSet(data->scripts);
-   free(data);
- }
- 
- void
- scriptAuxDataCopyTo(SCRIPT_AUX_DATA *from, SCRIPT_AUX_DATA *to) {
-   copyScriptSetTo(from->scripts, to->scripts);
- }
- 
- SCRIPT_AUX_DATA *
- scriptAuxDataCopy(SCRIPT_AUX_DATA *data) {
-   SCRIPT_AUX_DATA *newdata = newScriptAuxData();
-   scriptAuxDataCopyTo(data, newdata);
-   return newdata;
- }
- 
- SCRIPT_AUX_DATA *
- scriptAuxDataRead(STORAGE_SET *set) {
-   SCRIPT_AUX_DATA  *data = newScriptAuxData();
-   STORAGE_SET_LIST *list = read_list(set, "scripts");
-   STORAGE_SET    *script = NULL;
-   while( (script = storage_list_next(list)) != NULL)
-     scriptSetAdd(data->scripts, read_int(script, "vnum"));
-   return data;
- }
- 
- STORAGE_SET *
- scriptAuxDataStore(SCRIPT_AUX_DATA *data) {
-   STORAGE_SET       *set = new_storage_set();
-   STORAGE_SET_LIST *list = new_storage_list();
-   LIST          *scripts = scriptSetList(data->scripts, SCRIPT_TYPE_ANY);
-   SCRIPT_DATA    *script = NULL;
-   store_list(set, "scripts", list, NULL);
-   while((script = listPop(scripts)) != NULL) {
-     STORAGE_SET *scriptset = new_storage_set();
-     store_int(scriptset, "vnum", scriptGetVnum(script), NULL);
-     storage_list_put(list, scriptset);
-   }
-   deleteList(scripts);
-   return set;
- }
- 
- 
- //*****************************************************************************
- //
- // functions for getting script data from various datastructures
- //
- //*****************************************************************************
- SCRIPT_SET *roomGetScripts(const ROOM_DATA *room) {
-   SCRIPT_AUX_DATA *data = roomGetAuxiliaryData(room, "script_aux_data");
-   return data->scripts;
- }
- 
- void roomSetScripts(ROOM_DATA *room, SCRIPT_SET *scripts) {
-   SCRIPT_AUX_DATA *data = roomGetAuxiliaryData(room, "script_aux_data");
-   if(data->scripts) deleteScriptSet(data->scripts);
-   data->scripts = scripts;
- }
- 
- SCRIPT_SET *objGetScripts(const OBJ_DATA *obj) {
-   SCRIPT_AUX_DATA *data = objGetAuxiliaryData(obj, "script_aux_data");
-   return data->scripts;
- }
- 
- void objSetScripts(OBJ_DATA *obj, SCRIPT_SET *scripts) {
-   SCRIPT_AUX_DATA *data = objGetAuxiliaryData(obj, "script_aux_data");
-   if(data->scripts) deleteScriptSet(data->scripts);
-   data->scripts = scripts;
- }
- 
- SCRIPT_SET *charGetScripts(const CHAR_DATA *ch) {
-   SCRIPT_AUX_DATA *data = charGetAuxiliaryData(ch, "script_aux_data");
-   return data->scripts;
- }
- 
- void charSetScripts(CHAR_DATA *ch, SCRIPT_SET *scripts) {
-   SCRIPT_AUX_DATA *data = charGetAuxiliaryData(ch, "script_aux_data");
-   if(data->scripts) deleteScriptSet(data->scripts);
-   data->scripts = scripts;
- }
- 
- 
- 
- //*****************************************************************************
- //
- // functions 'n such for the script object
- //
- //*****************************************************************************
- struct script_data {
-   script_vnum vnum;
-   int         type;
-   char       *name;
-   char       *args;
-   int      num_arg;
-   char       *code;
- };
- 
- const char *script_type_info[NUM_SCRIPTS] = {
-   "Initialization",
-   "Speech",
-   "Drop",
-   "Give/Receive",
-   "Enter",
-   "Exit",
-   "Command"
- };
- 
- const char *scriptTypeName(int num) {
-   return script_type_info[num];
- }
- 
- SCRIPT_DATA *newScript() {
-   SCRIPT_DATA *script = malloc(sizeof(SCRIPT_DATA));
-   bzero(script, sizeof(*script));
-   
-   script->vnum = NOTHING;
-   script->type = SCRIPT_TYPE_INIT;
- 
-   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;
- }
- 
- STORAGE_SET *scriptStore(SCRIPT_DATA *script) {
-   STORAGE_SET *set = new_storage_set();
-   store_int   (set, "vnum", script->vnum, NULL);
-   store_int   (set, "type", script->type, NULL);
-   store_int   (set, "narg", script->num_arg, NULL);
-   store_string(set, "name", script->name, NULL);
-   store_string(set, "args", script->args, NULL);
-   store_string(set, "code", script->code, NULL);
-   return set;
- }
- 
- 
- SCRIPT_DATA *scriptCopy(SCRIPT_DATA *script) {
-   SCRIPT_DATA *newscript = newScript();
-   scriptCopyTo(script, newscript);
-   return newscript;
- }
- 
- 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;
-   to->num_arg = from->num_arg;
- }
- 
- script_vnum scriptGetVnum(SCRIPT_DATA *script) {
-   return script->vnum;
- }
- 
- int         scriptGetType(SCRIPT_DATA *script) {
-   return script->type;
- }
- 
- int         scriptGetNumArg(SCRIPT_DATA *script) {
-   return script->num_arg;
- }
- 
- const char *scriptGetArgs(SCRIPT_DATA *script) {
-   return script->args;
- }
- 
- const char *scriptGetName(SCRIPT_DATA *script) {
-   return script->name;
- }
- 
- 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) {
-   script->vnum = vnum;
- }
- 
- void scriptSetType(SCRIPT_DATA *script, int type) {
-   script->type = type;
- }
- 
- void scriptSetNumArg(SCRIPT_DATA *script, int num_arg) {
-   script->num_arg = num_arg;
- }
- 
- void scriptSetArgs(SCRIPT_DATA *script, const char *args) {
-   if(script->args) free(script->args);
-   script->args = strdup(args ? args : "");
- }
- 
- void scriptSetName(SCRIPT_DATA *script, const char *name) {
-   if(script->name) free(script->name);
-   script->name = strdup(name ? name : "");
- }
- 
- void scriptSetCode(SCRIPT_DATA *script, const char *code) {
-   if(script->code) free(script->code);
-   script->code = strdup(code ? code : "");
- }
- 
- 
- 
- //*****************************************************************************
- //
- // stuff we need for trying to run scripts
- //
- //*****************************************************************************
- 
- //
- // Toss a script into Python and let it run
- //
- void start_script(char *script) {
-   // we exited with an error! Log it
-   if(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);
-   }
- }
- 
- 
- void init_scripts() {
-   /* initialize python */
-   Py_Initialize();
- 
-   /* initialize modules */
-   init_PyChar();
-   init_PyRoom();
-   init_PyObj();
-   init_PyMud();
- 
- 
-   /* initialize our auxiliary data */
-   auxiliariesInstall("script_aux_data",
- 		     newAuxiliaryFuncs(AUXILIARY_TYPE_ROOM | AUXILIARY_TYPE_OBJ|
- 				       AUXILIARY_TYPE_CHAR,
- 				       newScriptAuxData, deleteScriptAuxData,
- 				       scriptAuxDataCopyTo, scriptAuxDataCopy,
- 				       scriptAuxDataStore, scriptAuxDataRead));
- }
- 
- 
- void finalize_scripts() {
-   Py_Finalize();
- }
- 
- 
- void run_script(const char *script, void *me, int me_type,
- 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit, 
- 		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");
-   //    i += snprintf(buf+i, MAX_SCRIPT - i - 1, "from exit 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));
-   else if(me_type == SCRIPTOR_EXIT)
-     ;
- 
-   // 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);
- }
- 
- 
- void format_script(char **script, int max_len) {
-   // python chokes on carriage returns
-   replace_string(script, "\r", "", TRUE);
- }
- 
- 
- //
- // Control we need to highlight
- //
- const char *control_table[] = {
-   "while",
-   "elif",
-   "else",
-   "def",
-   "for",
-   "if",
-   "in",
-   "is",
-   "and",
-   "or",
-   "not",
-   NULL
- };
- 
- 
- //
- // returns which control string we found. returns
- // -1 if none were found
- //
- int check_for_control(const char *ptr, int i) {
-   int syn_i;
-   for(syn_i = 0; control_table[syn_i] != NULL; syn_i++) {
-     int len = strlen(control_table[syn_i]);
-     // not enough characters for it to exist
-     if(i - len + 1 < 0)
-       continue;
-     // we found it might have found it. Check to make
-     // sure that we are surrounded by spaces or colons
-     if(!strncasecmp(ptr+i-len+1, control_table[syn_i], len)) {
-       // check the left side first
-       if(!(i - len < 0 || isspace(ptr[i-len]) || ptr[i-len] == ':'))
- 	continue;
-       //  and now the right side
-       if(!(ptr+i+1 == '\0' || isspace(ptr[i+1]) || ptr[i+1] == ':'))
- 	continue;
- 
-       return syn_i;
-     }
-   }
- 
-   // didn't find any
-   return -1;
- }
- 
- 
- void script_display(SOCKET_DATA *sock, const char *script, bool show_line_nums){
-   const char *ptr = script;//buffer_string(sock->text_editor);
-   char line[SMALL_BUFFER] = "\0";
-   int  line_num = 1;
-   int  line_i = 0, i = 0;
-   bool in_line_comment = FALSE; // are we displaying a comment?
-   bool in_digit = FALSE;        // are we displaying a digit?
-   bool in_string  = FALSE;      // how about a string?
-   char string_type = '"';       // what kinda string marker is it? ' or " ?
-   int  syn_to_color = -1;       // if we're coloring flow control, which one?
- 
-   for(i = 0; ptr[i] != '\0'; i++) {
-     // take off the color for digits
-     if(in_digit && !isdigit(ptr[i])) {
-       sprintf(line+line_i, "{g");
-       line_i += 2;
-       in_digit = FALSE;
-     } // NO ELSE ... we might need to color something else
- 
-     // transfer over the character
-     line[line_i] = ptr[i];
- 
-     // if the character is a #, color the comment red
-     if(ptr[i] == '#') {
-       sprintf(line+line_i, "{r#");
-       line_i += 3;
-       in_line_comment = TRUE;
-     }
- 
-     // we've found a digit that we have to color in
-     else if(isdigit(ptr[i]) && !in_digit && !in_line_comment && !in_string) {
-       sprintf(line+line_i, "{y%c", ptr[i]);
-       line_i += 3;
-       in_digit = TRUE;
-     }
- 
-     // if we've found a string marker, color/uncolor it
-     else if((ptr[i] == '"' || ptr[i] == '\'') && !in_line_comment &&
- 	    // if we're already coloring a string and the marker
- 	    // types don't match up, then don't worry about it
- 	    !(in_string && string_type != ptr[i])) {
- 
-       if(in_string && ptr[i] == string_type)
- 	sprintf(line+line_i, "\%c{g", string_type);
-       else
- 	sprintf(line+line_i, "{w%c", ptr[i]);
-       
-       line_i += 3;
-       in_string = (in_string + 1) % 2;
-       string_type = ptr[i];
-     }
- 
-     // we've hit a new line
-     else if(ptr[i] == '\n') {
- 
- 	// do we need to show line numbers
- 	char line_num_info[20];
- 	if(show_line_nums)
- 	  sprintf(line_num_info, "{c%2d]  ", line_num);
- 	else
- 	  *line_num_info = '\0';
- 
- 	line[line_i] = '\0';
- 	send_to_socket(sock, "%s{g%s\r\n", line_num_info, line);
- 	*line = '\0';
- 	line_i = 0;
- 	line_num++;
- 	in_line_comment = in_string = FALSE; // reset on newline
-     }
- 
-     // checking while, for, if, else, elif, etc...
-     // this is kinda tricky. We have to backtrack and check some stuff
-     else if(!(in_line_comment || in_digit || in_string) &&
- 	    (syn_to_color = check_for_control(ptr, i)) != -1) {
-       sprintf(line+line_i-strlen(control_table[syn_to_color])+1,
- 	      "{p%s{g", control_table[syn_to_color]);
-       line_i += 5; // the two markers for the color, and one for new character
-     }
- 
-     // didn't find anything of interest
-     else
- 	line_i++;
-   }
- 
-   line[line_i] = '\0';
-   // send the last line
-   if(*line)
-     send_to_socket(sock, "{c%2d]{g  %s\r\n", line_num, line);
-   // there was nothing on the first line
-   else if(line_num == 1)
-     send_to_socket(sock, "The buffer is empty.\r\n");
- 
-   if(ptr[strlen(ptr)-1] != '\n')
-     send_to_socket(sock, "Buffer does not end in newline!\r\n");
- }
- 
- 
- //*****************************************************************************
- //
- // tries for various speech triggers
- //
- //*****************************************************************************
- void try_speech_script_with(CHAR_DATA *ch, CHAR_DATA *listener, char *speech) {
-   LIST *speech_scripts = scriptSetList(charGetScripts(listener), 
- 				       SCRIPT_TYPE_SPEECH);
-   SCRIPT_DATA *script = NULL;
- 
-   while( (script = listPop(speech_scripts)) != NULL) {
-     if(is_keyword(scriptGetArgs(script), speech, FALSE)) {
-       run_script(scriptGetCode(script),
- 		 listener, SCRIPTOR_CHAR,
- 		 ch, NULL, charGetRoom(listener), NULL, NULL, speech, 0);
-     }
-   }
-   deleteList(speech_scripts);
- }
- 
- void try_speech_script(CHAR_DATA *ch, CHAR_DATA *listener, char *speech) {
-   if(listener != NULL)
-     try_speech_script_with(ch, listener, speech);
-   else {
-     LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(charGetRoom(ch)));
-     ITERATE_LIST(listener, char_i)
-       try_speech_script_with(ch, listener, speech);
-     deleteListIterator(char_i);
-   }
- }
- 
- 
- void try_enterance_script(CHAR_DATA *ch, ROOM_DATA *room, 
- 			  EXIT_DATA *exit, const char *dirname) {
-   // check the room
-   try_scripts(SCRIPT_TYPE_ENTER,
- 	      room, SCRIPTOR_ROOM,
- 	      ch, NULL, room, exit, dirname, NULL, 0);
- 
-   // check everyone in the room
-   LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room));
-   CHAR_DATA *greeter = NULL;
-   ITERATE_LIST(greeter, char_i) {
-     if(greeter == ch) 
-       continue;
-     try_scripts(SCRIPT_TYPE_ENTER,
- 		greeter, SCRIPTOR_CHAR,
- 		ch, NULL, room, exit, dirname, NULL, 0);
-   }
-   deleteListIterator(char_i);
- }
- 
- 
- void try_exit_script(CHAR_DATA *ch, ROOM_DATA *room, 
- 		     EXIT_DATA *exit, const char *dirname) {
-   // check the room
-   try_scripts(SCRIPT_TYPE_EXIT,
- 	      room, SCRIPTOR_ROOM,
- 	      ch, NULL, room, exit, dirname, NULL, 0);
- 
-   // check everyone in the room
-   LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room));
-   CHAR_DATA *watcher = NULL;
-   while( (watcher = listIteratorCurrent(char_i)) != NULL) {
-     listIteratorNext(char_i);
-     if(watcher == ch) 
-       continue;
-     try_scripts(SCRIPT_TYPE_EXIT,
- 		watcher, SCRIPTOR_CHAR,
- 		ch, NULL, room, exit, dirname, NULL, 0);
-   }
-   deleteListIterator(char_i);
- }
- 
- 
- int try_command_script(CHAR_DATA *ch, const char *cmd, const char *arg) {
-   int retval = 0;
- 
-   // the room had a command script, and we have
-   // to halt the normal command from going through
-   if(try_scripts(SCRIPT_TYPE_COMMAND,
- 		 charGetRoom(ch), SCRIPTOR_ROOM,
- 		 ch, NULL, charGetRoom(ch), NULL, cmd, arg, 0))
-     retval = 1;
- 
-   // check everyone in the room
-   LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(charGetRoom(ch)));
-   CHAR_DATA *scriptor = NULL;
-   while( (scriptor = listIteratorCurrent(char_i)) != NULL) {
-     listIteratorNext(char_i);
-     if(scriptor == ch) 
-       continue;
-     if(try_scripts(SCRIPT_TYPE_COMMAND,
- 		   scriptor, SCRIPTOR_CHAR,
- 		   ch, NULL, charGetRoom(ch), NULL, cmd, arg, 0))
-       retval = 1;
-   }
-   deleteListIterator(char_i);
-   return retval;
- }
- 
- 
- int try_scripts(int script_type,
- 		void *me, int me_type,
- 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit,
- 		const char *cmd, const char *arg, int narg) {
-   int retval = 0;
-   LIST *scripts = NULL;
-   SCRIPT_DATA *script = NULL;
- 
-   if(me_type == SCRIPTOR_CHAR)
-     scripts = scriptSetList(charGetScripts(me), script_type);
-   if(me_type == SCRIPTOR_ROOM)
-     scripts = scriptSetList(roomGetScripts(me), script_type);
-   if(me_type == SCRIPTOR_OBJ)
-     scripts = scriptSetList(objGetScripts(me), script_type);
-   /*
-   if(me_type == SCRIPTOR_EXIT)
-     scripts = scriptSetGetList(exitGetScripts(me), script_type);
-   */
- 
-   // see if we meet the script requirements
-   while( (script = listPop(scripts)) != NULL) {
-     // make specific checks by script type
-     switch(scriptGetType(script)) {
-     case SCRIPT_TYPE_GIVE:
-     case SCRIPT_TYPE_ENTER:
-     case SCRIPT_TYPE_EXIT:
-       // if the scriptor is a char and narg is 1,
-       // we have to make sure we can see the character
-       // before we run the script
-       if(me_type == SCRIPTOR_CHAR && 
- 	 scriptGetNumArg(script) == 1 &&
- 	 ch && !can_see_person(me, ch))
- 	continue;
-       break;
- 
-     case SCRIPT_TYPE_COMMAND:
-       // if the keyword isn't on our list, continue
-       if(!is_keyword(scriptGetArgs(script), cmd, FALSE))
- 	continue;
-       // if the numeric argument of the script is 1,
-       // we need to switch our retval to 1 and return
-       // it so we know not to carry on with the normal command
-       if(scriptGetNumArg(script) == 1)
- 	retval = 1;
-       break;
- 
-     default:
-       break;
-     }
- 
-     run_script(scriptGetCode(script), me, me_type,
- 	       ch, obj, room, exit, cmd, arg, narg);    
-   }
-   deleteList(scripts);
-   return retval;
- }
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/script.h nakedmudv1.4/src/modules/scripts/script.h
*** nakedmudv1.0/src/modules/scripts/script.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/script.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,273 ****
- #ifndef __SCRIPT_H
- #define __SCRIPT_H
- //*****************************************************************************
- //
- // script.h
- //
- // All of the information regarding scripts, from the functions to run them
- // and all of the different script types.
- //
- //*****************************************************************************
- 
- //
- // This must be put at the top of mud.h so the rest of the MUD knows that
- // we've got the scripts module installed
- // #define MODULE_SCRIPTS
- //
- 
- //*****************************************************************************
- //                            SCRIPT DOCUMENTATION
- //*****************************************************************************
- // SCRIPT_TYPE_INIT
- //   Description:
- //     runs when the scriptor is loaded for the first time, or reset in the
- //     case of rooms.
- //   String Arguments:
- //     None
- //   Numeric Argument:
- //     None
- //   Works with:
- //     rooms, objects, mobiles
- //   Parameters:
- //     me   = ourself
- //     ch   = the character loaded to (if applicable)
- //     room = the room loaded to (if applicable)
- //     obj  = the container loaded to (if applicable)
- 
- //*****************************************************************************
- // SCRIPT_TYPE_SPEECH
- //   Description:
- //     Runs when the scriptor hears a person in the room say something. This
- //     can be through say or ask.
- //   Arguments:
- //     a comma-separated list of keywords that the script triggers off of
- //   Numeric Argument:
- //     None
- //   Works with:
- //     mobiles
- //   Parameters:
- //     me   = ourself
- //     ch   = the person talking
- //     room = the room the speech trigger occured in
- //     arg  = the speech that was said
- 
- //*****************************************************************************
- // SCRIPT_TYPE_DROP
- //   Description:
- //     Runs when the scriptor is dropped (obj) or has something drop to 
- //     it (room)
- //   Arguments:
- //     None
- //   Numeric Argument:
- //     None
- //   Works with:
- //     rooms, objects
- //   Parameters:
- //     me   = ourself
- //     ch   = the character doing the dropping
- //     room = the room dropped to (if applicable) or ourself
- //     obj  = the object that was dropped to us (if applicable) or ourself
- 
- //*****************************************************************************
- // SCRIPT_TYPE_GIVE
- //   Description:
- //     Runs when an object is given to the scriptor, or the scriptor is
- //     given (in the case that the scriptor is an object)
- //   Arguments:
- //     None
- //   Numeric Arguments:
- //     1 if the receiver needs to see the character. 0 otherwise.
- //   Works with:
- //     objects, mobiles
- //   Parameters:
- //     me   = ourself
- //     ch   = the character doing the giving
- //     room = the room the giving is being done in
- //     obj  = the object being given (if applicable) or ourself
- 
- //*****************************************************************************
- // SCRIPT_TYPE_ENTER
- //   Description:
- //     Runs when a character enters the room we are in, or enters us
- //     in the case that we are a room
- //   Arguments:
- //     None
- //   Numeric Arguments:
- //     1 if me (a mob watching) needs to see the character. 0 otherwise
- //   Works with:
- //     rooms, mobiles
- //   Parameters:
- //     me   = ourself
- //     ch   = the character entering the room
- //     room = the room we are in (if applicable) or ourself
- 
- //*****************************************************************************
- // SCRIPT_TYPE_EXIT
- //   Description:
- //     Runs when a character exits a room.
- //   Arguments:
- //     None
- //   Numeric Arguments:
- //     1 if me (a mob watching) needs to see the character. 0 otherwise
- //   Works with:
- //     rooms, mobiles.
- //   Parameters:
- //     me   = ourself
- //     ch   = the character exiting
- //     room = the room being left (if applicable) or ourself
- //     cmd  = the direction that ch left through
- 
- //*****************************************************************************
- // SCRIPT_TYPE_COMMAND
- //   Description:
- //     Runs when a character enters a command in the argument list
- //   Arguments:
- //     A comma-separated list of commands that trigger this script
- //   Numeric Arguments:
- //     0 if the normal command should be followed through with afterwards
- //     1 otherwise
- //   Works with:
- //     rooms, mobiles
- //   Parameters:
- //     me   = ourself
- //     ch   = the person using a command
- //     room = the room the command was issued in
- //     cmd  = the command
- //     arg  = the argument supplied to the command
- 
- //*****************************************************************************
- #define SCRIPT_TYPE_NONE          (-1)
- #define SCRIPT_TYPE_INIT            0 // when the room/mob/obj resets or loads
- #define SCRIPT_TYPE_SPEECH          1 // when someone says a keyword
- #define SCRIPT_TYPE_DROP            2 // when obj is dropped
- #define SCRIPT_TYPE_GIVE            3 // when obj is given
- #define SCRIPT_TYPE_ENTER           4 // when a char enters the room
- #define SCRIPT_TYPE_EXIT            5 // when the character exits the room 
- #define SCRIPT_TYPE_COMMAND         6 // when a command is issued
- #define NUM_SCRIPTS                 7
- 
- 
- const char *scriptTypeName(int num);
- 
- SCRIPT_DATA *newScript   ();
- void         deleteScript(SCRIPT_DATA *script);
- 
- STORAGE_SET *scriptStore(SCRIPT_DATA *script);
- SCRIPT_DATA *scriptRead (STORAGE_SET *set);
- 
- SCRIPT_DATA *scriptCopy(SCRIPT_DATA *script);
- void         scriptCopyTo(SCRIPT_DATA *from, SCRIPT_DATA *to);
- 
- script_vnum scriptGetVnum(SCRIPT_DATA *script);
- int         scriptGetType(SCRIPT_DATA *script);
- int         scriptGetNumArg(SCRIPT_DATA *script);
- 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);
- void scriptSetNumArg(SCRIPT_DATA *script, int num_arg);
- void scriptSetArgs(SCRIPT_DATA *script, const char *args);
- void scriptSetName(SCRIPT_DATA *script, const char *name);
- void scriptSetCode(SCRIPT_DATA *script, const char *code);
- 
- 
- //
- // Functions for accessing auxiliary script data in 
- // rooms, characters, and objects.
- //
- SCRIPT_SET *roomGetScripts(const ROOM_DATA *room);
- void        roomSetScripts(ROOM_DATA *room, SCRIPT_SET *scripts);
- SCRIPT_SET *objGetScripts(const OBJ_DATA *obj);
- void        objSetScripts(OBJ_DATA *obj, SCRIPT_SET *scripts);
- SCRIPT_SET *charGetScripts(const CHAR_DATA *mob);
- void        charSetScripts(CHAR_DATA *mob, SCRIPT_SET *scripts);
- 
- 
- 
- 
- //*****************************************************************************
- //
- // The interface for running scripts
- //
- //*****************************************************************************
- 
- // different types for things that can trigger/have a script
- #define SCRIPTOR_NONE         (-1)
- #define SCRIPTOR_CHAR           0
- #define SCRIPTOR_ROOM           1
- #define SCRIPTOR_OBJ            2
- #define SCRIPTOR_EXIT           3
- 
- //
- // initialize the scripting system
- //
- void init_scripts();
- 
- //
- // Shut scripts down
- //
- void finalize_scripts();
- 
- 
- //
- // start up a script
- //
- void run_script(const char *script, void *me, int me_type,
- 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit, 
- 		const char *cmd, const char *arg, int narg);
- 
- //
- // format a string so that it is a viable script
- //
- void format_script(char **script, int max_len);
- 
- 
- //
- // Show a script to the socket
- //
- void script_display(SOCKET_DATA *sock, const char *script, bool show_line_nums);
- 
- 
- //
- // See if a speech script needs to be triggered. If listener == NULL,
- // everyone in the room is checked. If a listener is provided, then 
- // only the listener is checked
- //
- void try_speech_script(CHAR_DATA *ch, CHAR_DATA *listener, char *speech);
- 
- 
- //
- // Try enterance scripts in the given room (the room itself, and mobs)
- //
- void try_enterance_script(CHAR_DATA *ch, ROOM_DATA *room, 
- 			  EXIT_DATA *exit, const char *dirname);
- 
- //
- // Try exit scripts in the given room (the room itself, and mobs)
- //
- void try_exit_script(CHAR_DATA *ch, ROOM_DATA *room, 
- 		     EXIT_DATA *exit, const char *dirname);
- 
- //
- // Searches for command scripts in the room. If the actual command should
- // be followed through with, returns 0. If the actual command should be
- // prevented, returns 1.
- //
- int  try_command_script(CHAR_DATA *ch, const char *cmd, const char *arg);
- 
- //
- // Check for and run scripts of the given type found on the scriptor.
- // If the return value is non-zero, then whatever function that is checking
- // the script needs to be halted (e.g. if it is a command script, the command
- // parser should not continue checking for a normal command in the command list,
- // if the character is giving an object, the give should not complete, etc...)
- //
- int try_scripts(int script_type,
- 		void *me, int me_type,
- 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit,
- 		const char *cmd, const char *arg, int narg);
- 
- #endif //__SCRIPT_H
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/script_set.c nakedmudv1.4/src/modules/scripts/script_set.c
*** nakedmudv1.0/src/modules/scripts/script_set.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/script_set.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,78 ****
- //*****************************************************************************
- //
- // script_set.c
- //
- // A container of script numbers an object, mob, room, etc... may have. Provides
- // functions to make it easy to extract lists of scripts in the set that conform
- // to certain properties (e.g. all speech scripts, exit scripts, etc).
- //
- //*****************************************************************************
- 
- #include <mud.h>
- #include <utils.h>
- #include <world.h>
- 
- #include "script_set.h"
- #include "script.h"
- 
- 
- struct script_set_data {
-   LIST *script_vnums; // LIST is typically used for pointers, but because
-                       // they are the same number of bits as an int, we can
-                       // use them to store script vnum values as well
- };
- 
- SCRIPT_SET *newScriptSet() {
-   SCRIPT_SET *set = malloc(sizeof(SCRIPT_SET));
-   set->script_vnums = newList();
-   return set;
- }
- 
- void deleteScriptSet(SCRIPT_SET *set) {
-   // we don't have to delete any of the elements in here, since
-   // we are not actually using the list to point to anything
-   deleteList(set->script_vnums);
-   free(set);
- }
- 
- void scriptSetAdd   (SCRIPT_SET *set, script_vnum vnum) {
-   listQueue(set->script_vnums, (void *)vnum);
- }
- 
- void scriptSetRemove(SCRIPT_SET *set, script_vnum vnum) {
-   listRemove(set->script_vnums, (void *)vnum);
- }
- 
- LIST *scriptSetList (SCRIPT_SET *set, int type) {
-   LIST *scripts = newList();
-   int i = 0, script_vnum = NOTHING;
- 
-   //*************************************
-   // USE A LIST ITERATOR TO OPTIMIZE THIS
-   //*************************************
-   for(i = 0; i < listSize(set->script_vnums); i++) {
-     script_vnum = (int)listGet(set->script_vnums, i);
-     SCRIPT_DATA *script = worldGetScript(gameworld, script_vnum);
-     if(script != NULL &&
-        (type == SCRIPT_TYPE_NONE || scriptGetType(script) == type))
-       listPut(scripts, script);
-   }
-   return scripts;
- }
- 
- void copyScriptSetTo(SCRIPT_SET *from, SCRIPT_SET *to) {
-   // clear the "to" list
-   while(listSize(to->script_vnums) > 0)
-     listPop(to->script_vnums);
- 
-   // copy everything over
-   int i;
-   for(i = 0; i < listSize(from->script_vnums); i++)
-     listQueue(to->script_vnums, listGet(from->script_vnums, i));
- }
- 
- SCRIPT_SET *copyScriptSet(SCRIPT_SET *set) {
-   SCRIPT_SET *newset = newScriptSet();
-   copyScriptSetTo(set, newset);
-   return newset;
- }
--- 0 ----
diff -crN nakedmudv1.0/src/modules/scripts/script_set.h nakedmudv1.4/src/modules/scripts/script_set.h
*** nakedmudv1.0/src/modules/scripts/script_set.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/scripts/script_set.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,33 ****
- #ifndef __SCRIPT_SET_H
- #define __SCRIPT_SET_H
- //*****************************************************************************
- //
- // script_set.h
- //
- // A container of script numbers an object, mob, room, etc... may have. Provides
- // functions to make it easy to extract lists of scripts in the set that conform
- // to certain properties (e.g. all speech scripts, exit scripts, etc).
- //
- //*****************************************************************************
- 
- 
- #define SCRIPT_TYPE_ANY           (-1)
- 
- 
- SCRIPT_SET *newScriptSet();
- void deleteScriptSet(SCRIPT_SET *set);
- 
- void scriptSetAdd   (SCRIPT_SET *set, script_vnum vnum);
- void scriptSetRemove(SCRIPT_SET *set, script_vnum vnum);
- 
- void copyScriptSetTo(SCRIPT_SET *from, SCRIPT_SET *to);
- SCRIPT_SET *copyScriptSet(SCRIPT_SET *set);
- 
- //
- // Return a list of all scripts of a certain type the set contains.
- // use SCRIPT_TYPE_ANY for a list of all scripts. LIST must be 
- // deleted after being used. 
- //
- LIST *scriptSetList (SCRIPT_SET *set, int type);
- 
- #endif // __SCRIPT_SET_H
--- 0 ----
diff -crN nakedmudv1.0/src/modules/time/.depend nakedmudv1.4/src/modules/time/.depend
*** nakedmudv1.0/src/modules/time/.depend	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/time/.depend	1969-12-31 18:00:00.000000000 -0600
***************
*** 1 ****
- time.o: time.c mudtime.h
--- 0 ----
diff -crN nakedmudv1.0/src/modules/time/Makefile nakedmudv1.4/src/modules/time/Makefile
*** nakedmudv1.0/src/modules/time/Makefile	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/time/Makefile	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,52 ****
- ###############################################################################
- # Makefile for time
- ###############################################################################
- 
- # compiler to use
- CC = gcc
- 
- 
- ################################################################################
- #
- # Object files that this module generates. This should be the only only thing
- # you need to modify!!!
- #
- ################################################################################
- O_FILES = time.o
- 
- 
- 
- 
- # the top level directory of the MUD. We need to define this 
- # so we can include header files found there
- MUDTOP = ../..
- 
- 
- ################################################################################
- #
- # Libraries and compile-time flags
- #
- ################################################################################
- # flags to use during compilation
- C_FLAGS = -Wall -g -ggdb -O2 -I$(MUDTOP)
- 
- 
- ################################################################################
- # make commands
- ################################################################################
- all: $(O_FILES)
- 	cp *.o $(MUDTOP)
- 
- # make the object files
- .c.o: all
- 	$(CC) -c $(C_FLAGS) $<
- 
- # make dependancies for all of the files
- depend:
- 	$(CC) -MM *.c > .depend
- 
- -include .depend
- 
- clean:
- 	rm -f *.o
- 	rm -f *.*~
--- 0 ----
diff -crN nakedmudv1.0/src/modules/time/mudtime.h nakedmudv1.4/src/modules/time/mudtime.h
*** nakedmudv1.0/src/modules/time/mudtime.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/time/mudtime.h	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,72 ****
- #ifndef __MUDTIME_H
- #define __MUDTIME_H
- //*****************************************************************************
- //
- // mudtime.h
- //
- // A small module for handling time of day in the MUD.
- //
- //*****************************************************************************
- 
- //
- // This must be put at the top of mud.h so the rest of the MUD knows that
- // we've got the time module installed
- // #define MODULE_TIME
- //
- 
- //
- // Set up the time module
- //
- void init_time();
- 
- 
- //
- // what day is it?
- //
- const char *get_day();
- 
- 
- //
- // what month is it?
- //
- const char *get_month();
- 
- 
- //
- // what hour is it
- //
- int get_hour();
- 
- 
- //
- // what year is it?
- //
- int get_year();
- 
- 
- //
- // What period of the day are we in?
- //
- bool is_morning();
- bool is_afternoon();
- bool is_evening();
- bool is_night();
- 
- 
- //
- // 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
--- 0 ----
diff -crN nakedmudv1.0/src/modules/time/time.c nakedmudv1.4/src/modules/time/time.c
*** nakedmudv1.0/src/modules/time/time.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/modules/time/time.c	1969-12-31 18:00:00.000000000 -0600
***************
*** 1,299 ****
- //*****************************************************************************
- //
- // time.c
- //
- // A small module for handling time of day in the MUD.
- //
- //*****************************************************************************
- 
- #include <mud.h>
- #include <utils.h>
- #include <inform.h>
- #include <character.h>
- #include <room.h>
- #include <event.h>
- #include <storage.h>
- #include <auxiliary.h>
- #include "mudtime.h"
- 
- 
- #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?
-   int   num_days;         // how many days are in the month?
-   int   morning_starts;   // what time does morning start at?
-   int   afternoon_starts; // what time does the afternoon start at?
-   int   evening_starts;   // what times does evening start at?
-   int   night_starts;     // what time does the night start at?
- };
- 
- struct day_data {
-   char *name;
- };
- 
- const struct month_data month_info[NUM_MONTHS] = {
-   // month name                 days   morning   afternoon    evening   night
-   { "the month of dawn",          30,        6,         12,        18,     22 },
-   { "the month of light",         30,        4,         10,        19,     23 },
-   { "the month of the moon",      30,        6,         12,        17,     21 },
-   { "the month of twilight",      30,        5,         13,        16,     20 },
- };
- 
- const struct day_data day_info[DAYS_PER_WEEK] = {
-   { "the day of work" },
-   { "the day of play" },
-   { "the day of rest" },
- };
- 
- 
- int curr_hour         = 0; // what hour is it in the day?
- int curr_day_of_week  = 0; // what day of the week is it?
- int curr_day_of_month = 0; // what day is it in the month?
- int curr_month        = 0; // what month is it in the year?
- int curr_year         = 0; // what year is it?
- 
- 
- 
- //*****************************************************************************
- //
- // auxiliary data
- //
- // the time module gives rooms the ability to have different day and night
- // descriptions. Below are the functions required for installing this.
- //
- //*****************************************************************************
- 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 *
- timeAuxDataCopy(TIME_AUX_DATA *data) {
-   TIME_AUX_DATA *newdata = newTimeAuxData();
-   timeAuxDataCopyTo(data, newdata);
-   return newdata;
- }
- 
- STORAGE_SET *timeAuxDataStore(TIME_AUX_DATA *data) {
-   STORAGE_SET *set = new_storage_set();
-   store_string(set, "night_desc", data->night_desc, NULL);
-   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
- //
- //*****************************************************************************
- 
- //
- // Handle the hourly update of our times
- //
- void handle_time_update(void *self, void *data, char *arg) {
-   curr_hour++;
- 
-   if(curr_hour >= HOURS_PER_DAY) {
-     curr_hour = 0;
-     curr_day_of_week++;
-     curr_day_of_month++;
-   }
- 
-   if(curr_day_of_week >= DAYS_PER_WEEK)
-     curr_day_of_week = 0;
- 
-   if(curr_day_of_month >= month_info[curr_month].num_days) {
-     curr_day_of_month = 0;
-     curr_month++;
-   }
- 
-   if(curr_month >= NUM_MONTHS) {
-     curr_month = 0;
-     curr_year++;
-   }
- 
- 
-   // check to see if we've rolled over to a new time of day
-   if(curr_hour == month_info[curr_month].morning_starts)
-     send_outdoors("The morning sun slowly pokes its head up over the eastern horizon.\r\n");
-   if(curr_hour == month_info[curr_month].afternoon_starts)
-     send_outdoors("The sun hangs high overhead as afternoon approaches.\r\n");
-   if(curr_hour == month_info[curr_month].evening_starts)
-     send_outdoors("The sun slowly begins its descent as evening approaches.\r\n");
-   if(curr_hour == month_info[curr_month].night_starts)
-     send_outdoors("The sky goes dark as the sun passes over the western horizon.\r\n");
- 
-   // save our time data to file
-   STORAGE_SET *set = new_storage_set();
-   store_int(set, "hour",         curr_hour,         NULL);
-   store_int(set, "day_of_week",  curr_day_of_week,  NULL);
-   store_int(set, "day_of_month", curr_day_of_month, NULL);
-   store_int(set, "month",        curr_month,        NULL);
-   store_int(set, "year",         curr_year,         NULL);
-   storage_write(set, TIME_FILE);
-   storage_close(set);
- 
-   // throw ourself back into the event queue
-   start_event(NULL,
- 	      TIME_UPDATE_DELAY,
- 	      handle_time_update,
- 	      NULL, NULL, NULL);
- }
- 
- 
- void init_time() {
-   STORAGE_SET *set  = storage_read(TIME_FILE);
-   if(set != NULL) {
-     curr_hour         = read_int(set, "hour");
-     curr_day_of_week  = read_int(set, "day_of_week");
-     curr_day_of_month = read_int(set, "day_of_month");
-     curr_month        = read_int(set, "month");
-     curr_year         = read_int(set, "year");
-     storage_close(set);
-   }
-   else
-     curr_hour = curr_day_of_week = curr_day_of_month = curr_month = curr_year = 0;
- 
- 
-   // add the time command
-   add_cmd("time", NULL, cmd_time, 0, POS_SITTING,  POS_FLYING,
- 	  LEVEL_PLAYER, FALSE);
- 
-   // add night descriptions for rooms
-   auxiliariesInstall("time_aux_data",
- 		     newAuxiliaryFuncs(AUXILIARY_TYPE_ROOM,
- 				       newTimeAuxData, deleteTimeAuxData,
- 				       timeAuxDataCopyTo, timeAuxDataCopy,
- 				       timeAuxDataStore, timeAuxDataRead));
- 
-   // start our time updater
-   start_event(NULL,
- 	      TIME_UPDATE_DELAY,
- 	      handle_time_update,
- 	      NULL, NULL, NULL);
- }
- 
- 
- const char *get_day() {
-   return day_info[curr_day_of_week].name;
- }
- 
- 
- const char *get_month() {
-   return month_info[curr_month].name;
- }
- 
- 
- int get_year() {
-   return curr_year;
- }
- 
- 
- int get_hour() {
-   return curr_hour;
- }
- 
- 
- bool is_morning() {
-   return (curr_hour >= month_info[curr_month].morning_starts &&
- 	  curr_hour <  month_info[curr_month].afternoon_starts);
- }
- 
- 
- bool is_afternoon() {
-   return (curr_hour >= month_info[curr_month].afternoon_starts &&
- 	  curr_hour <  month_info[curr_month].evening_starts);
- }
- 
- 
- bool is_evening() {
-   return (curr_hour >= month_info[curr_month].evening_starts &&
- 	  curr_hour <  month_info[curr_month].night_starts);
- }
- 
- 
- bool is_night() {
-   return (curr_hour >= month_info[curr_month].night_starts ||
- 	  curr_hour <  month_info[curr_month].morning_starts);
- }
- 
- 
- //
- // is it am or pm?
- //
- bool is_am() {
-   return (curr_hour < HOURS_PER_DAY/2);
- }
- 
- 
- //
- // what time is it, am/pm - wise?
- //
- int ampm_hour() {
-   int ampm_time = curr_hour - (is_am() ? 0 : HOURS_PER_DAY/2);
-   if(ampm_time == 0) ampm_time = HOURS_PER_DAY/2;
-   return ampm_time;
- }
- 
- 
- COMMAND(cmd_time) {
-   send_to_char(ch,
- 	       "It is %d o'clock%s during the %s of %s,\r\n"
- 	       "which is the %d%s day of %s, year %d.\r\n",
- 	       (USE_AMPM ? ampm_hour() : curr_hour+1),
- 	       (USE_AMPM ? (is_am() ? " a.m" : " p.m") : ""),
- 	       (is_morning() ? "morning" :
- 		(is_afternoon() ? "afternoon" :
- 		 (is_evening() ? "evening" : "night"))),
- 	       day_info[curr_day_of_week].name,
- 	       curr_day_of_month+1, numth(curr_day_of_month+1),
- 	       month_info[curr_month].name, curr_year);
- }
--- 0 ----
diff -crN nakedmudv1.0/src/movement.c nakedmudv1.4/src/movement.c
*** nakedmudv1.0/src/movement.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/movement.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 21,27 ****
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  
--- 21,27 ----
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  
  
***************
*** 39,49 ****
        message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
  	      exitGetSpecLeave(exit));
      else if(dir != DIR_NONE)
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
! 	      "$n leaves %s.", dirGetName(dir));
      else
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
! 	      "$n leaves.");
  
      char_from_room(ch);
      char_to_room(ch, to);
--- 39,48 ----
        message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
  	      exitGetSpecLeave(exit));
      else if(dir != DIR_NONE)
!       send_around_char(ch, TRUE, "%s leaves %s.\r\n",
! 		       charGetName(ch), dirGetName(dir));
      else
!       send_around_char(ch, TRUE, "%s leaves.\r\n", charGetName(ch));
  
      char_from_room(ch);
      char_to_room(ch, to);
***************
*** 53,63 ****
        message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
  	      exitGetSpecEnter(exit));
      else if(dir != DIR_NONE)
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
! 	      "$n arrives from the %s.", dirGetName(dirGetOpposite(dir)));
      else
!       message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
! 	      "$n has arrived.");
  
      return TRUE;
    }
--- 52,61 ----
        message(ch, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
  	      exitGetSpecEnter(exit));
      else if(dir != DIR_NONE)
!       send_around_char(ch, TRUE, "%s arrives from the %s.\r\n",
! 		       charGetName(ch), dirGetName(dirGetOpposite(dir)));
      else
!       send_around_char(ch, TRUE, "%s has arrived.\r\n", charGetName(ch));
  
      return TRUE;
    }
***************
*** 175,183 ****
    }
    else {
      send_to_char(ch, "You %s.\r\n", posGetActionSelf(pos));
      charSetPos(ch, pos);
-     message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
- 	    "$n %s.", posGetActionOther(pos));
      return TRUE;
    }
  }
--- 173,181 ----
    }
    else {
      send_to_char(ch, "You %s.\r\n", posGetActionSelf(pos));
+     send_around_char(ch, TRUE, "%s %s.\r\n", 
+ 		     charGetName(ch), posGetActionOther(pos));
      charSetPos(ch, pos);
      return TRUE;
    }
  }
***************
*** 188,200 ****
    strip_word(arg, "at");
    strip_word(arg, "on");
  
-   int furniture_type  = FOUND_NONE;
    OBJ_DATA *furniture = generic_find(ch, arg,
  				     FIND_TYPE_OBJ, 
  				     FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				     FALSE, &furniture_type);
    
!   if(!furniture || furniture_type != FOUND_OBJ)
      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");
--- 186,197 ----
    strip_word(arg, "at");
    strip_word(arg, "on");
  
    OBJ_DATA *furniture = generic_find(ch, arg,
  				     FIND_TYPE_OBJ, 
  				     FIND_SCOPE_ROOM | FIND_SCOPE_VISIBLE,
! 				     FALSE, NULL);
    
!   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");
***************
*** 216,231 ****
  	      "$n stands up from $o.");
        char_from_furniture(ch);
      }
!     
!     // now sit down on the new thing
      send_to_char(ch, "You %s %s %s.\r\n",
  		 posGetActionSelf(pos),
  		 (objGetSubtype(furniture) == FURNITURE_ON ? "on" : "at"),
  		 objGetName(furniture));
!     message(ch, NULL, furniture, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
! 	    "$n %s %s $o.",
! 	    posGetActionOther(pos),
! 	    (objGetSubtype(furniture) == FURNITURE_ON ? "on" : "at"));
      char_to_furniture(ch, furniture);
      charSetPos(ch, pos);
      return TRUE;
--- 213,232 ----
  	      "$n stands up from $o.");
        char_from_furniture(ch);
      }
! 
!     // send out messages
!     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
      char_to_furniture(ch, furniture);
      charSetPos(ch, pos);
      return TRUE;
***************
*** 251,258 ****
  COMMAND(cmd_stand) {
    if(charGetPos(ch) == POS_FLYING) {
      send_to_char(ch, "You stop flying.\r\n");
!     message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
! 	    "$n stops flying.");
      charSetPos(ch, POS_STANDING);
    }
    else {
--- 252,258 ----
  COMMAND(cmd_stand) {
    if(charGetPos(ch) == POS_FLYING) {
      send_to_char(ch, "You stop flying.\r\n");
!     send_around_char(ch, TRUE, "%s stops flying.\r\n", charGetName(ch));
      charSetPos(ch, POS_STANDING);
    }
    else {
***************
*** 263,269 ****
  
  COMMAND(cmd_wake) {
    send_to_char(ch, "You stop sleeping and sit up.\r\n");
!   message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR,
! 	  "$n stops sleeping and sits up.");
    charSetPos(ch, POS_SITTING);
  }
--- 263,269 ----
  
  COMMAND(cmd_wake) {
    send_to_char(ch, "You stop sleeping and sit up.\r\n");
!   send_around_char(ch, TRUE, "%s stops sleeping and sits up.\r\n",
! 		   charGetName(ch));
    charSetPos(ch, POS_SITTING);
  }
diff -crN nakedmudv1.0/src/mud.h nakedmudv1.4/src/mud.h
*** nakedmudv1.0/src/mud.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/mud.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 24,29 ****
--- 24,33 ----
  #define MODULE_OLC
  #define MODULE_TIME
  #define MODULE_SCRIPTS
+ #define MODULE_ALIAS
+ #define MODULE_CHAR_VARS
+ #define MODULE_SOCIALS
+ 
  
  //
  // Two modules that I am working on... together, they work similar to KaVir's
***************
*** 221,233 ****
    char           * buf;     /* the buffer it should be stored in        */
  };
  
! #define COMMAND(name)      void name(CHAR_DATA *ch, char *arg, int subcmd)
  void init_commands();
! void show_commands(CHAR_DATA *ch);
  void remove_cmd   (const char *cmd);
  void add_cmd      (const char *cmd, const char *sort_by, void *func, 
  	           int subcmd, int min_pos, int max_pos,
! 	           int min_level, bool interrupts);
  
  
  struct buffer_type
--- 225,242 ----
    char           * buf;     /* the buffer it should be stored in        */
  };
  
! 
! #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, \
! 				     int subcmd, char *arg)
  void init_commands();
! void show_commands(CHAR_DATA *ch, int min_lev, int max_lev);
  void remove_cmd   (const char *cmd);
  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
***************
*** 311,320 ****
  				bool scripts_ok, bool aliases_ok);
  
  /* io.c */
! void    log_string            ( const char *txt, ... );
! void    bug                   ( const char *txt, ... );
  time_t  last_modified         ( char *helpfile );
! char   *read_help_entry       ( const char *helpfile );     /* pointer        */
  char   *fread_line            ( FILE *fp );                 /* pointer        */
  char   *fread_string          ( FILE *fp );                 /* allocated data */
  char   *fread_word            ( FILE *fp );                 /* pointer        */
--- 320,330 ----
  				bool scripts_ok, bool aliases_ok);
  
  /* io.c */
! void    log_string            ( const char *txt, ... ) __attribute__ ((format (printf, 1, 2)));
! void    bug                   ( const char *txt, ... ) __attribute__ ((format (printf, 1, 2)));
  time_t  last_modified         ( char *helpfile );
! char   *read_file             ( const char *file );
! char   *read_help_entry       ( const char *helpfile);
  char   *fread_line            ( FILE *fp );                 /* pointer        */
  char   *fread_string          ( FILE *fp );                 /* allocated data */
  char   *fread_word            ( FILE *fp );                 /* pointer        */
***************
*** 323,328 ****
--- 333,339 ----
  
  /* 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 );
***************
*** 331,345 ****
  void    __buffer_strcat       ( BUFFER *buffer, const char *text );
  void    buffer_free           ( BUFFER *buffer );
  void    buffer_clear          ( BUFFER *buffer );
! int     bprintf               ( BUFFER *buffer, char *fmt, ... );
  const char *buffer_string     ( BUFFER *buffer );
  void    buffer_format         ( BUFFER *buffer, bool indent );
  
- /* help_new.c */
- bool  check_help              ( CHAR_DATA *dMob, char *helpfile );
- void  load_helps              ( void );
- void  add_help                ( HELP_DATA *help );
- 
  /* mccp.c */
  bool  compressStart     ( SOCKET_DATA *dsock, unsigned char teleopt );
  bool  compressEnd       ( SOCKET_DATA *dsock, unsigned char teleopt, bool forced );
--- 342,351 ----
  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 );
  bool  compressEnd       ( SOCKET_DATA *dsock, unsigned char teleopt, bool forced );
***************
*** 355,360 ****
--- 361,368 ----
  void  page_continue         ( SOCKET_DATA *dsock);
  void  page_back             ( SOCKET_DATA *dsock);
  
+ /* help.c */
+ bool check_help(CHAR_DATA *dMob, char *helpfile);
  
  /*******************************
   * End of prototype declartion *
diff -crN nakedmudv1.0/src/object.c nakedmudv1.4/src/object.c
*** nakedmudv1.0/src/object.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/object.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 2,9 ****
  //
  // object.c
  //
! // this contains the implementation of object_data, and all of the functions
! // needed to interact with it.
  //
  //*****************************************************************************
  #include "mud.h"
--- 2,14 ----
  //
  // object.c
  //
! // this contains the basic implementation of the object data structure, and all
! // of the functions needed to interact with it. If you plan on adding any other
! // information to objects, it is strongly suggested you do so through auxiliary
! // data (see auxiliary.h).
! //
! // For a recap, IF YOU PLAN ON ADDING ANY OTHER INFORMATION TO OBJECTS, IT
! // IS STRONGLY SUGGESTED YOU DO SO THROUGH AUXILIARY DATA (see auxiliary.h).
  //
  //*****************************************************************************
  #include "mud.h"
diff -crN nakedmudv1.0/src/object.h nakedmudv1.4/src/object.h
*** nakedmudv1.0/src/object.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/object.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 4,16 ****
  //
  // object.h
  //
! // this is the main interface for working with objects (swords, staves, etc..)
! // contains all of the functions for interacting with the datastructure.
  //
  //*****************************************************************************
  
- 
- 
  OBJ_DATA    *newObj         ();
  void         deleteObj      (OBJ_DATA *obj);
  
--- 4,19 ----
  //
  // object.h
  //
! // Contains the basic interface for working with the object data structure, and
! // the functions needed to interact with it. If you plan on adding any other
! // information to objects, it is strongly suggested you do so through auxiliary
! // data (see auxiliary.h).
! //
! // For a recap, IF YOU PLAN ON ADDING ANY OTHER INFORMATION TO OBJECTS, IT
! // IS STRONGLY SUGGESTED YOU DO SO THROUGH AUXILIARY DATA (see auxiliary.h).
  //
  //*****************************************************************************
  
  OBJ_DATA    *newObj         ();
  void         deleteObj      (OBJ_DATA *obj);
  
***************
*** 81,86 ****
--- 84,90 ----
  void         objPrintBits     (OBJ_DATA *obj, int field, char *buf);
  const char  *objBitGetName    (int field, int bit);
  
+ 
  //*****************************************************************************
  //
  // Bitfields and their bits
***************
*** 96,101 ****
  #define BITFIELD_WORN             2
  #define NUM_WORN_BITS             0
  
- 
- 
  #endif // __OBJECT_H
--- 100,103 ----
diff -crN nakedmudv1.0/src/olc/dedit.c nakedmudv1.4/src/olc/dedit.c
*** nakedmudv1.0/src/olc/dedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/dedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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);
+ }
diff -crN nakedmudv1.0/src/olc/.depend nakedmudv1.4/src/olc/.depend
*** nakedmudv1.0/src/olc/.depend	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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
diff -crN nakedmudv1.0/src/olc/edesc_edit.c nakedmudv1.4/src/olc/edesc_edit.c
*** nakedmudv1.0/src/olc/edesc_edit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/edesc_edit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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);
+ }
diff -crN nakedmudv1.0/src/olc/exedit.c nakedmudv1.4/src/olc/exedit.c
*** nakedmudv1.0/src/olc/exedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/exedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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);
+ }
diff -crN nakedmudv1.0/src/olc/medit.c nakedmudv1.4/src/olc/medit.c
*** nakedmudv1.0/src/olc/medit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/medit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,260 ----
+ //*****************************************************************************
+ //
+ // 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"
+ 		 "{gD) Dialog       {y[{c%8d{y]  {w%s\r\n",
+ 		 charGetVnum(mob),
+ 		 charGetName(mob),
+ 		 charGetMultiName(mob),
+ 		 charGetKeywords(mob),
+ 		 charGetRdesc(mob),
+ 		 charGetMultiRdesc(mob),
+ 		 charGetDesc(mob),
+ 		 raceGetName(charGetRace(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_race_menu(SOCKET_DATA *sock, OLC_DATA *olc) {
+   int i;
+   for(i = 0; i < NUM_RACES; i++)
+     send_to_socket(sock, "%2d) %-20s%s", 
+ 		   i, raceGetName(i), (i % 3 == 2 ?"\r\n":""));
+   if(i % 3 != 0)
+     send_to_socket(sock, "\r\n");
+   send_to_socket(sock,
+ 		 "\r\nPlease select a race: ");
+ }
+ 
+ void medit_main_loop(SOCKET_DATA *sock, OLC_DATA *olc, char *arg) {
+   int next_substate = MEDIT_MAIN;
+ 
+   switch(*arg) {
+   case 'q':
+   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':
+   case 'R':
+     medit_race_menu(sock, olc);
+     next_substate = MEDIT_RACE;
+     break;
+ 
+   case 'd':
+   case 'D':
+     send_to_socket(sock, "Enter new dialog vnum (-1 for none) : ");
+     next_substate = MEDIT_DIALOG;
+     break;
+ 
+ #ifdef MODULE_SCRIPTS
+   case 's':
+   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: {
+     int race = RACE_NONE;
+     if(isdigit(*arg)) race = atoi(arg);
+     else              race = raceGetNum(arg);
+     if(race == RACE_NONE) {
+       send_to_socket(sock, "Invalid race! Try again: ");
+       next_substate = MEDIT_RACE;
+     }
+     else {
+       charSetRace(mob, race);
+       charResetBody(mob);
+     }
+     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);
+ }
diff -crN nakedmudv1.0/src/olc/module.mk nakedmudv1.4/src/olc/module.mk
*** nakedmudv1.0/src/olc/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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
diff -crN nakedmudv1.0/src/olc/oedit.c nakedmudv1.4/src/olc/oedit.c
*** nakedmudv1.0/src/olc/oedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/oedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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);
+ }
diff -crN nakedmudv1.0/src/olc/olc.c nakedmudv1.4/src/olc/olc.c
*** nakedmudv1.0/src/olc/olc.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/olc.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,877 ----
+ //*****************************************************************************
+ //
+ // 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_PLAYER,  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) {
+ 
+ }
+ 
+ 
+ #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
diff -crN nakedmudv1.0/src/olc/olc.h nakedmudv1.4/src/olc/olc.h
*** nakedmudv1.0/src/olc/olc.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/olc.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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
diff -crN nakedmudv1.0/src/olc/redit.c nakedmudv1.4/src/olc/redit.c
*** nakedmudv1.0/src/olc/redit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/redit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,461 ----
+ //*****************************************************************************
+ //
+ // 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;
+   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
+   for(i = 0; i < num_spec_exits; i++)
+     free(room_names[i]);
+   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);
+ }
diff -crN nakedmudv1.0/src/olc/resedit.c nakedmudv1.4/src/olc/resedit.c
*** nakedmudv1.0/src/olc/resedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/resedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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);
+ }
diff -crN nakedmudv1.0/src/olc/scedit.c nakedmudv1.4/src/olc/scedit.c
*** nakedmudv1.0/src/olc/scedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/scedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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
diff -crN nakedmudv1.0/src/olc/socedit.c nakedmudv1.4/src/olc/socedit.c
*** nakedmudv1.0/src/olc/socedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/socedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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
diff -crN nakedmudv1.0/src/olc/ssedit.c nakedmudv1.4/src/olc/ssedit.c
*** nakedmudv1.0/src/olc/ssedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/ssedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 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
diff -crN nakedmudv1.0/src/olc/zedit.c nakedmudv1.4/src/olc/zedit.c
*** nakedmudv1.0/src/olc/zedit.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/olc/zedit.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,148 ----
+ //*****************************************************************************
+ //
+ // 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(*arg) {
+   case 'q':
+   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);
+ }
diff -crN nakedmudv1.0/src/py.out nakedmudv1.4/src/py.out
*** nakedmudv1.0/src/py.out	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/py.out	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,178 ----
+ /sys/block/fd0/dev
+ /sys/block/md0/dev
+ /sys/block/hdc/dev
+ /sys/block/hda/hda3/dev
+ /sys/block/hda/hda2/dev
+ /sys/block/hda/hda1/dev
+ /sys/block/hda/dev
+ /sys/block/ram15/dev
+ /sys/block/ram14/dev
+ /sys/block/ram13/dev
+ /sys/block/ram12/dev
+ /sys/block/ram11/dev
+ /sys/block/ram10/dev
+ /sys/block/ram9/dev
+ /sys/block/ram8/dev
+ /sys/block/ram7/dev
+ /sys/block/ram6/dev
+ /sys/block/ram5/dev
+ /sys/block/ram4/dev
+ /sys/block/ram3/dev
+ /sys/block/ram2/dev
+ /sys/block/ram1/dev
+ /sys/block/ram0/dev
+ /sys/class/sound/adsp/dev
+ /sys/class/sound/audio/dev
+ /sys/class/sound/dsp/dev
+ /sys/class/sound/mixer/dev
+ /sys/class/sound/pcmC0D0c/dev
+ /sys/class/sound/pcmC0D0p/dev
+ /sys/class/sound/pcmC0D1c/dev
+ /sys/class/sound/timer/dev
+ /sys/class/sound/controlC0/dev
+ /sys/class/printer/lp0/dev
+ /sys/class/drm/r128/dev
+ /sys/class/netlink/tap15/dev
+ /sys/class/netlink/tap14/dev
+ /sys/class/netlink/tap13/dev
+ /sys/class/netlink/tap12/dev
+ /sys/class/netlink/tap11/dev
+ /sys/class/netlink/tap10/dev
+ /sys/class/netlink/tap9/dev
+ /sys/class/netlink/tap8/dev
+ /sys/class/netlink/tap7/dev
+ /sys/class/netlink/tap6/dev
+ /sys/class/netlink/tap5/dev
+ /sys/class/netlink/tap4/dev
+ /sys/class/netlink/tap3/dev
+ /sys/class/netlink/tap2/dev
+ /sys/class/netlink/tap1/dev
+ /sys/class/netlink/tap0/dev
+ /sys/class/netlink/dnrtmsg/dev
+ /sys/class/netlink/ip6_fw/dev
+ /sys/class/netlink/route6/dev
+ /sys/class/netlink/arpd/dev
+ /sys/class/netlink/xfrm/dev
+ /sys/class/netlink/nflog/dev
+ /sys/class/netlink/tcpdiag/dev
+ /sys/class/netlink/fwmonitor/dev
+ /sys/class/netlink/usersock/dev
+ /sys/class/netlink/skip/dev
+ /sys/class/netlink/route/dev
+ /sys/class/vc/vcsa7/dev
+ /sys/class/vc/vcs7/dev
+ /sys/class/vc/vcsa6/dev
+ /sys/class/vc/vcs6/dev
+ /sys/class/vc/vcsa5/dev
+ /sys/class/vc/vcs5/dev
+ /sys/class/vc/vcsa4/dev
+ /sys/class/vc/vcs4/dev
+ /sys/class/vc/vcsa3/dev
+ /sys/class/vc/vcs3/dev
+ /sys/class/vc/vcsa2/dev
+ /sys/class/vc/vcs2/dev
+ /sys/class/vc/vcsa1/dev
+ /sys/class/vc/vcs1/dev
+ /sys/class/vc/vcsa/dev
+ /sys/class/vc/vcs/dev
+ /sys/class/mem/kmsg/dev
+ /sys/class/mem/urandom/dev
+ /sys/class/mem/random/dev
+ /sys/class/mem/full/dev
+ /sys/class/mem/zero/dev
+ /sys/class/mem/port/dev
+ /sys/class/mem/null/dev
+ /sys/class/mem/kmem/dev
+ /sys/class/mem/mem/dev
+ /sys/class/input/event1/dev
+ /sys/class/input/event0/dev
+ /sys/class/input/mouse0/dev
+ /sys/class/input/mice/dev
+ /sys/class/misc/device-mapper/dev
+ /sys/class/misc/agpgart/dev
+ /sys/class/misc/rtc/dev
+ /sys/class/tty/ttyS7/dev
+ /sys/class/tty/ttyS6/dev
+ /sys/class/tty/ttyS5/dev
+ /sys/class/tty/ttyS4/dev
+ /sys/class/tty/ttyS3/dev
+ /sys/class/tty/ttyS2/dev
+ /sys/class/tty/ttyS1/dev
+ /sys/class/tty/ttyS0/dev
+ /sys/class/tty/tty63/dev
+ /sys/class/tty/tty62/dev
+ /sys/class/tty/tty61/dev
+ /sys/class/tty/tty60/dev
+ /sys/class/tty/tty59/dev
+ /sys/class/tty/tty58/dev
+ /sys/class/tty/tty57/dev
+ /sys/class/tty/tty56/dev
+ /sys/class/tty/tty55/dev
+ /sys/class/tty/tty54/dev
+ /sys/class/tty/tty53/dev
+ /sys/class/tty/tty52/dev
+ /sys/class/tty/tty51/dev
+ /sys/class/tty/tty50/dev
+ /sys/class/tty/tty49/dev
+ /sys/class/tty/tty48/dev
+ /sys/class/tty/tty47/dev
+ /sys/class/tty/tty46/dev
+ /sys/class/tty/tty45/dev
+ /sys/class/tty/tty44/dev
+ /sys/class/tty/tty43/dev
+ /sys/class/tty/tty42/dev
+ /sys/class/tty/tty41/dev
+ /sys/class/tty/tty40/dev
+ /sys/class/tty/tty39/dev
+ /sys/class/tty/tty38/dev
+ /sys/class/tty/tty37/dev
+ /sys/class/tty/tty36/dev
+ /sys/class/tty/tty35/dev
+ /sys/class/tty/tty34/dev
+ /sys/class/tty/tty33/dev
+ /sys/class/tty/tty32/dev
+ /sys/class/tty/tty31/dev
+ /sys/class/tty/tty30/dev
+ /sys/class/tty/tty29/dev
+ /sys/class/tty/tty28/dev
+ /sys/class/tty/tty27/dev
+ /sys/class/tty/tty26/dev
+ /sys/class/tty/tty25/dev
+ /sys/class/tty/tty24/dev
+ /sys/class/tty/tty23/dev
+ /sys/class/tty/tty22/dev
+ /sys/class/tty/tty21/dev
+ /sys/class/tty/tty20/dev
+ /sys/class/tty/tty19/dev
+ /sys/class/tty/tty18/dev
+ /sys/class/tty/tty17/dev
+ /sys/class/tty/tty16/dev
+ /sys/class/tty/tty15/dev
+ /sys/class/tty/tty14/dev
+ /sys/class/tty/tty13/dev
+ /sys/class/tty/tty12/dev
+ /sys/class/tty/tty11/dev
+ /sys/class/tty/tty10/dev
+ /sys/class/tty/tty9/dev
+ /sys/class/tty/tty8/dev
+ /sys/class/tty/tty7/dev
+ /sys/class/tty/tty6/dev
+ /sys/class/tty/tty5/dev
+ /sys/class/tty/tty4/dev
+ /sys/class/tty/tty3/dev
+ /sys/class/tty/tty2/dev
+ /sys/class/tty/tty1/dev
+ /sys/class/tty/tty0/dev
+ /sys/class/tty/ptmx/dev
+ /sys/class/tty/console/dev
+ /sys/class/tty/tty/dev
+ /dev
+ /initrd/dev
+ /proc/sys/dev
+ /proc/net/dev
+ /lib/modules/2.6.5-1.358/build/include/config/dev
+ /lib/modules/2.6.5-1.358/build/include/config/video/dev
+ /lib/modules/2.6.5-1.358/build/include/config/chr/dev
+ /lib/modules/2.6.5-1.358/build/include/config/blk/dev
+ /usr/X11R6/lib/X11/xkb/symbols/dev
+ /usr/X11R6/lib/X11/xkb/symbols/pc/dev
diff -crN nakedmudv1.0/src/races.c nakedmudv1.4/src/races.c
*** nakedmudv1.0/src/races.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/races.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 21,27 ****
  const struct race_data race_info[NUM_RACES] = {
    { "human", "hum",  BODYTYPE_HUMANOID, TRUE  },
    { "elf",   "elf",  BODYTYPE_HUMANOID, TRUE  },
!   { "dragon", "drg", BODYTYPE_DRAGON,  FALSE  }
  };
  
  bool raceIsForPC(int race) {
--- 21,27 ----
  const struct race_data race_info[NUM_RACES] = {
    { "human", "hum",  BODYTYPE_HUMANOID, TRUE  },
    { "elf",   "elf",  BODYTYPE_HUMANOID, TRUE  },
!   { "dragon","drg",  BODYTYPE_DRAGON,  FALSE  }
  };
  
  bool raceIsForPC(int race) {
diff -crN nakedmudv1.0/src/room.c nakedmudv1.4/src/room.c
*** nakedmudv1.0/src/room.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/room.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 1,9 ****
  //*****************************************************************************
  //
! // room.h
  //
! // the implementation of the room data structure, and its corresponding 
! // functions
  //
  //*****************************************************************************
  
--- 1,13 ----
  //*****************************************************************************
  //
! // room.c
  //
! // the basic implementation of the room data structure. If you plan on adding
! // any other information to rooms, it is strongly suggested you do so through
! // auxiliary data (see auxiliary.h)
! //
! // For a recap, IF YOU PLAN ON ADDING ANY OTHER INFORMATION TO ROOMS, IT
! // IS STRONGLY SUGGESTED YOU DO SO THROUGH AUXILIARY DATA (see auxiliary.h).
  //
  //*****************************************************************************
  
***************
*** 20,26 ****
  
  
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  
--- 24,30 ----
  
  
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  
  
***************
*** 32,40 ****
  struct room_data {
    room_vnum   vnum;              // what vnum are we?
  
!   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
--- 36,44 ----
  struct room_data {
    room_vnum   vnum;              // what vnum are we?
  
!   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
***************
*** 111,117 ****
      deleteHashIterator(hash_i);
    }
  
- 
    // delete strings
    if(room->name)        free(room->name);
    if(room->desc)        free(room->desc);
--- 115,120 ----
diff -crN nakedmudv1.0/src/room.h nakedmudv1.4/src/room.h
*** nakedmudv1.0/src/room.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/room.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 4,28 ****
  //
  // room.h
  //
! // the interface for working with the room structure.
  //
  //*****************************************************************************
  
! 
! 
! #define DIR_NONE       (-1)
! #define DIR_NORTH         0
! #define DIR_EAST          1
! #define DIR_SOUTH         2
! #define DIR_WEST          3
! #define DIR_UP            4
! #define DIR_DOWN          5
! #define DIR_NORTHEAST     6
! #define DIR_SOUTHEAST     7
! #define DIR_SOUTHWEST     8
! #define DIR_NORTHWEST     9
! #define NUM_DIRS         10
! 
  
  #define TERRAIN_NONE         (-1)
  #define TERRAIN_INDOORS         0	
--- 4,32 ----
  //
  // room.h
  //
! // the basic interface for working with the room structure.
! //
! // the basic interface for working with the room data structure. If you plan on
! // adding any other information to rooms, it is strongly suggested you do so
! // through auxiliary data (see auxiliary.h)
! //
! // For a recap, IF YOU PLAN ON ADDING ANY OTHER INFORMATION TO ROOMS, IT
! // IS STRONGLY SUGGESTED YOU DO SO THROUGH AUXILIARY DATA (see auxiliary.h).
  //
  //*****************************************************************************
  
! #define DIR_NONE             (-1)
! #define DIR_NORTH               0
! #define DIR_EAST                1
! #define DIR_SOUTH               2
! #define DIR_WEST                3
! #define DIR_UP                  4
! #define DIR_DOWN                5
! #define DIR_NORTHEAST           6
! #define DIR_SOUTHEAST           7
! #define DIR_SOUTHWEST           8
! #define DIR_NORTHWEST           9
! #define NUM_DIRS               10
  
  #define TERRAIN_NONE         (-1)
  #define TERRAIN_INDOORS         0	
***************
*** 35,54 ****
  #define TERRAIN_UNDERWATER	7	
  #define TERRAIN_FIELD           8	
  #define TERRAIN_PLAINS          9 
! #define TERRAIN_MEADOW          10
! #define TERRAIN_FOREST          11
! #define TERRAIN_DEEP_FOREST     12 
! #define TERRAIN_HILLS           13
! #define TERRAIN_HIGH_HILLS      14
! #define TERRAIN_MOUNTAIN        15
! #define TERRAIN_SWAMP           16 
! #define TERRAIN_DEEP_SWAMP      17
! #define TERRAIN_SAND            18 
! #define TERRAIN_DESERT          19
! #define TERRAIN_ICE             20
! #define TERRAIN_GLACIER         21
! #define TERRAIN_CAVERN          22
! #define NUM_TERRAINS            23
  
  
  //
--- 39,58 ----
  #define TERRAIN_UNDERWATER	7	
  #define TERRAIN_FIELD           8	
  #define TERRAIN_PLAINS          9 
! #define TERRAIN_MEADOW         10
! #define TERRAIN_FOREST         11
! #define TERRAIN_DEEP_FOREST    12 
! #define TERRAIN_HILLS          13
! #define TERRAIN_HIGH_HILLS     14
! #define TERRAIN_MOUNTAIN       15
! #define TERRAIN_SWAMP          16 
! #define TERRAIN_DEEP_SWAMP     17
! #define TERRAIN_SAND           18 
! #define TERRAIN_DESERT         19
! #define TERRAIN_ICE            20
! #define TERRAIN_GLACIER        21
! #define TERRAIN_CAVERN         22
! #define NUM_TERRAINS           23
  
  
  //
diff -crN nakedmudv1.0/src/scripts/.depend nakedmudv1.4/src/scripts/.depend
*** nakedmudv1.0/src/scripts/.depend	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,7 ----
+ pychar.o: pychar.c script.h pychar.h pyroom.h pyobj.h
+ pymud.o: pymud.c script.h pyroom.h pychar.h pyobj.h
+ pyobj.o: pyobj.c script.h pychar.h pyroom.h pyobj.h
+ pyroom.o: pyroom.c script.h pyroom.h pychar.h pyobj.h
+ script.o: script.c script.h script_set.h pychar.h pyroom.h pyobj.h \
+   pymud.h
+ script_set.o: script_set.c script_set.h script.h
Binary files nakedmudv1.0/src/scripts/.DS_Store and nakedmudv1.4/src/scripts/.DS_Store differ
diff -crN nakedmudv1.0/src/scripts/module.mk nakedmudv1.4/src/scripts/module.mk
*** nakedmudv1.0/src/scripts/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,116 ----
+ ################################################################################
+ #
+ # Python scripting stuff.
+ #
+ # To embed python as a scripting language, you will probably have to toy around
+ # with the make process. Sadly, this process can be very different from computer
+ # to computer. I've tried to set the defaults to what I've seen to be the most
+ # common settings, but chances are you will have to tweak a couple things in
+ # this file. There are three variables in this makefile you will have to edit.
+ # They are PYTHONTOP, LIBS, and C_FLAGS. I'll try to walk you through 
+ # everything you'll need to do to get these variables all proper-like:
+ #
+ # STEP 1: Locating Python
+ #   Figure out where your python directory is. If you do not know how to do
+ #   this, you can do a "find" from your shell:
+ #     find / -name "Python.h" -print
+ #
+ #   wait for the path to Python.h to show up. You'll have to doctor it a bit;
+ #   from the path, you will want to figure out the top directory for python, and
+ #   where all of the header files are located. If the path looks something like:
+ #     /usr/lib/python2.4/include/Python.h
+ #
+ #   PYTHONTOP would be /usr/lib/python2.4
+ #   and C_FLAGS should include -I$(PYTHONTOP)/include
+ #
+ #   If you are not running Python v2.4 or newer, it is strongly suggested you
+ #   upgrade before continuing (see http://www.python.org).
+ #
+ #
+ # STEP 2: Getting the linking requirements for python.
+ #   This is a relatively easy step; start up python (from shell, type "python")
+ #   and do this:
+ #
+ #   >>> import distutils.sysconfig
+ #   >>> distutils.sysconfig.get_config_var('LINKFORSHARED')
+ #
+ #   a string will print that looks something like:
+ #   '-Xlinker -export-dynamic'
+ #
+ #   copy this string (minus the two surrounding ') to the LIBS variable at the
+ #   end of this makefile.
+ #
+ #
+ # STEP 3: Compiling
+ #   Try compiling. If you get a bunch of errors, go onto step 4.
+ #
+ #
+ # STEP 4: Finding the runtime library.
+ #   Some operating systems will require that you take extra steps to link in 
+ #   the python runtime library. This is the step people seem to be having most
+ #   trouble with, so you may want to pay special attention to this step. What
+ #   you are going to need to do is find the location of your python runtime 
+ #   library and add it to the LIBS variable like you did for the other 
+ #   libraries in step 2. Change your directory to PYTHONTOP and type:
+ #     find . -name "libpython*a" -print
+ #
+ #   When it spits out the address to the python library, add a string like this
+ #   to the LIBs variable at the bottom of this file:
+ #     -L/<path> -lpythonXXX
+ #
+ #   Where <path> is the path to the library (minus the library file itself), 
+ #   and XXX is the version number of your python. So, for instance, on my
+ #   computer, I had to add the following line to LIBS:
+ #     -L/usr/local/lib/python2.4/config -lpython2.4
+ #
+ #   If this is not working for you, there are other ways to link in the Python
+ #   runtime library. For instance, you might be able to simply add the whole
+ #   pathname of the library to your LIBS variable. The above example would
+ #   translate into:
+ #     /usr/local/lib/python2.4/config/libpython2.4.a
+ #
+ #   There are many ways to skin this cat. Google should be able to provide you
+ #   with a couple others if these two are not working for you. I would also be
+ #   more than willing to assist you if you are running into problems.
+ #
+ #   At this point, you should attempt to compile your code. If you are still
+ #   getting errors, move on to step 5.
+ #
+ # 
+ # STEP 5: Adding more libraries.
+ #   Still won't compile? You may need to add some extra libraries that Python
+ #   requires. These are usually quite easy to find; if you are getting messages
+ #   messages like "undefined references to sin", "undefined reference to
+ #   pthread_start" etc... you will want to add the libraries that these 
+ #   functions belong to. for each one that comes up, do a "man XXX" and read
+ #   the man file until you figure out which library the function belongs to.
+ #   Ones that I found were neccessary for me to include on Fedora were -lm,
+ #   -lutil and -ldl . This, of course, will vary from OS to OS. Add all of the
+ #   libraries you need to the end of LIBS, where you put the libraries from
+ #   STEP 2. Try Recompiling. If things still aren't working for you, proceed
+ #   to STEP 6. If things ARE working, I would really appreciate an email
+ #   describing what your module.mk ended up looking like, and what operating
+ #   system you use. Help save the next NakedMud user from going through all of
+ #   the arduous work you just did!
+ #
+ #
+ # STEP 6: On your own
+ #   If you've gotten to this step, I don't really have much more to say. I 
+ #   would suggest finding some Python BBs and explaining your problem. Perhaps
+ #   someone a bit more experienced will be able to help out.
+ #
+ ################################################################################
+ 
+ # Object files we generate
+ SRC      += scripts/script_set.c scripts/script.c scripts/pychar.c \
+ 	    scripts/pyobj.c scripts/pymud.c scripts/pyroom.c \
+ 	    scripts/script_editor.c scripts/script_edit.c
+ 
+ # the top level directory of python
+ PYTHONTOP = /usr/local/include
+ 
+ # the folder where python headers are located
+ C_FLAGS  += -I$(PYTHONTOP)/python2.4
+ 
+ # libraries we have to include
+ LIBS     += -Xlinker -export-dynamic -lm -ldl -lutil -L/usr/local/lib/python2.4/config -lpython2.4
diff -crN nakedmudv1.0/src/scripts/pychar.c nakedmudv1.4/src/scripts/pychar.c
*** nakedmudv1.0/src/scripts/pychar.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pychar.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,920 ----
+ //*****************************************************************************
+ //
+ // py_char.c
+ //
+ // A python extention to allow python scripts to treat MUD characters as an
+ // object within the script.
+ //
+ //*****************************************************************************
+ 
+ #include <Python.h>
+ #include <structmember.h>
+ 
+ #include "../mud.h"
+ #include "../world.h"
+ #include "../room.h"
+ #include "../character.h"
+ #include "../object.h"
+ #include "../items.h"
+ #include "../races.h"
+ #include "../handler.h"
+ #include "../utils.h"
+ 
+ #include "script.h"
+ #include "pychar.h"
+ #include "pyroom.h"
+ #include "pyobj.h"
+ 
+ // optional modules
+ #ifdef MODULE_CHAR_VARS
+ #include "../char_vars/char_vars.h"
+ #endif
+ 
+ 
+ typedef struct {
+   PyObject_HEAD
+   int uid;
+ } PyChar;
+ 
+ 
+ //*****************************************************************************
+ //
+ // allocation, deallocation, and initialiation
+ //
+ //*****************************************************************************
+ static void
+ PyChar_dealloc(PyChar *self) {
+   self->ob_type->tp_free((PyObject*)self);
+ }
+ 
+ static PyObject *
+ PyChar_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
+     PyChar *self;
+ 
+     self = (PyChar  *)type->tp_alloc(type, 0);
+     self->uid = NOBODY;//NULL;
+     return (PyObject *)self;
+ }
+ 
+ static int
+ PyChar_init(PyChar *self, PyObject *args, PyObject *kwds) {
+   static char *kwlist[] = {"uid", NULL};
+   int uid = NOBODY;
+ 
+   // get the universal id
+   if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &uid)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Characters may only be created by uid");
+     return -1;
+   }
+ 
+   // make sure a character with the UID exists
+   if(!propertyTableGet(mob_table, uid)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character with uid, %d, does not exist", uid);
+     return -1;
+   }
+ 
+   self->uid = uid;
+   return 0;
+ }
+ 
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // methods and stuff for building the class
+ //
+ //*****************************************************************************
+ 
+ //
+ // sends a newline-tagged message to the character
+ //
+ static PyObject *
+ PyChar_send(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_to_char(ch, "%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 *
+ PyChar_act(PyChar *self, PyObject *value) {
+   int scripts_ok     = TRUE;
+   char *act          = NULL;
+   if (!PyArg_ParseTuple(value, "s|i", &act, &scripts_ok)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Characters actions must be strings.");
+     return NULL;
+   }
+ 
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch) {
+     do_cmd(ch, act, scripts_ok, FALSE);
+     return Py_BuildValue("i", 1);
+   }
+   else {
+     PyErr_Format(PyExc_TypeError, 
+                     "Nonexistant character, %d, tried to perform an action.", 
+ 		    self->uid);
+     return NULL;
+   }
+ }
+ 
+ 
+ #ifdef MODULE_CHAR_VARS
+ //
+ // Get the value of a variable stored on the character
+ //
+ static PyObject *
+ PyChar_getvar(PyChar *self, PyObject *arg) {
+   char *var = NULL;
+   if (!PyArg_ParseTuple(arg, "s", &var)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character variables must have string names.");
+     return NULL;
+   }
+ 
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) {
+     int vartype = charGetVarType(ch, var);
+     if(vartype == CHAR_VAR_INT)
+       return Py_BuildValue("i", charGetInt(ch, var));
+     else if(vartype == CHAR_VAR_LONG)
+       return Py_BuildValue("i", charGetLong(ch, var));
+     else if(vartype == CHAR_VAR_DOUBLE)
+       return Py_BuildValue("d", charGetDouble(ch, var));
+     else
+       return Py_BuildValue("s", charGetString(ch, var));
+   }
+   else {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to get a variable value for nonexistant character, %d",
+ 		 self->uid);
+     return NULL;
+   }
+ }
+ 
+ 
+ //
+ // Set the value of a variable assocciated with the character
+ //
+ static PyObject *
+ PyChar_setvar(PyChar *self, PyObject *args) {  
+   char     *var = NULL;
+   PyObject *val = NULL;
+ 
+   if (!PyArg_ParseTuple(args, "sO", &var, &val)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Character setvar must be supplied with a var name and integer value.");
+     return NULL;
+   }
+ 
+ 
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) {
+     if(PyInt_Check(val))
+       charSetInt(ch, var, (int)PyInt_AsLong(val));
+     else if(PyFloat_Check(val))
+       charSetDouble(ch, var, PyFloat_AsDouble(val));
+     else if(PyString_Check(val))
+       charSetString(ch, var, PyString_AsString(val));
+     else {
+       PyErr_Format(PyExc_TypeError,
+ 		   "Tried to store a char_var of invalid type on char %d.",
+ 		   self->uid);
+       return NULL;
+     }
+     return Py_BuildValue("i", 1);
+   }
+   else {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to set a variable value for nonexistant character, %d",
+ 		 self->uid);
+     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 */
+ };
+ 
+ 
+ //*****************************************************************************
+ //
+ // character attributes - mostly get and set
+ //
+ //*****************************************************************************
+ static PyObject *
+ PyChar_getname(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("s", charGetName(ch));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getdesc(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("s", charGetDesc(ch));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getrdesc(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("s", charGetRdesc(ch));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getrace(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("s", raceGetName(charGetRace(ch)));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getlevel(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("i", charGetLevel(ch));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getsex(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("s", sexGetName(charGetSex(ch)));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getposition(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("s", posGetName(charGetPos(ch)));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getroom(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("O", newPyRoom(charGetRoom(ch)));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getisnpc(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("i", charIsNPC(ch));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getispc(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("i", !charIsNPC(ch));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_geton(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch == NULL) 
+     return NULL;
+   else if(charGetFurniture(ch) == NULL)
+     return Py_None;
+   else 
+     return Py_BuildValue("i", newPyObj(charGetFurniture(ch)));
+ }
+ 
+ static PyObject *
+ PyChar_getuid(PyChar *self, void *closure) {
+   return Py_BuildValue("i", self->uid);
+ }
+ 
+ 
+ static PyObject *
+ PyChar_getvnum(PyChar *self, void *closure) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch != NULL) return Py_BuildValue("i", charGetVnum(ch));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyChar_getinv(PyChar *self, PyObject *args) {
+   CHAR_DATA *ch = propertyTableGet(mob_table, self->uid);
+   if(ch == NULL) 
+     return NULL;
+ 
+   LIST_ITERATOR *inv_i = newListIterator(charGetInventory(ch));
+   PyObject *list = PyList_New(0);
+   OBJ_DATA *obj;
+   
+   // for each obj in the inventory, add it to the Python list
+   ITERATE_LIST(obj, inv_i)
+     PyList_Append(list, newPyObj(obj));
+   deleteListIterator(inv_i);
+   return Py_BuildValue("O", list);
+ }
+ 
+ 
+ 
+ //
+ // Standard check to make sure the character exists when
+ // trying to set a value for it. If successful, assign the
+ // character to ch. Otherwise, return -1 (error)
+ //
+ #define PYCHAR_CHECK_CHAR_EXISTS(uid, ch)                                      \
+   ch = propertyTableGet(mob_table, uid);                                       \
+   if(ch == NULL) {                                                             \
+     PyErr_Format(PyExc_TypeError,                                              \
+ 		    "Tried to modify nonexistant character, %d", uid);         \
+     return -1;                                                                 \
+   }                                                                            
+ 
+ 
+ static int
+ PyChar_setname(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete character's name");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character names must be strings");
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   charSetName(ch, PyString_AsString(value));
+   return 0;
+ }
+ 
+ static int
+ PyChar_setdesc(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete character's description");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character descriptions must be strings");
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   charSetDesc(ch, PyString_AsString(value));
+   return 0;
+ }
+ 
+ static int
+ PyChar_setrdesc(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete character's rdesc");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character rdescs must be strings");
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   charSetRdesc(ch, PyString_AsString(value));
+   return 0;
+ }
+ 
+ static int
+ PyChar_setrace(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete a character's race");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character races must be strings");
+     return -1;
+   }
+ 
+   int race = raceGetNum(PyString_AsString(value));
+   if(race == RACE_NONE) {
+     char buf[SMALL_BUFFER];
+     sprintf(buf, "%s is an invalid race type", PyString_AsString(value));
+     PyErr_Format(PyExc_TypeError, buf);
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   charSetRace(ch, race);
+   return 0;
+ }
+ 
+ static int
+ PyChar_seton(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete a character's furniture.");
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+ 
+   if (value == Py_None) {
+     char_from_furniture(ch);
+     return 0;
+   }
+   else if(PyObj_Check(value)) {
+     OBJ_DATA *obj = propertyTableGet(obj_table, PyObj_AsUid(value));
+     if(obj == NULL) {
+       PyErr_Format(PyExc_TypeError, 
+ 		   "Tried to %s's furniture to a nonexistant object.",
+ 		   charGetName(ch));
+       return -1;
+     }
+     else if(objGetType(obj) == ITEM_FURNITURE) {
+       if(charGetFurniture(ch))
+ 	char_from_furniture(ch);
+       char_to_furniture(ch, obj);
+       return 0;
+     }
+   }
+ 
+   PyErr_Format(PyExc_TypeError, 
+ 	       "A Character's furniture may only be set to None or a ."
+ 	       "furniture object.");
+   return -1;
+ }
+ 
+ static int
+ PyChar_setsex(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete a character's sex");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character sexes must be strings");
+     return -1;
+   }
+ 
+   int sex = sexGetNum(PyString_AsString(value));
+   if(sex == SEX_NONE) {
+     char buf[SMALL_BUFFER];
+     sprintf(buf, "%s is an invalid sex type", PyString_AsString(value));
+     PyErr_Format(PyExc_TypeError, buf);
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   charSetSex(ch, sex);
+   return 0;
+ }
+ 
+ static int
+ PyChar_setposition(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete a character's position");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character positions must be strings");
+     return -1;
+   }
+ 
+   int pos = posGetNum(PyString_AsString(value));
+   if(pos == POS_NONE) {
+     char buf[SMALL_BUFFER];
+     sprintf(buf, "%s is an invalid position type", PyString_AsString(value));
+     PyErr_Format(PyExc_TypeError, buf);
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   charSetPos(ch, pos);
+   // players can't be on furniture if they are standing or flying
+   if(poscmp(charGetPos(ch), POS_STANDING) >= 0 && charGetFurniture(ch))
+     char_from_furniture(ch);
+   return 0;
+ }
+ 
+ static int
+ PyChar_setlevel(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete a character's level");
+     return -1;
+   }
+   
+   if (!PyInt_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Character levels must be integers");
+     return -1;
+   }
+ 
+   long lvl = PyInt_AsLong(value);
+   if(lvl < 1 || lvl > MAX_LEVEL) {
+     char buf[SMALL_BUFFER];
+     sprintf(buf, "Character levels are bounded between 1 and %d", MAX_LEVEL);
+     PyErr_Format(PyExc_TypeError, buf);
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   charSetLevel(ch, lvl);
+   return 0;
+ }
+ 
+ static int
+ PyChar_setroom(PyChar *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete a character's room");
+     return -1;
+   }
+ 
+   int vnum = NOWHERE;
+ 
+   if(PyRoom_Check(value))
+     vnum = PyRoom_AsVnum(value);
+   else if(PyInt_Check(value))
+     vnum = (int)PyInt_AsLong(value); // hmmm... is this safe?
+   else {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Character's room must be integer an integer value or a "
+ 		 "room object.");
+     return -1;
+   }
+ 
+   ROOM_DATA *room = worldGetRoom(gameworld, vnum);
+   if(room == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Attempting to move character to nonexistant room, %d.",
+ 		 vnum);
+     return -1;
+   }
+ 
+   CHAR_DATA *ch;
+   PYCHAR_CHECK_CHAR_EXISTS(self->uid, ch);
+   // only move if we're not already here
+   if(charGetRoom(ch) != room) {
+     char_from_room(ch);
+     char_to_room(ch, room);
+ 
+     // if we were on furniture, make sure we dismount it
+     if(charGetFurniture(ch))
+       char_from_furniture(ch);
+   }
+ 
+   return 0;
+ }
+ 
+ 
+ static PyGetSetDef PyChar_getseters[] = {
+   {"inv", (getter)PyChar_getinv, (setter)NULL,
+    "The objects in the character's inventory", 
+    NULL},
+   {"objs", (getter)PyChar_getinv, (setter)NULL,
+    "The objects in the character's inventory", 
+    NULL},
+   {"name", (getter)PyChar_getname, (setter)PyChar_setname,
+    "the character's name",
+    NULL},
+   {"desc", (getter)PyChar_getdesc, (setter)PyChar_setdesc,
+    "the character's description",
+    NULL},
+   {"rdesc", (getter)PyChar_getrdesc, (setter)PyChar_setrdesc,
+    "the character's room description",
+    NULL},
+   {"level", (getter)PyChar_getlevel, (setter)PyChar_setlevel,
+    "the character's level",
+    NULL},
+   {"sex", (getter)PyChar_getsex, (setter)PyChar_setsex,
+    "the character's sex",
+    NULL},
+   {"race", (getter)PyChar_getrace, (setter)PyChar_setrace,
+    "the character's race",
+    NULL},
+   {"position", (getter)PyChar_getposition, (setter)PyChar_setposition,
+    "the character's position",
+    NULL},
+   {"room", (getter)PyChar_getroom, (setter)PyChar_setroom,
+    "the character's room",
+    NULL},
+   {"on", (getter)PyChar_geton, (setter)PyChar_seton,
+    "The furniture the character is sitting on/at. If the character is not "
+    "on furniture, None is returned. To remove a character from furniture, "
+    "then use None",
+    NULL},
+   {"uid", (getter)PyChar_getuid, (setter)NULL,
+    "the unique identification number",
+    NULL},
+   {"vnum", (getter)PyChar_getvnum, (setter)NULL,
+    "the virtual number for the NPC. Returns -1 for characters.",
+    NULL},
+   {"is_npc", (getter)PyChar_getisnpc, (setter)NULL,
+    "returns 1 if the char is an NPC, and 0 otherwise.",
+    NULL},
+   {"is_pc", (getter)PyChar_getispc, (setter)NULL,
+    "returns 1 if the char is an NPC, and 0 otherwise.",
+    NULL},
+ 
+   {NULL}  /* Sentinel */
+ };
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // comparators, getattr, setattr, and all that other class stuff
+ //
+ //*****************************************************************************
+ 
+ //
+ // compare one character to another
+ //
+ static int
+ PyChar_compare(PyChar *ch1, PyChar *ch2) {
+   if(ch1->uid == ch2->uid)
+     return 0;
+   else if(ch1->uid < ch2->uid)
+     return -1;
+   else
+     return 1;
+ }
+ 
+ static PyTypeObject PyChar_Type = {
+     PyObject_HEAD_INIT(NULL)
+     0,                         /*ob_size*/
+     "char.Char",               /*tp_name*/
+     sizeof(PyChar),            /*tp_basicsize*/
+     0,                         /*tp_itemsize*/
+     (destructor)PyChar_dealloc,/*tp_dealloc*/
+     0,                         /*tp_print*/
+     0,                         /*tp_getattr*/
+     0,                         /*tp_setattr*/
+     (cmpfunc)PyChar_compare,   /*tp_compare*/
+     0,                         /*tp_repr*/
+     0,                         /*tp_as_number*/
+     0,                         /*tp_as_sequence*/
+     0,                         /*tp_as_mapping*/
+     0,                         /*tp_hash */
+     0,                         /*tp_call*/
+     0,                         /*tp_str*/
+     0,                         /*tp_getattro*/
+     0,                         /*tp_setattro*/
+     0,                         /*tp_as_buffer*/
+     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+     "Char/Mob objects",        /* tp_doc */
+     0,		               /* tp_traverse */
+     0,		               /* tp_clear */
+     0,		               /* tp_richcompare */
+     0,		               /* tp_weaklistoffset */
+     0,		               /* tp_iter */
+     0,		               /* tp_iternext */
+     PyChar_methods,            /* tp_methods */
+     0,                         /* tp_members */
+     PyChar_getseters,          /* tp_getset */
+     0,                         /* tp_base */
+     0,                         /* tp_dict */
+     0,                         /* tp_descr_get */
+     0,                         /* tp_descr_set */
+     0,                         /* tp_dictoffset */
+     (initproc)PyChar_init,    /* tp_init */
+     0,                         /* tp_alloc */
+     PyChar_new,               /* tp_new */
+ };
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // the char module
+ //
+ //*****************************************************************************
+ static PyObject *
+ PyChar_load_mob(PyObject *self, PyObject *args) {
+   int mob_vnum    = NOBODY, room_vnum = NOWHERE;
+   PyObject *to    = NULL;
+ 
+   ROOM_DATA *room  = NULL;
+   OBJ_DATA  *on    = NULL;
+   char  *posname   = NULL;
+   
+   if (!PyArg_ParseTuple(args, "iO|s", &mob_vnum, &to, &posname)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Load char failed - it needs vnum and destination.");
+     return NULL;
+   }
+ 
+   // see what we're trying to load to
+   if(PyInt_Check(to))
+     room_vnum = (int)PyInt_AsLong(to);
+   else if(PyRoom_Check(to))
+     room_vnum = (int)PyRoom_AsVnum(to);
+   else if(PyObj_Check(to))
+     on = propertyTableGet(obj_table, PyObj_AsUid(to));
+   else {
+     PyErr_Format(PyExc_TypeError, 
+                     "Load char failed: invalid load-to type.");
+     return NULL;
+   }
+ 
+   // check the mob
+   CHAR_DATA *mob_proto = worldGetMob(gameworld, mob_vnum);
+   if(mob_proto == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Load char failed: mobile number does not exist.");
+     return NULL;
+   }
+ 
+ 
+   // see if we're loading onto something
+   if(on)
+     room = objGetRoom(on);
+   else
+     room = worldGetRoom(gameworld, room_vnum);
+ 
+   if(room == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Load char failed: room does not exist, or furniture is not. "
+ 		 "in a room.");
+     return NULL;
+   }
+ 
+   // copy the mob, and put it into the game
+   CHAR_DATA *mob = charCopy(mob_proto);
+   char_to_game(mob);
+   char_to_room(mob, room);
+ 
+   // now check if we need to put the char onto some furniture
+   // default position is POS_SITTING
+   if(on) {
+     int pos = POS_SITTING;
+     char_to_furniture(mob, on);
+     if(posname)
+       pos = posGetNum(posname);
+ 
+     // if the position is none, or greater 
+     // than sitting, default to sitting.
+     if(pos == POS_NONE || poscmp(pos, POS_SITTING) > 0)
+       pos = POS_SITTING;
+     charSetPos(mob, pos);
+   }
+   else if(posname) {
+     int pos = posGetNum(posname);
+     // if it was an invalid name, set it to standing
+     if(pos == POS_NONE)
+       pos = POS_STANDING;
+     charSetPos(mob, pos);
+   }
+ 
+   // check for initialization scripts
+   try_scripts(SCRIPT_TYPE_INIT,
+ 	      mob, SCRIPTOR_CHAR,
+ 	      mob, NULL, room, NULL, NULL, NULL, 0);
+ 
+   // create a python object for the new char, and return it
+   PyChar *py_mob = (PyChar *)newPyChar(mob);
+   return Py_BuildValue("O", py_mob);
+ }
+ 
+ 
+ static PyObject *
+ PyChar_count_mobs(PyObject *self, PyObject *args) {
+   LIST *list = NULL;
+   PyObject *tgt;
+   PyObject *in = NULL;
+   ROOM_DATA *room = NULL;
+   OBJ_DATA  *furniture = NULL;
+   int vnum = NOBODY;
+   char *name = NULL;
+ 
+   if (!PyArg_ParseTuple(args, "O|O", &tgt, &in)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "count_mobs failed. No arguments supplied.");
+     return NULL;
+   }
+ 
+   // see if we're looking by name or vnum
+   if(PyInt_Check(tgt))
+     vnum = PyInt_AsLong(tgt);
+   else if(PyString_Check(tgt))
+     name = PyString_AsString(tgt);
+   else {
+     PyErr_Format(PyExc_TypeError, 
+                     "count_mobs failed. Invalid target type supplied.");
+     return NULL;
+   }
+ 
+   // if we didn't supply something to look in, assume it means the world
+   if(in == NULL)
+     return Py_BuildValue("i", count_chars(NULL, mobile_list,name, vnum, FALSE));
+ 
+ 
+   // see what we're looking in
+   if(PyInt_Check(in))
+     room = worldGetRoom(gameworld, PyInt_AsLong(in));
+   else if(PyRoom_Check(in))
+     room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
+   else if(PyObj_Check(in))
+     furniture = propertyTableGet(obj_table, PyObj_AsUid(in));
+ 
+   // now find the list we're dealing with
+   if(room)      list = roomGetCharacters(room);
+   if(furniture) list = objGetUsers(furniture);
+ 
+   if(list == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "count_mobs failed. invalid argument supplied.");
+     return NULL;
+   }
+   
+   return Py_BuildValue("i", count_chars(NULL, list, name, vnum, FALSE));
+ }
+ 
+ 
+ static PyMethodDef char_module_methods[] = {
+   { "load_mob", PyChar_load_mob, METH_VARARGS,
+     "load a mobile with the specified vnum to a room." },
+   { "count_mobs", PyChar_count_mobs, METH_VARARGS,
+     "count how many occurances of a mobile there are in the specified scope. "
+     "vnum or name can be used. Vnum -1 counts PCs" },
+   {NULL, NULL, 0, NULL}  /* Sentinel */
+ };
+ 
+ 
+ PyMODINIT_FUNC
+ init_PyChar(void) 
+ {
+     PyObject* m;
+ 
+     if (PyType_Ready(&PyChar_Type) < 0)
+         return;
+ 
+     m = Py_InitModule3("char", char_module_methods,
+                        "The char module, for all char/mob-related MUD stuff.");
+ 
+     if (m == NULL)
+       return;
+ 
+     Py_INCREF(&PyChar_Type);
+     PyModule_AddObject(m, "Char", (PyObject *)&PyChar_Type);
+ }
+ 
+ int PyChar_Check(PyObject *value) {
+   return PyObject_TypeCheck(value, &PyChar_Type);
+ }
+ 
+ int PyChar_AsUid(PyObject *ch) {
+   return ((PyChar *)ch)->uid;
+ }
+ 
+ PyObject *
+ newPyChar(CHAR_DATA *ch) {
+   PyChar *py_ch = (PyChar *)PyChar_new(&PyChar_Type, NULL, NULL);
+   py_ch->uid = charGetUID(ch);
+   return (PyObject *)py_ch;
+ }
diff -crN nakedmudv1.0/src/scripts/pychar.h nakedmudv1.4/src/scripts/pychar.h
*** nakedmudv1.0/src/scripts/pychar.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pychar.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,21 ----
+ #ifndef __PYCHAR_H
+ #define __PYCHAR_H
+ //*****************************************************************************
+ //
+ // py_char.h
+ //
+ // A python extention to allow python scripts to treat MUD characters as an
+ // object within the script.
+ //
+ //*****************************************************************************
+ 
+ /* initialize characters for use */
+ PyMODINIT_FUNC
+ init_PyChar(void);
+ int PyChar_AsUid(PyObject *ch);
+ int PyChar_Check(PyObject *value);
+ 
+ PyObject *
+ newPyChar(CHAR_DATA *ch);
+ 
+ #endif //__PYCHAR_H
diff -crN nakedmudv1.0/src/scripts/pymud.c nakedmudv1.4/src/scripts/pymud.c
*** nakedmudv1.0/src/scripts/pymud.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pymud.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,116 ----
+ //*****************************************************************************
+ //
+ // pymud.h
+ //
+ // a python module that provides some useful utility functions for interacting
+ // with the MUD. Includes stuff like global variables, messaging functions,
+ // and a whole bunch of other stuff.
+ //
+ // WORK FOR FUTURE: Our use of Py_INCREF is probably creating a
+ //                  memory leak somewhere.
+ //
+ //*****************************************************************************
+ 
+ #include <Python.h>
+ #include <structmember.h>
+ 
+ #include "../mud.h"
+ 
+ #include "script.h"
+ #include "pyroom.h"
+ #include "pychar.h"
+ #include "pyobj.h"
+ 
+ PyObject *globals = NULL;
+ 
+ 
+ //*****************************************************************************
+ //
+ // GLOBAL VARIABLES
+ //
+ // the following functions allow scriptors to store/access global variables.
+ // globals are stored in a python map, that maps two python objects together.
+ // the functions used to interact with globals are:
+ //   get_global(key)
+ //   set_global(key, val)
+ //   erase_global(key)
+ //
+ //*****************************************************************************
+ static PyObject *
+ mud_get_global(PyObject *self, PyObject *args) {
+   PyObject *key = NULL;
+ 
+   // get the key
+   if (!PyArg_ParseTuple(args, "O", &key)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Could not retrieve global variable - no key provided");
+     return NULL;
+   }
+ 
+   PyObject *val = PyDict_GetItem(globals, key);
+   if(val == NULL)
+     val = Py_None;
+   
+   Py_INCREF(val);
+   return val;
+ }
+ 
+ static PyObject *
+ mud_set_global(PyObject *self, PyObject *args) {
+   PyObject *key = NULL, *val = NULL;
+ 
+   if (!PyArg_ParseTuple(args, "OO", &key, &val)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Could not set global variable - need key and value");
+     return NULL;
+   }
+ 
+   //  Py_INCREF(val);
+   PyDict_SetItem(globals, key, val);
+   return Py_BuildValue("i", 1);
+ }
+ 
+ 
+ static PyObject *
+ mud_erase_global(PyObject *self, PyObject *args) {
+   PyObject *key = NULL;
+ 
+   if (!PyArg_ParseTuple(args, "O", &key)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Could not erase global variable - need key");
+     return NULL;
+   }
+ 
+   //  Py_INCREF(Py_None);
+   PyDict_SetItem(globals, key, Py_None);
+   return Py_BuildValue("i", 1);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // MUD module
+ //
+ //*****************************************************************************
+ static PyMethodDef mud_module_methods[] = {
+     {"get_global",  mud_get_global, METH_VARARGS,
+      "Get the value of a global variable."},
+     {"set_global",  mud_set_global, METH_VARARGS,
+      "Set the value of a global variable."},
+     {"erase_global",  mud_erase_global, METH_VARARGS,
+      "Erase the value of a global variable."},
+     {NULL, NULL, 0, NULL}        /* Sentinel */
+ };
+ 
+ 
+ PyMODINIT_FUNC
+ init_PyMud(void) {
+   PyObject *m;
+ 
+   globals = PyDict_New();
+   Py_INCREF(globals);
+ 
+   m = Py_InitModule3("mud", mud_module_methods,
+ 		     "The mud module, for all MUD misc mud utils.");
+ }
diff -crN nakedmudv1.0/src/scripts/pymud.h nakedmudv1.4/src/scripts/pymud.h
*** nakedmudv1.0/src/scripts/pymud.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pymud.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,17 ----
+ #ifndef __PYMUD_H
+ #define __PYMUD_H
+ //*****************************************************************************
+ //
+ // pymud.h
+ //
+ // a python module that provides some useful utility functions for interacting
+ // with the MUD. Includes stuff like global variables, messaging functions,
+ // and a whole bunch of other stuff. Browse pymud.c to see.
+ //
+ //*****************************************************************************
+ 
+ /* initialize mud module for use */
+ PyMODINIT_FUNC
+ init_PyMud(void);
+ 
+ #endif //__PYMUD_H
diff -crN nakedmudv1.0/src/scripts/pyobj.c nakedmudv1.4/src/scripts/pyobj.c
*** nakedmudv1.0/src/scripts/pyobj.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pyobj.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,574 ----
+ //*****************************************************************************
+ //
+ // py_char.c
+ //
+ // A python extention to allow python scripts to treat MUD characters as an
+ // object within the script.
+ //
+ //*****************************************************************************
+ 
+ #include <Python.h>
+ #include <structmember.h>
+ 
+ #include "../mud.h"
+ #include "../world.h"
+ #include "../room.h"
+ #include "../character.h"
+ #include "../object.h"
+ #include "../races.h"
+ #include "../handler.h"
+ #include "../utils.h"
+ 
+ #include "script.h"
+ #include "pychar.h"
+ #include "pyroom.h"
+ #include "pyobj.h"
+ 
+ 
+ typedef struct {
+   PyObject_HEAD
+   int uid;
+ } PyObj;
+ 
+ 
+ //*****************************************************************************
+ //
+ // allocation, deallocation, and initialiation
+ //
+ //*****************************************************************************
+ static void
+ PyObj_dealloc(PyObj *self) {
+   self->ob_type->tp_free((PyObject*)self);
+ }
+ 
+ static PyObject *
+ PyObj_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
+     PyObj *self;
+ 
+     self = (PyObj  *)type->tp_alloc(type, 0);
+     self->uid = NOTHING;
+     return (PyObject *)self;
+ }
+ 
+ static int
+ PyObj_init(PyObj *self, PyObject *args, PyObject *kwds) {
+   static char *kwlist[] = {"uid", NULL};
+   int uid = NOTHING;
+ 
+   // get the universal id
+   if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &uid)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Objects may only be created by uid");
+     return -1;
+   }
+ 
+   // make sure a object with the UID exists
+   if(!propertyTableGet(obj_table, uid)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Object with uid, %d, does not exist", uid);
+     return -1;
+   }
+ 
+   self->uid = uid;
+   return 0;
+ }
+ 
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // methods and stuff for building the class
+ //
+ //*****************************************************************************
+ static PyMethodDef PyObj_methods[] = {
+     {NULL}  /* Sentinel */
+ };
+ 
+ 
+ //*****************************************************************************
+ //
+ // character attributes - mostly get and set
+ //
+ //*****************************************************************************
+ static PyObject *
+ PyObj_getname(PyObj *self, void *closure) {
+   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
+   if(obj != NULL) return Py_BuildValue("s", objGetName(obj));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyObj_getdesc(PyObj *self, void *closure) {
+   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
+   if(obj != NULL) return Py_BuildValue("s", objGetDesc(obj));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyObj_getrdesc(PyObj *self, void *closure) {
+   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
+   if(obj != NULL) return Py_BuildValue("s", objGetRdesc(obj));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyObj_getuid(PyObj *self, void *closure) {
+   return Py_BuildValue("i", self->uid);
+ }
+ 
+ static PyObject *
+ PyObj_getvnum(PyObj *self, void *closure) {
+   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
+   if(obj != NULL) return Py_BuildValue("i", objGetVnum(obj));
+   else           return NULL;
+ }
+ 
+ static PyObject *
+ PyObj_getcontents(PyObj *self, PyObject *args) {
+   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
+   if(obj == NULL) 
+     return NULL;
+ 
+   LIST_ITERATOR *cont_i = newListIterator(objGetContents(obj));
+   PyObject *list = PyList_New(0);
+   OBJ_DATA *cont;
+   
+   // for each obj in the contentory, add it to the Python list
+   ITERATE_LIST(cont, cont_i)
+     PyList_Append(list, newPyObj(cont));
+   deleteListIterator(cont_i);
+   return Py_BuildValue("O", list);
+ }
+ 
+ static PyObject *
+ PyObj_getchars(PyObj *self, PyObject *args) {
+   OBJ_DATA *obj = propertyTableGet(obj_table, self->uid);
+   if(obj == NULL) 
+     return NULL;
+ 
+   LIST_ITERATOR *char_i = newListIterator(objGetUsers(obj));
+   PyObject *list = PyList_New(0);
+   CHAR_DATA *ch;
+   
+   // for each obj in the contentory, add it to the Python list
+   ITERATE_LIST(ch, char_i)
+     PyList_Append(list, newPyChar(ch));
+   deleteListIterator(char_i);
+   return Py_BuildValue("O", list);
+ }
+ 
+ 
+ //
+ // Standard check to make sure the object exists when
+ // trying to set a value for it. If successful, assign the
+ // object to ch. Otherwise, return -1 (error)
+ //
+ #define PYOBJ_CHECK_OBJ_EXISTS(uid, obj)                                       \
+   obj = propertyTableGet(obj_table, uid);                                      \
+   if(obj == NULL) {                                                            \
+     PyErr_Format(PyExc_TypeError,                                              \
+ 		    "Tried to modify nonexistant object, %d", uid);            \
+     return -1;                                                                 \
+   }                                                                            
+ 
+ static int
+ PyObj_setname(PyObj *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete object's name");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Object names must be strings");
+     return -1;
+   }
+ 
+   OBJ_DATA *obj;
+   PYOBJ_CHECK_OBJ_EXISTS(self->uid, obj);
+   objSetName(obj, PyString_AsString(value));
+   return 0;
+ }
+ 
+ static int
+ PyObj_setdesc(PyObj *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete object's description");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Object descriptions must be strings");
+     return -1;
+   }
+ 
+   OBJ_DATA *obj;
+   PYOBJ_CHECK_OBJ_EXISTS(self->uid, obj);
+   objSetDesc(obj, PyString_AsString(value));
+   return 0;
+ }
+ 
+ static int
+ PyObj_setrdesc(PyObj *self, PyObject *value, void *closure) {
+   if (value == NULL) {
+     PyErr_Format(PyExc_TypeError, "Cannot delete object's rdesc");
+     return -1;
+   }
+   
+   if (!PyString_Check(value)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Object rdescs must be strings");
+     return -1;
+   }
+ 
+   OBJ_DATA *obj;
+   PYOBJ_CHECK_OBJ_EXISTS(self->uid, obj);
+   objSetRdesc(obj, PyString_AsString(value));
+   return 0;
+ }
+ 
+ 
+ static PyGetSetDef PyObj_getseters[] = {
+   {"contents", (getter)PyObj_getcontents, (setter)NULL,
+    "the object's contents",
+    NULL},
+   {"objs", (getter)PyObj_getcontents, (setter)NULL,
+    "the object's contents",
+    NULL},
+   {"chars", (getter)PyObj_getchars, (setter)NULL,
+    "the characters sitting on/riding the object",
+    NULL},
+   {"name", (getter)PyObj_getname, (setter)PyObj_setname,
+    "the object's name",
+    NULL},
+   {"desc", (getter)PyObj_getdesc, (setter)PyObj_setdesc,
+    "the object's description",
+    NULL},
+   {"rdesc", (getter)PyObj_getrdesc, (setter)PyObj_setrdesc,
+    "the object's room description",
+    NULL},
+   {"uid", (getter)PyObj_getuid, (setter)NULL,
+    "the unique identification number",
+    NULL},
+   {"vnum", (getter)PyObj_getvnum, (setter)NULL,
+    "the virtual number for the object.",
+    NULL},
+   {NULL}  /* Sentinel */
+ };
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // comparators, getattr, setattr, and all that other class stuff
+ //
+ //*****************************************************************************
+ 
+ //
+ // compare one object to another
+ //
+ static int
+ PyObj_compare(PyObj *obj1, PyObj *obj2) {
+   if(obj1->uid == obj2->uid)
+     return 0;
+   else if(obj1->uid < obj2->uid)
+     return -1;
+   else
+     return 1;
+ }
+ 
+ static PyTypeObject PyObj_Type = {
+     PyObject_HEAD_INIT(NULL)
+     0,                         /*ob_size*/
+     "obj.Obj",                 /*tp_name*/
+     sizeof(PyObj),             /*tp_basicsize*/
+     0,                         /*tp_itemsize*/
+     (destructor)PyObj_dealloc, /*tp_dealloc*/
+     0,                         /*tp_print*/
+     0,                         /*tp_getattr*/
+     0,                         /*tp_setattr*/
+     (cmpfunc)PyObj_compare,    /*tp_compare*/
+     0,                         /*tp_repr*/
+     0,                         /*tp_as_number*/
+     0,                         /*tp_as_sequence*/
+     0,                         /*tp_as_mapping*/
+     0,                         /*tp_hash */
+     0,                         /*tp_call*/
+     0,                         /*tp_str*/
+     0,                         /*tp_getattro*/
+     0,                         /*tp_setattro*/
+     0,                         /*tp_as_buffer*/
+     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+     "Obj/Obj objects",         /* tp_doc */
+     0,		               /* tp_traverse */
+     0,		               /* tp_clear */
+     0,		               /* tp_richcompare */
+     0,		               /* tp_weaklistoffset */
+     0,		               /* tp_iter */
+     0,		               /* tp_iternext */
+     PyObj_methods,             /* tp_methods */
+     0,                         /* tp_members */
+     PyObj_getseters,           /* tp_getset */
+     0,                         /* tp_base */
+     0,                         /* tp_dict */
+     0,                         /* tp_descr_get */
+     0,                         /* tp_descr_set */
+     0,                         /* tp_dictoffset */
+     (initproc)PyObj_init,      /* tp_init */
+     0,                         /* tp_alloc */
+     PyObj_new,                 /* tp_new */
+ };
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // the obj module
+ //
+ //*****************************************************************************
+ static PyObject *
+ PyObj_load_obj(PyObject *self, PyObject *args) {
+   int obj_vnum = NOBODY;
+   PyObject *in = NULL;
+ 
+   ROOM_DATA *room = NULL; // are we loading to a room?
+   OBJ_DATA  *cont = NULL; // are we loading to a container?
+   CHAR_DATA *ch   = NULL; // are we loading to a character?
+   char *equip_to  = NULL; // are we trying to equip the character?
+ 
+   if (!PyArg_ParseTuple(args, "iO|s", &obj_vnum, &in, &equip_to)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Load obj failed - it needs a vnum and destination.");
+     return NULL;
+   }
+ 
+   // check the obj
+   OBJ_DATA *obj_proto = worldGetObj(gameworld, obj_vnum);
+   if(obj_proto == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Load obj failed: object number does not exist.");
+     return NULL;
+   }
+ 
+   // copy the object
+   OBJ_DATA *obj = objCopy(obj_proto);
+ 
+ 
+   // figure out what we're trying to load this thing into
+   if(PyInt_Check(in))
+     room = worldGetRoom(gameworld, (int)PyInt_AsLong(in));
+   else if(PyRoom_Check(in))
+     room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
+   else if(PyObj_Check(in))
+     cont = propertyTableGet(obj_table, PyObj_AsUid(in));
+   else if(PyChar_Check(in))
+     ch   = propertyTableGet(mob_table, PyChar_AsUid(in));
+ 
+ 
+   // figure out where we're trying to load the object to
+   if(room != NULL) {
+     obj_to_game(obj);
+     obj_to_room(obj, room);
+   }
+   else if(cont != NULL) {
+     obj_to_game(obj);
+     obj_to_obj(obj, cont);
+   }
+   else if(ch != NULL) {
+     // see if we're trying to equip the object
+     if(equip_to) {
+       obj_to_game(obj);
+       if(!try_equip(ch, obj, equip_to))
+ 	obj_to_char(obj, ch);
+     }
+     else {
+       obj_to_game(obj);
+       obj_to_char(obj, ch);
+     }
+   }
+ 
+   // We couldn't figure out the destination!
+   else {
+     PyErr_Format(PyExc_TypeError, 
+                     "Load obj failed: destination does not exist.");
+     return NULL;
+   }
+ 
+   // check for initialization scripts
+   try_scripts(SCRIPT_TYPE_INIT,
+ 	      obj, SCRIPTOR_OBJ,
+ 	      ch, cont, room, NULL, NULL, NULL, 0);
+ 
+   // create a python object for the new obj, and return it
+   PyObj *py_obj = (PyObj *)newPyObj(obj);
+   return Py_BuildValue("O", py_obj);
+ }
+ 
+ 
+ static PyObject *
+ PyObj_count_objs(PyObject *self, PyObject *args) {
+   LIST *list      = NULL;
+   PyObject *tgt;
+   PyObject *in    = NULL;
+   ROOM_DATA *room = NULL;
+   OBJ_DATA  *cont = NULL;
+   CHAR_DATA *ch   = NULL;
+   int vnum = NOTHING;
+   char *name = NULL;
+ 
+   if (!PyArg_ParseTuple(args, "O|O", &tgt, &in)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "count_objs failed. No arguments supplied.");
+     return NULL;
+   }
+ 
+   // see if we're looking by name or vnum
+   if(PyInt_Check(tgt))
+     vnum = PyInt_AsLong(tgt);
+   else if(PyString_Check(tgt))
+     name = PyString_AsString(tgt);
+   else {
+     PyErr_Format(PyExc_TypeError, 
+                     "count_objs failed. Invalid target type supplied.");
+     return NULL;
+   }
+ 
+   // if we didn't supply something to look in, assume it means the world
+   if(in == NULL)
+     return Py_BuildValue("i", count_objs(NULL, object_list, name, vnum, FALSE));
+ 
+   // see what we're looking in
+   if(PyInt_Check(in))
+     room = worldGetRoom(gameworld, PyInt_AsLong(in));
+   else if(PyRoom_Check(in))
+     room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
+   else if(PyObj_Check(in))
+     cont = propertyTableGet(obj_table, PyObj_AsUid(in));
+   else if(PyChar_Check(in))
+     ch   = propertyTableGet(mob_table, PyChar_AsUid(in));
+ 
+   // now find the list we're dealing with
+   if(room) list = roomGetContents(room);
+   if(cont) list = objGetContents(cont);
+   if(ch)   list = charGetInventory(ch);
+ 
+   if(list == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "count_objs failed. invalid argument supplied.");
+     return NULL;
+   }
+   
+   return Py_BuildValue("i", count_objs(NULL, list, name, vnum, FALSE));
+ }
+ 
+ 
+ static PyObject *
+ PyObj_find_obj(PyObject *self, PyObject *args) {
+   LIST *list           = object_list;
+   PyObject *in         = NULL;
+   ROOM_DATA *room      = NULL;
+   OBJ_DATA  *cont      = NULL;
+   CHAR_DATA *ch        = NULL;
+   CHAR_DATA *looker_ch = NULL;
+   PyObject *looker     = NULL;
+   char *tgt            = NULL;
+ 
+   if (!PyArg_ParseTuple(args, "s|OO", &tgt, &in, &looker)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "find_obj failed. No arguments supplied.");
+     return NULL;
+   }
+ 
+   // check for scope of search
+   if(in) {
+     if(PyInt_Check(in))
+       room = worldGetRoom(gameworld, PyInt_AsLong(in));
+     else if(PyRoom_Check(in))
+       room = worldGetRoom(gameworld, PyRoom_AsVnum(in));
+     else if(PyObj_Check(in))
+       cont = propertyTableGet(obj_table, PyObj_AsUid(in));
+     else if(PyChar_Check(in))
+       ch   = propertyTableGet(mob_table, PyChar_AsUid(in));
+   }
+ 
+   // check to see who's looking
+   if(looker && PyChar_Check(looker))
+     looker_ch = propertyTableGet(mob_table, PyChar_AsUid(looker));
+ 
+   // now find the list we're dealing with
+   if(room) list = roomGetContents(room);
+   if(cont) list = objGetContents(cont);
+   if(ch)   list = charGetInventory(ch);
+ 
+   // now, do the search
+   int count = 1;
+   char name[SMALL_BUFFER] = "";
+   get_count(tgt, name, &count);
+ 
+   // we're just looking for a single item
+   if(count != COUNT_ALL) {
+     OBJ_DATA *obj    = find_obj(looker_ch, list, count, name, NOTHING, 
+ 				(looker_ch ? TRUE : FALSE));
+     PyObject *py_obj = Py_None;
+     if(obj) py_obj = newPyObj(obj);
+     return Py_BuildValue("O", py_obj);
+   }
+   // otherwise, return everything that meets our critereon
+   else {
+     //***********
+     // FINISH ME
+     //***********
+     return Py_BuildValue("O", Py_None);
+   }
+ }
+ 
+ 
+ 
+ static PyMethodDef obj_module_methods[] = {
+   { "load_obj", PyObj_load_obj, METH_VARARGS,
+     "load a object with the specified vnum to a room." },
+   { "count_objs", PyObj_count_objs, METH_VARARGS,
+     "count how many occurances of an object there are in the specified scope. "
+     "vnum or name can be used."},
+   { "find_obj", PyObj_find_obj, METH_VARARGS,
+     "Takes a string argument, and returns the object(s) in the scope that "
+     "correspond to what the string is searching for."},
+   {NULL, NULL, 0, NULL}  /* Sentinel */
+ };
+ 
+ 
+ 
+ PyMODINIT_FUNC
+ init_PyObj(void) 
+ {
+     PyObject* m;
+ 
+     if (PyType_Ready(&PyObj_Type) < 0)
+         return;
+ 
+     m = Py_InitModule3("obj", obj_module_methods,
+                        "The object module, for all object-related MUD stuff.");
+ 
+     if (m == NULL)
+       return;
+ 
+     Py_INCREF(&PyObj_Type);
+     PyModule_AddObject(m, "Obj", (PyObject *)&PyObj_Type);
+ }
+ 
+ int PyObj_Check(PyObject *value) {
+   return PyObject_TypeCheck(value, &PyObj_Type);
+ }
+ 
+ int PyObj_AsUid(PyObject *obj) {
+   return ((PyObj *)obj)->uid;
+ }
+ 
+ PyObject *
+ newPyObj(OBJ_DATA *obj) {
+   PyObj *py_obj = (PyObj *)PyObj_new(&PyObj_Type, NULL, NULL);
+   py_obj->uid = objGetUID(obj);
+   return (PyObject *)py_obj;
+ }
diff -crN nakedmudv1.0/src/scripts/pyobj.h nakedmudv1.4/src/scripts/pyobj.h
*** nakedmudv1.0/src/scripts/pyobj.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pyobj.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,21 ----
+ #ifndef __PYOBJ_H
+ #define __PYOBJ_H
+ //*****************************************************************************
+ //
+ // pyobj.h
+ //
+ // A python extention to allow python scripts to treat MUD objects as an
+ // object within the script.
+ //
+ //*****************************************************************************
+ 
+ /* initialize characters for use */
+ PyMODINIT_FUNC
+ init_PyObj(void);
+ int PyObj_AsUid(PyObject *ch);
+ int PyObj_Check(PyObject *value);
+ 
+ PyObject *
+ newPyObj(OBJ_DATA *obj);
+ 
+ #endif //__PYOBJ_H
diff -crN nakedmudv1.0/src/scripts/pyroom.c nakedmudv1.4/src/scripts/pyroom.c
*** nakedmudv1.0/src/scripts/pyroom.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pyroom.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,482 ----
+ //*****************************************************************************
+ //
+ // pyroom.c
+ //
+ // A python extention to allow python scripts to treat MUD characters as an
+ // object within the script.
+ //
+ //*****************************************************************************
+ 
+ #include <Python.h>
+ #include <structmember.h>
+ 
+ #include "../mud.h"
+ #include "../world.h"
+ #include "../room.h"
+ #include "../exit.h"
+ #include "../character.h"
+ #include "../races.h"
+ #include "../handler.h"
+ #include "../utils.h"
+ 
+ #include "script.h"
+ #include "pyroom.h"
+ #include "pychar.h"
+ #include "pyobj.h"
+ 
+ typedef struct {
+   PyObject_HEAD
+   room_vnum vnum;
+ } PyRoom;
+ 
+ 
+ //*****************************************************************************
+ //
+ // allocation, deallocation, and initialiation
+ //
+ //*****************************************************************************
+ static void
+ PyRoom_dealloc(PyRoom *self) {
+   self->ob_type->tp_free((PyObject*)self);
+ }
+ 
+ static PyObject *
+ PyRoom_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
+     PyRoom *self;
+ 
+     self = (PyRoom  *)type->tp_alloc(type, 0);
+     self->vnum = NOWHERE;
+     return (PyObject *)self;
+ }
+ 
+ static int
+ PyRoom_init(PyRoom *self, PyObject *args, PyObject *kwds) {
+   static char *kwlist[] = {"vnum", NULL};
+   int vnum = NOWHERE;
+ 
+   // get the vnum
+   if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &vnum)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Rooms may only be created using a vnum");
+     return -1;
+   }
+ 
+   // make sure a room with the vnum exists
+   if(!worldGetRoom(gameworld, vnum)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Rom with vnum, %d, does not exist", vnum);
+     return -1;
+   }
+ 
+   self->vnum = vnum;
+   return 0;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // methods and stuff for building the class
+ //
+ //*****************************************************************************
+ 
+ //
+ // close a door in the specified direction
+ //
+ static PyObject *
+ PyRoom_close(PyRoom *self, PyObject *value) {
+   ROOM_DATA *room = NULL;
+   EXIT_DATA *exit = NULL;
+   char *dirname = NULL;
+   int dir = DIR_NONE;
+ 
+   if (!PyArg_ParseTuple(value, "s", &dirname)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Doornames provided to PyRoom_close must be directions.");
+     return NULL;
+   }
+ 
+   room = worldGetRoom(gameworld, self->vnum);
+   if(room == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to close door in non-existant room, %d.", 
+ 		 self->vnum);
+     return NULL;
+   }
+ 
+   // see if it's a normal exit
+   dir = dirGetNum(dirname);
+ 
+   if(dir != DIR_NONE)
+     exit = roomGetExit(room, dir);
+   else
+     exit = roomGetExitSpecial(room, dirname);
+ 
+   // make sure the exit exists
+   if(exit == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to close non-existant exit, %s, in room %d.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+ 
+   // make sure the exit can be closed in the first place
+   if(!exitIsClosable(exit)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to close exit, %s, in room %d that is not closable.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+ 
+   exitSetClosed(exit, TRUE);
+   return Py_BuildValue("i", 1);
+ }
+ 
+ 
+ //
+ // lock a door in the specified direction
+ //
+ static PyObject *
+ PyRoom_lock(PyRoom *self, PyObject *value) {
+   ROOM_DATA *room = NULL;
+   EXIT_DATA *exit = NULL;
+   char *dirname = NULL;
+   int dir = DIR_NONE;
+ 
+   if (!PyArg_ParseTuple(value, "s", &dirname)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Doornames provided to PyRoom_lock must be directions.");
+     return NULL;
+   }
+ 
+   room = worldGetRoom(gameworld, self->vnum);
+   if(room == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to lock door in non-existant room, %d.", 
+ 		 self->vnum);
+     return NULL;
+   }
+ 
+   // see if it's a normal exit
+   dir = dirGetNum(dirname);
+ 
+   if(dir != DIR_NONE)
+     exit = roomGetExit(room, dir);
+   else
+     exit = roomGetExitSpecial(room, dirname);
+ 
+   // make sure the exit exists
+   if(exit == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to lock non-existant exit, %s, in room %d.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+ 
+   // make sure the exit can be closed in the first place
+   if(!exitIsClosable(exit)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to lock exit, %s, in room %d that is not closable.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+   if(exitGetKey(exit) == NOTHING) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to lock exit, %s, in room %d that is not lockable.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+ 
+   exitSetClosed(exit, TRUE);
+   exitSetLocked(exit, TRUE);
+   return Py_BuildValue("i", 1);
+ }
+ 
+ 
+ //
+ // lock a door in the specified direction
+ //
+ static PyObject *
+ PyRoom_unlock(PyRoom *self, PyObject *value) {
+   ROOM_DATA *room = NULL;
+   EXIT_DATA *exit = NULL;
+   char *dirname = NULL;
+   int dir = DIR_NONE;
+ 
+   if (!PyArg_ParseTuple(value, "s", &dirname)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Doornames provided to PyRoom_unlock must be directions.");
+     return NULL;
+   }
+ 
+   room = worldGetRoom(gameworld, self->vnum);
+   if(room == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to unlock door in non-existant room, %d.", 
+ 		 self->vnum);
+     return NULL;
+   }
+ 
+   // see if it's a normal exit
+   dir = dirGetNum(dirname);
+ 
+   if(dir != DIR_NONE)
+     exit = roomGetExit(room, dir);
+   else
+     exit = roomGetExitSpecial(room, dirname);
+ 
+   // make sure the exit exists
+   if(exit == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to unlock non-existant exit, %s, in room %d.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+ 
+   // make sure the exit can be closed in the first place
+   if(!exitIsClosable(exit)) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to unlock exit, %s, in room %d that is not closable.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+   if(exitGetKey(exit) == NOTHING) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to unlock exit, %s, in room %d that is not lockable.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+ 
+   exitSetLocked(exit, FALSE);
+   return Py_BuildValue("i", 1);
+ }
+ 
+ 
+ //
+ // close a door in the specified direction
+ //
+ static PyObject *
+ PyRoom_open(PyRoom *self, PyObject *value) {
+   ROOM_DATA *room = NULL;
+   EXIT_DATA *exit = NULL;
+   char *dirname = NULL;
+   int dir = DIR_NONE;
+ 
+   if (!PyArg_ParseTuple(value, "s", &dirname)) {
+     PyErr_Format(PyExc_TypeError, 
+                     "Doornames provided to PyRoom_open must be directions.");
+     return NULL;
+   }
+ 
+   room = worldGetRoom(gameworld, self->vnum);
+   if(room == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to open door in non-existant room, %d.", 
+ 		 self->vnum);
+     return NULL;
+   }
+ 
+ 
+   // see if it's a normal exit
+   dir = dirGetNum(dirname);
+ 
+   if(dir != DIR_NONE)
+     exit = roomGetExit(room, dir);
+   else
+     exit = roomGetExitSpecial(room, dirname);
+ 
+   // make sure the exit exists
+   if(exit == NULL) {
+     PyErr_Format(PyExc_TypeError, 
+ 		 "Tried to open non-existant exit, %s, in room %d.",
+ 		 dirname, self->vnum);
+     return NULL;
+   }
+ 
+   exitSetClosed(exit, FALSE);
+   exitSetLocked(exit, FALSE);
+   return Py_BuildValue("i", 1);
+ }
+ 
+ 
+ 
+ static PyMethodDef PyRoom_methods[] = {
+     {"close", (PyCFunction)PyRoom_close, METH_VARARGS,
+      "close a door in the specified direction." },
+     {"open", (PyCFunction)PyRoom_open, METH_VARARGS,
+      "open a door in the specified direction. Unlocks it if neccessary." },
+     {"lock", (PyCFunction)PyRoom_lock, METH_VARARGS,
+      "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." },
+     {NULL}  /* Sentinel */
+ };
+ 
+ 
+ //*****************************************************************************
+ //
+ // character attributes - mostly get and set
+ //
+ //*****************************************************************************
+ static PyObject *
+ PyRoom_getvnum(PyRoom *self, void *closure) {
+   ROOM_DATA *room = worldGetRoom(gameworld, self->vnum);
+   if(room != NULL) return Py_BuildValue("i", roomGetVnum(room));
+   else             return NULL;
+ }
+ 
+ static PyObject *
+ PyRoom_getcharacters(PyRoom *self, PyObject *args) {
+   ROOM_DATA *room = worldGetRoom(gameworld, self->vnum);
+   if(room == NULL)
+     return NULL;
+   else {
+     LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room));
+     PyObject *list = PyList_New(0);
+     CHAR_DATA *ch;
+ 
+     // for each char in the room list, add him to a Python list
+     ITERATE_LIST(ch, char_i)
+       PyList_Append(list, newPyChar(ch));
+     deleteListIterator(char_i);
+     return Py_BuildValue("O", list);
+   }
+ }
+ 
+ static PyObject *
+ PyRoom_getcontents(PyRoom *self, PyObject *args) {
+   ROOM_DATA *room = worldGetRoom(gameworld, self->vnum);
+   if(room == NULL)
+     return NULL;
+   else {
+     LIST_ITERATOR *obj_i = newListIterator(roomGetContents(room));
+     PyObject *list = PyList_New(0);
+     OBJ_DATA *obj;
+ 
+     // for each obj in the room list, add him to a Python list
+     ITERATE_LIST(obj, obj_i)
+       PyList_Append(list, newPyObj(obj));
+     deleteListIterator(obj_i);
+     return Py_BuildValue("O", list);
+   }
+ }
+ 
+ 
+ static PyGetSetDef PyRoom_getseters[] = {
+   {"vnum", (getter)PyRoom_getvnum, (setter)NULL,
+    "The room's vnum", NULL},
+   {"chars", (getter)PyRoom_getcharacters, (setter)NULL,
+    "The characters in the room", NULL},
+   {"objs", (getter)PyRoom_getcontents, (setter)NULL,
+    "The objects in the room", NULL},
+   {"contents", (getter)PyRoom_getcontents, (setter)NULL,
+    "The objects in the room", NULL},
+   {NULL}  /* Sentinel */
+ };
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // comparators, getattr, setattr, and all that other class stuff
+ //
+ //*****************************************************************************
+ 
+ //
+ // compare one character to another
+ //
+ static int
+ PyRoom_compare(PyRoom *room1, PyRoom *room2) {
+   if(room1->vnum == room2->vnum)
+     return 0;
+   else if(room1->vnum < room2->vnum)
+     return -1;
+   else
+     return 1;
+ }
+ 
+ static PyTypeObject PyRoom_Type = {
+     PyObject_HEAD_INIT(NULL)
+     0,                         /*ob_size*/
+     "room.Room",               /*tp_name*/
+     sizeof(PyRoom),            /*tp_basicsize*/
+     0,                         /*tp_itemsize*/
+     (destructor)PyRoom_dealloc,/*tp_dealloc*/
+     0,                         /*tp_print*/
+     0,                         /*tp_getattr*/
+     0,                         /*tp_setattr*/
+     (cmpfunc)PyRoom_compare,   /*tp_compare*/
+     0,                         /*tp_repr*/
+     0,                         /*tp_as_number*/
+     0,                         /*tp_as_sequence*/
+     0,                         /*tp_as_mapping*/
+     0,                         /*tp_hash */
+     0,                         /*tp_call*/
+     0,                         /*tp_str*/
+     0,                         /*tp_getattro*/
+     0,                         /*tp_setattro*/
+     0,                         /*tp_as_buffer*/
+     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+     "Python Room object",      /* tp_doc */
+     0,		               /* tp_traverse */
+     0,		               /* tp_clear */
+     0,		               /* tp_richcompare */
+     0,		               /* tp_weaklistoffset */
+     0,		               /* tp_iter */
+     0,		               /* tp_iternext */
+     PyRoom_methods,            /* tp_methods */
+     0,                         /* tp_members */
+     PyRoom_getseters,          /* tp_getset */
+     0,                         /* tp_base */
+     0,                         /* tp_dict */
+     0,                         /* tp_descr_get */
+     0,                         /* tp_descr_set */
+     0,                         /* tp_dictoffset */
+     (initproc)PyRoom_init,    /* tp_init */
+     0,                         /* tp_alloc */
+     PyRoom_new,               /* tp_new */
+ };
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // the room module
+ //
+ //*****************************************************************************
+ static PyMethodDef room_module_methods[] = {
+   {NULL, NULL, 0, NULL}  /* Sentinel */
+ };
+ 
+ 
+ PyMODINIT_FUNC
+ init_PyRoom(void) {
+     PyObject* m;
+ 
+     if (PyType_Ready(&PyRoom_Type) < 0)
+         return;
+ 
+     m = Py_InitModule3("room", room_module_methods,
+                        "The room module, for all MUD room-related stuff.");
+ 
+     if (m == NULL)
+       return;
+ 
+     Py_INCREF(&PyRoom_Type);
+     PyModule_AddObject(m, "Room", (PyObject *)&PyRoom_Type);
+ }
+ 
+ int PyRoom_AsVnum(PyObject *room) {
+   return ((PyRoom *)room)->vnum;
+ }
+ 
+ int PyRoom_Check(PyObject *value) {
+   return PyObject_TypeCheck(value, &PyRoom_Type);
+ }
+ 
+ PyObject *
+ newPyRoom(ROOM_DATA *room) {
+   PyRoom *py_room = (PyRoom *)PyRoom_new(&PyRoom_Type, NULL, NULL);
+   py_room->vnum = roomGetVnum(room);
+   return (PyObject *)py_room;
+ }
diff -crN nakedmudv1.0/src/scripts/pyroom.h nakedmudv1.4/src/scripts/pyroom.h
*** nakedmudv1.0/src/scripts/pyroom.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/pyroom.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,22 ----
+ #ifndef __PYROOM_H
+ #define __PYROOM_H
+ //*****************************************************************************
+ //
+ // pyroom.h
+ //
+ // A python extention to allow python scripts to treat MUD rooms as an
+ // object within the script.
+ //
+ //*****************************************************************************
+ 
+ /* initialize characters for use */
+ PyMODINIT_FUNC
+ init_PyRoom(void);
+ 
+ int PyRoom_AsVnum(PyObject *room);
+ int PyRoom_Check(PyObject *value);
+ 
+ PyObject *
+ newPyRoom(ROOM_DATA *room);
+ 
+ #endif //__PYROOM_H
diff -crN nakedmudv1.0/src/scripts/README nakedmudv1.4/src/scripts/README
*** nakedmudv1.0/src/scripts/README	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/README	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,182 ----
+ If you are having problems installing scripts, you will want to read the 
+ documentation in src/modules/scripts/Makefile. This file is an explanation of
+ how to interact with scripts.
+ 
+ Scripting is a powerful method for adding character to your MUD. It essentially
+ allows you to edit (simple) code that will modify the way rooms, players, and
+ objects work. This scripting module uses Python (http://www.python.org) to run
+ scripts. It will probably be a good idea to get an understanding of the basic
+ python syntax before doing any scripting. Python is a relatively easy language
+ to learn - even for non-programmers - and that was why it was chosen as the
+ scripting language.
+ 
+ The scripting module for NakedMud adds a couple things to Python, so that it can
+ interact with the different types of data in the MUD (see pychar.c, pyobj.c,
+ pyroom.c, and pymud.c). Below is a quick synopsis of the various ways Python
+ can work with the MUD's data. For documentation on what specific script types
+ are used for, and how, see script.h in this directory.
+ 
+ 
+ 
+ ********************************************************************************
+ ****************************** PYTHON CHARACTERS *******************************
+ ********************************************************************************
+ The following variables are accessable on Python characters:
+   ch.inv         return a list of the items in the character's inventory
+   ch.objs        same as ch.inv
+   ch.is_npc      return true or false if the character is an NPC
+   ch.is_pc       return true or false if the character is a PC
+   ch.uid         get the character's unique ID (not settable)
+   ch.name        get/set a character's name
+   ch.desc        get/set a character's description
+   ch.rdesc       get/set a character's room description
+   ch.level       get/set a character's level
+   ch.on          get/set the furniture the character is sitting on
+   ch.vnum        get/set the character's virtual number
+   ch.sex         get/set a character's sex. Sex must be in string form 
+                  (e.g. 'male', 'female', or 'neutral')
+   ch.race        get/set a character's race. Race must be in string form
+                  (e.g. 'human', 'elf', 'dragon')
+   ch.position    get/set a character's position. Position must be in string form
+                  (e.g. 'sitting', 'standing')
+   ch.room        get/set a character's room. When setting, a room, either
+                  a room vnum can be used, or an actual room object (see pyroom).
+ 
+ 
+ The following functions are available for use with Python characters:
+   
+ SENDING MESSAGES
+ ch.send('message')
+ example: ch.send('hello, world!')
+ Send a character a text message.
+ 
+ PERFORMING ACTIONS
+ ch.act('command')
+ example: ch.act('say hello, world!')
+ Force a character to perform a specific action.
+ 
+ STORING SCRIPT DATA
+ ch.setvar('varname', value)
+ example: ch.setvar('blackjack_winnings', 100)
+ Allows you to store information on a character, regarding stuff that happened
+ during the script. These variables save over reboots and crashes. The only
+ restriction is that the variables must be integer values.
+ 
+ RETRIEVING SCRIPT DATA
+ ch.getvar('varname')
+ example: winnings = ch.getvar('blackjack_winnings')
+ Retrieve set data. If the variable has not been set yet, 0 is returned.
+ 
+ LOADING NEW MOBILES
+ load_mob(vnum, to)
+ example: new_mob = load_mob(100, 120)
+ Load a new mobile to the specified target. The first value is the mob's vnum
+ 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
+ a vnum if -1 is used, PCs are counted.
+ 
+ 
+ 
+ ********************************************************************************
+ ******************************** PYTHON OBJECTS ********************************
+ ********************************************************************************
+ The following variables are accessable on Python mud objects:
+   obj.contents    return a list of the things stored within the object
+   obj.objs        same as obj.contents
+   obj.chars       return the people sitting on the object
+   obj.uid         return the unique ID of the object. Not settable
+   obj.name        get/set the object's name
+   obj.desc        get/set the object's description
+   obj.rdesc       get/set the object's room description
+   obj.vnum        get/set the object's vnum
+ 
+ 
+ The following functions are available for use with Python mud objects:
+ LOADING NEW OBJECTS
+ load_obj(vnum, where, bodypart = NONE)
+ Load an object with the specified vnum to "where". Where can be a container,
+ a room, or a character. If a character is provided but a list of bodyparts
+ is not, then the object is loaded to inventory. If a list of bodyparts are
+ provided, the mobile will try to equip the object to those bodyparts. If, for
+ bodyparts, an empty string (e.g. '') is used, then the mobile will try to
+ equip the item to the first open, viable slots.
+ 
+ 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. 
+ 
+ 
+ 
+ ********************************************************************************
+ ********************************* PYTHON ROOMS *********************************
+ ********************************************************************************
+ The following variables are accessable on Python rooms:
+   room.chars      return a list of characters in the room
+   room.contents   return a lsit of objects in the room
+   room.objs       same as room.contents
+   room.vnum       return the virtual number of the room
+ 
+ 
+ The following functions are available for use with Python mud objects:
+ CLOSING DOORS
+ room.close('direction')
+ example: room.close('north')
+ Try to close the door in a specified direction, if a door and direction exist.
+ If the door was previously locked, it is unlocked.
+ 
+ OPENING DOORS
+ room.open('direction')
+ example: room.open('east')
+ Try to open the door in a specified direction, if a door and direction exist.
+ If the door was previously locked, it is unlocked.
+ 
+ LOCKING DOORS
+ room.lock('direction')
+ example: room.lock('up')
+ Try to lock the door in a specified direction, if a door and direction exist.
+ If the door was previously open, it is closed.
+ 
+ UNLOCKING DOORS
+ room.unlock('direction')
+ example: room.unlock('down')
+ Try to unlock the door in a specified direction, if a door and direction exist.
+ 
+ 
+ 
+ ********************************************************************************
+ ******************************* GLOBAL VARIABLES *******************************
+ ********************************************************************************
+ There are times when one might want to save a piece of information, but not
+ specifically on a character. Global variables allow for this. In addition,
+ global variables can be ANY type of value (string, integer, a character, a
+ room, you name it). However, global variables do not save over crashes.
+ 
+ SETTING GLOBAL VARIABLES
+ set_global('key', val)
+ example: set_global('bobs_killer', ch)
+ Allows you to store the value of a variable globally, which can be accessed
+ by other scripts, or by the same script at a later time.
+ 
+ RETREIVING THE VALUES OF GLOBAL VARIABLES
+ get_global('key')
+ example: killer = get_global('bobs_killer')
+ Retreive the value of a global variable. If the variable has not been set,
+ then None is returned.
+ 
+ ERASING A GLOBAL VARIABLE
+ erase_global('key')
+ example: erase_global('bobs_killer')
+ Erase the value of the global variable. Effectively, this is the same as
+ setting the variable's value to None.
diff -crN nakedmudv1.0/src/scripts/script.c nakedmudv1.4/src/scripts/script.c
*** nakedmudv1.0/src/scripts/script.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/script.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,708 ----
+ //*****************************************************************************
+ //
+ // script.c
+ //
+ // All of the information regarding scripts, from the functions to run them
+ // and all of the different script types.
+ //
+ //*****************************************************************************
+ 
+ // script stuff
+ #include <Python.h>
+ #include <structmember.h>
+ 
+ // mud stuff
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../socket.h"
+ #include "../character.h"
+ #include "../room.h"
+ #include "../object.h"
+ #include "../storage.h"
+ #include "../auxiliary.h"
+ 
+ #include "script.h"
+ #include "script_set.h"
+ #include "pychar.h"
+ #include "pyroom.h"
+ #include "pyobj.h"
+ #include "pymud.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // Auxiliary script data that we need to install into players, objects and
+ // rooms. Essentially, this just allows these datastructures to actually have
+ // scripts installed on them.
+ //
+ //*****************************************************************************
+ typedef struct script_aux_data {
+   SCRIPT_SET *scripts;    // the set of scripts that we have
+ } SCRIPT_AUX_DATA;
+ 
+ SCRIPT_AUX_DATA *
+ newScriptAuxData() {
+   SCRIPT_AUX_DATA *data = malloc(sizeof(SCRIPT_AUX_DATA));
+   data->scripts = newScriptSet();
+   return data;
+ }
+ 
+ void
+ deleteScriptAuxData(SCRIPT_AUX_DATA *data) {
+   deleteScriptSet(data->scripts);
+   free(data);
+ }
+ 
+ void
+ scriptAuxDataCopyTo(SCRIPT_AUX_DATA *from, SCRIPT_AUX_DATA *to) {
+   copyScriptSetTo(from->scripts, to->scripts);
+ }
+ 
+ SCRIPT_AUX_DATA *
+ scriptAuxDataCopy(SCRIPT_AUX_DATA *data) {
+   SCRIPT_AUX_DATA *newdata = newScriptAuxData();
+   scriptAuxDataCopyTo(data, newdata);
+   return newdata;
+ }
+ 
+ SCRIPT_AUX_DATA *
+ scriptAuxDataRead(STORAGE_SET *set) {
+   SCRIPT_AUX_DATA  *data = newScriptAuxData();
+   STORAGE_SET_LIST *list = read_list(set, "scripts");
+   STORAGE_SET    *script = NULL;
+   while( (script = storage_list_next(list)) != NULL)
+     scriptSetAdd(data->scripts, read_int(script, "vnum"));
+   return data;
+ }
+ 
+ STORAGE_SET *
+ scriptAuxDataStore(SCRIPT_AUX_DATA *data) {
+   STORAGE_SET       *set = new_storage_set();
+   STORAGE_SET_LIST *list = new_storage_list();
+   LIST          *scripts = scriptSetList(data->scripts, SCRIPT_TYPE_ANY);
+   SCRIPT_DATA    *script = NULL;
+   store_list(set, "scripts", list, NULL);
+   while((script = listPop(scripts)) != NULL) {
+     STORAGE_SET *scriptset = new_storage_set();
+     store_int(scriptset, "vnum", scriptGetVnum(script), NULL);
+     storage_list_put(list, scriptset);
+   }
+   deleteList(scripts);
+   return set;
+ }
+ 
+ 
+ //*****************************************************************************
+ //
+ // functions for getting script data from various datastructures
+ //
+ //*****************************************************************************
+ SCRIPT_SET *roomGetScripts(const ROOM_DATA *room) {
+   SCRIPT_AUX_DATA *data = roomGetAuxiliaryData(room, "script_aux_data");
+   return data->scripts;
+ }
+ 
+ void roomSetScripts(ROOM_DATA *room, SCRIPT_SET *scripts) {
+   SCRIPT_AUX_DATA *data = roomGetAuxiliaryData(room, "script_aux_data");
+   if(data->scripts) deleteScriptSet(data->scripts);
+   data->scripts = scripts;
+ }
+ 
+ SCRIPT_SET *objGetScripts(const OBJ_DATA *obj) {
+   SCRIPT_AUX_DATA *data = objGetAuxiliaryData(obj, "script_aux_data");
+   return data->scripts;
+ }
+ 
+ void objSetScripts(OBJ_DATA *obj, SCRIPT_SET *scripts) {
+   SCRIPT_AUX_DATA *data = objGetAuxiliaryData(obj, "script_aux_data");
+   if(data->scripts) deleteScriptSet(data->scripts);
+   data->scripts = scripts;
+ }
+ 
+ SCRIPT_SET *charGetScripts(const CHAR_DATA *ch) {
+   SCRIPT_AUX_DATA *data = charGetAuxiliaryData(ch, "script_aux_data");
+   return data->scripts;
+ }
+ 
+ void charSetScripts(CHAR_DATA *ch, SCRIPT_SET *scripts) {
+   SCRIPT_AUX_DATA *data = charGetAuxiliaryData(ch, "script_aux_data");
+   if(data->scripts) deleteScriptSet(data->scripts);
+   data->scripts = scripts;
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // functions 'n such for the script object
+ //
+ //*****************************************************************************
+ struct script_data {
+   script_vnum vnum;
+   int         type;
+   char       *name;
+   char       *args;
+   int      num_arg;
+   char       *code;
+ };
+ 
+ const char *script_type_info[NUM_SCRIPTS] = {
+   "Initialization",
+   "Speech",
+   "Drop",
+   "Give/Receive",
+   "Enter",
+   "Exit",
+   "Command"
+ };
+ 
+ const char *scriptTypeName(int num) {
+   return script_type_info[num];
+ }
+ 
+ SCRIPT_DATA *newScript() {
+   SCRIPT_DATA *script = malloc(sizeof(SCRIPT_DATA));
+   bzero(script, sizeof(*script));
+   
+   script->vnum = NOTHING;
+   script->type = SCRIPT_TYPE_INIT;
+ 
+   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;
+ }
+ 
+ STORAGE_SET *scriptStore(SCRIPT_DATA *script) {
+   STORAGE_SET *set = new_storage_set();
+   store_int   (set, "vnum", script->vnum, NULL);
+   store_int   (set, "type", script->type, NULL);
+   store_int   (set, "narg", script->num_arg, NULL);
+   store_string(set, "name", script->name, NULL);
+   store_string(set, "args", script->args, NULL);
+   store_string(set, "code", script->code, NULL);
+   return set;
+ }
+ 
+ 
+ SCRIPT_DATA *scriptCopy(SCRIPT_DATA *script) {
+   SCRIPT_DATA *newscript = newScript();
+   scriptCopyTo(script, newscript);
+   return newscript;
+ }
+ 
+ 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;
+   to->num_arg = from->num_arg;
+ }
+ 
+ script_vnum scriptGetVnum(SCRIPT_DATA *script) {
+   return script->vnum;
+ }
+ 
+ int         scriptGetType(SCRIPT_DATA *script) {
+   return script->type;
+ }
+ 
+ int         scriptGetNumArg(SCRIPT_DATA *script) {
+   return script->num_arg;
+ }
+ 
+ const char *scriptGetArgs(SCRIPT_DATA *script) {
+   return script->args;
+ }
+ 
+ const char *scriptGetName(SCRIPT_DATA *script) {
+   return script->name;
+ }
+ 
+ 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) {
+   script->vnum = vnum;
+ }
+ 
+ void scriptSetType(SCRIPT_DATA *script, int type) {
+   script->type = type;
+ }
+ 
+ void scriptSetNumArg(SCRIPT_DATA *script, int num_arg) {
+   script->num_arg = num_arg;
+ }
+ 
+ void scriptSetArgs(SCRIPT_DATA *script, const char *args) {
+   if(script->args) free(script->args);
+   script->args = strdup(args ? args : "");
+ }
+ 
+ void scriptSetName(SCRIPT_DATA *script, const char *name) {
+   if(script->name) free(script->name);
+   script->name = strdup(name ? name : "");
+ }
+ 
+ void scriptSetCode(SCRIPT_DATA *script, const char *code) {
+   if(script->code) free(script->code);
+   script->code = strdup(code ? code : "");
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // stuff we need for trying to run scripts
+ //
+ //*****************************************************************************
+ 
+ //
+ // Many thanks to Xanthros who pointed out that, if two scripts trigger
+ // 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--;
+ }
+ 
+ 
+ void init_scripts() {
+   // initialize python
+   Py_Initialize();
+ 
+   // initialize modules
+   init_PyChar();
+   init_PyRoom();
+   init_PyObj();
+   init_PyMud();
+ 
+ 
+   // initialize our auxiliary data
+   auxiliariesInstall("script_aux_data",
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_ROOM | AUXILIARY_TYPE_OBJ|
+ 				       AUXILIARY_TYPE_CHAR,
+ 				       newScriptAuxData, deleteScriptAuxData,
+ 				       scriptAuxDataCopyTo, scriptAuxDataCopy,
+ 				       scriptAuxDataStore, scriptAuxDataRead));
+ }
+ 
+ 
+ void finalize_scripts() {
+   Py_Finalize();
+ }
+ 
+ 
+ void run_script(const char *script, void *me, int me_type,
+ 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit, 
+ 		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");
+   //    i += snprintf(buf+i, MAX_SCRIPT - i - 1, "from exit 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));
+   else if(me_type == SCRIPTOR_EXIT)
+     ;
+ 
+   // 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);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // Stuff we need for formatting and coloring scripts on screen
+ //
+ //*****************************************************************************
+ void format_script(char **script, int max_len) {
+   // python chokes on carriage returns
+   replace_string(script, "\r", "", TRUE);
+ }
+ 
+ 
+ //
+ // Control we need to highlight
+ //
+ const char *control_table[] = {
+   "while",
+   "elif",
+   "else",
+   "def",
+   "for",
+   "if",
+   "in",
+   "is",
+   "and",
+   "or",
+   "not",
+   NULL
+ };
+ 
+ 
+ //
+ // returns which control string we found. returns
+ // -1 if none were found
+ //
+ int check_for_control(const char *ptr, int i) {
+   int syn_i;
+   for(syn_i = 0; control_table[syn_i] != NULL; syn_i++) {
+     int len = strlen(control_table[syn_i]);
+     // not enough characters for it to exist
+     if(i - len + 1 < 0)
+       continue;
+     // we found it might have found it. Check to make
+     // sure that we are surrounded by spaces or colons
+     if(!strncasecmp(ptr+i-len+1, control_table[syn_i], len)) {
+       // check the left side first
+       if(!(i - len < 0 || isspace(ptr[i-len]) || ptr[i-len] == ':'))
+ 	continue;
+       //  and now the right side
+       if(!(ptr+i+1 == '\0' || isspace(ptr[i+1]) || ptr[i+1] == ':'))
+ 	continue;
+ 
+       return syn_i;
+     }
+   }
+ 
+   // didn't find any
+   return -1;
+ }
+ 
+ 
+ void script_display(SOCKET_DATA *sock, const char *script, bool show_line_nums){
+   const char *ptr = script;//buffer_string(sock->text_editor);
+   char line[SMALL_BUFFER] = "\0";
+   int  line_num = 1;
+   int  line_i = 0, i = 0;
+   bool in_line_comment = FALSE; // are we displaying a comment?
+   bool in_digit = FALSE;        // are we displaying a digit?
+   bool in_string  = FALSE;      // how about a string?
+   char string_type = '"';       // what kinda string marker is it? ' or " ?
+   int  syn_to_color = -1;       // if we're coloring flow control, which one?
+ 
+   for(i = 0; ptr[i] != '\0'; i++) {
+     // take off the color for digits
+     if(in_digit && !isdigit(ptr[i])) {
+       sprintf(line+line_i, "{g");
+       line_i += 2;
+       in_digit = FALSE;
+     } // NO ELSE ... we might need to color something else
+ 
+     // transfer over the character
+     line[line_i] = ptr[i];
+ 
+     // if the character is a #, color the comment red
+     if(ptr[i] == '#') {
+       sprintf(line+line_i, "{r#");
+       line_i += 3;
+       in_line_comment = TRUE;
+     }
+ 
+     // we've found a digit that we have to color in
+     else if(isdigit(ptr[i]) && !in_digit && !in_line_comment && !in_string) {
+       sprintf(line+line_i, "{y%c", ptr[i]);
+       line_i += 3;
+       in_digit = TRUE;
+     }
+ 
+     // if we've found a string marker, color/uncolor it
+     else if((ptr[i] == '"' || ptr[i] == '\'') && !in_line_comment &&
+ 	    // if we're already coloring a string and the marker
+ 	    // types don't match up, then don't worry about it
+ 	    !(in_string && string_type != ptr[i])) {
+ 
+       if(in_string && ptr[i] == string_type)
+ 	sprintf(line+line_i, "\%c{g", string_type);
+       else
+ 	sprintf(line+line_i, "{w%c", ptr[i]);
+       
+       line_i += 3;
+       in_string = (in_string + 1) % 2;
+       string_type = ptr[i];
+     }
+ 
+     // we've hit a new line
+     else if(ptr[i] == '\n') {
+ 
+ 	// do we need to show line numbers
+ 	char line_num_info[20];
+ 	if(show_line_nums)
+ 	  sprintf(line_num_info, "{c%2d]  ", line_num);
+ 	else
+ 	  *line_num_info = '\0';
+ 
+ 	line[line_i] = '\0';
+ 	send_to_socket(sock, "%s{g%s\r\n", line_num_info, line);
+ 	*line = '\0';
+ 	line_i = 0;
+ 	line_num++;
+ 	in_line_comment = in_string = FALSE; // reset on newline
+     }
+ 
+     // checking while, for, if, else, elif, etc...
+     // this is kinda tricky. We have to backtrack and check some stuff
+     else if(!(in_line_comment || in_digit || in_string) &&
+ 	    (syn_to_color = check_for_control(ptr, i)) != -1) {
+       sprintf(line+line_i-strlen(control_table[syn_to_color])+1,
+ 	      "{p%s{g", control_table[syn_to_color]);
+       line_i += 5; // the two markers for the color, and one for new character
+     }
+ 
+     // didn't find anything of interest
+     else
+ 	line_i++;
+   }
+ 
+   line[line_i] = '\0';
+   // send the last line
+   if(*line)
+     send_to_socket(sock, "{c%2d]{g  %s\r\n", line_num, line);
+   // there was nothing on the first line
+   else if(line_num == 1)
+     send_to_socket(sock, "The buffer is empty.\r\n");
+ 
+   if(ptr[strlen(ptr)-1] != '\n')
+     send_to_socket(sock, "Buffer does not end in newline!\r\n");
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // tries for various speech triggers
+ //
+ //*****************************************************************************
+ void try_speech_script_with(CHAR_DATA *ch, CHAR_DATA *listener, char *speech) {
+   LIST *speech_scripts = scriptSetList(charGetScripts(listener), 
+ 				       SCRIPT_TYPE_SPEECH);
+   SCRIPT_DATA *script = NULL;
+ 
+   while( (script = listPop(speech_scripts)) != NULL) {
+     if(is_keyword(scriptGetArgs(script), speech, FALSE)) {
+       run_script(scriptGetCode(script),
+ 		 listener, SCRIPTOR_CHAR,
+ 		 ch, NULL, charGetRoom(listener), NULL, NULL, speech, 0);
+     }
+   }
+   deleteList(speech_scripts);
+ }
+ 
+ void try_speech_script(CHAR_DATA *ch, CHAR_DATA *listener, char *speech) {
+   if(listener != NULL)
+     try_speech_script_with(ch, listener, speech);
+   else {
+     LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(charGetRoom(ch)));
+     ITERATE_LIST(listener, char_i)
+       try_speech_script_with(ch, listener, speech);
+     deleteListIterator(char_i);
+   }
+ }
+ 
+ 
+ void try_enterance_script(CHAR_DATA *ch, ROOM_DATA *room, 
+ 			  EXIT_DATA *exit, const char *dirname) {
+   // check the room
+   try_scripts(SCRIPT_TYPE_ENTER,
+ 	      room, SCRIPTOR_ROOM,
+ 	      ch, NULL, room, exit, dirname, NULL, 0);
+ 
+   // check everyone in the room
+   LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room));
+   CHAR_DATA *greeter = NULL;
+   ITERATE_LIST(greeter, char_i) {
+     if(greeter == ch) 
+       continue;
+     try_scripts(SCRIPT_TYPE_ENTER,
+ 		greeter, SCRIPTOR_CHAR,
+ 		ch, NULL, room, exit, dirname, NULL, 0);
+   }
+   deleteListIterator(char_i);
+ }
+ 
+ 
+ void try_exit_script(CHAR_DATA *ch, ROOM_DATA *room, 
+ 		     EXIT_DATA *exit, const char *dirname) {
+   // check the room
+   try_scripts(SCRIPT_TYPE_EXIT,
+ 	      room, SCRIPTOR_ROOM,
+ 	      ch, NULL, room, exit, dirname, NULL, 0);
+ 
+   // check everyone in the room
+   LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room));
+   CHAR_DATA *watcher = NULL;
+   while( (watcher = listIteratorCurrent(char_i)) != NULL) {
+     listIteratorNext(char_i);
+     if(watcher == ch) 
+       continue;
+     try_scripts(SCRIPT_TYPE_EXIT,
+ 		watcher, SCRIPTOR_CHAR,
+ 		ch, NULL, room, exit, dirname, NULL, 0);
+   }
+   deleteListIterator(char_i);
+ }
+ 
+ 
+ int try_command_script(CHAR_DATA *ch, const char *cmd, const char *arg) {
+   int retval = 0;
+ 
+   // the room had a command script, and we have
+   // to halt the normal command from going through
+   if(try_scripts(SCRIPT_TYPE_COMMAND,
+ 		 charGetRoom(ch), SCRIPTOR_ROOM,
+ 		 ch, NULL, charGetRoom(ch), NULL, cmd, arg, 0))
+     retval = 1;
+ 
+   // check everyone in the room
+   LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(charGetRoom(ch)));
+   CHAR_DATA *scriptor = NULL;
+   while( (scriptor = listIteratorCurrent(char_i)) != NULL) {
+     listIteratorNext(char_i);
+     if(scriptor == ch) 
+       continue;
+     if(try_scripts(SCRIPT_TYPE_COMMAND,
+ 		   scriptor, SCRIPTOR_CHAR,
+ 		   ch, NULL, charGetRoom(ch), NULL, cmd, arg, 0))
+       retval = 1;
+   }
+   deleteListIterator(char_i);
+   return retval;
+ }
+ 
+ 
+ int try_scripts(int script_type,
+ 		void *me, int me_type,
+ 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit,
+ 		const char *cmd, const char *arg, int narg) {
+   int retval = 0;
+   LIST *scripts = NULL;
+   SCRIPT_DATA *script = NULL;
+ 
+   if(me_type == SCRIPTOR_CHAR)
+     scripts = scriptSetList(charGetScripts(me), script_type);
+   if(me_type == SCRIPTOR_ROOM)
+     scripts = scriptSetList(roomGetScripts(me), script_type);
+   if(me_type == SCRIPTOR_OBJ)
+     scripts = scriptSetList(objGetScripts(me), script_type);
+   /*
+   if(me_type == SCRIPTOR_EXIT)
+     scripts = scriptSetGetList(exitGetScripts(me), script_type);
+   */
+ 
+   // see if we meet the script requirements
+   while( (script = listPop(scripts)) != NULL) {
+     // make specific checks by script type
+     switch(scriptGetType(script)) {
+     case SCRIPT_TYPE_GIVE:
+     case SCRIPT_TYPE_ENTER:
+     case SCRIPT_TYPE_EXIT:
+       // if the scriptor is a char and narg is 1,
+       // we have to make sure we can see the character
+       // before we run the script
+       if(me_type == SCRIPTOR_CHAR && 
+ 	 scriptGetNumArg(script) == 1 &&
+ 	 ch && !can_see_char(me, ch))
+ 	continue;
+       break;
+ 
+     case SCRIPT_TYPE_COMMAND:
+       // if the keyword isn't on our list, continue
+       if(!is_keyword(scriptGetArgs(script), cmd, FALSE))
+ 	continue;
+       // if the numeric argument of the script is 1,
+       // we need to switch our retval to 1 and return
+       // it so we know not to carry on with the normal command
+       if(scriptGetNumArg(script) == 1)
+ 	retval = 1;
+       break;
+ 
+     default:
+       break;
+     }
+ 
+     run_script(scriptGetCode(script), me, me_type,
+ 	       ch, obj, room, exit, cmd, arg, narg);    
+   }
+   deleteList(scripts);
+   return retval;
+ }
diff -crN nakedmudv1.0/src/scripts/script.h nakedmudv1.4/src/scripts/script.h
*** nakedmudv1.0/src/scripts/script.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/script.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,273 ----
+ #ifndef __SCRIPT_H
+ #define __SCRIPT_H
+ //*****************************************************************************
+ //
+ // script.h
+ //
+ // All of the information regarding scripts, from the functions to run them
+ // and all of the different script types.
+ //
+ //*****************************************************************************
+ 
+ //
+ // This must be put at the top of mud.h so the rest of the MUD knows that
+ // we've got the scripts module installed
+ // #define MODULE_SCRIPTS
+ //
+ 
+ //*****************************************************************************
+ //                            SCRIPT DOCUMENTATION
+ //*****************************************************************************
+ // SCRIPT_TYPE_INIT
+ //   Description:
+ //     runs when the scriptor is loaded for the first time, or reset in the
+ //     case of rooms.
+ //   String Arguments:
+ //     None
+ //   Numeric Argument:
+ //     None
+ //   Works with:
+ //     rooms, objects, mobiles
+ //   Parameters:
+ //     me   = ourself
+ //     ch   = the character loaded to (if applicable)
+ //     room = the room loaded to (if applicable)
+ //     obj  = the container loaded to (if applicable)
+ 
+ //*****************************************************************************
+ // SCRIPT_TYPE_SPEECH
+ //   Description:
+ //     Runs when the scriptor hears a person in the room say something. This
+ //     can be through say or ask.
+ //   Arguments:
+ //     a comma-separated list of keywords that the script triggers off of
+ //   Numeric Argument:
+ //     None
+ //   Works with:
+ //     mobiles
+ //   Parameters:
+ //     me   = ourself
+ //     ch   = the person talking
+ //     room = the room the speech trigger occured in
+ //     arg  = the speech that was said
+ 
+ //*****************************************************************************
+ // SCRIPT_TYPE_DROP
+ //   Description:
+ //     Runs when the scriptor is dropped (obj) or has something drop to 
+ //     it (room)
+ //   Arguments:
+ //     None
+ //   Numeric Argument:
+ //     None
+ //   Works with:
+ //     rooms, objects
+ //   Parameters:
+ //     me   = ourself
+ //     ch   = the character doing the dropping
+ //     room = the room dropped to (if applicable) or ourself
+ //     obj  = the object that was dropped to us (if applicable) or ourself
+ 
+ //*****************************************************************************
+ // SCRIPT_TYPE_GIVE
+ //   Description:
+ //     Runs when an object is given to the scriptor, or the scriptor is
+ //     given (in the case that the scriptor is an object)
+ //   Arguments:
+ //     None
+ //   Numeric Arguments:
+ //     1 if the receiver needs to see the character. 0 otherwise.
+ //   Works with:
+ //     objects, mobiles
+ //   Parameters:
+ //     me   = ourself
+ //     ch   = the character doing the giving
+ //     room = the room the giving is being done in
+ //     obj  = the object being given (if applicable) or ourself
+ 
+ //*****************************************************************************
+ // SCRIPT_TYPE_ENTER
+ //   Description:
+ //     Runs when a character enters the room we are in, or enters us
+ //     in the case that we are a room
+ //   Arguments:
+ //     None
+ //   Numeric Arguments:
+ //     1 if me (a mob watching) needs to see the character. 0 otherwise
+ //   Works with:
+ //     rooms, mobiles
+ //   Parameters:
+ //     me   = ourself
+ //     ch   = the character entering the room
+ //     room = the room we are in (if applicable) or ourself
+ 
+ //*****************************************************************************
+ // SCRIPT_TYPE_EXIT
+ //   Description:
+ //     Runs when a character exits a room.
+ //   Arguments:
+ //     None
+ //   Numeric Arguments:
+ //     1 if me (a mob watching) needs to see the character. 0 otherwise
+ //   Works with:
+ //     rooms, mobiles.
+ //   Parameters:
+ //     me   = ourself
+ //     ch   = the character exiting
+ //     room = the room being left (if applicable) or ourself
+ //     cmd  = the direction that ch left through
+ 
+ //*****************************************************************************
+ // SCRIPT_TYPE_COMMAND
+ //   Description:
+ //     Runs when a character enters a command in the argument list
+ //   Arguments:
+ //     A comma-separated list of commands that trigger this script
+ //   Numeric Arguments:
+ //     0 if the normal command should be followed through with afterwards
+ //     1 otherwise
+ //   Works with:
+ //     rooms, mobiles
+ //   Parameters:
+ //     me   = ourself
+ //     ch   = the person using a command
+ //     room = the room the command was issued in
+ //     cmd  = the command
+ //     arg  = the argument supplied to the command
+ 
+ //*****************************************************************************
+ #define SCRIPT_TYPE_NONE          (-1)
+ #define SCRIPT_TYPE_INIT            0 // when the room/mob/obj resets or loads
+ #define SCRIPT_TYPE_SPEECH          1 // when someone says a keyword
+ #define SCRIPT_TYPE_DROP            2 // when obj is dropped
+ #define SCRIPT_TYPE_GIVE            3 // when obj is given
+ #define SCRIPT_TYPE_ENTER           4 // when a char enters the room
+ #define SCRIPT_TYPE_EXIT            5 // when the character exits the room 
+ #define SCRIPT_TYPE_COMMAND         6 // when a command is issued
+ #define NUM_SCRIPTS                 7
+ 
+ 
+ const char *scriptTypeName(int num);
+ 
+ SCRIPT_DATA *newScript   ();
+ void         deleteScript(SCRIPT_DATA *script);
+ 
+ STORAGE_SET *scriptStore(SCRIPT_DATA *script);
+ SCRIPT_DATA *scriptRead (STORAGE_SET *set);
+ 
+ SCRIPT_DATA *scriptCopy(SCRIPT_DATA *script);
+ void         scriptCopyTo(SCRIPT_DATA *from, SCRIPT_DATA *to);
+ 
+ script_vnum scriptGetVnum(SCRIPT_DATA *script);
+ int         scriptGetType(SCRIPT_DATA *script);
+ int         scriptGetNumArg(SCRIPT_DATA *script);
+ 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);
+ void scriptSetNumArg(SCRIPT_DATA *script, int num_arg);
+ void scriptSetArgs(SCRIPT_DATA *script, const char *args);
+ void scriptSetName(SCRIPT_DATA *script, const char *name);
+ void scriptSetCode(SCRIPT_DATA *script, const char *code);
+ 
+ 
+ //
+ // Functions for accessing auxiliary script data in 
+ // rooms, characters, and objects.
+ //
+ SCRIPT_SET *roomGetScripts(const ROOM_DATA *room);
+ void        roomSetScripts(ROOM_DATA *room, SCRIPT_SET *scripts);
+ SCRIPT_SET *objGetScripts(const OBJ_DATA *obj);
+ void        objSetScripts(OBJ_DATA *obj, SCRIPT_SET *scripts);
+ SCRIPT_SET *charGetScripts(const CHAR_DATA *mob);
+ void        charSetScripts(CHAR_DATA *mob, SCRIPT_SET *scripts);
+ 
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // The interface for running scripts
+ //
+ //*****************************************************************************
+ 
+ // different types for things that can trigger/have a script
+ #define SCRIPTOR_NONE         (-1)
+ #define SCRIPTOR_CHAR           0
+ #define SCRIPTOR_ROOM           1
+ #define SCRIPTOR_OBJ            2
+ #define SCRIPTOR_EXIT           3
+ 
+ //
+ // initialize the scripting system
+ //
+ void init_scripts();
+ 
+ //
+ // Shut scripts down
+ //
+ void finalize_scripts();
+ 
+ 
+ //
+ // start up a script
+ //
+ void run_script(const char *script, void *me, int me_type,
+ 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit, 
+ 		const char *cmd, const char *arg, int narg);
+ 
+ //
+ // format a string so that it is a viable script
+ //
+ void format_script(char **script, int max_len);
+ 
+ 
+ //
+ // Show a script to the socket
+ //
+ void script_display(SOCKET_DATA *sock, const char *script, bool show_line_nums);
+ 
+ 
+ //
+ // See if a speech script needs to be triggered. If listener == NULL,
+ // everyone in the room is checked. If a listener is provided, then 
+ // only the listener is checked
+ //
+ void try_speech_script(CHAR_DATA *ch, CHAR_DATA *listener, char *speech);
+ 
+ 
+ //
+ // Try enterance scripts in the given room (the room itself, and mobs)
+ //
+ void try_enterance_script(CHAR_DATA *ch, ROOM_DATA *room, 
+ 			  EXIT_DATA *exit, const char *dirname);
+ 
+ //
+ // Try exit scripts in the given room (the room itself, and mobs)
+ //
+ void try_exit_script(CHAR_DATA *ch, ROOM_DATA *room, 
+ 		     EXIT_DATA *exit, const char *dirname);
+ 
+ //
+ // Searches for command scripts in the room. If the actual command should
+ // be followed through with, returns 0. If the actual command should be
+ // prevented, returns 1.
+ //
+ int  try_command_script(CHAR_DATA *ch, const char *cmd, const char *arg);
+ 
+ //
+ // Check for and run scripts of the given type found on the scriptor.
+ // If the return value is non-zero, then whatever function that is checking
+ // the script needs to be halted (e.g. if it is a command script, the command
+ // parser should not continue checking for a normal command in the command list,
+ // if the character is giving an object, the give should not complete, etc...)
+ //
+ int try_scripts(int script_type,
+ 		void *me, int me_type,
+ 		CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit,
+ 		const char *cmd, const char *arg, int narg);
+ 
+ #endif //__SCRIPT_H
diff -crN nakedmudv1.0/src/scripts/script_set.c nakedmudv1.4/src/scripts/script_set.c
*** nakedmudv1.0/src/scripts/script_set.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/script_set.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,78 ----
+ //*****************************************************************************
+ //
+ // script_set.c
+ //
+ // A container of script numbers an object, mob, room, etc... may have. Provides
+ // functions to make it easy to extract lists of scripts in the set that conform
+ // to certain properties (e.g. all speech scripts, exit scripts, etc).
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../world.h"
+ 
+ #include "script_set.h"
+ #include "script.h"
+ 
+ 
+ struct script_set_data {
+   LIST *script_vnums; // LIST is typically used for pointers, but because
+                       // they are the same number of bits as an int, we can
+                       // use them to store script vnum values as well
+ };
+ 
+ SCRIPT_SET *newScriptSet() {
+   SCRIPT_SET *set = malloc(sizeof(SCRIPT_SET));
+   set->script_vnums = newList();
+   return set;
+ }
+ 
+ void deleteScriptSet(SCRIPT_SET *set) {
+   // we don't have to delete any of the elements in here, since
+   // we are not actually using the list to point to anything
+   deleteList(set->script_vnums);
+   free(set);
+ }
+ 
+ void scriptSetAdd   (SCRIPT_SET *set, script_vnum vnum) {
+   listQueue(set->script_vnums, (void *)vnum);
+ }
+ 
+ void scriptSetRemove(SCRIPT_SET *set, script_vnum vnum) {
+   listRemove(set->script_vnums, (void *)vnum);
+ }
+ 
+ LIST *scriptSetList (SCRIPT_SET *set, int type) {
+   LIST *scripts = newList();
+   int i = 0, script_vnum = NOTHING;
+ 
+   //*************************************
+   // USE A LIST ITERATOR TO OPTIMIZE THIS
+   //*************************************
+   for(i = 0; i < listSize(set->script_vnums); i++) {
+     script_vnum = (int)listGet(set->script_vnums, i);
+     SCRIPT_DATA *script = worldGetScript(gameworld, script_vnum);
+     if(script != NULL &&
+        (type == SCRIPT_TYPE_NONE || scriptGetType(script) == type))
+       listPut(scripts, script);
+   }
+   return scripts;
+ }
+ 
+ void copyScriptSetTo(SCRIPT_SET *from, SCRIPT_SET *to) {
+   // clear the "to" list
+   while(listSize(to->script_vnums) > 0)
+     listPop(to->script_vnums);
+ 
+   // copy everything over
+   int i;
+   for(i = 0; i < listSize(from->script_vnums); i++)
+     listQueue(to->script_vnums, listGet(from->script_vnums, i));
+ }
+ 
+ SCRIPT_SET *copyScriptSet(SCRIPT_SET *set) {
+   SCRIPT_SET *newset = newScriptSet();
+   copyScriptSetTo(set, newset);
+   return newset;
+ }
diff -crN nakedmudv1.0/src/scripts/script_set.h nakedmudv1.4/src/scripts/script_set.h
*** nakedmudv1.0/src/scripts/script_set.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/scripts/script_set.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,33 ----
+ #ifndef __SCRIPT_SET_H
+ #define __SCRIPT_SET_H
+ //*****************************************************************************
+ //
+ // script_set.h
+ //
+ // A container of script numbers an object, mob, room, etc... may have. Provides
+ // functions to make it easy to extract lists of scripts in the set that conform
+ // to certain properties (e.g. all speech scripts, exit scripts, etc).
+ //
+ //*****************************************************************************
+ 
+ 
+ #define SCRIPT_TYPE_ANY           (-1)
+ 
+ 
+ SCRIPT_SET *newScriptSet();
+ void deleteScriptSet(SCRIPT_SET *set);
+ 
+ void scriptSetAdd   (SCRIPT_SET *set, script_vnum vnum);
+ void scriptSetRemove(SCRIPT_SET *set, script_vnum vnum);
+ 
+ void copyScriptSetTo(SCRIPT_SET *from, SCRIPT_SET *to);
+ SCRIPT_SET *copyScriptSet(SCRIPT_SET *set);
+ 
+ //
+ // Return a list of all scripts of a certain type the set contains.
+ // use SCRIPT_TYPE_ANY for a list of all scripts. LIST must be 
+ // deleted after being used. 
+ //
+ LIST *scriptSetList (SCRIPT_SET *set, int type);
+ 
+ #endif // __SCRIPT_SET_H
diff -crN nakedmudv1.0/src/shop.c nakedmudv1.4/src/shop.c
*** nakedmudv1.0/src/shop.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/src/shop.h nakedmudv1.4/src/shop.h
*** nakedmudv1.0/src/shop.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/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.0/src/socials/.depend nakedmudv1.4/src/socials/.depend
*** nakedmudv1.0/src/socials/.depend	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/socials/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ socials.o: socials.c socials.h
diff -crN nakedmudv1.0/src/socials/module.mk nakedmudv1.4/src/socials/module.mk
*** nakedmudv1.0/src/socials/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/socials/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ # source files we contain
+ SRC += socials/socials.c
diff -crN nakedmudv1.0/src/socials/socials.c nakedmudv1.4/src/socials/socials.c
*** nakedmudv1.0/src/socials/socials.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/socials/socials.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,550 ----
+ //*****************************************************************************
+ //
+ // socials.c
+ //
+ // socials are commonly used emotes (e.g. smiling, grinning, laughing). Instead
+ // making people have to write out an entire emote every time they would like
+ // to express such an emote, they can simply use one of these simple commands
+ // to perform a pre-made emote.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../storage.h"
+ #include "../handler.h"     
+ #include "../inform.h"
+ #include "../character.h"
+ 
+ #include "socials.h"
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // local datastructures, defines, and functions
+ //
+ //*****************************************************************************
+ 
+ // the file where all of the socials are stored
+ #define SOCIALS_FILE "../lib/misc/socials"
+ 
+ // how many buckets are there in the social table
+ #define SOCIAL_TABLE_SIZE              100
+ 
+ // the table we store all of the socials in
+ HASHTABLE *social_table = NULL;
+ 
+ 
+ //
+ // save all of the socials to disk
+ //
+ void save_socials() {
+   STORAGE_SET       *set = new_storage_set();
+   LIST         *soc_list = newList();
+ 
+   // iterate across the social table and save all of the unique socials
+   HASH_ITERATOR  *hash_i = newHashIterator(social_table);
+   const char        *cmd = NULL;
+   SOCIAL_DATA      *data = NULL;
+ 
+   ITERATE_HASH(cmd, data, hash_i)
+     listPut(soc_list, data);
+   deleteHashIterator(hash_i);
+ 
+   store_list(set, "socials", gen_store_list(soc_list, socialStore), NULL);
+   deleteList(soc_list);
+ 
+   // write the set
+   storage_write(set, SOCIALS_FILE);
+   
+   // close the set
+   storage_close(set);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // Implementation of the social datastructure
+ //
+ //*****************************************************************************
+ struct social_data {
+   char *cmds;          // the list of commands we fire off of
+   char *to_char_notgt; // the message to us when there's no target
+   char *to_room_notgt; // the message to the room when there's no target
+   char *to_char_self;  // the message to ourself when tgt == us
+   char *to_room_self;  // the message to the room when tgt == us
+   char *to_char_tgt;   // the message to us when there's a target
+   char *to_vict_tgt;   // the message to the target
+   char *to_room_tgt;   // the message to the room when there's a target
+ 
+   int min_pos;         // the minimum position we can perform this from
+   int max_pos;         // and the maximum
+ };
+ 
+ 
+ SOCIAL_DATA *newSocial(const char *cmds,
+ 		       const char *to_char_notgt,
+ 		       const char *to_room_notgt,
+ 		       const char *to_char_self,
+ 		       const char *to_room_self,
+ 		       const char *to_char_tgt,
+ 		       const char *to_vict_tgt,
+ 		       const char *to_room_tgt,
+ 		       int min_pos, int max_pos) {
+   SOCIAL_DATA *data = malloc(sizeof(SOCIAL_DATA));
+   data->cmds          = strdup(cmds);
+   data->to_char_notgt = strdup(to_char_notgt ? to_char_notgt : "");
+   data->to_room_notgt = strdup(to_room_notgt ? to_room_notgt : "");
+   data->to_char_self  = strdup(to_char_self  ? to_char_self  : "");
+   data->to_room_self  = strdup(to_room_self  ? to_room_self  : "");
+   data->to_char_tgt   = strdup(to_char_tgt   ? to_char_tgt   : "");
+   data->to_vict_tgt   = strdup(to_vict_tgt   ? to_vict_tgt   : "");
+   data->to_room_tgt   = strdup(to_room_tgt   ? to_room_tgt   : "");
+   data->min_pos       = min_pos;
+   data->max_pos       = max_pos;
+   return data;
+ }
+ 
+ 
+ void deleteSocial(SOCIAL_DATA *data) {
+   if(data->cmds)          free(data->cmds);
+   if(data->to_char_notgt) free(data->to_char_notgt);
+   if(data->to_room_notgt) free(data->to_room_notgt);
+   if(data->to_char_self)  free(data->to_char_self);
+   if(data->to_room_self)  free(data->to_room_self);
+   if(data->to_char_tgt)   free(data->to_char_tgt);
+   if(data->to_vict_tgt)   free(data->to_vict_tgt);
+   if(data->to_room_tgt)   free(data->to_room_tgt);
+   free(data);
+ }
+ 
+ 
+ STORAGE_SET *socialStore(SOCIAL_DATA *data) {
+   STORAGE_SET *set = new_storage_set();
+   store_string(set, "cmds",          data->cmds,                NULL);
+   store_string(set, "to_char_notgt", data->to_char_notgt,       NULL);
+   store_string(set, "to_room_notgt", data->to_room_notgt,       NULL);
+   store_string(set, "to_char_self",  data->to_char_self,        NULL);
+   store_string(set, "to_room_self",  data->to_room_self,        NULL);
+   store_string(set, "to_char_tgt",   data->to_char_tgt,         NULL);
+   store_string(set, "to_vict_tgt",   data->to_vict_tgt,         NULL);
+   store_string(set, "to_room_tgt",   data->to_room_tgt,         NULL);
+   store_string(set, "min_pos",       posGetName(data->min_pos), NULL);
+   store_string(set, "max_pos",       posGetName(data->max_pos), NULL);
+   return set;
+ }
+ 
+ 
+ SOCIAL_DATA *socialRead(STORAGE_SET *set) {
+   return newSocial(read_string(set, "cmds"),
+ 		   read_string(set, "to_char_notgt"),
+ 		   read_string(set, "to_room_notgt"),
+ 		   read_string(set, "to_char_self"),
+ 		   read_string(set, "to_room_self"),
+ 		   read_string(set, "to_char_tgt"),
+ 		   read_string(set, "to_vict_tgt"),
+ 		   read_string(set, "to_room_tgt"),
+ 		   posGetNum(read_string(set, "min_pos")),
+ 		   posGetNum(read_string(set, "max_pos")));
+ }
+ 
+ 
+ void socialCopyTo(SOCIAL_DATA *from, SOCIAL_DATA *to) {
+   // free all of the strings
+   if(to->cmds)          free(to->cmds);
+   if(to->to_char_notgt) free(to->to_char_notgt);
+   if(to->to_room_notgt) free(to->to_room_notgt);
+   if(to->to_char_self)  free(to->to_char_self);
+   if(to->to_room_self)  free(to->to_room_self);
+   if(to->to_char_tgt)   free(to->to_char_tgt);
+   if(to->to_vict_tgt)   free(to->to_vict_tgt);
+   if(to->to_room_tgt)   free(to->to_room_tgt);
+ 
+   // copy over all of the new descs and commands
+   to->cmds          = strdup(from->cmds          ? from->cmds          : "");
+   to->to_char_notgt = strdup(from->to_char_notgt ? from->to_char_notgt : "");
+   to->to_room_notgt = strdup(from->to_room_notgt ? from->to_room_notgt : "");
+   to->to_char_self  = strdup(from->to_char_self  ? from->to_char_self  : "");
+   to->to_room_self  = strdup(from->to_room_self  ? from->to_room_self  : "");
+   to->to_char_tgt   = strdup(from->to_char_tgt   ? from->to_char_tgt   : "");
+   to->to_vict_tgt   = strdup(from->to_vict_tgt   ? from->to_vict_tgt   : "");
+   to->to_room_tgt   = strdup(from->to_room_tgt   ? from->to_room_tgt   : "");
+   to->min_pos       = from->min_pos;
+   to->max_pos       = from->max_pos;
+ }
+ 
+ 
+ SOCIAL_DATA *socialCopy(SOCIAL_DATA *social) {
+   SOCIAL_DATA *new_soc = newSocial("", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ 				   POS_STANDING, POS_STANDING);
+   socialCopyTo(social, new_soc);
+   return new_soc;
+ }
+ 
+ const char *socialGetCmds(SOCIAL_DATA *social) {
+   return social->cmds;
+ }
+ 
+ const char *socialGetCharNotgt(SOCIAL_DATA *social) {
+   return social->to_char_notgt;
+ }
+ 
+ const char *socialGetRoomNotgt(SOCIAL_DATA *social) {
+   return social->to_room_notgt;
+ }
+ 
+ const char *socialGetCharSelf (SOCIAL_DATA *social) {
+   return social->to_char_self;
+ }
+ 
+ const char *socialGetRoomSelf (SOCIAL_DATA *social) {
+   return social->to_room_self;
+ }
+ 
+ const char *socialGetCharTgt(SOCIAL_DATA *social) {
+   return social->to_char_tgt;
+ }
+ 
+ const char *socialGetVictTgt(SOCIAL_DATA *social) {
+   return social->to_vict_tgt;
+ }
+ 
+ const char *socialGetRoomTgt(SOCIAL_DATA *social) {
+   return social->to_room_tgt;
+ }
+ 
+ int socialGetMinPos(SOCIAL_DATA *social) {
+   return social->min_pos;
+ }
+ 
+ int socialGetMaxPos(SOCIAL_DATA *social) {
+   return social->max_pos;
+ }
+ 
+ void socialSetCharNotgt(SOCIAL_DATA *social, const char *mssg) {
+   if(social->to_char_notgt) free(social->to_char_notgt);
+   social->to_char_notgt   = strdup(mssg ? mssg : "");
+ }
+ 
+ void socialSetRoomNotgt(SOCIAL_DATA *social, const char *mssg) {
+   if(social->to_room_notgt) free(social->to_room_notgt);
+   social->to_room_notgt   = strdup(mssg ? mssg : "");
+ }
+ 
+ void socialSetCharSelf(SOCIAL_DATA *social, const char *mssg) {
+   if(social->to_char_self) free(social->to_char_self);
+   social->to_char_self   = strdup(mssg ? mssg : "");
+ }
+ 
+ void socialSetRoomSelf(SOCIAL_DATA *social, const char *mssg) {
+   if(social->to_room_self) free(social->to_room_self);
+   social->to_room_self   = strdup(mssg ? mssg : "");
+ }
+ 
+ void socialSetCharTgt(SOCIAL_DATA *social, const char *mssg) {
+   if(social->to_char_tgt) free(social->to_char_tgt);
+   social->to_char_tgt   = strdup(mssg ? mssg : "");
+ }
+ 
+ void socialSetVictTgt(SOCIAL_DATA *social, const char *mssg) {
+   if(social->to_vict_tgt) free(social->to_vict_tgt);
+   social->to_vict_tgt   = strdup(mssg ? mssg : "");
+ }
+ 
+ void socialSetRoomTgt(SOCIAL_DATA *social, const char *mssg) {
+   if(social->to_room_tgt) free(social->to_room_tgt);
+   social->to_room_tgt   = strdup(mssg ? mssg : "");
+ }
+ 
+ void socialSetMinPos(SOCIAL_DATA *social, int pos) {
+   social->min_pos = pos;
+ }
+ 
+ void socialSetMaxPos(SOCIAL_DATA *social, int pos) {
+   social->max_pos = pos;
+ }
+ 
+ 
+ //
+ // Link one social to another
+ //   usage: soclink [new command] [old command]
+ //
+ COMMAND(cmd_soclink) {
+   char new_soc[SMALL_BUFFER];
+ 
+   if(!arg || !*arg) {
+     send_to_char(ch, "Link which social to which?\r\n");
+     return;
+   }
+ 
+   arg = one_arg(arg, new_soc);
+ 
+   if(!*new_soc || !*arg) {
+     send_to_char(ch, "You must provide a new command and an old social "
+ 		 "to link it to.\r\n");
+     return;
+   }
+ 
+   // find the social we're trying to link to
+   SOCIAL_DATA *social = get_social(arg);
+ 
+   if(social == NULL) {
+     send_to_char(ch, "No social exists for %s.\r\n", arg);
+     return;
+   }
+ 
+   // perform the link
+   link_social(new_soc, arg);
+   send_to_char(ch, "%s linked to %s.\r\n", new_soc, arg);
+ }
+ 
+ 
+ //
+ // Unlink a social
+ //   usage: socunlink [command]
+ //
+ COMMAND(cmd_socunlink) {
+   if(!arg || !*arg) {
+     send_to_char(ch, "Unlink which social?\r\n");
+     return;
+   }
+ 
+   // find the social we're trying to link to
+   SOCIAL_DATA *social = get_social(arg);
+ 
+   if(social == NULL) {
+     send_to_char(ch, "No social exists for %s.\r\n", arg);
+     return;
+   }
+ 
+   // perform the unlinking
+   unlink_social(arg);
+   send_to_char(ch, "The %s social was unlinked.\r\n", arg);
+ }
+ 
+ 
+ //
+ // List all of the socials to the character
+ //
+ COMMAND(cmd_socials) {
+   HASH_ITERATOR  *soc_i = newHashIterator(social_table);
+   const char       *soc = NULL;
+   SOCIAL_DATA     *data = NULL;
+   LIST        *soc_list = newList();
+   int count             = 0;
+ 
+   // go through the hashtable and pull out each key
+   ITERATE_HASH(soc, data, soc_i)
+     listPut(soc_list, strdup(soc));
+   deleteHashIterator(soc_i);
+ 
+   // now sort them, and pop them out one at a time
+   listSortWith(soc_list, strcmp);
+ 
+   // and pop them out one at a time to print
+   while( (soc = listPop(soc_list)) != NULL) {
+     count++;
+     send_to_char(ch, "%-20s%s", soc, (count % 4 == 0 ? "\r\n" : ""));    
+   }
+   deleteListWith(soc_list, free);
+ 
+   if(count == 0 || count % 4 != 0)
+     send_to_char(ch, "\r\n");
+ }
+ 
+ 
+ 
+ //
+ // One generic command for handling socials. Does table lookup on all of
+ // the existing socials and executes the proper one.
+ //
+ COMMAND(cmd_social) {
+   // look up the social
+   SOCIAL_DATA *data = hashGet(social_table, cmd);
+ 
+   // does the social exist? Do we have a problem? DO WE?
+   if(data != NULL) {
+     // find the target
+     CHAR_DATA *tgt = NULL;
+     if(*arg) {
+       int tgt_type = FOUND_NONE;
+       tgt = generic_find(ch, arg, FIND_TYPE_CHAR, FIND_SCOPE_IMMEDIATE,
+ 			 FALSE, &tgt_type);
+     }
+ 
+     // see if we were trying to find a target but couldn't
+     if(*arg && !tgt)
+       send_to_char(ch, "Who were you looking for?\r\n");
+     // no target was supplied
+     else if(!tgt) {
+       if(*data->to_char_notgt)
+ 	message(ch, NULL, NULL, NULL, TRUE, TO_CHAR, 
+ 		data->to_char_notgt);
+       if(*data->to_room_notgt)
+ 	message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR, 
+ 		data->to_room_notgt);
+     }
+ 
+     // a target was supplied, and it was us
+     else if(ch == tgt) {
+       if(*data->to_char_self)
+ 	message(ch, NULL, NULL, NULL, TRUE, TO_CHAR, data->to_char_self);
+       else if(*data->to_char_notgt)
+ 	message(ch, NULL, NULL, NULL, TRUE, TO_CHAR, data->to_char_notgt);
+       if(*data->to_room_self)
+ 	message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR, 
+ 		data->to_room_self);
+       else if(*data->to_room_notgt)
+ 	message(ch, NULL, NULL, NULL, TRUE, TO_ROOM | TO_NOTCHAR, 
+ 		data->to_room_notgt);
+     }
+ 
+     // a target was supplied and it was not us
+     else {
+       if(*data->to_char_tgt)
+ 	message(ch, tgt, NULL, NULL, TRUE, TO_CHAR, data->to_char_tgt);
+       if(*data->to_vict_tgt)
+ 	message(ch, tgt, NULL, NULL, TRUE, TO_VICT, data->to_vict_tgt);
+       if(*data->to_room_tgt)
+ 	message(ch, tgt, NULL, NULL, TRUE, TO_ROOM | TO_NOTVICT | TO_NOTCHAR,
+ 		data->to_room_tgt);
+     }
+   }
+   else
+     log_string("ERROR: %s tried social, %s, but no such social exists!",
+ 	charGetName(ch), cmd);
+ }
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // implementation of socials.h
+ //
+ //*****************************************************************************
+ 
+ // I feel dirty doing this, but it's small and it saves us lots of work. So,
+ // well, we'll just have to live with it ;)
+ //
+ // init_socials calls add_social to add in all of the socials it loads up.
+ // But add_social calls save_socials each time that a new social is added.
+ // Thus, when we are booting up, we're making so so so many writes to disk
+ // that are un-needed. Here, we just have a little variable that tells whether
+ // we're booting up or if we're adding a new social in-game. If we're just
+ // booting up, then add_socials won't save any changes.
+ bool in_social_init = TRUE;
+ 
+ void init_socials() {
+   // create the social table
+   social_table = newHashtable(SOCIAL_TABLE_SIZE);
+ 
+   // open up the storage set
+   STORAGE_SET       *set = storage_read(SOCIALS_FILE);
+   STORAGE_SET_LIST *list = read_list(set, "socials");
+   STORAGE_SET    *social = NULL;
+ 
+   // parse all of the socials
+   while( (social = storage_list_next(list)) != NULL)
+     add_social(socialRead(social));
+   
+   // close the storage set
+   storage_close(set);
+ 
+   // add all of the socials to the command table
+   HASH_ITERATOR *hash_i = newHashIterator(social_table);
+   const char       *cmd = NULL;
+   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);
+ 
+   // link/unlink commands for the admins
+   add_cmd("soclink", NULL, cmd_soclink, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, FALSE);
+   add_cmd("socunlink", NULL, cmd_socunlink, 0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_BUILDER, FALSE, FALSE);
+   add_cmd("socials",   NULL, cmd_socials,   0, POS_UNCONCIOUS, POS_FLYING,
+ 	  LEVEL_PLAYER,  TRUE, FALSE);
+ 
+   // let add_social know it can start saving again
+   in_social_init = FALSE;
+ }
+ 
+ 
+ SOCIAL_DATA *get_social(const char *cmd) {
+   return hashGet(social_table, cmd);
+ }
+ 
+ 
+ void add_social(SOCIAL_DATA *social) {
+   // for each of our keywords, go through and 
+   // unlink all of the current socials and link the new one
+   int i, num_cmds = 0;
+   char **cmd_list = parse_keywords(social->cmds, &num_cmds);
+ 
+   for(i = 0; i < num_cmds; i++) {
+     unlink_social(cmd_list[i]);
+     hashPut(social_table, cmd_list[i], social);
+     // add the new command to the game
+     add_cmd(cmd_list[i], NULL, cmd_social, 0, social->min_pos, social->max_pos,
+ 	    LEVEL_PLAYER, TRUE, FALSE);
+     free(cmd_list[i]);
+   }
+   free(cmd_list);
+ 
+   // save changes
+   if(!in_social_init)
+     save_socials();
+ }
+ 
+ 
+ void link_social(const char *new_cmd, const char *old_cmd) {
+   // check for old_cmd
+   SOCIAL_DATA *data = hashGet(social_table, old_cmd);
+ 
+   // link new_cmd to old_cmd
+   if(data != NULL) {
+     // first, remove the current new_cmd social, if it exists
+     unlink_social(new_cmd);
+ 
+     // add the new keyword to the social
+     add_keyword(&(data->cmds), new_cmd);
+     
+     // add the new command to the social table
+     hashPut(social_table, new_cmd, data);
+     
+     // add the new command to the game
+     add_cmd(new_cmd, NULL, cmd_social, 0, data->min_pos, data->max_pos,
+ 	    LEVEL_PLAYER, TRUE, FALSE);
+   }
+ 
+   // save changes
+   if(!in_social_init)
+     save_socials();
+ }
+ 
+ 
+ void unlink_social(const char *cmd) {
+   // remove the command
+   SOCIAL_DATA *data = hashRemove(social_table, cmd);
+ 
+   // unlink the social
+   if(data != NULL) {
+     remove_keyword(data->cmds, cmd);
+ 
+     // remove the command from the command table
+     remove_cmd(cmd);
+ 
+     // if no links are left, delete the social
+     if(!*data->cmds)
+       deleteSocial(data);
+ 
+     // save changes
+     if(!in_social_init)
+       save_socials();
+   }
+ }
diff -crN nakedmudv1.0/src/socials/socials.h nakedmudv1.4/src/socials/socials.h
*** nakedmudv1.0/src/socials/socials.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/socials/socials.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,136 ----
+ #ifndef __SOCIALS_H
+ #define __SOCIALS_H
+ //*****************************************************************************
+ //
+ // socials.h
+ //
+ // socials are commonly used emotes (e.g. smiling, grinning, laughing). Instead
+ // making people have to write out an entire emote every time they would like
+ // to express such an emote, they can simply use one of these simple commands
+ // to perform a pre-made emote.
+ //
+ //*****************************************************************************
+ 
+ //
+ // This must be put at the top of mud.h so the rest of the MUD knows that
+ // we've got the socials module installed
+ // #define MODULE_SOCIALS
+ //
+ 
+ 
+ //
+ // prepare socials for use
+ //
+ void init_socials();
+ 
+ 
+ //
+ // cmds are the list of commands that trigger the social. More than one cmd 
+ // can be specified (comma-separated). Assumes cmds != NULL. All other
+ // arguments can be NULL.
+ //
+ // to_char_notgt is the message sent to the character if no target for
+ // the social is provided.
+ //
+ // to_room_notgt is the message sent to the room if no target for the
+ // social is provided.
+ //
+ // to_char_self is the message sent to ourself when the target provided
+ // was ourself. If to_char_self is not provided, the message will default
+ // to the same one used for to_char_notgt.
+ //
+ // to_room_self is the message sent to the room when the target provided
+ // was ourself. If to_room_self is not provided, the message will default
+ // to the same one used for to_char_notgt.
+ //
+ // to_char_tgt is the message sent to the character when a target is
+ // provided.
+ //
+ // to_vict_tgt is the message sent to the target when a target is provided
+ //
+ // to_room_tgt is the message sent to the room when a target is provided
+ //
+ // min_pos and max_pos are the minimum and maximum positions the socials can
+ // per performed from, respectively.
+ //
+ typedef struct social_data SOCIAL_DATA; 
+ SOCIAL_DATA *newSocial(const char *cmds,
+ 		       const char *to_char_notgt,
+ 		       const char *to_room_notgt,
+ 		       const char *to_char_self,
+ 		       const char *to_room_self,
+ 		       const char *to_char_tgt,
+ 		       const char *to_vict_tgt,
+ 		       const char *to_room_tgt,
+ 		       int min_pos, int max_pos);
+ 
+ void         deleteSocial(SOCIAL_DATA *data);
+ STORAGE_SET *socialStore (SOCIAL_DATA *social);
+ SOCIAL_DATA *socialRead  (STORAGE_SET *set);
+ SOCIAL_DATA *socialCopy  (SOCIAL_DATA *social);
+ void         socialCopyTo(SOCIAL_DATA *from, SOCIAL_DATA *to);
+ 
+ 
+ // This stuff is mainly intended for use with OLC, so socials can be displayed
+ const char *socialGetCmds     (SOCIAL_DATA *social);
+ const char *socialGetCharNotgt(SOCIAL_DATA *social);
+ const char *socialGetRoomNotgt(SOCIAL_DATA *social);
+ const char *socialGetCharSelf (SOCIAL_DATA *social);
+ const char *socialGetRoomSelf (SOCIAL_DATA *social);
+ const char *socialGetCharTgt  (SOCIAL_DATA *social);
+ const char *socialGetVictTgt  (SOCIAL_DATA *social);
+ const char *socialGetRoomTgt  (SOCIAL_DATA *social);
+ int         socialGetMinPos   (SOCIAL_DATA *social);
+ int         socialGetMaxPos   (SOCIAL_DATA *social);
+ 
+ //
+ // Again, mostly intended for use with OLC
+ //
+ // socialSetCmds is no longer in use. Try using the link_social() instead
+ // void         socialSetCmds     (SOCIAL_DATA *social, const char *cmds);
+ //
+ void         socialSetCharNotgt(SOCIAL_DATA *social, const char *mssg);
+ void         socialSetRoomNotgt(SOCIAL_DATA *social, const char *mssg);
+ void         socialSetCharSelf (SOCIAL_DATA *social, const char *mssg);
+ void         socialSetRoomSelf (SOCIAL_DATA *social, const char *mssg);
+ void         socialSetCharTgt  (SOCIAL_DATA *social, const char *mssg);
+ void         socialSetVictTgt  (SOCIAL_DATA *social, const char *mssg);
+ void         socialSetRoomTgt  (SOCIAL_DATA *social, const char *mssg);
+ void         socialSetMinPos   (SOCIAL_DATA *social, int pos);
+ void         socialSetMaxPos   (SOCIAL_DATA *social, int pos);
+ 
+ 
+ //
+ // save any changes that have been made to socials. OLC will need this.
+ //
+ void save_socials();
+ 
+ 
+ //
+ // Return the social assocciated with the command. If no social exists,
+ // return NULL
+ //
+ SOCIAL_DATA *get_social(const char *cmd);
+ 
+ 
+ //
+ // add in a new social. If any of the commands already exist as socials,
+ // they are unlinked first.
+ //
+ void add_social(SOCIAL_DATA *social);
+ 
+ 
+ //
+ // link a new command to a pre-existing social. Change will be saved to file
+ //
+ void link_social(const char *new_cmd, const char *old_cmd);
+ 
+ 
+ //
+ // unlink a command from it's social messages. If there are no
+ // more commands linked to the social, delete the social.
+ //
+ void unlink_social(const char *cmd);
+ 
+ 
+ #endif // __SOCIALS_H
diff -crN nakedmudv1.0/src/socket.c nakedmudv1.4/src/socket.c
*** nakedmudv1.0/src/socket.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/socket.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 15,21 ****
  #include "socket.h"
  
  #ifdef MODULE_OLC
! #include "modules/olc/olc.h"
  #endif
  
  
--- 15,21 ----
  #include "socket.h"
  
  #ifdef MODULE_OLC
! #include "olc/olc.h"
  #endif
  
  
***************
*** 742,752 ****
    SOCKET_DATA *dsock;
    LIST_ITERATOR *sock_i = newListIterator(socket_list);
  
!   // can't use ITERATE_LIST, because we might be 
!   // removing the current element from the list
!   while ( (dsock = (SOCKET_DATA *)listIteratorCurrent(sock_i)) != NULL) {
!     listIteratorNext(sock_i);
!     if (dsock->lookup_status != TSTATE_CLOSED) continue;
  
      /* remove the socket from the main list */
      listRemove(socket_list, dsock);
--- 742,750 ----
    SOCKET_DATA *dsock;
    LIST_ITERATOR *sock_i = newListIterator(socket_list);
  
!   ITERATE_LIST(dsock, sock_i) {
!     if (dsock->lookup_status != TSTATE_CLOSED) 
!       continue;
  
      /* remove the socket from the main list */
      listRemove(socket_list, dsock);
diff -crN nakedmudv1.0/src/socket.h nakedmudv1.4/src/socket.h
*** nakedmudv1.0/src/socket.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/socket.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 56,62 ****
  
  /* sends the output directly */
  bool  text_to_socket        ( SOCKET_DATA *dsock, const char *txt );
! void  send_to_socket        ( SOCKET_DATA *dsock, const char *format, ...);
  
  /* buffers the output        */
  void  text_to_buffer        ( SOCKET_DATA *dsock, const char *txt );
--- 56,62 ----
  
  /* sends the output directly */
  bool  text_to_socket        ( SOCKET_DATA *dsock, const char *txt );
! void  send_to_socket        ( SOCKET_DATA *dsock, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
  
  /* buffers the output        */
  void  text_to_buffer        ( SOCKET_DATA *dsock, const char *txt );
diff -crN nakedmudv1.0/src/storage.c nakedmudv1.4/src/storage.c
*** nakedmudv1.0/src/storage.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/storage.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 126,131 ****
--- 126,136 ----
    return new_data_string(str_val, key);
  }
  
+ STORAGE_DATA    *new_data_long(long val, const char *key) {
+   char str_val[20]; sprintf(str_val, "%ld", val);
+   return new_data_string(str_val, key);
+ }
+ 
  STORAGE_DATA *new_data_double(double val, const char *key) {
    char str_val[20]; sprintf(str_val, "%lf", val);
    return new_data_string(str_val, key);
***************
*** 227,236 ****
  
  
  void write_storage_data(STORAGE_DATA *data, FILE *fl, int key_width,int indent){
-   /*
-   if(data->comment)
-     write_storage_comment(fl, data->comment, indent);
-   */
    // first, we see if we have a string value. If we do, print it
    if(*data->str_val) {
      print_key(fl, data->key, key_width, indent);
--- 232,237 ----
***************
*** 535,543 ****
  
  STORAGE_SET *storage_read(const char *fname) {
    FILE *fl = NULL;
!   // we wanted to open a file, but we couldn't ... abort
    if((fl = fopen(fname, "r")) == NULL)
!     return NULL;
    STORAGE_SET *set = parse_storage_set(fl, 0);
    fclose(fl);
    return set;
--- 536,544 ----
  
  STORAGE_SET *storage_read(const char *fname) {
    FILE *fl = NULL;
!   // we wanted to open a file, but we couldn't ... return an empty set
    if((fl = fopen(fname, "r")) == NULL)
!     return NULL;//    return new_storage_set();
    STORAGE_SET *set = parse_storage_set(fl, 0);
    fclose(fl);
    return set;
***************
*** 600,605 ****
--- 601,611 ----
    storage_put(set, new_data_int(val, key));
  }
  
+ void store_long(STORAGE_SET *set, const char *key, long val, 
+ 	       const char *comment) {
+   storage_put(set, new_data_long(val, key));
+ }
+ 
  STORAGE_SET    *read_set(STORAGE_SET *set, const char *key) {
    STORAGE_DATA *data = hashGet(set->entries, key);
    if(data) 
***************
*** 628,640 ****
  
  double read_double(STORAGE_SET *set, const char *key) {
    STORAGE_DATA *data = hashGet(set->entries, key);
!   if(data) {
!     double dbl = 0;
!     sscanf(data->str_val, "%lf", &dbl);
!     return dbl;
!   }
!   else
!     return 0;
  }
  
  int read_int(STORAGE_SET *set, const char *key) {
--- 634,641 ----
  
  double read_double(STORAGE_SET *set, const char *key) {
    STORAGE_DATA *data = hashGet(set->entries, key);
!   if(data) return atof(data->str_val);
!   else     return 0;
  }
  
  int read_int(STORAGE_SET *set, const char *key) {
***************
*** 643,648 ****
--- 644,658 ----
    else     return 0;
  }
  
+ long read_long(STORAGE_SET *set, const char *key) {
+   STORAGE_DATA *data = hashGet(set->entries, key);
+   if(data) return atol(data->str_val);
+   else     return 0;
+ }
+ 
+ bool storage_contains(STORAGE_SET *set, const char *key) {
+   return (hashGet(set->entries, key) != NULL);
+ }
  
  //
  // make a storage list out of a normal MUD list
diff -crN nakedmudv1.0/src/storage.h nakedmudv1.4/src/storage.h
*** nakedmudv1.0/src/storage.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/storage.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 69,74 ****
--- 69,76 ----
  		  const char *comment);
  void    store_int(STORAGE_SET *set, const char *key, int val,
  		  const char *comment);
+ void   store_long(STORAGE_SET *set, const char *key, long val,
+ 		  const char *comment);
  
  
  //
***************
*** 79,84 ****
--- 81,97 ----
  const char       *read_string(STORAGE_SET *set, const char *key);
  double            read_double(STORAGE_SET *set, const char *key);
  int                  read_int(STORAGE_SET *set, const char *key);
+ long                read_long(STORAGE_SET *set, const char *key);
+ 
+ 
+ //
+ // returns TRUE if the key exists in the set, and false if it
+ // doesn't. Note that you can read key values even if the key
+ // doesn't exist; the values will just have a default value
+ // (0 for doubles and ints, "\0" for strings, an empty list
+ // for lists).
+ //
+ bool storage_contains(STORAGE_SET *set, const char *key);
  
  
  //
diff -crN nakedmudv1.0/src/strings.c nakedmudv1.4/src/strings.c
*** nakedmudv1.0/src/strings.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/strings.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 87,92 ****
--- 87,115 ----
    return fStr;
  }
  
+ 
+ //
+ // pull out the argument of the specified number
+ //
+ void arg_num(const char *from, char *to, int num) {
+   int count = 1;
+ 
+   while(count < num && *from != '\0') {
+     if(isspace(*from))
+       count++;
+     from++;
+   }
+ 
+   int i;
+   // copy up to the first space
+   for(i = 0; !isspace(from[i]) && from[i] != '\0'; i++)
+     to[i] = from[i];
+ 
+   // now cap our string
+   to[i] = '\0';
+ }
+ 
+ 
  char *capitalize(char *txt)
  {
    static char buf[MAX_BUFFER];
diff -crN nakedmudv1.0/src/text_editor.c nakedmudv1.4/src/text_editor.c
*** nakedmudv1.0/src/text_editor.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/text_editor.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 16,25 ****
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  #ifdef MODULE_OLC
! #include "modules/olc/olc.h"
  #endif
  
  
--- 16,25 ----
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  #ifdef MODULE_OLC
! #include "olc/olc.h"
  #endif
  
  
diff -crN nakedmudv1.0/src/time/.depend nakedmudv1.4/src/time/.depend
*** nakedmudv1.0/src/time/.depend	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/time/.depend	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1 ----
+ time.o: time.c mudtime.h
diff -crN nakedmudv1.0/src/time/module.mk nakedmudv1.4/src/time/module.mk
*** nakedmudv1.0/src/time/module.mk	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/time/module.mk	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,2 ----
+ # the source files we will use in the build
+ SRC += time/time.c
diff -crN nakedmudv1.0/src/time/mudtime.h nakedmudv1.4/src/time/mudtime.h
*** nakedmudv1.0/src/time/mudtime.h	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/time/mudtime.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,72 ----
+ #ifndef __MUDTIME_H
+ #define __MUDTIME_H
+ //*****************************************************************************
+ //
+ // mudtime.h
+ //
+ // A small module for handling time of day in the MUD.
+ //
+ //*****************************************************************************
+ 
+ //
+ // This must be put at the top of mud.h so the rest of the MUD knows that
+ // we've got the time module installed
+ // #define MODULE_TIME
+ //
+ 
+ //
+ // Set up the time module
+ //
+ void init_time();
+ 
+ 
+ //
+ // what day is it?
+ //
+ const char *get_day();
+ 
+ 
+ //
+ // what month is it?
+ //
+ const char *get_month();
+ 
+ 
+ //
+ // what hour is it
+ //
+ int get_hour();
+ 
+ 
+ //
+ // what year is it?
+ //
+ int get_year();
+ 
+ 
+ //
+ // What period of the day are we in?
+ //
+ bool is_morning();
+ bool is_afternoon();
+ bool is_evening();
+ bool is_night();
+ 
+ 
+ //
+ // 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
diff -crN nakedmudv1.0/src/time/time.c nakedmudv1.4/src/time/time.c
*** nakedmudv1.0/src/time/time.c	1969-12-31 18:00:00.000000000 -0600
--- nakedmudv1.4/src/time/time.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 0 ****
--- 1,300 ----
+ //*****************************************************************************
+ //
+ // time.c
+ //
+ // A small module for handling time of day in the MUD.
+ //
+ //*****************************************************************************
+ 
+ #include "../mud.h"
+ #include "../utils.h"
+ #include "../inform.h"
+ #include "../character.h"
+ #include "../room.h"
+ #include "../event.h"
+ #include "../storage.h"
+ #include "../auxiliary.h"
+ 
+ #include "mudtime.h"
+ 
+ 
+ #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?
+   int   num_days;         // how many days are in the month?
+   int   morning_starts;   // what time does morning start at?
+   int   afternoon_starts; // what time does the afternoon start at?
+   int   evening_starts;   // what times does evening start at?
+   int   night_starts;     // what time does the night start at?
+ };
+ 
+ struct day_data {
+   char *name;
+ };
+ 
+ const struct month_data month_info[NUM_MONTHS] = {
+   // month name                 days   morning   afternoon    evening   night
+   { "the month of dawn",          30,        6,         12,        18,     22 },
+   { "the month of light",         30,        4,         10,        19,     23 },
+   { "the month of the moon",      30,        6,         12,        17,     21 },
+   { "the month of twilight",      30,        5,         13,        16,     20 },
+ };
+ 
+ const struct day_data day_info[DAYS_PER_WEEK] = {
+   { "the day of work" },
+   { "the day of play" },
+   { "the day of rest" },
+ };
+ 
+ 
+ int curr_hour         = 0; // what hour is it in the day?
+ int curr_day_of_week  = 0; // what day of the week is it?
+ int curr_day_of_month = 0; // what day is it in the month?
+ int curr_month        = 0; // what month is it in the year?
+ int curr_year         = 0; // what year is it?
+ 
+ 
+ 
+ //*****************************************************************************
+ //
+ // auxiliary data
+ //
+ // the time module gives rooms the ability to have different day and night
+ // descriptions. Below are the functions required for installing this.
+ //
+ //*****************************************************************************
+ 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 *
+ timeAuxDataCopy(TIME_AUX_DATA *data) {
+   TIME_AUX_DATA *newdata = newTimeAuxData();
+   timeAuxDataCopyTo(data, newdata);
+   return newdata;
+ }
+ 
+ STORAGE_SET *timeAuxDataStore(TIME_AUX_DATA *data) {
+   STORAGE_SET *set = new_storage_set();
+   store_string(set, "night_desc", data->night_desc, NULL);
+   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
+ //
+ //*****************************************************************************
+ 
+ //
+ // Handle the hourly update of our times
+ //
+ void handle_time_update(void *self, void *data, char *arg) {
+   curr_hour++;
+ 
+   if(curr_hour >= HOURS_PER_DAY) {
+     curr_hour = 0;
+     curr_day_of_week++;
+     curr_day_of_month++;
+   }
+ 
+   if(curr_day_of_week >= DAYS_PER_WEEK)
+     curr_day_of_week = 0;
+ 
+   if(curr_day_of_month >= month_info[curr_month].num_days) {
+     curr_day_of_month = 0;
+     curr_month++;
+   }
+ 
+   if(curr_month >= NUM_MONTHS) {
+     curr_month = 0;
+     curr_year++;
+   }
+ 
+ 
+   // check to see if we've rolled over to a new time of day
+   if(curr_hour == month_info[curr_month].morning_starts)
+     send_outdoors("The morning sun slowly pokes its head up over the eastern horizon.\r\n");
+   if(curr_hour == month_info[curr_month].afternoon_starts)
+     send_outdoors("The sun hangs high overhead as afternoon approaches.\r\n");
+   if(curr_hour == month_info[curr_month].evening_starts)
+     send_outdoors("The sun slowly begins its descent as evening approaches.\r\n");
+   if(curr_hour == month_info[curr_month].night_starts)
+     send_outdoors("The sky goes dark as the sun passes over the western horizon.\r\n");
+ 
+   // save our time data to file
+   STORAGE_SET *set = new_storage_set();
+   store_int(set, "hour",         curr_hour,         NULL);
+   store_int(set, "day_of_week",  curr_day_of_week,  NULL);
+   store_int(set, "day_of_month", curr_day_of_month, NULL);
+   store_int(set, "month",        curr_month,        NULL);
+   store_int(set, "year",         curr_year,         NULL);
+   storage_write(set, TIME_FILE);
+   storage_close(set);
+ 
+   // throw ourself back into the event queue
+   start_event(NULL,
+ 	      TIME_UPDATE_DELAY,
+ 	      handle_time_update,
+ 	      NULL, NULL, NULL);
+ }
+ 
+ 
+ void init_time() {
+   STORAGE_SET *set  = storage_read(TIME_FILE);
+   if(set != NULL) {
+     curr_hour         = read_int(set, "hour");
+     curr_day_of_week  = read_int(set, "day_of_week");
+     curr_day_of_month = read_int(set, "day_of_month");
+     curr_month        = read_int(set, "month");
+     curr_year         = read_int(set, "year");
+     storage_close(set);
+   }
+   else
+     curr_hour = curr_day_of_week = curr_day_of_month = curr_month = curr_year = 0;
+ 
+ 
+   // add the time command
+   add_cmd("time", NULL, cmd_time, 0, POS_SITTING,  POS_FLYING,
+ 	  LEVEL_PLAYER, TRUE, FALSE);
+ 
+   // add night descriptions for rooms
+   auxiliariesInstall("time_aux_data",
+ 		     newAuxiliaryFuncs(AUXILIARY_TYPE_ROOM,
+ 				       newTimeAuxData, deleteTimeAuxData,
+ 				       timeAuxDataCopyTo, timeAuxDataCopy,
+ 				       timeAuxDataStore, timeAuxDataRead));
+ 
+   // start our time updater
+   start_event(NULL,
+ 	      TIME_UPDATE_DELAY,
+ 	      handle_time_update,
+ 	      NULL, NULL, NULL);
+ }
+ 
+ 
+ const char *get_day() {
+   return day_info[curr_day_of_week].name;
+ }
+ 
+ 
+ const char *get_month() {
+   return month_info[curr_month].name;
+ }
+ 
+ 
+ int get_year() {
+   return curr_year;
+ }
+ 
+ 
+ int get_hour() {
+   return curr_hour;
+ }
+ 
+ 
+ bool is_morning() {
+   return (curr_hour >= month_info[curr_month].morning_starts &&
+ 	  curr_hour <  month_info[curr_month].afternoon_starts);
+ }
+ 
+ 
+ bool is_afternoon() {
+   return (curr_hour >= month_info[curr_month].afternoon_starts &&
+ 	  curr_hour <  month_info[curr_month].evening_starts);
+ }
+ 
+ 
+ bool is_evening() {
+   return (curr_hour >= month_info[curr_month].evening_starts &&
+ 	  curr_hour <  month_info[curr_month].night_starts);
+ }
+ 
+ 
+ bool is_night() {
+   return (curr_hour >= month_info[curr_month].night_starts ||
+ 	  curr_hour <  month_info[curr_month].morning_starts);
+ }
+ 
+ 
+ //
+ // is it am or pm?
+ //
+ bool is_am() {
+   return (curr_hour < HOURS_PER_DAY/2);
+ }
+ 
+ 
+ //
+ // what time is it, am/pm - wise?
+ //
+ int ampm_hour() {
+   int ampm_time = curr_hour - (is_am() ? 0 : HOURS_PER_DAY/2);
+   if(ampm_time == 0) ampm_time = HOURS_PER_DAY/2;
+   return ampm_time;
+ }
+ 
+ 
+ COMMAND(cmd_time) {
+   send_to_char(ch,
+ 	       "It is %d o'clock%s during the %s of %s,\r\n"
+ 	       "which is the %d%s day of %s, year %d.\r\n",
+ 	       (USE_AMPM ? ampm_hour() : curr_hour+1),
+ 	       (USE_AMPM ? (is_am() ? " a.m" : " p.m") : ""),
+ 	       (is_morning() ? "morning" :
+ 		(is_afternoon() ? "afternoon" :
+ 		 (is_evening() ? "evening" : "night"))),
+ 	       day_info[curr_day_of_week].name,
+ 	       curr_day_of_month+1, numth(curr_day_of_month+1),
+ 	       month_info[curr_month].name, curr_year);
+ }
diff -crN nakedmudv1.0/src/utils.c nakedmudv1.4/src/utils.c
*** nakedmudv1.0/src/utils.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/utils.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 22,44 ****
  #include "save.h"
  #include "handler.h"
  #include "inform.h"
- #include "help.h"
  #include "dialog.h"
  #include "event.h"
  #include "action.h"
  
  
  // optional modules
- #ifdef MODULE_FACULTY
- #include "modules/faculty/faculty.h"
- #endif
- #ifdef MODULE_COMBAT
- #include "modules/combat/combat.h"
- #endif
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  /*
   * Check to see if a given name is
   * legal, returning FALSE if it
--- 22,39 ----
  #include "save.h"
  #include "handler.h"
  #include "inform.h"
  #include "dialog.h"
  #include "event.h"
  #include "action.h"
+ #include "help.h"
  
  
  // optional modules
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  
+ 
  /*
   * Check to see if a given name is
   * legal, returning FALSE if it
***************
*** 96,104 ****
  #endif
    interrupt_events_involving(ch);
  
! #ifdef MODULE_COMBAT
    stop_all_targetting(ch);
!   stop_combat(ch);
  #endif
  
    // unequip everything the character is wearing
--- 91,99 ----
  #endif
    interrupt_events_involving(ch);
  
! #ifdef MODULE_FIGHT
    stop_all_targetting(ch);
!   stop_fight(ch);
  #endif
  
    // unequip everything the character is wearing
***************
*** 133,173 ****
    default:
      bug("Communicate: Bad Range %d.", range);
      return;
!   case COMM_LOCAL:  /* everyone in the same room */
      send_to_char(dMob, "{yYou say, '%s'{n\r\n", txt);
!     message(dMob, NULL, NULL, NULL, FALSE, TO_ROOM | TO_NOTCHAR,
! 	    "{y$n says, '%s'", txt);
      try_dialog_all(dMob, roomGetCharacters(charGetRoom(dMob)), txt);
  #ifdef MODULE_SCRIPTS
      try_speech_script(dMob, NULL, txt);
  #endif
      break;
  
!   case COMM_GLOBAL: /* everyone in the world */
      send_to_char(dMob, "{cYou chat, '%s'{n\r\n", txt);
!     message(dMob, NULL, NULL, NULL, FALSE, TO_WORLD | TO_NOTCHAR,
! 	    "{c$n chats, '%s'", txt);
      break;
  
!   case COMM_LOG: {
!     CHAR_DATA *xMob;
!     LIST_ITERATOR *mob_i = newListIterator(mobile_list);
!     ITERATE_LIST(xMob, mob_i) {
!       if (!IS_ADMIN(xMob)) continue;
!       send_to_char(xMob, "[LOG: %s]\r\n", txt);
!     }
!     deleteListIterator(mob_i);
      break;
    }
-   }
  }
  
  
  /*
   * Loading of help files, areas, etc, at boot time.
   */
! void load_muddata(bool fCopyOver)
! {  
    load_helps();
    gameworld = worldLoad(WORLD_PATH);
    if(gameworld == NULL) {
--- 128,165 ----
    default:
      bug("Communicate: Bad Range %d.", range);
      return;
! 
!   case COMM_LOCAL: {  /* everyone in the same room */
!     char other_buf[MAX_BUFFER];
!     sprintf(other_buf, "{y$n says, '%s'{n", txt);
      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;
+   }
  
!   case COMM_GLOBAL: { /* everyone in the world */
!     char other_buf[MAX_BUFFER];
!     sprintf(other_buf, "{c$n chats, '%s'{n", txt);
      send_to_char(dMob, "{cYou chat, '%s'{n\r\n", txt);
!     message(dMob, NULL, NULL, NULL, FALSE, TO_WORLD | TO_NOTCHAR, other_buf);
      break;
+   }
  
!   case COMM_LOG:
!     send_to_level(LEVEL_ADMIN, "[LOG: %s]\r\n", txt);
      break;
    }
  }
  
  
  /*
   * Loading of help files, areas, etc, at boot time.
   */
! void load_muddata(bool fCopyOver) {  
    load_helps();
    gameworld = worldLoad(WORLD_PATH);
    if(gameworld == NULL) {
***************
*** 175,185 ****
--- 167,181 ----
      abort();
    }
  
+   greeting = read_file("../lib/txt/greeting");
+   motd     = read_file("../lib/txt/motd");
+ 
    /* copyover */
    if (fCopyOver)
      copyover_recover();
  }
  
+ 
  char *get_time()
  {
    static char buf[16];
***************
*** 329,335 ****
    return 0;
  }
  
! bool  can_see_person          ( CHAR_DATA *ch, CHAR_DATA *target) {
    if(ch == target)
      return TRUE;
    if(poscmp(charGetPos(ch), POS_SLEEPING) <= 0)
--- 325,331 ----
    return 0;
  }
  
! bool  can_see_char          ( CHAR_DATA *ch, CHAR_DATA *target) {
    if(ch == target)
      return TRUE;
    if(poscmp(charGetPos(ch), POS_SLEEPING) <= 0)
***************
*** 353,358 ****
--- 349,365 ----
    return TRUE;
  }
  
+ const char *see_char_as (CHAR_DATA *ch, CHAR_DATA *target) {
+   if(can_see_char(ch, target))
+     return charGetName(target);
+   return SOMEONE;
+ }
+ 
+ const char *see_obj_as  (CHAR_DATA *ch, OBJ_DATA  *target) {
+   if(can_see_obj(ch, target))
+     return objGetName(target);
+   return SOMETHING;
+ }
  
  int count_objs(CHAR_DATA *looker, LIST *list, const char *name, int vnum,
  	       bool must_see) {
***************
*** 382,388 ****
    int count = 0;
  
    ITERATE_LIST(ch, char_i) {
!     if(must_see && !can_see_person(looker, ch))
        continue;
      // if we have a name, search by it
      if(name && *name && charIsName(ch, name))
--- 389,395 ----
    int count = 0;
  
    ITERATE_LIST(ch, char_i) {
!     if(must_see && !can_see_char(looker, ch))
        continue;
      // if we have a name, search by it
      if(name && *name && charIsName(ch, name))
***************
*** 410,416 ****
    CHAR_DATA *ch;
  
    ITERATE_LIST(ch, char_i) {
!     if(must_see && !can_see_person(looker, ch))
        continue;
      // if we have a name, search by name
      if(name && *name && charIsName(ch, name))
--- 417,423 ----
    CHAR_DATA *ch;
  
    ITERATE_LIST(ch, char_i) {
!     if(must_see && !can_see_char(looker, ch))
        continue;
      // if we have a name, search by name
      if(name && *name && charIsName(ch, name))
***************
*** 466,472 ****
    CHAR_DATA *ch;
  
    ITERATE_LIST(ch, char_i) {
!     if(must_see && !can_see_person(looker, ch))
        continue;
      if(name && (!*name || charIsName(ch, name)))
        listPut(char_list, ch);
--- 473,479 ----
    CHAR_DATA *ch;
  
    ITERATE_LIST(ch, char_i) {
!     if(must_see && !can_see_char(looker, ch))
        continue;
      if(name && (!*name || charIsName(ch, name)))
        listPut(char_list, ch);
***************
*** 716,723 ****
      // skip all spaces and commas
      while(isspace(*keywords) || *keywords == ',')
        keywords = keywords+1;
      // see if we compare to the current keyword
!     if(!abbrev_ok && !strncasecmp(keywords, word,next_letter_in(keywords, ',')))
        return TRUE;
      if(abbrev_ok && !strncasecmp(keywords, word, word_len))
        return TRUE;
--- 723,734 ----
      // skip all spaces and commas
      while(isspace(*keywords) || *keywords == ',')
        keywords = keywords+1;
+     // figure out the length of the current keyword
+     int keyword_len = next_letter_in(keywords, ',');
+ 
      // see if we compare to the current keyword
!     if(!abbrev_ok && !strncasecmp(keywords, word, keyword_len) &&
!        keyword_len == word_len)
        return TRUE;
      if(abbrev_ok && !strncasecmp(keywords, word, word_len))
        return TRUE;
***************
*** 801,806 ****
--- 812,862 ----
  
  
  //
+ // If the keyword does not already exist, add it to the keyword list
+ // keywords may be freed and re-built in the process, to make room
+ //
+ void add_keyword(char **keywords_ptr, const char *word) {
+   // if it's already a keyword, do nothing
+   if(!is_keyword(*keywords_ptr, word, FALSE)) {
+     char buf[MAX_BUFFER];
+     // copy everything over
+     strcpy(buf, *keywords_ptr);
+     // print the new word
+     strcat(buf, ", ");
+     strcat(buf, word);
+     // free the old string
+     free(*keywords_ptr);
+     // copy the new one
+     *keywords_ptr = strdup(buf);
+   }
+ }
+ 
+ 
+ //
+ // go through the keywords and if word is found, remove it
+ //
+ void remove_keyword(char *keywords, const char *word) {
+   int i, key_i = 0, num_keywords = 0;
+   char **words = parse_keywords(keywords, &num_keywords);
+ 
+   // clear the current list... we will rebuild it
+   *keywords = '\0';
+ 
+   // go through and add them all back into keywords. If we
+   // ever encounter word, then leave it out
+   for(i = 0; i < num_keywords; i++) {
+     if(strcasecmp(words[i], word) != 0) {
+       key_i += sprintf(keywords+key_i, "%s", words[i]);
+       if(i < num_keywords-1 && strcasecmp(words[i+1], word) != 0)
+ 	key_i += sprintf(keywords+key_i, ", ");
+     }
+     free(words[i]);
+   }
+   free(words);
+ }
+ 
+ 
+ //
  // fill up the buffer with characters until
  // a newline is reached, or we hit our critical
  // length. Return how many characters were read
***************
*** 1020,1027 ****
        char *response = tagResponses(dialog,
  				    responseGetMessage(resp),
  				    "{c", "{p");
!       message(ch, listener, NULL, NULL, FALSE, TO_CHAR,
! 	      "{p$N replies, '%s'", response);
        free(response);
        return TRUE;
      }
--- 1076,1082 ----
        char *response = tagResponses(dialog,
  				    responseGetMessage(resp),
  				    "{c", "{p");
!       send_to_char(ch, "{p%s replies, '%s'\r\n", charGetName(listener), response);
        free(response);
        return TRUE;
      }
***************
*** 1205,1229 ****
    return ret_val;
  }
  
  const char *custom_prompt(CHAR_DATA *ch) {
    static char prompt[MAX_BUFFER];
    *prompt = '\0';
! 
! #ifdef MODULE_COMBAT
!   CHAR_DATA *tgt = get_target(ch);
!   if(tgt != NULL) {
!     sprintf(prompt, 
! 	    "{bMind %d, Left %d, Right %d, Feet %d, dam %d | %s :: dam %d > {n",
! 	    get_action_points(ch, FACULTY_MIND),
! 	    get_action_points(ch, FACULTY_LEFT_HAND),
! 	    get_action_points(ch, FACULTY_RIGHT_HAND),
! 	    get_action_points(ch, FACULTY_FEET),
! 	    get_damage(ch),
! 	    charGetName(tgt), get_damage(tgt));
!   }
!   else
! #endif
!     strcat(prompt, "\r\nprompt> ");
! 
    return prompt;
  }
--- 1260,1270 ----
    return ret_val;
  }
  
+ 
  const char *custom_prompt(CHAR_DATA *ch) {
    static char prompt[MAX_BUFFER];
    *prompt = '\0';
!   strcat(prompt, "\r\nprompt> ");
!     
    return prompt;
  }
diff -crN nakedmudv1.0/src/utils.h nakedmudv1.4/src/utils.h
*** nakedmudv1.0/src/utils.h	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/utils.h	2010-11-01 15:54:18.000000000 -0500
***************
*** 42,55 ****
  #define HESHE(ch)             (charGetSex(ch) == SEX_MALE ? "he" : \
  			       (charGetSex(ch) == SEX_FEMALE ? "she" : "it"))
  
! 
! bool  can_see_person      ( CHAR_DATA *ch, CHAR_DATA *target);
  bool  can_see_obj         ( CHAR_DATA *ch, OBJ_DATA  *target);
  bool  can_see_exit        ( CHAR_DATA *ch, EXIT_DATA *exit);
  bool  try_enter_game      ( CHAR_DATA *ch);
  int   can_see_hidden      ( CHAR_DATA *ch);
  int   can_see_invis       ( CHAR_DATA *ch);
  
  bool  try_dialog          (CHAR_DATA *ch, CHAR_DATA *listener,const char *mssg);
  void  try_dialog_all      (CHAR_DATA *ch, LIST *listeners, const char *mssg);
  
--- 42,61 ----
  #define HESHE(ch)             (charGetSex(ch) == SEX_MALE ? "he" : \
  			       (charGetSex(ch) == SEX_FEMALE ? "she" : "it"))
  
! bool  can_see_char      ( CHAR_DATA *ch, CHAR_DATA *target);
  bool  can_see_obj         ( CHAR_DATA *ch, OBJ_DATA  *target);
  bool  can_see_exit        ( CHAR_DATA *ch, EXIT_DATA *exit);
  bool  try_enter_game      ( CHAR_DATA *ch);
  int   can_see_hidden      ( CHAR_DATA *ch);
  int   can_see_invis       ( CHAR_DATA *ch);
  
+ //
+ // returns the target's name if the ch can see the target,
+ // and returns SOMEONE/SOMETHING otherwise.
+ //
+ const char *see_char_as (CHAR_DATA *ch, CHAR_DATA *target);
+ const char *see_obj_as  (CHAR_DATA *ch, OBJ_DATA  *target);
+ 
  bool  try_dialog          (CHAR_DATA *ch, CHAR_DATA *listener,const char *mssg);
  void  try_dialog_all      (CHAR_DATA *ch, LIST *listeners, const char *mssg);
  
***************
*** 78,87 ****
--- 84,97 ----
  //
  //*****************************************************************************
  #define CLEAR_SCREEN      "\033[H\033[J"
+ #define AN(string)        (strchr("AEIOU", toupper(*string)) ? "an" : "a")
+ 
  char **parse_keywords     (const char *keywords, int *num_keywords);
  bool is_keyword           (const char *keywords, const char *word, 
  			   bool abbrev_ok);
  int  find_keyword         (const char *keywords, const char *string);
+ void add_keyword          (char **keywords_ptr, const char *word);
+ void remove_keyword       (char *keywords, const char *word);
  void trim                 (char *string);
  void strip_word           (char *string, const char *word);
  int  replace_string       (char **string, const char *a, const char *b, 
***************
*** 121,127 ****
        hashIteratorNext(it), \
        key = hashIteratorCurrentKey(it), val = hashIteratorCurrentVal(it))
  
! 
  
  
  //
--- 131,142 ----
        hashIteratorNext(it), \
        key = hashIteratorCurrentKey(it), val = hashIteratorCurrentVal(it))
  
! // iterate across all of the elements in a map
! #define ITERATE_MAP(key, val, it) \
!   for(key = mapIteratorCurrentKey(it), val = mapIteratorCurrentVal(it); \
!       key != NULL; \
!       mapIteratorNext(it), \
!       key = mapIteratorCurrentKey(it), val = mapIteratorCurrentVal(it))
  
  
  //
diff -crN nakedmudv1.0/src/world.c nakedmudv1.4/src/world.c
*** nakedmudv1.0/src/world.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/world.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 25,31 ****
  #include "world.h"
  
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  
--- 25,31 ----
  #include "world.h"
  
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  
  
diff -crN nakedmudv1.0/src/zone.c nakedmudv1.4/src/zone.c
*** nakedmudv1.0/src/zone.c	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/src/zone.c	2010-11-01 15:54:18.000000000 -0500
***************
*** 18,24 ****
  #include "dialog.h"
  
  #ifdef MODULE_SCRIPTS
! #include "modules/scripts/script.h"
  #endif
  
  
--- 18,24 ----
  #include "dialog.h"
  
  #ifdef MODULE_SCRIPTS
! #include "scripts/script.h"
  #endif
  
  
diff -crN nakedmudv1.0/TODO nakedmudv1.4/TODO
*** nakedmudv1.0/TODO	2010-11-01 15:54:17.000000000 -0500
--- nakedmudv1.4/TODO	2010-11-01 15:54:18.000000000 -0500
***************
*** 3,24 ****
  
  
  +-- NOT COMPLETE
    * random dungeon generator
    * spellchecking in the text editor
    * mounts and vehicles
    * being able to stream music would be cool...
!   * clean up and document resedit in modules/olc
!   * write helpfiles, create a better helpfile system, and do hedit
!   * Document all of the modules
!   * Finish cleaning up all of the module stuff
    * tracking and path following
    * shops (for mobiles and players)
    * customized prompts
    * DOCUMENT DOCUMENT DOCUMENT!! Most of the major headers need full
      documentation still.
-   * soft-code chat channels
    * character positions and changing of positions is a bit of a hack.
!     it could really do with some cleaning up.
    * Mysty's Dialog
      * Betta
      * Oren
--- 3,26 ----
  
  
  +-- NOT COMPLETE
+   * remove the EXIT_DATA parameter from the script functions
+   * write helpfiles, create a better helpfile system, and do hedit
+   * condense normal and special exits in rooms
+   * soft-code chat channels
    * random dungeon generator
    * spellchecking in the text editor
    * mounts and vehicles
    * being able to stream music would be cool...
!   * clean up and document resedit in the olc module
    * tracking and path following
    * 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
***************
*** 30,37 ****
  
  
  +-- NEEDS DEBUGGING
-   * check all of our ITERATE_NEXT and make sure that we're not using
-     it in any cases where we might remove the current element we're on
    * containers
    * room reset
    * Make sure extract obj/char is catching everything, and is running well
--- 32,37 ----
