]> jfr.im git - irc/gameservirc.git/blobdiff - gameserv/gameserv.cpp
Fixed a bug adding wrong bonuses for level gains
[irc/gameservirc.git] / gameserv / gameserv.cpp
index 546692be60115f5b1fe16d6b90fad43d73f310a7..536afafee64c7cddede659127f2a4457dac83247 100644 (file)
@@ -1,27 +1,46 @@
-#include "sockhelp.h"
 #include "aClient.h"
 #include "aClient.h"
-#include "list.h"
+#include "config.h"
 #include "extern.h"
 #include "extern.h"
+#include "flags.h"
+#include "list.h"
+#include "sockhelp.h"
+
 #include <cctype>
 #include <cctype>
-#include <fstream.h>
+#include <fstream>
+
+using std::ifstream;
+using std::ofstream;
+using std::ios;
+
+#if defined(HAVE_CRYPT_H)
+
 #include <crypt.h>
 
 #include <crypt.h>
 
-List<aClient> players;
-Monster monsters[5][12];
-Monster masters[12];
+#elif defined(HAVE_UNISTD_H)
+
+#include <unistd.h> 
+
+#endif
+
+
+Monster *monsters[LEVELS][MONSTERS];   // Monsters per level. Total = MONSTERS * LEVELS
+Monster boss;                          // The boss monster
+
+Monster *masters[LEVELS];              // A master for each level
 
 // Database functions
 int save_gs_dbase();
 int load_gs_dbase();
 
 // String functions
 
 // Database functions
 int save_gs_dbase();
 int load_gs_dbase();
 
 // String functions
-#undef strtok
+#ifndef HAVE_STRTOK
 char *strtok(char *str, const char *delim);
 char *strtok(char *str, const char *delim);
+#endif
+
 int stricmp(const char *s1, const char *s2);
 int strnicmp(const char *s1, const char *s2, size_t len);
 // String Functions
 
 int stricmp(const char *s1, const char *s2);
 int strnicmp(const char *s1, const char *s2, size_t len);
 // String Functions
 
-
 /********** Password functions **********/
 
 bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
 /********** Password functions **********/
 
 bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
@@ -33,47 +52,74 @@ bool check_password(char *name, char *plaintext); // Finds a password for the gi
 
 /********** GameServ Booleans **********/
 
 
 /********** GameServ Booleans **********/
 
+bool shuttingdown;
+bool timedOut(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.
 bool is_playing(char *u); // True if the given nickname in the clients list is playing.
-bool has_started(char *u); // True if the given nickname in the clients list has started playing.
+bool is_playing(aClient *user);
+
 bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
 bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
-bool isnt_fighting(char *u); // True if the given nick isn't fighting. Same as !is_fighting(u).
+bool is_fighting(aClient *user);
+
 bool player_fight(char *u); // True if the player is fighting another player.
 bool player_fight(char *u); // True if the player is fighting another player.
+bool player_fight(aClient *user);
+
 bool master_fight(char *u); // True if the player is fighting their master.
 bool master_fight(char *u); // True if the player is fighting their master.
+bool master_fight(aClient *user);
 
 /********** GameServ Booleans **********/
 
 
 /********** GameServ Booleans **********/
 
-
+void display_help(char *u, char *file = NULL);
 void display_monster(char *u);
 void display_players(char *u);
 void display_monster(char *u);
 void display_players(char *u);
+void display_players(aClient *user);
 long int chartoint(char ch);
 int isstringnum(char *num);
 long int pow (int x, int y);
 long int stringtoint(char *number);
 
 char *spaces(int len, char *seperator);
 long int chartoint(char ch);
 int isstringnum(char *num);
 long int pow (int x, int y);
 long int stringtoint(char *number);
 
 char *spaces(int len, char *seperator);
-void init_masters();
-void refresh(aClient *ni);
+void refresh(Player *p);
 void refreshall();
 void refreshall();
-void reset(aClient *ni);
+void updateTS(Player *p);
+void reset(Player *p);
+void init_masters();
 void init_monsters();
 void init_monsters();
+bool load_monsters();
+void delete_monsters();
+void delete_masters();
 
 
-void do_list(char *u);
-void do_register(char *u);
+void do_admin(char *u);
+void do_attack(char *u);
+void do_bank(char *u);
+void do_fight(char *u);
+void do_heal(char *u);
+void do_help(char *u);
 void do_identify(char *u);
 void do_identify(char *u);
+void do_inventory(char *u);
+void do_refresh(char *u);
+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_play(char *u);
 void do_quitg(char *u);
 void do_reset(char *u);
-void do_fight(char *u);
-void do_store(char *u);
-void do_heal(char *u);
-void do_bank(char *u);
-void do_attack(char *u);
 void do_run(char *u);
 void do_run(char *u);
-void do_visit(char *u);
 void do_stats(char *u);
 void do_stats(char *u);
-void see_mystic(char *u);
+void do_store(char *u);
+void do_tavern(char *u);
+void do_use(char *u);
+void see_master(char *u);
 
 
+void logout(aClient *user);
 void showstats(const char *u, const char *nick);
 void showstats(const char *u, const char *nick);
+void showinventory(aClient *from, aClient *to);
+void showBankBalance(const char *u);
+void end_turn(aClient *user);
 
 #define WNA 16
 char *weapons[WNA] = {  "Fists", "Stick", "Dagger", "Quarterstaff",  "Short Sword", 
 
 #define WNA 16
 char *weapons[WNA] = {  "Fists", "Stick", "Dagger", "Quarterstaff",  "Short Sword", 
@@ -81,37 +127,58 @@ char *weapons[WNA] = {  "Fists", "Stick", "Dagger", "Quarterstaff",  "Short Swor
                        "Chain Saw", "Poison Sword",  "Flame Sword", "Earth Hammer", 
                        "Light Saber", "Masamune", "Mystical Sword"};
 
                        "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", 
                      "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit", 
                      "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor", 
-                     "Hades' Cloak", "Dragon Scales", "Mystical 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 prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000, 
                        1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
-int webonus[WNA] = {0, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
-int arbonus[WNA] = {0, 1, 3, 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};
 int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
 
 
 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};
 int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
 
-
 void gameserv(char *source, char *buf)
 {
 void gameserv(char *source, char *buf)
 {
-    char *cmd, input[1024];
+    char *cmd, z;
     cmd = strtok(buf, " ");
 
     cmd = strtok(buf, " ");
 
-    source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
-    cmd++;    // Get rid of that : at the beginning of the :text  (command)
+    #ifndef P10
+        source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
+    #endif
+
+    z = cmd[0];
+    if (z == ':')
+        cmd++;    // Get rid of that : at the beginning of the :text  (command)
+
+    #ifdef DEBUGMODE
+       log("Source: %s  Command: %s", source, cmd);
+    #endif
+
+    struct tm *tm;
+    time_t ti;
+    time(&ti);
+    tm = localtime(&ti);
 
 
-    cout << "Source: " << source << "\ncmd: " << cmd << endl;
-    if (strnicmp(cmd, ":\1PING", 6) == 0)
+    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 *timestamp;
-       timestamp = strtok(NULL, "\1");
-        notice(s_GameServ, source, "\1PING %s\1", timestamp);
-    } else if (stricmp(cmd, ":\1VERSION\1") == 0) {
-       notice(s_GameServ, source, "\1VERSION GameServ v1.0b\1");
+       char *ts;
+       ts = strtok(NULL, "\1");
+        notice(s_GameServ, source, "\1PING %s\1", ts);
+    } else if (stricmp(cmd, "\1VERSION\1") == 0) {
+       notice(s_GameServ, source, "\1VERSION %s %s\1", PACKAGE, VERSION);
     } else if (stricmp(cmd, "SEARCH") == 0) {
        cmd = strtok(NULL, " ");
 
     } else if (stricmp(cmd, "SEARCH") == 0) {
        cmd = strtok(NULL, " ");
 
@@ -119,42 +186,154 @@ void gameserv(char *source, char *buf)
            notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
        else
            do_forest(source);
            notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
        else
            do_forest(source);
+
     } else if (stricmp(cmd, "FIGHT") == 0) {
        do_fight(source);
     } else if (stricmp(cmd, "ATTACK") == 0) {
        do_attack(source);
     } else if (stricmp(cmd, "FIGHT") == 0) {
        do_fight(source);
     } else if (stricmp(cmd, "ATTACK") == 0) {
        do_attack(source);
+    } else if (stricmp(cmd, "RUN") == 0) {
+       do_run(source);
+    } else if (stricmp(cmd, "USE") == 0) {
+       do_use(source);
     } else if (stricmp(cmd, "HEAL") == 0) {
        do_heal(source);
     } else if (stricmp(cmd, "HEAL") == 0) {
        do_heal(source);
+    } else if (stricmp(cmd, "INVENTORY") == 0) {
+       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, "STORE") == 0) {
        do_store(source);
-    } else if (stricmp(cmd, "PRINT") == 0) {
-       cout << "Printing Clients List: " << endl;
-       clients.print();
-       cout << "\nPrinting Player List: " << endl;
-       players.print();
+    } else if (stricmp(cmd, "BANK") == 0) {
+       do_bank(source);
+    } else if (stricmp(cmd, "ADMIN") == 0) {
+       do_admin(source);
+    } else if (stricmp(cmd, "REFRESH") == 0) {
+       do_refresh(source);
+    } else if (stricmp(cmd, "RESET") == 0) {
+       do_reset(source);
+    } else if (stricmp(cmd, "TAVERN") == 0) {
+       do_tavern(source);
     } else if (stricmp(cmd, "LIST") == 0) {
        do_list(source);
     } else if (stricmp(cmd, "LIST") == 0) {
        do_list(source);
+    } else if (stricmp(cmd, "LOGOUT") == 0) {
+       do_logout(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) {
     } 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, "STATS") == 0) {
        do_stats(source);
     } else if (stricmp(cmd, "SHUTDOWN") == 0) {
     } else if (stricmp(cmd, "STATS") == 0) {
        do_stats(source);
     } else if (stricmp(cmd, "SHUTDOWN") == 0) {
-       save_gs_dbase();
-       raw("SQUIT %s :leaving", servername);
+       aClient *user;
+
+       if (!(user = find(source)))
+       {
+           notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
+               log("Error: aClient not found: %s", source);
+       }
+       else if (!isAdmin(user))
+       {
+           notice(s_GameServ, source, "You must be a %S admin to use this command!");
+       }
+       else
+       {
+           save_gs_dbase();
+           #ifdef P10
+               raw("[] SQ %s 0 :leaving: %s used the Shutdown command.", servername, user->getRealNick());
+           #else
+               raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source);
+           #endif
+           shuttingdown = true;
+       }
     } else if (stricmp(cmd, "SAVE") == 0) {
     } else if (stricmp(cmd, "SAVE") == 0) {
-       save_gs_dbase();
+       aClient *user;
+
+       if (!(user = find(source)))
+       {
+           notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
+               log("Error: aClient not found: %s", source);
+       }
+       else if (!isAdmin(user))
+       {
+           notice(s_GameServ, source, "You must be a %S admin to use this command!");
+       }
+       else
+        {
+           save_gs_dbase();
+        }
     } else if (stricmp(cmd, "LOAD") == 0) {
     } else if (stricmp(cmd, "LOAD") == 0) {
-       load_gs_dbase();
+       aClient *user;
+
+       if (!(user = find(source)))
+       {
+           notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
+           log("Error: aClient not found: %s", source);
+       }
+       else if (!isAdmin(user))
+       {
+           notice(s_GameServ, source, "You must be a %S admin to use this command!");
+       }
+       else
+        {
+           char *cmd2 = strtok(NULL, " ");
+           if (!cmd2)
+           {
+               notice(s_GameServ, source, "Loading player data from %s", playerdata);
+               load_gs_dbase();
+           }
+           else if (stricmp(cmd2, "MONSTERS") == 0)
+           {
+               notice(s_GameServ, source, "Loading monster data from %s", monsterdata);
+               load_monsters();
+           }
+           else
+               display_help(source, cmd);
+       }
+    #ifdef DEBUGMODE
     } else if (stricmp(cmd, "RAW") == 0) {
     } else if (stricmp(cmd, "RAW") == 0) {
-       char *rest = strtok(NULL, "");
-       raw(rest);
-    }
+       aClient *user;
+
+       if (!(user = find(source)))
+       {
+           notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
+               log("Error: aClient not found: %s", source);
+       }
+       else if (!isAdmin(user))
+       {
+           notice(s_GameServ, source, "You must be a %S admin to use this command!");
+       }
+       else
+        {
+           char *rest = strtok(NULL, "");
+           raw("%s", rest);
+       }
+    #endif
+    } else {
+       aClient *user;
+       if ((user = find(source)))
+       {
+           if (isIgnore(user))
+           {
+               #ifdef DEBUGMODE
+                   log("Ignoring %s.", user->getNick());
+               #endif
+           }
+           else
+           {
+               notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd);
+           }
+       }
+    } 
 
 
-   source--;  // Bring the : back so we don't leak memory
-   cmd--;     // Same thing :)
+    #ifndef P10
+       source--;  // Bring the ':' back so we don't leak memory
+    #endif
+    if (z == ':')
+       cmd--;     // Same thing :)
 }
 
 int stricmp(const char *s1, const char *s2)
 }
 
 int stricmp(const char *s1, const char *s2)
@@ -180,14 +359,12 @@ void showstats(const char *u, const char *nick)
     char *space;
 
 
     char *space;
 
 
-    cout << "\n\nu: " << u << "\nnick: " << nick << endl;
-    if (!(ni = findbynick(nick)))
+    if (!(ni = findplayer(nick)))
     {
         notice(s_GameServ, u, "%s not found", nick);
     }
     else if (ni->stats)
     {
     {
         notice(s_GameServ, u, "%s not found", nick);
     }
     else if (ni->stats)
     {
-
         notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
 
         sprintf(buf, "Experience: %ld", ni->stats->exp);
         notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
 
         sprintf(buf, "Experience: %ld", ni->stats->exp);
@@ -201,7 +378,7 @@ void showstats(const char *u, const char *nick)
         notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
         delete [] space;
 
         notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
         delete [] space;
 
-        notice(s_GameServ, sender->getNick(), "Health Points: %d of %d", ni->stats->hp,
+        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]);
                  ni->stats->maxhp);
 
         sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
@@ -220,18 +397,35 @@ void showstats(const char *u, const char *nick)
         space = spaces(strlen(buf), " ");
         notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
         delete [] space;
         space = spaces(strlen(buf), " ");
         notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
         delete [] space;
+       Pouch *inv = &ni->stats->inventory;
+
+       notice(s_GameServ, u, "Potions");
+       sprintf(buf, "Healing: %d", inv->Healing());
+       space = spaces(strlen(buf), " ");
+       notice(s_GameServ, sender->getNick(), "%s%sHP: %d", buf, 
+               space, inv->HP());
+       delete [] space;
+
+       sprintf(buf, "Strength: %d", inv->Strength());
+       space = spaces(strlen(buf), " ");
+       notice(s_GameServ, sender->getNick(), "%s%sDefense: %d", buf, 
+               space, inv->Defense());
+       delete [] space;
+    }
+    else
+    {
+       notice(s_GameServ, u, "%s is not playing!", ni->stats->name);
     }
     delete [] buf;
     }
     delete [] buf;
-
 }
 
 char *spaces(int len, char *seperator)
 {
     char *final;
 }
 
 char *spaces(int len, char *seperator)
 {
     char *final;
-    final = new char[40];
+    final = new char[30];
     int y;
     strcpy(final, seperator);
     int y;
     strcpy(final, seperator);
-    for (y = 0; y < 40 - len; y++)
+    for (y = 0; y < 30 - len; y++)
         strcat(final, seperator);
     return final;
 }
         strcat(final, seperator);
     return final;
 }
@@ -263,8 +457,11 @@ void raw(const char *fmt, ...)
        }
 
     }
        }
 
     }
+    #ifdef DEBUGMODE
+       log("Input: %s", input);
+    #endif
+
     sprintf(input, "%s%s", input, "\r\n");
     sprintf(input, "%s%s", input, "\r\n");
-    cout << "input: " << input << flush;
     sock_puts(sock, input);
     delete [] input;
     va_end(args);
     sock_puts(sock, input);
     delete [] input;
     va_end(args);
@@ -273,6 +470,25 @@ void raw(const char *fmt, ...)
 
 void notice(const char *source, const char *dest, const char *fmt, ...)
 {
 
 void notice(const char *source, const char *dest, const char *fmt, ...)
 {
+    if (fmt[0] == '\0')
+       return;
+
+    char *commanduse;
+    commanduse = new char[16];
+
+    #ifdef P10
+       if (isUsePrivmsg())
+           strcpy(commanduse, "P");
+       else
+           strcpy(commanduse, "O");
+    #else
+
+       if (isUsePrivmsg())
+           strcpy(commanduse, "PRIVMSG");
+       else
+           strcpy(commanduse, "NOTICE");
+    #endif
+
     va_list args;
     char *input;
     const char *t = fmt;
     va_list args;
     char *input;
     const char *t = fmt;
@@ -281,11 +497,23 @@ void notice(const char *source, const char *dest, const char *fmt, ...)
     if (dest[0] == ':')
     {
        dest++;
     if (dest[0] == ':')
     {
        dest++;
-       sprintf(input, ":%s NOTICE %s :", source, dest);
+
+      #if !defined(P10)
+       sprintf(input, ":%s %s %s :", source, commanduse, dest);
+      #else
+       sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
+      #endif
+
        dest--;
     }
     else
        dest--;
     }
     else
-       sprintf(input, ":%s NOTICE %s :", source, dest);
+    {
+      #if !defined(P10)
+       sprintf(input, ":%s %s %s :", source, commanduse, dest);
+      #else
+       sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
+      #endif
+    }
 
     for (; *t; t++)
     {
 
     for (; *t; t++)
     {
@@ -306,9 +534,12 @@ void notice(const char *source, const char *dest, const char *fmt, ...)
        }
 
     }
        }
 
     }
+    #ifdef DEBUGMODE
+       log("Input: %s", input);
+    #endif
     sprintf(input, "%s%s", input, "\r\n");
     sprintf(input, "%s%s", input, "\r\n");
-    cout << "input: " << input << flush;
     sock_puts(sock, input);
     sock_puts(sock, input);
+    delete [] commanduse;
     delete [] input;
 va_end(args);
 }
     delete [] input;
 va_end(args);
 }
@@ -331,6 +562,7 @@ int strnicmp(const char *s1, const char *s2, size_t len)
     return 1;
 }
 
     return 1;
 }
 
+#ifndef HAVE_STRTOK
 char *strtok(char *str, const char *delim)
 {
     static char *current = NULL;
 char *strtok(char *str, const char *delim)
 {
     static char *current = NULL;
@@ -349,28 +581,176 @@ char *strtok(char *str, const char *delim)
         *current++ = 0;
     return ret;
 }
         *current++ = 0;
     return ret;
 }
+#endif
 
 void do_list(char *u)
 {
 
 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);
+       return;
+    }
+    else if (isIgnore(user))
+    {
+       #ifdef DEBUGMODE
+           log("Ignoring %s. Command LIST", user->getNick());
+       #endif
+       return;
+    }
+
     ListNode<aClient> *temp;
     ListNode<aClient> *temp;
-    temp = players.First();
-    if (!players.isEmpty())
+    bool header = false;
+
+  for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
+  {
+    temp = players[x].First();
+    if (!players[x].isEmpty())
     {
     {
-       notice(s_GameServ, u, "People Playing:");
        while(temp)
        {
        while(temp)
        {
-           notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getNick(), temp->getData()->stats->name);
+           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);
+               #else
+               notice(s_GameServ, u, "IRC: %s     Game: %s", temp->getData()->getNick(), 
+                       temp->getData()->stats->name);
+               #endif
+           }
+
            temp = temp->Next();
        }
            temp = temp->Next();
        }
-       notice(s_GameServ, u, "End of List");
     }
     }
-    else
+   }
+    if (!header)
        notice(s_GameServ, u, "No one is playing");
        notice(s_GameServ, u, "No one is playing");
+    else
+       notice(s_GameServ, u, "End of List");
+
+}
+
+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))
+    {
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", user->getNick());
+       #endif
+       return;
+    }
+
+    if (name)
+    {
+       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);
+           logout(user);
+       }
+    }
+    else if (!name)
+    {
+       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);
+       }
+    }
+}
+
+void logout(aClient *user)
+{
+    if (is_playing(user))
+    {
+       ListNode<aClient> *it;
+       aClient *temp;
+       unsigned long hv = iHASH((unsigned char *) user->stats->name);
+       it = players[hv].Find(user);
+
+        if (!it)
+        {
+            notice(s_GameServ, user->getNick(), "Fatal error. Contact "\
+               "%S Admin. Cannot find you in the players list.");
+           log("Error on logout(). Can't find %s in the players list",
+               #ifdef P10 
+                   user->getRealNick()
+               #else 
+                   user->getNick()
+               #endif
+               );
+            return;
+        }
+
+       temp = new aClient;
+       temp->stats = new Player;
+       temp->stats->setData(user->stats);
+       user->stats->client = NULL;
+
+       if (player_fight(user))
+           user->stats->battle->stats->battle = NULL;
+
+       delete user->stats;
+       user->stats = NULL;
+       temp->stats->client = NULL;
+       #ifdef P10
+           temp->setRealNick("Not Playing");
+       #endif
+       temp->setNick("Not Playing");
+
+       it->setNewPtr(temp);
+       #ifdef DEBUGMODE
+           log("Logged out player %s",
+               #ifdef P10 
+                   user->getRealNick()
+               #else 
+                   user->getNick()
+               #endif 
+               );
+       #endif
+    }
+    clearPlaying(user);
 }
 }
+
 void do_register(char *u)
 {
 void do_register(char *u)
 {
-    char *password;
+    char *password, *name;
     aClient *user;
     aClient *user;
+    name = strtok(NULL, " ");
     password = strtok(NULL, " ");
 
     static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
     password = strtok(NULL, " ");
 
     static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
@@ -378,21 +758,51 @@ void do_register(char *u)
     
     salt[0] = saltChars[rand() % strlen(saltChars)];
     salt[1] = saltChars[rand() % strlen(saltChars)];
     
     salt[0] = saltChars[rand() % strlen(saltChars)];
     salt[1] = saltChars[rand() % strlen(saltChars)];
-    salt[3] = '\0';
+    salt[2] = '\0';
 
 
-    if (!password)
+    if (!name)
+    {
+       notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
+    }
+    else if (!password)
+    {
+       notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
+    }
+    else if ((user = findplayer(name)))
+    {
+       notice(s_GameServ, u, "%s is already registered!", name);
+       notice(s_GameServ, u, "Choose another name!");
+    }
+    else if (!(user = find(u)))
+    {
+       log("Fatal Error: Couldn't find %s in the clients list", u);
+    }
+    else if (isIgnore(user))
     {
     {
-       notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER PASSWORD");
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", user->getNick());
+       #endif
+       return;
     }
     }
-    else if (user = find(u))
+    else
     {
     {
-        if (!user->stats)
+        if (!is_playing(user))
         {
         {
+           ListNode<aClient> *temp;
            user->stats = new Player(user);
            user->stats = new Player(user);
-           user->stats->started = 1;
-           user->stats->user = user; // Set the backwards pointer
-           strcpy(user->stats->password, crypt(password, salt));
-           players.insertAtBack(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);
+           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);
+           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);
+           setPlaying(user); // set the playing flag
        }
        else
        {
        }
        else
        {
@@ -407,635 +817,248 @@ void do_identify(char *u)
     aClient *user, *p;
     name = strtok(NULL, " ");
     password = strtok(NULL, " ");
     aClient *user, *p;
     name = strtok(NULL, " ");
     password = strtok(NULL, " ");
-
     if (!password || !name)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
     }
     if (!password || !name)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
     }
+    else if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
+       log("Error: aClient not found: %s", u);
+    }
+    else if (isIgnore(user))
+    {
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", user->getNick());
+       #endif
+       return;
+    }
     else if (!(p = findplayer(name)) || !p->stats)
            notice(s_GameServ, u, "Player %s not found", name);
     else if (!(p = findplayer(name)) || !p->stats)
            notice(s_GameServ, u, "Player %s not found", name);
-    else if (!check_password(name, password))
+    else if (is_playing(user))
     {
     {
-           notice(s_GameServ, u, "Password incorrect");
+       notice(s_GameServ, u, "You are already playing!");
     }
     }
-    else if (user = find(u))
+    else if (p->stats->client != NULL && !isAdmin(user))
     {
     {
-        if (!user->stats)
-        {
-           ListNode<aClient> *temp;
-           temp = players.Find(p);
-           if (!temp)
-           {
-               notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s", 
-                       strtok(NULL, ""));
-               return;
-           }
-           user->stats = new Player(p->stats->name);
-           cout << "Setting data for identified" << endl;
-           user->stats->setData(p->stats);
-           cout << "Player Identified" << endl << flush;
+       notice(s_GameServ, u, "That player has already identified.");
+    }
+    else if (!check_password(name, password) && !isAdmin(user))
+    {
+           notice(s_GameServ, u, "Password incorrect");
+    }
+    else {
+       ListNode<aClient> *temp;
+       unsigned long hv = iHASH((unsigned char *) p->stats->name);
+       temp = players[hv].Find(p);
+       if (!temp)
+       {
+           notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s", 
+               strtok(NULL, ""));
+           return;
+       }
+       user->stats = new Player(p->stats->name);
+       #ifdef DEBUGMODE
+           log("Setting data for identified");
+       #endif
+       user->stats->setData(p->stats);
+       user->stats->client = user;
+       updateTS(user->stats);
 
 
-           temp->setPtr(user);
 
 
-           notice(s_GameServ, u, "Password Accepted. Identified.");        
+       #ifdef DEBUGMODE
+           log("Player %s IRC: %s Identified", user->stats->name, 
+               user->getNick());
+       #endif
 
 
-       }
-       else
-       {
-           notice(s_GameServ, u, "Already identified. Contact a %S admin for help.");
-       }
+       setPlaying(user); // set the playing flag
+
+       temp->setPtr(user);
+       notice(s_GameServ, u, "Password Accepted. Identified.");
+       showNews(u, todaysnews);
     }
 }
 
 void do_stats(char *u)
 {
     char *nick;
     }
 }
 
 void do_stats(char *u)
 {
     char *nick;
-    aClient *source;
+    aClient *user;
 
     nick = strtok(NULL, " ");
 
     nick = strtok(NULL, " ");
-    source = find(u);
 
 
-    if (!nick)
-       showstats(u, source->getNick());
+    if (!(user = find(u)))
+    {
+       log("Fatal Error: %s not found in client list", u);
+       return;
+    }
+    else if (isIgnore(user))
+    {
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", user->getNick());
+       #endif
+       return;
+    }
+    else if (!nick)
+    {
+       if (!is_playing(user))
+       {
+           notice(s_GameServ, u, "You're not playing, so you have no stats!");
+           return;
+       }
+       else
+       {
+           updateTS(user->stats);
+           showstats(u, user->stats->name);
+       }
+    }
     else
        showstats(u, nick);
 }
     else
        showstats(u, nick);
 }
+
 void init_masters()
 {
 void init_masters()
 {
-    masters[0].name = "Old Bones";
-    masters[0].weapon = "Dull Sword Cane";
-    masters[0].strength = 30;
-    masters[0].gold = 0;
-    masters[0].exp = 0;
-    masters[0].maxhp = 30;
-    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!";
-
-    masters[1].name = "Master Chang";
-    masters[1].weapon = "Nanchaku";
-    masters[1].strength = 57;
-    masters[1].gold = 0;
-    masters[1].exp = 0;
-    masters[1].maxhp = 40;
-    masters[1].death = "You try to make out what Master Chang is saying, but the only thing you catch is something about a grasshopper.";
-
-    masters[2].name = "Chuck Norris";
-    masters[2].weapon = "Ranger Kick";
-    masters[2].strength = 85;
-    masters[2].gold = 0;
-    masters[2].exp = 0;
-    masters[2].maxhp = 70;
-    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!";
-
-
-    masters[3].name = "Mr. Miagi";
-    masters[3].weapon = "Petrified Bonsai";
-    masters[3].strength = 100;
-    masters[3].gold = 0;
-    masters[3].exp = 0;
-    masters[3].maxhp = 120;
-    masters[3].death = "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!";
-
-    masters[4].name = "Jackie Chan";
-    masters[4].weapon = "Drunken Boxing";
-    masters[4].strength = 125;
-    masters[4].maxhp = 200;
-    masters[4].gold = 0;
-    masters[4].exp = 0;
-    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!";
-
-    masters[5].name = "Jet Li";
-    masters[5].weapon = "Motorcycle";
-    masters[5].strength = 150;
-    masters[5].maxhp = 400;
-    masters[5].gold = 0;
-    masters[5].exp = 0;
-    masters[5].death = "Failure is a fuel for excuses. It's the doing the do, that makes the making.";
-
-
-    masters[6].name = "Muhammad Ali";
-    masters[6].weapon = "Quick Jab";
-    masters[6].strength = 175;
-    masters[6].maxhp = 600;
-    masters[6].gold = 0;
-    masters[6].exp = 0;
-    masters[6].death = "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.";
-
-    masters[7].name = "Li Mu Bai";
-    masters[7].weapon = "Green Destiny";
-    masters[7].strength = 200;
-    masters[7].maxhp = 800;
-    masters[7].gold = 0;
-    masters[7].exp = 0;
-    masters[7].death = "No growth without resistance.  No action without reaction.  No desire without restraint.";
-
-
-    masters[8].name = "Jimmy Wang Yu";
-    masters[8].weapon = "Flying Guillotine";
-    masters[8].strength = 275;
-    masters[8].maxhp = 1200;
-    masters[8].gold = 0;
-    masters[8].exp = 0;
-    masters[8].death = "You have beaten the one armed boxer. Proceed with caution!";
-
-    masters[9].name = "Wong Fei Hung";
-    masters[9].weapon = "Drunken Boxing";
-    masters[9].strength = 350;
-    masters[9].maxhp = 1800;
-    masters[9].gold = 0;
-    masters[9].exp = 0;
-    masters[9].death = "";
-
-    masters[10].name = "Bruce Lee";
-    masters[10].strength = 575;
-    masters[10].maxhp = 2500;
-    masters[10].gold = 0;
-    masters[10].exp = 0;
-    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.";
+    #ifdef DEBUGMODE
+       log("Calling delete_masters()");
+    #endif
+
+    delete_masters();
+
+    #ifdef DEBUGMODE
+       log("Initializing masters");
+    #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()
 {
 }
 
 void init_monsters()
 {
-    // Hard coded for now - Kain
-    monsters[0][0].name = "Slime";
-    monsters[0][0].weapon = "Acid Goo";
-    monsters[0][0].strength = 6;
-    monsters[0][0].gold = 50;
-    monsters[0][0].exp = 3;
-    monsters[0][0].maxhp = 9;
-    monsters[0][0].death = "The slime oozes into nothing... you clean the acid goo off of your weapon";
-
-    monsters[0][1].name = "Ghost";
-    monsters[0][1].weapon = "Cold Breath";
-    monsters[0][1].strength = 8;
-    monsters[0][1].gold = 100;
-    monsters[0][1].exp = 10;
-    monsters[0][1].maxhp = 10;
-    monsters[0][1].death = "You feel a chill as the spirit leaves the realm.";
-
-    monsters[0][2].name = "Ugly Rodent";
-    monsters[0][2].weapon = "Sharp Teeth";
-    monsters[0][2].strength = 9;
-    monsters[0][2].gold = 75;
-    monsters[0][2].exp = 8;
-    monsters[0][2].maxhp = 13;
-    monsters[0][2].death = "You stomp on the Ugly Rodent's remains for a finishing blow.";
-
-    monsters[0][3].name = "Whart Hog";
-    monsters[0][3].weapon = "Tusks";
-    monsters[0][3].strength = 10;
-    monsters[0][3].gold = 80;
-    monsters[0][3].exp = 6;
-    monsters[0][3].maxhp = 10;
-    monsters[0][3].death = "You cook and eat the hog for good measure!";
-
-    monsters[0][4].name = "Pesky Kid";
-    monsters[0][4].weapon = "Slingshot";
-    monsters[0][4].strength = 8;
-    monsters[0][4].gold = 30;
-    monsters[0][4].exp = 4;
-    monsters[0][4].maxhp = 6;
-    monsters[0][4].death = "You take his slingshot and snap the band, sending the kid crying home to mom!";
-
-    monsters[0][5].name = "Playground Bully";
-    monsters[0][5].weapon = "Painful Noogie";
-    monsters[0][5].strength = 11;
-    monsters[0][5].gold = 44;
-    monsters[0][5].exp = 6;
-    monsters[0][5].maxhp = 10;
-    monsters[0][5].death = "You give him an indian burn, and punt him across the schoolyard!";
-
-    monsters[0][6].name = "Small Imp";
-    monsters[0][6].weapon = "Dagger";
-    monsters[0][6].strength = 6;
-    monsters[0][6].gold = 64;
-    monsters[0][6].exp = 10;
-    monsters[0][6].maxhp = 10;
-    monsters[0][6].death = "You can't help but laugh as he stumbles and falls onto his own dagger!";
-
-    monsters[0][7].name = "Little Monkey";
-    monsters[0][7].weapon = "Monkey Wrench";
-    monsters[0][7].strength = 6;
-    monsters[0][7].gold = 53;
-    monsters[0][7].exp = 9;
-    monsters[0][7].maxhp = 9;
-    monsters[0][7].death = "You want to cook it, but you just can't think of eating something that looks so human!";
-
-    monsters[0][8].name = "Grub Worm";
-    monsters[0][8].weapon = "Minor Nudge";
-    monsters[0][8].strength = 2;
-    monsters[0][8].gold = 10;
-    monsters[0][8].exp = 3;
-    monsters[0][8].maxhp = 3;
-    monsters[0][8].death = "You decide to save the poor little fella for your next fishing trip.";
-
-    monsters[0][9].name = "Drakee";
-    monsters[0][9].weapon = "Tail Slap";
-    monsters[0][9].strength = 5;
-    monsters[0][9].gold = 22;
-    monsters[0][9].exp = 7;
-    monsters[0][9].maxhp = 5;
-    monsters[0][9].death = "You pull the little Drakee by its tale and slam it down on a dry stump!";
-
-    monsters[0][10].name = "Fat Slob";
-    monsters[0][10].weapon = "Smelly Breath";
-    monsters[0][10].strength = 6;
-    monsters[0][10].gold = 40;
-    monsters[0][10].exp = 10;
-    monsters[0][10].maxhp = 7;
-    monsters[0][10].death = "You kick his stomach for fun, and are thrown back by the spring of it all!";
-
-    monsters[0][11].name = "Lost Warrior";
-    monsters[0][11].weapon = "Long Sword";
-    monsters[0][11].strength = 10;
-    monsters[0][11].gold = 250;
-    monsters[0][11].exp = 19;
-    monsters[0][11].maxhp = 15;
-    monsters[0][11].death = "You give him a proper burial in respect for the dead warrior.";
-
-    monsters[1][0].name = "Lost Warrior's Cousin Larry";
-    monsters[1][0].weapon = "Wood Axe";
-    monsters[1][0].strength = 19;
-    monsters[1][0].gold = 134;
-    monsters[1][0].exp = 24;
-    monsters[1][0].maxhp = 30;
-    monsters[1][0].death = "He was pretty pissed you killed his cousin, but he seems to have suffered the same fate!";
-
-    monsters[1][1].name = "Sandman";
-    monsters[1][1].weapon = "Sleeping Dust";
-    monsters[1][1].strength = 25;
-    monsters[1][1].gold = 80;
-    monsters[1][1].exp = 6;
-    monsters[1][1].maxhp = 27;
-    monsters[1][1].death = "You put the sandman to his final sleep.";
-
-    monsters[1][2].name = "Dirty Transvestite";
-    monsters[1][2].weapon = "Stiletto Heel";
-    monsters[1][2].strength = 21;
-    monsters[1][2].gold = 160;
-    monsters[1][2].exp = 12;
-    monsters[1][2].maxhp = 25;
-    monsters[1][2].death = "You shudder at the thought of ever mistaking this for a woman!";
-
-    monsters[1][3].name = "Goblin Gardener";
-    monsters[1][3].weapon = "Garden Spade";
-    monsters[1][3].strength = 18;
-    monsters[1][3].gold = 130;
-    monsters[1][3].exp = 8;
-    monsters[1][3].maxhp = 20;
-    monsters[1][3].death = "You trample on his garden after slaying him... that felt good!";
-
-    monsters[1][4].name = "Evil Elf";
-    monsters[1][4].weapon = "Elvish Bow";
-    monsters[1][4].strength = 23;
-    monsters[1][4].gold = 136;
-    monsters[1][4].exp = 13;
-    monsters[1][4].maxhp = 24;
-    monsters[1][4].death = "Elves are usually nice you thought... hmm.";
-
-    monsters[1][5].name = "Viking Warrior";
-    monsters[1][5].weapon = "Broad Sword";
-    monsters[1][5].strength = 21;
-    monsters[1][5].gold = 330;
-    monsters[1][5].exp = 20;
-    monsters[1][5].maxhp = 18;
-    monsters[1][5].death = "You heard vikings were big, but not THAT big you thought.";
-
-    monsters[1][6].name = "Wicked Witch";
-    monsters[1][6].weapon = "Cackling Laugh";
-    monsters[1][6].strength = 20;
-    monsters[1][6].gold = 130;
-    monsters[1][6].exp = 20;
-    monsters[1][6].maxhp = 26;
-    monsters[1][6].death = "Just for kicks, you splash some water on her and watch her melt.";
-
-    monsters[1][7].name = "Vampire Bat";
-    monsters[1][7].weapon = "Blood Sucking Fangs";
-    monsters[1][7].strength = 18;
-    monsters[1][7].gold = 125;
-    monsters[1][7].exp = 21;
-    monsters[1][7].maxhp = 29;
-    monsters[1][7].death = "You fry up the bat and eat it... needs garlic.";
-
-    monsters[1][8].name = "Thorn Bush";
-    monsters[1][8].weapon = "101 Thorns";
-    monsters[1][8].strength = 16;
-    monsters[1][8].gold = 94;
-    monsters[1][8].exp = 15;
-    monsters[1][8].maxhp = 25;
-    monsters[1][8].death = "You set the bush ablaze and roast some marshmallows.";
-
-    monsters[1][9].name = "Barbarian";
-    monsters[1][9].weapon = "Heavy Sword";
-    monsters[1][9].strength = 29;
-    monsters[1][9].gold = 250;
-    monsters[1][9].exp = 25;
-    monsters[1][9].maxhp = 30;
-    monsters[1][9].death = "You listen to him moan as he falls over dead.";
-
-    monsters[1][10].name = "Crypt Rat";
-    monsters[1][10].weapon = "Stinging Bite";
-    monsters[1][10].strength = 25;
-    monsters[1][10].gold = 119;
-    monsters[1][10].exp = 20;
-    monsters[1][10].maxhp = 26;
-    monsters[1][10].death = "You squash the little rodent for fear that it might not be dead.";
-
-    monsters[1][11].name = "Small Orc";
-    monsters[1][11].weapon = "blade";
-    monsters[1][11].strength = 28;
-    monsters[1][11].gold = 300;
-    monsters[1][11].exp = 30;
-    monsters[1][11].maxhp = 36;
-    monsters[1][11].death = "It's an ugly one, and it would've grown up to be a terror...";
-
-    monsters[2][0].name = "Teferi";
-    monsters[2][0].weapon = "Puzzle Box";
-    monsters[2][0].strength = 29;
-    monsters[2][0].gold = 380;
-    monsters[2][0].exp = 18;
-    monsters[2][0].maxhp = 29;
-    monsters[2][0].death = "It was a puzzling experience.";
-
-    monsters[2][1].name = "Spineless Thug";
-    monsters[2][1].weapon = "Spiked Bat";
-    monsters[2][1].strength = 37;
-    monsters[2][1].gold = 384;
-    monsters[2][1].exp = 27;
-    monsters[2][1].maxhp = 32;
-    monsters[2][1].death = "See you at the crossroads!";
-
-    monsters[2][2].name = "Pyromaniac";
-    monsters[2][2].weapon = "Pyrotechnics";
-    monsters[2][2].strength = 29;
-    monsters[2][2].gold = 563;
-    monsters[2][2].exp = 22;
-    monsters[2][2].maxhp = 45;
-    monsters[2][2].death = "He chants FIRE FIRE as he falls to the ground... a burning heap of flesh.";
-
-    monsters[2][3].name = "Evil Enchantress";
-    monsters[2][3].weapon = "Deadly Spell";
-    monsters[2][3].strength = 50;
-    monsters[2][3].gold = 830;
-    monsters[2][3].exp = 35;
-    monsters[2][3].maxhp = 35;
-    monsters[2][3].death = "She looked just about as good as she fought.";
-
-    monsters[2][4].name = "Killer Leprechaun";
-    monsters[2][4].weapon = "Gold Rush";
-    monsters[2][4].strength = 35;
-    monsters[2][4].gold = 1300;
-    monsters[2][4].exp = 30;
-    monsters[2][4].maxhp = 37;
-    monsters[2][4].death = "You steal his pot of gold... that's a lot of money!";
-
-    monsters[2][5].name = "Avalanche Rider";
-    monsters[2][5].weapon = "Huge Snowball";
-    monsters[2][5].strength = 32;
-    monsters[2][5].gold = 700;
-    monsters[2][5].exp = 32;
-    monsters[2][5].maxhp = 38;
-    monsters[2][5].death = "You take his snowboard and snap it in two!";
-
-    monsters[2][6].name = "Blundering Idiot";
-    monsters[2][6].weapon = "Stupidity";
-    monsters[2][6].strength = 14;
-    monsters[2][6].gold = 700;
-    monsters[2][6].exp = 20;
-    monsters[2][6].maxhp = 29;
-    monsters[2][6].death = "Now there's one person you don't feel sorry for killing!";
-
-    monsters[2][7].name = "Militant Anarchist";
-    monsters[2][7].weapon = "Molotov Cocktail";
-    monsters[2][7].strength = 33;
-    monsters[2][7].gold = 245;
-    monsters[2][7].exp = 45;
-    monsters[2][7].maxhp = 32;
-    monsters[2][7].death = "Order has been restored for now...";
-
-    monsters[2][8].name = "Scathe Zombies";
-    monsters[2][8].weapon = "Death Grip";
-    monsters[2][8].strength = 38;
-    monsters[2][8].gold = 763;
-    monsters[2][8].exp = 15;
-    monsters[2][8].maxhp = 45;
-    monsters[2][8].death = "That was perhaps the scariest experience of your life.";
-
-    monsters[2][9].name = "Spitting Llama";
-    monsters[2][9].weapon = "Spit Spray";
-    monsters[2][9].strength = 48;
-    monsters[2][9].gold = 638;
-    monsters[2][9].exp = 28;
-    monsters[2][9].maxhp = 34;
-    monsters[2][9].death = "You wipe the spit off your face and fling it back at the Llama.";
-
-    monsters[2][10].name = "Juggalo";
-    monsters[2][10].weapon = "Clown Axe";
-    monsters[2][10].strength = 60;
-    monsters[2][10].gold = 650;
-    monsters[2][10].exp = 30;
-    monsters[2][10].maxhp = 29;
-    monsters[2][10].death = "What is a Juggalo? I don't know!";
-
-    monsters[2][11].name = "The Boogie Man";
-    monsters[2][11].weapon = "Striking Fear";
-    monsters[2][11].strength = 46;
-    monsters[2][11].gold = 600;
-    monsters[2][11].exp = 35;
-    monsters[2][11].maxhp = 27;
-    monsters[2][11].death = "He's scared you for the very last time!";
-
-    monsters[3][0].name = "Living Fire";
-    monsters[3][0].weapon = "Scorching Wind";
-    monsters[3][0].strength = 55;
-    monsters[3][0].gold = 1100;
-    monsters[3][0].exp = 36;
-    monsters[3][0].maxhp = 55;
-    monsters[3][0].death = "You extinguish the Living Flame once and for all!";
-
-    monsters[3][1].name = "Raging Orc";
-    monsters[3][1].weapon = "Orcish Artillary";
-    monsters[3][1].strength = 89;
-    monsters[3][1].gold = 900;
-    monsters[3][1].exp = 25;
-    monsters[3][1].maxhp = 50;
-    monsters[3][1].death = "This orc was a bit tougher than you remembered!";
-
-    monsters[3][2].name = "Huge Tarantula";
-    monsters[3][2].weapon = "Tangling Web";
-    monsters[3][2].strength = 59;
-    monsters[3][2].gold = 1000;
-    monsters[3][2].exp = 35;
-    monsters[3][2].maxhp = 60;
-    monsters[3][2].death = "You're glad you overcame your arachniphobia so soon!";
-
-    monsters[3][3].name = "Rabid Wolf";
-    monsters[3][3].weapon = "Cujo Bite";
-    monsters[3][3].strength = 40;
-    monsters[3][3].gold = 1200;
-    monsters[3][3].exp = 47;
-    monsters[3][3].maxhp = 76;
-    monsters[3][3].death = "The mutt falls over dead as white foam drips from its deadly canines...";
-
-    monsters[3][4].name = "Goblin Fighter";
-    monsters[3][4].weapon = "Morning Star";
-    monsters[3][4].strength = 38;
-    monsters[3][4].gold = 700;
-    monsters[3][4].exp = 30;
-    monsters[3][4].maxhp = 75;
-    monsters[3][4].death = "He almost caught you with his chain mace, but you sliced off his head.";
-
-    monsters[3][5].name = "Grizzly Bear";
-    monsters[3][5].weapon = "Razor Claws";
-    monsters[3][5].strength = 68;
-    monsters[3][5].gold = 1747;
-    monsters[3][5].exp = 81;
-    monsters[3][5].maxhp = 51;
-    monsters[3][5].death = "It almost got you this time... better be careful";
-
-    monsters[3][6].name = "Skeleton Man";
-    monsters[3][6].weapon = "Leg Bone";
-    monsters[3][6].strength = 70;
-    monsters[3][6].gold = 597;
-    monsters[3][6].exp = 57;
-    monsters[3][6].maxhp = 60;
-    monsters[3][6].death = "As a finisher, you wind up with the broad side of your weapon and hit his skull off for a home run!";
-
-    monsters[3][7].name = "Young Werewolf";
-    monsters[3][7].weapon = "Howling Bites";
-    monsters[3][7].strength = 75;
-    monsters[3][7].gold = 1742;
-    monsters[3][7].exp = 65;
-    monsters[3][7].maxhp = 42;
-    monsters[3][7].death = "You scatter the wolf's body parts in hopes he will stay dead!";
-
-    monsters[3][8].name = "Dark Infantry";
-    monsters[3][8].weapon = "Flesh Reaper";
-    monsters[3][8].strength = 69;
-    monsters[3][8].gold = 870;
-    monsters[3][8].exp = 43;
-    monsters[3][8].maxhp = 65;
-    monsters[3][8].death = "Light has prevailed this time... but it's only so long before you meet again.";
-
-    monsters[3][9].name = "Erie Spirit";
-    monsters[3][9].weapon = "Deadly Grin";
-    monsters[3][9].strength = 63;
-    monsters[3][9].gold = 1300;
-    monsters[3][9].exp = 32;
-    monsters[3][9].maxhp = 50;
-    monsters[3][9].death = "His cousin the ghost was a little bit easier.";
-
-    monsters[3][10].name = "Gollum";
-    monsters[3][10].weapon = "Precious Treasure";
-    monsters[3][10].strength = 66;
-    monsters[3][10].gold = 1492;
-    monsters[3][10].exp = 73;
-    monsters[3][10].maxhp = 54;
-    monsters[3][10].death = "Gollum screams out \"MY PRECIOUS\" as his small body falls limp from your blow.";
-
-    monsters[3][11].name = "Rock Fighter";
-    monsters[3][11].weapon = "Small Boulders";
-    monsters[3][11].strength = 87;
-    monsters[3][11].gold = 1742;
-    monsters[3][11].exp = 99;
-    monsters[3][11].maxhp = 65;
-    monsters[3][11].death = "You dodge his last rock, and counter with a low blow, cutting off his legs.";
-
-
-    monsters[4][0].name = "Giant Sphinx";
-    monsters[4][0].weapon = "Ancient Curse";
-    monsters[4][0].strength = 120;
-    monsters[4][0].gold = 1000;
-    monsters[4][0].exp = 100;
-    monsters[4][0].maxhp = 80;
-    monsters[4][0].death = "You look in awe at the great wonder, collapsed at your feet!";
-
-    monsters[4][1].name = "Giant Ogre";
-    monsters[4][1].weapon = "Big Log";
-    monsters[4][1].strength = 130;
-    monsters[4][1].gold = 857;
-    monsters[4][1].exp = 175;
-    monsters[4][1].maxhp = 100;
-    monsters[4][1].death = "Your witz outmatched the ogres brawn... big dumb thing.";
-
-    monsters[4][2].name = "Massive Cockroach";
-    monsters[4][2].weapon = "Piercing Hiss";
-    monsters[4][2].strength = 125;
-    monsters[4][2].gold = 700;
-    monsters[4][2].exp = 150;
-    monsters[4][2].maxhp = 112;
-    monsters[4][2].death = "Where's the exterminator when you need one?";
-
-    monsters[4][3].name = "Big Venomous Snake";
-    monsters[4][3].weapon = "Poison Fangs";
-    monsters[4][3].strength = 140;
-    monsters[4][3].gold = 900;
-    monsters[4][3].exp = 175;
-    monsters[4][3].maxhp = 126;
-    monsters[4][3].death = "After killing this beast you check for puncture marks... you find none, luckily.";
-
-    monsters[4][4].name = "Lizard Man";
-    monsters[4][4].weapon = "Deadly Jaws";
-    monsters[4][4].strength = 145;
-    monsters[4][4].gold = 1250;
-    monsters[4][4].exp = 175;
-    monsters[4][4].maxhp = 150;
-    monsters[4][4].death = "His scales made for tough armor, and his jaws for a tougher opponent!";
-
-    monsters[4][5].name = "Face Dancer";
-    monsters[4][5].weapon = "Illusion Scyth";
-    monsters[4][5].strength = 138;
-    monsters[4][5].gold = 1603;
-    monsters[4][5].exp = 198;
-    monsters[4][5].maxhp = 173;
-    monsters[4][5].death = "His carcus takes the shape of many things before it dies. His true form is so repulsive, you know why he changed faces so much!";
-
-    monsters[4][6].name = "Darklord Longbow Archer";
-    monsters[4][6].weapon = "Deadly Bow and Arrows";
-    monsters[4][6].strength = 145;
-    monsters[4][6].gold = 1569;
-    monsters[4][6].exp = 243;
-    monsters[4][6].maxhp = 170;
-    monsters[4][6].death = "Your face turns white with horror after you realize you just met the devil's protector!";
-
-    monsters[4][7].name = "Hell's Paladin";
-    monsters[4][7].weapon = "Sword of Hellfire";
-    monsters[4][7].strength = 200;
-    monsters[4][7].gold = 2191;
-    monsters[4][7].exp = 254;
-    monsters[4][7].maxhp = 175;
-    monsters[4][7].death = "This is starting to get tough you think. Do you really want to go to level 12?";
-
-    monsters[4][8].name = "The Unknown Soldier";
-    monsters[4][8].weapon = "Soul Torture";
-    monsters[4][8].strength = 175;
-    monsters[4][8].gold = 1890;
-    monsters[4][8].exp = 200;
-    monsters[4][8].maxhp = 180;
-    monsters[4][8].death = "Who was that? Where was he from? And what was that weapon??";
-
-    monsters[4][9].name = "Undead Cult Leader";
-    monsters[4][9].weapon = "Lance of Deceit";
-    monsters[4][9].strength = 180;
-    monsters[4][9].gold = 1792;
-    monsters[4][9].exp = 195;
-    monsters[4][9].maxhp = 190;
-    monsters[4][9].death = "His words fall on deaf ears... this is one cult you will NOT be part of!";
-
-    monsters[4][10].name = "Water Serpent";
-    monsters[4][10].weapon = "Forked Tongue";
-    monsters[4][10].strength = 150;
-    monsters[4][10].gold = 1500;
-    monsters[4][10].exp = 176;
-    monsters[4][10].maxhp = 220;
-    monsters[4][10].death = "The serpent squeals as you cut off its head!";
-
-    monsters[4][11].name = "Silverback Gorilla";
-    monsters[4][11].weapon = "Deadly Banana Peel";
-    monsters[4][11].strength = 160;
-    monsters[4][11].gold = 1300;
-    monsters[4][11].exp = 150;
-    monsters[4][11].maxhp = 178;
-    monsters[4][11].death = "Was that gorilla or guerilla?";
+    #ifdef DEBUGMODE
+       log("Calling delete_monsters");
+    #endif
+
+    delete_monsters();
+
+    for (int x = 0; x < LEVELS; x++)
+       for (int y = 0; y < MONSTERS; y++)
+           monsters[x][y] = new Monster();
+}
+
+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];
+}
+
+void delete_masters()
+{
+    for (int x = 0; x < LEVELS; x++)
+       if (masters[x])
+           delete masters[x];
 }
 
 void display_monster(char *u)
 }
 
 void display_monster(char *u)
@@ -1056,19 +1079,26 @@ void display_monster(char *u)
 
 void display_players(char *u)
 {
 
 void display_players(char *u)
 {
-    if (is_playing(u))
+    aClient *user;
+    if (!(user = find(u)))
     {
     {
-       aClient *ni = find(u);
-
-       aClient *battle = ni->stats->battle;
-
-       notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->stats->hp);
-       notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->getNick(), 
-                                                       battle->stats->hp);
+       log("Fatal error in display_players(): Couldn't find %s", u);
+    }
+    else
+       display_players(user);
+}
 
 
+void display_players(aClient *user)
+{
+    char *u = user->getNick();
+    if (is_playing(user) && player_fight(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, "Here are your commands:");
        notice(s_GameServ, u, "Here are your commands:");
-       notice(s_GameServ, u, "/msg %s attack", s_GameServ);
-       notice(s_GameServ, u, "/msg %s run", s_GameServ);
+       notice(s_GameServ, u, "/msg %S attack");
+       notice(s_GameServ, u, "/msg %S run");
        notice(s_GameServ, u, "What will you do?");
     }
 }
        notice(s_GameServ, u, "What will you do?");
     }
 }
@@ -1078,42 +1108,66 @@ bool is_playing(char *u)
 {
     aClient *user;
     if (!(user = find(u)))
 {
     aClient *user;
     if (!(user = find(u)))
-    {
        return false;
        return false;
-    }
     else
     else
-    {
-       return user->stats != NULL;
-    }
+       return is_playing(user);
 }
 
 }
 
-bool is_fighting(char *u)
+bool is_playing(aClient *user)
 {
 {
-    aClient *user;
-
-    if (!(user = find(u)))
+    if (user->stats == NULL)
     {
        return false;
     }
     {
        return false;
     }
-    else if (user->stats)
+    else if (user->stats->client == NULL)
     {
     {
-       return user->stats->fight != NULL || user->stats->battle != NULL 
-               || user->stats->master != NULL;
+       return false;
+    }
+    else if (!FL_is_playing(user))
+    {
+       return false;
     }
     else
     }
     else
-       return false;
+       return true;
 }
 
 }
 
-bool player_fight(char *u)
+bool is_fighting(char *u)
 {
     aClient *user;
 
     if (!(user = find(u)))
        return false;
 {
     aClient *user;
 
     if (!(user = find(u)))
        return false;
-    else if (user->stats)
-       return user->stats->battle != NULL;
     else
     else
+       return is_fighting(user);
+}
+
+bool is_fighting(aClient *user)
+{
+    if (!is_playing(user))
+       return false;
+    else
+       return player_fight(user) || master_fight(user) || user->stats->fight != NULL;
+}
+
+bool player_fight(char *u)
+{
+    aClient *user;
+
+    if (!(user = find(u)))
+       return false;
+    else 
+       return player_fight(user);
+}
+
+bool player_fight(aClient *user)
+{
+    if (!is_playing(user))
        return false;
        return false;
+    else if (user->stats->battle != NULL)
+    {
+       return user->stats->battle->stats != NULL;
+    }
+    return false;
 }
 
 bool master_fight(char *u)
 }
 
 bool master_fight(char *u)
@@ -1122,15 +1176,16 @@ bool master_fight(char *u)
 
     if (!(user = find(u)))
        return false;
 
     if (!(user = find(u)))
        return false;
-    else if (user->stats)
-       return user->stats->master != NULL;
     else
     else
-       return false;
+       return master_fight(user);
 }
 
 }
 
-bool isnt_fighting(char *u)
+bool master_fight(aClient *user)
 {
 {
-    return !is_fighting(u);
+    if (!is_playing(user))
+       return false;
+    else
+       return user->stats->master != NULL;
 }
 
 void do_fight(char *u)
 }
 
 void do_fight(char *u)
@@ -1142,51 +1197,375 @@ void do_fight(char *u)
     if (!nick)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
     if (!nick)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
+       return;
     }
     else if (!(ni = find(u)))
     {
     }
     else if (!(ni = find(u)))
     {
+       notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
        return;
     }
        return;
     }
-    else if (!(battle = find(nick)))
+    else if (isIgnore(ni))
     {
     {
-       notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", ni->getNick());
+       #endif
+       return;
     }
     }
-    else if (!is_playing(u))
+    else if (!is_playing(ni))
     {
        notice(s_GameServ, u, "You are not playing!");
     {
        notice(s_GameServ, u, "You are not playing!");
+       return;
+    }
+
+    updateTS(ni->stats);
+
+    if (ni->stats->player_fights <= 0)
+    {
+       ni->stats->player_fights = 0; // just to be safe
+       notice(s_GameServ, u, "You are out of player fights for the "\
+               "day. You have to wait until tomorrow!");
+    }
+    else if (!(battle = findplayer(nick)))
+    {
+       notice(s_GameServ, u, "Player %s not found!", nick);
+    }
+    else if (!isAlive(ni->stats))
+    {
+       notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
+    }
+    else if (!is_playing(battle))
+    {
+       notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
+    }
+
+/* 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);
+        display_players(u);
+    }
+*/
+    else if (stricmp(ni->stats->name, battle->stats->name) == 0)
+    {
+       notice(s_GameServ, u, "Are you trying to commit suicide!?");
     }
     }
-/*
- * 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->getNick());
- *       display_players(u);
- *   }
- */
-    else if (is_playing(u) && is_playing(nick))
+    else if (!isAlive(battle->stats))
+    {
+        notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
+    }
+    else if (player_fight(battle))
+    {
+       notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
+    }
+    else if (master_fight(battle))
+    {
+       notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name);
+    }
+    else if (is_fighting(battle))
+    {
+       notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
+    }
+    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);
+    }
+    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);
+    }
+    else
     {
        // Set your battle pointer to the other player
         ni->stats->battle = battle;
 
        // Set the other player's battle pointer to you
     {
        // Set your battle pointer to the other player
         ni->stats->battle = battle;
 
        // Set the other player's battle pointer to you
-        battle->stats->battle = ni;
+       ni->stats->battle->stats->battle = ni;
 
        // The initiator gets the first move (perhaps this should be 50/50)
 
        // The initiator gets the first move (perhaps this should be 50/50)
-        ni->stats->yourturn = 1;
-        battle->stats->yourturn = 0;
+       setYourTurn(ni->stats);
+       clearYourTurn(battle->stats);
 
        // Initiate Battle sequence!
 
        // Initiate Battle sequence!
-        notice(s_GameServ, u, "You challenge %s to an online duel!", battle->getNick());
-        notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", u);
-        notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", u);
-        notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", u);
-        display_players(u);
+       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, 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);
+        display_players(ni);
+    }
+}
+
+void do_use(char *u)
+{
+    aClient *user;
+    Pouch *p;
+
+    char *item = strtok(NULL, " ");
+
+    if (!item)
+    {
+       notice(s_GameServ, u, "SYNTAX: USE ITEM");
+       notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
+       return;
+    }
+    else if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
+       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 use items!");
+       return;
+    }
+
+    updateTS(user->stats);
+
+    p = &user->stats->inventory;
+
+    if (stricmp(item, "HEALING") == 0)
+    {
+       if (p->Healing() <= 0)
+       {
+           notice(s_GameServ, u, "You are out of Healing Potions!");
+           return;
+       }
+       int oldhealing = 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.");
+       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))
+       {
+           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;
+       notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
+       notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
+       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)
+    {
+       if (p->Defense() <= 0)
+       {
+           notice(s_GameServ, u, "You are out of Defense Potions!");
+           return;
+       }
+       int olddefense = user->stats->defense;
+       notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
+       notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
+       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)
+    {
+       if (p->HP() <= 0)
+       {
+           notice(s_GameServ, u, "You are out of HP Potions!");
+           return;
+       }
+       int oldHP = user->stats->maxhp;
+       notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
+       user->stats->maxhp += 2 + 
+       (rand() % 100 > 70 ? (rand() % 7) : (rand() % 2) );
+
+       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 {HEALING | STRENGTH | DEFENSE | HP}");
+       return;
+    }
+
+    end_turn(user); // If they're fighting, end their turn
+}
+void do_run(char *u)
+{
+    aClient *user;
+    Player *p, *p2 = NULL;
+
+    if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
+       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 run!");
+        return;
+    }
+
+    updateTS(user->stats);
+    p = user->stats;
+
+    if (p->battle)
+       p2 = p->battle->stats;
+
+    if (!is_fighting(user))
+       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);
+       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);
+       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);
+    }
+    else if (master_fight(user))
+    {
+       notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
+    }
+    p->battle = NULL;
+}
+
+void end_turn(aClient *user)
+{
+    char *nick, *u = user->getNick();
+    Monster *fight;
+    aClient *battle;
+    int mhit;
+
+    nick = new char[strlen(user->getNick()) + 1];
+
+    if (!user || !is_playing(user) || !is_fighting(user))
+       goto endturn;
+
+    if (!player_fight(user) && !master_fight(user))
+       fight = user->stats->fight;
+    else
+       fight = user->stats->master;
+    battle = user->stats->battle;
+
+    if (!player_fight(user))
+    {
+        // Opponent's Hit
+        mhit = (fight->strength / 2) +
+               (rand() % (fight->strength / 2) - (user->stats->defense +
+                arbonus[user->stats->armor]));
+    }
+    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]));
+    }
+    if (!player_fight(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);
+        }
+        else if (mhit <= 0)
+            notice(s_GameServ, u, "%s completely misses you!", fight->name);
+
+        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 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;
+            }
+            else
+            {
+                notice(s_GameServ, u, "%s has bested you! You will have to wait "\
+                        "until tomorrow to try again", user->stats->master->name);
+                user->stats->fight = NULL;
+                user->stats->master = NULL;
+               goto endturn;
+            }
+        }
+        else
+        {
+            if (mhit > 0)
+                user->stats->hp -= mhit;
+            display_monster(u);
+            goto endturn;
+        }
     }
     }
+    else
+    {
+       clearYourTurn(user->stats);
+       setYourTurn(battle->stats);
+        display_players(battle);
+    }
+endturn:
+    delete nick;
 }
 
 void do_attack(char *u)
 }
 
 void do_attack(char *u)
@@ -1196,11 +1575,23 @@ void do_attack(char *u)
     Monster *fight; // The monster they may be fighting
 
     if (!(ni = find(u)))
     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;
     }
     {
        notice(s_GameServ, u, "You're not playing!");
        return;
     }
-    else if (!ni->stats->fight && !ni->stats->battle && !ni->stats->master)
+    else if (!is_fighting(ni))
     {
        notice(s_GameServ, u, "You're not in battle!");
        return;
     {
        notice(s_GameServ, u, "You're not in battle!");
        return;
@@ -1217,8 +1608,9 @@ void do_attack(char *u)
        // One has to be !NULL based on the previous else if
        // We wouldn't be here if they were all 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(u))
+    if (!player_fight(ni))
     {
        // Player's Hit
         hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
     {
        // Player's Hit
         hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
@@ -1242,7 +1634,7 @@ void do_attack(char *u)
                (battle->stats->defense + arbonus[battle->stats->armor]));
     }
 
                (battle->stats->defense + arbonus[battle->stats->armor]));
     }
 
-  if (!player_fight(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);
   {
     if (hit > 0)
         notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
@@ -1251,8 +1643,13 @@ void do_attack(char *u)
 
     if (hit >= fight->hp)
     {
 
     if (hit >= fight->hp)
     {
-        if (master_fight(u))
+        if (master_fight(ni))
+       {
             notice(s_GameServ, u, "You have bested %s!", fight->name);
             notice(s_GameServ, u, "You have bested %s!", fight->name);
+           addNews(todaysnews, "%s has bested %s and moved "\
+                   "to level %d", ni->stats->name, fight->name,
+                   (ni->stats->level + 1));
+       }
         else
             notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
 
         else
             notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
 
@@ -1266,18 +1663,18 @@ void do_attack(char *u)
        // Unsigned long int maybe? Leave it for now.
         ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 : 
                                ni->stats->exp + fight->exp);
        // 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->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 : 
                                ni->stats->gold + fight->gold);
-        ni->stats->fight = NULL; // They're dead so remove the pointer
 
 
-        if (master_fight(u))
+
+        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
         {
             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];
 
            // Increase your maximum hit points
             ni->stats->maxhp += hpbonus[ni->stats->level - 1];
@@ -1291,9 +1688,17 @@ void do_attack(char *u)
            // Add to your defensive power
             ni->stats->defense += defbonus[ni->stats->level - 1];
 
            // Add to your defensive power
             ni->stats->defense += defbonus[ni->stats->level - 1];
 
+            ni->stats->level++;
+
            // Clear the pointer for your master
             ni->stats->master = NULL;
         }
            // 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
         return;
     }
     else
@@ -1302,7 +1707,7 @@ void do_attack(char *u)
             fight->hp -= hit;
         if (mhit > 0)
         {
             fight->hp -= hit;
         if (mhit > 0)
         {
-            notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
+            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)
                      fight->name, fight->weapon, mhit);
         }
         else if (mhit <= 0)
@@ -1310,20 +1715,26 @@ void do_attack(char *u)
 
         if (mhit >= ni->stats->hp)
         {
 
         if (mhit >= ni->stats->hp)
         {
-            if (!master_fight(u))
+            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!");
             {
                 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!");
+               addNews(todaysnews, "%s has been killed by %s!",
+                       ni->stats->name, fight->name);
                 ni->stats->gold = 0;
                 ni->stats->exp -= (long int)(ni->stats->exp * .10);
                 ni->stats->gold = 0;
                 ni->stats->exp -= (long int)(ni->stats->exp * .10);
+               ni->stats->hp = 0;
                 ni->stats->fight = NULL;
                 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);
                 return;
             }
             else
             {
                 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
                         "until tomorrow to try again", ni->stats->master->name);
+               addNews(todaysnews, "%s tried to best %s and failed!",
+                       ni->stats->name, fight->name);
                 ni->stats->fight = NULL;
                 ni->stats->master = NULL;
                return;
                 ni->stats->fight = NULL;
                 ni->stats->master = NULL;
                return;
@@ -1338,7 +1749,7 @@ void do_attack(char *u)
         }
     }
   }
         }
     }
   }
-  else if (player_fight(u))
+  else if (player_fight(ni))
   {
 /* Offline fighting not available yet
    if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
   {
 /* Offline fighting not available yet
    if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
@@ -1424,41 +1835,37 @@ void do_attack(char *u)
    }
 * end offline fighting */
 
    }
 * end offline fighting */
 
-   if (is_playing(battle->getNick()))
+   if (is_playing(battle))
    {
    {
-    if (ni->stats->yourturn == 0)
+    if (!isYourTurn(ni->stats))
     {
         notice(s_GameServ, u, "Please wait until %s decides what to do!", 
     {
         notice(s_GameServ, u, "Please wait until %s decides what to do!", 
-               battle->getNick());
+               battle->stats->name);
         return;
     }
     if (hit > 0)
     {
         return;
     }
     if (hit > 0)
     {
-        notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->getNick(), hit);
+        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 "\
 
         notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
-                                             "\ 2%d\ 2 damage!", u, weapons[ni->stats->weapon], 
-                                             hit);
-        ni->stats->yourturn = 0;
-        battle->stats->yourturn = 1;
-        display_players(battle->getNick());
+                                             "\ 2%d\ 2 damage!", ni->stats->name, 
+                                             weapons[ni->stats->weapon], hit);
     }
     else
     {
     }
     else
     {
-        notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->getNick());
-        notice(s_GameServ, battle->getNick(), "%s misses you completely!", u);
-        ni->stats->yourturn = 0;
-        battle->stats->yourturn = 1;
-        display_players(battle->getNick());
+        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);
     }
     }
+
     if (hit >= battle->stats->hp)
     {
     if (hit >= battle->stats->hp)
     {
-        notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->getNick());
+        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, 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!", u);
+        notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!", 
+               ni->stats->name);
         battle->stats->hp = 0;
         battle->stats->hp = 0;
-        battle->stats->alive = 0;
+        clearAlive(battle->stats);
 
         if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
         {
 
         if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
         {
@@ -1484,13 +1891,15 @@ 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 "\
             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.", u);
+                       "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;
         }
 
             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;
         ni->stats->battle = NULL;
         return;
        battle->stats->battle = NULL;
         ni->stats->battle = NULL;
         return;
@@ -1499,17 +1908,17 @@ void do_attack(char *u)
     {
         if (hit > 0)
             battle->stats->hp -= hit;
     {
         if (hit > 0)
             battle->stats->hp -= hit;
-        //display_players(battle->getNick());
-        ni->stats->yourturn = 0;
-        battle->stats->yourturn = 1;
+       clearYourTurn(ni->stats);
+       setYourTurn(battle->stats);
+        display_players(battle);
         notice(s_GameServ, u, "Please wait while %s decides what to do!", 
         notice(s_GameServ, u, "Please wait while %s decides what to do!", 
-               battle->getNick());
-
+               battle->stats->name);
         return;
     }
    }
   }
 }
         return;
     }
    }
   }
 }
+
 void do_heal(char *u)
 {
     aClient *ni;
 void do_heal(char *u)
 {
     aClient *ni;
@@ -1519,20 +1928,43 @@ void do_heal(char *u)
     if (!amount)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
     if (!amount)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
+       return;
+    }
+    else if (!(ni = find(u)))
+    {
+       notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
+       return;
+    }
+    else if (isIgnore(ni))
+    {
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", ni->getNick());
+       #endif
+       return;
     }
     }
-    else if (!(ni = find(u)) || !ni->stats)
+    else if (!is_playing(ni))
     {
        notice(s_GameServ, u, "You aren't playing!");
     {
        notice(s_GameServ, u, "You aren't playing!");
+       return;
+    }
+    else if (!isAlive(ni->stats))
+    {
+       notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
+       return;
     }
     }
-    else if (is_fighting(u))
+    else if (is_fighting(ni))
     {
        notice(s_GameServ, u, "You can't heal in battle!");
     {
        notice(s_GameServ, u, "You can't heal in battle!");
+       return;
     }
     else if (ni->stats->hp >= ni->stats->maxhp)
     {
         notice(s_GameServ, u, "You don't need healing!");
     }
     else if (ni->stats->hp >= ni->stats->maxhp)
     {
         notice(s_GameServ, u, "You don't need healing!");
+       return;
     }
     }
-    else if (stricmp(amount, "ALL") == 0)
+
+    updateTS(ni->stats);
+    if (stricmp(amount, "ALL") == 0)
     {
         price = ni->stats->level * 3;
         if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
     {
         price = ni->stats->level * 3;
         if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
@@ -1587,7 +2019,7 @@ void do_heal(char *u)
 
 int isstringnum(char *num)
 {
 
 int isstringnum(char *num)
 {
-    int x;
+    unsigned int x;
     for (x = 0; x < strlen(num); x++)
     {
         if ((int)num[x] < 48 || (int)num[x] > 57)
     for (x = 0; x < strlen(num); x++)
     {
         if ((int)num[x] < 48 || (int)num[x] > 57)
@@ -1603,9 +2035,7 @@ long int stringtoint(char *number)
         return chartoint(number[0]);
     sum += chartoint(number[len - 1]);
     for (x = len - 2; x >= 0; x--)
         return chartoint(number[0]);
     sum += chartoint(number[len - 1]);
     for (x = len - 2; x >= 0; x--)
-    {
         sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
         sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
-    }
     return sum;
 }
 
     return sum;
 }
 
@@ -1627,40 +2057,15 @@ return value;
 
 long int chartoint(char ch)
 {
 
 long int chartoint(char ch)
 {
-        switch(ch)
-        {
-            case '0':
-                return 0;
-               break;
-            case '1':
-                return 1;
-            case '2':
-                return 2;
-            case '3':
-                return 3;
-            case '4':
-                return 4;
-            case '5':
-                return 5;
-            case '6':
-                return 6;
-            case '7':
-                return 7;
-            case '8':
-                return 8;
-            case '9':
-                return 9;
-            case '\n':
-                break;
-            default:
-                return -1;
-        }
-return -1;
+       if (int(ch) >= 48 && int(ch) <= 57)
+               return int(ch) - 48;
+       else
+               return 0;
 }
 
 int save_gs_dbase()
 {
 }
 
 int save_gs_dbase()
 {
-    ListNode<aClient> *ptr = players.First();
+    ListNode<aClient> *ptr;
     Player *it;
     ofstream outfile;
 
     Player *it;
     ofstream outfile;
 
@@ -1668,21 +2073,28 @@ int save_gs_dbase()
 
     if (!outfile)
     {
 
     if (!outfile)
     {
-       cerr << "Error opening " << playerdata << endl;
+       log("Error opening %s", playerdata);
        return 0;
     }
 
        return 0;
     }
 
+   for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
+   {
+    ptr = players[x].First();
     while(ptr)
     {
        it = ptr->getData()->stats;
     while(ptr)
     {
        it = ptr->getData()->stats;
+       clearYourTurn(it);
        outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
                << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
        outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
                << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
-               << it->armor << ' ' << it->weapon << ' ' << (it->alive ? "alive" : "dead") << ' '
+               << it->armor << ' ' << it->weapon << ' '
                << it->forest_fights << ' ' << it->player_fights <<  ' ' 
                << it->forest_fights << ' ' << it->player_fights <<  ' ' 
-               << it->password << endl;
+               << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
+               << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
        ptr = ptr->Next();
     }
        ptr = ptr->Next();
     }
+   }
 outfile.close();
 outfile.close();
+return 1;
 }
 
 int load_gs_dbase()
 }
 
 int load_gs_dbase()
@@ -1690,32 +2102,24 @@ int load_gs_dbase()
     ifstream infile;
     aClient *temp;
     Player *p;
     ifstream infile;
     aClient *temp;
     Player *p;
-    char *alive, *tempname, *buf, *password;
+    char *tempname, *buf, *password;
     buf = new char[1023];
 
     infile.open(playerdata);
 
     if (infile.fail())
     {
     buf = new char[1023];
 
     infile.open(playerdata);
 
     if (infile.fail())
     {
-       cerr << "Error opening " << playerdata << endl;
+       log("Error opening %s", playerdata);
        return 0;
     }
 
     while (infile.getline(buf, 1024, '\n'))
     {
        return 0;
     }
 
     while (infile.getline(buf, 1024, '\n'))
     {
-        cout << "temp = new aClient;" << endl << flush;
        temp = new aClient;
        temp = new aClient;
-       cout << "tempname = strtok(buf, " ");" << endl << flush;
        tempname = strtok(buf, " ");
        tempname = strtok(buf, " ");
-
-       cout << "temp->stats = new Player(tempname);" << endl << flush;
-
        temp->stats = new Player(tempname);
        temp->stats = new Player(tempname);
-
-       cout << "p = temp->stats;" << endl << flush;
        p = temp->stats;
 
        p = temp->stats;
 
-       //Kain 1 1 0 500 10 10 0 0 1 1 alive 100 3
        p->level = stringtoint(strtok(NULL, " "));
        p->exp = stringtoint(strtok(NULL, " "));
        p->gold = stringtoint(strtok(NULL, " "));
        p->level = stringtoint(strtok(NULL, " "));
        p->exp = stringtoint(strtok(NULL, " "));
        p->gold = stringtoint(strtok(NULL, " "));
@@ -1726,25 +2130,45 @@ int load_gs_dbase()
        p->defense = stringtoint(strtok(NULL, " "));
        p->armor = stringtoint(strtok(NULL, " "));
        p->weapon = stringtoint(strtok(NULL, " "));
        p->defense = stringtoint(strtok(NULL, " "));
        p->armor = stringtoint(strtok(NULL, " "));
        p->weapon = stringtoint(strtok(NULL, " "));
-       alive = strtok(NULL, " ");
-       p->alive = (stricmp(alive, "ALIVE") == 0 ? true : false);
        p->forest_fights = stringtoint(strtok(NULL, " "));
        p->player_fights = 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);
        password = strtok(NULL, " ");
        strcpy(p->password, password);
-       temp->setNick("NULL");
-
-       printf("%s %d %ld %ld %ld %d %d %d %d %d %d %s %d %d %s\n", p->name, p->level, 
-       p->exp, p->gold, p->bank, p->hp, p->maxhp, p->strength, p->defense, p->armor, p->weapon, 
-       alive, p->forest_fights, p->player_fights, p->password);
-
-       cout << "Inserting " << temp->stats->name << " at back of list" << endl;
-       players.insertAtBack(temp);
-       cout << temp->stats->name << " Inserted, now deleting" << endl;
+       temp->setNick("Not Playing");
+       #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, " ");
+       if (tempname)
+           p->inventory.setHP(stringtoint(tempname));
+       unsigned long hv = iHASH((unsigned char *) temp->stats->name);
+
+       temp->stats->client = NULL;
+       players[hv].insertAtBack(temp);
        delete temp;
        delete temp;
-       cout << "Deleted" << endl;
     }
 delete [] buf;
     }
 delete [] buf;
+infile.close();
+return 1;
 }
 
 bool passcmp(char *encrypted, char *plaintext)
 }
 
 bool passcmp(char *encrypted, char *plaintext)
@@ -1787,14 +2211,42 @@ void do_store(char *u)
     char *item = strtok(NULL, " ");
     char *num = strtok(NULL, " ");
     char *space;
     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");
 
     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;
     }
     }
-    else if (stricmp(cmd, "LIST") == 0)
+    else if (!(user = find(u)))
+    {
+       log("Fatal Error: could not find %s in client list", u);
+       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 use the store!");
+       return;
+    }
+    else if (!isAlive(user->stats))
+    {
+       notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
+       return;
+    }
+    updateTS(user->stats);
+
+    if (stricmp(cmd, "LIST") == 0)
     {
        if (stricmp(item, "WEAPONS") == 0)
        {
     {
        if (stricmp(item, "WEAPONS") == 0)
        {
@@ -1826,5 +2278,1143 @@ void do_store(char *u)
 
        }
     } else if (stricmp(cmd, "BUY") == 0) {
 
        }
     } else if (stricmp(cmd, "BUY") == 0) {
-    }
+       if (!num)
+       {
+           notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
+           return;
+       }
+       else if (!isstringnum(num))
+       {
+           notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
+           return;
+       }
+       if (stricmp(item, "WEAPON") == 0)
+        {
+            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;
+            }
+
+           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
+            {
+                notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
+                p->weapon = wep;
+                p->gold -= prices[wep - 1];
+            }
+        }
+       else if (stricmp(item, "ARMOR") == 0)
+        {
+            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;
+            }
+
+           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
+            {
+                notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
+                p->armor = wep;
+                p->gold -= prices[wep - 1];
+            }
+        }
+    }
+    else if (stricmp(cmd, "SELL" ) == 0)
+    {
+       p = user->stats;
+
+        if (stricmp(item, "WEAPON") == 0)
+        {
+            if (p->weapon == 0)
+            {
+                notice(s_GameServ, u, "You want me to chop off your hands?");
+                return;
+            }
+            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;
+            }
+            else if (2000000000 - p->gold < (prices[p->weapon - 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;
+            }
+            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;
+            }
+        }
+        else if (stricmp(item, "ARMOR") == 0)
+        {
+           p = user->stats;
+
+            if (p->armor == 0)
+            {
+                notice(s_GameServ, u, "I don't think you can be any more naked...");
+                return;
+            }
+            if (p->gold == 2000000000)
+            {
+                notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
+                p->armor = 0;
+            }
+            else if (2000000000 - p->gold < (prices[p->armor - 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;
+            }
+            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;
+            }
+       }
+        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");
+       }
+    }
+    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)
+{
+    aClient *user;
+
+    if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
+       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 check your inventory!");
+       return;
+    }
+    updateTS(user->stats);
+    showinventory(user, user);
+}
+void showinventory(aClient *from, aClient *to)
+{
+    char *nick = to->getNick();
+
+    if (!to)
+       to = from;
+    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());
+    }
+}
+void do_tavern(char *u)
+{
+    char *cmd = strtok(NULL, " ");
+    long int price;
+
+    aClient *user;
+    Player *p;
+
+    if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
+       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 go to the Tavern");
+       return;
+    }
+    else if (is_fighting(user))
+    {
+       notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
+       return;
+    }
+
+    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?");
+    }
+    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", 
+                                       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!");
+    }
+    else if (stricmp(cmd, "BUY") == 0)
+    {
+       char *chnum = strtok(NULL, " ");
+       int num = stringtoint(chnum);
+
+       if (!chnum)
+       {
+           notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
+           notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
+           return;
+       }
+       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", 
+                                       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)
+       {
+           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
+    {
+       notice(s_GameServ, u, "Improper Syntax.");
+       notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
+    }
+}
+
+void do_bank(char *u)
+{
+    char *cmd = strtok(NULL, " ");
+    char *amount = strtok(NULL, " ");
+    char *nick = strtok(NULL, " ");
+
+    aClient *user;
+    Player *p;
+
+    if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
+    {
+       notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
+       notice (s_GameServ, u, "BANK BALANCE");
+       return;
+    }
+    else if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
+                               " admin for help");
+       log("Fatal Error. Couldn't find %s while executing do_bank()", u);
+       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 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)
+    {
+        showBankBalance(u);
+        return;
+    }
+    else if (!isAlive(user->stats))
+    {
+       notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
+       return;
+    }
+    else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
+    {
+        notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
+        return;
+    }
+
+    p = user->stats;
+
+    if (stricmp(cmd, "DEPOSIT") == 0)
+    {
+        if (p->bank == 2000000000)
+        {
+            notice(s_GameServ, u, "Your bank account is full, sire!");
+            return;
+        }
+        else if (stricmp(amount, "ALL") == 0)
+        {
+            if (2000000000 - p->bank < p->gold)
+            {
+                notice(s_GameServ, u, "You don't have enough room for all of your gold.");
+                notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
+                p->gold -= (2000000000 - p->bank);
+                p->bank = 2000000000;
+               showBankBalance(u);
+            }
+            else
+            {
+                notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
+                p->bank += p->gold;
+                p->gold = 0;
+               showBankBalance(u);
+            }
+        }
+        else if (stringtoint(amount) > p->gold)
+        {
+            notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
+           showBankBalance(u);
+            return;
+        }
+        else
+        {
+            if (2000000000 - p->bank < stringtoint(amount))
+            {
+                notice(s_GameServ, u, "You don't have room in your account for that much.");
+                notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
+                p->gold -= (2000000000 - p->bank);
+                p->bank = 2000000000;
+               showBankBalance(u);
+            }
+            else
+            {
+                notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
+                p->bank += stringtoint(amount);
+                p->gold -= stringtoint(amount);
+               showBankBalance(u);
+            }
+        }
+    }
+    else if (stricmp(cmd, "WITHDRAW") == 0)
+    {
+        if (p->gold == 2000000000)
+        {
+            notice(s_GameServ, u, "You cannot carry any more gold, sire!");
+           showBankBalance(u);
+            return;
+        }
+        else if (stricmp(amount, "ALL") == 0)
+        {
+            if (2000000000 - p->gold < p->bank)
+            {
+                notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
+                notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
+                p->bank -= (2000000000 - p->gold);
+                p->gold = 2000000000;
+               showBankBalance(u);
+            }
+            else
+            {
+                notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
+                p->gold += p->bank;
+                p->bank = 0;
+               showBankBalance(u);
+            }
+        }
+        else if (stringtoint(amount) > p->bank)
+        {
+            notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
+           showBankBalance(u);
+            return;
+        }
+        else
+        {
+            if (2000000000 - p->gold < stringtoint(amount))
+            {
+                notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
+                notice(s_GameServ, u, "You fill your pockets with %ld gold!",
+                        (2000000000 - p->gold));
+                p->bank -= (2000000000 - p->gold);
+                p->gold = 2000000000;
+               showBankBalance(u);
+            }
+            else
+            {
+                notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
+                p->gold += stringtoint(amount);
+                p->bank -= stringtoint(amount);
+               showBankBalance(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, ""));
+       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 fight the dragon!");
+       return;
+    }
+    else if (is_fighting(user))
+    {
+       notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
+       return;
+    }
+    else if (!isAlive(user->stats))
+    {
+       notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
+       return;
+    }
+    else if (user->stats->level < REALLEVELS)
+    {
+       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;
+    p->fight = new Monster(boss);
+    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.");
+    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!");
+    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;
+
+    if (seenMaster(p))
+    {
+       notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
+       return;
+    }
+
+    if (cmd != NULL)
+    {
+       switch(p->level)
+       {
+           case 1:
+               need = 200;
+               break;
+           case 2:
+               need = 800;
+               break;
+           case 3:
+               need = 2000;
+               break;
+           case 4:
+               need = 8000;
+               break;
+           case 5:
+               need = 20000;
+               break;
+           case 6:
+               need = 80000;
+               break;
+           case 7:
+               need = 200000;
+               break;
+           case 8:
+               need = 800000;
+               break;
+           case 9:
+               need = 2000000;
+               break;
+           case 10:
+               need = 8000000;
+               break;
+           case 11:
+               need = 20000000;
+               break;
+
+           case REALLEVELS:
+               need = p->exp + 1;
+               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!
+               break;
+       }   
+    }
+    else
+    {
+       notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
+       return;
+    }
+
+    if (stricmp(cmd, "FIGHT") == 0)
+    {
+       if (p->exp >= need)
+       {
+           setMaster(p);
+           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));
+       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);
+       else
+           notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
+
+       return;
+    }
+    else
+    {
+       notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
+    }
+}
+
+void see_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; 
+    }
+
+    if (!is_fighting(user) && is_playing(user))
+    {
+       Player *p = user->stats;
+       p->master = new Monster(masters[p->level - 1]);
+       p->fight = p->master;
+       display_monster(u);  // Since master is the same structure, use this function
+    }
+}
+
+void showBankBalance(const char *u)
+{
+    aClient *user;
+    Player *p;
+
+    if (!(user = find(u)))
+        return;
+
+    p = user->stats;
+
+    if (!p)
+       return;
+
+    notice(s_GameServ, u, "Account Balance: %ld     Gold On hand: %ld", p->bank, p->gold);
+
+}
+
+void refreshall()
+{
+    ListNode <aClient> *it;
+    Player *p;
+   for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
+   {
+    it = players[x].First();
+
+    while (it)
+    {
+       p = it->getData()->stats;
+       refresh(p);
+       it = it->Next();
+    }
+   }
+}
+
+void refresh(Player *p)
+{
+    if (!p)
+       return;
+
+    if (p->hp < p->maxhp)
+       p->hp = p->maxhp;
+    p->forest_fights = forestfights;
+    p->player_fights = 3;
+    setAlive(p);
+    clearMaster(p);
+}
+
+void do_refresh(char *u)
+{
+    char *nick = strtok(NULL, " ");
+    aClient *user;
+
+    if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
+       log("Error: aClient not found: %s", u);
+       return;
+    }
+    else if (isIgnore(user))
+    {
+       #ifdef DEBUGMODE
+           log("Ignoring %s.", user->getNick());
+       #endif
+       return;
+    }
+    else if (!isAdmin(user))
+    {
+       notice(s_GameServ, u, "You must be a %S admin to use this command!");
+       return;
+    }
+    if (!nick)
+    {
+       notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
+       return;
+    }
+    else if (stricmp(nick, "ALL") == 0)
+    {
+       notice(s_GameServ, u, "Refreshing everyone's stats!");
+       refreshall();
+    }
+    else if ((user = findplayer(nick)))
+    {
+       if (is_playing(user))
+       {
+           #ifdef P10
+           notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
+           #else
+           notice(s_GameServ, u, "Refreshing %s.", user->getNick());
+           #endif
+           refresh(user->stats);
+       }
+       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
+       }
+    }
+    else
+    {
+       notice(s_GameServ, u, "Nick %s not found.", nick);
+       return;
+    }
+}
+
+
+void resetall()
+{
+    ListNode <aClient> *it;
+    Player *p;
+
+   for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
+   {
+    it = players[x].First();
+
+    while (it)
+    {
+       p = it->getData()->stats;
+       reset(p);
+       it = it->Next();
+    }
+   }
+}
+
+void reset(Player *p)
+{
+    if (!p)
+       return;
+
+    p->reset();
+}
+
+void updateTS(Player *p)
+{
+    if (!p)
+       return;
+
+    #ifdef DEBUGMODE
+        log("Old timestamp for %s: %ld", p->name, p->lastcommand);
+    #endif
+    p->lastcommand = time(NULL);
+    #ifdef DEBUGMODE
+        log("New timestamp for %s: %ld", p->name, p->lastcommand);
+    #endif
+
+}
+
+bool timedOut(Player *p)
+{
+    if (!p)
+       return false;
+    else if (p->lastcommand == 0)
+       return false;
+    else
+    {
+       if ((time(NULL) - p->lastcommand) >= maxidletime)
+           return true;
+
+           return false;
+    }
+}
+
+void timeOutEvent(Player *p)
+{
+    aClient *user = findplayer(p->name);
+
+    if (!user || !p->client) // then they're not playing
+       return;
+
+    char *nick = user->getNick();
+
+    if (player_fight(user) && isYourTurn(p))
+    {
+       // Check to see if they were the idler or if it was the other 
+       // person
+       if (p->lastcommand != p->battle->stats->lastcommand)
+       {
+           // This person's last command was given earlier,
+           // so this person is the idler
+           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);
+           clearYourTurn(p);
+           setYourTurn(p->battle->stats);
+
+           // Update the TS for both players to give them another
+           // Chance to wake up, but if the other player doesn't
+           // Attack now, they both get logged out.
+           updateTS(p);
+           p->battle->stats->lastcommand = p->lastcommand;
+           display_players(p->battle);
+           return;
+       }
+       else
+       {
+           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);
+           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);
+           logout(p->battle);
+           logout(user);
+           return;
+       }
+    }
+    else if (!player_fight(user))
+    {
+      if (isAlive(user->stats) && user->stats->gold > 0)
+      {
+       // Place fun stuff here :)
+       int randnum = 1 + rand() % 100; // 1-100
+       #define GSN(s) notice(s_GameServ, nick, s)
+       #define GSN2(s, f) notice(s_GameServ, nick, s, f)
+
+        if (randnum < 50)
+        {
+           // 35-100% of your gold goes pffft - kain
+           int stolen = (35 + (rand() % 66)) * user->stats->gold / 100;
+           
+           GSN("You stop for a moment to rest on the "\
+            "street corner. All of a sudden, you "\
+            "are ambushed from all sides by a hoarde "\
+            "of knife wielding thugs.");
+           GSN2("The thugs beat you into utter submission "\
+           "and steal %d gold from you!", stolen);
+           user->stats->gold -= stolen;
+       }
+       else if (randnum >= 50 && randnum < 75)
+       {
+           // 25-65% of your gold goes pffft - kain
+           int stolen = (25 + (rand() % 41)) * user->stats->gold / 100;
+           GSN("While dilly dallying around, you lose "\
+           "your sense of time. Little did you know, "\
+           "but thieves lifted your gold while you "\
+           "weren't watching.");
+           GSN2("Better luck next time... you lose %d gold", stolen);
+           user->stats->gold -= stolen;
+       }
+       else if (randnum >= 75)
+       {
+           // 25-75% of your gold goes pffft - kain
+           int stolen = (25 + (rand() % 51)) * user->stats->gold / 100;
+           GSN("Good grief! A gaggle of gooey green ghostlike "\
+               "goblins grabbed your gold!");
+           GSN2("They stole %d gold from you!", stolen);
+           user->stats->gold -= stolen;
+       }
+      }
+
+       // Always log out the user
+       logout(user);
+    }
+}
+
+void do_reset(char *u)
+{
+    char *nick = strtok(NULL, " ");
+    aClient *user;
+
+    if (!(user = find(u)))
+    {
+       notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
+       log("Error: aClient not found: %s", u);
+       return;
+    }
+    else if (!isAdmin(user))
+    {
+       notice(s_GameServ, u, "You must be a %S admin to use this command!");
+       return;
+    }
+
+    if (!nick)
+    {
+       notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
+       return;
+    }
+    else if (stricmp(nick, "ALL") == 0)
+    {
+       notice(s_GameServ, u, "Resetting everyone's stats!");
+       resetall();
+    }
+    else if ((user = findbyrealnick(nick)))
+    {
+       if (is_playing(user))
+       {
+           #ifdef P10
+           notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
+           #else
+           notice(s_GameServ, u, "Resetting %s.", user->getNick());
+           #endif
+           reset(user->stats);
+       }
+       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
+       }
+    }
+    else
+    {
+       notice(s_GameServ, u, "Nick %s not found.", nick);
+       return;
+    }
+}
+
+void do_help(char *u)
+{
+    char *cmd = strtok(NULL, " ");
+
+    display_help(u, cmd);
+}
+
+void display_help(char *u, char *file)
+{
+    ifstream infile;
+    char *buf;
+
+    if (!file)
+    {
+       infile.open("helpfiles/help");
+       if (infile.fail())
+       {
+           log("Error opening helpfiles/help");
+           notice(s_GameServ, u, "Error opening helpfiles/help");
+           return;
+       }
+       buf = new char[1024];
+       while(infile.getline(buf, 1024))
+       {
+           // Written this way, it will process %S in the helpfiles
+           // Instead of notice(s_GameServ, u, "%s", buf);
+               notice(s_GameServ, u, buf);
+       }
+
+       // Minor recursion
+       aClient *user = find(u);
+       if (user && isAdmin(user))
+           display_help(u, "admin_commands");
+    }
+    else
+    {
+       char *filename;
+       filename = new char[strlen(file) + 11];
+       strcpy(filename, "helpfiles/");
+       strcat(filename, file);
+
+       for (unsigned int x = 10; x < strlen(filename); x++)
+           filename[x] = tolower(filename[x]);
+
+       infile.open(filename);
+       delete [] filename;
+       if (infile.fail())
+       {
+           notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
+           return;
+       }
+       buf = new char[1024];
+       while(infile.getline(buf, 1024))
+       {
+           // Written this way, it will process %S in the helpfiles
+           // Instead of notice(s_GameServ, u, "%s", buf);
+           notice(s_GameServ, u, buf);
+       }
+    }
+    infile.close();
+    delete [] buf;
+}
+
+void do_admin(char *u)
+{
+    aClient *user;
+    char *pass = strtok(NULL, " ");
+
+    if (!(user = find(u)))
+    {
+       log("Error: aClient not found: %s", u);
+       notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
+       return;
+    }
+
+    if (!pass)
+    {
+       notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
+       return;
+    }
+
+    if (isAdmin(user))
+    {
+       notice(s_GameServ, u, "You already have administrator privledges.");
+       return;
+    }
+    else if (strcmp(pass, adminpass) == 0)
+    {
+       notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
+       setAdmin(user);
+       #ifdef P10
+       log("%s became an administrator.", user->getRealNick());
+       #else
+       log("%s became an administrator.", user->getNick());
+       #endif
+    }
+    else
+    {
+       notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
+       return;
+    }
+}
+
+bool load_monsters()
+{
+    ifstream infile;
+    infile.open("monsters.dat");
+
+    char *buf;
+
+    if (infile.fail())
+    {
+       log("Error opening monsters.dat");
+       return false;
+    }
+    init_monsters();
+    buf = new char[2048];
+
+    #ifdef DEBUGMODE
+       log("Loading monsters from monsters.dat");
+    #endif
+
+  for (int l = 0; l < REALLEVELS; l++)
+  {
+    for (int m = 0; m < MONSTERS;)
+    {
+       infile.getline(buf, 2048);
+       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++;
+       }
+    }
+  }
+    delete [] buf;
+return true;
 }
 }