X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/ad7dfaa0a894de4dce5ed73deba7dd9edb85b55c..6370e3da091b0fd12c3ed4904410ce27854d357f:/gameserv/gameserv.cpp diff --git a/gameserv/gameserv.cpp b/gameserv/gameserv.cpp index 546692b..536afaf 100644 --- a/gameserv/gameserv.cpp +++ b/gameserv/gameserv.cpp @@ -1,27 +1,46 @@ -#include "sockhelp.h" #include "aClient.h" -#include "list.h" +#include "config.h" #include "extern.h" +#include "flags.h" +#include "list.h" +#include "sockhelp.h" + #include -#include +#include + +using std::ifstream; +using std::ofstream; +using std::ios; + +#if defined(HAVE_CRYPT_H) + #include -List players; -Monster monsters[5][12]; -Monster masters[12]; +#elif defined(HAVE_UNISTD_H) + +#include + +#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 -#undef strtok +#ifndef HAVE_STRTOK 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 - /********** 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 **********/ +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 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 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(aClient *user); + bool master_fight(char *u); // True if the player is fighting their master. +bool master_fight(aClient *user); /********** GameServ Booleans **********/ - +void display_help(char *u, char *file = NULL); 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); -void init_masters(); -void refresh(aClient *ni); +void refresh(Player *p); void refreshall(); -void reset(aClient *ni); +void updateTS(Player *p); +void reset(Player *p); +void init_masters(); 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_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_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_visit(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 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", @@ -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"}; -char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor", +char *armors[WNA] = { "Birthday Suit", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor", "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit", "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor", - "Hades' Cloak", "Dragon Scales", "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 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}; - void gameserv(char *source, char *buf) { - char *cmd, input[1024]; + char *cmd, z; 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, " "); @@ -119,42 +186,154 @@ void gameserv(char *source, char *buf) 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, "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, "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, "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, "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) { + do_help(source); } 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) { - 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) { - 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) { - 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) @@ -180,14 +359,12 @@ void showstats(const char *u, const char *nick) 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, 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(), "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]); @@ -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; + 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; - } char *spaces(int len, char *seperator) { char *final; - final = new char[40]; + final = new char[30]; int y; strcpy(final, seperator); - for (y = 0; y < 40 - len; y++) + for (y = 0; y < 30 - len; y++) 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"); - cout << "input: " << input << flush; 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, ...) { + 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; @@ -281,11 +497,23 @@ void notice(const char *source, const char *dest, const char *fmt, ...) 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 - 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++) { @@ -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"); - cout << "input: " << input << flush; sock_puts(sock, input); + delete [] commanduse; delete [] input; va_end(args); } @@ -331,6 +562,7 @@ int strnicmp(const char *s1, const char *s2, size_t len) return 1; } +#ifndef HAVE_STRTOK 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; } +#endif 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 *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) { - 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(); } - notice(s_GameServ, u, "End of List"); } - else + } + if (!header) 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 *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) { - char *password; + char *password, *name; aClient *user; + name = strtok(NULL, " "); 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[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 *temp; 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 { @@ -407,635 +817,248 @@ void do_identify(char *u) aClient *user, *p; name = strtok(NULL, " "); password = strtok(NULL, " "); - 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 (!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 *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 *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; - aClient *source; + aClient *user; 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); } + 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() { - // 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) @@ -1056,19 +1079,26 @@ void display_monster(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: %d", ni->stats->hp); - notice(s_GameServ, u, "%s's Hitpoints: %d", 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: %d", user->stats->hp); + notice(s_GameServ, u, "%s's Hitpoints: %d", battle->stats->name, battle->stats->hp); 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?"); } } @@ -1078,42 +1108,66 @@ bool is_playing(char *u) { aClient *user; if (!(user = find(u))) - { return false; - } 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; } - 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 - return false; + return true; } -bool player_fight(char *u) +bool is_fighting(char *u) { aClient *user; if (!(user = find(u))) return false; - else if (user->stats) - return user->stats->battle != NULL; 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; + else if (user->stats->battle != NULL) + { + return user->stats->battle->stats != NULL; + } + return false; } bool master_fight(char *u) @@ -1122,15 +1176,16 @@ bool master_fight(char *u) if (!(user = find(u))) return false; - else if (user->stats) - return user->stats->master != NULL; 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) @@ -1142,51 +1197,375 @@ void do_fight(char *u) if (!nick) { notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER"); + return; } else if (!(ni = find(u))) { + notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); 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!"); + 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 - battle->stats->battle = ni; + ni->stats->battle->stats->battle = ni; // 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! - 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 %s 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 %s like a little baby!", p2->name); + notice(s_GameServ, p->battle->getNick(), "%s 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 %s decides what to do.", p2->name); + } + else if (master_fight(user)) + { + notice(s_GameServ, u, "You cannot run from %s! 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, "%s attacks with their %s for %d 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 killed 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) @@ -1196,11 +1575,23 @@ void do_attack(char *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; } - 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; @@ -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 } + updateTS(ni->stats); - if (!player_fight(u)) + if (!player_fight(ni)) { // 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])); } - if (!player_fight(u)) + if (!player_fight(ni)) { if (hit > 0) notice(s_GameServ, u, "You attack %s for %d points!", fight->name, hit); @@ -1251,8 +1643,13 @@ void do_attack(char *u) if (hit >= fight->hp) { - if (master_fight(u)) + if (master_fight(ni)) + { 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 %s!", 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); + 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 - ni->stats->level++; // 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]; + ni->stats->level++; + // 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 @@ -1302,7 +1707,7 @@ void do_attack(char *u) fight->hp -= hit; if (mhit > 0) { - notice(s_GameServ, u, "%s hits you with their %s for %d damage!", + notice(s_GameServ, u, "%s attacks with their %s for %d damage!", fight->name, fight->weapon, mhit); } else if (mhit <= 0) @@ -1310,20 +1715,26 @@ void do_attack(char *u) if (mhit >= ni->stats->hp) { - if (!master_fight(u)) + if (!master_fight(ni)) { notice(s_GameServ, u, "You have been killed 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->hp = 0; 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); + addNews(todaysnews, "%s tried to best %s and failed!", + ni->stats->name, fight->name); 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)) @@ -1424,41 +1835,37 @@ void do_attack(char *u) } * 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!", - battle->getNick()); + battle->stats->name); return; } if (hit > 0) { - notice(s_GameServ, u, "You attack %s for %d points!", battle->getNick(), hit); + notice(s_GameServ, u, "You attack %s for %d points!", battle->stats->name, hit); notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\ - "%d damage!", u, weapons[ni->stats->weapon], - hit); - ni->stats->yourturn = 0; - battle->stats->yourturn = 1; - display_players(battle->getNick()); + "%d damage!", ni->stats->name, + weapons[ni->stats->weapon], hit); } else { - notice(s_GameServ, u, "You miss %s 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 %s completely!", battle->stats->name); + notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name); } + if (hit >= battle->stats->hp) { - notice(s_GameServ, u, "You have killed %s!", battle->getNick()); + notice(s_GameServ, u, "You have killed %s!", battle->stats->name); notice(s_GameServ, u, "You recieve %d experience and %ld gold!", (long int)(battle->stats->exp * .10), battle->stats->gold); - notice(s_GameServ, battle->getNick(), "You have been killed by %s!", u); + notice(s_GameServ, battle->getNick(), "You have been killed by %s!", + ni->stats->name); battle->stats->hp = 0; - battle->stats->alive = 0; + clearAlive(battle->stats); 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 "\ - "gold.", u); + "gold.", ni->stats->name); notice(s_GameServ, battle->getNick(), "Luckily, you still have %ld 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; @@ -1499,17 +1908,17 @@ void do_attack(char *u) { 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!", - battle->getNick()); - + battle->stats->name); return; } } } } + 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 | #}"); + 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!"); + 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!"); + return; } 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) @@ -1587,7 +2019,7 @@ void do_heal(char *u) 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) @@ -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--) - { sum += chartoint(number[x]) * pow(10, abs(x - len + 1)); - } return sum; } @@ -1627,40 +2057,15 @@ return value; 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() { - ListNode *ptr = players.First(); + ListNode *ptr; Player *it; ofstream outfile; @@ -1668,21 +2073,28 @@ int save_gs_dbase() if (!outfile) { - cerr << "Error opening " << playerdata << endl; + log("Error opening %s", playerdata); return 0; } + for (unsigned long x = 0; x < U_TABLE_SIZE; x++) + { + ptr = players[x].First(); 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 << ' ' - << it->armor << ' ' << it->weapon << ' ' << (it->alive ? "alive" : "dead") << ' ' + << it->armor << ' ' << it->weapon << ' ' << 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(); } + } outfile.close(); +return 1; } int load_gs_dbase() @@ -1690,32 +2102,24 @@ int load_gs_dbase() 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()) { - cerr << "Error opening " << playerdata << endl; + log("Error opening %s", playerdata); return 0; } while (infile.getline(buf, 1024, '\n')) { - cout << "temp = new aClient;" << endl << flush; temp = new aClient; - cout << "tempname = strtok(buf, " ");" << endl << flush; tempname = strtok(buf, " "); - - cout << "temp->stats = new Player(tempname);" << endl << flush; - temp->stats = new Player(tempname); - - cout << "p = temp->stats;" << endl << flush; 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, " ")); @@ -1726,25 +2130,45 @@ int load_gs_dbase() 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->setFlags(stringtoint(strtok(NULL, " "))); + 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; - cout << "Deleted" << endl; } delete [] buf; +infile.close(); +return 1; } 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; + int wep; + aClient *user; + Player *p; if (!cmd || !item) { notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}"); notice(s_GameServ, u, " STORE SELL {ARMOR | WEAPON}"); notice(s_GameServ, u, " STORE BUY {ARMOR | WEAPON} NUMBER"); + 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) { @@ -1826,5 +2278,1143 @@ void do_store(char *u) } } else if (stricmp(cmd, "BUY") == 0) { - } + if (!num) + { + notice(s_GameServ, u, "SYNTAX: STORE BUY {ARMOR | WEAPON} NUMBER"); + 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, " STORE SELL {ARMOR | WEAPON}"); + notice(s_GameServ, u, " STORE BUY {ARMOR | WEAPON} NUMBER"); + } + } + else + { + notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}"); + notice(s_GameServ, u, " STORE SELL {ARMOR | WEAPON}"); + notice(s_GameServ, u, " STORE BUY {ARMOR | WEAPON} NUMBER"); + 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 *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 *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 %s", 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: ADMIN password"); + 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; }