|
|
1.1 ! root 1: /* ! 2: * interplayer.c - player to player routines for Phantasia ! 3: */ ! 4: ! 5: #include "include.h" ! 6: ! 7: /************************************************************************ ! 8: / ! 9: / FUNCTION NAME: checkbattle() ! 10: / ! 11: / FUNCTION: check to see if current player should battle another ! 12: / ! 13: / AUTHOR: E. A. Estes, 12/4/85 ! 14: / ! 15: / ARGUMENTS: none ! 16: / ! 17: / RETURN VALUE: none ! 18: / ! 19: / MODULES CALLED: battleplayer(), fread(), fseek() ! 20: / ! 21: / GLOBAL INPUTS: Other, Users, Player, Fileloc, *Playersfp ! 22: / ! 23: / GLOBAL OUTPUTS: Users ! 24: / ! 25: / DESCRIPTION: ! 26: / Seach player file for a foe at the same coordinates as the ! 27: / current player. ! 28: / Also update user count. ! 29: / ! 30: /************************************************************************/ ! 31: ! 32: checkbattle() ! 33: { ! 34: long foeloc = 0L; /* location in file of person to fight */ ! 35: ! 36: Users = 0; ! 37: fseek(Playersfp, 0L, 0); ! 38: ! 39: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 40: { ! 41: if (Other.p_status != S_OFF ! 42: && Other.p_status != S_NOTUSED ! 43: && Other.p_status != S_HUNGUP ! 44: && (Other.p_status != S_CLOAKED || Other.p_specialtype != SC_VALAR)) ! 45: /* player is on and not a cloaked valar */ ! 46: { ! 47: ++Users; ! 48: ! 49: if (Player.p_x == Other.p_x ! 50: && Player.p_y == Other.p_y ! 51: /* same coordinates */ ! 52: && foeloc != Fileloc ! 53: /* not self */ ! 54: && Player.p_status == S_PLAYING ! 55: && (Other.p_status == S_PLAYING || Other.p_status == S_INBATTLE) ! 56: /* both are playing */ ! 57: && Other.p_specialtype != SC_VALAR ! 58: && Player.p_specialtype != SC_VALAR) ! 59: /* neither is valar */ ! 60: { ! 61: battleplayer(foeloc); ! 62: return; ! 63: } ! 64: } ! 65: foeloc += SZ_PLAYERSTRUCT; ! 66: } ! 67: } ! 68: /**/ ! 69: /************************************************************************ ! 70: / ! 71: / FUNCTION NAME: battleplayer() ! 72: / ! 73: / FUNCTION: inter-terminal battle with another player ! 74: / ! 75: / AUTHOR: E. A. Estes, 2/15/86 ! 76: / ! 77: / ARGUMENTS: ! 78: / long foeplace - location in player file of person to battle ! 79: / ! 80: / RETURN VALUE: none ! 81: / ! 82: / MODULES CALLED: readrecord(), readmessage(), writerecord(), collecttaxes(), ! 83: / displaystats(), fabs(), more(), death(), sleep(), wmove(), waddch(), printw(), ! 84: / myturn(), altercoordinates(), waddstr(), wrefresh(), mvprintw(), ! 85: / getanswer(), wclrtoeol(), wclrtobot() ! 86: / ! 87: / GLOBAL INPUTS: Foestrikes, LINES, Lines, Other, Shield, Player, *stdscr, ! 88: / Fileloc, *Enemyname ! 89: / ! 90: / GLOBAL OUTPUTS: Foestrikes, Lines, Shield, Player, Luckout, *Enemyname ! 91: / ! 92: / DESCRIPTION: ! 93: / Inter-terminal battle is a very fragile and slightly klugy thing. ! 94: / At any time, one player is master and the other is slave. ! 95: / We pick who is master first by speed and level. After that, ! 96: / the slave waits for the master to relinquish its turn, and ! 97: / the slave becomes master, and so on. ! 98: / ! 99: / The items in the player structure which control the handshake are: ! 100: / p_tampered: ! 101: / master increments this to relinquish control ! 102: / p_istat: ! 103: / master sets this to specify particular action ! 104: / p_1scratch: ! 105: / set to total damage inflicted so far; changes to indicate action ! 106: / ! 107: /************************************************************************/ ! 108: ! 109: battleplayer(foeplace) ! 110: long foeplace; ! 111: { ! 112: double dtemp; /* for temporary calculations */ ! 113: double oldhits = 0.0; /* previous damage inflicted by foe */ ! 114: register int loop; /* for timing out */ ! 115: int ch; /* input */ ! 116: short oldtampered; /* old value of foe's p_tampered */ ! 117: ! 118: Lines = 8; ! 119: Luckout = FALSE; ! 120: mvaddstr(4, 0, "Preparing for battle!\n"); ! 121: refresh(); ! 122: ! 123: #ifdef SYS5 ! 124: flushinp(); ! 125: #endif ! 126: ! 127: /* set up variables, file, etc. */ ! 128: Player.p_status = S_INBATTLE; ! 129: Shield = Player.p_energy; ! 130: ! 131: /* if p_tampered is not 0, someone else may try to change it (king, etc.) */ ! 132: Player.p_tampered = oldtampered = 1; ! 133: Player.p_1scratch = 0.0; ! 134: Player.p_istat = I_OFF; ! 135: ! 136: readrecord(&Other, foeplace); ! 137: if (fabs(Player.p_level - Other.p_level) > 20.0) ! 138: /* see if players are greatly mismatched */ ! 139: { ! 140: dtemp = (Player.p_level - Other.p_level) / MAX(Player.p_level, Other.p_level); ! 141: if (dtemp < -0.5) ! 142: /* foe outweighs this one */ ! 143: Player.p_speed *= 2.0; ! 144: } ! 145: ! 146: writerecord(&Player, Fileloc); /* write out all our info */ ! 147: ! 148: if (Player.p_blindness) ! 149: Enemyname = "someone"; ! 150: else ! 151: Enemyname = Other.p_name; ! 152: ! 153: mvprintw(6, 0, "You have encountered %s Level: %.0f\n", Enemyname, Other.p_level); ! 154: refresh(); ! 155: ! 156: for (loop = 0; Other.p_status != S_INBATTLE && loop < 30; ++loop) ! 157: /* wait for foe to respond */ ! 158: { ! 159: readrecord(&Other, foeplace); ! 160: sleep(1); ! 161: } ! 162: ! 163: if (Other.p_status != S_INBATTLE) ! 164: /* foe did not respond */ ! 165: { ! 166: mvprintw(5, 0, "%s is not responding.\n", Enemyname); ! 167: goto LEAVE; ! 168: } ! 169: /* else, we are ready to battle */ ! 170: ! 171: move(4, 0); ! 172: clrtoeol(); ! 173: ! 174: /* ! 175: * determine who is first master ! 176: * if neither player is faster, check level ! 177: * if neither level is greater, battle is not allowed ! 178: * (this should never happen, but we have to handle it) ! 179: */ ! 180: if (Player.p_speed > Other.p_speed) ! 181: Foestrikes = FALSE; ! 182: else if (Other.p_speed > Player.p_speed) ! 183: Foestrikes = TRUE; ! 184: else if (Player.p_level > Other.p_level) ! 185: Foestrikes = FALSE; ! 186: else if (Other.p_level > Player.p_level) ! 187: Foestrikes = TRUE; ! 188: else ! 189: /* no one is faster */ ! 190: { ! 191: printw("You can't fight %s yet.", Enemyname); ! 192: goto LEAVE; ! 193: } ! 194: ! 195: for (;;) ! 196: { ! 197: displaystats(); ! 198: readmessage(); ! 199: mvprintw(1, 26, "%20.0f", Shield); /* overprint energy */ ! 200: ! 201: if (!Foestrikes) ! 202: /* take action against foe */ ! 203: myturn(); ! 204: else ! 205: /* wait for foe to take action */ ! 206: { ! 207: mvaddstr(4, 0, "Waiting...\n"); ! 208: clrtoeol(); ! 209: refresh(); ! 210: ! 211: for (loop = 0; loop < 20; ++loop) ! 212: /* wait for foe to act */ ! 213: { ! 214: readrecord(&Other, foeplace); ! 215: if (Other.p_1scratch != oldhits) ! 216: /* p_1scratch changes to indicate action */ ! 217: break; ! 218: else ! 219: /* wait and try again */ ! 220: { ! 221: sleep(1); ! 222: addch('.'); ! 223: refresh(); ! 224: } ! 225: } ! 226: ! 227: if (Other.p_1scratch == oldhits) ! 228: { ! 229: /* timeout */ ! 230: mvaddstr(22, 0, "Timeout: waiting for response. Do you want to wait ? "); ! 231: ch = getanswer("NY", FALSE); ! 232: move(22, 0); ! 233: clrtobot(); ! 234: if (ch == 'Y') ! 235: continue; ! 236: else ! 237: break; ! 238: } ! 239: else ! 240: /* foe took action */ ! 241: { ! 242: switch (Other.p_istat) ! 243: { ! 244: case I_RAN: /* foe ran away */ ! 245: mvprintw(Lines++, 0, "%s ran away!", Enemyname); ! 246: break; ! 247: ! 248: case I_STUCK: /* foe tried to run, but couldn't */ ! 249: mvprintw(Lines++, 0, "%s tried to run away.", Enemyname); ! 250: break; ! 251: ! 252: case I_BLEWIT: /* foe tried to luckout, but didn't */ ! 253: mvprintw(Lines++, 0, "%s tried to luckout!", Enemyname); ! 254: break; ! 255: ! 256: default: ! 257: dtemp = Other.p_1scratch - oldhits; ! 258: mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, dtemp); ! 259: Shield -= dtemp; ! 260: break; ! 261: } ! 262: ! 263: oldhits = Other.p_1scratch; /* keep track of old hits */ ! 264: ! 265: if (Other.p_tampered != oldtampered) ! 266: /* p_tampered changes to relinquish turn */ ! 267: { ! 268: oldtampered = Other.p_tampered; ! 269: Foestrikes = FALSE; ! 270: } ! 271: } ! 272: } ! 273: ! 274: /* decide what happens next */ ! 275: refresh(); ! 276: if (Lines > LINES - 2) ! 277: { ! 278: more(Lines); ! 279: move(Lines = 8, 0); ! 280: clrtobot(); ! 281: } ! 282: ! 283: if (Other.p_istat == I_KILLED || Shield < 0.0) ! 284: /* we died */ ! 285: { ! 286: Shield = -2.0; /* insure this value is negative */ ! 287: break; ! 288: } ! 289: ! 290: if (Player.p_istat == I_KILLED) ! 291: /* we killed foe; award treasre */ ! 292: { ! 293: mvprintw(Lines++, 0, "You killed %s!", Enemyname); ! 294: Player.p_experience += Other.p_experience; ! 295: Player.p_crowns += (Player.p_level < 1000.0) ? Other.p_crowns : 0; ! 296: Player.p_amulets += Other.p_amulets; ! 297: Player.p_charms += Other.p_charms; ! 298: collecttaxes(Other.p_gold, Other.p_gems); ! 299: Player.p_sword = MAX(Player.p_sword, Other.p_sword); ! 300: Player.p_shield = MAX(Player.p_shield, Other.p_shield); ! 301: Player.p_quksilver = MAX(Player.p_quksilver, Other.p_quksilver); ! 302: if (Other.p_virgin && !Player.p_virgin) ! 303: { ! 304: mvaddstr(Lines++, 0, "You have rescued a virgin. Will you be honorable ? "); ! 305: if ((ch = getanswer("YN", FALSE)) == 'Y') ! 306: Player.p_virgin = TRUE; ! 307: else ! 308: { ! 309: ++Player.p_sin; ! 310: Player.p_experience += 8000.0; ! 311: } ! 312: } ! 313: sleep(3); /* give other person time to die */ ! 314: break; ! 315: } ! 316: else if (Player.p_istat == I_RAN || Other.p_istat == I_RAN) ! 317: /* either player ran away */ ! 318: break; ! 319: } ! 320: ! 321: LEAVE: ! 322: /* clean up things and leave */ ! 323: writerecord(&Player, Fileloc); /* update a final time */ ! 324: altercoordinates(0.0, 0.0, A_NEAR); /* move away from battle site */ ! 325: Player.p_energy = Shield; /* set energy to actual value */ ! 326: Player.p_tampered = T_OFF; /* clear p_tampered */ ! 327: ! 328: more(Lines); /* pause */ ! 329: ! 330: move(4, 0); ! 331: clrtobot(); /* clear bottom area of screen */ ! 332: ! 333: if (Player.p_energy < 0.0) ! 334: /* we are dead */ ! 335: death("Interterminal battle"); ! 336: } ! 337: /**/ ! 338: /************************************************************************ ! 339: / ! 340: / FUNCTION NAME: myturn() ! 341: / ! 342: / FUNCTION: process players action against foe in battle ! 343: / ! 344: / AUTHOR: E. A. Estes, 2/7/86 ! 345: / ! 346: / ARGUMENTS: none ! 347: / ! 348: / RETURN VALUE: none ! 349: / ! 350: / MODULES CALLED: writerecord(), inputoption(), floor(), wmove(), drandom(), ! 351: / waddstr(), wrefresh(), mvprintw(), wclrtoeol(), wclrtobot() ! 352: / ! 353: / GLOBAL INPUTS: Lines, Other, Player, *stdscr, Fileloc, Luckout, ! 354: / *Enemyname ! 355: / ! 356: / GLOBAL OUTPUTS: Foestrikes, Lines, Player, Luckout ! 357: / ! 358: / DESCRIPTION: ! 359: / Take action action against foe, and decide who is master ! 360: / for next iteration. ! 361: / ! 362: /************************************************************************/ ! 363: ! 364: myturn() ! 365: { ! 366: double dtemp; /* for temporary calculations */ ! 367: int ch; /* input */ ! 368: ! 369: mvaddstr(7, 0, "1:Fight 2:Run Away! 3:Power Blast "); ! 370: if (Luckout) ! 371: clrtoeol(); ! 372: else ! 373: addstr("4:Luckout "); ! 374: ! 375: ch = inputoption(); ! 376: move(Lines = 8, 0); ! 377: clrtobot(); ! 378: ! 379: switch (ch) ! 380: { ! 381: default: /* fight */ ! 382: dtemp = ROLL(2.0, Player.p_might); ! 383: HIT: ! 384: mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, dtemp); ! 385: Player.p_sin += 0.5; ! 386: Player.p_1scratch += dtemp; ! 387: Player.p_istat = I_OFF; ! 388: break; ! 389: ! 390: case '2': /* run away */ ! 391: Player.p_1scratch -= 1.0; /* change this to indicate action */ ! 392: if (drandom() > 0.25) ! 393: { ! 394: mvaddstr(Lines++, 0, "You got away!"); ! 395: Player.p_istat = I_RAN; ! 396: } ! 397: else ! 398: { ! 399: mvprintw(Lines++, 0, "%s is still after you!", Enemyname); ! 400: Player.p_istat = I_STUCK; ! 401: } ! 402: break; ! 403: ! 404: case '3': /* power blast */ ! 405: dtemp = MIN(Player.p_mana, Player.p_level * 5.0); ! 406: Player.p_mana -= dtemp; ! 407: dtemp *= (drandom() + 0.5) * Player.p_magiclvl * 0.2 + 2.0; ! 408: mvprintw(Lines++, 0, "You blasted %s !", Enemyname); ! 409: goto HIT; ! 410: ! 411: case '4': /* luckout */ ! 412: if (Luckout || drandom() > 0.1) ! 413: { ! 414: if (Luckout) ! 415: mvaddstr(Lines++, 0, "You already tried that!"); ! 416: else ! 417: { ! 418: mvaddstr(Lines++, 0, "Not this time . . ."); ! 419: Luckout = TRUE; ! 420: } ! 421: ! 422: Player.p_1scratch -= 1.0; ! 423: Player.p_istat = I_BLEWIT; ! 424: } ! 425: else ! 426: { ! 427: mvaddstr(Lines++, 0, "You just lucked out!"); ! 428: Player.p_1scratch = Other.p_energy * 1.1; ! 429: } ! 430: break; ! 431: } ! 432: ! 433: refresh(); ! 434: Player.p_1scratch = floor(Player.p_1scratch); /* clean up any mess */ ! 435: ! 436: if (Player.p_1scratch > Other.p_energy) ! 437: Player.p_istat = I_KILLED; ! 438: else if (drandom() * Player.p_speed < drandom() * Other.p_speed) ! 439: /* relinquish control */ ! 440: { ! 441: ++Player.p_tampered; ! 442: Foestrikes = TRUE; ! 443: } ! 444: ! 445: writerecord(&Player, Fileloc); /* let foe know what we did */ ! 446: } ! 447: /**/ ! 448: /************************************************************************ ! 449: / ! 450: / FUNCTION NAME: checktampered() ! 451: / ! 452: / FUNCTION: check if current player has been tampered with ! 453: / ! 454: / AUTHOR: E. A. Estes, 12/4/85 ! 455: / ! 456: / ARGUMENTS: none ! 457: / ! 458: / RETURN VALUE: none ! 459: / ! 460: / MODULES CALLED: readrecord(), fread(), fseek(), tampered(), writevoid() ! 461: / ! 462: / GLOBAL INPUTS: *Energyvoidfp, Other, Player, Fileloc, Enrgyvoid ! 463: / ! 464: / GLOBAL OUTPUTS: Enrgyvoid ! 465: / ! 466: / DESCRIPTION: ! 467: / Check for energy voids, holy grail, and tampering by other ! 468: / players. ! 469: / ! 470: /************************************************************************/ ! 471: ! 472: checktampered() ! 473: { ! 474: long loc = 0L; /* location in energy void file */ ! 475: ! 476: /* first check for energy voids */ ! 477: fseek(Energyvoidfp, 0L, 0); ! 478: while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1) ! 479: if (Enrgyvoid.ev_active ! 480: && Enrgyvoid.ev_x == Player.p_x ! 481: && Enrgyvoid.ev_y == Player.p_y) ! 482: /* sitting on one */ ! 483: { ! 484: if (loc > 0L) ! 485: /* not the holy grail; inactivate energy void */ ! 486: { ! 487: Enrgyvoid.ev_active = FALSE; ! 488: writevoid(&Enrgyvoid, loc); ! 489: tampered(T_NRGVOID, 0.0, 0.0); ! 490: } ! 491: else if (Player.p_status != S_CLOAKED) ! 492: /* holy grail */ ! 493: tampered(T_GRAIL, 0.0, 0.0); ! 494: break; ! 495: } ! 496: else ! 497: loc += SZ_VOIDSTRUCT; ! 498: ! 499: /* now check for other things */ ! 500: readrecord(&Other, Fileloc); ! 501: if (Other.p_tampered != T_OFF) ! 502: tampered(Other.p_tampered, Other.p_1scratch, Other.p_2scratch); ! 503: } ! 504: /**/ ! 505: /************************************************************************ ! 506: / ! 507: / FUNCTION NAME: tampered() ! 508: / ! 509: / FUNCTION: take care of tampering by other players ! 510: / ! 511: / AUTHOR: E. A. Estes, 12/4/85 ! 512: / ! 513: / ARGUMENTS: ! 514: / int what - what type of tampering ! 515: / double arg1, arg2 - rest of tampering info ! 516: / ! 517: / RETURN VALUE: none ! 518: / ! 519: / MODULES CALLED: writerecord(), more(), fread(), death(), fseek(), sleep(), ! 520: / floor(), wmove(), waddch(), drandom(), printw(), altercoordinates(), ! 521: / waddstr(), wrefresh(), encounter(), writevoid() ! 522: / ! 523: / GLOBAL INPUTS: Other, Player, *stdscr, Enrgyvoid, *Playersfp ! 524: / ! 525: / GLOBAL OUTPUTS: Other, Player, Changed, Enrgyvoid ! 526: / ! 527: / DESCRIPTION: ! 528: / Take care of energy voids, holy grail, decree and intervention ! 529: / action on current player. ! 530: / ! 531: /************************************************************************/ ! 532: ! 533: tampered(what, arg1, arg2) ! 534: int what; ! 535: double arg1; ! 536: double arg2; ! 537: { ! 538: long loc; /* location in file of other players */ ! 539: ! 540: Changed = TRUE; ! 541: move(4,0); ! 542: ! 543: Player.p_tampered = T_OFF; /* no longer tampered with */ ! 544: ! 545: switch (what) ! 546: { ! 547: case T_NRGVOID: ! 548: addstr("You've hit an energy void !\n"); ! 549: Player.p_mana /= 3.0; ! 550: Player.p_energy /= 2.0; ! 551: Player.p_gold = floor(Player.p_gold/1.25) + 0.1; ! 552: altercoordinates(0.0, 0.0, A_NEAR); ! 553: break; ! 554: ! 555: case T_TRANSPORT: ! 556: addstr("The king transported you ! "); ! 557: if (Player.p_charms > 0) ! 558: { ! 559: addstr("But your charm saved you. . .\n"); ! 560: --Player.p_charms; ! 561: } ! 562: else ! 563: { ! 564: altercoordinates(0.0, 0.0, A_FAR); ! 565: addch('\n'); ! 566: } ! 567: break; ! 568: ! 569: case T_BESTOW: ! 570: printw("The king has bestowed %.0f gold pieces on you !\n", arg1); ! 571: Player.p_gold += arg1; ! 572: break; ! 573: ! 574: case T_CURSED: ! 575: addstr("You've been cursed ! "); ! 576: if (Player.p_blessing) ! 577: { ! 578: addstr("But your blessing saved you. . .\n"); ! 579: Player.p_blessing = FALSE; ! 580: } ! 581: else ! 582: { ! 583: addch('\n'); ! 584: Player.p_poison += 2.0; ! 585: Player.p_energy = 10.0; ! 586: Player.p_maxenergy *= 0.95; ! 587: Player.p_status = S_PLAYING; /* no longer cloaked */ ! 588: } ! 589: break; ! 590: ! 591: case T_VAPORIZED: ! 592: addstr("You have been vaporized!\n"); ! 593: more(7); ! 594: death("Vaporization"); ! 595: break; ! 596: ! 597: case T_MONSTER: ! 598: addstr("The Valar zapped you with a monster!\n"); ! 599: more(7); ! 600: encounter((int) arg1); ! 601: return; ! 602: ! 603: case T_BLESSED: ! 604: addstr("The Valar has blessed you!\n"); ! 605: Player.p_energy = (Player.p_maxenergy *= 1.05) + Player.p_shield; ! 606: Player.p_mana += 500.0; ! 607: Player.p_strength += 0.5; ! 608: Player.p_brains += 0.5; ! 609: Player.p_magiclvl += 0.5; ! 610: Player.p_poison = MIN(0.5, Player.p_poison); ! 611: break; ! 612: ! 613: case T_RELOCATE: ! 614: addstr("You've been relocated. . .\n"); ! 615: altercoordinates(arg1, arg2, A_FORCED); ! 616: break; ! 617: ! 618: case T_HEAL: ! 619: addstr("You've been healed!\n"); ! 620: Player.p_poison -= 0.25; ! 621: Player.p_energy = Player.p_maxenergy + Player.p_shield; ! 622: break; ! 623: ! 624: case T_EXVALAR: ! 625: addstr("You are no longer Valar!\n"); ! 626: Player.p_specialtype = SC_COUNCIL; ! 627: break; ! 628: ! 629: case T_GRAIL: ! 630: addstr("You have found The Holy Grail!!\n"); ! 631: if (Player.p_specialtype < SC_COUNCIL) ! 632: /* must be council of wise to behold grail */ ! 633: { ! 634: addstr("However, you are not experienced enough to behold it.\n"); ! 635: Player.p_sin *= Player.p_sin; ! 636: Player.p_mana += 1000; ! 637: } ! 638: else if (Player.p_specialtype == SC_VALAR ! 639: || Player.p_specialtype == SC_EXVALAR) ! 640: { ! 641: addstr("You have made it to the position of Valar once already.\n"); ! 642: addstr("The Grail is of no more use to you now.\n"); ! 643: } ! 644: else ! 645: { ! 646: addstr("It is now time to see if you are worthy to behold it. . .\n"); ! 647: refresh(); ! 648: sleep(4); ! 649: ! 650: if (drandom() / 2.0 < Player.p_sin) ! 651: { ! 652: addstr("You have failed!\n"); ! 653: Player.p_strength = ! 654: Player.p_mana = ! 655: Player.p_energy = ! 656: Player.p_maxenergy = ! 657: Player.p_magiclvl = ! 658: Player.p_brains = ! 659: Player.p_experience = ! 660: Player.p_quickness = 1.0; ! 661: ! 662: altercoordinates(1.0, 1.0, A_FORCED); ! 663: Player.p_level = 0.0; ! 664: } ! 665: else ! 666: { ! 667: addstr("You made to position of Valar!\n"); ! 668: Player.p_specialtype = SC_VALAR; ! 669: Player.p_lives = 5; ! 670: fseek(Playersfp, 0L, 0); ! 671: loc = 0L; ! 672: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 673: /* search for existing valar */ ! 674: if (Other.p_specialtype == SC_VALAR ! 675: && Other.p_status != S_NOTUSED) ! 676: /* found old valar */ ! 677: { ! 678: Other.p_tampered = T_EXVALAR; ! 679: writerecord(&Other, loc); ! 680: break; ! 681: } ! 682: else ! 683: loc += SZ_PLAYERSTRUCT; ! 684: } ! 685: } ! 686: ! 687: /* move grail to new location */ ! 688: Enrgyvoid.ev_active = TRUE; ! 689: Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6); ! 690: Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6); ! 691: writevoid(&Enrgyvoid, 0L); ! 692: break; ! 693: } ! 694: refresh(); ! 695: sleep(2); ! 696: } ! 697: /**/ ! 698: /************************************************************************ ! 699: / ! 700: / FUNCTION NAME: userlist() ! 701: / ! 702: / FUNCTION: print list of players and locations ! 703: / ! 704: / AUTHOR: E. A. Estes, 2/28/86 ! 705: / ! 706: / ARGUMENTS: ! 707: / bool ingameflag - set if called while playing ! 708: / ! 709: / RETURN VALUE: none ! 710: / ! 711: / MODULES CALLED: descrstatus(), descrlocation(), more(), fread(), fseek(), ! 712: / floor(), wmove(), printw(), waddstr(), distance(), wrefresh(), ! 713: / descrtype(), wclrtobot() ! 714: / ! 715: / GLOBAL INPUTS: LINES, Other, Circle, Wizard, Player, *stdscr, *Playersfp ! 716: / ! 717: / GLOBAL OUTPUTS: none ! 718: / ! 719: / DESCRIPTION: ! 720: / We can only see the coordinate of those closer to the origin ! 721: / from us. ! 722: / Kings and council of the wise can see and can be seen by everyone. ! 723: / Palantirs are good for seeing everyone; and the valar can use ! 724: / one to see through a 'cloak' spell. ! 725: / The valar has no coordinates, and is completely invisible if ! 726: / cloaked. ! 727: / ! 728: /************************************************************************/ ! 729: ! 730: userlist(ingameflag) ! 731: bool ingameflag; ! 732: { ! 733: register int numusers = 0; /* number of users on file */ ! 734: ! 735: if (ingameflag && Player.p_blindness) ! 736: { ! 737: mvaddstr(8, 0, "You cannot see anyone.\n"); ! 738: return; ! 739: } ! 740: ! 741: fseek(Playersfp, 0L, 0); ! 742: mvaddstr(8, 0, ! 743: "Name X Y Lvl Type Login Status\n"); ! 744: ! 745: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 746: { ! 747: if (Other.p_status == S_NOTUSED ! 748: /* record is unused */ ! 749: || (Other.p_specialtype == SC_VALAR && Other.p_status == S_CLOAKED)) ! 750: /* cloaked valar */ ! 751: { ! 752: if (!Wizard) ! 753: /* wizard can see everything on file */ ! 754: continue; ! 755: } ! 756: ! 757: ++numusers; ! 758: ! 759: if (ingameflag && ! 760: /* must be playing for the rest of these conditions */ ! 761: (Player.p_specialtype >= SC_KING ! 762: /* kings and higher can see others */ ! 763: || Other.p_specialtype >= SC_KING ! 764: /* kings and higher can be seen by others */ ! 765: || Circle >= CIRCLE(Other.p_x, Other.p_y) ! 766: /* those nearer the origin can be seen */ ! 767: || Player.p_palantir) ! 768: /* palantir enables one to see others */ ! 769: && (Other.p_status != S_CLOAKED ! 770: || (Player.p_specialtype == SC_VALAR && Player.p_palantir)) ! 771: /* not cloaked; valar can see through cloak with a palantir */ ! 772: && Other.p_specialtype != SC_VALAR) ! 773: /* not a valar */ ! 774: /* coordinates should be printed */ ! 775: printw("%-20s %8.0f %8.0f ", ! 776: Other.p_name, Other.p_x, Other.p_y); ! 777: else ! 778: /* cannot see player's coordinates */ ! 779: printw("%-20s %19.19s ", ! 780: Other.p_name, descrlocation(&Other, TRUE)); ! 781: ! 782: printw("%6.0f %s %-9.9s%s\n", Other.p_level, descrtype(&Other, TRUE), ! 783: Other.p_login, descrstatus(&Other)); ! 784: ! 785: if ((numusers % (LINES - 10)) == 0) ! 786: { ! 787: more(LINES - 1); ! 788: move(9, 0); ! 789: clrtobot(); ! 790: } ! 791: } ! 792: ! 793: printw("Total players on file = %d\n", numusers); ! 794: refresh(); ! 795: } ! 796: /**/ ! 797: /************************************************************************ ! 798: / ! 799: / FUNCTION NAME: throneroom() ! 800: / ! 801: / FUNCTION: king stuff upon entering throne ! 802: / ! 803: / AUTHOR: E. A. Estes, 12/16/85 ! 804: / ! 805: / ARGUMENTS: none ! 806: / ! 807: / RETURN VALUE: none ! 808: / ! 809: / MODULES CALLED: writerecord(), fread(), fseek(), fopen(), wmove(), fclose(), ! 810: / fwrite(), altercoordinates(), waddstr(), fprintf() ! 811: / ! 812: / GLOBAL INPUTS: *Energyvoidfp, Other, Player, *stdscr, Voidfile[], ! 813: / Messfile[], Enrgyvoid, *Playersfp ! 814: / ! 815: / GLOBAL OUTPUTS: Other, Player, Changed ! 816: / ! 817: / DESCRIPTION: ! 818: / If player is not already king, make him/her so if the old king ! 819: / is not playing. ! 820: / Clear energy voids with new king. ! 821: / Print 'decree' prompt. ! 822: / ! 823: /************************************************************************/ ! 824: ! 825: throneroom() ! 826: { ! 827: FILE *fp; /* to clear energy voids */ ! 828: long loc = 0L; /* location of old king in player file */ ! 829: ! 830: if (Player.p_specialtype < SC_KING) ! 831: /* not already king -- assumes crown */ ! 832: { ! 833: fseek(Playersfp, 0L, 0); ! 834: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 835: if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED) ! 836: /* found old king */ ! 837: { ! 838: if (Other.p_status != S_OFF) ! 839: /* old king is playing */ ! 840: { ! 841: mvaddstr( 4, 0, "The king is playing, so you cannot steal his throne\n"); ! 842: altercoordinates(0.0, 0.0, A_NEAR); ! 843: move(6, 0); ! 844: return; ! 845: } ! 846: else ! 847: /* old king is not playing - remove him/her */ ! 848: { ! 849: Other.p_specialtype = SC_NONE; ! 850: if (Other.p_crowns) ! 851: --Other.p_crowns; ! 852: writerecord(&Other, loc); ! 853: break; ! 854: } ! 855: } ! 856: else ! 857: loc += SZ_PLAYERSTRUCT; ! 858: ! 859: /* make player new king */ ! 860: Changed = TRUE; ! 861: Player.p_specialtype = SC_KING; ! 862: mvaddstr(4, 0, "You have become king!\n"); ! 863: ! 864: /* let everyone else know */ ! 865: fp = fopen(Messfile, "w"); ! 866: fprintf(fp, "All hail the new king!"); ! 867: fclose(fp); ! 868: ! 869: /* clear all energy voids; retain location of holy grail */ ! 870: fseek(Energyvoidfp, 0L, 0); ! 871: fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp); ! 872: fp = fopen(Voidfile, "w"); ! 873: fwrite((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, fp); ! 874: fclose(fp); ! 875: } ! 876: ! 877: mvaddstr(6, 0, "0:Decree "); ! 878: } ! 879: /**/ ! 880: /************************************************************************ ! 881: / ! 882: / FUNCTION NAME: dotampered() ! 883: / ! 884: / FUNCTION: king and valar special options ! 885: / ! 886: / AUTHOR: E. A. Estes, 2/28/86 ! 887: / ! 888: / ARGUMENTS: none ! 889: / ! 890: / RETURN VALUE: none ! 891: / ! 892: / MODULES CALLED: writerecord(), truncstring(), fread(), fseek(), fopen(), ! 893: / floor(), wmove(), drandom(), fclose(), fwrite(), sscanf(), strcmp(), ! 894: / infloat(), waddstr(), findname(), distance(), userlist(), mvprintw(), ! 895: / allocvoid(), getanswer(), getstring(), wclrtoeol(), writevoid() ! 896: / ! 897: / GLOBAL INPUTS: *Energyvoidfp, Other, Illcmd[], Wizard, Player, *stdscr, ! 898: / Databuf[], Goldfile[], Enrgyvoid ! 899: / ! 900: / GLOBAL OUTPUTS: Other, Player, Enrgyvoid ! 901: / ! 902: / DESCRIPTION: ! 903: / Tamper with other players. Handle king/valar specific options. ! 904: / ! 905: /************************************************************************/ ! 906: ! 907: dotampered() ! 908: { ! 909: short tamper; /* value for tampering with other players */ ! 910: char *option; /* pointer to option description */ ! 911: double temp1 = 0.0, temp2 = 0.0; /* other tampering values */ ! 912: int ch; /* input */ ! 913: long loc; /* location in energy void file */ ! 914: FILE *fp; /* for opening gold file */ ! 915: ! 916: move(6, 0); ! 917: clrtoeol(); ! 918: if (Player.p_specialtype < SC_COUNCIL && !Wizard) ! 919: /* king options */ ! 920: { ! 921: addstr("1:Transport 2:Curse 3:Energy Void 4:Bestow 5:Collect Taxes "); ! 922: ! 923: ch = getanswer(" ", TRUE); ! 924: move(6, 0); ! 925: clrtoeol(); ! 926: move(4, 0); ! 927: switch (ch) ! 928: { ! 929: case '1': /* transport someone */ ! 930: tamper = T_TRANSPORT; ! 931: option = "transport"; ! 932: break; ! 933: ! 934: case '2': /* curse another */ ! 935: tamper = T_CURSED; ! 936: option = "curse"; ! 937: break; ! 938: ! 939: case '3': /* create energy void */ ! 940: if ((loc = allocvoid()) > 20L * SZ_VOIDSTRUCT) ! 941: /* can only have 20 void active at once */ ! 942: mvaddstr(5, 0, "Sorry, void creation limit reached.\n"); ! 943: else ! 944: { ! 945: addstr("Enter the X Y coordinates of void ? "); ! 946: getstring(Databuf, SZ_DATABUF); ! 947: sscanf(Databuf, "%lf %lf", &temp1, &temp2); ! 948: Enrgyvoid.ev_x = floor(temp1); ! 949: Enrgyvoid.ev_y = floor(temp2); ! 950: Enrgyvoid.ev_active = TRUE; ! 951: writevoid(&Enrgyvoid, loc); ! 952: mvaddstr(5, 0, "It is done.\n"); ! 953: } ! 954: return; ! 955: ! 956: case '4': /* bestow gold to subject */ ! 957: tamper = T_BESTOW; ! 958: addstr("How much gold to bestow ? "); ! 959: temp1 = infloat(); ! 960: if (temp1 > Player.p_gold || temp1 < 0) ! 961: { ! 962: mvaddstr(5, 0, "You don't have that !\n"); ! 963: return; ! 964: } ! 965: ! 966: /* adjust gold after we are sure it will be given to someone */ ! 967: option = "give gold to"; ! 968: break; ! 969: ! 970: case '5': /* collect accumulated taxes */ ! 971: if ((fp = fopen(Goldfile, "r+")) != NULL) ! 972: /* collect taxes */ ! 973: { ! 974: fread((char *) &temp1, sizeof(double), 1, fp); ! 975: fseek(fp, 0L, 0); ! 976: /* clear out value */ ! 977: temp2 = 0.0; ! 978: fwrite((char *) &temp2, sizeof(double), 1, fp); ! 979: fclose(fp); ! 980: } ! 981: ! 982: mvprintw(4, 0, "You have collected %.0f in gold.\n", temp1); ! 983: Player.p_gold += floor(temp1); ! 984: return; ! 985: ! 986: default: ! 987: return; ! 988: } ! 989: /* end of king options */ ! 990: } ! 991: else ! 992: /* council of wise, valar, wizard options */ ! 993: { ! 994: addstr("1:Heal "); ! 995: if (Player.p_palantir || Wizard) ! 996: addstr("2:Seek Grail "); ! 997: if (Player.p_specialtype == SC_VALAR || Wizard) ! 998: addstr("3:Throw Monster 4:Relocate 5:Bless "); ! 999: if (Wizard) ! 1000: addstr("6:Vaporize "); ! 1001: ! 1002: ch = getanswer(" ", TRUE); ! 1003: if (!Wizard) ! 1004: { ! 1005: if (ch > '2' && Player.p_specialtype != SC_VALAR) ! 1006: { ! 1007: ILLCMD(); ! 1008: return; ! 1009: } ! 1010: ! 1011: if (Player.p_mana < MM_INTERVENE) ! 1012: { ! 1013: mvaddstr(5, 0, "No mana left.\n"); ! 1014: return; ! 1015: } ! 1016: else ! 1017: Player.p_mana -= MM_INTERVENE; ! 1018: } ! 1019: ! 1020: switch (ch) ! 1021: { ! 1022: case '1': /* heal another */ ! 1023: tamper = T_HEAL; ! 1024: option = "heal"; ! 1025: break; ! 1026: ! 1027: case '2': /* seek grail */ ! 1028: if (Player.p_palantir) ! 1029: /* need a palantir to seek */ ! 1030: { ! 1031: fseek(Energyvoidfp, 0L, 0); ! 1032: fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp); ! 1033: temp1 = distance(Player.p_x, Enrgyvoid.ev_x, Player.p_y, Enrgyvoid.ev_y); ! 1034: temp1 += ROLL(-temp1 / 10.0, temp1 / 5.0); /* add some error */ ! 1035: mvprintw(5, 0, "The palantir says the Grail is about %.0f away.\n", temp1); ! 1036: } ! 1037: else ! 1038: /* no palantir */ ! 1039: mvaddstr(5, 0, "You need a palantir to seek the Grail.\n"); ! 1040: return; ! 1041: ! 1042: case '3': /* lob monster at someone */ ! 1043: mvaddstr(4, 0, "Which monster [0-99] ? "); ! 1044: temp1 = infloat(); ! 1045: temp1 = MAX(0.0, MIN(99.0, temp1)); ! 1046: tamper = T_MONSTER; ! 1047: option = "throw a monster at"; ! 1048: break; ! 1049: ! 1050: case '4': /* move another player */ ! 1051: mvaddstr(4, 0, "New X Y coordinates ? "); ! 1052: getstring(Databuf, SZ_DATABUF); ! 1053: sscanf(Databuf, "%lf %lf", &temp1, &temp2); ! 1054: tamper = T_RELOCATE; ! 1055: option = "relocate"; ! 1056: break; ! 1057: ! 1058: case '5': /* bless a player */ ! 1059: tamper = T_BLESSED; ! 1060: option = "bless"; ! 1061: break; ! 1062: ! 1063: case '6': /* kill off a player */ ! 1064: if (Wizard) ! 1065: { ! 1066: tamper = T_VAPORIZED; ! 1067: option = "vaporize"; ! 1068: break; ! 1069: } ! 1070: else ! 1071: return; ! 1072: ! 1073: default: ! 1074: return; ! 1075: } ! 1076: ! 1077: /* adjust age after we are sure intervention will be done */ ! 1078: /* end of valar, etc. options */ ! 1079: } ! 1080: ! 1081: for (;;) ! 1082: /* prompt for player to affect */ ! 1083: { ! 1084: mvprintw(4, 0, "Who do you want to %s ? ", option); ! 1085: getstring(Databuf, SZ_DATABUF); ! 1086: truncstring(Databuf); ! 1087: ! 1088: if (Databuf[0] == '\0') ! 1089: userlist(TRUE); ! 1090: else ! 1091: break; ! 1092: } ! 1093: ! 1094: if (strcmp(Player.p_name, Databuf) != 0) ! 1095: /* name other than self */ ! 1096: { ! 1097: if ((loc = findname(Databuf, &Other)) >= 0L) ! 1098: { ! 1099: if (Other.p_tampered != T_OFF) ! 1100: { ! 1101: mvaddstr(5, 0, "That person has something pending already.\n"); ! 1102: return; ! 1103: } ! 1104: else ! 1105: { ! 1106: if (tamper == T_RELOCATE ! 1107: && CIRCLE(temp1, temp2) < CIRCLE(Other.p_x, Other.p_y) ! 1108: && !Wizard) ! 1109: mvaddstr(5, 0, "Cannot move someone closer to the Lord's Chamber.\n"); ! 1110: else ! 1111: { ! 1112: if (tamper == T_BESTOW) Player.p_gold -= floor(temp1); ! 1113: if (!Wizard && (tamper == T_HEAL || tamper == T_MONSTER || ! 1114: tamper == T_RELOCATE || tamper == T_BLESSED)) ! 1115: Player.p_age += N_AGE; /* age penalty */ ! 1116: Other.p_tampered = tamper; ! 1117: Other.p_1scratch = floor(temp1); ! 1118: Other.p_2scratch = floor(temp2); ! 1119: writerecord(&Other, loc); ! 1120: mvaddstr(5, 0, "It is done.\n"); ! 1121: } ! 1122: return; ! 1123: } ! 1124: } ! 1125: else ! 1126: /* player not found */ ! 1127: mvaddstr(5, 0, "There is no one by that name.\n"); ! 1128: } ! 1129: else ! 1130: /* self */ ! 1131: mvaddstr(5, 0, "You may not do it to yourself!\n"); ! 1132: } ! 1133: /**/ ! 1134: /************************************************************************ ! 1135: / ! 1136: / FUNCTION NAME: writevoid() ! 1137: / ! 1138: / FUNCTION: update energy void entry in energy void file ! 1139: / ! 1140: / AUTHOR: E. A. Estes, 12/4/85 ! 1141: / ! 1142: / ARGUMENTS: ! 1143: / struct energyvoid *vp - pointer to structure to write to file ! 1144: / long loc - location in file to update ! 1145: / ! 1146: / RETURN VALUE: none ! 1147: / ! 1148: / MODULES CALLED: fseek(), fwrite(), fflush() ! 1149: / ! 1150: / GLOBAL INPUTS: *Energyvoidfp ! 1151: / ! 1152: / GLOBAL OUTPUTS: none ! 1153: / ! 1154: / DESCRIPTION: ! 1155: / Write out energy void structure at specified location. ! 1156: / ! 1157: /************************************************************************/ ! 1158: ! 1159: writevoid(vp, loc) ! 1160: register struct energyvoid *vp; ! 1161: long loc; ! 1162: { ! 1163: ! 1164: fseek(Energyvoidfp, loc, 0); ! 1165: fwrite((char *) vp, SZ_VOIDSTRUCT, 1, Energyvoidfp); ! 1166: fflush(Energyvoidfp); ! 1167: fseek(Energyvoidfp, 0L, 0); ! 1168: } ! 1169: /**/ ! 1170: /************************************************************************ ! 1171: / ! 1172: / FUNCTION NAME: allocvoid() ! 1173: / ! 1174: / FUNCTION: allocate space for a new energy void ! 1175: / ! 1176: / AUTHOR: E. A. Estes, 12/4/85 ! 1177: / ! 1178: / ARGUMENTS: none ! 1179: / ! 1180: / RETURN VALUE: location of new energy void space ! 1181: / ! 1182: / MODULES CALLED: fread(), fseek() ! 1183: / ! 1184: / GLOBAL INPUTS: *Energyvoidfp, Enrgyvoid ! 1185: / ! 1186: / GLOBAL OUTPUTS: none ! 1187: / ! 1188: / DESCRIPTION: ! 1189: / Search energy void file for an inactive entry and return its ! 1190: / location. ! 1191: / If no inactive ones are found, return one more than last location. ! 1192: / ! 1193: /************************************************************************/ ! 1194: ! 1195: long ! 1196: allocvoid() ! 1197: { ! 1198: long loc = 0L; /* location of new energy void */ ! 1199: ! 1200: fseek(Energyvoidfp, 0L, 0); ! 1201: while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1) ! 1202: if (Enrgyvoid.ev_active) ! 1203: loc += SZ_VOIDSTRUCT; ! 1204: else ! 1205: break; ! 1206: ! 1207: return(loc); ! 1208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.