|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 16038 (0x3ea6)
Types: TextFile
Names: »fight.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Phantasia/fight.c«
/*
* fight.c Phantasia monster fighting routine
*/
/*
* The code exists here for fight to the finish. Simply add code to
* set 'fgttofin = TRUE' as an option. Everything else is here.
*/
#include "phant.h"
void fight(stat,particular) /* monster fighting routine */
struct stats *stat;
int particular;
{
bool fghttofin = FALSE, luckout = FALSE, firsthit = stat->bls;
char aline[80];
double monhit, mdamage, sdamage, monspd, maxspd, inflict, monstr, temp, shield;
int ch;
int whichm, size, howmany, lines;
struct mstats monster;
fghting = changed = TRUE;
shield = 0.0;
if (setjmp(fightenv) == 2)
shield = roll(100 + (stat->mxn + stat->shd)*6.2,3000);
howmany = 1;
size = (valhala) ? stat->lvl/5 : circ(stat->x,stat->y);
if (particular >= 0)
whichm = particular;
else if (marsh)
whichm = roll(0,15);
else if (size > 24)
whichm = roll(14,86);
else if (size > 15)
whichm = roll(0,50) + roll(14,37);
else if (size > 8)
whichm = roll(0,50) + roll(14,26);
else if (size > 3)
whichm = roll(14,50);
else
whichm = roll(14,25);
move(6,0);
clrtobot();
CALL: move(6,0);
lines = 9;
callmonster(whichm,size,&monster);
if (stat->blind)
strcpy(monster.name,"a monster");
if (monster.typ == 1) /* unicorn */
if (stat->vrg)
{
printw("You just subdued %s, thanx to the virgin.\n",monster.name);
stat->vrg = FALSE;
goto FINISH;
}
else
{
printw("You just saw %s running away!\n",monster.name);
goto LEAVE;
}
if (monster.typ == 2 && stat->typ > 20)
{
strcpy(monster.name,"Morgoth");
monster.str = rnd()*(stat->mxn + stat->shd)/1.4 + rnd()*(stat->mxn + stat->shd)/1.5;
monster.brn = stat->brn;
monster.hit = stat->str*30;
monster.typ = 23;
monster.spd = speed*1.1 + speed*(stat->typ == 90);
monster.flk = monster.trs = monster.exp = 0;
mvprintw(4,0,"You've encountered %s, Bane of the Council and Valar.\n",monster.name);
}
fghttofin = luckout = FALSE;
monstr = monster.str;
monhit = monster.hit;
mdamage = sdamage = 0;
monspd = maxspd = monster.spd;
if (speed <= 0)
{
monster.spd += - speed;
speed = 1;
}
*monster.name = toupper(*monster.name);
move(8,0);
clrtobot();
TOP: mvprintw(6,0,"You are being attacked by %s, EXP: %.0f (Size: %d)\n",monster.name,monster.exp,size);
printstats(stat);
mesg();
mvprintw(1,26,"%20.0f",stat->nrg + shield);
if (monster.typ == 4 && stat->bls && stat->chm)
{
mvprintw(7,0,"You just overpowered %s!",monster.name);
lines = 8;
stat->bls = FALSE;
--stat->chm;
goto FINISH;
}
monster.spd = min(monster.spd + 1,maxspd);
if (rnd()*monster.spd > rnd()*speed && monster.typ != 4 && monster.typ != 16
&& !firsthit)
{
if (monster.typ)
switch (monster.typ) /* do special things */
{
case 5: /* Leanan-Sidhe */
if (rnd() > 0.25)
goto NORMALHIT;
inflict = roll(1,(size - 1)/2);
inflict = min(stat->str,inflict);
mvprintw(lines++,0,"%s sapped %0.f of your strength!",monster.name,inflict);
stat->str -= inflict;
strength -= inflict;
break;
case 6: /* Saruman */
if (stat->pal)
{
mvprintw(lines++,0,"Wormtongue stole your palantir!");
stat->pal = FALSE;
}
else if (rnd() > 0.2)
goto NORMALHIT;
else if (rnd() > 0.5)
{
mvprintw(lines++,0,"%s transformed your gems into gold!",monster.name);
stat->gld += stat->gem;
stat->gem = 0.0;
}
else
{
mvprintw(lines++,0,"%s scrambled your stats!",monster.name);
scramble(stat);
}
break;
case 7: /* Thaumaturgist */
if (rnd() > 0.15)
goto NORMALHIT;
mvprintw(lines++,0,"%s transported you!",monster.name);
stat->x += sgn(stat->x)*roll(50*size,250*size);
stat->y += sgn(stat->y)*roll(50*size,250*size);
goto LEAVE;
case 8: /* Balrog */
inflict = roll(10,monster.str);
inflict = min(stat->exp,inflict);
mvprintw(lines++,0,"%s took away %.0f experience points.",monster.name,inflict);
stat->exp -= inflict;
break;
case 9: /* Vortex */
if (rnd() > 0.2)
goto NORMALHIT;
inflict = roll(0,7.5*size);
inflict = min(stat->man,floor(inflict));
mvprintw(lines++,0,"%s sucked up %.0f of your mana!",monster.name,inflict);
stat->man -= inflict;
break;
case 10: /* Nazgul */
if (rnd() > 0.3)
goto NORMALHIT;
if (stat->rng.type && stat->rng.type < 10)
{
mvaddstr(lines++,0,"Will you relinguish your ring ? ");
ch = getans("YN", FALSE);
if (ch == 'Y')
{
stat->rng.type = NONE;
goto LEAVE;
}
}
mvprintw(lines++,0,"%s neutralized 1/5 of your brain!",monster.name);
stat->brn *= 0.8;
break;
case 11: /* Tiamat */
if (rnd() > 0.6)
goto NORMALHIT;
mvprintw(lines++,0,"%s took half your gold and gems and flew off.",monster.name);
stat->gld = floor(stat->gld/2);
stat->gem = floor(stat->gem/2);
goto LEAVE;
case 12: /* Kobold */
if (rnd() >.7)
goto NORMALHIT;
mvprintw(lines++,0,"%s stole one gold piece and ran away.",monster.name);
stat->gld = max(0,stat->gld-1);
goto LEAVE;
case 13: /* Shelob */
if (rnd() > 0.5)
goto NORMALHIT;
mvprintw(lines++,0,"%s has bitten and poisoned you!",monster.name);
++stat->psn;
break;
case 14: /* Faeries */
if (!stat->hw)
goto NORMALHIT;
mvprintw(lines++,0,"Your holy water killed it!");
--stat->hw;
goto FINISH;
case 15: /* Lamprey */
if (rnd() > 0.7)
goto NORMALHIT;
mvprintw(lines++,0,"%s bit and poisoned you!",monster.name);
stat->psn += 0.25;
break;
case 17: /* Bonnacon */
if (rnd() > 0.1)
goto NORMALHIT;
mvprintw(lines++,0,"%s farted and scampered off.",monster.name);
stat->nrg /= 2;
goto LEAVE;
case 18: /* Smeagol */
if (rnd() > 0.5 || !stat->rng.type)
goto NORMALHIT;
mvprintw(lines++,0,"%s tried to steal your ring, ",monster.name);
if (rnd() > 0.1)
addstr("but was unsuccessful.");
else
{
addstr("and ran away with it!");
stat->rng.type = NONE;
goto LEAVE;
}
break;
case 19: /* Succubus */
if (rnd() > 0.3)
goto NORMALHIT;
inflict = roll(15,size*10);
inflict = min(inflict,stat->nrg);
mvprintw(lines++,0,"%s sapped %.0f of your energy.",monster.name,inflict);
stat->nrg -= inflict;
break;
case 20: /* Cerberus */
if (rnd() > 0.25)
goto NORMALHIT;
mvprintw(lines++,0,"%s took all your metal treasures!",monster.name);
stat->swd = stat->shd =stat->gld = stat->crn = 0;
goto LEAVE;
case 21: /* Ungoliant */
if (rnd() > 0.1)
goto NORMALHIT;
mvprintw(lines++,0,"%s poisoned you, and took one quik.",monster.name);
stat->psn += 5;
--stat->quk;
break;
case 22: /* Jabberwock */
if (rnd() > 0.1)
goto NORMALHIT;
mvprintw(lines++,0,"%s flew away, and left you to contend with one of its friends.",monster.name);
whichm = 55 + 22*(rnd() > 0.5);
goto CALL;
case 24: /* Troll */
if (rnd() > 0.5)
goto NORMALHIT;
mvprintw(lines++,0,"%s partially regenerated his energy.!",monster.name);
monster.hit += floor((monhit*size - monster.hit)/2);
monster.str = monstr;
mdamage = sdamage = 0;
maxspd = monspd;
break;
case 25: /* wraith */
if (rnd() > 0.3 || stat->blind)
goto NORMALHIT;
mvprintw(lines++,0,"%s blinded you!",monster.name);
stat->blind = TRUE;
break;
default:
goto NORMALHIT;
}
else
NORMALHIT: {
inflict = rnd()*monster.str + 0.5;
mvprintw(lines++,0,"%s hit you %.0f times!",monster.name,inflict);
SPECIALHIT: if ((shield -= inflict) < 0)
{
stat->nrg += shield;
shield = 0;
}
}
}
else
{
if (fghttofin)
goto MELEE;
mvaddstr(7,0,"1:Melee 2:Skirmish 3:Evade 4:Spell 5:Nick ");
if (!luckout)
if (monster.typ == 23)
addstr("6:Ally ");
else
addstr("6:Luckout ");
if (stat->rng.type > 0)
addstr("7:Use Ring ");
else
clrtoeol();
ch = gch(stat->rng.type);
firsthit = FALSE;
move(8,0);
clrtobot();
lines = 9;
mvaddstr(4,0,"\n\n");
switch (ch)
{
case 'T': /* timeout; lose turn */
break;
default:
case '1': /* melee */
MELEE: inflict = roll(strength/2 + 5,1.3*strength) + (stat->rng.type < 0 ? strength : 0);
mdamage += inflict;
monster.str = monstr - mdamage/monhit*monstr/4;
goto HITMONSTER;
case '2': /* skirmish */
inflict = roll(strength/3 + 3,1.1*strength) + (stat->rng.type < 0 ? strength : 0);
sdamage += inflict;
maxspd = monspd - sdamage/monhit*monspd/4;
goto HITMONSTER;
case '3': /* evade */
if ((monster.typ == 4 || monster.typ == 16
|| rnd()*speed*stat->brn > rnd()*monster.spd*monster.brn)
&& (monster.typ != 23))
{
mvaddstr(lines++,0,"You got away!");
stat->x += roll(-2,5);
stat->y += roll(-2,5);
goto LEAVE;
}
else
mvprintw(lines++,0,"%s is still after you!",monster.name);
break;
case '4': /* spell */
mvaddstr(7,0,"\n\n");
mvaddstr(7,0,"1:All or Nothing ");
if (stat->mag >= 5)
addstr("2:Magic Bolt ");
if (stat->mag >= 15)
addstr("3:Force Field ");
if (stat->mag >= 25)
addstr("4:Transform ");
if(stat->mag >= 35)
addstr("5:Increase Might\n");
if (stat->mag >= 45)
mvaddstr(8,0,"6:Invisibility ");
if (stat->mag >= 60)
addstr("7:Transport ");
if (stat->mag >= 75)
addstr("8:Paralyze ");
if (stat->typ > 20)
addstr("9:Specify");
mvaddstr(4,0,"Spell ? ");
ch = getans(" ", TRUE);
mvaddstr(7,0,"\n\n");
if (monster.typ == 23 && ch != '3')
illspell();
else
switch (ch)
{
case '1': /* all or nothing */
{
inflict = (rnd() < 0.25) ? (monster.hit*1.0001 + 1) : 0;
if (monster.typ == 4)
inflict *= .9;
if (stat->man)
--stat->man;
maxspd *= 2;
monspd *= 2;
monster.spd = max(1,monster.spd * 2);
monstr = monster.str *= 2;
goto HITMONSTER;
}
case '2': /* magic bolt */
if (stat->mag < 5)
illspell();
else
{
do
{
mvaddstr(4,0,"How much mana for bolt? ");
getstring(aline,80);
sscanf(aline,"%F",&temp);
}
while (temp < 0 || temp > stat->man);
stat->man -= floor(temp);
inflict = temp*roll(10,sqrt(stat->mag/3.0 + 1.0));
mvaddstr(5,0,"Magic Bolt fired!\n");
if (monster.typ == 4)
inflict = 0.0;
goto HITMONSTER;
}
case '5': /* increase might */
{
if (stat->mag < 45)
illspell();
else if (stat->man < 75)
nomana();
else
{
stat->man -= 75;
strength += (1.2*(stat->str+stat->swd)+5-strength)/2;
mvprintw(5,0,"New strength: %.0f\n",strength);
}
break;
}
case '3': /* force field */
{
if (stat->mag < 15)
illspell();
else if (stat->man < 30)
nomana();
else
{
shield = (stat->mxn + stat->shd)*4.2 + 45;
stat->man -= 30;
mvaddstr(5,0,"Force Field up.\n");
}
break;
}
case '4': /* transform */
{
if (stat->mag < 25)
illspell();
else if (stat->man < 50)
nomana();
else
{
stat->man -= 50;
whichm = roll(0,100);
goto CALL;
}
break;
}
case '6': /* invisible */
{
if (stat->mag < 45)
illspell();
else if (stat->man < 90)
nomana();
else
{
stat->man -= 90;
speed += (1.2*(stat->quk+stat->quks)+5-speed)/2;
mvprintw(5,0,"New quik : %.0f\n",speed);
}
break;
}
case '7': /* transport */
{
if (stat->mag < 60)
illspell();
else if (stat->man < 125)
nomana();
else
{
stat->man -= 125;
if (stat->brn + stat->mag < monster.exp/200*rnd())
{
mvaddstr(5,0,"Transport backfired!\n");
stat->x += (250*size*rnd() + 50*size)*sgn(stat->x);
stat->y += (250*size*rnd() + 50*size)*sgn(stat->y);
goto LEAVE;
}
else
{
mvprintw(5,0,"%s is transported.\n",monster.name);
monster.trs *= (rnd() > 0.3);
goto FINISH;
}
}
break;
}
case '8': /* paralyze */
{
if (stat->mag < 75)
illspell();
else if (stat->man < 150)
nomana();
else
{
stat->man -= 150;
if (stat->mag > monster.exp/1000*rnd())
{
mvprintw(5,0,"%s is held.\n",monster.name);
monster.spd = -2;
}
else
mvaddstr(5,0,"Monster unaffected.\n");
}
break;
}
case '9': /* specify */
{
if (stat->typ < 20)
illspell();
else if (stat->man < 1000)
nomana();
else
{
mvaddstr(5,0,"Which monster do you want [0-99] ? ");
whichm = inflt();
whichm = max(0,min(99,whichm));
stat->man -= 1000;
goto CALL;
}
break;
}
}
break;
case '5':
inflict = 1 + stat->swd;
stat->exp += floor(monster.exp/10);
monster.exp *= 0.92;
maxspd += 2;
monster.spd = (monster.spd < 0) ? 0 : monster.spd + 2;
if (monster.typ == 4)
{
mvprintw(lines++,0,"You hit %s %.0f times, and made him mad!",monster.name,inflict);
stat->quk /= 2;
stat->x += sgn(stat->x)*roll(50*size,250*size);
stat->y += sgn(stat->y)*roll(50*size,250*size);
stat->y += (250*size*rnd() + 50*size)*sgn(stat->y);
goto LEAVE;
}
else
goto HITMONSTER;
case '6': /* luckout */
if (luckout)
mvaddstr(lines++,0,"You already tried that.");
else
if (monster.typ == 23)
if (rnd() < stat->sin/100) {
mvprintw(lines++,0,"%s accepted!",monster.name);
goto LEAVE;
}
else
{
luckout = TRUE;
mvaddstr(lines++,0,"Nope, he's not interested.");
}
else
if ((rnd() + .333)*stat->brn < (rnd() + .333)*monster.brn)
{
luckout = TRUE;
mvprintw(lines++,0,"You blew it, %s.",stat->name);
}
else
{
mvaddstr(lines++,0,"You made it!");
goto FINISH;
}
break;
case '\014': /* clear screen */
clear();
break;
case '7': /* use ring */
if (stat->rng.type > 0)
{
mvaddstr(lines++,0,"Now using ring.");
stat->rng.type = -stat->rng.type;
if (abs(stat->rng.type) != DLREG)
--stat->rng.duration;
goto HITMONSTER;
}
break;
}
goto BOT;
HITMONSTER: {
inflict = floor(inflict);
mvprintw(lines++,0,"You hit %s %.0f times!",monster.name,inflict);
if ((monster.hit -= inflict) >0)
switch (monster.typ)
{
case 4: /* dark lord */
inflict = stat->nrg + shield +1;
goto SPECIALHIT;
case 16: /* shrieker */
mvaddstr(lines++,0,"Shreeeek!! You scared it, and it called one of its friends.");
paws(lines);
whichm = roll(70,30);
goto CALL;
}
else
{
if (monster.typ == 23) /* morgoth */
mvaddstr(lines++,0,"You have defeated Morgoth, but he may return. . .");
else
mvprintw(lines++,0,"You killed it. Good work, %s.",stat->name);
goto FINISH;
}
}
}
BOT: refresh();
if (lines > LINES - 2)
{
paws(lines);
move(lines = 8,0);
clrtobot();
}
if (stat->nrg <= 0)
{
paws(lines);
death(stat);
goto LEAVE;
}
goto TOP;
FINISH: stat->exp += monster.exp;
if (rnd() < monster.flk/100.0) /* flock monster */
{
paws(lines);
fghttofin = FALSE;
++howmany;
goto CALL;
}
else if (size > 1 && monster.trs && rnd() > 0.2 + pow(0.4,(double) (howmany/3.0 + size/3.0))) /* this takes # of flocks and size into account */
{
paws(lines);
treasure(stat,monster.trs,size);
}
else
LEAVE: paws(lines);
stat->rng.type = abs(stat->rng.type);
move(4,0);
clrtobot();
fghting = FALSE;
}