]> jfr.im git - irc/gameservirc.git/blobdiff - gameserv/gameserv.cpp
just syncing the cvs
[irc/gameservirc.git] / gameserv / gameserv.cpp
index 7a6414a86a5133b8c4499361e18436c9b45cfe19..2087c33a7acbf6cedf15a4a0d5859ccbebd4da53 100644 (file)
@@ -3,6 +3,7 @@
 #include "extern.h"
 #include "flags.h"
 #include "list.h"
+#include "level.h"
 #include "sockhelp.h"
 
 #include <cctype>
@@ -23,10 +24,7 @@ using std::ios;
 #endif
 
 
-Monster *monsters[LEVELS][MONSTERS];   // Monsters per level. Total = MONSTERS * LEVELS
-Monster boss;                          // The boss monster
-
-Monster *masters[LEVELS];              // A master for each level
+Level levels[LEVELS];                  // The newest way to store monsters
 
 // Database functions
 int save_gs_dbase();
@@ -43,7 +41,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.
  
@@ -54,7 +52,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.
@@ -69,6 +67,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);
@@ -85,15 +86,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);
@@ -109,6 +110,7 @@ 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);
@@ -158,20 +160,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;
@@ -191,6 +179,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) {
@@ -220,14 +210,15 @@ void gameserv(char *source, char *buf)
     } else if (stricmp(cmd, "LOGOUT") == 0) {
        do_logout(source);
     } else if (stricmp(cmd, "NEWS") == 0) {
-       addNews(todaysnews, "This is a test");
-       showNews(source, todaysnews);
+       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) {
@@ -290,7 +281,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
@@ -314,6 +305,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;
@@ -368,7 +367,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), " ");
@@ -417,7 +416,7 @@ void showstats(const char *u, const char *nick)
     }
     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;
 }
@@ -586,6 +585,20 @@ 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;
@@ -614,7 +627,7 @@ void do_list(char *u)
     {
        while(temp)
        {
-           if (!cmd || is_playing(temp->getData()))
+           if (cmd || is_playing(temp->getData()))
            {
                if (!header)
                {
@@ -623,10 +636,10 @@ void do_list(char *u)
                }
                #ifdef P10
                notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getRealNick(), 
-                       temp->getData()->stats->name);
+                       temp->getData()->stats->name.c_str());
                #else
                notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getNick(), 
-                       temp->getData()->stats->name);
+                       temp->getData()->stats->name.c_str());
                #endif
            }
 
@@ -640,6 +653,128 @@ 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|WEAPON|ARMOR|HP POTIONS|STRENGTH POTIONS|DEFENSE POTIONS|HEALING POTIONS|ALIVE|SEEN MASTER} {STRING|NUMBER|ON|OFF}");
+      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
+       }
+      else
+       {
+         target->stats->bank = stringtoint(cmd2);
+         notice(s_GameServ, u, "Balance changed!");
+       }
+    }
+  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, " ");
+         target->stats->player_fights = stringtoint(cmd2);
+         notice(s_GameServ, u, "Player fights changed!");
+       }         
+    }
+  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, " ");
+         target->stats->player_fights = stringtoint(cmd2);
+         notice(s_GameServ, u, "Player fights changed!");
+       }         
+    }
+  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|WEAPON|ARMOR|HP POTIONS|STRENGTH POTIONS|DEFENSE POTIONS|HEALING POTIONS|ALIVE|SEEN MASTER} {STRING|NUMBER|ON|OFF}");
+      return;
+    }
+}
 
 void do_logout(char *u)
 {
@@ -674,7 +809,7 @@ void do_logout(char *u)
        }
        else
        {
-           notice(s_GameServ, u, "Logging out %s", user->stats->name);
+           notice(s_GameServ, u, "Logging out %s", user->stats->name.c_str());
            logout(user);
        }
     }
@@ -702,7 +837,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)
@@ -756,13 +891,6 @@ 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");
@@ -795,16 +923,19 @@ void do_register(char *u)
            user->stats = new Player(user);
            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
@@ -852,7 +983,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)
        {
@@ -870,13 +1001,17 @@ 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);
+
+       // Update the last login time
+       user->stats->lastlogin = time(NULL);
+
        notice(s_GameServ, u, "Password Accepted. Identified.");
        showNews(u, todaysnews);
     }
@@ -911,157 +1046,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("data/masters.dat");
+    char *buf;
+    int l = 0;
+    buf = new char[1024];
 
-    delete_masters();
+    if (infile.fail())
+    {
+       log("Error opening data/masters.dat");
+       return false;
+    }
 
     #ifdef DEBUGMODE
-       log("Initializing masters");
+       log("Loading masters from data/masters.dat");
     #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 = 32;
-    masters[0]->gold = 0;
-    masters[0]->exp = 0;
-    masters[0]->maxhp = 35;
-    masters[0]->hp = 35;
-    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 = 48;
-    masters[1]->gold = 0;
-    masters[1]->exp = 0;
-    masters[1]->maxhp = 51;
-    masters[1]->hp = 51;
-    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 = 88;
-    masters[2]->gold = 0;
-    masters[2]->exp = 0;
-    masters[2]->maxhp = 100;
-    masters[2]->hp = 100;
-    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 = 169;
-    masters[3]->gold = 0;
-    masters[3]->exp = 0;
-    masters[3]->maxhp = 165;
-    masters[3]->hp = 165;
-    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 = 275;
-    masters[4]->gold = 0;
-    masters[4]->exp = 0;
-    masters[4]->maxhp = 232;
-    masters[4]->hp = 232;
-    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 = 347;
-    masters[5]->gold = 0;
-    masters[5]->exp = 0;
-    masters[5]->maxhp = 504;
-    masters[5]->hp = 504;
-    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 = 515;
-    masters[6]->gold = 0;
-    masters[6]->exp = 0;
-    masters[6]->maxhp = 1078;
-    masters[6]->hp = 1078;
-    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 = 655;
-    masters[7]->gold = 0;
-    masters[7]->exp = 0;
-    masters[7]->maxhp = 2207;
-    masters[7]->hp = 2207;
-    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 = 819;
-    masters[8]->gold = 0;
-    masters[8]->exp = 0;
-    masters[8]->maxhp = 2780;
-    masters[8]->hp = 2780;
-    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 = 1014;
-    masters[9]->gold = 0;
-    masters[9]->exp = 0;
-    masters[9]->maxhp = 3046;
-    masters[9]->hp = 3046;
-    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 = 1286;
-    masters[10]->gold = 0;
-    masters[10]->exp = 0;
-    masters[10]->maxhp = 3988;
-    masters[10]->hp = 3988;
-    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; 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)  // 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)
@@ -1072,7 +1128,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");
@@ -1098,7 +1154,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");
@@ -1191,6 +1247,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 (user->stats->level == LEVELS && master_fight(user));
+}
 void do_fight(char *u)
 {
     aClient *ni, *battle;
@@ -1251,11 +1323,11 @@ void do_fight(char *u)
 
         notice(s_GameServ, u, "You decide to fight %s while they're "\
                              "not in the realm!",
-                 battle->stats->name);
+                 battle->stats->name.c_str());
         display_players(u);
     }
 */
-    else if (stricmp(ni->stats->name, battle->stats->name) == 0)
+    else if (stricmp(ni->stats->name.c_str(), battle->stats->name.c_str()) == 0)
     {
        notice(s_GameServ, u, "Are you trying to commit suicide!?");
     }
@@ -1265,29 +1337,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
     {
@@ -1304,11 +1376,11 @@ 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);
     }
 }
@@ -1356,9 +1428,20 @@ void do_use(char *u)
            return;
        }
        int oldhealing = user->stats->hp;
+       user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
+       if (user->stats->hp - user->stats->maxhp >= 100)
+       {
+           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.");
-       user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
        notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealing);
        p->decHealing();
        if (player_fight(user))
@@ -1466,23 +1549,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;
 }
@@ -1525,16 +1608,16 @@ 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;
@@ -1547,7 +1630,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;
@@ -1640,36 +1723,45 @@ void do_attack(char *u)
   if (!player_fight(ni))
   {
     if (hit > 0)
-        notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
+        notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name.c_str(), hit);
     else
-        notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
+        notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name.c_str());
 
     if (hit >= fight->hp)
     {
-        if (master_fight(ni))
+        if (master_fight(ni) && !dragon_fight(ni))
        {
-            notice(s_GameServ, u, "You have bested %s!", fight->name);
+            notice(s_GameServ, u, "You have bested %s!", fight->name.c_str());
            addNews(todaysnews, "%s has bested %s and moved "\
-                   "to level %d", ni->stats->name, fight->name,
+                   "to level %d", ni->stats->name.c_str(), fight->name.c_str(),
                    (ni->stats->level + 1));
        }
         else
-            notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
+            notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name.c_str());
 
-        notice(s_GameServ, u, "%s", fight->death);
+        notice(s_GameServ, u, "%s", fight->death.c_str());
         notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
                  fight->exp, fight->gold);
 
+       if (dragon_fight(ni))
+       {
+           addNews(todaysnews, "%s is a true warrior! %s has beaten %s!!", 
+               ni->stats->name.c_str(), ni->stats->name.c_str(), 
+               ni->stats->master->name.c_str());
+           ni->stats->master = NULL; // Don't progress in levels
+       }
+
        // 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);
+       ni->stats->exp += fight->exp;
+       if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
+           ni->stats->exp = 2000000000;
 
+       ni->stats->gold += fight->gold;
+       if (ni->stats->gold < 0 || ni->stats->gold > 2000000000)
+           ni->stats->gold = 2000000000;
 
         if (master_fight(ni))
         {
@@ -1711,20 +1803,20 @@ void do_attack(char *u)
         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 >= 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 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!");
                addNews(todaysnews, "%s has been killed by %s!",
-                       ni->stats->name, fight->name);
+                       ni->stats->name.c_str(), fight->name.c_str());
                 ni->stats->gold = 0;
                 ni->stats->exp -= (long int)(ni->stats->exp * .10);
                ni->stats->hp = 0;
@@ -1735,9 +1827,9 @@ void do_attack(char *u)
             else
             {
                 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
-                        "until tomorrow to try again", ni->stats->master->name);
+                        "until tomorrow to try again", ni->stats->master->name.c_str());
                addNews(todaysnews, "%s tried to best %s and failed!",
-                       ni->stats->name, fight->name);
+                       ni->stats->name.c_str(), fight->name.c_str());
                 ni->stats->fight = NULL;
                 ni->stats->master = NULL;
                return;
@@ -1843,43 +1935,38 @@ void do_attack(char *u)
     if (!isYourTurn(ni->stats))
     {
         notice(s_GameServ, u, "Please wait until %s decides what to do!", 
-               battle->stats->name);
+               battle->stats->name.c_str());
         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, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name.c_str(), hit);
 
         notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
-                                             "\ 2%d\ 2 damage!", ni->stats->name, 
+                                             "\ 2%d\ 2 damage!", ni->stats->name.c_str()
                                              weapons[ni->stats->weapon], hit);
     }
     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);
+        notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name.c_str());
+        notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name.c_str());
     }
 
     if (hit >= battle->stats->hp)
     {
-        notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
+        notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name.c_str());
         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);
+               ni->stats->name.c_str());
         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 += (long int)(battle->stats->exp * .10);
+        battle->stats->exp -= (long int)(battle->stats->exp * .10);
+
+        if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
             ni->stats->exp = 2000000000;
-        }
 
         if (2000000000 - ni->stats->gold > battle->stats->gold)
         {
@@ -1894,13 +1981,14 @@ void do_attack(char *u)
             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);
+                       "gold.", ni->stats->name.c_str());
 
             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;
         }
+
        clearYourTurn(ni->stats);
        clearYourTurn(battle->stats);
        battle->stats->battle = NULL;
@@ -1915,7 +2003,7 @@ void do_attack(char *u)
        setYourTurn(battle->stats);
         display_players(battle);
         notice(s_GameServ, u, "Please wait while %s decides what to do!", 
-               battle->stats->name);
+               battle->stats->name.c_str());
         return;
     }
    }
@@ -2087,12 +2175,13 @@ 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->forest_fights << ' ' << it->player_fights <<  ' ' 
                << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
-               << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
+               << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP()
+               << ' ' << it->lastlogin << endl;
        ptr = ptr->Next();
     }
    }
@@ -2116,6 +2205,19 @@ int load_gs_dbase()
        return 0;
     }
 
+    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;
@@ -2138,7 +2240,7 @@ int load_gs_dbase()
        p->setFlags(stringtoint(strtok(NULL, " ")));
 
        password = strtok(NULL, " ");
-       strcpy(p->password, password);
+       p->password = password;
        temp->setNick("Not Playing");
        #ifdef P10
        temp->setRealNick("Not Playing");
@@ -2163,7 +2265,14 @@ int load_gs_dbase()
        tempname = strtok(NULL, " ");
        if (tempname)
            p->inventory.setHP(stringtoint(tempname));
-       unsigned long hv = iHASH((unsigned char *) temp->stats->name);
+
+        tempname = strtok(NULL, " ");
+       if (tempname)
+           p->lastlogin = stringtoint(tempname);
+       else
+           p->lastlogin = time(NULL);
+
+       unsigned long hv = iHASH((unsigned char *) temp->stats->name.c_str());
 
        temp->stats->client = NULL;
        players[hv].insertAtBack(temp);
@@ -2174,7 +2283,7 @@ infile.close();
 return 1;
 }
 
-bool passcmp(char *encrypted, char *plaintext)
+bool passcmp(const char *encrypted, char *plaintext)
 {
     char salt[3];
     char *plaintext2, *plainToencrypt;
@@ -2204,7 +2313,7 @@ bool check_password(char *name, char *plaintext)
        return false;
     else
     {
-       return passcmp(client->stats->password, plaintext);
+       return passcmp(client->stats->password.c_str(), plaintext);
     }
 }
 
@@ -2335,6 +2444,11 @@ void do_store(char *u)
                 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)
     {
@@ -2444,7 +2558,7 @@ void showinventory(aClient *from, aClient *to)
     if (is_playing(from))
     {
        Pouch *p = &from->stats->inventory;
-       notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
+       notice(s_GameServ, nick, "Inventory for %s:", from->stats->name.c_str());
        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());
@@ -2509,7 +2623,6 @@ void do_tavern(char *u)
     else if (stricmp(cmd, "BUY") == 0)
     {
        char *chnum = strtok(NULL, " ");
-       int num = stringtoint(chnum);
 
        if (!chnum)
        {
@@ -2517,6 +2630,8 @@ void do_tavern(char *u)
            notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
            return;
        }
+       int num = stringtoint(chnum);
+
        if (num < 1 || num > 4)
        {
            notice(s_GameServ, u, "Invalid Choice!");
@@ -2646,7 +2761,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)
@@ -2785,7 +2905,7 @@ void do_dragon(char *u)
        notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
        return;
     }
-    else if (user->stats->level < REALLEVELS)
+    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!");
@@ -2797,7 +2917,8 @@ void do_dragon(char *u)
     updateTS(user->stats);
 
     Player *p = user->stats;
-    p->fight = new Monster(boss);
+    setMaster(p);
+    see_master(u);
     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 "\
@@ -2806,7 +2927,8 @@ void do_dragon(char *u)
     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.");
+       "lower and lower, deeper into the dragon's den.", 
+       armors[p->armor], weapons[p->weapon]);
     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 "\
@@ -2924,15 +3046,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;
     }
@@ -2955,7 +3080,7 @@ 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
     }
@@ -3089,10 +3214,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)
@@ -3101,11 +3232,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
 
 }
@@ -3127,7 +3258,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;
@@ -3145,7 +3276,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);
 
@@ -3162,11 +3293,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;
@@ -3248,7 +3379,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))
        {
@@ -3261,11 +3392,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
@@ -3378,45 +3506,62 @@ 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;