]> jfr.im git - irc/gameservirc.git/blobdiff - gameserv/gameserv.cpp
Fixed bug # 998029 causing a crash on gentoo systems due to a mistake in code:
[irc/gameservirc.git] / gameserv / gameserv.cpp
index 33237acad3e307101bd62678c3e46e6270435bf0..d1b50f7ab84013cf67b543fb66c3947aac7502ad 100644 (file)
@@ -3,6 +3,7 @@
 #include "extern.h"
 #include "flags.h"
 #include "list.h"
+#include "level.h"
 #include "sockhelp.h"
 
 #include <cctype>
@@ -23,8 +24,8 @@ using std::ios;
 #endif
 
 
-Monster *monsters[LEVELS][MONSTERS];   // Monsters per level. Total = MONSTERS * LEVELS
 Monster boss;                          // The boss monster
+Level levels[LEVELS];                  // The newest way to store monsters
 
 Monster *masters[LEVELS];              // A master for each level
 
@@ -54,7 +55,7 @@ bool check_password(char *name, char *plaintext); // Finds a password for the gi
 
 bool shuttingdown;
 bool timedOut(Player *p);
-void  updateTS(Player *p);
+void updateTS(Player *p);
 void timeOutEvent(Player *p);
 
 bool is_playing(char *u); // True if the given nickname in the clients list is playing.
@@ -86,14 +87,15 @@ void refreshall();
 void updateTS(Player *p);
 void reset(Player *p);
 void init_masters();
-void init_monsters();
 bool load_monsters();
+bool load_levels();
 void delete_monsters();
 void delete_masters();
 
 void do_admin(char *u);
 void do_attack(char *u);
 void do_bank(char *u);
+void do_check(char *u);
 void do_fight(char *u);
 void do_heal(char *u);
 void do_help(char *u);
@@ -158,22 +160,6 @@ void gameserv(char *source, char *buf)
        log("Source: %s  Command: %s", source, cmd);
     #endif
 
-    struct tm *tm;
-    time_t ti;
-    time(&ti);
-    tm = localtime(&ti);
-
-    int curday = tm->tm_mday;
-
-    if (curday != day)
-    {
-        refreshall();
-       clearNews(todaysnews);
-       saveNews(newsdata, todaysnews);
-        day = curday;
-       save_day(); // here i come to save the day!
-    }
-
     if (strnicmp(cmd, "\1PING", 6) == 0)
     {
        char *ts;
@@ -193,6 +179,8 @@ void gameserv(char *source, char *buf)
        do_fight(source);
     } else if (stricmp(cmd, "ATTACK") == 0) {
        do_attack(source);
+    } else if (stricmp(cmd, "CHECK") == 0) {
+       do_check(source);
     } else if (stricmp(cmd, "RUN") == 0) {
        do_run(source);
     } else if (stricmp(cmd, "USE") == 0) {
@@ -315,6 +303,14 @@ void gameserv(char *source, char *buf)
            char *rest = strtok(NULL, "");
            raw("%s", rest);
        }
+    } else if (stricmp(cmd, "PRINT") == 0) {
+       for (int x = 0; x < LEVELS; x++)
+           levels[x].monsters.print();
+    } else if (stricmp(cmd, "RANDOM") == 0) {
+       char *rstr = strtok(NULL, "");
+       range trange;
+       trange.setRange(rstr);
+       notice(s_GameServ, source, "Random number in that range: %d", trange.random());
     #endif
     } else {
        aClient *user;
@@ -587,6 +583,20 @@ char *strtok(char *str, const char *delim)
 }
 #endif
 
+void do_check(char *u)
+{
+    int days, hours, minutes, seconds;
+    long complete;
+    complete = (lastrefresh + refreshperiod) - time(NULL);
+    days = complete / 86400;
+    hours = (complete % 86400) / 3600;
+    minutes = (complete % 86400) % 3600 / 60;
+    seconds = (complete % 86400) % 3600 % 60;
+
+    notice(s_GameServ, u, "Time left to next refresh: %dd %dh %dm %ds", 
+          days, hours, minutes, seconds);
+}
+
 void do_list(char *u)
 {
     aClient *user;
@@ -615,7 +625,7 @@ void do_list(char *u)
     {
        while(temp)
        {
-           if (!cmd || is_playing(temp->getData()))
+           if (cmd || is_playing(temp->getData()))
            {
                if (!header)
                {
@@ -803,6 +813,9 @@ void do_register(char *u)
            temp = players[hv].insertAtBack_RLN(user);
            temp->setPtr(user); // This is an extra step, but necessary for now
 
+           // Update the last login time
+           user->stats->lastlogin = time(NULL);
+
            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);
@@ -878,6 +891,10 @@ void do_identify(char *u)
        setPlaying(user); // set the playing flag
 
        temp->setPtr(user);
+
+       // Update the last login time
+       user->stats->lastlogin = time(NULL);
+
        notice(s_GameServ, u, "Password Accepted. Identified.");
        showNews(u, todaysnews);
     }
@@ -1037,25 +1054,10 @@ void init_masters()
     strcpy(masters[10]->death, "You must learn to concentrate. It is like a finger pointing away to the moon... DONT concentrate on the finger, or you will miss all the heavenly glory.");
 }
 
-void init_monsters()
-{
-    #ifdef DEBUGMODE
-       log("Calling delete_monsters");
-    #endif
-
-    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];
+       levels[x].monsters.deleteNodes();
 }
 
 void delete_masters()
@@ -1676,12 +1678,13 @@ void do_attack(char *u)
        // then set your exp to 2bil. (2 billion max)... otherwise add them.
        // This could be a problem with overflowing out of the sign bit.
        // Unsigned long int maybe? Leave it for now.
-        ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 : 
-                               ni->stats->exp + fight->exp);
-
-        ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 : 
-                               ni->stats->gold + fight->gold);
+       ni->stats->exp += fight->exp;
+       if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
+           ni->stats->exp = 2000000000;
 
+       ni->stats->gold += fight->gold;
+       if (ni->stats->gold < 0 || ni->stats->gold > 2000000000)
+           ni->stats->gold = 2000000000;
 
         if (master_fight(ni))
         {
@@ -1882,16 +1885,11 @@ void do_attack(char *u)
         battle->stats->hp = 0;
         clearAlive(battle->stats);
 
-        if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
-        {
-            ni->stats->exp += (long int)(battle->stats->exp * .10);
-            battle->stats->exp -= (long int)(battle->stats->exp * .10);
-        }
-        else
-        {
-            battle->stats->exp -= (long int)(battle->stats->exp * .10);
+        ni->stats->exp += (long int)(battle->stats->exp * .10);
+        battle->stats->exp -= (long int)(battle->stats->exp * .10);
+
+        if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
             ni->stats->exp = 2000000000;
-        }
 
         if (2000000000 - ni->stats->gold > battle->stats->gold)
         {
@@ -1913,6 +1911,7 @@ void do_attack(char *u)
 
             ni->stats->gold = 2000000000;
         }
+
        clearYourTurn(ni->stats);
        clearYourTurn(battle->stats);
        battle->stats->battle = NULL;
@@ -2104,7 +2103,8 @@ int save_gs_dbase()
                << it->armor << ' ' << it->weapon << ' '
                << it->forest_fights << ' ' << it->player_fights <<  ' ' 
                << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
-               << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
+               << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP()
+               << ' ' << it->lastlogin << endl;
        ptr = ptr->Next();
     }
    }
@@ -2188,6 +2188,13 @@ int load_gs_dbase()
        tempname = strtok(NULL, " ");
        if (tempname)
            p->inventory.setHP(stringtoint(tempname));
+
+        tempname = strtok(NULL, " ");
+       if (tempname)
+           p->lastlogin = stringtoint(tempname);
+       else
+           p->lastlogin = time(NULL);
+
        unsigned long hv = iHASH((unsigned char *) temp->stats->name);
 
        temp->stats->client = NULL;
@@ -2595,7 +2602,7 @@ void do_tavern(char *u)
                    notice(s_GameServ, u, "You don't have enough gold!");
                break;
            case 4:
-               price = 3000 * p->level * 4;
+               price = 2000 * p->level * 4;
                if (p->gold >= price)
                {
                    notice(s_GameServ, u, "One HP Potion coming right up!");
@@ -2828,7 +2835,7 @@ void do_dragon(char *u)
     updateTS(user->stats);
 
     Player *p = user->stats;
-    p->fight = new Monster(boss);
+    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 "\
@@ -2837,7 +2844,7 @@ 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->level - 1], weapons[p->level - 1]);
     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 "\
@@ -3120,10 +3127,15 @@ void resetall()
 
 void reset(Player *p)
 {
+    char *myname;
+    myname = new char[strlen(p->name)];
+    strcpy(myname, p->name);
     if (!p)
        return;
 
     p->reset();
+    strcpy(p->name, myname);
+    delete [] myname;
 }
 
 void updateTS(Player *p)
@@ -3279,7 +3291,7 @@ void do_reset(char *u)
        notice(s_GameServ, u, "Resetting everyone's stats!");
        resetall();
     }
-    else if ((user = findbyrealnick(nick)))
+    else if ((user = findplayer(nick)))
     {
        if (is_playing(user))
        {
@@ -3292,11 +3304,8 @@ void do_reset(char *u)
        }
        else
        {
-           #ifdef P10
-           notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
-           #else
-           notice(s_GameServ, u, "%s is not playing.", user->getNick());
-           #endif
+           notice(s_GameServ, u, "Resetting %s", user->stats->name);
+           reset(user->stats);
        }
     }
     else
@@ -3409,45 +3418,62 @@ void do_admin(char *u)
     }
 }
 
+bool load_levels()
+{
+    char *filename;
+    filename = new char[256];
+
+    for (int x = 1; x <= LEVELS; x++)
+    {
+       sprintf(filename, "data/levels/level%d.dat", x);
+       if (levels[x - 1].loadLevel(filename) == false)
+           return false;
+    }
+
+    delete []filename;
+    return true;
+}
 bool load_monsters()
 {
+    char *filename;
     ifstream infile;
-    infile.open("monsters.dat");
-
     char *buf;
+    buf = new char[2048];
 
-    if (infile.fail())
+  for (int level = 1; level <= LEVELS; level++)
+  {
+    filename = new char[256];
+    sprintf(filename, "data/monsters/level%d.dat", level);
+    infile.open(filename);
+
+    if (!infile)
     {
-       log("Error opening monsters.dat");
+       log("Error opening %s", filename);
        return false;
     }
-    init_monsters();
-    buf = new char[2048];
 
     #ifdef DEBUGMODE
-       log("Loading monsters from monsters.dat");
+       log("Loading monsters from %s", filename);
     #endif
 
-  for (int l = 0; l < REALLEVELS; l++)
-  {
-    for (int m = 0; m < MONSTERS;)
+    while (infile.getline(buf, 2048))
     {
-       infile.getline(buf, 2048);
+       if (buf[0] == '^')
+           break;
        if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
            continue;
-       else
-       {
-           strcpy(monsters[l][m]->name, strtok(buf, "~"));
-           strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
-           monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
-           monsters[l][m]->hp = monsters[l][m]->maxhp;
-           strcpy(monsters[l][m]->death, strtok(NULL, ""));
-           m++;
-       }
+       Monster *temp;
+       temp = new Monster;
+
+            strcpy(temp->name, strtok(buf, "~"));
+            strcpy(temp->weapon, strtok(NULL, "~"));
+            strcpy(temp->death, strtok(NULL, "~"));
+
+       levels[level - 1].monsters.insertAtBack_RLN(temp);
+       delete temp;
     }
+    delete [] filename;
+    infile.close();
   }
     delete [] buf;
 return true;