X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/c8ada07e2ac45fbb2aeee5fcdf25115ec8bf94f7..169c286a23bcef717a3034d0ab5693b92b6e68c9:/gameserv/gameserv.cpp diff --git a/gameserv/gameserv.cpp b/gameserv/gameserv.cpp index 878fcbe..8926afe 100644 --- a/gameserv/gameserv.cpp +++ b/gameserv/gameserv.cpp @@ -1,34 +1,47 @@ -#include "sockhelp.h" #include "aClient.h" -#include "list.h" +#include "config.h" #include "extern.h" +#include "flags.h" +#include "list.h" +#include "level.h" +#include "sockhelp.h" + #include -#include +#include + +using std::ifstream; +using std::ofstream; +using std::ios; + +#if defined(HAVE_CRYPT_H) + #include -#define LEVELS 5 // Number of character levels in the game -#define MONSTERS 12 // Monsters per level +#elif defined(HAVE_UNISTD_H) -List players; -Monster *monsters[LEVELS][MONSTERS]; // Monsters per level. Total = MONSTERS * LEVELS +#include -Monster *masters[LEVELS]; // A master for each level +#endif + + +Level levels[LEVELS]; // The newest way to store monsters // 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 +bool passcmp(const char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given. @@ -37,49 +50,78 @@ 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 **********/ +bool dragon_fight(char *u); // True if the player is fighting the dragon. +bool dragon_fight(aClient *user); +/********** GameServ Booleans **********/ +void display_help(char *u, char *file = NULL); 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 refresh(aClient *ni); +void refresh(Player *p); void refreshall(); -void reset(aClient *ni); -void init_masters(); -void init_monsters(); +void updateTS(Player *p); +void reset(Player *p); +bool load_masters(); +bool load_monsters(); +bool load_levels(); 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_check(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_set(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", @@ -87,37 +129,44 @@ 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) - cout << "Source: " << source << "\ncmd: " << cmd << endl; - if (strnicmp(cmd, ":\1PING", 6) == 0) + #ifdef DEBUGMODE + log("Source: %s Command: %s", source, cmd); + #endif + + 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, " "); @@ -125,46 +174,168 @@ 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, "CHECK") == 0) { + do_check(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, "BANK") == 0) { do_bank(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, "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, "NEWS") == 0) { + do_news(source); } else if (stricmp(cmd, "REGISTER") == 0) { do_register(source); } else if (stricmp(cmd, "IDENTIFY") == 0) { do_identify(source); } else if (stricmp(cmd, "HELP") == 0) { + do_help(source); + } else if (stricmp(cmd, "SET") == 0) { + do_set(source); } else if (stricmp(cmd, "STATS") == 0) { do_stats(source); } else if (stricmp(cmd, "SHUTDOWN") == 0) { - 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"); + 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); + } + } else if (stricmp(cmd, "PRINT") == 0) { + for (int x = 0; x < LEVELS; x++) + levels[x].monsters.print(); + } else if (stricmp(cmd, "RANDOM") == 0) { + char *rstr = strtok(NULL, ""); + range trange; + trange.setRange(rstr); + notice(s_GameServ, source, "Random number in that range: %d", trange.random()); + #endif + } else { + aClient *user; + 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) @@ -190,15 +361,13 @@ 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); + notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name.c_str()); sprintf(buf, "Experience: %ld", ni->stats->exp); space = spaces(strlen(buf), " "); @@ -211,7 +380,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]); @@ -230,18 +399,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.c_str()); } 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; } @@ -273,8 +459,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); @@ -283,6 +472,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; @@ -291,11 +499,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++) { @@ -316,9 +536,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); } @@ -341,6 +564,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; @@ -359,1776 +583,3312 @@ char *strtok(char *str, const char *delim) *current++ = 0; return ret; } +#endif -void do_list(char *u) +void do_check(char *u) { - ListNode *temp; - temp = players.First(); - if (!players.isEmpty()) - { - notice(s_GameServ, u, "People Playing:"); - while(temp) - { - notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(), temp->getData()->stats->name); - temp = temp->Next(); - } - notice(s_GameServ, u, "End of List"); - } - else - notice(s_GameServ, u, "No one is playing"); + int days, hours, minutes, seconds; + long complete; + complete = (lastrefresh + refreshperiod) - time(NULL); + days = complete / 86400; + hours = (complete % 86400) / 3600; + minutes = (complete % 86400) % 3600 / 60; + seconds = (complete % 86400) % 3600 % 60; + + notice(s_GameServ, u, "Time left to next refresh: %dd %dh %dm %ds", + days, hours, minutes, seconds); } -void do_register(char *u) + +void do_list(char *u) { - char *password; aClient *user; - password = strtok(NULL, " "); - - static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; - static char salt[3]; - - salt[0] = saltChars[rand() % strlen(saltChars)]; - salt[1] = saltChars[rand() % strlen(saltChars)]; - salt[3] = '\0'; + char *cmd = strtok(NULL, " "); - if (!password) + if (!(user = find(u))) { - notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER PASSWORD"); + log("Fatal Error: Couldn't find %s in the client list", u); + return; } - else if (user = find(u)) + else if (isIgnore(user)) { - if (!user->stats) - { - 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); - } - else - { - notice(s_GameServ, u, "Already registered. Contact a %S admin for help."); - } + #ifdef DEBUGMODE + log("Ignoring %s. Command LIST", user->getNick()); + #endif + return; } -} -void do_identify(char *u) -{ - char *password, *name; - aClient *user, *p; - name = strtok(NULL, " "); - password = strtok(NULL, " "); + ListNode *temp; + bool header = false; - if (!password || !name) - { - notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD"); - } - else if (!(p = findplayer(name)) || !p->stats) - notice(s_GameServ, u, "Player %s not found", name); - else if (!check_password(name, password)) - { - notice(s_GameServ, u, "Password incorrect"); - } - else if (user = find(u)) + for (unsigned long x = 0; x < U_TABLE_SIZE; x++) + { + temp = players[x].First(); + if (!players[x].isEmpty()) { - if (!user->stats) - { - ListNode *temp; - temp = players.Find(p); - if (!temp) + while(temp) + { + if (cmd || is_playing(temp->getData())) { - notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s", - strtok(NULL, "")); - return; + 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.c_str()); + #else + notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(), + temp->getData()->stats->name.c_str()); + #endif } - user->stats = new Player(p->stats->name); - cout << "Setting data for identified" << endl; - user->stats->setData(p->stats); - cout << "Player Identified" << endl << flush; - - temp->setPtr(user); - notice(s_GameServ, u, "Password Accepted. Identified."); - - } - else - { - notice(s_GameServ, u, "Already identified. Contact a %S admin for help."); + temp = temp->Next(); } } -} - -void do_stats(char *u) -{ - char *nick; - aClient *source; - - nick = strtok(NULL, " "); - source = find(u); - - if (!nick) - showstats(u, source->getNick()); + } + if (!header) + notice(s_GameServ, u, "No one is playing"); else - showstats(u, nick); -} -void init_masters() -{ - //delete_masters(); - - 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 = 30; - masters[0]->gold = 0; - masters[0]->exp = 0; - masters[0]->maxhp = 30; - 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 = 57; - masters[1]->gold = 0; - masters[1]->exp = 0; - masters[1]->maxhp = 40; - 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 = 85; - masters[2]->gold = 0; - masters[2]->exp = 0; - masters[2]->maxhp = 70; - 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 = 100; - masters[3]->gold = 0; - masters[3]->exp = 0; - masters[3]->maxhp = 120; - 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, "Drunken Boxing"); - masters[4]->strength = 125; - masters[4]->maxhp = 200; - masters[4]->gold = 0; - masters[4]->exp = 0; - 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 = 150; - masters[5]->maxhp = 400; - masters[5]->gold = 0; - masters[5]->exp = 0; - 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 = 175; - masters[6]->maxhp = 600; - masters[6]->gold = 0; - masters[6]->exp = 0; - 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 = 200; - masters[7]->maxhp = 800; - masters[7]->gold = 0; - masters[7]->exp = 0; - 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 = 275; - masters[8]->maxhp = 1200; - masters[8]->gold = 0; - masters[8]->exp = 0; - 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 = 350; - masters[9]->maxhp = 1800; - masters[9]->gold = 0; - masters[9]->exp = 0; - strcpy(masters[9]->death, "Hiccup!"); - - strcpy(masters[10]->name, "Bruce Lee"); - strcpy(masters[10]->weapon, "Fists of fury"); - masters[10]->strength = 575; - masters[10]->maxhp = 2500; - masters[10]->gold = 0; - masters[10]->exp = 0; - 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() -{ - delete_monsters(); - for (int x = 0; x < LEVELS; x++) - for (int y = 0; y < MONSTERS; y++) - monsters[x][y] = new Monster(); - - // Hard coded for now - Kain - - strcpy(monsters[0][0]->name, "Slime"); - strcpy(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; - strcpy(monsters[0][0]->death, "The slime oozes into nothing... you clean the acid goo off of your weapon"); - - strcpy(monsters[0][1]->name, "Ghost"); - strcpy(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; - strcpy(monsters[0][1]->death, "You feel a chill as the spirit leaves the realm."); - - strcpy(monsters[0][2]->name, "Ugly Rodent"); - strcpy(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; - strcpy(monsters[0][2]->death, "You stomp on the Ugly Rodent's remains for a finishing blow."); - - strcpy(monsters[0][3]->name, "Whart Hog"); - strcpy(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; - strcpy(monsters[0][3]->death, "You cook and eat the hog for good measure!"); - - strcpy(monsters[0][4]->name, "Pesky Kid"); - strcpy(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; - strcpy(monsters[0][4]->death, "You take his slingshot and snap the band, sending the kid crying home to mom!"); - - strcpy(monsters[0][5]->name, "Playground Bully"); - strcpy(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; - strcpy(monsters[0][5]->death, "You give him an indian burn, and punt him across the schoolyard!"); - - strcpy(monsters[0][6]->name, "Small Imp"); - strcpy(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; - strcpy(monsters[0][6]->death, "You can't help but laugh as he stumbles and falls onto his own dagger!"); - - strcpy(monsters[0][7]->name, "Little Monkey"); - strcpy(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; - strcpy(monsters[0][7]->death, "You want to cook it, but you just can't think of eating something that looks so human!"); - - strcpy(monsters[0][8]->name, "Grub Worm"); - strcpy(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; - strcpy(monsters[0][8]->death, "You decide to save the poor little fella for your next fishing trip."); - - strcpy(monsters[0][9]->name, "Drakee"); - strcpy(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; - strcpy(monsters[0][9]->death, "You pull the little Drakee by its tale and slam it down on a dry stump!"); - - strcpy(monsters[0][10]->name, "Fat Slob"); - strcpy(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; - strcpy(monsters[0][10]->death, "You kick his stomach for fun, and are thrown back by the spring of it all!"); - - strcpy(monsters[0][11]->name, "Lost Warrior"); - strcpy(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; - strcpy(monsters[0][11]->death, "You give him a proper burial in respect for the dead warrior."); - - strcpy(monsters[1][0]->name, "Lost Warrior's Cousin Larry"); - strcpy(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; - strcpy(monsters[1][0]->death, "He was pretty pissed you killed his cousin, but he seems to have suffered the same fate!"); - - strcpy(monsters[1][1]->name, "Sandman"); - strcpy(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; - strcpy(monsters[1][1]->death, "You put the sandman to his final sleep."); - - strcpy(monsters[1][2]->name, "Dirty Prostitute"); - strcpy(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; - strcpy(monsters[1][2]->death, "Your pimp hand is strong!"); - - strcpy(monsters[1][3]->name, "Goblin Gardener"); - strcpy(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; - strcpy(monsters[1][3]->death, "You trample on his garden after slaying him... that felt good!"); - - strcpy(monsters[1][4]->name, "Evil Elf"); - strcpy(monsters[1][4]->weapon, "Dark Bow"); - monsters[1][4]->strength = 23; - monsters[1][4]->gold = 136; - monsters[1][4]->exp = 13; - monsters[1][4]->maxhp = 24; - strcpy(monsters[1][4]->death, "Elves are usually nice you thought... hmm."); - - strcpy(monsters[1][5]->name, "Viking Warrior"); - strcpy(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; - strcpy(monsters[1][5]->death, "You heard vikings were big, but not THAT big you thought."); - - strcpy(monsters[1][6]->name, "Wicked Witch"); - strcpy(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; - strcpy(monsters[1][6]->death, "Just for kicks, you splash some water on her and watch her melt."); - - strcpy(monsters[1][7]->name, "Vampire Bat"); - strcpy(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; - strcpy(monsters[1][7]->death, "You fry up the bat and eat it... needs garlic."); - - strcpy(monsters[1][8]->name, "Thorn Bush"); - strcpy(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; - strcpy(monsters[1][8]->death, "You set the bush ablaze and roast some marshmallows."); - - strcpy(monsters[1][9]->name, "Barbarian"); - strcpy(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; - strcpy(monsters[1][9]->death, "You listen to him moan as he falls over dead."); - - strcpy(monsters[1][10]->name, "Crypt Rat"); - strcpy(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; - strcpy(monsters[1][10]->death, "You squash the little rodent for fear that it might not be dead."); - - strcpy(monsters[1][11]->name, "Small Orc"); - strcpy(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; - strcpy(monsters[1][11]->death, "It's an ugly one, and it would've grown up to be a terror..."); - - strcpy(monsters[2][0]->name, "Teferi"); - strcpy(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; - strcpy(monsters[2][0]->death, "It was a puzzling experience."); - - strcpy(monsters[2][1]->name, "Spineless Thug"); - strcpy(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; - strcpy(monsters[2][1]->death, "See you at the crossroads!"); - - strcpy(monsters[2][2]->name, "Pyromaniac"); - strcpy(monsters[2][2]->weapon, "Flame Thrower"); - monsters[2][2]->strength = 29; - monsters[2][2]->gold = 563; - monsters[2][2]->exp = 22; - monsters[2][2]->maxhp = 45; - strcpy(monsters[2][2]->death, "He chants FIRE FIRE as he falls to the ground... a burning heap of flesh."); - - strcpy(monsters[2][3]->name, "Evil Enchantress"); - strcpy(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; - strcpy(monsters[2][3]->death, "She looked just about as good as she fought."); - - strcpy(monsters[2][4]->name, "Killer Leprechaun"); - strcpy(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; - strcpy(monsters[2][4]->death, "You steal his pot of gold... that's a lot of money!"); - - strcpy(monsters[2][5]->name, "Avalanche Rider"); - strcpy(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; - strcpy(monsters[2][5]->death, "You take his snowboard and snap it in two!"); - - strcpy(monsters[2][6]->name, "Blundering Idiot"); - strcpy(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; - strcpy(monsters[2][6]->death, "Now there's one person you don't feel sorry for killing!"); - - strcpy(monsters[2][7]->name, "Militant Anarchist"); - strcpy(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; - strcpy(monsters[2][7]->death, "Order has been restored for now..."); - - strcpy(monsters[2][8]->name, "Scathe Zombies"); - strcpy(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; - strcpy(monsters[2][8]->death, "That was perhaps the scariest experience of your life."); - - strcpy(monsters[2][9]->name, "Spitting Llama"); - strcpy(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; - strcpy(monsters[2][9]->death, "You wipe the spit off your face and fling it back at the Llama."); - - strcpy(monsters[2][10]->name, "Juggalo"); - strcpy(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; - strcpy(monsters[2][10]->death, "What is a Juggalo? I don't know!"); - - strcpy(monsters[2][11]->name, "The Boogie Man"); - strcpy(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; - strcpy(monsters[2][11]->death, "He's scared you for the very last time!"); - - strcpy(monsters[3][0]->name, "Living Fire"); - strcpy(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; - strcpy(monsters[3][0]->death, "You extinguish the Living Flame once and for all!"); - - strcpy(monsters[3][1]->name, "Raging Orc"); - strcpy(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; - strcpy(monsters[3][1]->death, "This orc was a bit tougher than you remembered!"); - - strcpy(monsters[3][2]->name, "Huge Tarantula"); - strcpy(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; - strcpy(monsters[3][2]->death, "You're glad you overcame your arachniphobia so soon!"); - - strcpy(monsters[3][3]->name, "Rabid Wolf"); - strcpy(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; - strcpy(monsters[3][3]->death, "The mutt falls over dead as white foam drips from its deadly canines..."); - - strcpy(monsters[3][4]->name, "Goblin Fighter"); - strcpy(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; - strcpy(monsters[3][4]->death, "He almost caught you with his chain mace, but you sliced off his head."); - - strcpy(monsters[3][5]->name, "Grizzly Bear"); - strcpy(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; - strcpy(monsters[3][5]->death, "It almost got you this time... better be careful"); - - strcpy(monsters[3][6]->name, "Skeleton Man"); - strcpy(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; - strcpy(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!"); - - strcpy(monsters[3][7]->name, "Young Werewolf"); - strcpy(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; - strcpy(monsters[3][7]->death, "You scatter the wolf's body parts in hopes he will stay dead!"); - - strcpy(monsters[3][8]->name, "Dark Infantry"); - strcpy(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; - strcpy(monsters[3][8]->death, "Light has prevailed this time... but it's only so long before you meet again."); - - strcpy(monsters[3][9]->name, "Erie Spirit"); - strcpy(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; - strcpy(monsters[3][9]->death, "His cousin the ghost was a little bit easier."); - - strcpy(monsters[3][10]->name, "Gollum"); - strcpy(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; - strcpy(monsters[3][10]->death, "Gollum screams out \"MY PRECIOUS\" as his small body falls limp from your blow."); - - strcpy(monsters[3][11]->name, "Rock Fighter"); - strcpy(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; - strcpy(monsters[3][11]->death, "You dodge his last rock, and counter with a low blow, cutting off his legs."); - - - strcpy(monsters[4][0]->name, "Giant Sphinx"); - strcpy(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; - strcpy(monsters[4][0]->death, "You look in awe at the great wonder, collapsed at your feet!"); - - strcpy(monsters[4][1]->name, "Giant Ogre"); - strcpy(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; - strcpy(monsters[4][1]->death, "Your wits outmatched the ogre's brawn... big dumb thing."); - - strcpy(monsters[4][2]->name, "Massive Cockroach"); - strcpy(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; - strcpy(monsters[4][2]->death, "Where's the exterminator when you need one?"); - - strcpy(monsters[4][3]->name, "Big Venomous Snake"); - strcpy(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; - strcpy(monsters[4][3]->death, "After killing this beast you check for puncture marks... you find none, luckily."); - - strcpy(monsters[4][4]->name, "Lizard Man"); - strcpy(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; - strcpy(monsters[4][4]->death, "His scales made for tough armor, and his jaws for a tougher opponent!"); - - strcpy(monsters[4][5]->name, "Face Dancer"); - strcpy(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; - strcpy(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!"); - - strcpy(monsters[4][6]->name, "Darklord Longbow Archer"); - strcpy(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; - strcpy(monsters[4][6]->death, "Your face turns white with horror after you realize you just met the devil's protector!"); - - strcpy(monsters[4][7]->name, "Hell's Paladin"); - strcpy(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; - strcpy(monsters[4][7]->death, "This is starting to get tough you think. Do you really want to go to level 6?"); - - strcpy(monsters[4][8]->name, "The Unknown Soldier"); - strcpy(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; - strcpy(monsters[4][8]->death, "Who was that? Where was he from? And what was that weapon??"); - - strcpy(monsters[4][9]->name, "Undead Cult Leader"); - strcpy(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; - strcpy(monsters[4][9]->death, "His words fall on deaf ears... this is one cult you will NOT be part of!"); - - strcpy(monsters[4][10]->name, "Water Serpent"); - strcpy(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; - strcpy(monsters[4][10]->death, "The serpent squeals as you cut off its head!"); - - strcpy(monsters[4][11]->name, "Silverback Gorilla"); - strcpy(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; - strcpy(monsters[4][11]->death, "Was that gorilla or guerilla?"); -} - -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]; -} + notice(s_GameServ, u, "End of List"); -void delete_masters() -{ - for (int x = 0; x < LEVELS; x++) - if (masters[x]) - delete masters[x]; } - -void display_monster(char *u) +void do_set(char *u) { - if (is_playing(u)) + aClient *user, *target; + char *name = strtok(NULL, " "); + char *cmd = strtok(NULL, " "); + char *cmd2; + + if (!(user = find(u))) { - aClient *user = find(u); - Player *ni = user->stats; - - notice(s_GameServ, u, "Your Hitpoints: %d", ni->hp); - notice(s_GameServ, u, "%s's Hitpoints: %d", ni->fight->name, ni->fight->hp); - notice(s_GameServ, u, "Here are your commands:"); - notice(s_GameServ, u, "/msg %S attack"); - notice(s_GameServ, u, "/msg %S run"); - notice(s_GameServ, u, "What will you do?"); + notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\ + "Buf: %s LOGOUT", u); + return; } -} - -void display_players(char *u) -{ - if (is_playing(u)) + else if (isIgnore(user)) { - 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); - - 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, "What will you do?"); +#ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); +#endif + return; } -} - - -bool is_playing(char *u) -{ - aClient *user; - if (!(user = find(u))) + else if (!name) { - return false; + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|WEAPON|ARMOR|HP POTIONS|STRENGTH POTIONS|DEFENSE POTIONS|HEALING POTIONS|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}"); + return; } - else + else if (!(target = findplayer(name))) + { + // Back the pointers up... they didn't send a name probably + cmd2= cmd; + cmd = name; + target = user; + + if (!is_playing(user)) + { + notice(s_GameServ, u, "You must be playing to set things for yourself!"); + return; + } + } + else { - return user->stats != NULL; + cmd2 = strtok(NULL, " "); } -} -bool is_fighting(char *u) -{ - aClient *user; + // Regardless of the previous if/else, if it got here, we know we have the cmd pointer at the right spot. + if (stricmp(cmd, "PASSWORD") == 0) + { + // Person is looking to change their password + // If they're an admin, or it's theirself, allow it + // cmd2 is pointing to the password now + if (isAdmin(user) || user == target) + { + target->stats->setPassword(cmd2); + notice(s_GameServ, u, "Password successfully changed"); + } + else if (user != target && !isAdmin(user)) + { + notice(s_GameServ, u, "You must be a %S admin to set other peoples' passwords."); + return; + } + } + else if (stricmp(cmd, "BANK") == 0 || stricmp(cmd, "BALANCE") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else if (stricmp(cmd, "BANK") == 0) + { + cmd2 = strtok(NULL, " "); // Need an extra parameter for set bank balance + } + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] [BANK] BALANCE "); + return; + } - if (!(user = find(u))) + target->stats->bank = stringtoint(cmd2); + notice(s_GameServ, u, "Bank balance changed to %s!", cmd2); + } + else if (stricmp(cmd, "PLAYER") == 0) { - return false; + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else if (stricmp(cmd2, "FIGHTS") != 0) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS "); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS "); + return; + } + target->stats->player_fights = stringtoint(cmd2); + notice(s_GameServ, u, "Player fights changed to %s!", cmd2); + } } - else if (user->stats) + else if (stricmp(cmd, "FOREST") == 0) { - return user->stats->fight != NULL || user->stats->battle != NULL - || user->stats->master != NULL; + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else if (stricmp(cmd2, "FIGHTS") != 0) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS "); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS "); + return; + } + target->stats->forest_fights = stringtoint(cmd2); + notice(s_GameServ, u, "Forest fights changed to %s!", cmd2); + } } + else if (stricmp(cmd, "GOLD") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } else - return false; -} - -bool player_fight(char *u) -{ - aClient *user; + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] GOLD "); + return; + } + target->stats->gold = stringtoint(cmd2); + notice(s_GameServ, u, "Gold set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "STRENGTH") == 0 && stricmp(cmd2, "POTIONS") != 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] STRENGTH "); + return; + } - if (!(user = find(u))) - return false; - else if (user->stats) - return user->stats->battle != NULL; + target->stats->strength = stringtoint(cmd2); + notice(s_GameServ, u, "Strength set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "DEFENSE") == 0 && stricmp(cmd2, "POTIONS") != 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } else - return false; -} + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] DEFENSE "); + return; + } -bool master_fight(char *u) -{ - aClient *user; + target->stats->defense = stringtoint(cmd2); + notice(s_GameServ, u, "Defense set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "HP") == 0 && stricmp(cmd2, "POTIONS") != 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HP "); + return; + } + target->stats->hp = stringtoint(cmd2); + notice(s_GameServ, u, "HP set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "MAXHP") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] MAXHP "); + return; + } + target->stats->maxhp = stringtoint(cmd2); + notice(s_GameServ, u, "MaxHP set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "EXPERIENCE") == 0 || stricmp(cmd, "EXP") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {EXPERIENCE|EXP} "); + return; + } - if (!(user = find(u))) - return false; - else if (user->stats) - return user->stats->master != NULL; + target->stats->exp = stringtoint(cmd2); + notice(s_GameServ, u, "Exp set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "LEVEL") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } else - return false; -} + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] LEVEL "); + return; + } + target->stats->level = stringtoint(cmd2); + notice(s_GameServ, u, "Level set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "WEAPON") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] WEAPON "); + return; + } -bool isnt_fighting(char *u) -{ - return !is_fighting(u); + target->stats->weapon = stringtoint(cmd2); + notice(s_GameServ, u, "Weapon set to %s", weapons[target->stats->weapon]); + return; + } + } + else if (stricmp(cmd, "ARMOR") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] ARMOR "); + return; + } + target->stats->armor = stringtoint(cmd2); + notice(s_GameServ, u, "Armor set to %s", armors[target->stats->armor]); + return; + } + } + else if (stricmp(cmd, "HP") == 0 && stricmp(cmd2, "POTIONS") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HP POTIONS "); + return; + } + target->stats->inventory.setHP(stringtoint(cmd2)); + notice(s_GameServ, u, "HP Potions set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "HEALING") == 0 && stricmp(cmd2, "POTIONS") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HEALING POTIONS "); + return; + } + target->stats->inventory.setHealing(stringtoint(cmd2)); + notice(s_GameServ, u, "Healing Potions set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "STRENGTH") == 0 && stricmp(cmd2, "POTIONS") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] STRENGTH POTIONS "); + return; + } + target->stats->inventory.setStrength(stringtoint(cmd2)); + notice(s_GameServ, u, "Strength Potions set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "DEFENSE") == 0 && stricmp(cmd2, "POTIONS") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] DEFENSE POTIONS "); + return; + } + target->stats->inventory.setDefense(stringtoint(cmd2)); + notice(s_GameServ, u, "Defense Potions set to %s", cmd2); + return; + } + } + else if (stricmp(cmd, "ALIVE") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2 || (stricmp(cmd2, "TRUE") != 0 && stricmp(cmd2, "FALSE") != 0)) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET ALIVE TRUE|FALSE"); + return; + } + else if (stricmp(cmd2, "TRUE") == 0) + { + notice(s_GameServ, u, "Target has been Resurrected!"); + target->addFlag(FLAG_ALIVE); + } + else + { + notice(s_GameServ, u, "Target is now dead!"); + target->remFlag(FLAG_ALIVE); + } + } + } + else if (stricmp(cmd, "SEEN") == 0) + { + if (!isAdmin(user)) + { + notice(s_GameServ, u, "Admins Only!"); + return; + } + else if (stricmp(cmd2, "MASTER") != 0) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] SEEN MASTER {TRUE|FALSE}"); + return; + } + else + { + cmd2 = strtok(NULL, " "); + if (!cmd2 || (stricmp(cmd2, "TRUE") != 0 && stricmp(cmd2, "FALSE") != 0)) + { + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NICK] SEEN MASTER {TRUE|FALSE}"); + return; + } + else if (stricmp(cmd2, "TRUE") == 0) + { + notice(s_GameServ, u, "Target has seen their master now."); + target->addFlag(FLAG_MASTER); + } + else + { + notice(s_GameServ, u, "Target has not seen their master now."); + target->remFlag(FLAG_MASTER); + } + } + } + else + { + notice(s_GameServ, u, "Unknown command: SET %s", cmd); + notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|WEAPON|ARMOR|HP POTIONS|STRENGTH POTIONS|DEFENSE POTIONS|HEALING POTIONS|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}"); + return; + } } -void do_fight(char *u) +void do_logout(char *u) { - aClient *ni, *battle; - - char *nick = strtok(NULL, " "); + aClient *user; + char *name = strtok(NULL, " "); - if (!nick) + if (!(user = find(u))) { - notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER"); + 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 (!(ni = find(u))) + else if (isIgnore(user)) { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif return; } - else if (!(battle = find(nick))) + + if (name) { - notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick); + 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.c_str()); + logout(user); + } } - else if (!is_playing(u)) + else if (!name) { - notice(s_GameServ, u, "You are not playing!"); + 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); + } } -/* - * 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)) - { - // 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; +void logout(aClient *user) +{ + if (is_playing(user)) + { + ListNode *it; + aClient *temp; + unsigned long hv = iHASH((unsigned char *) user->stats->name.c_str()); + it = players[hv].Find(user); - // The initiator gets the first move (perhaps this should be 50/50) - ni->stats->yourturn = 1; - battle->stats->yourturn = 0; + 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; + } - // 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); - } + 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_run(char *u) + +void do_register(char *u) { + char *password, *name; aClient *user; - Player *p, *p2; + name = strtok(NULL, " "); + password = strtok(NULL, " "); - if (!(user = find(u))) + if (!name) { - notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin"); - return; + notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD"); } - - p = user->stats; - - if (p->battle) - p2 = p->battle->stats; - - if (!is_fighting(u)) - notice(s_GameServ, u, "You run in place... try fighting next time."); - else if (!player_fight(u) && !master_fight(u)) + else if (!password) { - notice(s_GameServ, u, "You run away from %s like a little baby!", p->fight->name); - delete p->fight; - p->fight = NULL; + notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD"); } - else if (player_fight(u) && p->yourturn) + else if ((user = findplayer(name))) { - 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; + notice(s_GameServ, u, "%s is already registered!", name); + notice(s_GameServ, u, "Choose another name!"); } - else if (player_fight(u) && !p->yourturn) + else if (!(user = find(u))) { - notice(s_GameServ, u, "It is not your turn. Please wait until %s decides what to do.", p2->name); + log("Fatal Error: Couldn't find %s in the clients list", u); } - else if (master_fight(u)) + else if (isIgnore(user)) { - notice(s_GameServ, u, "You cannot run from %s! FIGHT!", p->master->name); + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } + else + { + if (!is_playing(user)) + { + ListNode *temp; + user->stats = new Player(user); + user->stats->client = user; // Set the backwards pointer + user->stats->reset(); // set the user up + user->stats->setPassword(password); + user->stats->name = name; + unsigned long hv = iHASH((unsigned char *) name); + updateTS(user->stats); + temp = players[hv].insertAtBack_RLN(user); + temp->setPtr(user); // This is an extra step, but necessary for now + + // Update the last login time + user->stats->lastlogin = time(NULL); + + notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name.c_str(), password); + notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!"); + log("Nickname %s registered player %s.", u, user->stats->name.c_str()); + setPlaying(user); // set the playing flag + } + else + { + notice(s_GameServ, u, "Already registered. Contact a %S admin for help."); + } } - p->battle = NULL; } -void do_attack(char *u) -{ - int hit, mhit; - aClient *ni, *battle; // The player and perhaps the player they're fighting - Monster *fight; // The monster they may be fighting - if (!(ni = find(u))) +void do_identify(char *u) +{ + char *password, *name; + aClient *user, *p; + name = strtok(NULL, " "); + password = strtok(NULL, " "); + if (!password || !name) { - notice(s_GameServ, u, "You're not playing!"); - return; + notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD"); } - else if (!ni->stats->fight && !ni->stats->battle && !ni->stats->master) + else if (!(user = find(u))) { - notice(s_GameServ, u, "You're not in battle!"); + 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 + else if (!(p = findplayer(name)) || !p->stats) + notice(s_GameServ, u, "Player %s not found", name); + else if (is_playing(user)) { - if (!ni->stats->master) // This is not a master fight - fight = ni->stats->fight; // Monster Could be NULL - else // This IS a master fight - fight = ni->stats->master; // Master Could be NULL - - battle = ni->stats->battle; // Player Could be NULL - - // One has to be !NULL based on the previous else if - // We wouldn't be here if they were all NULL + notice(s_GameServ, u, "You are already playing!"); } - - if (!player_fight(u)) + else if (p->stats->client != NULL && !isAdmin(user)) { - // Player's Hit - hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) + - (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2)); - - // Opponent's Hit - mhit = (fight->strength / 2) + - (rand() % (fight->strength / 2) - (ni->stats->defense + - arbonus[ni->stats->armor])); + notice(s_GameServ, u, "That player has already identified."); } - else + else if (!check_password(name, password) && !isAdmin(user)) { - // Opponent's Hit - mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) + - (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) - - (ni->stats->defense + arbonus[ni->stats->armor])); - - // Player's Hit - hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) + - (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) - - (battle->stats->defense + arbonus[battle->stats->armor])); + notice(s_GameServ, u, "Password incorrect"); } + else { + ListNode *temp; + unsigned long hv = iHASH((unsigned char *) p->stats->name.c_str()); + 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); - if (!player_fight(u)) - { - if (hit > 0) - notice(s_GameServ, u, "You attack %s for %d points!", fight->name, hit); - else - notice(s_GameServ, u, "You miss %s completely!", fight->name); - if (hit >= fight->hp) - { - if (master_fight(u)) - notice(s_GameServ, u, "You have bested %s!", fight->name); - else - notice(s_GameServ, u, "You have killed %s!", fight->name); + #ifdef DEBUGMODE + log("Player %s IRC: %s Identified", user->stats->name.c_str(), + user->getNick()); + #endif - notice(s_GameServ, u, "%s", fight->death); - notice(s_GameServ, u, "You recieve %d experience and %d gold!", - fight->exp, fight->gold); + setPlaying(user); // set the playing flag - // If your new experience (or gold) will be greater than 2 billion, - // then set your exp to 2bil. (2 billion max)... otherwise add them. - // This could be a problem with overflowing out of the sign bit. - // Unsigned long int maybe? Leave it for now. - ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 : - ni->stats->exp + fight->exp); - ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 : - ni->stats->gold + fight->gold); + temp->setPtr(user); - // They're dead so remove the pointer - delete ni->stats->fight; - ni->stats->fight = NULL; + // Update the last login time + user->stats->lastlogin = time(NULL); - if (master_fight(u)) - { - 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]); + notice(s_GameServ, u, "Password Accepted. Identified."); + showNews(u, todaysnews); + } +} + +void do_stats(char *u) +{ + char *nick; + aClient *user; + + nick = strtok(NULL, " "); + + 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.c_str()); + } + } + else + showstats(u, nick); +} + +bool load_masters() +{ + ifstream infile("data/masters.dat"); + char *buf; + int l = 0; + buf = new char[1024]; + + if (infile.fail()) + { + log("Error opening data/masters.dat"); + return false; + } + + #ifdef DEBUGMODE + log("Loading masters from data/masters.dat"); + #endif + + for (l = 0; l < LEVELS; l++) + { + infile.getline(buf, 1024, '\n'); + + log("%s", buf); + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') + { + l--; + continue; + } + else if (buf[0] == '^') + break; + + Monster *master = &levels[l].master; + + char *name, *weapon, *strength, *gold, *exp, *maxhp, *death; + + + name = strtok(buf, "~"); + weapon = strtok(NULL, "~"); + strength = strtok(NULL, "~"); + gold = strtok(NULL, "~"); + exp = strtok(NULL, "~"); + maxhp = strtok(NULL, "~"); + death = strtok(NULL, "~"); + + master->name = name; + master->weapon = weapon; + master->strength = stringtoint(strength); + master->gold = stringtoint(gold); + master->exp = stringtoint(exp); + master->maxhp = stringtoint(maxhp); + master->hp = master->maxhp; + master->death = death; + } + + delete []buf; + + if (l < LEVELS) // We didn't load a master for every level - check data/masters.dat + return false; + else + return true; +} + +void delete_monsters() +{ + for (int x = 0; x < LEVELS; x++) + levels[x].monsters.deleteNodes(); +} + +void display_monster(char *u) +{ + if (is_playing(u)) + { + aClient *user = find(u); + Player *ni = user->stats; + + notice(s_GameServ, u, "Your Hitpoints: %d", ni->hp); + notice(s_GameServ, u, "%s's Hitpoints: %d", ni->fight->name.c_str(), ni->fight->hp); + notice(s_GameServ, u, "Here are your commands:"); + notice(s_GameServ, u, "/msg %S attack"); + notice(s_GameServ, u, "/msg %S run"); + notice(s_GameServ, u, "What will you do?"); + } +} + +void display_players(char *u) +{ + aClient *user; + if (!(user = find(u))) + { + 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.c_str(), battle->stats->hp); + notice(s_GameServ, u, "Here are your commands:"); + notice(s_GameServ, u, "/msg %S attack"); + notice(s_GameServ, u, "/msg %S run"); + notice(s_GameServ, u, "What will you do?"); + } +} + + +bool is_playing(char *u) +{ + aClient *user; + if (!(user = find(u))) + return false; + else + return is_playing(user); +} + +bool is_playing(aClient *user) +{ + if (user->stats == NULL) + { + return false; + } + else if (user->stats->client == NULL) + { + return false; + } + else if (!FL_is_playing(user)) + { + return false; + } + else + return true; +} + +bool is_fighting(char *u) +{ + aClient *user; + + if (!(user = find(u))) + return false; + 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) +{ + aClient *user; + + if (!(user = find(u))) + return false; + else + return master_fight(user); +} + +bool master_fight(aClient *user) +{ + if (!is_playing(user)) + return false; + else + return user->stats->master != NULL; +} + +bool dragon_fight(char *u) +{ + aClient *user; + if (!(user = find(u))) + return false; + else + return dragon_fight(user); +} + +bool dragon_fight(aClient *user) +{ + if (!is_playing(user)) + return false; + else + return (user->stats->level == LEVELS && master_fight(user)); +} +void do_fight(char *u) +{ + aClient *ni, *battle; + + char *nick = strtok(NULL, " "); + + 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 (isIgnore(ni)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", ni->getNick()); + #endif + return; + } + 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.c_str()); + display_players(u); + } +*/ + else if (stricmp(ni->stats->name.c_str(), battle->stats->name.c_str()) == 0) + { + notice(s_GameServ, u, "Are you trying to commit suicide!?"); + } + 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.c_str(), battle->stats->battle->stats->name.c_str()); + } + else if (master_fight(battle)) + { + notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name.c_str()); + } + else if (is_fighting(battle)) + { + notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name.c_str(), battle->stats->fight->name.c_str()); + } + else if (ni->stats->level - battle->stats->level > maxbfightdistance) + { + // You can't fight someone below you by more than X level(s) + // level 12 can fight level (12 - X) but not < (12 - X) + notice(s_GameServ, u, "You may not fight %s. You're too strong!", + battle->stats->name.c_str()); + } + else if (battle->stats->level - ni->stats->level > maxafightdistance) + { + // You can't fight someone above you by more than X level(S) + // level 1 can fight level (1 + X), but not > (1 + X) + notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\ + "weakling!", ni->stats->name.c_str()); + } + else + { + // Set your battle pointer to the other player + ni->stats->battle = battle; + + // Set the other player's battle pointer to you + ni->stats->battle->stats->battle = ni; + + // The initiator gets the first move (perhaps this should be 50/50) + setYourTurn(ni->stats); + clearYourTurn(battle->stats); + + // Initiate Battle sequence! + ni->stats->player_fights -= 1; + + notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name.c_str()); + notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name.c_str()); + notice(s_GameServ, battle->getNick(), "%s gets to go first "\ + "because they initiated!", ni->stats->name.c_str()); + notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name.c_str()); + 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; + user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level; + if (user->stats->hp - user->stats->maxhp >= 100) + { + user->stats->hp = user->stats->maxhp + 100; + + if (oldhealing >= (user->stats->maxhp + 100)) + { + notice(s_GameServ, u, "You cannot hold anymore HP!"); + return; + } + } + + notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters."); + notice(s_GameServ, u, "Rejuvination spreads throughout your body."); + 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.c_str()); + 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.c_str()); + notice(s_GameServ, p->battle->getNick(), "%s ran away from you like a little baby!", p->name.c_str()); + p2->battle = NULL; + } + else if (player_fight(user) && !isYourTurn(p)) + { + notice(s_GameServ, u, "It is not your turn. Please wait until %s decides what to do.", p2->name.c_str()); + } + else if (master_fight(user)) + { + notice(s_GameServ, u, "You cannot run from %s! FIGHT!", p->master->name.c_str()); + } + 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.c_str(), fight->weapon.c_str(), mhit); + } + else if (mhit <= 0) + notice(s_GameServ, u, "%s completely misses you!", fight->name.c_str()); + + if (mhit >= user->stats->hp) + { + if (!master_fight(user)) + { + notice(s_GameServ, u, "You have been killed by %s!", fight->name.c_str()); + notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\ + "of your experience!"); + user->stats->gold = 0; + 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.c_str()); + 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) +{ + int hit, mhit; + aClient *ni, *battle; // The player and perhaps the player they're fighting + 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 (!is_fighting(ni)) + { + notice(s_GameServ, u, "You're not in battle!"); + return; + } + else + { + if (!ni->stats->master) // This is not a master fight + fight = ni->stats->fight; // Monster Could be NULL + else // This IS a master fight + fight = ni->stats->master; // Master Could be NULL + + battle = ni->stats->battle; // Player Could be NULL + + // One has to be !NULL based on the previous else if + // We wouldn't be here if they were all NULL + } + updateTS(ni->stats); + + if (!player_fight(ni)) + { + // Player's Hit + hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) + + (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2)); + + // Opponent's Hit + mhit = (fight->strength / 2) + + (rand() % (fight->strength / 2) - (ni->stats->defense + + arbonus[ni->stats->armor])); + } + else + { + // Opponent's Hit + mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) + + (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) - + (ni->stats->defense + arbonus[ni->stats->armor])); + + // Player's Hit + hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) + + (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) - + (battle->stats->defense + arbonus[battle->stats->armor])); + } + + if (!player_fight(ni)) + { + if (hit > 0) + notice(s_GameServ, u, "You attack %s for %d points!", fight->name.c_str(), hit); + else + notice(s_GameServ, u, "You miss %s completely!", fight->name.c_str()); + + if (hit >= fight->hp) + { + if (master_fight(ni) && !dragon_fight(ni)) + { + notice(s_GameServ, u, "You have bested %s!", fight->name.c_str()); + addNews(todaysnews, "%s has bested %s and moved "\ + "to level %d", ni->stats->name.c_str(), fight->name.c_str(), + (ni->stats->level + 1)); + } + else + notice(s_GameServ, u, "You have killed %s!", fight->name.c_str()); + + notice(s_GameServ, u, "%s", fight->death.c_str()); + notice(s_GameServ, u, "You recieve %d experience and %d gold!", + fight->exp, fight->gold); + + if (dragon_fight(ni)) + { + addNews(todaysnews, "%s is a true warrior! %s has beaten %s!!", + ni->stats->name.c_str(), ni->stats->name.c_str(), + ni->stats->master->name.c_str()); + ni->stats->master = NULL; // Don't progress in levels + } + + // If your new experience (or gold) will be greater than 2 billion, + // then set your exp to 2bil. (2 billion max)... otherwise add them. + // This could be a problem with overflowing out of the sign bit. + // Unsigned long int maybe? Leave it for now. + ni->stats->exp += fight->exp; + if (ni->stats->exp < 0 || ni->stats->exp > 2000000000) + ni->stats->exp = 2000000000; + + ni->stats->gold += fight->gold; + if (ni->stats->gold < 0 || ni->stats->gold > 2000000000) + ni->stats->gold = 2000000000; + + if (master_fight(ni)) + { + 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 + + // Increase your maximum hit points + ni->stats->maxhp += hpbonus[ni->stats->level - 1]; + + // Heal the player by setting hp to their max + ni->stats->hp = ni->stats->maxhp; + + // Add to your strength + ni->stats->strength += strbonus[ni->stats->level - 1]; + + // Add to your defensive power + ni->stats->defense += defbonus[ni->stats->level - 1]; - // Increase your level ni->stats->level++; - // Increase your maximum hit points - ni->stats->maxhp += hpbonus[ni->stats->level - 1]; + // 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 + { + if (hit > 0) + fight->hp -= hit; + if (mhit > 0) + { + notice(s_GameServ, u, "%s attacks with their %s for %d damage!", + fight->name.c_str(), fight->weapon.c_str(), mhit); + } + else if (mhit <= 0) + notice(s_GameServ, u, "%s completely misses you!", fight->name.c_str()); + + if (mhit >= ni->stats->hp) + { + if (!master_fight(ni)) + { + notice(s_GameServ, u, "You have been killed by %s!", fight->name.c_str()); + notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\ + "of your experience!"); + addNews(todaysnews, "%s has been killed by %s!", + ni->stats->name.c_str(), fight->name.c_str()); + 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.c_str()); + addNews(todaysnews, "%s tried to best %s and failed!", + ni->stats->name.c_str(), fight->name.c_str()); + ni->stats->fight = NULL; + ni->stats->master = NULL; + return; + } + } + else + { + if (mhit > 0) + ni->stats->hp -= mhit; + display_monster(u); + return; + } + } + } + else if (player_fight(ni)) + { +/* Offline fighting not available yet + if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online)) + { + if (hit > 0) + notice(s_GameServ, u, "You attack %s for %d points!", battle->nick, hit); + else + notice(s_GameServ, u, "You miss %s completely!", battle->nick); + if (hit >= battle->stats->hp) + { + notice(s_GameServ, u, "You have killed %s!", battle->nick); +* notice(s_GameServ, u, "You recieve %d experience and %ld gold!", + (long int)(battle->stats->exp * .10), battle->stats->gold); + if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10)) + { + ni->stats->exp += (long int)(battle->stats->exp * .10); + battle->stats->exp -= (long int)(battle->stats->exp * .10); + } +* else + { + battle->stats->exp -= (long int)(battle->stats->exp * .10); + ni->stats->exp = 2000000000; + } + + if (2000000000 - ni->stats->gold > battle->stats->gold) + { +* ni->stats->gold += battle->stats->gold; + battle->stats->gold = 0; + } + else + { + battle->stats->gold = 2000000000 - ni->stats->gold; + ni->stats->gold = 2000000000; + } +* ni->stats->battle->stats->alive = 0; + ni->stats->battle->battle = NULL; + ni->stats->battle = NULL; + return; + } + else + { + if (hit > 0) +* battle->stats->hp -= hit; + if (mhit > 0) + { + notice(s_GameServ, u, "%s hits you with their %s for %d damage!", + battle->nick, weapons[battle->stats->weapon], mhit); + } + else if (mhit <= 0) + notice(s_GameServ, u, "%s completely misses you!", battle->nick); +* + if (mhit >= ni->stats->hp) + { + notice(s_GameServ, u, "You have been killed by %s!", battle->nick); + if (2000000000 - battle->stats->gold > ni->stats->gold) + { + notice(s_GameServ, u, "%s took all your gold!", battle->nick); + battle->stats->gold += ni->stats->gold; +* ni->stats->gold = 0; + } + else + { + notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.", + battle->nick); + ni->stats->gold -= (2000000000 - battle->stats->gold); + notice(s_GameServ, u, "You were left dead with %d gold.", +* (long int)ni->stats->gold); + battle->stats->gold = 2000000000; + } + ni->stats->battle->battle = NULL; + ni->stats->battle = NULL; + ni->stats->alive = 0; + return; + } +* else + { + if (mhit > 0) + ni->stats->hp -= mhit; + display_players(u); + return; + } + } + } +* end offline fighting */ + + if (is_playing(battle)) + { + if (!isYourTurn(ni->stats)) + { + notice(s_GameServ, u, "Please wait until %s decides what to do!", + battle->stats->name.c_str()); + return; + } + if (hit > 0) + { + notice(s_GameServ, u, "You attack %s for %d points!", battle->stats->name.c_str(), hit); + + notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\ + "%d damage!", ni->stats->name.c_str(), + weapons[ni->stats->weapon], hit); + } + else + { + notice(s_GameServ, u, "You miss %s completely!", battle->stats->name.c_str()); + notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name.c_str()); + } + + if (hit >= battle->stats->hp) + { + notice(s_GameServ, u, "You have killed %s!", battle->stats->name.c_str()); + 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!", + ni->stats->name.c_str()); + battle->stats->hp = 0; + clearAlive(battle->stats); + + ni->stats->exp += (long int)(battle->stats->exp * .10); + battle->stats->exp -= (long int)(battle->stats->exp * .10); + + if (ni->stats->exp < 0 || ni->stats->exp > 2000000000) + ni->stats->exp = 2000000000; + + if (2000000000 - ni->stats->gold > battle->stats->gold) + { + notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\ + "all gold on hand!"); + ni->stats->gold += battle->stats->gold; + battle->stats->gold = 0; + } + else + { + battle->stats->gold = 2000000000 - ni->stats->gold; + notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!"); + + notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\ + "gold.", ni->stats->name.c_str()); + + 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; + } + else + { + if (hit > 0) + battle->stats->hp -= hit; + clearYourTurn(ni->stats); + setYourTurn(battle->stats); + display_players(battle); + notice(s_GameServ, u, "Please wait while %s decides what to do!", + battle->stats->name.c_str()); + return; + } + } + } +} + +void do_heal(char *u) +{ + aClient *ni; + char *amount = strtok(NULL, " "); + int price, num; + + 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 (!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(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; + } + + updateTS(ni->stats); + if (stricmp(amount, "ALL") == 0) + { + price = ni->stats->level * 3; + if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price) + { + notice(s_GameServ, u, "Healing %d points for %d gold per point.", + (long int)ni->stats->gold/price, price); + ni->stats->hp += ni->stats->gold / price; + ni->stats->gold %= price; + } + else + { + notice(s_GameServ, u, "Healing all possible points at %d gold "\ + "per point.", price); + notice(s_GameServ, u, "%d points healed for %ld gold. HP at MAX!", + (ni->stats->maxhp - ni->stats->hp), + (price * (ni->stats->maxhp - ni->stats->hp)) ); + ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp); + ni->stats->hp = ni->stats->maxhp; + } + } + else if (isstringnum(amount)) + { + num = stringtoint(amount); + price = ni->stats->level * 3; + if (ni->stats->gold < price * num) + { + notice(s_GameServ, u, "You only have enough gold to heal %d points!", + (long int)ni->stats->gold/price); + } + else if (num <= ni->stats->maxhp - ni->stats->hp) + { + notice(s_GameServ, u, "Healing %d points at %d gold per point.", + num, price); + ni->stats->hp += num; + ni->stats->gold -= num * price; + } + else if (num > ni->stats->maxhp - ni->stats->hp) + { + notice(s_GameServ, u, "Healing all possible points at %d gold "\ + "per point.", price); + notice(s_GameServ, u, "%d points healed. HP at MAX!", + (ni->stats->maxhp - ni->stats->hp)); + ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp); + ni->stats->hp = ni->stats->maxhp; + } + } + else if (amount[0] == '-') + notice(s_GameServ, u, "You trying to cheat?"); + else + notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}"); +} + +int isstringnum(char *num) +{ + unsigned int x; + for (x = 0; x < strlen(num); x++) + { + if ((int)num[x] < 48 || (int)num[x] > 57) + return 0; + } +return 1; +} + +long int stringtoint(char *number) +{ + long int x, len = strlen(number), sum = 0; + if (len == 1) + 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; +} + +long int pow(int x, int y) +{ + long int value = 0; + int count = 0; + value += x; + + if (x != 0 && y != 0) + { + for (count = 1; count <= y - 1; count++) + value *= x; + } + else + return 1; +return value; +} + +long int chartoint(char ch) +{ + if (int(ch) >= 48 && int(ch) <= 57) + return int(ch) - 48; + else + return 0; +} + +int save_gs_dbase() +{ + ListNode *ptr; + Player *it; + ofstream outfile; + + outfile.open(playerdata); + + if (!outfile) + { + 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.c_str() << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' ' + << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' ' + << it->armor << ' ' << it->weapon << ' ' + << it->forest_fights << ' ' << it->player_fights << ' ' + << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing() + << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() + << ' ' << it->lastlogin << endl; + ptr = ptr->Next(); + } + } +outfile.close(); +return 1; +} + +int load_gs_dbase() +{ + ifstream infile; + aClient *temp; + Player *p; + char *tempname, *buf, *password; + buf = new char[1023]; + + infile.open(playerdata); + + if (infile.fail()) + { + log("Error opening %s", playerdata); + return 0; + } + + for (int x = 0; x < U_TABLE_SIZE; x++) + { + ListNode *tempNode; + tempNode = players[x].First(); + while (tempNode) + { + if (tempNode->getData()->stats->client) + logout(tempNode->getData()->stats->client); + tempNode = tempNode->Next(); + } + players[x].deleteNodes(); + } + + while (infile.getline(buf, 1024, '\n')) + { + temp = new aClient; + tempname = strtok(buf, " "); + temp->stats = new Player(tempname); + p = temp->stats; + + p->level = stringtoint(strtok(NULL, " ")); + p->exp = stringtoint(strtok(NULL, " ")); + p->gold = stringtoint(strtok(NULL, " ")); + p->bank = stringtoint(strtok(NULL, " ")); + p->hp = stringtoint(strtok(NULL, " ")); + p->maxhp = stringtoint(strtok(NULL, " ")); + p->strength = stringtoint(strtok(NULL, " ")); + p->defense = stringtoint(strtok(NULL, " ")); + p->armor = stringtoint(strtok(NULL, " ")); + p->weapon = stringtoint(strtok(NULL, " ")); + p->forest_fights = stringtoint(strtok(NULL, " ")); + p->player_fights = stringtoint(strtok(NULL, " ")); + p->setFlags(stringtoint(strtok(NULL, " "))); + + password = strtok(NULL, " "); + p->password = password; + 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)); + + tempname = strtok(NULL, " "); + if (tempname) + p->lastlogin = stringtoint(tempname); + else + p->lastlogin = time(NULL); + + unsigned long hv = iHASH((unsigned char *) temp->stats->name.c_str()); + + temp->stats->client = NULL; + players[hv].insertAtBack(temp); + delete temp; + } +delete [] buf; +infile.close(); +return 1; +} + +bool passcmp(const char *encrypted, char *plaintext) +{ + char salt[3]; + char *plaintext2, *plainToencrypt; + bool same = false; + + plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra + strcpy(plaintext2, plaintext); + + salt[0] = encrypted[0]; + salt[1] = encrypted[1]; + salt[3] = '\0'; + + plainToencrypt = crypt(plaintext2, salt); + + same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false); + + delete []plaintext2; + + return same; +} + +bool check_password(char *name, char *plaintext) +{ + aClient *client; + + if (!(client = findplayer(name))) + return false; + else + { + return passcmp(client->stats->password.c_str(), plaintext); + } +} + +void do_store(char *u) +{ + char *cmd = strtok(NULL, " "); + 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 (!(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) + { + notice(s_GameServ, u, "Welcome to Kain's Armory"); + notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:"); + for (int x = 1; x < WNA; x++) + { + space = spaces(strlen(weapons[x]), "."); + notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]); + free(space); + } + notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY NUM."); + notice(s_GameServ, u, "Where num. is the weapon number from the menu above."); + + } + else if (stricmp(item, "ARMOR") == 0) + { + notice(s_GameServ, u, "Welcome to Kain's Armory"); + notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:"); + for (int x = 1; x < WNA; x++) + { + space = spaces(strlen(armors[x]), "."); + notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]); + free(space); + } + notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num."); + notice(s_GameServ, u, "Where num. is the armor number from the menu above."); + + + } + } 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; + } - // Heal the player by setting hp to their max - ni->stats->hp = ni->stats->maxhp; + p = user->stats; - // Add to your strength - ni->stats->strength += strbonus[ni->stats->level - 1]; + 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; + } - // Add to your defensive power - ni->stats->defense += defbonus[ni->stats->level - 1]; + p = user->stats; - // Clear the pointer for your master - ni->stats->master = NULL; + 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]; + } } - return; + else + { + notice(s_GameServ, u, "SYNTAX: STORE BUY {ARMOR | WEAPON} NUMBER"); + return; + } } - else + else if (stricmp(cmd, "SELL" ) == 0) { - if (hit > 0) - fight->hp -= hit; - if (mhit > 0) + p = user->stats; + + if (stricmp(item, "WEAPON") == 0) { - notice(s_GameServ, u, "%s hits you with their %s for %d damage!", - fight->name, fight->weapon, mhit); + 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 (mhit <= 0) - notice(s_GameServ, u, "%s completely misses you!", fight->name); - - if (mhit >= ni->stats->hp) + else if (stricmp(item, "ARMOR") == 0) { - if (!master_fight(u)) + p = user->stats; + + if (p->armor == 0) { - 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!"); - ni->stats->gold = 0; - ni->stats->exp -= (long int)(ni->stats->exp * .10); - ni->stats->fight = NULL; + 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, "%s has bested you! You will have to wait "\ - "until tomorrow to try again", ni->stats->master->name); - ni->stats->fight = NULL; - ni->stats->master = NULL; - return; + 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 - { - if (mhit > 0) - ni->stats->hp -= mhit; - display_monster(u); - return; - } + { + 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.c_str()); + notice(s_GameServ, nick, " Healing Potions: %d", p->Healing()); + notice(s_GameServ, nick, "Strength Potions: %d", p->Strength()); + notice(s_GameServ, nick, " Defense Potions: %d", p->Defense()); + 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, " "); + + if (!chnum) + { + notice(s_GameServ, u, "SYNTAX: TAVERN BUY #"); + notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1"); + return; + } + int num = stringtoint(chnum); + + if (num < 1 || num > 4) + { + notice(s_GameServ, u, "Invalid Choice!"); + 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; + } + if (stringtoint(amount) < 0) + { + notice(s_GameServ, u, "Sorry. This bank is not licensed "\ + "to handle such sums of cash, noble Lord."); + return; } - } - else if (player_fight(u)) - { -/* Offline fighting not available yet - if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online)) - { - if (hit > 0) - notice(s_GameServ, u, "You attack %s for %d points!", battle->nick, hit); - else - notice(s_GameServ, u, "You miss %s completely!", battle->nick); - if (hit >= battle->stats->hp) + p = user->stats; + + if (stricmp(cmd, "DEPOSIT") == 0) { - notice(s_GameServ, u, "You have killed %s!", battle->nick); -* notice(s_GameServ, u, "You recieve %d experience and %ld gold!", - (long int)(battle->stats->exp * .10), battle->stats->gold); - if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10)) + if (p->bank == 2000000000) { - ni->stats->exp += (long int)(battle->stats->exp * .10); - battle->stats->exp -= (long int)(battle->stats->exp * .10); + notice(s_GameServ, u, "Your bank account is full, sire!"); + return; } -* else + else if (stricmp(amount, "ALL") == 0) { - battle->stats->exp -= (long int)(battle->stats->exp * .10); - ni->stats->exp = 2000000000; + 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); + } } - - if (2000000000 - ni->stats->gold > battle->stats->gold) + else if (stringtoint(amount) > p->gold) { -* ni->stats->gold += battle->stats->gold; - battle->stats->gold = 0; + notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold); + showBankBalance(u); + return; } else { - battle->stats->gold = 2000000000 - ni->stats->gold; - ni->stats->gold = 2000000000; + 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); + } } -* ni->stats->battle->stats->alive = 0; - ni->stats->battle->battle = NULL; - ni->stats->battle = NULL; - return; } - else + else if (stricmp(cmd, "WITHDRAW") == 0) { - if (hit > 0) -* battle->stats->hp -= hit; - if (mhit > 0) + if (p->gold == 2000000000) { - notice(s_GameServ, u, "%s hits you with their %s for %d damage!", - battle->nick, weapons[battle->stats->weapon], mhit); + notice(s_GameServ, u, "You cannot carry any more gold, sire!"); + showBankBalance(u); + return; } - else if (mhit <= 0) - notice(s_GameServ, u, "%s completely misses you!", battle->nick); -* - if (mhit >= ni->stats->hp) + else if (stricmp(amount, "ALL") == 0) { - notice(s_GameServ, u, "You have been killed by %s!", battle->nick); - if (2000000000 - battle->stats->gold > ni->stats->gold) + if (2000000000 - p->gold < p->bank) { - notice(s_GameServ, u, "%s took all your gold!", battle->nick); - battle->stats->gold += ni->stats->gold; -* ni->stats->gold = 0; + 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, "You're lucky, %s couldn't carry all your gold.", - battle->nick); - ni->stats->gold -= (2000000000 - battle->stats->gold); - notice(s_GameServ, u, "You were left dead with %d gold.", -* (long int)ni->stats->gold); - battle->stats->gold = 2000000000; + notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank); + p->gold += p->bank; + p->bank = 0; + showBankBalance(u); } - ni->stats->battle->battle = NULL; - ni->stats->battle = NULL; - ni->stats->alive = 0; - return; } -* else + else if (stringtoint(amount) > p->bank) { - if (mhit > 0) - ni->stats->hp -= mhit; - display_players(u); + 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); + } + } } - } -* end offline fighting */ - if (is_playing(battle->getNick())) - { - if (ni->stats->yourturn == 0) +} + +void do_dragon(char *u) +{ + aClient *user; + + if (!(user = find(u))) { - notice(s_GameServ, u, "Please wait until %s decides what to do!", - battle->getNick()); - return; + notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); + return; } - if (hit > 0) + else if (isIgnore(user)) { - notice(s_GameServ, u, "You attack %s for %d points!", battle->getNick(), 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()); + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; } - else + else if (!is_playing(user)) { - 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 must be playing to fight the dragon!"); + return; } - if (hit >= battle->stats->hp) + else if (is_fighting(user)) { - notice(s_GameServ, u, "You have killed %s!", battle->getNick()); - 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); - battle->stats->hp = 0; - battle->stats->alive = 0; - - if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10)) - { - ni->stats->exp += (long int)(battle->stats->exp * .10); - battle->stats->exp -= (long int)(battle->stats->exp * .10); - } - else - { - battle->stats->exp -= (long int)(battle->stats->exp * .10); - ni->stats->exp = 2000000000; - } + 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 < LEVELS) + { + 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; + } - if (2000000000 - ni->stats->gold > battle->stats->gold) - { - notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\ - "all gold on hand!"); - ni->stats->gold += battle->stats->gold; - battle->stats->gold = 0; - } - else - { - battle->stats->gold = 2000000000 - ni->stats->gold; - notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!"); + updateTS(user->stats); + + Player *p = user->stats; + setMaster(p); + notice(s_GameServ, u, "You approach the dragon's lair cautiously."); + notice(s_GameServ, u, "The stench of sulfer fills the air as a "\ + "deep, red fog rolls in. The air is filled with the "\ + "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.", + armors[p->armor], weapons[p->weapon]); + notice(s_GameServ, u, "You come to the end of the cave to find "\ + "a tooth. It is a large tooth... bigger than your torso."\ + " Suddenly the darkness lifts from the gleam of an eye "\ + " 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!"); + see_master(u); +} - notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\ - "gold.", u); +void do_master(char *u) +{ + aClient *user; - notice(s_GameServ, battle->getNick(), "Luckily, you still have %ld gold "\ - "left. All is not lost!", battle->stats->gold); - ni->stats->gold = 2000000000; - } - battle->stats->battle = NULL; - ni->stats->battle = NULL; - return; + if (!(user = find(u))) + { + notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); + return; } - else + else if (isIgnore(user)) { - if (hit > 0) - battle->stats->hp -= hit; - //display_players(battle->getNick()); - ni->stats->yourturn = 0; - battle->stats->yourturn = 1; - notice(s_GameServ, u, "Please wait while %s decides what to do!", - battle->getNick()); - - return; + #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; } - } - } -} -void do_heal(char *u) -{ - aClient *ni; - char *amount = strtok(NULL, " "); - int price, num; - if (!amount) + updateTS(user->stats); + + char *cmd = strtok(NULL, " "); + Player *p = user->stats; + long int need = 0; + + if (seenMaster(p)) { - notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}"); + notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again"); + return; } - else if (!(ni = find(u)) || !ni->stats) + + if (cmd != NULL) { - notice(s_GameServ, u, "You aren't playing!"); + 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 if (is_fighting(u)) + else { - notice(s_GameServ, u, "You can't heal in battle!"); + notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}"); + return; } - else if (ni->stats->hp >= ni->stats->maxhp) + + if (stricmp(cmd, "FIGHT") == 0) { - notice(s_GameServ, u, "You don't need healing!"); + 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.", + levels[p->level - 1].master.name.c_str(), (need - p->exp)); + return; } - else if (stricmp(amount, "ALL") == 0) + else if (stricmp(cmd, "QUESTION") == 0) { - price = ni->stats->level * 3; - if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price) - { - notice(s_GameServ, u, "Healing %d points for %d gold per point.", - (long int)ni->stats->gold/price, price); - ni->stats->hp += ni->stats->gold / price; - ni->stats->gold %= price; - } - else - { - notice(s_GameServ, u, "Healing all possible points at %d gold "\ - "per point.", price); - notice(s_GameServ, u, "%d points healed for %ld gold. HP at MAX!", - (ni->stats->maxhp - ni->stats->hp), - (price * (ni->stats->maxhp - ni->stats->hp)) ); - ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp); - ni->stats->hp = ni->stats->maxhp; - } + 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.", + levels[p->level - 1].master.name.c_str()); + else + notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", + levels[p->level - 1].master.name.c_str(), p->name.c_str()); + + return; } - else if (isstringnum(amount)) + else { - num = stringtoint(amount); - price = ni->stats->level * 3; - if (ni->stats->gold < price * num) - { - notice(s_GameServ, u, "You only have enough gold to heal %d points!", - (long int)ni->stats->gold/price); - } - else if (num <= ni->stats->maxhp - ni->stats->hp) - { - notice(s_GameServ, u, "Healing %d points at %d gold per point.", - num, price); - ni->stats->hp += num; - ni->stats->gold -= num * price; - } - else if (num > ni->stats->maxhp - ni->stats->hp) - { - notice(s_GameServ, u, "Healing all possible points at %d gold "\ - "per point.", price); - notice(s_GameServ, u, "%d points healed. HP at MAX!", - (ni->stats->maxhp - ni->stats->hp)); - ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp); - ni->stats->hp = ni->stats->maxhp; - } + notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}"); } - else if (amount[0] == '-') - notice(s_GameServ, u, "You trying to cheat?"); - else - notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}"); } -int isstringnum(char *num) +void see_master(char *u) { - int x; - for (x = 0; x < strlen(num); x++) + aClient *user; + + if (!(user = find(u))) { - if ((int)num[x] < 48 || (int)num[x] > 57) - return 0; + notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); + return; } -return 1; -} -long int stringtoint(char *number) -{ - cout << "stringtoint: " << number << endl; - long int x, len = strlen(number), sum = 0; - if (len == 1) - return chartoint(number[0]); - sum += chartoint(number[len - 1]); - for (x = len - 2; x >= 0; x--) + if (!is_fighting(user) && is_playing(user)) { - cout << "Adding: " << chartoint(number[x]) * pow(10, abs(x - len + 1)) << - endl; - sum += chartoint(number[x]) * pow(10, abs(x - len + 1)); + Player *p = user->stats; + p->master = new Monster(&levels[p->level - 1].master); + p->fight = p->master; + display_monster(u); // Since master is the same structure, use this function } - return sum; } -long int pow(int x, int y) +void showBankBalance(const char *u) { - long int value = 0; - int count = 0; - value += x; + aClient *user; + Player *p; - if (x != 0 && y != 0) + 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) { - for (count = 1; count <= y - 1; count++) - value *= x; + p = it->getData()->stats; + refresh(p); + it = it->Next(); } - else - return 1; -return value; + } } -long int chartoint(char ch) +void refresh(Player *p) { - if (int(ch) >= 48 && int(ch) <= 57) - return int(ch) - 48; - else - return 0; + if (!p) + return; + + if (p->hp < p->maxhp) + p->hp = p->maxhp; + p->forest_fights = forestfights; + p->player_fights = 3; + setAlive(p); + clearMaster(p); } -int save_gs_dbase() +void do_refresh(char *u) { - ListNode *ptr = players.First(); - Player *it; - ofstream outfile; - - outfile.open(playerdata); + char *nick = strtok(NULL, " "); + aClient *user; - if (!outfile) + if (!(user = find(u))) { - cerr << "Error opening " << playerdata << endl; - return 0; + notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin"); + log("Error: aClient not found: %s", u); + return; } - - while(ptr) + else if (isIgnore(user)) { - it = ptr->getData()->stats; - 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->forest_fights << ' ' << it->player_fights << ' ' - << it->password << endl; - ptr = ptr->Next(); + #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; } -outfile.close(); } -int load_gs_dbase() + +void resetall() { - ifstream infile; - aClient *temp; + ListNode *it; Player *p; - char *alive, *tempname, *buf, *password; - buf = new char[1023]; - infile.open(playerdata); + for (unsigned long x = 0; x < U_TABLE_SIZE; x++) + { + it = players[x].First(); - if (infile.fail()) + while (it) { - cerr << "Error opening " << playerdata << endl; - return 0; + p = it->getData()->stats; + reset(p); + it = it->Next(); } + } +} - while (infile.getline(buf, 1024, '\n')) - { - cout << "temp = new aClient;" << endl << flush; - temp = new aClient; - cout << "tempname = strtok(buf, " ");" << endl << flush; - tempname = strtok(buf, " "); +void reset(Player *p) +{ + string *myname; - cout << "temp->stats = new Player(tempname);" << endl << flush; + if (!p) + return; - temp->stats = new Player(tempname); + myname = new string(p->name); - cout << "p = temp->stats;" << endl << flush; - p = temp->stats; + p->reset(); + p->name = *myname; + delete myname; +} - //Kain 1 1 0 500 10 10 0 0 1 1 alive 100 3 - p->level = stringtoint(strtok(NULL, " ")); - p->exp = stringtoint(strtok(NULL, " ")); - p->gold = stringtoint(strtok(NULL, " ")); - p->bank = stringtoint(strtok(NULL, " ")); - p->hp = stringtoint(strtok(NULL, " ")); - p->maxhp = stringtoint(strtok(NULL, " ")); - p->strength = stringtoint(strtok(NULL, " ")); - p->defense = stringtoint(strtok(NULL, " ")); - p->armor = stringtoint(strtok(NULL, " ")); - p->weapon = stringtoint(strtok(NULL, " ")); - alive = strtok(NULL, " "); - p->alive = (stricmp(alive, "ALIVE") == 0 ? true : false); - p->forest_fights = stringtoint(strtok(NULL, " ")); - p->player_fights = stringtoint(strtok(NULL, " ")); - password = strtok(NULL, " "); - strcpy(p->password, password); - temp->setNick("NULL"); +void updateTS(Player *p) +{ + if (!p) + return; - 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); + #ifdef DEBUGMODE + log("Old timestamp for %s: %ld", p->name.c_str(), p->lastcommand); + #endif + p->lastcommand = time(NULL); + #ifdef DEBUGMODE + log("New timestamp for %s: %ld", p->name.c_str(), p->lastcommand); + #endif - cout << "Inserting " << temp->stats->name << " at back of list" << endl; - players.insertAtBack(temp); - cout << temp->stats->name << " Inserted, now deleting" << endl; - delete temp; - cout << "Deleted" << endl; - } -delete [] buf; } -bool passcmp(char *encrypted, char *plaintext) +bool timedOut(Player *p) { - char salt[3]; - char *plaintext2, *plainToencrypt; - bool same = false; + if (!p) + return false; + else if (p->lastcommand == 0) + return false; + else + { + if ((time(NULL) - p->lastcommand) >= maxidletime) + return true; - plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra - strcpy(plaintext2, plaintext); - - salt[0] = encrypted[0]; - salt[1] = encrypted[1]; - salt[3] = '\0'; + return false; + } +} - plainToencrypt = crypt(plaintext2, salt); +void timeOutEvent(Player *p) +{ + aClient *user = findplayer(p->name.c_str()); - same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false); + if (!user || !p->client) // then they're not playing + return; - delete []plaintext2; + char *nick = user->getNick(); - return same; -} + 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.c_str()); + 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.c_str()); + notice(s_GameServ, user->getNick(), + "You and %s timed out at the same time."\ + " Don't fight if you're just going to "\ + "sit there!", p->battle->stats->name.c_str()); + 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) -bool check_password(char *name, char *plaintext) -{ - aClient *client; + 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; + } + } - if (!(client = findplayer(name))) - return false; - else - { - return passcmp(client->stats->password, plaintext); + // Always log out the user + logout(user); } } -void do_store(char *u) +void do_reset(char *u) { - char *cmd = strtok(NULL, " "); - char *item = strtok(NULL, " "); - char *num = strtok(NULL, " "); - char *space; - int wep; + char *nick = strtok(NULL, " "); aClient *user; - Player *p; - if (!is_playing(u) || !(user = find(u))) - notice(s_GameServ, u, "You must be playing to use the store!"); - else if (!cmd || !item) + if (!(user = find(u))) { - 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"); + notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin"); + log("Error: aClient not found: %s", u); + return; } - else if (stricmp(cmd, "LIST") == 0) + else if (!isAdmin(user)) { - if (stricmp(item, "WEAPONS") == 0) - { - notice(s_GameServ, u, "Welcome to Kain's Armory"); - notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:"); - for (int x = 1; x < WNA; x++) - { - space = spaces(strlen(weapons[x]), "."); - notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]); - free(space); - } - notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY NUM."); - notice(s_GameServ, u, "Where num. is the weapon number from the menu above."); + 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 = findplayer(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 if (stricmp(item, "ARMOR") == 0) + else { - notice(s_GameServ, u, "Welcome to Kain's Armory"); - notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:"); - for (int x = 1; x < WNA; x++) - { - space = spaces(strlen(armors[x]), "."); - notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]); - free(space); - } - notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num."); - notice(s_GameServ, u, "Where num. is the armor number from the menu above."); + notice(s_GameServ, u, "Resetting %s", user->stats->name.c_str()); + reset(user->stats); + } + } + else + { + notice(s_GameServ, u, "Nick %s not found.", nick); + return; + } +} +void do_help(char *u) +{ + char *cmd = strtok(NULL, " "); - } - } else if (stricmp(cmd, "BUY") == 0) { - if (!num) + display_help(u, cmd); +} + +void display_help(char *u, char *file) +{ + ifstream infile; + char *buf; + + if (!file) + { + infile.open("helpfiles/help"); + if (infile.fail()) { - notice(s_GameServ, u, "SYNTAX: STORE BUY {ARMOR | WEAPON} NUMBER"); + log("Error opening helpfiles/help"); + notice(s_GameServ, u, "Error opening helpfiles/help"); return; } - else if (!isstringnum(num)) + buf = new char[1024]; + while(infile.getline(buf, 1024)) { - notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num); - return; + // Written this way, it will process %S in the helpfiles + // Instead of notice(s_GameServ, u, "%s", buf); + notice(s_GameServ, u, buf); } - 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]; - } - } + // Minor recursion + aClient *user = find(u); + if (user && isAdmin(user)) + display_help(u, "admin_commands"); } - else if (stricmp(cmd, "SELL" ) == 0) + else { - 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; + char *filename; + filename = new char[strlen(file) + 11]; + strcpy(filename, "helpfiles/"); + strcat(filename, file); - 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)); + for (unsigned int x = 10; x < strlen(filename); x++) + filename[x] = tolower(filename[x]); - p->gold += (prices[p->armor - 1] / 2); - p->armor = 0; - } + infile.open(filename); + delete [] filename; + if (infile.fail()) + { + notice(s_GameServ, u, "No help for %s", file); + return; } - else + buf = new char[1024]; + while(infile.getline(buf, 1024)) { - 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"); + // 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_bank(char *u) +void do_admin(char *u) { - char *cmd = strtok(NULL, " "); - char *amount = strtok(NULL, " "); - char *nick = strtok(NULL, " "); - aClient *user; - Player *p; + char *pass = strtok(NULL, " "); - if (!cmd || !amount || (stricmp(cmd, "TRANSFER") == 0 && !nick)) + if (!(user = find(u))) { - notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}"); + log("Error: aClient not found: %s", u); + notice(s_GameServ, u, "Error: aClient not found. Contact %S admin."); return; } - else if (!is_playing(u) || !(user = find(u))) + + if (!pass) { - notice(s_GameServ, u, "You must be playing to use the bank!"); + notice(s_GameServ, u, "SYNTAX: ADMIN password"); return; } - else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0) + + if (isAdmin(user)) { - notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!"); - return; + 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; } +} - p = user->stats; +bool load_levels() +{ + char *filename; + filename = new char[256]; - if (stricmp(cmd, "DEPOSIT") == 0) + for (int x = 1; x <= LEVELS; x++) { - 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; - } - else - { - notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold); - p->bank += p->gold; - p->gold = 0; - } - } - else if (stringtoint(amount) > p->gold) - { - notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold); - 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; - } - else - { - notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount)); - p->bank += stringtoint(amount); - p->gold -= stringtoint(amount); - } - } + sprintf(filename, "data/levels/level%d.dat", x); + if (levels[x - 1].loadLevel(filename) == false) + return false; } - else if (stricmp(cmd, "WITHDRAW") == 0) + + delete []filename; + return true; +} +bool load_monsters() +{ + char *filename; + ifstream infile; + char *buf; + buf = new char[2048]; + + for (int level = 1; level <= LEVELS; level++) + { + filename = new char[256]; + sprintf(filename, "data/monsters/level%d.dat", level); + infile.open(filename); + + if (!infile) { - if (p->gold == 2000000000) - { - notice(s_GameServ, u, "You cannot carry any more gold, sire!"); - 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; - } - else - { - notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank); - p->gold += p->bank; - p->bank = 0; - } - } - else if (stringtoint(amount) > p->bank) - { - notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank); - 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; - } - else - { - notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount)); - p->gold += stringtoint(amount); - p->bank -= stringtoint(amount); - } - } + log("Error opening %s", filename); + return false; } + #ifdef DEBUGMODE + log("Loading monsters from %s", filename); + #endif + + while (infile.getline(buf, 2048)) + { + if (buf[0] == '^') + break; + if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#') + continue; + Monster *temp; + temp = new Monster; + + temp->name = strtok(buf, "~"); + temp->weapon = strtok(NULL, "~"); + temp->death = strtok(NULL, "~"); + + levels[level - 1].monsters.insertAtBack_RLN(temp); + delete temp; + } + delete [] filename; + infile.close(); + } + delete [] buf; +return true; }