]> jfr.im git - irc/gameservirc.git/blobdiff - gameserv/gameserv.cpp
Fixed a bug causing the dragon's stats to be displayed twice
[irc/gameservirc.git] / gameserv / gameserv.cpp
index 281c0576d7dd8a47bbe22f1aeb7d1895ebc7ac2c..8926afea894f02e69bf2a0c7060f613854ee213f 100644 (file)
@@ -24,7 +24,6 @@ using std::ios;
 #endif
 
 
-Monster boss;                          // The boss monster
 Level levels[LEVELS];                  // The newest way to store monsters
 
 // Database functions
@@ -68,6 +67,9 @@ bool player_fight(aClient *user);
 bool master_fight(char *u); // True if the player is fighting their master.
 bool master_fight(aClient *user);
 
+bool dragon_fight(char *u); // True if the player is fighting the dragon.
+bool dragon_fight(aClient *user);
+
 /********** GameServ Booleans **********/
 
 void display_help(char *u, char *file = NULL);
@@ -108,6 +110,7 @@ void do_play(char *u);
 void do_quitg(char *u);
 void do_reset(char *u);
 void do_run(char *u);
+void do_set(char *u);
 void do_stats(char *u);
 void do_store(char *u);
 void do_tavern(char *u);
@@ -214,6 +217,8 @@ void gameserv(char *source, char *buf)
        do_identify(source);
     } else if (stricmp(cmd, "HELP") == 0) {
        do_help(source);
+    } else if (stricmp(cmd, "SET") == 0) {
+       do_set(source);
     } else if (stricmp(cmd, "STATS") == 0) {
        do_stats(source);
     } else if (stricmp(cmd, "SHUTDOWN") == 0) {
@@ -648,6 +653,455 @@ void do_list(char *u)
        notice(s_GameServ, u, "End of List");
 
 }
+void do_set(char *u)
+{
+  aClient *user, *target;
+  char *name = strtok(NULL, " ");
+  char *cmd = strtok(NULL, " ");
+  char *cmd2;
+  
+  if (!(user = find(u)))
+    {
+      notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
+            "Buf: %s LOGOUT", u);
+      return;
+    }
+  else if (isIgnore(user))
+    {
+#ifdef DEBUGMODE
+      log("Ignoring %s.", user->getNick());
+#endif
+      return;
+    }
+  else if (!name)
+    {
+      notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|WEAPON|ARMOR|HP POTIONS|STRENGTH POTIONS|DEFENSE POTIONS|HEALING POTIONS|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
+      return;
+    }
+  else if (!(target = findplayer(name)))
+    {
+      // Back the pointers up... they didn't send a name probably
+      cmd2= cmd;
+      cmd = name;
+      target = user;
+
+      if (!is_playing(user))
+       {
+         notice(s_GameServ, u, "You must be playing to set things for yourself!");
+         return;
+       }
+    }
+  else
+    {
+      cmd2 = strtok(NULL, " ");
+    }
+
+  // Regardless of the previous if/else, if it got here, we know we have the cmd pointer at the right spot.
+  if (stricmp(cmd, "PASSWORD") == 0)
+    {
+      // Person is looking to change their password
+      // If they're an admin, or it's theirself, allow it
+      // cmd2 is pointing to the password now
+      if (isAdmin(user) || user == target)
+       {
+         target->stats->setPassword(cmd2);
+         notice(s_GameServ, u, "Password successfully changed");
+       }
+      else if (user != target && !isAdmin(user))
+       {
+         notice(s_GameServ, u, "You must be a %S admin to set other peoples' passwords.");
+         return;
+       }
+    }
+  else if (stricmp(cmd, "BANK") == 0 || stricmp(cmd, "BALANCE") == 0)
+    {
+        if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+       else if (stricmp(cmd, "BANK") == 0)
+       {
+         cmd2 = strtok(NULL, " "); // Need an extra parameter for set bank balance
+       }
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] [BANK] BALANCE <NUMBER>");
+           return;
+       }
+
+       target->stats->bank = stringtoint(cmd2);
+       notice(s_GameServ, u, "Bank balance changed to %s!", cmd2);
+    }
+  else if (stricmp(cmd, "PLAYER") == 0)
+    {
+      if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+      else if (stricmp(cmd2, "FIGHTS") != 0)
+       {
+         notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
+         return;
+       }
+      else
+       {
+         cmd2 = strtok(NULL, " ");
+           if (!cmd2)
+           {
+               notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
+               return;
+           }
+         target->stats->player_fights = stringtoint(cmd2);
+         notice(s_GameServ, u, "Player fights changed to %s!", cmd2);
+       }         
+    }
+  else if (stricmp(cmd, "FOREST") == 0)
+    {
+      if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+      else if (stricmp(cmd2, "FIGHTS") != 0)
+       {
+         notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <number>");
+         return;
+       }
+      else
+       {
+         cmd2 = strtok(NULL, " ");
+           if (!cmd2)
+           {
+               notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <NUMBER>");
+               return;
+           }
+         target->stats->forest_fights = stringtoint(cmd2);
+         notice(s_GameServ, u, "Forest fights changed to %s!", cmd2);
+       }         
+    }
+  else if (stricmp(cmd, "GOLD") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] GOLD <NUMBER>");
+           return;
+       }
+         target->stats->gold = stringtoint(cmd2);
+         notice(s_GameServ, u, "Gold set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "STRENGTH") == 0 && stricmp(cmd2, "POTIONS") != 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] STRENGTH <NUMBER>");
+           return;
+       }
+
+         target->stats->strength = stringtoint(cmd2);
+         notice(s_GameServ, u, "Strength set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "DEFENSE") == 0 && stricmp(cmd2, "POTIONS") != 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] DEFENSE <NUMBER>");
+           return;
+       }
+
+         target->stats->defense = stringtoint(cmd2);
+         notice(s_GameServ, u, "Defense set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "HP") == 0 && stricmp(cmd2, "POTIONS") != 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HP <NUMBER>");
+           return;
+       }
+         target->stats->hp = stringtoint(cmd2);
+         notice(s_GameServ, u, "HP set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "MAXHP") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] MAXHP <NUMBER>");
+           return;
+       }
+         target->stats->maxhp = stringtoint(cmd2);
+         notice(s_GameServ, u, "MaxHP set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "EXPERIENCE") == 0 || stricmp(cmd, "EXP") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {EXPERIENCE|EXP} <NUMBER>");
+           return;
+       }
+
+         target->stats->exp = stringtoint(cmd2);
+         notice(s_GameServ, u, "Exp set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "LEVEL") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] LEVEL <NUMBER>");
+           return;
+       }
+         target->stats->level = stringtoint(cmd2);
+         notice(s_GameServ, u, "Level set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "WEAPON") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] WEAPON <NUMBER>");
+           return;
+       }
+
+         target->stats->weapon = stringtoint(cmd2);
+         notice(s_GameServ, u, "Weapon set to %s", weapons[target->stats->weapon]);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "ARMOR") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] ARMOR <NUMBER>");
+           return;
+       }
+         target->stats->armor = stringtoint(cmd2);
+         notice(s_GameServ, u, "Armor set to %s", armors[target->stats->armor]);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "HP") == 0 && stricmp(cmd2, "POTIONS") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+         cmd2 = strtok(NULL, " ");
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HP POTIONS <NUMBER>");
+           return;
+       }
+         target->stats->inventory.setHP(stringtoint(cmd2));
+         notice(s_GameServ, u, "HP Potions set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "HEALING") == 0 && stricmp(cmd2, "POTIONS") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+         cmd2 = strtok(NULL, " ");
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HEALING POTIONS <NUMBER>");
+           return;
+       }
+         target->stats->inventory.setHealing(stringtoint(cmd2));
+         notice(s_GameServ, u, "Healing Potions set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "STRENGTH") == 0 && stricmp(cmd2, "POTIONS") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+         cmd2 = strtok(NULL, " ");
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] STRENGTH POTIONS <NUMBER>");
+           return;
+       }
+         target->stats->inventory.setStrength(stringtoint(cmd2));
+         notice(s_GameServ, u, "Strength Potions set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "DEFENSE") == 0 && stricmp(cmd2, "POTIONS") == 0)
+  {
+    if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;         
+       }
+    else
+       {
+         cmd2 = strtok(NULL, " ");
+       if (!cmd2)
+       {
+           notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] DEFENSE POTIONS <NUMBER>");
+           return;
+       }
+         target->stats->inventory.setDefense(stringtoint(cmd2));
+         notice(s_GameServ, u, "Defense Potions set to %s", cmd2);
+         return;
+       }
+  }
+  else if (stricmp(cmd, "ALIVE") == 0)
+  {
+     if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+     else
+       {
+         cmd2 = strtok(NULL, " ");
+         if (!cmd2 || (stricmp(cmd2, "TRUE") != 0 && stricmp(cmd2, "FALSE") != 0))
+         {
+            notice(s_GameServ, u, "SYNTAX: /msg %S SET ALIVE TRUE|FALSE");
+            return;
+         }
+         else if (stricmp(cmd2, "TRUE") == 0)
+         {
+            notice(s_GameServ, u, "Target has been Resurrected!");
+            target->addFlag(FLAG_ALIVE);
+         }
+         else
+         {
+            notice(s_GameServ, u, "Target is now dead!");
+            target->remFlag(FLAG_ALIVE);
+         }
+       }
+  }
+  else if (stricmp(cmd, "SEEN") == 0)
+    {
+      if (!isAdmin(user))
+       {
+         notice(s_GameServ, u, "Admins Only!");
+         return;
+       }
+      else if (stricmp(cmd2, "MASTER") != 0)
+       {
+         notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] SEEN MASTER {TRUE|FALSE}");
+         return;
+       }
+      else
+       {
+         cmd2 = strtok(NULL, " ");
+         if (!cmd2 || (stricmp(cmd2, "TRUE") != 0 && stricmp(cmd2, "FALSE") != 0))
+         {
+            notice(s_GameServ, u, "SYNTAX: /msg %S SET [NICK] SEEN MASTER {TRUE|FALSE}");
+            return;
+         }
+         else if (stricmp(cmd2, "TRUE") == 0)
+         {
+            notice(s_GameServ, u, "Target has seen their master now.");
+            target->addFlag(FLAG_MASTER);
+         }
+         else
+         {
+            notice(s_GameServ, u, "Target has not seen their master now.");
+            target->remFlag(FLAG_MASTER);
+         }
+       }         
+    }
+  else
+  {
+     notice(s_GameServ, u, "Unknown command: SET %s", cmd);
+     notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|WEAPON|ARMOR|HP POTIONS|STRENGTH POTIONS|DEFENSE POTIONS|HEALING POTIONS|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
+     return;
+  }
+}
 
 void do_logout(char *u)
 {
@@ -764,13 +1218,6 @@ void do_register(char *u)
     name = strtok(NULL, " ");
     password = strtok(NULL, " ");
 
-    static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
-    static char salt[3];
-    
-    salt[0] = saltChars[rand() % strlen(saltChars)];
-    salt[1] = saltChars[rand() % strlen(saltChars)];
-    salt[2] = '\0';
-
     if (!name)
     {
        notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
@@ -803,7 +1250,7 @@ void do_register(char *u)
            user->stats = new Player(user);
            user->stats->client = user; // Set the backwards pointer
            user->stats->reset(); // set the user up
-           user->stats->password = crypt(password, salt);
+           user->stats->setPassword(password);
            user->stats->name = name;
            unsigned long hv = iHASH((unsigned char *) name);
            updateTS(user->stats);
@@ -988,7 +1435,7 @@ bool load_masters()
 
     delete []buf;
 
-    if (l < LEVELS - 1)  // We didn't load a master for every level - check data/masters.dat
+    if (l < LEVELS)  // We didn't load a master for every level - check data/masters.dat
        return false;
     else
        return true;
@@ -1127,6 +1574,22 @@ bool master_fight(aClient *user)
        return user->stats->master != NULL;
 }
 
+bool dragon_fight(char *u)
+{
+    aClient *user;
+    if (!(user = find(u)))
+       return false;
+    else
+       return dragon_fight(user);
+}
+
+bool dragon_fight(aClient *user)
+{
+    if (!is_playing(user))
+       return false;
+    else
+       return (user->stats->level == LEVELS && master_fight(user));
+}
 void do_fight(char *u)
 {
     aClient *ni, *battle;
@@ -1593,7 +2056,7 @@ void do_attack(char *u)
 
     if (hit >= fight->hp)
     {
-        if (master_fight(ni))
+        if (master_fight(ni) && !dragon_fight(ni))
        {
             notice(s_GameServ, u, "You have bested %s!", fight->name.c_str());
            addNews(todaysnews, "%s has bested %s and moved "\
@@ -1607,6 +2070,14 @@ void do_attack(char *u)
         notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
                  fight->exp, fight->gold);
 
+       if (dragon_fight(ni))
+       {
+           addNews(todaysnews, "%s is a true warrior! %s has beaten %s!!", 
+               ni->stats->name.c_str(), ni->stats->name.c_str(), 
+               ni->stats->master->name.c_str());
+           ni->stats->master = NULL; // Don't progress in levels
+       }
+
        // If your new experience (or gold) will be greater than 2 billion,
        // then set your exp to 2bil. (2 billion max)... otherwise add them.
        // This could be a problem with overflowing out of the sign bit.
@@ -2761,7 +3232,7 @@ void do_dragon(char *u)
        notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
        return;
     }
-    else if (user->stats->level < REALLEVELS)
+    else if (user->stats->level < LEVELS)
     {
        notice(s_GameServ, u, "You fool! Only those strong enough "\
                "to vanquish any foe should DARE fight the dragon!");
@@ -2773,7 +3244,7 @@ void do_dragon(char *u)
     updateTS(user->stats);
 
     Player *p = user->stats;
-    p->fight = new Monster(&boss);
+    setMaster(p);
     notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
     notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
        "deep, red fog rolls in. The air is filled with the "\
@@ -2782,7 +3253,8 @@ void do_dragon(char *u)
     notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
        "your %s, and venture into the hot, dark cave. "\
        "You are surprised at the angle of descent as you climb "\
-       "lower and lower, deeper into the dragon's den.");
+       "lower and lower, deeper into the dragon's den.", 
+       armors[p->armor], weapons[p->weapon]);
     notice(s_GameServ, u, "You come to the end of the cave to find "\
        "a tooth. It is a large tooth... bigger than your torso."\
        " Suddenly the darkness lifts from the gleam of an eye "\
@@ -2790,7 +3262,7 @@ void do_dragon(char *u)
     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);
+    see_master(u);
 }
 
 void do_master(char *u)