]> jfr.im git - irc/gameservirc.git/blame - gameserv/gameserv.cpp
Added tcpserver for use in gameserv development.
[irc/gameservirc.git] / gameserv / gameserv.cpp
CommitLineData
85ce9d3e 1#include "sockhelp.h"
2#include "aClient.h"
3#include "list.h"
4#include "extern.h"
5#include <cctype>
6#include <fstream.h>
e3c5fe46 7#include <crypt.h>
85ce9d3e 8
9List<aClient> players;
10Monster monsters[5][12];
11
a8fb9757 12// Database functions
85ce9d3e 13int save_gs_dbase();
14int load_gs_dbase();
15
16// String functions
17#undef strtok
18char *strtok(char *str, const char *delim);
19int stricmp(const char *s1, const char *s2);
20int strnicmp(const char *s1, const char *s2, size_t len);
21// String Functions
22
e3c5fe46 23
24/********** Password functions **********/
25
26bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
27
28bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
29
30/********** Password functions **********/
31
32
33/********** GameServ Booleans **********/
34
35bool is_playing(char *u); // True if the given nickname in the clients list is playing.
36bool has_started(char *u); // True if the given nickname in the clients list has started playing.
37bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
38bool isnt_fighting(char *u); // True if the given nick isn't fighting. Same as !is_fighting(u).
39bool player_fight(char *u); // True if the player is fighting another player.
40bool master_fight(char *u); // True if the player is fighting their master.
41
42/********** GameServ Booleans **********/
85ce9d3e 43
44
45void display_monster(char *u);
46void display_players(char *u);
47long int chartoint(char ch);
48int isstringnum(char *num);
49long int pow (int x, int y);
50long int stringtoint(char *number);
51
52char *spaces(int len, char *seperator);
53void init_masters();
54void refresh(aClient *ni);
55void refreshall();
56void reset(aClient *ni);
57void init_monsters();
58
59void do_list(char *u);
60void do_register(char *u);
61void do_identify(char *u);
62void do_play(char *u);
63void do_quitg(char *u);
64void do_reset(char *u);
65void do_fight(char *u);
66void do_store(char *u);
67void do_heal(char *u);
68void do_bank(char *u);
69void do_attack(char *u);
70void do_run(char *u);
71void do_visit(char *u);
72void do_stats(char *u);
73void see_mystic(char *u);
74
75void showstats(const char *u, const char *nick);
76
77#define WNA 16
78char *weapons[WNA] = { "Fists", "Stick", "Dagger", "Quarterstaff", "Short Sword",
79 "Long Sword", "Silver Spear", "Battle Axe", "The Ragnarok",
80 "Chain Saw", "Poison Sword", "Flame Sword", "Earth Hammer",
81 "Light Saber", "Masamune", "Mystical Sword"};
82
83char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor",
84 "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit",
85 "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor",
86 "Hades' Cloak", "Dragon Scales", "Mystical Armor"};
87
88int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000,
89 1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
90int webonus[WNA] = {0, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
91int arbonus[WNA] = {0, 1, 3, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
92
93int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
94int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
95int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
96
97
98void gameserv(char *source, char *buf)
99{
100 char *cmd, input[1024];
101 cmd = strtok(buf, " ");
102
103 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
104 cmd++; // Get rid of that : at the beginning of the :text (command)
105
106 cout << "Source: " << source << "\ncmd: " << cmd << endl;
107 if (strnicmp(cmd, ":\1PING", 6) == 0)
108 {
109 char *timestamp;
110 timestamp = strtok(NULL, "\1");
111 notice(s_GameServ, source, "\1PING %s\1", timestamp);
112 } else if (stricmp(cmd, ":\1VERSION\1") == 0) {
113 notice(s_GameServ, source, "\1VERSION GameServ v1.0b\1");
114 } else if (stricmp(cmd, "SEARCH") == 0) {
115 cmd = strtok(NULL, " ");
116
117 if (!cmd)
118 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
119 else
120 do_forest(source);
121 } else if (stricmp(cmd, "FIGHT") == 0) {
122 do_fight(source);
123 } else if (stricmp(cmd, "ATTACK") == 0) {
124 do_attack(source);
125 } else if (stricmp(cmd, "HEAL") == 0) {
126 do_heal(source);
127 } else if (stricmp(cmd, "PRINT") == 0) {
128 cout << "Printing Clients List: " << endl;
129 clients.print();
130 cout << "Printing Player List: " << endl;
131 players.print();
132 } else if (stricmp(cmd, "LIST") == 0) {
133 do_list(source);
134 } else if (stricmp(cmd, "REGISTER") == 0) {
135 do_register(source);
136 } else if (stricmp(cmd, "IDENTIFY") == 0) {
137 do_identify(source);
138 } else if (stricmp(cmd, "HELP") == 0) {
139 } else if (stricmp(cmd, "STATS") == 0) {
140 do_stats(source);
141 } else if (stricmp(cmd, "SHUTDOWN") == 0) {
142 //save_gs_dbase();
143 raw("SQUIT %s :leaving", servername);
144 } else if (stricmp(cmd, "SAVE") == 0) {
145 save_gs_dbase();
146 } else if (stricmp(cmd, "LOAD") == 0) {
147 load_gs_dbase();
148 } else if (stricmp(cmd, "RAW") == 0) {
149 char *rest = strtok(NULL, "");
150 raw(rest);
151 }
152
153 source--; // Bring the : back so we don't leak memory
154 cmd--; // Same thing :)
155}
156
157int stricmp(const char *s1, const char *s2)
158{
159 register int c;
160
161 while ((c = tolower(*s1)) == tolower(*s2)) {
162 if (c == 0)
163 return 0;
164 s1++;
165 s2++;
166 }
167 if (c < tolower(*s2))
168 return -1;
169 return 1;
170}
171
172void showstats(const char *u, const char *nick)
173{
174 aClient *ni, *sender = find(u);
175 char *buf;
176 buf = new char[50];
177 char *space;
178
179
180 cout << "\n\nu: " << u << "\nnick: " << nick << endl;
181 if (!(ni = findbynick(nick)))
182 {
183 notice(s_GameServ, u, "%s not found", nick);
184 }
185 else if (ni->stats)
186 {
187
188 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
189
190 sprintf(buf, "Experience: %ld", ni->stats->exp);
191 space = spaces(strlen(buf), " ");
192 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
193 ni->stats->level);
194 delete space;
195
196 sprintf(buf, "Gold: %ld", ni->stats->gold);
197 space = spaces(strlen(buf), " ");
198 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
199 delete space;
200
201 notice(s_GameServ, sender->getNick(), "Health Points: %d of %d", ni->stats->hp,
202 ni->stats->maxhp);
203
204 sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
205 space = spaces(strlen(buf), " ");
206 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
207 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
208 delete space;
209
210 sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
211 space = spaces(strlen(buf), " ");
212 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
213 weapons[ni->stats->weapon]);
214 delete space;
215
216 sprintf(buf, "Forest Fights: %d", ni->stats->forest_fights);
217 space = spaces(strlen(buf), " ");
218 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
219 delete space;
220 }
221 delete buf;
222
223}
224
225char *spaces(int len, char *seperator)
226{
227 char *final;
228 final = new char[40];
229 int y;
230 strcpy(final, seperator);
231 for (y = 0; y < 40 - len; y++)
232 strcat(final, seperator);
233 return final;
234}
235
236void raw(const char *fmt, ...)
237{
238 va_list args;
239 char *input;
240 const char *t = fmt;
241 input = new char[1024];
242 va_start(args, fmt);
243 memset(input, 0, sizeof(input)); // Initialize to NULL
244 for (; *t; t++)
245 {
246 if (*t == '%')
247 {
248 switch(*++t) {
249 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
250 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
251 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
252 case 'l':
253 if (*++t == 'd')
254 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
255 }
256 }
257 else
258 {
259 sprintf(input, "%s%c", input, *t);
260 }
261
262 }
263 sprintf(input, "%s%s", input, "\r\n");
264 cout << "input: " << input << flush;
265 sock_puts(sock, input);
266 delete input;
267 va_end(args);
268}
269/* Send a NOTICE from the given source to the given nick. */
270
271void notice(const char *source, const char *dest, const char *fmt, ...)
272{
273 va_list args;
274 char *input;
275 const char *t = fmt;
276 input = new char[1024];
277 va_start(args, fmt);
278 if (dest[0] == ':')
279 {
280 dest++;
281 sprintf(input, ":%s NOTICE %s :", source, dest);
282 dest--;
283 }
284 else
285 sprintf(input, ":%s NOTICE %s :", source, dest);
286
287 for (; *t; t++)
288 {
289 if (*t == '%')
290 {
291 switch(*++t) {
292 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
293 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
294 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
295 case 'l':
296 if (*++t == 'd')
297 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
298 }
299 }
300 else
301 {
302 sprintf(input, "%s%c", input, *t);
303 }
304
305 }
306 sprintf(input, "%s%s", input, "\r\n");
307 cout << "input: " << input << flush;
308 sock_puts(sock, input);
309 delete input;
310va_end(args);
311}
312
313
314int strnicmp(const char *s1, const char *s2, size_t len)
315{
316 register int c;
317
318 if (!len)
319 return 0;
320 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
321 if (c == 0 || --len == 0)
322 return 0;
323 s1++;
324 s2++;
325 }
326 if (c < tolower(*s2))
327 return -1;
328 return 1;
329}
330
331char *strtok(char *str, const char *delim)
332{
333 static char *current = NULL;
334 char *ret;
335
336 if (str)
337 current = str;
338 if (!current)
339 return NULL;
340 current += strspn(current, delim);
341 ret = *current ? current : NULL;
342 current += strcspn(current, delim);
343 if (!*current)
344 current = NULL;
345 else
346 *current++ = 0;
347 return ret;
348}
349
350void do_list(char *u)
351{
352 ListNode<aClient> *temp;
353 temp = players.First();
354 if (!players.isEmpty())
355 {
356 notice(s_GameServ, u, "People Playing:");
357 while(temp)
358 {
359 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(), temp->getData()->stats->name);
360 temp = temp->Next();
361 }
362 notice(s_GameServ, u, "End of List");
363 }
364 else
365 notice(s_GameServ, u, "No one is playing");
366}
367void do_register(char *u)
368{
369 char *password;
370 aClient *user;
371 password = strtok(NULL, " ");
372
e3c5fe46 373 static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
374 static char salt[3];
375
376 salt[0] = saltChars[rand() % strlen(saltChars)];
377 salt[1] = saltChars[rand() % strlen(saltChars)];
378 salt[3] = '\0';
379
85ce9d3e 380 if (!password)
381 {
382 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER PASSWORD");
383 }
384 else if (user = find(u))
385 {
386 if (!user->stats)
387 {
388 user->stats = new Player(user);
389 user->stats->started = 1;
390 user->stats->user = user; // Set the backwards pointer
e3c5fe46 391 strcpy(user->stats->password, crypt(password, salt));
85ce9d3e 392 players.insertAtBack(user);
393 }
394 else
395 {
396 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
397 }
398 }
399}
400
401void do_identify(char *u)
402{
403 char *password;
404 aClient *user;
405 password = strtok(NULL, " ");
406
407 if (!password)
408 {
409 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY PASSWORD");
410 }
411 else if (stricmp(password, "TEST") != 0)
412 {
413 notice(s_GameServ, u, "Password incorrect");
414 }
415 else if (user = find(u))
416 {
417 if (!user->stats)
418 {
419 user->stats = new Player(user);
420 user->stats->started = 1;
421 players.insertAtBack(user);
422 notice(s_GameServ, u, "Password Accepted. Identified.");
423 }
424 else
425 {
426 notice(s_GameServ, u, "Already identified. Contact a %S admin for help.");
427 }
428 }
429}
430
431void do_stats(char *u)
432{
433 char *nick;
434 aClient *source;
435
436 nick = strtok(NULL, " ");
437 source = find(u);
438
439 if (!nick)
440 showstats(u, source->getNick());
441 else
442 showstats(u, nick);
443}
444
445void init_monsters()
446{
447 // Hard coded for now - Kain
448 monsters[0][0].name = "Slime";
449 monsters[0][0].weapon = "Acid Goo";
450 monsters[0][0].strength = 6;
451 monsters[0][0].gold = 50;
452 monsters[0][0].exp = 3;
453 monsters[0][0].maxhp = 9;
454 monsters[0][0].death = "The slime oozes into nothing... you clean the acid goo off of your weapon";
455
456 monsters[0][1].name = "Ghost";
457 monsters[0][1].weapon = "Cold Breath";
458 monsters[0][1].strength = 8;
459 monsters[0][1].gold = 100;
460 monsters[0][1].exp = 10;
461 monsters[0][1].maxhp = 10;
462 monsters[0][1].death = "You feel a chill as the spirit leaves the realm.";
463
464 monsters[0][2].name = "Ugly Rodent";
465 monsters[0][2].weapon = "Sharp Teeth";
466 monsters[0][2].strength = 9;
467 monsters[0][2].gold = 75;
468 monsters[0][2].exp = 8;
469 monsters[0][2].maxhp = 13;
470 monsters[0][2].death = "You stomp on the Ugly Rodent's remains for a finishing blow.";
471
472 monsters[0][3].name = "Whart Hog";
473 monsters[0][3].weapon = "Tusks";
474 monsters[0][3].strength = 10;
475 monsters[0][3].gold = 80;
476 monsters[0][3].exp = 6;
477 monsters[0][3].maxhp = 10;
478 monsters[0][3].death = "You cook and eat the hog for good measure!";
479
480 monsters[0][4].name = "Pesky Kid";
481 monsters[0][4].weapon = "Slingshot";
482 monsters[0][4].strength = 8;
483 monsters[0][4].gold = 30;
484 monsters[0][4].exp = 4;
485 monsters[0][4].maxhp = 6;
486 monsters[0][4].death = "You take his slingshot and snap the band, sending the kid crying home to mom!";
487
488 monsters[0][5].name = "Playground Bully";
489 monsters[0][5].weapon = "Painful Noogie";
490 monsters[0][5].strength = 11;
491 monsters[0][5].gold = 44;
492 monsters[0][5].exp = 6;
493 monsters[0][5].maxhp = 10;
494 monsters[0][5].death = "You give him an indian burn, and punt him across the schoolyard!";
495
496 monsters[0][6].name = "Small Imp";
497 monsters[0][6].weapon = "Dagger";
498 monsters[0][6].strength = 6;
499 monsters[0][6].gold = 64;
500 monsters[0][6].exp = 10;
501 monsters[0][6].maxhp = 10;
502 monsters[0][6].death = "You can't help but laugh as he stumbles and falls onto his own dagger!";
503
504 monsters[0][7].name = "Little Monkey";
505 monsters[0][7].weapon = "Monkey Wrench";
506 monsters[0][7].strength = 6;
507 monsters[0][7].gold = 53;
508 monsters[0][7].exp = 9;
509 monsters[0][7].maxhp = 9;
510 monsters[0][7].death = "You want to cook it, but you just can't think of eating something that looks so human!";
511
512 monsters[0][8].name = "Grub Worm";
513 monsters[0][8].weapon = "Minor Nudge";
514 monsters[0][8].strength = 2;
515 monsters[0][8].gold = 10;
516 monsters[0][8].exp = 3;
517 monsters[0][8].maxhp = 3;
518 monsters[0][8].death = "You decide to save the poor little fella for your next fishing trip.";
519
520 monsters[0][9].name = "Drakee";
521 monsters[0][9].weapon = "Tail Slap";
522 monsters[0][9].strength = 5;
523 monsters[0][9].gold = 22;
524 monsters[0][9].exp = 7;
525 monsters[0][9].maxhp = 5;
526 monsters[0][9].death = "You pull the little Drakee by its tale and slam it down on a dry stump!";
527
528 monsters[0][10].name = "Fat Slob";
529 monsters[0][10].weapon = "Smelly Breath";
530 monsters[0][10].strength = 6;
531 monsters[0][10].gold = 40;
532 monsters[0][10].exp = 10;
533 monsters[0][10].maxhp = 7;
534 monsters[0][10].death = "You kick his stomach for fun, and are thrown back by the spring of it all!";
535
536 monsters[0][11].name = "Lost Warrior";
537 monsters[0][11].weapon = "Long Sword";
538 monsters[0][11].strength = 10;
539 monsters[0][11].gold = 250;
540 monsters[0][11].exp = 19;
541 monsters[0][11].maxhp = 15;
542 monsters[0][11].death = "You give him a proper burial in respect for the dead warrior.";
543
544 monsters[1][0].name = "Lost Warrior's Cousin Larry";
545 monsters[1][0].weapon = "Wood Axe";
546 monsters[1][0].strength = 19;
547 monsters[1][0].gold = 134;
548 monsters[1][0].exp = 24;
549 monsters[1][0].maxhp = 30;
550 monsters[1][0].death = "He was pretty pissed you killed his cousin, but he seems to have suffered the same fate!";
551
552 monsters[1][1].name = "Sandman";
553 monsters[1][1].weapon = "Sleeping Dust";
554 monsters[1][1].strength = 25;
555 monsters[1][1].gold = 80;
556 monsters[1][1].exp = 6;
557 monsters[1][1].maxhp = 27;
558 monsters[1][1].death = "You put the sandman to his final sleep.";
559
560 monsters[1][2].name = "Dirty Transvestite";
561 monsters[1][2].weapon = "Stiletto Heel";
562 monsters[1][2].strength = 21;
563 monsters[1][2].gold = 160;
564 monsters[1][2].exp = 12;
565 monsters[1][2].maxhp = 25;
566 monsters[1][2].death = "You shudder at the thought of ever mistaking this for a woman!";
567
568 monsters[1][3].name = "Goblin Gardener";
569 monsters[1][3].weapon = "Garden Spade";
570 monsters[1][3].strength = 18;
571 monsters[1][3].gold = 130;
572 monsters[1][3].exp = 8;
573 monsters[1][3].maxhp = 20;
574 monsters[1][3].death = "You trample on his garden after slaying him... that felt good!";
575
576 monsters[1][4].name = "Evil Elf";
577 monsters[1][4].weapon = "Elvish Bow";
578 monsters[1][4].strength = 23;
579 monsters[1][4].gold = 136;
580 monsters[1][4].exp = 13;
581 monsters[1][4].maxhp = 24;
582 monsters[1][4].death = "Elves are usually nice you thought... hmm.";
583
584 monsters[1][5].name = "Viking Warrior";
585 monsters[1][5].weapon = "Broad Sword";
586 monsters[1][5].strength = 21;
587 monsters[1][5].gold = 330;
588 monsters[1][5].exp = 20;
589 monsters[1][5].maxhp = 18;
590 monsters[1][5].death = "You heard vikings were big, but not THAT big you thought.";
591
592 monsters[1][6].name = "Wicked Witch";
593 monsters[1][6].weapon = "Cackling Laugh";
594 monsters[1][6].strength = 20;
595 monsters[1][6].gold = 130;
596 monsters[1][6].exp = 20;
597 monsters[1][6].maxhp = 26;
598 monsters[1][6].death = "Just for kicks, you splash some water on her and watch her melt.";
599
600 monsters[1][7].name = "Vampire Bat";
601 monsters[1][7].weapon = "Blood Sucking Fangs";
602 monsters[1][7].strength = 18;
603 monsters[1][7].gold = 125;
604 monsters[1][7].exp = 21;
605 monsters[1][7].maxhp = 29;
606 monsters[1][7].death = "You fry up the bat and eat it... needs garlic.";
607
608 monsters[1][8].name = "Thorn Bush";
609 monsters[1][8].weapon = "101 Thorns";
610 monsters[1][8].strength = 16;
611 monsters[1][8].gold = 94;
612 monsters[1][8].exp = 15;
613 monsters[1][8].maxhp = 25;
614 monsters[1][8].death = "You set the bush ablaze and roast some marshmallows.";
615
616 monsters[1][9].name = "Barbarian";
617 monsters[1][9].weapon = "Heavy Sword";
618 monsters[1][9].strength = 29;
619 monsters[1][9].gold = 250;
620 monsters[1][9].exp = 25;
621 monsters[1][9].maxhp = 30;
622 monsters[1][9].death = "You listen to him moan as he falls over dead.";
623
624 monsters[1][10].name = "Crypt Rat";
625 monsters[1][10].weapon = "Stinging Bite";
626 monsters[1][10].strength = 25;
627 monsters[1][10].gold = 119;
628 monsters[1][10].exp = 20;
629 monsters[1][10].maxhp = 26;
630 monsters[1][10].death = "You squash the little rodent for fear that it might not be dead.";
631
632 monsters[1][11].name = "Small Orc";
633 monsters[1][11].weapon = "blade";
634 monsters[1][11].strength = 28;
635 monsters[1][11].gold = 300;
636 monsters[1][11].exp = 30;
637 monsters[1][11].maxhp = 36;
638 monsters[1][11].death = "It's an ugly one, and it would've grown up to be a terror...";
639
640 monsters[2][0].name = "Teferi";
641 monsters[2][0].weapon = "Puzzle Box";
642 monsters[2][0].strength = 29;
643 monsters[2][0].gold = 380;
644 monsters[2][0].exp = 18;
645 monsters[2][0].maxhp = 29;
646 monsters[2][0].death = "It was a puzzling experience.";
647
648 monsters[2][1].name = "Spineless Thug";
649 monsters[2][1].weapon = "Spiked Bat";
650 monsters[2][1].strength = 37;
651 monsters[2][1].gold = 384;
652 monsters[2][1].exp = 27;
653 monsters[2][1].maxhp = 32;
654 monsters[2][1].death = "See you at the crossroads!";
655
656 monsters[2][2].name = "Pyromaniac";
657 monsters[2][2].weapon = "Pyrotechnics";
658 monsters[2][2].strength = 29;
659 monsters[2][2].gold = 563;
660 monsters[2][2].exp = 22;
661 monsters[2][2].maxhp = 45;
662 monsters[2][2].death = "He chants FIRE FIRE as he falls to the ground... a burning heap of flesh.";
663
664 monsters[2][3].name = "Evil Enchantress";
665 monsters[2][3].weapon = "Deadly Spell";
666 monsters[2][3].strength = 50;
667 monsters[2][3].gold = 830;
668 monsters[2][3].exp = 35;
669 monsters[2][3].maxhp = 35;
670 monsters[2][3].death = "She looked just about as good as she fought.";
671
672 monsters[2][4].name = "Killer Leprechaun";
673 monsters[2][4].weapon = "Gold Rush";
674 monsters[2][4].strength = 35;
675 monsters[2][4].gold = 1300;
676 monsters[2][4].exp = 30;
677 monsters[2][4].maxhp = 37;
678 monsters[2][4].death = "You steal his pot of gold... that's a lot of money!";
679
680 monsters[2][5].name = "Avalanche Rider";
681 monsters[2][5].weapon = "Huge Snowball";
682 monsters[2][5].strength = 32;
683 monsters[2][5].gold = 700;
684 monsters[2][5].exp = 32;
685 monsters[2][5].maxhp = 38;
686 monsters[2][5].death = "You take his snowboard and snap it in two!";
687
688 monsters[2][6].name = "Blundering Idiot";
689 monsters[2][6].weapon = "Stupidity";
690 monsters[2][6].strength = 14;
691 monsters[2][6].gold = 700;
692 monsters[2][6].exp = 20;
693 monsters[2][6].maxhp = 29;
694 monsters[2][6].death = "Now there's one person you don't feel sorry for killing!";
695
696 monsters[2][7].name = "Militant Anarchist";
697 monsters[2][7].weapon = "Molotov Cocktail";
698 monsters[2][7].strength = 33;
699 monsters[2][7].gold = 245;
700 monsters[2][7].exp = 45;
701 monsters[2][7].maxhp = 32;
702 monsters[2][7].death = "Order has been restored for now...";
703
704 monsters[2][8].name = "Scathe Zombies";
705 monsters[2][8].weapon = "Death Grip";
706 monsters[2][8].strength = 38;
707 monsters[2][8].gold = 763;
708 monsters[2][8].exp = 15;
709 monsters[2][8].maxhp = 45;
710 monsters[2][8].death = "That was perhaps the scariest experience of your life.";
711
712 monsters[2][9].name = "Spitting Llama";
713 monsters[2][9].weapon = "Spit Spray";
714 monsters[2][9].strength = 48;
715 monsters[2][9].gold = 638;
716 monsters[2][9].exp = 28;
717 monsters[2][9].maxhp = 34;
718 monsters[2][9].death = "You wipe the spit off your face and fling it back at the Llama.";
719
720 monsters[2][10].name = "Juggalo";
721 monsters[2][10].weapon = "Clown Axe";
722 monsters[2][10].strength = 60;
723 monsters[2][10].gold = 650;
724 monsters[2][10].exp = 30;
725 monsters[2][10].maxhp = 29;
726 monsters[2][10].death = "What is a Juggalo? I don't know!";
727
728 monsters[2][11].name = "The Boogie Man";
729 monsters[2][11].weapon = "Striking Fear";
730 monsters[2][11].strength = 46;
731 monsters[2][11].gold = 600;
732 monsters[2][11].exp = 35;
733 monsters[2][11].maxhp = 27;
734 monsters[2][11].death = "He's scared you for the very last time!";
735
736 monsters[3][0].name = "Living Fire";
737 monsters[3][0].weapon = "Scorching Wind";
738 monsters[3][0].strength = 55;
739 monsters[3][0].gold = 1100;
740 monsters[3][0].exp = 36;
741 monsters[3][0].maxhp = 55;
742 monsters[3][0].death = "You extinguish the Living Flame once and for all!";
743
744 monsters[3][1].name = "Raging Orc";
745 monsters[3][1].weapon = "Orcish Artillary";
746 monsters[3][1].strength = 89;
747 monsters[3][1].gold = 900;
748 monsters[3][1].exp = 25;
749 monsters[3][1].maxhp = 50;
750 monsters[3][1].death = "This orc was a bit tougher than you remembered!";
751
752 monsters[3][2].name = "Huge Tarantula";
753 monsters[3][2].weapon = "Tangling Web";
754 monsters[3][2].strength = 59;
755 monsters[3][2].gold = 1000;
756 monsters[3][2].exp = 35;
757 monsters[3][2].maxhp = 60;
758 monsters[3][2].death = "You're glad you overcame your arachniphobia so soon!";
759
760 monsters[3][3].name = "Rabid Wolf";
761 monsters[3][3].weapon = "Cujo Bite";
762 monsters[3][3].strength = 40;
763 monsters[3][3].gold = 1200;
764 monsters[3][3].exp = 47;
765 monsters[3][3].maxhp = 76;
766 monsters[3][3].death = "The mutt falls over dead as white foam drips from its deadly canines...";
767
768 monsters[3][4].name = "Goblin Fighter";
769 monsters[3][4].weapon = "Morning Star";
770 monsters[3][4].strength = 38;
771 monsters[3][4].gold = 700;
772 monsters[3][4].exp = 30;
773 monsters[3][4].maxhp = 75;
774 monsters[3][4].death = "He almost caught you with his chain mace, but you sliced off his head.";
775
776 monsters[3][5].name = "Grizzly Bear";
777 monsters[3][5].weapon = "Razor Claws";
778 monsters[3][5].strength = 68;
779 monsters[3][5].gold = 1747;
780 monsters[3][5].exp = 81;
781 monsters[3][5].maxhp = 51;
782 monsters[3][5].death = "It almost got you this time... better be careful";
783
784 monsters[3][6].name = "Skeleton Man";
785 monsters[3][6].weapon = "Leg Bone";
786 monsters[3][6].strength = 70;
787 monsters[3][6].gold = 597;
788 monsters[3][6].exp = 57;
789 monsters[3][6].maxhp = 60;
790 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!";
791
792 monsters[3][7].name = "Young Werewolf";
793 monsters[3][7].weapon = "Howling Bites";
794 monsters[3][7].strength = 75;
795 monsters[3][7].gold = 1742;
796 monsters[3][7].exp = 65;
797 monsters[3][7].maxhp = 42;
798 monsters[3][7].death = "You scatter the wolf's body parts in hopes he will stay dead!";
799
800 monsters[3][8].name = "Dark Infantry";
801 monsters[3][8].weapon = "Flesh Reaper";
802 monsters[3][8].strength = 69;
803 monsters[3][8].gold = 870;
804 monsters[3][8].exp = 43;
805 monsters[3][8].maxhp = 65;
806 monsters[3][8].death = "Light has prevailed this time... but it's only so long before you meet again.";
807
808 monsters[3][9].name = "Erie Spirit";
809 monsters[3][9].weapon = "Deadly Grin";
810 monsters[3][9].strength = 63;
811 monsters[3][9].gold = 1300;
812 monsters[3][9].exp = 32;
813 monsters[3][9].maxhp = 50;
814 monsters[3][9].death = "His cousin the ghost was a little bit easier.";
815
816 monsters[3][10].name = "Gollum";
817 monsters[3][10].weapon = "Precious Treasure";
818 monsters[3][10].strength = 66;
819 monsters[3][10].gold = 1492;
820 monsters[3][10].exp = 73;
821 monsters[3][10].maxhp = 54;
822 monsters[3][10].death = "Gollum screams out \"MY PRECIOUS\" as his small body falls limp from your blow.";
823
824 monsters[3][11].name = "Rock Fighter";
825 monsters[3][11].weapon = "Small Boulders";
826 monsters[3][11].strength = 87;
827 monsters[3][11].gold = 1742;
828 monsters[3][11].exp = 99;
829 monsters[3][11].maxhp = 65;
830 monsters[3][11].death = "You dodge his last rock, and counter with a low blow, cutting off his legs.";
831
832
833 monsters[4][0].name = "Giant Sphinx";
834 monsters[4][0].weapon = "Ancient Curse";
835 monsters[4][0].strength = 120;
836 monsters[4][0].gold = 1000;
837 monsters[4][0].exp = 100;
838 monsters[4][0].maxhp = 80;
839 monsters[4][0].death = "You look in awe at the great wonder, collapsed at your feet!";
840
841 monsters[4][1].name = "Giant Ogre";
842 monsters[4][1].weapon = "Big Log";
843 monsters[4][1].strength = 130;
844 monsters[4][1].gold = 857;
845 monsters[4][1].exp = 175;
846 monsters[4][1].maxhp = 100;
847 monsters[4][1].death = "Your witz outmatched the ogres brawn... big dumb thing.";
848
849 monsters[4][2].name = "Massive Cockroach";
850 monsters[4][2].weapon = "Piercing Hiss";
851 monsters[4][2].strength = 125;
852 monsters[4][2].gold = 700;
853 monsters[4][2].exp = 150;
854 monsters[4][2].maxhp = 112;
855 monsters[4][2].death = "Where's the exterminator when you need one?";
856
857 monsters[4][3].name = "Big Venomous Snake";
858 monsters[4][3].weapon = "Poison Fangs";
859 monsters[4][3].strength = 140;
860 monsters[4][3].gold = 900;
861 monsters[4][3].exp = 175;
862 monsters[4][3].maxhp = 126;
863 monsters[4][3].death = "After killing this beast you check for puncture marks... you find none, luckily.";
864
865 monsters[4][4].name = "Lizard Man";
866 monsters[4][4].weapon = "Deadly Jaws";
867 monsters[4][4].strength = 145;
868 monsters[4][4].gold = 1250;
869 monsters[4][4].exp = 175;
870 monsters[4][4].maxhp = 150;
871 monsters[4][4].death = "His scales made for tough armor, and his jaws for a tougher opponent!";
872
873 monsters[4][5].name = "Face Dancer";
874 monsters[4][5].weapon = "Illusion Scyth";
875 monsters[4][5].strength = 138;
876 monsters[4][5].gold = 1603;
877 monsters[4][5].exp = 198;
878 monsters[4][5].maxhp = 173;
879 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!";
880
881 monsters[4][6].name = "Darklord Longbow Archer";
882 monsters[4][6].weapon = "Deadly Bow and Arrows";
883 monsters[4][6].strength = 145;
884 monsters[4][6].gold = 1569;
885 monsters[4][6].exp = 243;
886 monsters[4][6].maxhp = 170;
887 monsters[4][6].death = "Your face turns white with horror after you realize you just met the devil's protector!";
888
889 monsters[4][7].name = "Hell's Paladin";
890 monsters[4][7].weapon = "Sword of Hellfire";
891 monsters[4][7].strength = 200;
892 monsters[4][7].gold = 2191;
893 monsters[4][7].exp = 254;
894 monsters[4][7].maxhp = 175;
895 monsters[4][7].death = "This is starting to get tough you think. Do you really want to go to level 12?";
896
897 monsters[4][8].name = "The Unknown Soldier";
898 monsters[4][8].weapon = "Soul Torture";
899 monsters[4][8].strength = 175;
900 monsters[4][8].gold = 1890;
901 monsters[4][8].exp = 200;
902 monsters[4][8].maxhp = 180;
903 monsters[4][8].death = "Who was that? Where was he from? And what was that weapon??";
904
905 monsters[4][9].name = "Undead Cult Leader";
906 monsters[4][9].weapon = "Lance of Deceit";
907 monsters[4][9].strength = 180;
908 monsters[4][9].gold = 1792;
909 monsters[4][9].exp = 195;
910 monsters[4][9].maxhp = 190;
911 monsters[4][9].death = "His words fall on deaf ears... this is one cult you will NOT be part of!";
912
913 monsters[4][10].name = "Water Serpent";
914 monsters[4][10].weapon = "Forked Tongue";
915 monsters[4][10].strength = 150;
916 monsters[4][10].gold = 1500;
917 monsters[4][10].exp = 176;
918 monsters[4][10].maxhp = 220;
919 monsters[4][10].death = "The serpent squeals as you cut off its head!";
920
921 monsters[4][11].name = "Silverback Gorilla";
922 monsters[4][11].weapon = "Deadly Banana Peel";
923 monsters[4][11].strength = 160;
924 monsters[4][11].gold = 1300;
925 monsters[4][11].exp = 150;
926 monsters[4][11].maxhp = 178;
927 monsters[4][11].death = "Was that gorilla or guerilla?";
928}
929
930void display_monster(char *u)
931{
932 if (is_playing(u))
933 {
934 aClient *user = find(u);
935 Player *ni = user->stats;
936
937 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
938 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name, ni->fight->hp);
939 notice(s_GameServ, u, "Here are your commands:");
940 notice(s_GameServ, u, "/msg %S attack");
941 notice(s_GameServ, u, "/msg %S run");
942 notice(s_GameServ, u, "What will you do?");
943 }
944}
945
946void display_players(char *u)
947{
948 if (is_playing(u))
949 {
950 aClient *ni = find(u);
951
952 aClient *battle = ni->stats->battle;
953
954 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->stats->hp);
955 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->getNick(),
956 battle->stats->hp);
957
958 notice(s_GameServ, u, "Here are your commands:");
959 notice(s_GameServ, u, "/msg %s attack", s_GameServ);
960 notice(s_GameServ, u, "/msg %s run", s_GameServ);
961 notice(s_GameServ, u, "What will you do?");
962 }
963}
964
965
966bool is_playing(char *u)
967{
968 aClient *user;
969 if (!(user = find(u)))
970 {
971 return false;
972 }
973 else
974 {
975 return user->stats != NULL;
976 }
977}
978
979bool is_fighting(char *u)
980{
981 aClient *user;
982
983 if (!(user = find(u)))
984 {
985 return false;
986 }
987 else if (user->stats)
988 {
989 return user->stats->fight != NULL || user->stats->battle != NULL
990 || user->stats->master != NULL;
991 }
992 else
993 return false;
994}
995
996bool player_fight(char *u)
997{
998 aClient *user;
999
1000 if (!(user = find(u)))
1001 return false;
1002 else if (user->stats)
1003 return user->stats->battle != NULL;
1004 else
1005 return false;
1006}
1007
1008bool master_fight(char *u)
1009{
1010 aClient *user;
1011
1012 if (!(user = find(u)))
1013 return false;
1014 else if (user->stats)
1015 return user->stats->master != NULL;
1016 else
1017 return false;
1018}
1019
1020bool isnt_fighting(char *u)
1021{
1022 return !is_fighting(u);
1023}
1024
1025void do_fight(char *u)
1026{
1027 aClient *ni, *battle;
1028
1029 char *nick = strtok(NULL, " ");
1030
1031 if (!nick)
1032 {
1033 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
1034 }
1035 else if (!(ni = find(u)))
1036 {
1037 return;
1038 }
1039 else if (!(battle = find(nick)))
1040 {
1041 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
1042 }
1043 else if (!is_playing(u))
1044 {
1045 notice(s_GameServ, u, "You are not playing!");
1046 }
1047/*
1048 * Offline fighting not implemented yet.
1049 * else if (!(fight = finduser(nick)))
1050 * {
1051 * ni->stats->battle = battle;
1052 * battle->battle = ni;
1053 * ni->yourturn = 1;
1054 * battle->yourturn = 0;
1055 * notice(s_GameServ, u, "You decide to fight %s while they're not online!",
1056 * battle->getNick());
1057 * display_players(u);
1058 * }
1059 */
1060 else if (is_playing(u) && is_playing(nick))
1061 {
1062 // Set your battle pointer to the other player
1063 ni->stats->battle = battle;
1064
1065 // Set the other player's battle pointer to you
1066 battle->stats->battle = ni;
1067
1068 // The initiator gets the first move (perhaps this should be 50/50)
1069 ni->stats->yourturn = 1;
1070 battle->stats->yourturn = 0;
1071
1072 // Initiate Battle sequence!
1073 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->getNick());
1074 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", u);
1075 notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", u);
1076 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", u);
1077 display_players(u);
1078 }
1079}
1080
1081void do_attack(char *u)
1082{
1083 int hit, mhit;
1084 aClient *ni, *battle; // The player and perhaps the player they're fighting
1085 Monster *fight; // The monster they may be fighting
1086
1087 if (!(ni = find(u)))
1088 {
1089 notice(s_GameServ, u, "You're not playing!");
1090 return;
1091 }
1092 else if (!ni->stats->fight && !ni->stats->battle && !ni->stats->master)
1093 {
1094 notice(s_GameServ, u, "You're not in battle!");
1095 return;
1096 }
1097 else
1098 {
1099 if (!ni->stats->master) // This is not a master fight
1100 fight = ni->stats->fight; // Monster Could be NULL
1101 else // This IS a master fight
1102 fight = ni->stats->master; // Master Could be NULL
1103
1104 battle = ni->stats->battle; // Player Could be NULL
1105
1106 // One has to be !NULL based on the previous else if
1107 // We wouldn't be here if they were all NULL
1108 }
1109
1110 if (!player_fight(u))
1111 {
1112 // Player's Hit
1113 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1114 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1115
1116 // Opponent's Hit
1117 mhit = (fight->strength / 2) +
1118 (rand() % (fight->strength / 2) - (ni->stats->defense +
1119 arbonus[ni->stats->armor]));
1120 }
1121 else
1122 {
1123 // Opponent's Hit
1124 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1125 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1126 (ni->stats->defense + arbonus[ni->stats->armor]));
1127
1128 // Player's Hit
1129 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1130 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1131 (battle->stats->defense + arbonus[battle->stats->armor]));
1132 }
1133
1134 if (!player_fight(u))
1135 {
1136 if (hit > 0)
1137 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1138 else
1139 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1140
1141 if (hit >= fight->hp)
1142 {
1143 if (master_fight(u))
1144 notice(s_GameServ, u, "You have bested %s!", fight->name);
1145 else
1146 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1147
1148 notice(s_GameServ, u, "%s", fight->death);
1149 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1150 fight->exp, fight->gold);
1151
1152 // If your new experience (or gold) will be greater than 2 billion,
1153 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1154 // This could be a problem with overflowing out of the sign bit.
1155 // Unsigned long int maybe? Leave it for now.
1156 ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 :
1157 ni->stats->exp + fight->exp);
1158 ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 :
1159 ni->stats->gold + fight->gold);
1160 ni->stats->fight = NULL; // They're dead so remove the pointer
1161
1162 if (master_fight(u))
1163 {
1164 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1165 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1166 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1167
1168 // Increase your level
1169 ni->stats->level++;
1170
1171 // Increase your maximum hit points
1172 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1173
1174 // Heal the player by setting hp to their max
1175 ni->stats->hp = ni->stats->maxhp;
1176
1177 // Add to your strength
1178 ni->stats->strength += strbonus[ni->stats->level - 1];
1179
1180 // Add to your defensive power
1181 ni->stats->defense += defbonus[ni->stats->level - 1];
1182
1183 // Clear the pointer for your master
1184 ni->stats->master = NULL;
1185 }
1186 return;
1187 }
1188 else
1189 {
1190 if (hit > 0)
1191 fight->hp -= hit;
1192 if (mhit > 0)
1193 {
1194 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1195 fight->name, fight->weapon, mhit);
1196 }
1197 else if (mhit <= 0)
1198 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1199
1200 if (mhit >= ni->stats->hp)
1201 {
1202 if (!master_fight(u))
1203 {
1204 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1205 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1206 "of your experience!");
1207 ni->stats->gold = 0;
1208 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1209 ni->stats->fight = NULL;
1210 return;
1211 }
1212 else
1213 {
1214 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1215 "until tomorrow to try again", ni->stats->master->name);
1216 ni->stats->fight = NULL;
1217 ni->stats->master = NULL;
1218 return;
1219 }
1220 }
1221 else
1222 {
1223 if (mhit > 0)
1224 ni->stats->hp -= mhit;
1225 display_monster(u);
1226 return;
1227 }
1228 }
1229 }
1230 else if (player_fight(u))
1231 {
1232/* Offline fighting not available yet
1233 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1234 {
1235 if (hit > 0)
1236 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1237 else
1238 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1239 if (hit >= battle->stats->hp)
1240 {
1241 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1242* notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1243 (long int)(battle->stats->exp * .10), battle->stats->gold);
1244 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1245 {
1246 ni->stats->exp += (long int)(battle->stats->exp * .10);
1247 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1248 }
1249* else
1250 {
1251 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1252 ni->stats->exp = 2000000000;
1253 }
1254
1255 if (2000000000 - ni->stats->gold > battle->stats->gold)
1256 {
1257* ni->stats->gold += battle->stats->gold;
1258 battle->stats->gold = 0;
1259 }
1260 else
1261 {
1262 battle->stats->gold = 2000000000 - ni->stats->gold;
1263 ni->stats->gold = 2000000000;
1264 }
1265* ni->stats->battle->stats->alive = 0;
1266 ni->stats->battle->battle = NULL;
1267 ni->stats->battle = NULL;
1268 return;
1269 }
1270 else
1271 {
1272 if (hit > 0)
1273* battle->stats->hp -= hit;
1274 if (mhit > 0)
1275 {
1276 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1277 battle->nick, weapons[battle->stats->weapon], mhit);
1278 }
1279 else if (mhit <= 0)
1280 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1281*
1282 if (mhit >= ni->stats->hp)
1283 {
1284 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1285 if (2000000000 - battle->stats->gold > ni->stats->gold)
1286 {
1287 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1288 battle->stats->gold += ni->stats->gold;
1289* ni->stats->gold = 0;
1290 }
1291 else
1292 {
1293 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1294 battle->nick);
1295 ni->stats->gold -= (2000000000 - battle->stats->gold);
1296 notice(s_GameServ, u, "You were left dead with %d gold.",
1297* (long int)ni->stats->gold);
1298 battle->stats->gold = 2000000000;
1299 }
1300 ni->stats->battle->battle = NULL;
1301 ni->stats->battle = NULL;
1302 ni->stats->alive = 0;
1303 return;
1304 }
1305* else
1306 {
1307 if (mhit > 0)
1308 ni->stats->hp -= mhit;
1309 display_players(u);
1310 return;
1311 }
1312 }
1313 }
1314* end offline fighting */
1315
1316 if (is_playing(battle->getNick()))
1317 {
1318 if (ni->stats->yourturn == 0)
1319 {
1320 notice(s_GameServ, u, "Please wait until %s decides what to do!",
1321 battle->getNick());
1322 return;
1323 }
1324 if (hit > 0)
1325 {
1326 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->getNick(), hit);
1327
1328 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
1329 "\ 2%d\ 2 damage!", u, weapons[ni->stats->weapon],
1330 hit);
1331 ni->stats->yourturn = 0;
1332 battle->stats->yourturn = 1;
1333 display_players(battle->getNick());
1334 }
1335 else
1336 {
1337 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->getNick());
1338 notice(s_GameServ, battle->getNick(), "%s misses you completely!", u);
1339 ni->stats->yourturn = 0;
1340 battle->stats->yourturn = 1;
1341 display_players(battle->getNick());
1342 }
1343 if (hit >= battle->stats->hp)
1344 {
1345 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->getNick());
1346 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1347 (long int)(battle->stats->exp * .10), battle->stats->gold);
1348 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!", u);
1349 battle->stats->hp = 0;
1350 battle->stats->alive = 0;
1351
1352 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1353 {
1354 ni->stats->exp += (long int)(battle->stats->exp * .10);
1355 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1356 }
1357 else
1358 {
1359 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1360 ni->stats->exp = 2000000000;
1361 }
1362
1363 if (2000000000 - ni->stats->gold > battle->stats->gold)
1364 {
1365 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1366 "all gold on hand!");
1367 ni->stats->gold += battle->stats->gold;
1368 battle->stats->gold = 0;
1369 }
1370 else
1371 {
1372 battle->stats->gold = 2000000000 - ni->stats->gold;
1373 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1374
1375 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
1376 "gold.", u);
1377
1378 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1379 "left. All is not lost!", battle->stats->gold);
1380
1381 ni->stats->gold = 2000000000;
1382 }
1383 battle->stats->battle = NULL;
1384 ni->stats->battle = NULL;
1385 return;
1386 }
1387 else
1388 {
1389 if (hit > 0)
1390 battle->stats->hp -= hit;
1391 //display_players(battle->getNick());
1392 ni->stats->yourturn = 0;
1393 battle->stats->yourturn = 1;
1394 notice(s_GameServ, u, "Please wait while %s decides what to do!",
1395 battle->getNick());
1396
1397 return;
1398 }
1399 }
1400 }
1401}
1402void do_heal(char *u)
1403{
1404 aClient *ni;
1405 char *amount = strtok(NULL, " ");
1406 int price, num;
1407
1408 if (!amount)
1409 {
1410 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1411 }
1412 else if (!(ni = find(u)) || !ni->stats)
1413 {
1414 notice(s_GameServ, u, "You aren't playing!");
1415 }
1416 else if (is_fighting(u))
1417 {
1418 notice(s_GameServ, u, "You can't heal in battle!");
1419 }
1420 else if (ni->stats->hp >= ni->stats->maxhp)
1421 {
1422 notice(s_GameServ, u, "You don't need healing!");
1423 }
1424 else if (stricmp(amount, "ALL") == 0)
1425 {
1426 price = ni->stats->level * 3;
1427 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1428 {
1429 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1430 (long int)ni->stats->gold/price, price);
1431 ni->stats->hp += ni->stats->gold / price;
1432 ni->stats->gold %= price;
1433 }
1434 else
1435 {
1436 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1437 "per point.", price);
1438 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1439 (ni->stats->maxhp - ni->stats->hp));
1440 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1441 ni->stats->hp = ni->stats->maxhp;
1442 }
1443 }
1444 else if (isstringnum(amount))
1445 {
1446 num = stringtoint(amount);
1447 price = ni->stats->level * 3;
1448 if (ni->stats->gold < price * num)
1449 {
1450 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1451 (long int)ni->stats->gold/price);
1452 }
1453 else if (num <= ni->stats->maxhp - ni->stats->hp)
1454 {
1455 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1456 num, price);
1457 ni->stats->hp += num;
1458 ni->stats->gold -= num * price;
1459 }
1460 else if (num > ni->stats->maxhp - ni->stats->hp)
1461 {
1462 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1463 "per point.", price);
1464 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1465 (ni->stats->maxhp - ni->stats->hp));
1466 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1467 ni->stats->hp = ni->stats->maxhp;
1468 }
1469 }
1470 else if (amount[0] == '-')
1471 notice(s_GameServ, u, "You trying to cheat?");
1472 else
1473 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1474}
1475
1476int isstringnum(char *num)
1477{
1478 int x;
1479 for (x = 0; x < strlen(num); x++)
1480 {
1481 if ((int)num[x] < 48 || (int)num[x] > 57)
1482 return 0;
1483 }
1484return 1;
1485}
1486
1487long int stringtoint(char *number)
1488{
1489 long int x, len = strlen(number), sum = 0;
1490 if (len == 1)
1491 return chartoint(number[0]);
1492 sum += chartoint(number[len - 1]);
1493 for (x = len - 2; x >= 0; x--)
1494 {
1495 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
1496 }
1497 return sum;
1498}
1499
1500long int pow(int x, int y)
1501{
1502 long int value = 0;
1503 int count = 0;
1504 value += x;
1505
1506 if (x != 0 && y != 0)
1507 {
1508 for (count = 1; count <= y - 1; count++)
1509 value *= x;
1510 }
1511 else
1512 return 1;
1513return value;
1514}
1515
1516long int chartoint(char ch)
1517{
1518 switch(ch)
1519 {
1520 case '0':
1521 return 0;
1522 break;
1523 case '1':
1524 return 1;
1525 case '2':
1526 return 2;
1527 case '3':
1528 return 3;
1529 case '4':
1530 return 4;
1531 case '5':
1532 return 5;
1533 case '6':
1534 return 6;
1535 case '7':
1536 return 7;
1537 case '8':
1538 return 8;
1539 case '9':
1540 return 9;
1541 case '\n':
1542 break;
1543 default:
1544 return -1;
1545 }
1546return -1;
1547}
1548
1549int save_gs_dbase()
1550{
1551 ListNode<aClient> *ptr = players.First();
1552 Player *it;
1553 ofstream outfile;
1554
1555 outfile.open(playerdata);
1556
1557 if (!outfile)
1558 {
1559 cerr << "Error opening " << playerdata << endl;
1560 return 0;
1561 }
1562
1563 while(ptr)
1564 {
1565 it = ptr->getData()->stats;
1566 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
1567 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
1568 << it->armor << ' ' << it->weapon << ' ' << (it->alive ? "alive" : "dead") << ' '
e3c5fe46 1569 << it->forest_fights << ' ' << it->player_fights << ' '
1570 << it->password << endl;
85ce9d3e 1571 ptr = ptr->Next();
1572 }
1573outfile.close();
1574}
1575
1576int load_gs_dbase()
1577{
1578 ifstream infile;
1579 aClient *temp;
1580 Player *p;
e3c5fe46 1581 char *alive, *tempname, *buf, *password;
85ce9d3e 1582 buf = new char[1023];
1583
1584 infile.open(playerdata);
1585
1586 if (infile.fail())
1587 {
1588 cerr << "Error opening " << playerdata << endl;
1589 return 0;
1590 }
1591
1592 while (infile.getline(buf, 1024, '\n'))
1593 {
1594 temp = new aClient;
1595 tempname = strtok(buf, " ");
1596 temp->stats = new Player(tempname);
1597 p = temp->stats;
1598
1599 //Kain 1 1 0 500 10 10 0 0 1 1 alive 100 3
1600 p->level = stringtoint(strtok(NULL, " "));
1601 p->exp = stringtoint(strtok(NULL, " "));
1602 p->gold = stringtoint(strtok(NULL, " "));
1603 p->bank = stringtoint(strtok(NULL, " "));
1604 p->hp = stringtoint(strtok(NULL, " "));
1605 p->maxhp = stringtoint(strtok(NULL, " "));
1606 p->strength = stringtoint(strtok(NULL, " "));
1607 p->defense = stringtoint(strtok(NULL, " "));
1608 p->armor = stringtoint(strtok(NULL, " "));
1609 p->weapon = stringtoint(strtok(NULL, " "));
1610 alive = strtok(NULL, " ");
1611 p->alive = (stricmp(alive, "ALIVE") == 0 ? true : false);
1612 p->forest_fights = stringtoint(strtok(NULL, " "));
1613 p->player_fights = stringtoint(strtok(NULL, " "));
e3c5fe46 1614 password = strtok(NULL, " ");
1615 strcpy(p->password, password);
85ce9d3e 1616 temp->setNick("NULL");
1617
e3c5fe46 1618 printf("%s %d %ld %ld %ld %d %d %d %d %d %d %s %d %d %s\n", p->name, p->level,
1619 p->exp, p->gold, p->bank, p->hp, p->maxhp, p->strength, p->defense, p->armor, p->weapon,
1620 alive, p->forest_fights, p->player_fights, p->password);
1621
85ce9d3e 1622 players.insertAtBack(temp);
1623 delete temp;
1624 }
1625delete buf;
1626}
1627
e3c5fe46 1628bool passcmp(char *encrypted, char *plaintext)
1629{
1630 char salt[3];
1631 salt[0] = encrypted[0];
1632 salt[1] = encrypted[1];
1633 salt[3] = '\0';
1634 return (strcmp(encrypted, crypt(plaintext, salt)) == 0);
1635}
1636
1637bool check_password(char *name, char *plaintext)
1638{
1639 ListNode<aClient> *tempPtr = clients.First();
1640
1641 while (tempPtr)
1642 {
1643 if (stricmp(name, tempPtr->getData()->getNick()) == 0)
1644 return passcmp(tempPtr->getData()->stats->password, plaintext);
1645
1646 tempPtr = tempPtr->Next();
1647 }
1648 return false;
1649}