📄 fight.c
字号:
/* * fight.c Phantasia monster fighting routines */#include "include.h"/************************************************************************// FUNCTION NAME: encounter()// FUNCTION: monster battle routine// AUTHOR: E. A. Estes, 2/20/86// ARGUMENTS:/ int particular - particular monster to fight if >= 0// RETURN VALUE: none// MODULES CALLED: monsthits(), playerhits(), readmessage(), callmonster(), / writerecord(), pickmonster(), displaystats(), pow(), cancelmonster(), / awardtreasure(), more(), death(), wmove(), setjmp(), drandom(), printw(), / longjmp(), wrefresh(), mvprintw(), wclrtobot()// GLOBAL INPUTS: Curmonster, Whichmonster, LINES, Lines, Circle, Shield, / Player, *stdscr, Fileloc, Fightenv[], *Enemyname// GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, Luckout// DESCRIPTION:/ Choose a monster and check against some special types./ Arbitrate between monster and player. Watch for either/ dying.//************************************************************************/encounter(particular)int particular;{bool firsthit = Player.p_blessing; /* set if player gets the first hit */int flockcnt = 1; /* how many time flocked */ /* let others know what we are doing */ Player.p_status = S_MONSTER; writerecord(&Player, Fileloc);#ifdef SYS5 flushinp();#endif Shield = 0.0; /* no shield up yet */ if (particular >= 0) /* monster is specified */ Whichmonster = particular; else /* pick random monster */ Whichmonster = pickmonster(); setjmp(Fightenv); /* this is to enable changing fight state */ move(6, 0); clrtobot(); /* clear bottom area of screen */ Lines = 9; callmonster(Whichmonster); /* set up monster to fight */ Luckout = FALSE; /* haven't tried to luckout yet */ if (Curmonster.m_type == SM_MORGOTH) mvprintw(4, 0, "You've encountered %s, Bane of the Council and Valar.\n", Enemyname); if (Curmonster.m_type == SM_UNICORN) { if (Player.p_virgin) { printw("You just subdued %s, thanks to the virgin.\n", Enemyname); Player.p_virgin = FALSE; } else { printw("You just saw %s running away!\n", Enemyname); Curmonster.m_experience = 0.0; Curmonster.m_treasuretype = 0; } } else /* not a special monster */ for (;;) /* print header, and arbitrate between player and monster */ { mvprintw(6, 0, "You are being attacked by %s, EXP: %.0f (Size: %.0f)\n", Enemyname, Curmonster.m_experience, Circle); displaystats(); mvprintw(1, 26, "%20.0f", Player.p_energy + Shield); /* overprint energy */ readmessage(); if (Curmonster.m_type == SM_DARKLORD && Player.p_blessing && Player.p_charms > 0) /* overpower Dark Lord with blessing and charm */ { mvprintw(7, 0, "You just overpowered %s!", Enemyname); Lines = 8; Player.p_blessing = FALSE; --Player.p_charms; break; } /* allow paralyzed monster to wake up */ Curmonster.m_speed = MIN(Curmonster.m_speed + 1.0, Curmonster.m_maxspeed); if (drandom() * Curmonster.m_speed > drandom() * Player.p_speed /* monster is faster */ && Curmonster.m_type != SM_DARKLORD /* not D. L. */ && Curmonster.m_type != SM_SHRIEKER /* not mimic */ && !firsthit) /* monster gets a hit */ monsthits(); else /* player gets a hit */ { firsthit = FALSE; playerhits(); } refresh(); if (Lines > LINES - 2) /* near bottom of screen - pause */ { more(Lines); move(Lines = 8, 0); clrtobot(); } if (Player.p_energy <= 0.0) /* player died */ { more(Lines); death(Enemyname); cancelmonster(); break; /* fight ends if the player is saved from death */ } if (Curmonster.m_energy <= 0.0) /* monster died */ break; } /* give player credit for killing monster */ Player.p_experience += Curmonster.m_experience; if (drandom() < Curmonster.m_flock / 100.0) /* monster flocks */ { more(Lines); ++flockcnt; longjmp(Fightenv, 0); /*NOTREACHED*/ } else if (Circle > 1.0 && Curmonster.m_treasuretype > 0 && drandom() > 0.2 + pow(0.4, (double) (flockcnt / 3 + Circle / 3.0))) /* monster has treasure; this takes # of flocks and size into account */ { more(Lines); awardtreasure(); } /* pause before returning */ getyx(stdscr, Lines, flockcnt); more(Lines + 1); Player.p_ring.ring_inuse = FALSE; /* not using ring */ /* clean up the screen */ move(4, 0); clrtobot();}/**//************************************************************************// FUNCTION NAME: pickmonster()// FUNCTION: choose a monster based upon where we are// AUTHOR: E. A. Estes, 2/20/86// ARGUMENTS: none// RETURN VALUE: monster number to call// MODULES CALLED: floor(), drandom()// GLOBAL INPUTS: Marsh, Circle, Player// GLOBAL OUTPUTS: none// DESCRIPTION:/ Certain monsters can be found in certain areas of the grid./ We take care of rolling them here./ Unfortunately, this routine assumes that the monster data/ base is arranged in a particular order. If the data base/ is altered (to add monsters, or make them tougher), this/ routine may also need to be changed.//************************************************************************/pickmonster(){ if (Player.p_specialtype == SC_VALAR) /* even chance of any monster */ return((int) ROLL(0.0, 100.0)); if (Marsh) /* water monsters */ return((int) ROLL(0.0, 15.0)); else if (Circle > 24) /* even chance of all non-water monsters */ return((int) ROLL(14.0, 86.0)); else if (Circle > 15) /* chance of all non-water monsters, weighted toward middle */ return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 37.0))); else if (Circle > 8) /* not all non-water monsters, weighted toward middle */ return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 26.0))); else if (Circle > 3) /* even chance of some tamer non-water monsters */ return((int) ROLL(14.0, 50.0)); else /* even chance of some of the tamest non-water monsters */ return((int) ROLL(14.0, 25.0));}/**//************************************************************************// FUNCTION NAME: playerhits()// FUNCTION: prompt player for action in monster battle, and process// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS: none// RETURN VALUE: none// MODULES CALLED: hitmonster(), throwspell(), inputoption(), cancelmonster(), / floor(), wmove(), drandom(), altercoordinates(), waddstr(), mvprintw(), / wclrtoeol(), wclrtobot()// GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, Luckout, *Enemyname// GLOBAL OUTPUTS: Curmonster, Lines, Player, Luckout// DESCRIPTION:/ Process all monster battle options.//************************************************************************/playerhits(){double inflict; /* damage inflicted */int ch; /* input */ mvaddstr(7, 0, "1:Melee 2:Skirmish 3:Evade 4:Spell 5:Nick "); if (!Luckout) /* haven't tried to luckout yet */ if (Curmonster.m_type == SM_MORGOTH) /* cannot luckout against Morgoth */ addstr("6:Ally "); else addstr("6:Luckout "); if (Player.p_ring.ring_type != R_NONE) /* player has a ring */ addstr("7:Use Ring "); else clrtoeol(); ch = inputoption(); move(8, 0); clrtobot(); /* clear any messages from before */ Lines = 9; mvaddstr(4, 0, "\n\n"); /* clear status area */ switch (ch) { case 'T': /* timeout; lose turn */ break; case ' ': case '1': /* melee */ /* melee affects monster's energy and strength */ inflict = ROLL(Player.p_might / 2.0 + 5.0, 1.3 * Player.p_might) + (Player.p_ring.ring_inuse ? Player.p_might : 0.0); Curmonster.m_melee += inflict; Curmonster.m_strength = Curmonster.m_o_strength - Curmonster.m_melee / Curmonster.m_o_energy * Curmonster.m_o_strength / 4.0; hitmonster(inflict); break; case '2': /* skirmish */ /* skirmish affects monter's energy and speed */ inflict = ROLL(Player.p_might / 3.0 + 3.0, 1.1 * Player.p_might) + (Player.p_ring.ring_inuse ? Player.p_might : 0.0); Curmonster.m_skirmish += inflict; Curmonster.m_maxspeed = Curmonster.m_o_speed - Curmonster.m_skirmish / Curmonster.m_o_energy * Curmonster.m_o_speed / 4.0; hitmonster(inflict); break; case '3': /* evade */ /* use brains and speed to try to evade */ if ((Curmonster.m_type == SM_DARKLORD || Curmonster.m_type == SM_SHRIEKER /* can always run from D. L. and shrieker */ || drandom() * Player.p_speed * Player.p_brains > drandom() * Curmonster.m_speed * Curmonster.m_brains) && (Curmonster.m_type != SM_MIMIC)) /* cannot run from mimic */ { mvaddstr(Lines++, 0, "You got away!"); cancelmonster(); altercoordinates(0.0, 0.0, A_NEAR); } else mvprintw(Lines++, 0, "%s is still after you!", Enemyname); break; case 'M': case '4': /* magic spell */ throwspell(); break; case '5': /* nick */ /* hit 1 plus sword; give some experience */ inflict = 1.0 + Player.p_sword; Player.p_experience += floor(Curmonster.m_experience / 10.0); Curmonster.m_experience *= 0.92; /* monster gets meaner */ Curmonster.m_maxspeed += 2.0; Curmonster.m_speed = (Curmonster.m_speed < 0.0) ? 0.0 : Curmonster.m_speed + 2.0; if (Curmonster.m_type == SM_DARKLORD) /* Dark Lord; doesn't like to be nicked */ { mvprintw(Lines++, 0, "You hit %s %.0f times, and made him mad!", Enemyname, inflict); Player.p_quickness /= 2.0; altercoordinates(0.0, 0.0, A_FAR); cancelmonster(); } else hitmonster(inflict); break; case 'B': case '6': /* luckout */ if (Luckout) mvaddstr(Lines++, 0, "You already tried that."); else { Luckout = TRUE; if (Curmonster.m_type == SM_MORGOTH) /* Morgoth; ally */ { if (drandom() < Player.p_sin / 100.0) { mvprintw(Lines++, 0, "%s accepted!", Enemyname); cancelmonster(); } else mvaddstr(Lines++, 0, "Nope, he's not interested."); } else /* normal monster; use brains for success */ { if ((drandom() + 0.333) * Player.p_brains < (drandom() + 0.333) * Curmonster.m_brains) mvprintw(Lines++, 0, "You blew it, %s.", Player.p_name); else { mvaddstr(Lines++, 0, "You made it!"); Curmonster.m_energy = 0.0; } } } break; case '7': /* use ring */ if (Player.p_ring.ring_type != R_NONE) { mvaddstr(Lines++, 0, "Now using ring."); Player.p_ring.ring_inuse = TRUE; if (Player.p_ring.ring_type != R_DLREG) /* age ring */ --Player.p_ring.ring_duration; } break; }}/**//************************************************************************// FUNCTION NAME: monsthits()// FUNCTION: process a monster hitting the player// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS: none// RETURN VALUE: none// MODULES CALLED: cancelmonster(), scramblestats(), more(), floor(), wmove(), / drandom(), altercoordinates(), longjmp(), waddstr(), mvprintw(), / getanswer()// GLOBAL INPUTS: Curmonster, Lines, Circle, Shield, Player, *stdscr, / Fightenv[], *Enemyname// GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, / *Enemyname// DESCRIPTION:/ Handle all special monsters here. If the monster is not a special/ one, simply roll a hit against the player.//************************************************************************/monsthits(){double inflict; /* damage inflicted */int ch; /* input */ switch (Curmonster.m_type) /* may be a special monster */ { case SM_DARKLORD: /* hits just enough to kill player */ inflict = (Player.p_energy + Shield) * 1.02; goto SPECIALHIT; case SM_SHRIEKER: /* call a big monster */ mvaddstr(Lines++, 0, "Shrieeeek!! You scared it, and it called one of its friends."); more(Lines); Whichmonster = (int) ROLL(70.0, 30.0); longjmp(Fightenv, 0); /*NOTREACHED*/ case SM_BALROG: /* take experience away */ inflict = ROLL(10.0, Curmonster.m_strength); inflict = MIN(Player.p_experience, inflict); mvprintw(Lines++, 0, "%s took away %.0f experience points.", Enemyname, inflict); Player.p_experience -= inflict; return; case SM_FAERIES: if (Player.p_holywater > 0) /* holy water kills when monster tries to hit */ { mvprintw(Lines++, 0, "Your holy water killed it!"); --Player.p_holywater; Curmonster.m_energy = 0.0; return; } break; case SM_NONE: /* normal hit */ break; default: if (drandom() > 0.2) /* normal hit */ break; /* else special things */ switch (Curmonster.m_type) { case SM_LEANAN: /* takes some of the player's strength */ inflict = ROLL(1.0, (Circle - 1.0) / 2.0); inflict = MIN(Player.p_strength, inflict); mvprintw(Lines++, 0, "%s sapped %0.f of your strength!", Enemyname, inflict); Player.p_strength -= inflict; Player.p_might -= inflict; break; case SM_SARUMAN: if (Player.p_palantir) /* take away palantir */ { mvprintw(Lines++, 0, "Wormtongue stole your palantir!"); Player.p_palantir = FALSE; } else if (drandom() > 0.5) /* gems turn to gold */ { mvprintw(Lines++, 0, "%s transformed your gems into gold!", Enemyname); Player.p_gold += Player.p_gems; Player.p_gems = 0.0; } else /* scramble some stats */ { mvprintw(Lines++, 0, "%s scrambled your stats!", Enemyname); scramblestats(); } break; case SM_THAUMATURG: /* transport player */ mvprintw(Lines++, 0, "%s transported you!", Enemyname); altercoordinates(0.0, 0.0, A_FAR); cancelmonster(); break; case SM_VORTEX: /* suck up some mana */ inflict = ROLL(0, 7.5 * Circle); inflict = MIN(Player.p_mana, floor(inflict)); mvprintw(Lines++, 0, "%s sucked up %.0f of your mana!", Enemyname, inflict); Player.p_mana -= inflict; break; case SM_NAZGUL: /* try to take ring if player has one */ if (Player.p_ring.ring_type != R_NONE) /* player has a ring */ { mvaddstr(Lines++, 0, "Will you relinguish your ring ? "); ch = getanswer("YN", FALSE); if (ch == 'Y') /* take ring away */ { Player.p_ring.ring_type = R_NONE; Player.p_ring.ring_inuse = FALSE; cancelmonster();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -