]> jfr.im git - irc/gameservirc.git/blobdiff - gameserv/gameserv.cpp
implemented the tavern only listing certain items based on level
[irc/gameservirc.git] / gameserv / gameserv.cpp
index 1929a2f170fbf303077a435d1d5a3cab11f8959c..26cbe2b90bc168b947f8e63b61aa9c8af0cd56cf 100644 (file)
@@ -1,16 +1,21 @@
 #include "aClient.h"
 #include "config.h"
 #include "extern.h"
+#include "player.h"
+#include "pouch.h"
 #include "flags.h"
 #include "list.h"
+#include "level.h"
 #include "sockhelp.h"
+#include "item.h"
 
 #include <cctype>
 #include <fstream>
+#include <stdlib.h>
+#include <list>
+#include <iterator>
 
-using std::ifstream;
-using std::ofstream;
-using std::ios;
+using namespace std;
 
 #if defined(HAVE_CRYPT_H)
 
@@ -22,22 +27,20 @@ using std::ios;
 
 #endif
 
-// this will be hash.cpp start
-// thank you wcampbel
-unsigned long sHASH(const unsigned char *name);
-unsigned long iHASH(const unsigned char *name);
-List<aClient> players[U_TABLE_SIZE];
-// this will be hash.cpp end
-
-
-Monster *monsters[LEVELS][MONSTERS];   // Monsters per level. Total = MONSTERS * LEVELS
-Monster boss;                          // The boss monster
-
-Monster *masters[LEVELS];              // A master for each level
+Monster dragon;                                // The current dragon
+Level levels[LEVELS];                  // The newest way to store monsters
+list<item*> Items;                      // The master list of items
+list<tavernItem> tavern;                // The list of items available at the tavern
 
 // Database functions
 int save_gs_dbase();
 int load_gs_dbase();
+int load_items();
+int load_tavern();
+int load_dragon();
+int save_dragon();
+
+item *findItemByID(int id);
 
 // String functions
 #ifndef HAVE_STRTOK
@@ -50,7 +53,7 @@ int strnicmp(const char *s1, const char *s2, size_t len);
 
 /********** Password functions **********/
 
-bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
+bool passcmp(const char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
 
 bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
  
@@ -61,7 +64,7 @@ bool check_password(char *name, char *plaintext); // Finds a password for the gi
 
 bool shuttingdown;
 bool timedOut(Player *p);
-void  updateTS(Player *p);
+void updateTS(Player *p);
 void timeOutEvent(Player *p);
 
 bool is_playing(char *u); // True if the given nickname in the clients list is playing.
@@ -76,6 +79,9 @@ bool player_fight(aClient *user);
 bool master_fight(char *u); // True if the player is fighting their master.
 bool master_fight(aClient *user);
 
+bool dragon_fight(char *u); // True if the player is fighting the dragon.
+bool dragon_fight(aClient *user);
+
 /********** GameServ Booleans **********/
 
 void display_help(char *u, char *file = NULL);
@@ -92,15 +98,15 @@ void refresh(Player *p);
 void refreshall();
 void updateTS(Player *p);
 void reset(Player *p);
-void init_masters();
-void init_monsters();
+bool load_masters();
 bool load_monsters();
+bool load_levels();
 void delete_monsters();
-void delete_masters();
 
 void do_admin(char *u);
 void do_attack(char *u);
 void do_bank(char *u);
+void do_check(char *u);
 void do_fight(char *u);
 void do_heal(char *u);
 void do_help(char *u);
@@ -111,10 +117,12 @@ void do_register(char *u);
 void do_list(char *u);
 void do_logout(char *u);
 void do_master(char *u);
+void do_dragon(char *u);
 void do_play(char *u);
 void do_quitg(char *u);
 void do_reset(char *u);
 void do_run(char *u);
+void do_set(char *u);
 void do_stats(char *u);
 void do_store(char *u);
 void do_tavern(char *u);
@@ -123,6 +131,7 @@ void see_master(char *u);
 
 void logout(aClient *user);
 void showstats(const char *u, const char *nick);
+void showTavern(aClient *user);
 void showinventory(aClient *from, aClient *to);
 void showBankBalance(const char *u);
 void end_turn(aClient *user);
@@ -133,15 +142,15 @@ char *weapons[WNA] = {  "Fists", "Stick", "Dagger", "Quarterstaff",  "Short Swor
                        "Chain Saw", "Poison Sword",  "Flame Sword", "Earth Hammer", 
                        "Light Saber", "Masamune", "Mystical Sword"};
 
-char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor", 
+char *armors[WNA] = { "Birthday Suit", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor", 
                      "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit", 
                      "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor", 
                      "Hades' Cloak", "Dragon Scales", "Adamantium"};
 
 int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000, 
                        1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
-int webonus[WNA] = {1, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
-int arbonus[WNA] = {1, 2, 4, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
+int webonus[WNA] = {2, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
+int arbonus[WNA] = {2, 3, 5, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
 
 int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
 int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
@@ -164,20 +173,6 @@ void gameserv(char *source, char *buf)
        log("Source: %s  Command: %s", source, cmd);
     #endif
 
-    struct tm *tm;
-    time_t ti;
-    time(&ti);
-    tm = localtime(&ti);
-
-    int curday = tm->tm_mday;
-
-    if (curday != day)
-    {
-        refreshall();
-        day = curday;
-       save_day(); // here i come to save the day!
-    }
-
     if (strnicmp(cmd, "\1PING", 6) == 0)
     {
        char *ts;
@@ -197,6 +192,8 @@ void gameserv(char *source, char *buf)
        do_fight(source);
     } else if (stricmp(cmd, "ATTACK") == 0) {
        do_attack(source);
+    } else if (stricmp(cmd, "CHECK") == 0) {
+       do_check(source);
     } else if (stricmp(cmd, "RUN") == 0) {
        do_run(source);
     } else if (stricmp(cmd, "USE") == 0) {
@@ -207,6 +204,8 @@ void gameserv(char *source, char *buf)
        do_inventory(source);
     } else if (stricmp(cmd, "MASTER") == 0) {
        do_master(source);
+    } else if (stricmp(cmd, "DRAGON") == 0) {
+       do_dragon(source);
     } else if (stricmp(cmd, "STORE") == 0) {
        do_store(source);
     } else if (stricmp(cmd, "BANK") == 0) {
@@ -223,12 +222,16 @@ void gameserv(char *source, char *buf)
        do_list(source);
     } else if (stricmp(cmd, "LOGOUT") == 0) {
        do_logout(source);
+    } else if (stricmp(cmd, "NEWS") == 0) {
+       do_news(source);
     } else if (stricmp(cmd, "REGISTER") == 0) {
        do_register(source);
     } else if (stricmp(cmd, "IDENTIFY") == 0) {
        do_identify(source);
     } else if (stricmp(cmd, "HELP") == 0) {
        do_help(source);
+    } else if (stricmp(cmd, "SET") == 0) {
+       do_set(source);
     } else if (stricmp(cmd, "STATS") == 0) {
        do_stats(source);
     } else if (stricmp(cmd, "SHUTDOWN") == 0) {
@@ -291,7 +294,7 @@ void gameserv(char *source, char *buf)
            }
            else if (stricmp(cmd2, "MONSTERS") == 0)
            {
-               notice(s_GameServ, source, "Loading monster data from %s", monsterdata);
+               notice(s_GameServ, source, "Loading monster data");
                load_monsters();
            }
            else
@@ -315,6 +318,14 @@ void gameserv(char *source, char *buf)
            char *rest = strtok(NULL, "");
            raw("%s", rest);
        }
+    } else if (stricmp(cmd, "PRINT") == 0) {
+       for (int x = 0; x < LEVELS; x++)
+           levels[x].monsters.print();
+    } else if (stricmp(cmd, "RANDOM") == 0) {
+       char *rstr = strtok(NULL, "");
+       range trange;
+       trange.setRange(rstr);
+       notice(s_GameServ, source, "Random number in that range: %d", trange.random());
     #endif
     } else {
        aClient *user;
@@ -369,7 +380,7 @@ void showstats(const char *u, const char *nick)
     }
     else if (ni->stats)
     {
-        notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
+        notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name.c_str());
 
         sprintf(buf, "Experience: %ld", ni->stats->exp);
         space = spaces(strlen(buf), " ");
@@ -385,26 +396,27 @@ void showstats(const char *u, const char *nick)
         notice(s_GameServ, sender->getNick(), "Hit Points: %d of %d", ni->stats->hp,
                  ni->stats->maxhp);
 
-        sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
+        sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->wea]);
         space = spaces(strlen(buf), " ");
         notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
-                 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
+                 buf, space, ni->stats->defense + arbonus[ni->stats->arm]);
         delete [] space;
 
-        sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
+        sprintf(buf, "Armor: %s", armors[ni->stats->arm]);
         space = spaces(strlen(buf), " ");
         notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
-                 weapons[ni->stats->weapon]);
+                 weapons[ni->stats->wea]);
         delete [] space;
 
         sprintf(buf, "Forest Fights: %d", ni->stats->forest_fights);
         space = spaces(strlen(buf), " ");
         notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
         delete [] space;
+       showinventory(ni, ni);
     }
     else
     {
-       notice(s_GameServ, u, "%s is not playing!", ni->stats->name);
+       notice(s_GameServ, u, "%s is not playing!", ni->stats->name.c_str());
     }
     delete [] buf;
 }
@@ -470,7 +482,7 @@ void notice(const char *source, const char *dest, const char *fmt, ...)
        if (isUsePrivmsg())
            strcpy(commanduse, "P");
        else
-           strcpy(commanduse, "N");
+           strcpy(commanduse, "O");
     #else
 
        if (isUsePrivmsg())
@@ -513,6 +525,7 @@ void notice(const char *source, const char *dest, const char *fmt, ...)
                case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break; 
                case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
                case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
+               case 'c': sprintf(input, "%s%c", input, va_arg(args, int)); break;
                case 'l':
                   if (*++t == 'd')
                          sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
@@ -573,9 +586,25 @@ char *strtok(char *str, const char *delim)
 }
 #endif
 
+void do_check(char *u)
+{
+    int days, hours, minutes, seconds;
+    long complete;
+    complete = (lastrefresh + refreshperiod) - time(NULL);
+    days = complete / 86400;
+    hours = (complete % 86400) / 3600;
+    minutes = (complete % 86400) % 3600 / 60;
+    seconds = (complete % 86400) % 3600 % 60;
+
+    notice(s_GameServ, u, "Time left to next refresh: %dd %dh %dm %ds", 
+          days, hours, minutes, seconds);
+}
+
 void do_list(char *u)
 {
     aClient *user;
+    char *cmd = strtok(NULL, " ");
+
     if (!(user = find(u)))
     {
        log("Fatal Error: Couldn't find %s in the client list", u);
@@ -591,25 +620,29 @@ void do_list(char *u)
 
     ListNode<aClient> *temp;
     bool header = false;
+
   for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
   {
     temp = players[x].First();
     if (!players[x].isEmpty())
     {
-       if (!header)
-       {
-           notice(s_GameServ, u, "People Playing:");
-           header = true;
-       }
        while(temp)
        {
-           #ifdef P10
-           notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getRealNick(), 
-                  temp->getData()->stats->name);
-           #else
-           notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getNick(), 
-                  temp->getData()->stats->name);
-           #endif
+           if (cmd || is_playing(temp->getData()))
+           {
+               if (!header)
+               {
+                   notice(s_GameServ, u, "Players:");
+                   header = true;
+               }
+               #ifdef P10
+               notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getRealNick(), 
+                       temp->getData()->stats->name.c_str());
+               #else
+               notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getNick(), 
+                       temp->getData()->stats->name.c_str());
+               #endif
+           }
 
            temp = temp->Next();
        }
@@ -621,16 +654,399 @@ void do_list(char *u)
        notice(s_GameServ, u, "End of List");
 
 }
+void do_set(char *u)
+{
+  aClient *user, *target;
+  char *name = strtok(NULL, " ");
+  char *cmd = strtok(NULL, " ");
+  char *cmd2;
+  
+  if (!(user = find(u)))
+    {
+      notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
+            "Buf: %s LOGOUT", u);
+      return;
+    }
+  else if (isIgnore(user))
+    {
+#ifdef DEBUGMODE
+      log("Ignoring %s.", user->getNick());
+#endif
+      return;
+    }
+  else if (!name)
+    {
+      notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
+      return;
+    }
+  else if (!(target = findplayer(name)))
+    {
+      // Back the pointers up... they didn't send a name probably
+      cmd2= cmd;
+      cmd = name;
+      target = user;
+
+      if (!is_playing(user))
+       {
+         notice(s_GameServ, u, "You must be playing to set things for yourself!");
+         return;
+       }
+    }
+  else
+    {
+      cmd2 = strtok(NULL, " ");
+    }
+
+  // Regardless of the previous if/else, if it got here, we know we have the cmd pointer at the right spot.
+  if (stricmp(cmd, "PASSWORD") == 0)
+    {
+      // Person is looking to change their password
+      // If they're an admin, or it's theirself, allow it
+      // cmd2 is pointing to the password now
+      if (isAdmin(user) || user == target)
+       {
+         target->stats->setPassword(cmd2);
+         notice(s_GameServ, u, "Password successfully changed");
+       }
+      else if (user != target && !isAdmin(user))
+       {
+         notice(s_GameServ, u, "You must be a %S admin to set other peoples' passwords.");
+         return;
+       }
+    }
+  else if (stricmp(cmd, "BANK") == 0 || stricmp(cmd, "BALANCE") == 0)
+    {
+        if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+       else if (stricmp(cmd, "BANK") == 0)
+       {
+         cmd2 = strtok(NULL, " "); // Need an extra parameter for set bank balance
+       }
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] [BANK] BALANCE <NUMBER>");
+           return;
+       }
+
+       target->stats->bank = stringtoint(cmd2);
+
+       // Cheap bounds checking
+       if (target->stats->bank > 2000000000)
+           target->stats->bank = 2000000000;
+       else if (target->stats->bank < 0)
+           target->stats->bank *= -1;
+
+       notice(s_GameServ, u, "Bank balance changed to %ld!", target->stats->bank);
+    }
+  else if (stricmp(cmd, "PLAYER") == 0)
+    {
+      if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+      else if (stricmp(cmd2, "FIGHTS") != 0)
+       {
+         notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
+         return;
+       }
+      else
+       {
+         cmd2 = strtok(NULL, " ");
+           if (!cmd2)
+           {
+               notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
+               return;
+           }
+         target->stats->player_fights = stringtoint(cmd2);
+
+         if (target->stats->player_fights < 0)
+             target->stats->player_fights *= -1;
+
+         notice(s_GameServ, u, "Player fights changed to %d!", target->stats->player_fights);
+       }         
+    }
+  else if (stricmp(cmd, "FOREST") == 0)
+    {
+      if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+      else if (stricmp(cmd2, "FIGHTS") != 0)
+       {
+         notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <number>");
+         return;
+       }
+      else
+       {
+         cmd2 = strtok(NULL, " ");
+           if (!cmd2)
+           {
+               notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <NUMBER>");
+               return;
+           }
+
+         target->stats->forest_fights = stringtoint(cmd2);
+
+         if (target->stats->forest_fights < 0)
+             target->stats->forest_fights *= -1;
+
+         notice(s_GameServ, u, "Forest fights changed to %d!", target->stats->forest_fights);
+       }         
+    }
+  else if (stricmp(cmd, "GOLD") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] GOLD <NUMBER>");
+           return;
+       }
+         target->stats->gold = stringtoint(cmd2);
+
+         if (target->stats->gold > 2000000000)
+             target->stats->gold = 2000000000;
+         else if (target->stats->gold < 0)
+             target->stats->gold *= -1;
+
+         notice(s_GameServ, u, "Gold set to %ld", target->stats->gold);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "STRENGTH") == 0 && stricmp(cmd2, "POTIONS") != 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] STRENGTH <NUMBER>");
+           return;
+       }
+
+         target->stats->strength = stringtoint(cmd2);
+
+         if (target->stats->strength < 0)
+               target->stats->strength *= -1;
+
+         notice(s_GameServ, u, "Strength set to %d", target->stats->strength);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "DEFENSE") == 0 && stricmp(cmd2, "POTIONS") != 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] DEFENSE <NUMBER>");
+           return;
+       }
+
+         target->stats->defense = stringtoint(cmd2);
+
+         if (target->stats->defense < 0)
+               target->stats->defense *= -1;
+
+         notice(s_GameServ, u, "Defense set to %d", target->stats->defense);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "HP") == 0 && stricmp(cmd2, "POTIONS") != 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HP <NUMBER>");
+           return;
+       }
+         target->stats->hp = stringtoint(cmd2);
+
+         if (target->stats->hp < 0)
+               target->stats->hp *= -1;
+
+         notice(s_GameServ, u, "HP set to %d", target->stats->hp);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "MAXHP") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] MAXHP <NUMBER>");
+           return;
+       }
+         target->stats->maxhp = stringtoint(cmd2);
+
+         if (target->stats->maxhp < 0)
+               target->stats->maxhp *= -1;
+
+         notice(s_GameServ, u, "MaxHP set to %d", target->stats->maxhp);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "EXPERIENCE") == 0 || stricmp(cmd, "EXP") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {EXPERIENCE|EXP} <NUMBER>");
+           return;
+       }
+
+         target->stats->exp = stringtoint(cmd2);
+
+         if (target->stats->exp > 2000000000)
+               target->stats->exp = 2000000000;
+         else if (target->stats->exp < 0)
+               target->stats->exp *= -1;
+
+         notice(s_GameServ, u, "Exp set to %ld", target->stats->exp);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "LEVEL") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] LEVEL <NUMBER>");
+           return;
+       }
+         target->stats->level = stringtoint(cmd2);
+
+         if (target->stats->level < 0)
+               target->stats->level = 1;
+         else if (target->stats->level > REALLEVELS)
+               target->stats->level = REALLEVELS;
+
+         notice(s_GameServ, u, "Level set to %d", target->stats->level);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "ALIVE") == 0)
+  {
+     if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+     else
+       {
+         cmd2 = strtok(NULL, " ");
+         if (!cmd2 || (stricmp(cmd2, "TRUE") != 0 && stricmp(cmd2, "FALSE") != 0))
+         {
+            notice(s_GameServ, u, "SYNTAX: /msg %S SET ALIVE TRUE|FALSE");
+            return;
+         }
+         else if (stricmp(cmd2, "TRUE") == 0)
+         {
+            notice(s_GameServ, u, "%s has been Resurrected!", target->stats->name.c_str());
+            setAlive(target->stats);
+         }
+         else
+         {
+            notice(s_GameServ, u, "%s is now dead!", target->stats->name.c_str());
+            clearAlive(target->stats);
+         }
+       }
+  }
+  else if (stricmp(cmd, "SEEN") == 0)
+    {
+      if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+      else if (stricmp(cmd2, "MASTER") != 0)
+       {
+         notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] SEEN MASTER {TRUE|FALSE}");
+         return;
+       }
+      else
+       {
+         cmd2 = strtok(NULL, " ");
+         if (!cmd2 || (stricmp(cmd2, "TRUE") != 0 && stricmp(cmd2, "FALSE") != 0))
+         {
+            notice(s_GameServ, u, "SYNTAX: /msg %S SET [NICK] SEEN MASTER {TRUE|FALSE}");
+            return;
+         }
+         else if (stricmp(cmd2, "TRUE") == 0)
+         {
+            notice(s_GameServ, u, "%s has seen their master now.", target->stats->name.c_str());
+            target->addFlag(FLAG_MASTER);
+         }
+         else
+         {
+            notice(s_GameServ, u, "%s has not seen their master now.", target->stats->name.c_str());
+            target->remFlag(FLAG_MASTER);
+         }
+       }         
+    }
+  else
+  {
+     notice(s_GameServ, u, "Unknown command: SET %s", cmd);
+     notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
+     return;
+  }
+}
 
 void do_logout(char *u)
 {
     aClient *user;
+    char *name = strtok(NULL, " ");
+
     if (!(user = find(u)))
     {
        notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
                "Buf: %s LOGOUT", u);
        log("Could not find aClient Buf: %s LOGOUT", 
                u);
+       return;
     }
     else if (isIgnore(user))
     {
@@ -639,18 +1055,38 @@ void do_logout(char *u)
        #endif
        return;
     }
-    else if (!is_playing(user))
-    {
-       notice(s_GameServ, u, "You're not logged in!");
-    }
-    else if (is_fighting(user))
+
+    if (name)
     {
-       notice(s_GameServ, u, "You can't logout while fighting!");
+       if (!isAdmin(user))
+       {
+           notice(s_GameServ, u, "You must be a %S admin to use this command!");
+       }
+       else if (!(user = findplayer(name)))
+       {
+           notice(s_GameServ, u, "Couldn't find a player named %s", name);
+       }
+       else
+       {
+           notice(s_GameServ, u, "Logging out %s", user->stats->name.c_str());
+           logout(user);
+       }
     }
-    else
+    else if (!name)
     {
-       notice(s_GameServ, u, "You have left the fields. You have lived to kill another day!");
-       logout(user);
+       if (!is_playing(user))
+       {
+           notice(s_GameServ, u, "You're not logged in!");
+       }
+       else if (is_fighting(user))
+       {
+           notice(s_GameServ, u, "You can't logout while fighting!");
+       }
+       else
+       {
+           notice(s_GameServ, u, "You have left the fields. You have lived to kill another day!");
+           logout(user);
+       }
     }
 }
 
@@ -660,7 +1096,7 @@ void logout(aClient *user)
     {
        ListNode<aClient> *it;
        aClient *temp;
-       unsigned long hv = iHASH((unsigned char *) user->stats->name);
+       unsigned long hv = iHASH((unsigned char *) user->stats->name.c_str());
        it = players[hv].Find(user);
 
         if (!it)
@@ -714,17 +1150,15 @@ void do_register(char *u)
     name = strtok(NULL, " ");
     password = strtok(NULL, " ");
 
-    static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
-    static char salt[3];
-    
-    salt[0] = saltChars[rand() % strlen(saltChars)];
-    salt[1] = saltChars[rand() % strlen(saltChars)];
-    salt[2] = '\0';
-
     if (!name)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
     }
+    else if (stricmp(name, s_GameServ) == 0)
+    {
+       notice(s_GameServ, u, "You can't use %S as a name!");
+       return;
+    }
     else if (!password)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
@@ -750,19 +1184,22 @@ void do_register(char *u)
         if (!is_playing(user))
         {
            ListNode<aClient> *temp;
-           user->stats = new Player(user);
+           user->stats = new Player();
            user->stats->client = user; // Set the backwards pointer
            user->stats->reset(); // set the user up
-           strncpy(user->stats->password, crypt(password, salt), 255);
-           strncpy(user->stats->name, name, 255);
+           user->stats->setPassword(password);
+           user->stats->name = name;
            unsigned long hv = iHASH((unsigned char *) name);
            updateTS(user->stats);
            temp = players[hv].insertAtBack_RLN(user);
            temp->setPtr(user); // This is an extra step, but necessary for now
 
-           notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name, password);
+           // Update the last login time
+           user->stats->lastlogin = time(NULL);
+
+           notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name.c_str(), password);
            notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
-           log("Nickname %s registered player %s.", u, user->stats->name);
+           log("Nickname %s registered player %s.", u, user->stats->name.c_str());
            setPlaying(user); // set the playing flag
        }
        else
@@ -810,7 +1247,7 @@ void do_identify(char *u)
     }
     else {
        ListNode<aClient> *temp;
-       unsigned long hv = iHASH((unsigned char *) p->stats->name);
+       unsigned long hv = iHASH((unsigned char *) p->stats->name.c_str());
        temp = players[hv].Find(p);
        if (!temp)
        {
@@ -828,14 +1265,19 @@ void do_identify(char *u)
 
 
        #ifdef DEBUGMODE
-           log("Player %s IRC: %s Identified", user->stats->name, 
+           log("Player %s IRC: %s Identified", user->stats->name.c_str()
                user->getNick());
        #endif
 
        setPlaying(user); // set the playing flag
 
        temp->setPtr(user);
-       notice(s_GameServ, u, "Password Accepted. Identified.");            
+
+       // Update the last login time
+       user->stats->lastlogin = time(NULL);
+
+       notice(s_GameServ, u, "Password Accepted. Identified.");
+       showNews(u, todaysnews);
     }
 }
 
@@ -868,157 +1310,78 @@ void do_stats(char *u)
        else
        {
            updateTS(user->stats);
-           showstats(u, user->stats->name);
+           showstats(u, user->stats->name.c_str());
        }
     }
     else
        showstats(u, nick);
 }
 
-void init_masters()
+bool load_masters()
 {
-    #ifdef DEBUGMODE
-       log("Calling delete_masters()");
-    #endif
+    ifstream infile(masterdata);
+    char *buf;
+    int l = 0;
+    buf = new char[1024];
 
-    delete_masters();
+    if (infile.fail())
+    {
+       log("Error opening %s", masterdata);
+       return false;
+    }
 
     #ifdef DEBUGMODE
-       log("Initializing masters");
+       log("Loading masters from %s", masterdata);
     #endif
 
-    for (int x = 0; x < LEVELS; x++)
-       masters[x] = new Monster;
-
-    strcpy(masters[0]->name, "Old Bones");
-    strcpy(masters[0]->weapon, "Dull Sword Cane");
-    masters[0]->strength = 25;
-    masters[0]->gold = 0;
-    masters[0]->exp = 0;
-    masters[0]->maxhp = 30;
-    masters[0]->hp = 30;
-    strcpy(masters[0]->death, "You have done well my student, but the road is long. Use your new strength with humility and honor as you progress in levels!");
-
-    strcpy(masters[1]->name, "Master Chang");
-    strcpy(masters[1]->weapon, "Nanchaku");
-    masters[1]->strength = 35;
-    masters[1]->gold = 0;
-    masters[1]->exp = 0;
-    masters[1]->maxhp = 40;
-    masters[1]->hp = 40;
-    strcpy(masters[1]->death, "You try to make out what Master Chang is saying, but the only thing you catch is something about a grasshopper.");
-
-    strcpy(masters[2]->name, "Chuck Norris");
-    strcpy(masters[2]->weapon, "Ranger Kick");
-    masters[2]->strength = 95;
-    masters[2]->gold = 0;
-    masters[2]->exp = 0;
-    masters[2]->maxhp = 70;
-    masters[2]->hp = 70;
-    strcpy(masters[2]->death, "Be strong, and keep your goals in site. Drink milk, and don't do drugs. One day you may be fighting next to me as a Texas Ranger YEEHAW!");
-
-
-    strcpy(masters[3]->name, "Mr. Miagi");
-    strcpy(masters[3]->weapon, "Petrified Bonsai");
-    masters[3]->strength = 130;
-    masters[3]->gold = 0;
-    masters[3]->exp = 0;
-    masters[3]->maxhp = 120;
-    masters[3]->hp = 120;
-    strcpy(masters[3]->death, "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!");
-
-    strcpy(masters[4]->name, "Jackie Chan");
-    strcpy(masters[4]->weapon, "Kung Fu Kick");
-    masters[4]->strength = 156;
-    masters[4]->gold = 0;
-    masters[4]->exp = 0;
-    masters[4]->maxhp = 200;
-    masters[4]->hp = 200;
-    strcpy(masters[4]->death, "I like to let people talk who like to talk... it's easier to find out how full of it they really are!");
-
-    strcpy(masters[5]->name, "Jet Li");
-    strcpy(masters[5]->weapon, "Motorcycle");
-    masters[5]->strength = 180;
-    masters[5]->gold = 0;
-    masters[5]->exp = 0;
-    masters[5]->maxhp = 400;
-    masters[5]->hp = 400;
-    strcpy(masters[5]->death, "Failure is a fuel for excuses. It's the doing the do, that makes the making.");
-
-
-    strcpy(masters[6]->name, "Muhammad Ali");
-    strcpy(masters[6]->weapon, "Quick Jab");
-    masters[6]->strength = 200;
-    masters[6]->gold = 0;
-    masters[6]->exp = 0;
-    masters[6]->maxhp = 600;
-    masters[6]->hp = 600;
-    strcpy(masters[6]->death, "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.");
-
-    strcpy(masters[7]->name, "Li Mu Bai");
-    strcpy(masters[7]->weapon, "Green Destiny");
-    masters[7]->strength = 225;
-    masters[7]->gold = 0;
-    masters[7]->exp = 0;
-    masters[7]->maxhp = 800;
-    masters[7]->hp = 800;
-    strcpy(masters[7]->death, "No growth without resistance.  No action without reaction.  No desire without restraint.");
-
-
-    strcpy(masters[8]->name, "Jimmy Wang Yu");
-    strcpy(masters[8]->weapon, "Flying Guillotine");
-    masters[8]->strength = 290;
-    masters[8]->gold = 0;
-    masters[8]->exp = 0;
-    masters[8]->maxhp = 1200;
-    masters[8]->hp = 1200;
-    strcpy(masters[8]->death, "You have beaten the one armed boxer. Proceed with caution!");
-
-    strcpy(masters[9]->name, "Wong Fei Hung");
-    strcpy(masters[9]->weapon, "Drunken Boxing");
-    masters[9]->strength = 385;
-    masters[9]->gold = 0;
-    masters[9]->exp = 0;
-    masters[9]->maxhp = 1800;
-    masters[9]->hp = 1800;
-    strcpy(masters[9]->death, "Hiccup! Monkey drinks master's wine!");
-
-    strcpy(masters[10]->name, "Bruce Lee");
-    strcpy(masters[10]->weapon, "Fists of fury");
-    masters[10]->strength = 600;
-    masters[10]->gold = 0;
-    masters[10]->exp = 0;
-    masters[10]->maxhp = 2500;
-    masters[10]->hp = 2500;
-    strcpy(masters[10]->death, "You must learn to concentrate. It is like a finger pointing away to the moon... DONT concentrate on the finger, or you will miss all the heavenly glory.");
-}
-
-void init_monsters()
-{
-    #ifdef DEBUGMODE
-       log("Calling delete_monsters");
-    #endif
+    for (l = 0; l < LEVELS - 1; l++)
+    {
+       infile.getline(buf, 1024, '\n');
 
-    delete_monsters();
+       log("%s", buf);
+       if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r')
+       {
+           l--;
+           continue;
+       }
+       else if (buf[0] == '^')
+           break;
 
-    for (int x = 0; x < LEVELS; x++)
-       for (int y = 0; y < MONSTERS; y++)
-           monsters[x][y] = new Monster();
-}
+       Monster *master = &levels[l].master;
 
-void delete_monsters()
-{
-    for (int x = 0; x < LEVELS; x++)
-       for (int y = 0; y < MONSTERS; y++)
-           if (monsters[x][y])
-               delete monsters[x][y];
+       char *name, *weapon, *strength, *gold, *exp, *maxhp, *death;
+
+
+       name = strtok(buf, "~");
+       weapon = strtok(NULL, "~");
+       strength = strtok(NULL, "~");
+       gold = strtok(NULL, "~");
+       exp = strtok(NULL, "~");
+       maxhp = strtok(NULL, "~");
+       death = strtok(NULL, "~");
+       
+       master->name = name;
+       master->weapon = weapon;
+       master->strength = stringtoint(strength);
+       master->gold = stringtoint(gold);
+       master->exp = stringtoint(exp);
+       master->maxhp = stringtoint(maxhp);
+       master->hp = master->maxhp;
+       master->death = death;
+    }
+
+    delete []buf;
+
+    if (l < LEVELS - 1)  // We didn't load a master for every level - check data/masters.dat
+       return false;
+    else
+       return true;
 }
 
-void delete_masters()
+void delete_monsters()
 {
     for (int x = 0; x < LEVELS; x++)
-       if (masters[x])
-           delete masters[x];
+       levels[x].monsters.deleteNodes();
 }
 
 void display_monster(char *u)
@@ -1029,7 +1392,7 @@ void display_monster(char *u)
        Player *ni = user->stats;
        
        notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
-       notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name, ni->fight->hp);
+       notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name.c_str(), ni->fight->hp);
        notice(s_GameServ, u, "Here are your commands:");
        notice(s_GameServ, u, "/msg %S attack");
        notice(s_GameServ, u, "/msg %S run");
@@ -1055,7 +1418,7 @@ void display_players(aClient *user)
     {
        aClient *battle = user->stats->battle;
        notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->hp);
-       notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name, battle->stats->hp);
+       notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name.c_str(), battle->stats->hp);
        notice(s_GameServ, u, "Here are your commands:");
        notice(s_GameServ, u, "/msg %S attack");
        notice(s_GameServ, u, "/msg %S run");
@@ -1123,8 +1486,11 @@ bool player_fight(aClient *user)
 {
     if (!is_playing(user))
        return false;
-    else
-       return user->stats->battle != NULL;
+    else if (user->stats->battle != NULL && is_playing(user->stats->battle))
+    {
+       return user->stats->battle->stats != NULL;
+    }
+    return false;
 }
 
 bool master_fight(char *u)
@@ -1145,6 +1511,22 @@ bool master_fight(aClient *user)
        return user->stats->master != NULL;
 }
 
+bool dragon_fight(char *u)
+{
+    aClient *user;
+    if (!(user = find(u)))
+       return false;
+    else
+       return dragon_fight(user);
+}
+
+bool dragon_fight(aClient *user)
+{
+    if (!is_playing(user))
+       return false;
+    else
+       return (isDragonFight(user->stats));
+}
 void do_fight(char *u)
 {
     aClient *ni, *battle;
@@ -1194,20 +1576,22 @@ void do_fight(char *u)
     {
        notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
     }
-/*
- * Offline fighting not implemented yet.
- *   else if (!(fight = finduser(nick)))
- *   {
- *       ni->stats->battle = battle;
- *       battle->battle = ni;
- *       ni->yourturn = 1;
- *       battle->yourturn = 0;
- *       notice(s_GameServ, u, "You decide to fight %s while they're not online!",
- *                battle->stats->name);
- *       display_players(u);
- *   }
- */
-    else if (stricmp(ni->stats->name, battle->stats->name) == 0)
+
+/* offline fighting not available yet
+    else if (!(fight = finduser(nick)))
+    {
+        ni->stats->battle = battle;
+        battle->battle = ni;
+       setYourTurn(ni->stats);
+        clearYourTurn(battle->stats);
+
+        notice(s_GameServ, u, "You decide to fight %s while they're "\
+                             "not in the realm!",
+                 battle->stats->name.c_str());
+        display_players(u);
+    }
+*/
+    else if (stricmp(ni->stats->name.c_str(), battle->stats->name.c_str()) == 0)
     {
        notice(s_GameServ, u, "Are you trying to commit suicide!?");
     }
@@ -1217,29 +1601,29 @@ void do_fight(char *u)
     }
     else if (player_fight(battle))
     {
-       notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
+       notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name.c_str(), battle->stats->battle->stats->name.c_str());
     }
     else if (master_fight(battle))
     {
-       notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name);
+       notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name.c_str());
     }
     else if (is_fighting(battle))
     {
-       notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
+       notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name.c_str(), battle->stats->fight->name.c_str());
     }
     else if (ni->stats->level - battle->stats->level > maxbfightdistance)
     {
        // You can't fight someone below you by more than X level(s)
        // level 12 can fight level (12 - X) but not < (12 - X)
        notice(s_GameServ, u, "You may not fight %s. You're too strong!", 
-               battle->stats->name);
+               battle->stats->name.c_str());
     }
     else if (battle->stats->level - ni->stats->level > maxafightdistance)
     {
        // You can't fight someone above you by more than X level(S)
        // level 1 can fight level (1 + X), but not > (1 + X)
        notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\
-               "weakling!", ni->stats->name);
+               "weakling!", ni->stats->name.c_str());
     }
     else
     {
@@ -1256,17 +1640,18 @@ void do_fight(char *u)
        // Initiate Battle sequence!
        ni->stats->player_fights -= 1;
 
-        notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name);
-        notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name);
+        notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name.c_str());
+        notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name.c_str());
         notice(s_GameServ, battle->getNick(), "%s gets to go first "\
-                       "because they initiated!", ni->stats->name);
-        notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name);
+                       "because they initiated!", ni->stats->name.c_str());
+        notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name.c_str());
         display_players(ni);
     }
 }
 
 void do_use(char *u)
 {
+  /*
     aClient *user;
     Pouch *p;
 
@@ -1300,25 +1685,41 @@ void do_use(char *u)
 
     p = &user->stats->inventory;
 
-    if (stricmp(item, "HEALTH") == 0)
+    if (stricmp(item, "HEALING") == 0)
     {
        if (p->Healing() <= 0)
        {
-           notice(s_GameServ, u, "You are out of Health Potions!");
+           notice(s_GameServ, u, "You are out of Healing Potions!");
            return;
        }
-       int oldhealth = user->stats->hp;
-       notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
-       notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
+       int oldhealing = user->stats->hp;
        user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
-       notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealth);
-       p->decHealing();
-    }
-    else if (stricmp(item, "STRENGTH") == 0)
-    {
-       if (p->Strength() <= 0)
+       if (user->stats->hp - user->stats->maxhp >= 100)
        {
-           notice(s_GameServ, u, "You are out of Strength Potions!");
+           user->stats->hp = user->stats->maxhp + 100;
+
+           if (oldhealing >= (user->stats->maxhp + 100))
+           {
+               notice(s_GameServ, u, "You cannot hold anymore HP!");
+               return;
+           }
+       }
+
+       notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
+       notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
+       notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealing);
+       p->decHealing();
+       if (player_fight(user))
+       {
+           notice(s_GameServ, user->stats->battle->getNick(),
+               "%s has used a healing potion!");
+       }
+    }
+    else if (stricmp(item, "STRENGTH") == 0)
+    {
+       if (p->Strength() <= 0)
+       {
+           notice(s_GameServ, u, "You are out of Strength Potions!");
            return;
        }
        int oldstrength = user->stats->strength;
@@ -1327,6 +1728,11 @@ void do_use(char *u)
        user->stats->strength += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
        notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
        p->decStrength();
+       if (player_fight(user))
+       {
+           notice(s_GameServ, user->stats->battle->getNick(),
+               "%s has used a strength potion!");
+       }
     }
     else if (stricmp(item, "DEFENSE") == 0)
     {
@@ -1341,6 +1747,11 @@ void do_use(char *u)
        user->stats->defense += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
        notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
        p->decDefense();
+       if (player_fight(user))
+       {
+           notice(s_GameServ, user->stats->battle->getNick(),
+               "%s has used a defense potion!");
+       }
     }
     else if (stricmp(item, "HP") == 0)
     {
@@ -1356,14 +1767,21 @@ void do_use(char *u)
 
        notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
        p->decHP();
+       if (player_fight(user))
+       {
+           notice(s_GameServ, user->stats->battle->getNick(),
+               "%s has used a HP potion!");
+       }
     }
     else
     {
-       notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALTH | STRENGTH | DEFENSE}");
+       notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALING | STRENGTH | DEFENSE | HP}");
        return;
     }
 
     end_turn(user); // If they're fighting, end their turn
+  */
+  return;
 }
 void do_run(char *u)
 {
@@ -1398,23 +1816,23 @@ void do_run(char *u)
        notice(s_GameServ, u, "You run in place... try fighting next time.");
     else if (!player_fight(user) && !master_fight(user))
     {
-       notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name);
+       notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name.c_str());
        delete p->fight;
        p->fight = NULL;
     }
     else if (player_fight(user) && isYourTurn(p))
     {
-       notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name);
-       notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name);
+       notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name.c_str());
+       notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name.c_str());
        p2->battle = NULL;
     }
     else if (player_fight(user) && !isYourTurn(p))
     {
-       notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name);
+       notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name.c_str());
     }
     else if (master_fight(user))
     {
-       notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
+       notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name.c_str());
     }
     p->battle = NULL;
 }
@@ -1442,14 +1860,14 @@ void end_turn(aClient *user)
         // Opponent's Hit
         mhit = (fight->strength / 2) +
                (rand() % (fight->strength / 2) - (user->stats->defense +
-                arbonus[user->stats->armor]));
+                arbonus[user->stats->arm]));
     }
     else
     {
         // Opponent's Hit
-        mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
-               (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
-               (user->stats->defense + arbonus[user->stats->armor]));
+        mhit = (((battle->stats->strength + webonus[battle->stats->wea]) / 2) +
+               (rand() % ((battle->stats->strength + webonus[battle->stats->wea])) / 2) -
+               (user->stats->defense + arbonus[user->stats->arm]));
     }
     if (!player_fight(user))
     {
@@ -1457,20 +1875,21 @@ void end_turn(aClient *user)
         if (mhit > 0)
         {
             notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
-                     fight->name, fight->weapon, mhit);
+                     fight->name.c_str(), fight->weapon.c_str(), mhit);
         }
         else if (mhit <= 0)
-            notice(s_GameServ, u, "%s completely misses you!", fight->name);
+            notice(s_GameServ, u, "%s completely misses you!", fight->name.c_str());
 
         if (mhit >= user->stats->hp)
         {
             if (!master_fight(user))
             {
-                notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
+                notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name.c_str());
                 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
                         "of your experience!");
                 user->stats->gold = 0;
                 user->stats->exp -= (long int)(user->stats->exp * .10);
+               user->stats->hp = 0;
                 user->stats->fight = NULL;
                clearAlive(user->stats);
                 goto endturn;
@@ -1478,7 +1897,7 @@ void end_turn(aClient *user)
             else
             {
                 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
-                        "until tomorrow to try again", user->stats->master->name);
+                        "until tomorrow to try again", user->stats->master->name.c_str());
                 user->stats->fight = NULL;
                 user->stats->master = NULL;
                goto endturn;
@@ -1502,349 +1921,6 @@ endturn:
     delete nick;
 }
 
-void do_attack(char *u)
-{
-    int hit, mhit;
-    aClient *ni, *battle; // The player and perhaps the player they're fighting
-    Monster *fight; // The monster they may be fighting
-
-    if (!(ni = find(u)))
-    {
-       notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
-       return;
-    }
-    else if (isIgnore(ni))
-    {
-       #ifdef DEBUGMODE
-           log("Ignoring %s.", ni->getNick());
-       #endif
-       return;
-    }
-    else if (!is_playing(ni))
-    {
-       notice(s_GameServ, u, "You're not playing!");
-       return;
-    }
-    else if (!is_fighting(ni))
-    {
-       notice(s_GameServ, u, "You're not in battle!");
-       return;
-    }
-    else
-    {
-       if (!ni->stats->master) // This is not a master fight
-               fight = ni->stats->fight;       // Monster      Could be NULL
-       else                    // This IS a master fight
-               fight = ni->stats->master;      // Master       Could be NULL
-
-       battle = ni->stats->battle;             // Player       Could be NULL
-
-       // One has to be !NULL based on the previous else if
-       // We wouldn't be here if they were all NULL
-    }
-    updateTS(ni->stats);
-
-    if (!player_fight(ni))
-    {
-       // Player's Hit
-        hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
-              (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
-
-       // Opponent's Hit
-        mhit = (fight->strength / 2) +
-               (rand() % (fight->strength / 2) - (ni->stats->defense +
-                arbonus[ni->stats->armor]));
-    }
-    else
-    {
-       // Opponent's Hit
-        mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
-               (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
-               (ni->stats->defense + arbonus[ni->stats->armor]));
-
-       // Player's Hit
-        hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
-               (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
-               (battle->stats->defense + arbonus[battle->stats->armor]));
-    }
-
-  if (!player_fight(ni))
-  {
-    if (hit > 0)
-        notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
-    else
-        notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
-
-    if (hit >= fight->hp)
-    {
-        if (master_fight(ni))
-            notice(s_GameServ, u, "You have bested %s!", fight->name);
-        else
-            notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
-
-        notice(s_GameServ, u, "%s", fight->death);
-        notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
-                 fight->exp, fight->gold);
-
-       // If your new experience (or gold) will be greater than 2 billion,
-       // then set your exp to 2bil. (2 billion max)... otherwise add them.
-       // This could be a problem with overflowing out of the sign bit.
-       // Unsigned long int maybe? Leave it for now.
-        ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 : 
-                               ni->stats->exp + fight->exp);
-
-        ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 : 
-                               ni->stats->gold + fight->gold);
-
-
-        if (master_fight(ni))
-        {
-            notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
-            notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
-                     strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
-
-           // Increase your level
-            ni->stats->level++;
-
-           // Increase your maximum hit points
-            ni->stats->maxhp += hpbonus[ni->stats->level - 1];
-
-           // Heal the player by setting hp to their max
-            ni->stats->hp = ni->stats->maxhp;
-
-           // Add to your strength
-            ni->stats->strength += strbonus[ni->stats->level - 1];
-
-           // Add to your defensive power
-            ni->stats->defense += defbonus[ni->stats->level - 1];
-
-           // Clear the pointer for your master
-            ni->stats->master = NULL;
-        }
-
-       // They're dead so remove the pointer
-       delete ni->stats->fight;
-        ni->stats->fight = NULL; 
-       ni->stats->master = NULL;
-
-        return;
-    }
-    else
-    {
-        if (hit > 0)
-            fight->hp -= hit;
-        if (mhit > 0)
-        {
-            notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
-                     fight->name, fight->weapon, mhit);
-        }
-        else if (mhit <= 0)
-            notice(s_GameServ, u, "%s completely misses you!", fight->name);
-
-        if (mhit >= ni->stats->hp)
-        {
-            if (!master_fight(ni))
-            {
-                notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
-                notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
-                        "of your experience!");
-                ni->stats->gold = 0;
-                ni->stats->exp -= (long int)(ni->stats->exp * .10);
-                ni->stats->fight = NULL;
-               clearAlive(ni->stats);
-                return;
-            }
-            else
-            {
-                notice(s_GameServ, u, "%s has bested you! You will have to wait "\
-                        "until tomorrow to try again", ni->stats->master->name);
-                ni->stats->fight = NULL;
-                ni->stats->master = NULL;
-               return;
-            }
-        }
-        else
-        {
-            if (mhit > 0)
-                ni->stats->hp -= mhit;
-            display_monster(u);
-            return;
-        }
-    }
-  }
-  else if (player_fight(ni))
-  {
-/* Offline fighting not available yet
-   if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
-   {
-    if (hit > 0)
-        notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
-    else
-        notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
-    if (hit >= battle->stats->hp)
-    {
-        notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
-*        notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
-                (long int)(battle->stats->exp * .10), battle->stats->gold);
-        if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
-        {
-            ni->stats->exp += (long int)(battle->stats->exp * .10);
-            battle->stats->exp -= (long int)(battle->stats->exp * .10);
-        }
-*        else
-        {
-            battle->stats->exp -= (long int)(battle->stats->exp * .10);
-            ni->stats->exp = 2000000000;
-        }
-
-        if (2000000000 - ni->stats->gold > battle->stats->gold)
-        {
-*            ni->stats->gold += battle->stats->gold;
-            battle->stats->gold = 0;
-        }
-        else
-        {
-            battle->stats->gold = 2000000000 - ni->stats->gold;
-            ni->stats->gold = 2000000000;
-        }
-*        ni->stats->battle->stats->alive = 0;
-        ni->stats->battle->battle = NULL;
-        ni->stats->battle = NULL;
-        return;
-    }
-    else
-    {
-        if (hit > 0)
-*            battle->stats->hp -= hit;
-        if (mhit > 0)
-        {
-            notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
-                     battle->nick, weapons[battle->stats->weapon], mhit);
-        }
-        else if (mhit <= 0)
-            notice(s_GameServ, u, "%s completely misses you!", battle->nick);
-*
-        if (mhit >= ni->stats->hp)
-        {
-            notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
-            if (2000000000 - battle->stats->gold > ni->stats->gold)
-            {
-                notice(s_GameServ, u, "%s took all your gold!", battle->nick);
-                battle->stats->gold += ni->stats->gold;
-*                ni->stats->gold = 0;
-            }
-            else
-            {
-                notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
-                        battle->nick);
-                ni->stats->gold -= (2000000000 - battle->stats->gold);
-                notice(s_GameServ, u, "You were left dead with %d gold.",
-*                         (long int)ni->stats->gold);
-                battle->stats->gold = 2000000000;
-            }
-            ni->stats->battle->battle = NULL;
-            ni->stats->battle = NULL;
-            ni->stats->alive = 0;
-            return;
-        }
-*        else
-        {
-            if (mhit > 0)
-                ni->stats->hp -= mhit;
-            display_players(u);
-            return;
-        }
-    }
-   }
-* end offline fighting */
-
-   if (is_playing(battle))
-   {
-    if (!isYourTurn(ni->stats))
-    {
-        notice(s_GameServ, u, "Please wait until %s decides what to do!", 
-               battle->stats->name);
-        return;
-    }
-    if (hit > 0)
-    {
-        notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name, hit);
-
-        notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
-                                             "\ 2%d\ 2 damage!", ni->stats->name, 
-                                             weapons[ni->stats->weapon], hit);
-       clearYourTurn(ni->stats);
-       setYourTurn(battle->stats);
-        display_players(battle);
-    }
-    else
-    {
-        notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name);
-        notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name);
-       clearYourTurn(ni->stats);
-       setYourTurn(battle->stats);
-        display_players(battle);
-    }
-    if (hit >= battle->stats->hp)
-    {
-        notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
-        notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
-                (long int)(battle->stats->exp * .10), battle->stats->gold);
-        notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!", 
-               ni->stats->name);
-        battle->stats->hp = 0;
-        clearAlive(battle->stats);
-
-        if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
-        {
-            ni->stats->exp += (long int)(battle->stats->exp * .10);
-            battle->stats->exp -= (long int)(battle->stats->exp * .10);
-        }
-        else
-        {
-            battle->stats->exp -= (long int)(battle->stats->exp * .10);
-            ni->stats->exp = 2000000000;
-        }
-
-        if (2000000000 - ni->stats->gold > battle->stats->gold)
-        {
-           notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
-                                                "all gold on hand!");
-            ni->stats->gold += battle->stats->gold;
-            battle->stats->gold = 0;
-        }
-        else
-        {
-            battle->stats->gold = 2000000000 - ni->stats->gold;
-            notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
-
-            notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
-                       "gold.", ni->stats->name);
-
-            notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
-                       "left. All is not lost!", battle->stats->gold);
-
-            ni->stats->gold = 2000000000;
-        }
-       battle->stats->battle = NULL;
-        ni->stats->battle = NULL;
-        return;
-    }
-    else
-    {
-        if (hit > 0)
-            battle->stats->hp -= hit;
-       clearYourTurn(ni->stats);
-       setYourTurn(battle->stats);
-        notice(s_GameServ, u, "Please wait while %s decides what to do!", 
-               battle->stats->name);
-
-        return;
-    }
-   }
-  }
-}
-
 void do_heal(char *u)
 {
     aClient *ni;
@@ -1956,6 +2032,8 @@ return 1;
 
 long int stringtoint(char *number)
 {
+    return atol(number);
+/*
     long int x, len = strlen(number), sum = 0;
     if (len == 1)
         return chartoint(number[0]);
@@ -1963,6 +2041,7 @@ long int stringtoint(char *number)
     for (x = len - 2; x >= 0; x--)
         sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
     return sum;
+*/
 }
 
 long int pow(int x, int y)
@@ -2010,12 +2089,25 @@ int save_gs_dbase()
     {
        it = ptr->getData()->stats;
        clearYourTurn(it);
-       outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
+       outfile << it->name.c_str() << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
                << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
-               << it->armor << ' ' << it->weapon << ' '
+               << it->arm << ' ' << it->wea << ' '
                << it->forest_fights << ' ' << it->player_fights <<  ' ' 
-               << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
-               << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
+               << it->getFlags() << ' ' << it->password << ' ' << it->lastlogin;
+
+       // Traverse the list and write out each item ID and how many uses are left
+       if (!it->inventory->isEmpty())
+         {
+           list<itemContainer> *myitems;
+           list<itemContainer>::iterator item_iter;
+           myitems = it->inventory->getItems();
+           
+           for(item_iter = myitems->begin();item_iter != myitems->end();item_iter++)
+             {
+               outfile << ' ' << (*item_iter).getItem()->getID() << ' ' << (*item_iter).getUses();
+             }
+         }
+       outfile << endl;
        ptr = ptr->Next();
     }
    }
@@ -2023,13 +2115,179 @@ outfile.close();
 return 1;
 }
 
+int load_dragon()
+{
+    ifstream infile;
+    char *buf;
+
+    infile.open(dragondata);
+
+    if (infile.fail())
+    {
+       infile.clear();
+       log ("Error opening %s. Trying initialdragon.dat", dragondata);
+       infile.open("data/initialdragon.dat");
+       if (infile.fail())
+        {
+           log ("Error opening data/initialdragon.dat");
+           return 0;
+       }
+    }
+
+    buf = new char[1024];
+
+    infile.getline(buf, 1024, '\n');
+    infile.close(); // Done with the file... we have what we want
+
+    dragon.name = strtok(buf, "~");
+    dragon.weapon = strtok(NULL, "~");
+    dragon.gold = 0;
+    dragon.exp = 0;
+    dragon.strength = stringtoint(strtok(NULL, "~"));
+    dragon.hp = stringtoint(strtok(NULL, "~"));
+    dragon.defense = stringtoint(strtok(NULL, "~"));
+    dragon.death = strtok(NULL, "");
+
+    log ("loaded dragon: %s", dragon.name.c_str());
+
+    delete []buf;
+
+return save_dragon();  // Save the dragon file and return the status code :)
+}
+
+int save_dragon()
+{
+    ofstream outfile;
+
+    outfile.open(dragondata);
+
+    if (outfile.fail())
+    {
+       log ("Error opening %s. Exiting.", dragondata);
+       return 0;
+    }
+
+    outfile << dragon.name.c_str() << '~' << dragon.weapon.c_str() << '~' 
+               << dragon.strength << '~' << dragon.hp << '~' 
+               << dragon.defense << '~' << dragon.death.c_str() << "\n^"
+               << endl;
+
+outfile.close();
+
+return 1;
+}
+int load_tavern()
+{
+  ifstream infile;
+  char *buf;
+  tavernItem tempItem;
+  buf = new char[1024];
+  long id, level;
+
+  infile.open(tavernitemdata);
+  if (infile.fail())
+    {
+      log("Error opening %s", tavernitemdata);
+      return 0;
+    }
+
+  while (infile.getline(buf, 1024, '\n'))
+    {
+      try
+       {
+         if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
+           {
+             item *tempItem2;
+             id = stringtoint(strtok(buf, "~"));
+             level = stringtoint(strtok(NULL, ""));
+             tempItem2 = findItemByID(id);
+             if (tempItem2 == NULL)
+               {
+                 log("Invalid ID in %s", tavernitemdata);
+                 return 0;
+               }
+             tempItem.setItem(tempItem2);
+             tempItem.setLevel(level);
+
+             log("pushing item %s level %ld", tempItem2->getName().c_str(), level);
+             tavern.push_back(tempItem);
+           }
+       }
+      catch (char *str)
+       {
+         log("Exception loading tavern: %s", str);
+         delete []buf;
+         return 0;
+       }
+    }
+  delete []buf;
+  return 1;
+}
+int load_items()
+{
+  ifstream infile;
+  char *buf;
+  item *tempItem;
+
+
+  buf = new char[1024];
+
+  infile.open(itemdata);
+
+  if (infile.fail())
+    {
+      log("Error opening %s", itemdata);
+      return 0;
+    }
+
+  while (infile.getline(buf, 1024, '\n'))
+    {
+      if (buf[0] == '^')
+       break;
+      try
+       {
+         if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
+           {
+             switch(buf[0])
+               {
+               case '1':
+                 tempItem = new weapon();
+                 break;
+               case '2':
+                 tempItem = new armor();
+                 break;
+               case '3':
+                 tempItem = new potion();
+                 break;
+               default:
+                 log("Invalid Item Type %c in %s", buf[0], itemdata);
+                 delete []buf;
+                 return 0;
+                 break;
+               }
+             if(tempItem->setData(buf))
+               {
+                 Items.push_back(tempItem);
+               }
+           }
+       }
+      catch (char *str)
+       {
+         log("Exception loading items: %s", str);
+         delete []buf;
+         return 0;
+       }
+    }
+  delete []buf;
+  return 1;
+}
 int load_gs_dbase()
 {
     ifstream infile;
     aClient *temp;
     Player *p;
     char *tempname, *buf, *password;
-    buf = new char[1023];
+    buf = new char[1024];
 
     infile.open(playerdata);
 
@@ -2039,8 +2297,21 @@ int load_gs_dbase()
        return 0;
     }
 
-    while (infile.getline(buf, 1024, '\n'))
+    for (int x = 0; x < U_TABLE_SIZE; x++)
     {
+       ListNode<aClient> *tempNode;
+       tempNode = players[x].First();
+       while (tempNode)
+       {
+           if (tempNode->getData()->stats->client)
+               logout(tempNode->getData()->stats->client);
+           tempNode = tempNode->Next();
+       }
+       players[x].deleteNodes();
+    }
+
+    while (infile.getline(buf, 1024, '\n'))
+      {
        temp = new aClient;
        tempname = strtok(buf, " ");
        temp->stats = new Player(tempname);
@@ -2054,278 +2325,297 @@ int load_gs_dbase()
        p->maxhp = stringtoint(strtok(NULL, " "));
        p->strength = stringtoint(strtok(NULL, " "));
        p->defense = stringtoint(strtok(NULL, " "));
-       p->armor = stringtoint(strtok(NULL, " "));
-       p->weapon = stringtoint(strtok(NULL, " "));
+       p->arm = stringtoint(strtok(NULL, " "));
+       p->wea = stringtoint(strtok(NULL, " "));
        p->forest_fights = stringtoint(strtok(NULL, " "));
        p->player_fights = stringtoint(strtok(NULL, " "));
        p->setFlags(stringtoint(strtok(NULL, " ")));
 
+       
+       
        password = strtok(NULL, " ");
-       strcpy(p->password, password);
+       p->password = password;
        temp->setNick("Not Playing");
-       #ifdef P10
+#ifdef P10
        temp->setRealNick("Not Playing");
-       #endif
-
-       p->inventory.reset(); // Set inventory to all 0s
-       // Old player databases didn't have these three extra values
-       // If they come up null, leave them to 0 as the default.
-       // On the next gameserv database save, it will save the values.
-       tempname = strtok(NULL, " ");
-       if (tempname)
-           p->inventory.setHealing(stringtoint(tempname));
-
-       tempname = strtok(NULL, " ");
-       if (tempname)
-           p->inventory.setStrength(stringtoint(tempname));
-
-       tempname = strtok(NULL, " ");
-       if (tempname)
-           p->inventory.setDefense(stringtoint(tempname));
-
-       tempname = strtok(NULL, " ");
+#endif
+        tempname = strtok(NULL, " ");
        if (tempname)
-           p->inventory.setHP(stringtoint(tempname));
-       unsigned long hv = iHASH((unsigned char *) temp->stats->name);
-
+         p->lastlogin = stringtoint(tempname);
+       else
+         p->lastlogin = time(NULL);
+       
+       for (tempname = strtok(NULL, " "); tempname != NULL; tempname = strtok(NULL, " "))
+         {
+           long int id, uses;
+           list<item*>::iterator item_iter;
+           id = stringtoint(tempname);
+           tempname = strtok(NULL, " ");
+           uses = stringtoint(tempname);
+
+           item_iter = Items.begin();
+           while (item_iter != Items.end())
+             {
+               if ((*item_iter)->getID() == id)
+                 {
+                   p->inventory->addItem((*item_iter))->setUses(uses);
+                 }
+               item_iter++;
+             }
+         }
+
+       unsigned long hv = iHASH((unsigned char *) temp->stats->name.c_str());
+       
        temp->stats->client = NULL;
        players[hv].insertAtBack(temp);
        delete temp;
-    }
-delete [] buf;
-infile.close();
-return 1;
+      }
+    delete [] buf;
+    infile.close();
+    return 1;
 }
 
-bool passcmp(char *encrypted, char *plaintext)
-{
-    char salt[3];
-    char *plaintext2, *plainToencrypt;
-    bool same = false;
-
-    plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
-    strcpy(plaintext2, plaintext);
-   
-    salt[0] = encrypted[0];
-    salt[1] = encrypted[1];
-    salt[3] = '\0';
-
-    plainToencrypt = crypt(plaintext2, salt);
-
-    same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
-
-    delete []plaintext2;
-
-    return same;
+bool passcmp(const char *encrypted, char *plaintext)
+{
+  char salt[3];
+  char *plaintext2, *plainToencrypt;
+  bool same = false;
+  
+  plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
+  strcpy(plaintext2, plaintext);
+  
+  salt[0] = encrypted[0];
+  salt[1] = encrypted[1];
+  salt[3] = '\0';
+  
+  plainToencrypt = crypt(plaintext2, salt);
+  
+  same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
+  
+  delete []plaintext2;
+  
+  return same;
 }
 
 bool check_password(char *name, char *plaintext)
 {
-    aClient *client;
-
-    if (!(client = findplayer(name)))
-       return false;
-    else
+  aClient *client;
+  
+  if (!(client = findplayer(name)))
+    return false;
+  else
     {
-       return passcmp(client->stats->password, plaintext);
+      return passcmp(client->stats->password.c_str(), plaintext);
     }
 }
 
 void do_store(char *u)
 {
-    char *cmd = strtok(NULL, " ");
-    char *item = strtok(NULL, " ");
-    char *num = strtok(NULL, " ");
-    char *space;
-    int wep;
-    aClient *user;
-    Player *p;
-
-    if (!cmd || !item)
+  char *cmd = strtok(NULL, " ");
+  char *item = strtok(NULL, " ");
+  char *num = strtok(NULL, " ");
+  char *space;
+  int wep;
+  aClient *user;
+  Player *p;
+  
+  if (!cmd || !item)
     {
-       notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
-       notice(s_GameServ, u, "        \ 2STORE SELL {ARMOR | WEAPON}\ 2");
-       notice(s_GameServ, u, "        \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
-       return;
+      notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
+      notice(s_GameServ, u, "        \ 2STORE SELL {ARMOR | WEAPON}\ 2");
+      notice(s_GameServ, u, "        \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
+      return;
     }
-    else if (!(user = find(u)))
+  else if (!(user = find(u)))
     {
-       log("Fatal Error: could not find %s in client list", u);
-       return;
+      log("Fatal Error: could not find %s in client list", u);
+      return;
     }
-    else if (isIgnore(user))
+  else if (isIgnore(user))
     {
-       #ifdef DEBUGMODE
-           log("Ignoring %s.", user->getNick());
-       #endif
-       return;
+#ifdef DEBUGMODE
+      log("Ignoring %s.", user->getNick());
+#endif
+      return;
     }
-    else if (!is_playing(user))
+  else if (!is_playing(user))
     {
-       notice(s_GameServ, u, "You must be playing to use the store!");
-       return;
+      notice(s_GameServ, u, "You must be playing to use the store!");
+      return;
     }
-    else if (!isAlive(user->stats))
+  else if (!isAlive(user->stats))
     {
-       notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
-       return;
+      notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
+      return;
     }
-    updateTS(user->stats);
-
-    if (stricmp(cmd, "LIST") == 0)
+  updateTS(user->stats);
+  
+  if (stricmp(cmd, "LIST") == 0)
     {
-       if (stricmp(item, "WEAPONS") == 0)
+      if (stricmp(item, "WEAPONS") == 0)
        {
-            notice(s_GameServ, u, "Welcome to Kain's Armory");
-            notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
-           for (int x = 1; x < WNA; x++)
+         notice(s_GameServ, u, "Welcome to Kain's Armory");
+         notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
+         for (int x = 1; x < WNA; x++)
             {
-                space = spaces(strlen(weapons[x]), ".");
-                notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
-                free(space);
+             space = spaces(strlen(weapons[x]), ".");
+             notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
+             free(space);
             }
-           notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
-            notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
-
+         notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
+         notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
+         
        }
-       else if (stricmp(item, "ARMOR") == 0)
+      else if (stricmp(item, "ARMOR") == 0)
        {
-           notice(s_GameServ, u, "Welcome to Kain's Armory");
-           notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
-           for (int x = 1; x < WNA; x++)
+         notice(s_GameServ, u, "Welcome to Kain's Armory");
+         notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
+         for (int x = 1; x < WNA; x++)
             {
-               space = spaces(strlen(armors[x]), ".");
-               notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
-               free(space);
+             space = spaces(strlen(armors[x]), ".");
+             notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
+             free(space);
            }
-            notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
-            notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
-
-
+         notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
+         notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
+         
+         
        }
     } else if (stricmp(cmd, "BUY") == 0) {
-       if (!num)
+      if (!num)
        {
-           notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
-           return;
+         notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
+         return;
        }
-       else if (!isstringnum(num))
+      else if (!isstringnum(num))
        {
-           notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
-           return;
+         notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
+         return;
        }
-       if (stricmp(item, "WEAPON") == 0)
+      if (stricmp(item, "WEAPON") == 0)
         {
-            wep = stringtoint(num);
-            if (wep >= WNA || wep < 1)
+         wep = stringtoint(num);
+         if (wep >= WNA || wep < 1)
             {
-               notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
-                return;
+             notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
+             return;
             }
-
-           p = user->stats;
-
-            if (p->weapon != 0)
-                notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
-            else if (p->gold < prices[wep - 1])
-                notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
-            else
+         
+         p = user->stats;
+         
+         if (p->wea != 0)
+           notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->wea]);
+         else if (p->gold < prices[wep - 1])
+           notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
+         else
             {
-                notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
-                p->weapon = wep;
-                p->gold -= prices[wep - 1];
+             notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
+             p->wea = wep;
+             p->gold -= prices[wep - 1];
             }
         }
-       else if (stricmp(item, "ARMOR") == 0)
+      else if (stricmp(item, "ARMOR") == 0)
         {
-            wep = stringtoint(num);
-            if (wep >= WNA || wep < 1)
+         wep = stringtoint(num);
+         if (wep >= WNA || wep < 1)
             {
-               notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
-                return;
+             notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
+             return;
             }
-
-           p = user->stats;
-
-            if (p->armor != 0)
-                notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
-            else if (p->gold < prices[wep - 1])
-                notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
-            else
+         
+         p = user->stats;
+         
+         if (p->arm != 0)
+           notice(s_GameServ, u, "You have to sell your %s first!", armors[p->arm]);
+         else if (p->gold < prices[wep - 1])
+           notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
+         else
             {
-                notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
-                p->armor = wep;
-                p->gold -= prices[wep - 1];
+             notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
+             p->arm = wep;
+             p->gold -= prices[wep - 1];
             }
         }
+      else
+       {
+         notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
+         return;
+       }
     }
-    else if (stricmp(cmd, "SELL" ) == 0)
+  else if (stricmp(cmd, "SELL" ) == 0)
     {
-       p = user->stats;
-
-        if (stricmp(item, "WEAPON") == 0)
+      p = user->stats;
+      
+      if (stricmp(item, "WEAPON") == 0)
         {
-            if (p->weapon == 0)
+         if (p->wea == 0)
             {
-                notice(s_GameServ, u, "You want me to chop off your hands?");
-                return;
+             notice(s_GameServ, u, "You want me to chop off your hands?");
+             return;
             }
-            else if (p->gold == 2000000000)
+         else if (p->gold == 2000000000)
             {
-                notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
-                p->weapon = 0;
+             notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
+             p->wea = 0;
             }
-            else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
+         else if (2000000000 - p->gold < (prices[p->wea - 1] / 2))
             {
-                notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
-                notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
-                p->gold = 2000000000;
-                p->weapon = 0;
+             notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
+             notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
+             p->gold = 2000000000;
+             p->wea = 0;
             }
-            else
+         else
            {
-                notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
-                p->gold += (prices[p->weapon - 1] / 2);
-                p->weapon = 0;
+             notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->wea - 1] / 2));
+             p->gold += (prices[p->wea - 1] / 2);
+             p->wea = 0;
             }
         }
-        else if (stricmp(item, "ARMOR") == 0)
+      else if (stricmp(item, "ARMOR") == 0)
         {
-           p = user->stats;
-
-            if (p->armor == 0)
+         p = user->stats;
+         
+         if (p->arm == 0)
             {
-                notice(s_GameServ, u, "I don't think you can be any more naked...");
-                return;
+             notice(s_GameServ, u, "I don't think you can be any more naked...");
+             return;
             }
-            if (p->gold == 2000000000)
+         if (p->gold == 2000000000)
             {
-                notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
-                p->armor = 0;
+             notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
+             p->arm = 0;
             }
-            else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
+         else if (2000000000 - p->gold < (prices[p->arm - 1] / 2))
             {
-                notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
-                notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
-               p->gold = 2000000000;
-                p->armor = 0;
+             notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
+             notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
+             p->gold = 2000000000;
+             p->arm = 0;
             }
-            else
+         else
             {
-                notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
-                         (prices[p->armor - 1] / 2));
-
-                p->gold += (prices[p->armor - 1] / 2);
-                p->armor = 0;
+             notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
+                    (prices[p->arm - 1] / 2));
+             
+             p->gold += (prices[p->arm - 1] / 2);
+             p->arm = 0;
             }
        }
-        else
+      else
        {
-           notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
-           notice(s_GameServ, u, "        \ 2STORE SELL {ARMOR | WEAPON}\ 2");
-           notice(s_GameServ, u, "        \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
+         notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
+         notice(s_GameServ, u, "        \ 2STORE SELL {ARMOR | WEAPON}\ 2");
+         notice(s_GameServ, u, "        \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
        }
     }
+  else
+    {
+      notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
+      notice(s_GameServ, u, "        \ 2STORE SELL {ARMOR | WEAPON}\ 2");
+      notice(s_GameServ, u, "        \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
+      return;
+    }
 }
 void do_inventory(char *u)
 {
@@ -2351,152 +2641,171 @@ void do_inventory(char *u)
     updateTS(user->stats);
     showinventory(user, user);
 }
+
 void showinventory(aClient *from, aClient *to)
 {
-    char *nick = to->getNick();
+  char *nick;
+  if (!to)
+    to = from;
 
-    if (!to)
-       to = from;
-    if (is_playing(from))
+  nick = to->getNick();
+  
+  if (is_playing(from))
     {
-       Pouch *p = &from->stats->inventory;
-       notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
-       notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
-       notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
-       notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
-       notice(s_GameServ, nick, "      HP Potions: %d", p->HP());
+      if (from->stats->inventory->isEmpty())
+       {
+         notice(s_GameServ, nick, "You aren't carrying anything");
+         return;
+       }
+
+      list <itemContainer> *items;
+      items = from->stats->inventory->getItems();
+
+      list <itemContainer>::iterator item_iter;
+      item_iter = items->begin();
+
+      notice(s_GameServ, nick, "Inventory for %s:", from->stats->name.c_str());
+      int x = 0;
+      while (item_iter != items->end())
+       {
+         notice(s_GameServ, nick, "%d.) %s", ++x, (*item_iter).getItem()->getName().c_str());
+         item_iter++;
+       }
     }
+
 }
 void do_tavern(char *u)
 {
-    char *cmd = strtok(NULL, " ");
-    long int price;
-
-    aClient *user;
-    Player *p;
-    if (!(user = find(u)))
+  char *cmd = strtok(NULL, " ");
+  aClient *user;
+  Player *p;
+  
+  if (!(user = find(u)))
     {
-       notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
-       return;
+      notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
+      return;
     }
-    else if (isIgnore(user))
+  else if (isIgnore(user))
     {
-       #ifdef DEBUGMODE
-           log("Ignoring %s.", user->getNick());
-       #endif
-       return;
+#ifdef DEBUGMODE
+      log("Ignoring %s.", user->getNick());
+#endif
+      return;
     }
-    else if (!is_playing(user))
+  else if (!is_playing(user))
     {
-       notice(s_GameServ, u, "You must be playing to go to the Tavern");
-       return;
+      notice(s_GameServ, u, "You must be playing to go to the Tavern");
+      return;
     }
-    else if (is_fighting(user))
+  else if (is_fighting(user))
     {
-       notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
-       return;
+      notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
+      return;
     }
-
-    updateTS(user->stats);
-    p = user->stats;
-
-    if (!cmd)
+  
+  updateTS(user->stats);
+  p = user->stats;
+  
+  if (!cmd)
     {
-       notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
-       notice(s_GameServ, u, "Your commands:");
-       notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
-       notice(s_GameServ, u, "What'll it be?");
+      notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary and General Store");
+      notice(s_GameServ, u, "Your commands:");
+      notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
+      notice(s_GameServ, u, "What'll it be?");
     }
-    else if (stricmp(cmd, "LIST") == 0)
+  else if (stricmp(cmd, "LIST") == 0)
     {
-       notice(s_GameServ, u, "Here is a list of what we have to offer:");
-       notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 100 * p->level + (p->exp / 10));
-       notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 205 * p->level + (p->exp / 10));
-       notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 200 * p->level + (p->exp / 10));
-       notice(s_GameServ, u, "4. HP Potions for %ld Gold", 230 * p->level + (p->exp / 10));
-       notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
-       notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
-       notice(s_GameServ, u, "By something will ya!");
+      notice(s_GameServ, u, "Here is a list of what we have to offer:");
+      showTavern(user);
+      notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
+      notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
     }
-    else if (stricmp(cmd, "BUY") == 0)
+  /*  else if (stricmp(cmd, "BUY") == 0)
     {
-       char *chnum = strtok(NULL, " ");
-       int num = stringtoint(chnum);
-
-       if (!chnum)
+      char *chnum = strtok(NULL, " ");
+      
+      if (!chnum)
        {
-           notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
-           notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
-           return;
+         notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
+         notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
+         return;
        }
-       if (num < 1 || num > 4)
+      int num = stringtoint(chnum);
+      
+      if (num < 1 || num > 4)
        {
-           notice(s_GameServ, u, "Invalid Choice!");
-           notice(s_GameServ, u, "Here is a list of what we have to offer:");
-           notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 100 * p->level + (p->exp / 10));
-           notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 205 * p->level + (p->exp / 10));
-           notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 200 * p->level + (p->exp / 10));
-           notice(s_GameServ, u, "4. HP Potions for %ld Gold", 230 * p->level + (p->exp / 10));
-           notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
-           notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
-           return;
+         notice(s_GameServ, u, "Invalid Choice!");
+         notice(s_GameServ, u, "Here is a list of what we have to offer:");
+         notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 
+                1000 * p->level * 4);
+         notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 
+                2500 * p->level * 4);
+         notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 
+                3000 * p->level * 4);
+         notice(s_GameServ, u, "4. HP Potions for %ld Gold", 
+                2000 * p->level * 4);
+         notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
+         notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
+         return;
        }
-       switch(num)
+      switch(num)
        {
-           case 1:
-               price = (100 * p->level) + (p->exp / 10);
-               if (p->gold >= price)
-               {
-                   notice(s_GameServ, u, "One healing potion coming right up!");
-                   p->inventory.incHealing();
-                   p->gold -= price;
-               
-               else
-                   notice(s_GameServ, u, "You don't have enough gold!");
-               break;
-           case 2:
-               price = (205 * p->level) + (p->exp / 10);
-               if (p->gold >= price)
-               {
-                   notice(s_GameServ, u, "One strength boost coming right up!");
-                   p->inventory.incStrength();
-                   p->gold -= price;
-               }
-               else
-                   notice(s_GameServ, u, "You don't have enough gold!");
-               break;
-           case 3:
-               price = (200 * p->level) + (p->exp / 10);
-               if (p->gold >= price)
-               {
-                   notice(s_GameServ, u, "One defense boost coming right up!");
-                   p->inventory.incDefense();
-                   p->gold -= price;
-               }
-               else
-                   notice(s_GameServ, u, "You don't have enough gold!");
-               break;
-           case 4:
-               price = (230 * p->level) + (p->exp / 10);
-               if (p->gold >= price)
-               {
-                   notice(s_GameServ, u, "One HP Potion coming right up!");
-                   p->inventory.incHP();
-                   p->gold -= price;
-               }
-               else
-                   notice(s_GameServ, u, "You don't have enough gold!");
-               break;
-           default:
-               notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
-               break;
+       case 1:
+         price = (1000 * p->level * 4);
+         if (p->gold >= price)
+           {
+             notice(s_GameServ, u, "One healing potion coming right up!");
+             p->inventory.incHealing();
+             p->gold -= price;
+           } 
+         else
+           notice(s_GameServ, u, "You don't have enough gold!");
+         break;
+       case 2:
+         price = 2500 * p->level * 4;
+         if (p->gold >= price)
+           {
+             notice(s_GameServ, u, "One strength boost coming right up!");
+             p->inventory.incStrength();
+             p->gold -= price;
+           }
+         else
+           notice(s_GameServ, u, "You don't have enough gold!");
+         break;
+       case 3:
+         price = 3000 * p->level * 4;
+         if (p->gold >= price)
+           {
+             notice(s_GameServ, u, "One defense boost coming right up!");
+             p->inventory.incDefense();
+             p->gold -= price;
+           }
+         else
+           notice(s_GameServ, u, "You don't have enough gold!");
+         break;
+       case 4:
+         price = 3000 * p->level * 4;
+         if (p->gold >= price)
+           {
+             notice(s_GameServ, u, "One HP Potion coming right up!");
+             p->inventory.incHP();
+             p->gold -= price;
+           }
+         else
+           notice(s_GameServ, u, "You don't have enough gold!");
+         break;
+       default:
+         notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
+         break;
        }
     }
-    else
+  */
+  else
     {
-       notice(s_GameServ, u, "Improper Syntax.");
-       notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
+      notice(s_GameServ, u, "Improper Syntax.");
+      notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
     }
+  return;
 }
 
 void do_bank(char *u)
@@ -2533,7 +2842,11 @@ void do_bank(char *u)
        notice(s_GameServ, u, "You must be playing to use the bank!");
        return;
     }
-
+    else if (is_fighting(user))
+    {
+       notice(s_GameServ, u, "You can't go to the bank during a fight!");
+       return;
+    }
     updateTS(user->stats);
     if (stricmp(cmd, "BALANCE") == 0)
     {
@@ -2550,7 +2863,12 @@ void do_bank(char *u)
         notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
         return;
     }
-
+    if (stringtoint(amount) < 0)
+    {
+        notice(s_GameServ, u, "Sorry. This bank is not licensed "\
+       "to handle such sums of cash, noble Lord.");
+        return;
+    }
     p = user->stats;
 
     if (stricmp(cmd, "DEPOSIT") == 0)
@@ -2658,11 +2976,10 @@ void do_bank(char *u)
 
 }
 
-void do_master(char *u)
+void do_dragon(char *u)
 {
     aClient *user;
 
-
     if (!(user = find(u)))
     {
        notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
@@ -2675,9 +2992,14 @@ void do_master(char *u)
        #endif
        return;
     }
+    else if (!is_playing(user))
+    {
+       notice(s_GameServ, u, "You must be playing to fight the dragon!");
+       return;
+    }
     else if (is_fighting(user))
     {
-       notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
+       notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
        return;
     }
     else if (!isAlive(user->stats))
@@ -2685,13 +3007,76 @@ void do_master(char *u)
        notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
        return;
     }
+    else if (user->stats->level < LEVELS)
+    {
+       notice(s_GameServ, u, "You fool! Only those strong enough "\
+               "to vanquish any foe should DARE fight the dragon!");
+       notice(s_GameServ, u, "To put it in terms you can understand: "\
+               "You are too weak. You must be Level %d!", REALLEVELS);
+       return;
+    }
+
+    updateTS(user->stats);
+
+    Player *p = user->stats;
+    setMaster(p);
+    notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
+    notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
+       "deep, red fog rolls in. The air is filled with the "\
+       "heated mist of deadly fire from beyond the cave "\
+       "entrance.");
+    notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
+       "your %s, and venture into the hot, dark cave. "\
+       "You are surprised at the angle of descent as you climb "\
+       "lower and lower, deeper into the dragon's den.", 
+       armors[p->arm], weapons[p->wea]);
+    notice(s_GameServ, u, "You come to the end of the cave to find "\
+       "a tooth. It is a large tooth... bigger than your torso."\
+       " Suddenly the darkness lifts from the gleam of an eye "\
+       " staring into your soul! The eye is large... HUGE!");
+    notice(s_GameServ, u, "Just then you notice the eye begin to "\
+       "glare orange! The tooth is moving... but it is still too "\
+       "dark for you to make out.... THE DRAGON! You see it!");
+    p->fight = new Monster(dragon);
+    setDragonFight(p);
+    display_monster(u);
+}
+
+void do_master(char *u)
+{
+    aClient *user;
+
+
+    if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
+       return;
+    }
+    else if (isIgnore(user))
+    {
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", user->getNick());
+       #endif
+       return;
+    }
     else if (!is_playing(user))
     {
        notice(s_GameServ, u, "You must be playing to see your master!");
        return;
     }
+    else if (is_fighting(user))
+    {
+       notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
+       return;
+    }
+    else if (!isAlive(user->stats))
+    {
+       notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
+       return;
+    }
 
     updateTS(user->stats);
+
     char *cmd = strtok(NULL, " ");
     Player *p = user->stats;
     long int need = 0;
@@ -2707,41 +3092,43 @@ void do_master(char *u)
        switch(p->level)
        {
            case 1:
-               need = 100;
+               need = 200;
                break;
            case 2:
-               need = 400;
+               need = 800;
                break;
            case 3:
-               need = 1000;
+               need = 2000;
                break;
            case 4:
-               need = 4000;
+               need = 8000;
                break;
            case 5:
-               need = 10000;
+               need = 20000;
                break;
            case 6:
-               need = 40000;
+               need = 80000;
                break;
            case 7:
-               need = 100000;
+               need = 200000;
                break;
            case 8:
-               need = 400000;
+               need = 800000;
                break;
            case 9:
-               need = 1000000;
+               need = 2000000;
                break;
            case 10:
-               need = 4000000;
+               need = 8000000;
                break;
            case 11:
-               need = 10000000;
+               need = 20000000;
                break;
-           case 12:
+
+           case REALLEVELS:
                need = p->exp + 1;
-               notice(s_GameServ, u, "You are at level 12. You are the master. What's left? The DRAGON!");
+               notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
+               return;
                break;
            default:
                need = p->exp + 1; // Unknown level... don't let them fight a fake master!
@@ -2762,15 +3149,18 @@ void do_master(char *u)
            see_master(u);
        }
        else
-           notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
+           notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", 
+               levels[p->level - 1].master.name.c_str(), (need - p->exp));
        return;
     }
     else if (stricmp(cmd, "QUESTION") == 0)
     {
        if (p->exp >= need)
-           notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.", masters[p->level - 1]->name);
+           notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.", 
+               levels[p->level - 1].master.name.c_str());
        else
-           notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
+           notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", 
+               levels[p->level - 1].master.name.c_str(), p->name.c_str());
 
        return;
     }
@@ -2793,12 +3183,43 @@ void see_master(char *u)
     if (!is_fighting(user) && is_playing(user))
     {
        Player *p = user->stats;
-       p->master = new Monster(masters[p->level - 1]);
+       p->master = new Monster(&levels[p->level - 1].master);
        p->fight = p->master;
        display_monster(u);  // Since master is the same structure, use this function
     }
 }
 
+void showTavern(aClient *user)
+{
+  Player *p;
+  list<tavernItem>::iterator item_iterator;
+  item *tempItem;
+
+  p = user->stats;
+
+  if (!p)
+    return;
+
+  item_iterator = tavern.begin();
+  if (tavern.empty())
+    {
+      notice(s_GameServ, user->getNick(), "Tavern is empty");
+      return;
+    }
+
+  while (item_iterator != tavern.end())
+    {
+      if (p->level < (*item_iterator).getLevel())
+       {
+         item_iterator++;
+         continue;
+       }
+      tempItem = (*item_iterator).getItem();
+      notice(s_GameServ, user->getNick(), "%d. %s for %ld gold", tempItem->getID(), tempItem->getName().c_str(), tempItem->price());
+      item_iterator++;
+    }
+}
+
 void showBankBalance(const char *u)
 {
     aClient *user;
@@ -2927,10 +3348,16 @@ void resetall()
 
 void reset(Player *p)
 {
+    string *myname;
+
     if (!p)
        return;
 
+    myname = new string(p->name);
+
     p->reset();
+    p->name = *myname;
+    delete myname;
 }
 
 void updateTS(Player *p)
@@ -2939,11 +3366,11 @@ void updateTS(Player *p)
        return;
 
     #ifdef DEBUGMODE
-        log("Old timestamp for %s: %ld", p->name, p->lastcommand);
+        log("Old timestamp for %s: %ld", p->name.c_str(), p->lastcommand);
     #endif
     p->lastcommand = time(NULL);
     #ifdef DEBUGMODE
-        log("New timestamp for %s: %ld", p->name, p->lastcommand);
+        log("New timestamp for %s: %ld", p->name.c_str(), p->lastcommand);
     #endif
 
 }
@@ -2965,7 +3392,7 @@ bool timedOut(Player *p)
 
 void timeOutEvent(Player *p)
 {
-    aClient *user = findplayer(p->name);
+    aClient *user = findplayer(p->name.c_str());
 
     if (!user || !p->client) // then they're not playing
        return;
@@ -2983,7 +3410,7 @@ void timeOutEvent(Player *p)
            notice(s_GameServ, nick, "You timed out "\
                "during a fight. You lose your turn!");
            notice(s_GameServ, p->battle->getNick(),
-                  "%s hesitated for too long. Your move.", p->name);
+                  "%s hesitated for too long. Your move.", p->name.c_str());
            clearYourTurn(p);
            setYourTurn(p->battle->stats);
 
@@ -3000,11 +3427,11 @@ void timeOutEvent(Player *p)
            notice(s_GameServ, p->battle->getNick(),
                "You and %s timed out at the same time."\
                " Don't fight if you're just going to "\
-               "sit there!", p->name);
+               "sit there!", p->name.c_str());
            notice(s_GameServ, user->getNick(),
                "You and %s timed out at the same time."\
                " Don't fight if you're just going to "\
-               "sit there!", p->battle->stats->name);
+               "sit there!", p->battle->stats->name.c_str());
            logout(p->battle);
            logout(user);
            return;
@@ -3012,7 +3439,7 @@ void timeOutEvent(Player *p)
     }
     else if (!player_fight(user))
     {
-      if (isAlive(user) && user->stats->gold > 0)
+      if (isAlive(user->stats) && user->stats->gold > 0)
       {
        // Place fun stuff here :)
        int randnum = 1 + rand() % 100; // 1-100
@@ -3086,7 +3513,7 @@ void do_reset(char *u)
        notice(s_GameServ, u, "Resetting everyone's stats!");
        resetall();
     }
-    else if ((user = findbyrealnick(nick)))
+    else if ((user = findplayer(nick)))
     {
        if (is_playing(user))
        {
@@ -3099,11 +3526,8 @@ void do_reset(char *u)
        }
        else
        {
-           #ifdef P10
-           notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
-           #else
-           notice(s_GameServ, u, "%s is not playing.", user->getNick());
-           #endif
+           notice(s_GameServ, u, "Resetting %s", user->stats->name.c_str());
+           reset(user->stats);
        }
     }
     else
@@ -3216,78 +3640,80 @@ void do_admin(char *u)
     }
 }
 
+bool load_levels()
+{
+    char *filename;
+    filename = new char[256];
+
+    for (int x = 1; x <= LEVELS; x++)
+    {
+       sprintf(filename, "data/levels/level%d.dat", x);
+       if (levels[x - 1].loadLevel(filename) == false)
+           return false;
+    }
+
+    delete []filename;
+    return true;
+}
 bool load_monsters()
 {
+    char *filename;
     ifstream infile;
-    infile.open("monsters.dat");
-
     char *buf;
+    buf = new char[2048];
 
-    if (infile.fail())
+  for (int level = 1; level <= LEVELS; level++)
+  {
+    filename = new char[256];
+    sprintf(filename, "data/monsters/level%d.dat", level);
+    infile.open(filename);
+
+    if (!infile)
     {
-       log("Error opening monsters.dat");
+       log("Error opening %s", filename);
        return false;
     }
-    init_monsters();
-    buf = new char[2048];
 
     #ifdef DEBUGMODE
-       log("Loading monsters from monsters.dat");
+       log("Loading monsters from %s", filename);
     #endif
 
-  for (int l = 0; l < REALLEVELS; l++)
-  {
-    for (int m = 0; m < MONSTERS;)
+    while (infile.getline(buf, 2048))
     {
-       infile.getline(buf, 2048);
+       if (buf[0] == '^')
+           break;
        if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
            continue;
-       else
-       {
-           strcpy(monsters[l][m]->name, strtok(buf, "~"));
-           strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
-           monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->hp = monsters[l][m]->maxhp;
-           strcpy(monsters[l][m]->death, strtok(NULL, ""));
-           m++;
-       }
+       Monster *temp;
+       temp = new Monster;
+
+           temp->name = strtok(buf, "~");
+           temp->weapon = strtok(NULL, "~");
+            temp->death = strtok(NULL, "~");
+
+       levels[level - 1].monsters.insertAtBack_RLN(temp);
+       delete temp;
     }
+    delete [] filename;
+    infile.close();
   }
     delete [] buf;
 return true;
 }
 
-// this will be hash.cpp start
-// thank you wcampbel
-unsigned long sHASH(const unsigned char *name)
+item *findItemByID(int id)
 {
-  unsigned long h = 0, g;
-
-  while (*name)
-  {
-    h = (h << 4) + (*name++); // Case sensitive for numerics
-    if ((g = (h & 0xF0000000)))
-      h ^= g >> 24;
-    h &= ~g;
-  }
-  return h % U_TABLE_SIZE;
-}
+  list<item*>::iterator item_iterator;
 
-unsigned long iHASH(const unsigned char *name)
-{
-  unsigned long h = 0, g;
+  item_iterator = Items.begin();
 
-  while (*name)
-  {
-    h = (h << 4) + tolower(*name++);
-    if ((g = (h & 0xF0000000)))
-      h ^= g >> 24;
-    h &= ~g;
-  }
-  return h % U_TABLE_SIZE;
+  while (item_iterator != Items.end())
+    {
+      if ((*item_iterator)->getID() == id)
+       {
+         return (*item_iterator);
+       }
+      item_iterator++;
+    }
+  return NULL;
 }
-
-// this will be hash.cpp end