|
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; }