From bcced3608bdd120315d4ed1d9b9478f7caa4a2f1 Mon Sep 17 00:00:00 2001 From: jtc Date: Fri, 21 Oct 1994 21:19:39 +0000 Subject: phantasia(6), from 44lite --- phantasia/interplayer.c | 1208 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1208 insertions(+) create mode 100644 phantasia/interplayer.c (limited to 'phantasia/interplayer.c') diff --git a/phantasia/interplayer.c b/phantasia/interplayer.c new file mode 100644 index 00000000..0c923f0c --- /dev/null +++ b/phantasia/interplayer.c @@ -0,0 +1,1208 @@ +/* + * interplayer.c - player to player routines for Phantasia + */ + +#include "include.h" + +/************************************************************************ +/ +/ FUNCTION NAME: checkbattle() +/ +/ FUNCTION: check to see if current player should battle another +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: battleplayer(), fread(), fseek() +/ +/ GLOBAL INPUTS: Other, Users, Player, Fileloc, *Playersfp +/ +/ GLOBAL OUTPUTS: Users +/ +/ DESCRIPTION: +/ Seach player file for a foe at the same coordinates as the +/ current player. +/ Also update user count. +/ +/************************************************************************/ + +checkbattle() +{ +long foeloc = 0L; /* location in file of person to fight */ + + Users = 0; + fseek(Playersfp, 0L, 0); + + while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) + { + if (Other.p_status != S_OFF + && Other.p_status != S_NOTUSED + && Other.p_status != S_HUNGUP + && (Other.p_status != S_CLOAKED || Other.p_specialtype != SC_VALAR)) + /* player is on and not a cloaked valar */ + { + ++Users; + + if (Player.p_x == Other.p_x + && Player.p_y == Other.p_y + /* same coordinates */ + && foeloc != Fileloc + /* not self */ + && Player.p_status == S_PLAYING + && (Other.p_status == S_PLAYING || Other.p_status == S_INBATTLE) + /* both are playing */ + && Other.p_specialtype != SC_VALAR + && Player.p_specialtype != SC_VALAR) + /* neither is valar */ + { + battleplayer(foeloc); + return; + } + } + foeloc += SZ_PLAYERSTRUCT; + } +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: battleplayer() +/ +/ FUNCTION: inter-terminal battle with another player +/ +/ AUTHOR: E. A. Estes, 2/15/86 +/ +/ ARGUMENTS: +/ long foeplace - location in player file of person to battle +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: readrecord(), readmessage(), writerecord(), collecttaxes(), +/ displaystats(), fabs(), more(), death(), sleep(), wmove(), waddch(), printw(), +/ myturn(), altercoordinates(), waddstr(), wrefresh(), mvprintw(), +/ getanswer(), wclrtoeol(), wclrtobot() +/ +/ GLOBAL INPUTS: Foestrikes, LINES, Lines, Other, Shield, Player, *stdscr, +/ Fileloc, *Enemyname +/ +/ GLOBAL OUTPUTS: Foestrikes, Lines, Shield, Player, Luckout, *Enemyname +/ +/ DESCRIPTION: +/ Inter-terminal battle is a very fragile and slightly klugy thing. +/ At any time, one player is master and the other is slave. +/ We pick who is master first by speed and level. After that, +/ the slave waits for the master to relinquish its turn, and +/ the slave becomes master, and so on. +/ +/ The items in the player structure which control the handshake are: +/ p_tampered: +/ master increments this to relinquish control +/ p_istat: +/ master sets this to specify particular action +/ p_1scratch: +/ set to total damage inflicted so far; changes to indicate action +/ +/************************************************************************/ + +battleplayer(foeplace) +long foeplace; +{ +double dtemp; /* for temporary calculations */ +double oldhits = 0.0; /* previous damage inflicted by foe */ +register int loop; /* for timing out */ +int ch; /* input */ +short oldtampered; /* old value of foe's p_tampered */ + + Lines = 8; + Luckout = FALSE; + mvaddstr(4, 0, "Preparing for battle!\n"); + refresh(); + +#ifdef SYS5 + flushinp(); +#endif + + /* set up variables, file, etc. */ + Player.p_status = S_INBATTLE; + Shield = Player.p_energy; + + /* if p_tampered is not 0, someone else may try to change it (king, etc.) */ + Player.p_tampered = oldtampered = 1; + Player.p_1scratch = 0.0; + Player.p_istat = I_OFF; + + readrecord(&Other, foeplace); + if (fabs(Player.p_level - Other.p_level) > 20.0) + /* see if players are greatly mismatched */ + { + dtemp = (Player.p_level - Other.p_level) / MAX(Player.p_level, Other.p_level); + if (dtemp < -0.5) + /* foe outweighs this one */ + Player.p_speed *= 2.0; + } + + writerecord(&Player, Fileloc); /* write out all our info */ + + if (Player.p_blindness) + Enemyname = "someone"; + else + Enemyname = Other.p_name; + + mvprintw(6, 0, "You have encountered %s Level: %.0f\n", Enemyname, Other.p_level); + refresh(); + + for (loop = 0; Other.p_status != S_INBATTLE && loop < 30; ++loop) + /* wait for foe to respond */ + { + readrecord(&Other, foeplace); + sleep(1); + } + + if (Other.p_status != S_INBATTLE) + /* foe did not respond */ + { + mvprintw(5, 0, "%s is not responding.\n", Enemyname); + goto LEAVE; + } + /* else, we are ready to battle */ + + move(4, 0); + clrtoeol(); + + /* + * determine who is first master + * if neither player is faster, check level + * if neither level is greater, battle is not allowed + * (this should never happen, but we have to handle it) + */ + if (Player.p_speed > Other.p_speed) + Foestrikes = FALSE; + else if (Other.p_speed > Player.p_speed) + Foestrikes = TRUE; + else if (Player.p_level > Other.p_level) + Foestrikes = FALSE; + else if (Other.p_level > Player.p_level) + Foestrikes = TRUE; + else + /* no one is faster */ + { + printw("You can't fight %s yet.", Enemyname); + goto LEAVE; + } + + for (;;) + { + displaystats(); + readmessage(); + mvprintw(1, 26, "%20.0f", Shield); /* overprint energy */ + + if (!Foestrikes) + /* take action against foe */ + myturn(); + else + /* wait for foe to take action */ + { + mvaddstr(4, 0, "Waiting...\n"); + clrtoeol(); + refresh(); + + for (loop = 0; loop < 20; ++loop) + /* wait for foe to act */ + { + readrecord(&Other, foeplace); + if (Other.p_1scratch != oldhits) + /* p_1scratch changes to indicate action */ + break; + else + /* wait and try again */ + { + sleep(1); + addch('.'); + refresh(); + } + } + + if (Other.p_1scratch == oldhits) + { + /* timeout */ + mvaddstr(22, 0, "Timeout: waiting for response. Do you want to wait ? "); + ch = getanswer("NY", FALSE); + move(22, 0); + clrtobot(); + if (ch == 'Y') + continue; + else + break; + } + else + /* foe took action */ + { + switch (Other.p_istat) + { + case I_RAN: /* foe ran away */ + mvprintw(Lines++, 0, "%s ran away!", Enemyname); + break; + + case I_STUCK: /* foe tried to run, but couldn't */ + mvprintw(Lines++, 0, "%s tried to run away.", Enemyname); + break; + + case I_BLEWIT: /* foe tried to luckout, but didn't */ + mvprintw(Lines++, 0, "%s tried to luckout!", Enemyname); + break; + + default: + dtemp = Other.p_1scratch - oldhits; + mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, dtemp); + Shield -= dtemp; + break; + } + + oldhits = Other.p_1scratch; /* keep track of old hits */ + + if (Other.p_tampered != oldtampered) + /* p_tampered changes to relinquish turn */ + { + oldtampered = Other.p_tampered; + Foestrikes = FALSE; + } + } + } + + /* decide what happens next */ + refresh(); + if (Lines > LINES - 2) + { + more(Lines); + move(Lines = 8, 0); + clrtobot(); + } + + if (Other.p_istat == I_KILLED || Shield < 0.0) + /* we died */ + { + Shield = -2.0; /* insure this value is negative */ + break; + } + + if (Player.p_istat == I_KILLED) + /* we killed foe; award treasre */ + { + mvprintw(Lines++, 0, "You killed %s!", Enemyname); + Player.p_experience += Other.p_experience; + Player.p_crowns += (Player.p_level < 1000.0) ? Other.p_crowns : 0; + Player.p_amulets += Other.p_amulets; + Player.p_charms += Other.p_charms; + collecttaxes(Other.p_gold, Other.p_gems); + Player.p_sword = MAX(Player.p_sword, Other.p_sword); + Player.p_shield = MAX(Player.p_shield, Other.p_shield); + Player.p_quksilver = MAX(Player.p_quksilver, Other.p_quksilver); + if (Other.p_virgin && !Player.p_virgin) + { + mvaddstr(Lines++, 0, "You have rescued a virgin. Will you be honorable ? "); + if ((ch = getanswer("YN", FALSE)) == 'Y') + Player.p_virgin = TRUE; + else + { + ++Player.p_sin; + Player.p_experience += 8000.0; + } + } + sleep(3); /* give other person time to die */ + break; + } + else if (Player.p_istat == I_RAN || Other.p_istat == I_RAN) + /* either player ran away */ + break; + } + +LEAVE: + /* clean up things and leave */ + writerecord(&Player, Fileloc); /* update a final time */ + altercoordinates(0.0, 0.0, A_NEAR); /* move away from battle site */ + Player.p_energy = Shield; /* set energy to actual value */ + Player.p_tampered = T_OFF; /* clear p_tampered */ + + more(Lines); /* pause */ + + move(4, 0); + clrtobot(); /* clear bottom area of screen */ + + if (Player.p_energy < 0.0) + /* we are dead */ + death("Interterminal battle"); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: myturn() +/ +/ FUNCTION: process players action against foe in battle +/ +/ AUTHOR: E. A. Estes, 2/7/86 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: writerecord(), inputoption(), floor(), wmove(), drandom(), +/ waddstr(), wrefresh(), mvprintw(), wclrtoeol(), wclrtobot() +/ +/ GLOBAL INPUTS: Lines, Other, Player, *stdscr, Fileloc, Luckout, +/ *Enemyname +/ +/ GLOBAL OUTPUTS: Foestrikes, Lines, Player, Luckout +/ +/ DESCRIPTION: +/ Take action action against foe, and decide who is master +/ for next iteration. +/ +/************************************************************************/ + +myturn() +{ +double dtemp; /* for temporary calculations */ +int ch; /* input */ + + mvaddstr(7, 0, "1:Fight 2:Run Away! 3:Power Blast "); + if (Luckout) + clrtoeol(); + else + addstr("4:Luckout "); + + ch = inputoption(); + move(Lines = 8, 0); + clrtobot(); + + switch (ch) + { + default: /* fight */ + dtemp = ROLL(2.0, Player.p_might); +HIT: + mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, dtemp); + Player.p_sin += 0.5; + Player.p_1scratch += dtemp; + Player.p_istat = I_OFF; + break; + + case '2': /* run away */ + Player.p_1scratch -= 1.0; /* change this to indicate action */ + if (drandom() > 0.25) + { + mvaddstr(Lines++, 0, "You got away!"); + Player.p_istat = I_RAN; + } + else + { + mvprintw(Lines++, 0, "%s is still after you!", Enemyname); + Player.p_istat = I_STUCK; + } + break; + + case '3': /* power blast */ + dtemp = MIN(Player.p_mana, Player.p_level * 5.0); + Player.p_mana -= dtemp; + dtemp *= (drandom() + 0.5) * Player.p_magiclvl * 0.2 + 2.0; + mvprintw(Lines++, 0, "You blasted %s !", Enemyname); + goto HIT; + + case '4': /* luckout */ + if (Luckout || drandom() > 0.1) + { + if (Luckout) + mvaddstr(Lines++, 0, "You already tried that!"); + else + { + mvaddstr(Lines++, 0, "Not this time . . ."); + Luckout = TRUE; + } + + Player.p_1scratch -= 1.0; + Player.p_istat = I_BLEWIT; + } + else + { + mvaddstr(Lines++, 0, "You just lucked out!"); + Player.p_1scratch = Other.p_energy * 1.1; + } + break; + } + + refresh(); + Player.p_1scratch = floor(Player.p_1scratch); /* clean up any mess */ + + if (Player.p_1scratch > Other.p_energy) + Player.p_istat = I_KILLED; + else if (drandom() * Player.p_speed < drandom() * Other.p_speed) + /* relinquish control */ + { + ++Player.p_tampered; + Foestrikes = TRUE; + } + + writerecord(&Player, Fileloc); /* let foe know what we did */ +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: checktampered() +/ +/ FUNCTION: check if current player has been tampered with +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: readrecord(), fread(), fseek(), tampered(), writevoid() +/ +/ GLOBAL INPUTS: *Energyvoidfp, Other, Player, Fileloc, Enrgyvoid +/ +/ GLOBAL OUTPUTS: Enrgyvoid +/ +/ DESCRIPTION: +/ Check for energy voids, holy grail, and tampering by other +/ players. +/ +/************************************************************************/ + +checktampered() +{ +long loc = 0L; /* location in energy void file */ + + /* first check for energy voids */ + fseek(Energyvoidfp, 0L, 0); + while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1) + if (Enrgyvoid.ev_active + && Enrgyvoid.ev_x == Player.p_x + && Enrgyvoid.ev_y == Player.p_y) + /* sitting on one */ + { + if (loc > 0L) + /* not the holy grail; inactivate energy void */ + { + Enrgyvoid.ev_active = FALSE; + writevoid(&Enrgyvoid, loc); + tampered(T_NRGVOID, 0.0, 0.0); + } + else if (Player.p_status != S_CLOAKED) + /* holy grail */ + tampered(T_GRAIL, 0.0, 0.0); + break; + } + else + loc += SZ_VOIDSTRUCT; + + /* now check for other things */ + readrecord(&Other, Fileloc); + if (Other.p_tampered != T_OFF) + tampered(Other.p_tampered, Other.p_1scratch, Other.p_2scratch); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: tampered() +/ +/ FUNCTION: take care of tampering by other players +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: +/ int what - what type of tampering +/ double arg1, arg2 - rest of tampering info +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: writerecord(), more(), fread(), death(), fseek(), sleep(), +/ floor(), wmove(), waddch(), drandom(), printw(), altercoordinates(), +/ waddstr(), wrefresh(), encounter(), writevoid() +/ +/ GLOBAL INPUTS: Other, Player, *stdscr, Enrgyvoid, *Playersfp +/ +/ GLOBAL OUTPUTS: Other, Player, Changed, Enrgyvoid +/ +/ DESCRIPTION: +/ Take care of energy voids, holy grail, decree and intervention +/ action on current player. +/ +/************************************************************************/ + +tampered(what, arg1, arg2) +int what; +double arg1; +double arg2; +{ +long loc; /* location in file of other players */ + + Changed = TRUE; + move(4,0); + + Player.p_tampered = T_OFF; /* no longer tampered with */ + + switch (what) + { + case T_NRGVOID: + addstr("You've hit an energy void !\n"); + Player.p_mana /= 3.0; + Player.p_energy /= 2.0; + Player.p_gold = floor(Player.p_gold/1.25) + 0.1; + altercoordinates(0.0, 0.0, A_NEAR); + break; + + case T_TRANSPORT: + addstr("The king transported you ! "); + if (Player.p_charms > 0) + { + addstr("But your charm saved you. . .\n"); + --Player.p_charms; + } + else + { + altercoordinates(0.0, 0.0, A_FAR); + addch('\n'); + } + break; + + case T_BESTOW: + printw("The king has bestowed %.0f gold pieces on you !\n", arg1); + Player.p_gold += arg1; + break; + + case T_CURSED: + addstr("You've been cursed ! "); + if (Player.p_blessing) + { + addstr("But your blessing saved you. . .\n"); + Player.p_blessing = FALSE; + } + else + { + addch('\n'); + Player.p_poison += 2.0; + Player.p_energy = 10.0; + Player.p_maxenergy *= 0.95; + Player.p_status = S_PLAYING; /* no longer cloaked */ + } + break; + + case T_VAPORIZED: + addstr("You have been vaporized!\n"); + more(7); + death("Vaporization"); + break; + + case T_MONSTER: + addstr("The Valar zapped you with a monster!\n"); + more(7); + encounter((int) arg1); + return; + + case T_BLESSED: + addstr("The Valar has blessed you!\n"); + Player.p_energy = (Player.p_maxenergy *= 1.05) + Player.p_shield; + Player.p_mana += 500.0; + Player.p_strength += 0.5; + Player.p_brains += 0.5; + Player.p_magiclvl += 0.5; + Player.p_poison = MIN(0.5, Player.p_poison); + break; + + case T_RELOCATE: + addstr("You've been relocated. . .\n"); + altercoordinates(arg1, arg2, A_FORCED); + break; + + case T_HEAL: + addstr("You've been healed!\n"); + Player.p_poison -= 0.25; + Player.p_energy = Player.p_maxenergy + Player.p_shield; + break; + + case T_EXVALAR: + addstr("You are no longer Valar!\n"); + Player.p_specialtype = SC_COUNCIL; + break; + + case T_GRAIL: + addstr("You have found The Holy Grail!!\n"); + if (Player.p_specialtype < SC_COUNCIL) + /* must be council of wise to behold grail */ + { + addstr("However, you are not experienced enough to behold it.\n"); + Player.p_sin *= Player.p_sin; + Player.p_mana += 1000; + } + else if (Player.p_specialtype == SC_VALAR + || Player.p_specialtype == SC_EXVALAR) + { + addstr("You have made it to the position of Valar once already.\n"); + addstr("The Grail is of no more use to you now.\n"); + } + else + { + addstr("It is now time to see if you are worthy to behold it. . .\n"); + refresh(); + sleep(4); + + if (drandom() / 2.0 < Player.p_sin) + { + addstr("You have failed!\n"); + Player.p_strength = + Player.p_mana = + Player.p_energy = + Player.p_maxenergy = + Player.p_magiclvl = + Player.p_brains = + Player.p_experience = + Player.p_quickness = 1.0; + + altercoordinates(1.0, 1.0, A_FORCED); + Player.p_level = 0.0; + } + else + { + addstr("You made to position of Valar!\n"); + Player.p_specialtype = SC_VALAR; + Player.p_lives = 5; + fseek(Playersfp, 0L, 0); + loc = 0L; + while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) + /* search for existing valar */ + if (Other.p_specialtype == SC_VALAR + && Other.p_status != S_NOTUSED) + /* found old valar */ + { + Other.p_tampered = T_EXVALAR; + writerecord(&Other, loc); + break; + } + else + loc += SZ_PLAYERSTRUCT; + } + } + + /* move grail to new location */ + Enrgyvoid.ev_active = TRUE; + Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6); + Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6); + writevoid(&Enrgyvoid, 0L); + break; + } + refresh(); + sleep(2); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: userlist() +/ +/ FUNCTION: print list of players and locations +/ +/ AUTHOR: E. A. Estes, 2/28/86 +/ +/ ARGUMENTS: +/ bool ingameflag - set if called while playing +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: descrstatus(), descrlocation(), more(), fread(), fseek(), +/ floor(), wmove(), printw(), waddstr(), distance(), wrefresh(), +/ descrtype(), wclrtobot() +/ +/ GLOBAL INPUTS: LINES, Other, Circle, Wizard, Player, *stdscr, *Playersfp +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ We can only see the coordinate of those closer to the origin +/ from us. +/ Kings and council of the wise can see and can be seen by everyone. +/ Palantirs are good for seeing everyone; and the valar can use +/ one to see through a 'cloak' spell. +/ The valar has no coordinates, and is completely invisible if +/ cloaked. +/ +/************************************************************************/ + +userlist(ingameflag) +bool ingameflag; +{ +register int numusers = 0; /* number of users on file */ + + if (ingameflag && Player.p_blindness) + { + mvaddstr(8, 0, "You cannot see anyone.\n"); + return; + } + + fseek(Playersfp, 0L, 0); + mvaddstr(8, 0, + "Name X Y Lvl Type Login Status\n"); + + while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) + { + if (Other.p_status == S_NOTUSED + /* record is unused */ + || (Other.p_specialtype == SC_VALAR && Other.p_status == S_CLOAKED)) + /* cloaked valar */ + { + if (!Wizard) + /* wizard can see everything on file */ + continue; + } + + ++numusers; + + if (ingameflag && + /* must be playing for the rest of these conditions */ + (Player.p_specialtype >= SC_KING + /* kings and higher can see others */ + || Other.p_specialtype >= SC_KING + /* kings and higher can be seen by others */ + || Circle >= CIRCLE(Other.p_x, Other.p_y) + /* those nearer the origin can be seen */ + || Player.p_palantir) + /* palantir enables one to see others */ + && (Other.p_status != S_CLOAKED + || (Player.p_specialtype == SC_VALAR && Player.p_palantir)) + /* not cloaked; valar can see through cloak with a palantir */ + && Other.p_specialtype != SC_VALAR) + /* not a valar */ + /* coordinates should be printed */ + printw("%-20s %8.0f %8.0f ", + Other.p_name, Other.p_x, Other.p_y); + else + /* cannot see player's coordinates */ + printw("%-20s %19.19s ", + Other.p_name, descrlocation(&Other, TRUE)); + + printw("%6.0f %s %-9.9s%s\n", Other.p_level, descrtype(&Other, TRUE), + Other.p_login, descrstatus(&Other)); + + if ((numusers % (LINES - 10)) == 0) + { + more(LINES - 1); + move(9, 0); + clrtobot(); + } + } + + printw("Total players on file = %d\n", numusers); + refresh(); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: throneroom() +/ +/ FUNCTION: king stuff upon entering throne +/ +/ AUTHOR: E. A. Estes, 12/16/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: writerecord(), fread(), fseek(), fopen(), wmove(), fclose(), +/ fwrite(), altercoordinates(), waddstr(), fprintf() +/ +/ GLOBAL INPUTS: *Energyvoidfp, Other, Player, *stdscr, +/ Enrgyvoid, *Playersfp +/ +/ GLOBAL OUTPUTS: Other, Player, Changed +/ +/ DESCRIPTION: +/ If player is not already king, make him/her so if the old king +/ is not playing. +/ Clear energy voids with new king. +/ Print 'decree' prompt. +/ +/************************************************************************/ + +throneroom() +{ +FILE *fp; /* to clear energy voids */ +long loc = 0L; /* location of old king in player file */ + + if (Player.p_specialtype < SC_KING) + /* not already king -- assumes crown */ + { + fseek(Playersfp, 0L, 0); + while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) + if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED) + /* found old king */ + { + if (Other.p_status != S_OFF) + /* old king is playing */ + { + mvaddstr( 4, 0, "The king is playing, so you cannot steal his throne\n"); + altercoordinates(0.0, 0.0, A_NEAR); + move(6, 0); + return; + } + else + /* old king is not playing - remove him/her */ + { + Other.p_specialtype = SC_NONE; + if (Other.p_crowns) + --Other.p_crowns; + writerecord(&Other, loc); + break; + } + } + else + loc += SZ_PLAYERSTRUCT; + + /* make player new king */ + Changed = TRUE; + Player.p_specialtype = SC_KING; + mvaddstr(4, 0, "You have become king!\n"); + + /* let everyone else know */ + fp = fopen(_PATH_MESS, "w"); + fprintf(fp, "All hail the new king!"); + fclose(fp); + + /* clear all energy voids; retain location of holy grail */ + fseek(Energyvoidfp, 0L, 0); + fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp); + fp = fopen(_PATH_VOID, "w"); + fwrite((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, fp); + fclose(fp); + } + + mvaddstr(6, 0, "0:Decree "); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: dotampered() +/ +/ FUNCTION: king and valar special options +/ +/ AUTHOR: E. A. Estes, 2/28/86 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: writerecord(), truncstring(), fread(), fseek(), fopen(), +/ floor(), wmove(), drandom(), fclose(), fwrite(), sscanf(), strcmp(), +/ infloat(), waddstr(), findname(), distance(), userlist(), mvprintw(), +/ allocvoid(), getanswer(), getstring(), wclrtoeol(), writevoid() +/ +/ GLOBAL INPUTS: *Energyvoidfp, Other, Illcmd[], Wizard, Player, *stdscr, +/ Databuf[], Enrgyvoid +/ +/ GLOBAL OUTPUTS: Other, Player, Enrgyvoid +/ +/ DESCRIPTION: +/ Tamper with other players. Handle king/valar specific options. +/ +/************************************************************************/ + +dotampered() +{ +short tamper; /* value for tampering with other players */ +char *option; /* pointer to option description */ +double temp1 = 0.0, temp2 = 0.0; /* other tampering values */ +int ch; /* input */ +long loc; /* location in energy void file */ +FILE *fp; /* for opening gold file */ + + move(6, 0); + clrtoeol(); + if (Player.p_specialtype < SC_COUNCIL && !Wizard) + /* king options */ + { + addstr("1:Transport 2:Curse 3:Energy Void 4:Bestow 5:Collect Taxes "); + + ch = getanswer(" ", TRUE); + move(6, 0); + clrtoeol(); + move(4, 0); + switch (ch) + { + case '1': /* transport someone */ + tamper = T_TRANSPORT; + option = "transport"; + break; + + case '2': /* curse another */ + tamper = T_CURSED; + option = "curse"; + break; + + case '3': /* create energy void */ + if ((loc = allocvoid()) > 20L * SZ_VOIDSTRUCT) + /* can only have 20 void active at once */ + mvaddstr(5, 0, "Sorry, void creation limit reached.\n"); + else + { + addstr("Enter the X Y coordinates of void ? "); + getstring(Databuf, SZ_DATABUF); + sscanf(Databuf, "%lf %lf", &temp1, &temp2); + Enrgyvoid.ev_x = floor(temp1); + Enrgyvoid.ev_y = floor(temp2); + Enrgyvoid.ev_active = TRUE; + writevoid(&Enrgyvoid, loc); + mvaddstr(5, 0, "It is done.\n"); + } + return; + + case '4': /* bestow gold to subject */ + tamper = T_BESTOW; + addstr("How much gold to bestow ? "); + temp1 = infloat(); + if (temp1 > Player.p_gold || temp1 < 0) + { + mvaddstr(5, 0, "You don't have that !\n"); + return; + } + + /* adjust gold after we are sure it will be given to someone */ + option = "give gold to"; + break; + + case '5': /* collect accumulated taxes */ + if ((fp = fopen(_PATH_GOLD, "r+")) != NULL) + /* collect taxes */ + { + fread((char *) &temp1, sizeof(double), 1, fp); + fseek(fp, 0L, 0); + /* clear out value */ + temp2 = 0.0; + fwrite((char *) &temp2, sizeof(double), 1, fp); + fclose(fp); + } + + mvprintw(4, 0, "You have collected %.0f in gold.\n", temp1); + Player.p_gold += floor(temp1); + return; + + default: + return; + } + /* end of king options */ + } + else + /* council of wise, valar, wizard options */ + { + addstr("1:Heal "); + if (Player.p_palantir || Wizard) + addstr("2:Seek Grail "); + if (Player.p_specialtype == SC_VALAR || Wizard) + addstr("3:Throw Monster 4:Relocate 5:Bless "); + if (Wizard) + addstr("6:Vaporize "); + + ch = getanswer(" ", TRUE); + if (!Wizard) + { + if (ch > '2' && Player.p_specialtype != SC_VALAR) + { + ILLCMD(); + return; + } + + if (Player.p_mana < MM_INTERVENE) + { + mvaddstr(5, 0, "No mana left.\n"); + return; + } + else + Player.p_mana -= MM_INTERVENE; + } + + switch (ch) + { + case '1': /* heal another */ + tamper = T_HEAL; + option = "heal"; + break; + + case '2': /* seek grail */ + if (Player.p_palantir) + /* need a palantir to seek */ + { + fseek(Energyvoidfp, 0L, 0); + fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp); + temp1 = distance(Player.p_x, Enrgyvoid.ev_x, Player.p_y, Enrgyvoid.ev_y); + temp1 += ROLL(-temp1 / 10.0, temp1 / 5.0); /* add some error */ + mvprintw(5, 0, "The palantir says the Grail is about %.0f away.\n", temp1); + } + else + /* no palantir */ + mvaddstr(5, 0, "You need a palantir to seek the Grail.\n"); + return; + + case '3': /* lob monster at someone */ + mvaddstr(4, 0, "Which monster [0-99] ? "); + temp1 = infloat(); + temp1 = MAX(0.0, MIN(99.0, temp1)); + tamper = T_MONSTER; + option = "throw a monster at"; + break; + + case '4': /* move another player */ + mvaddstr(4, 0, "New X Y coordinates ? "); + getstring(Databuf, SZ_DATABUF); + sscanf(Databuf, "%lf %lf", &temp1, &temp2); + tamper = T_RELOCATE; + option = "relocate"; + break; + + case '5': /* bless a player */ + tamper = T_BLESSED; + option = "bless"; + break; + + case '6': /* kill off a player */ + if (Wizard) + { + tamper = T_VAPORIZED; + option = "vaporize"; + break; + } + else + return; + + default: + return; + } + + /* adjust age after we are sure intervention will be done */ + /* end of valar, etc. options */ + } + + for (;;) + /* prompt for player to affect */ + { + mvprintw(4, 0, "Who do you want to %s ? ", option); + getstring(Databuf, SZ_DATABUF); + truncstring(Databuf); + + if (Databuf[0] == '\0') + userlist(TRUE); + else + break; + } + + if (strcmp(Player.p_name, Databuf) != 0) + /* name other than self */ + { + if ((loc = findname(Databuf, &Other)) >= 0L) + { + if (Other.p_tampered != T_OFF) + { + mvaddstr(5, 0, "That person has something pending already.\n"); + return; + } + else + { + if (tamper == T_RELOCATE + && CIRCLE(temp1, temp2) < CIRCLE(Other.p_x, Other.p_y) + && !Wizard) + mvaddstr(5, 0, "Cannot move someone closer to the Lord's Chamber.\n"); + else + { + if (tamper == T_BESTOW) Player.p_gold -= floor(temp1); + if (!Wizard && (tamper == T_HEAL || tamper == T_MONSTER || + tamper == T_RELOCATE || tamper == T_BLESSED)) + Player.p_age += N_AGE; /* age penalty */ + Other.p_tampered = tamper; + Other.p_1scratch = floor(temp1); + Other.p_2scratch = floor(temp2); + writerecord(&Other, loc); + mvaddstr(5, 0, "It is done.\n"); + } + return; + } + } + else + /* player not found */ + mvaddstr(5, 0, "There is no one by that name.\n"); + } + else + /* self */ + mvaddstr(5, 0, "You may not do it to yourself!\n"); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: writevoid() +/ +/ FUNCTION: update energy void entry in energy void file +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: +/ struct energyvoid *vp - pointer to structure to write to file +/ long loc - location in file to update +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: fseek(), fwrite(), fflush() +/ +/ GLOBAL INPUTS: *Energyvoidfp +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Write out energy void structure at specified location. +/ +/************************************************************************/ + +writevoid(vp, loc) +register struct energyvoid *vp; +long loc; +{ + + fseek(Energyvoidfp, loc, 0); + fwrite((char *) vp, SZ_VOIDSTRUCT, 1, Energyvoidfp); + fflush(Energyvoidfp); + fseek(Energyvoidfp, 0L, 0); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: allocvoid() +/ +/ FUNCTION: allocate space for a new energy void +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: location of new energy void space +/ +/ MODULES CALLED: fread(), fseek() +/ +/ GLOBAL INPUTS: *Energyvoidfp, Enrgyvoid +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Search energy void file for an inactive entry and return its +/ location. +/ If no inactive ones are found, return one more than last location. +/ +/************************************************************************/ + +long +allocvoid() +{ +long loc = 0L; /* location of new energy void */ + + fseek(Energyvoidfp, 0L, 0); + while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1) + if (Enrgyvoid.ev_active) + loc += SZ_VOIDSTRUCT; + else + break; + + return(loc); +} -- cgit v1.2.3-56-ge451