|
|
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 t
Length: 20311 (0x4f57)
Types: TextFile
Names: »trap.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Nethack/trap.c«
/* SCCS Id: @(#)trap.c 2.1 87/10/18
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
#include <stdio.h>
#include "hack.h"
extern struct monst *makemon();
#ifdef KAA
extern char *Xmonnam();
extern char *nomovemsg;
#endif
char vowels[] = "aeiou";
char *traps[] = {
"",
" bear trap",
"n arrow trap",
" dart trap",
" trapdoor",
" teleportation trap",
" pit",
" sleeping gas trap",
" piercer",
" mimic"
#ifdef NEWTRAPS
," magic trap"
," squeaky board"
#endif
#ifdef SPIDERS
," web"
#endif
#ifdef NEWCLASS
," spiked pit"
," level teleporter"
#endif
#ifdef SPELLS
," anti-magic field"
#endif
#ifdef KAA
," rust trap"
# ifdef RPH
,"polymorph trap"
# endif
#endif
};
struct trap *
maketrap(x,y,typ)
register x,y,typ;
{
register struct trap *ttmp;
ttmp = newtrap();
ttmp->ttyp = typ;
ttmp->tseen = 0;
ttmp->once = 0;
ttmp->tx = x;
ttmp->ty = y;
ttmp->ntrap = ftrap;
ftrap = ttmp;
return(ttmp);
}
dotrap(trap) register struct trap *trap; {
register int ttype = trap->ttyp;
register struct monst *mtmp;
nomul(0);
if(trap->tseen && !rn2(5) && !(ttype == PIT
#ifdef NEWCLASS
|| ttype == SPIKED_PIT
#endif
#ifdef SPELLS
|| ttype == ANTI_MAGIC
#endif
))
pline("You escape a%s.", traps[ttype]);
else {
trap->tseen = 1;
switch(ttype) {
case SLP_GAS_TRAP:
pline("A cloud of gas puts you to sleep!");
nomul(-rnd(25));
break;
case BEAR_TRAP:
if(Levitation) {
pline("You float over a bear trap.");
break;
}
u.utrap = 4 + rn2(4);
u.utraptype = TT_BEARTRAP;
pline("A bear trap closes on your foot!");
if(u.usym=='o') pline("You howl in anger!");
break;
case PIERC:
deltrap(trap);
if(mtmp=makemon(PM_PIERCER,u.ux,u.uy)) {
pline("%s suddenly drops from the ceiling!", Xmonnam(mtmp));
if(uarmh)
pline("Its blow glances off your helmet.");
else
(void) thitu(3,d(4,6),"falling piercer");
}
break;
case ARROW_TRAP:
pline("An arrow shoots out at you!");
if(!thitu(8,rnd(6),"arrow")){
mksobj_at(ARROW, u.ux, u.uy);
fobj->quan = 1;
}
break;
case TRAPDOOR:
if(!xdnstair) {
pline("A trap door in the ceiling opens and a rock falls on your head!");
if(uarmh) pline("Fortunately, you are wearing a helmet!");
losehp(uarmh ? 2 : d(2,10),"falling rock");
mksobj_at(ROCK, u.ux, u.uy);
fobj->quan = 1;
stackobj(fobj);
if(Invisible) newsym(u.ux, u.uy);
} else {
register int newlevel = dlevel + 1;
while(!rn2(4) && newlevel < 29)
newlevel++;
pline("A trap door opens up under you!");
if(Levitation || u.ustuck) {
pline("For some reason you don't fall in.");
break;
}
fflush(stdout);
goto_level(newlevel, FALSE);
}
break;
case DART_TRAP:
pline("A little dart shoots out at you!");
if(thitu(7,rnd(3),"little dart")) {
if(!rn2(6))
poisoned("dart","poison dart");
} else {
mksobj_at(DART, u.ux, u.uy);
fobj->quan = 1;
}
break;
case TELEP_TRAP:
if(trap->once) {
deltrap(trap);
newsym(u.ux,u.uy);
vtele();
} else {
newsym(u.ux,u.uy);
tele();
}
break;
#ifdef KAA
case RUST_TRAP:
switch (rn2(5)) {
case 0:
pline("A gush of water hits you on the head!");
if (uarmh) {
if (uarmh->rustfree)
pline("Your helmet is not affected!");
else if (uarmh->spe > -6) {
pline("Your helmet rusts!");
uarmh->spe--;
} else
pline("Your helmet looks quite rusted now.");
}
break;
case 1:
pline("A gush of water hits your left arm!");
if (uarms) {
pline("Your shield is not affected!");
break;
}
if (uwep && uwep->otyp == TWO_HANDED_SWORD) goto two_hand;
/* Two goto statements in a row--aaarrrgggh! */
glovecheck: if(uarmg) pline("Your gloves are not affected!");
break;
case 2:
pline("A gush of water hits your right arm!");
two_hand: corrode_weapon();
goto glovecheck;
default:
pline("A gush of water hits you!");
if (uarm) {
if (uarm->rustfree ||
uarm->otyp >= STUDDED_LEATHER_ARMOR)
pline("Your %s not affected!",
aobjnam(uarm,"are"));
else if(uarm->spe > -6) {
pline("Your %s!",
aobjnam(uarm,"corrode"));
uarm->spe--;
} else
pline("Your %s quite rusted now.",
aobjnam(uarm, "look"));
}
}
break;
#endif
case PIT:
if (Levitation || index("EyBfk'&",u.usym)) {
pline("A pit opens up under you!");
pline("You don't fall in!");
break;
}
pline("You fall into a pit!");
u.utrap = rn1(6,2);
u.utraptype = TT_PIT;
losehp(rnd(6),"fall into a pit");
selftouch("Falling, you");
break;
#ifdef NEWCLASS
case SPIKED_PIT:
if (Levitation || index("EyBfk'&",u.usym)) {
pline("A pit opens up under you!");
pline("You don't fall in!");
pline("There are spikes in that pit!!!");
break;
}
pline("You fall into a pit!");
pline("You land on a set of sharp iron spikes!");
u.utrap = rn1(6,2);
u.utraptype = TT_PIT;
losehp(rnd(10),"fall onto iron spikes");
if(!rn2(6)) poisoned("spikes","poison spikes");
selftouch("Falling, you");
break;
case LEVEL_TELEP:
if (!Blind) pline("You are momentarily blinded by a flash of light");
else pline("You are momentarily disoriented.");
deltrap(trap);
newsym(u.ux,u.uy);
level_tele();
break;
#endif
#ifdef SPELLS
case ANTI_MAGIC:
pline("You feel your magical energy drain away!");
u.uen -= (rnd(u.ulevel) + 1);
if(u.uen < 0) {
u.uenmax += u.uen;
if(u.uenmax < 0) u.uenmax = 0;
u.uen = 0;
}
flags.botl = 1;
break;
#endif
#if defined(RPH) && defined(KAA)
case POLY_TRAP:
pline("You feel a change coming over you.");
polyself();
deltrap(trap);
break;
#endif
#ifdef NEWTRAPS
case MGTRP:
/* A magic trap. */
domagictrap();
break;
case SQBRD: {
#include "edog.h"
register struct monst *mtmp = fmon;
/* Stepped on a squeaky board. */
pline("A board underfoot gives off a loud squeak!");
/* Wake up nearby monsters. */
while(mtmp) {
if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
if(mtmp->msleep)
mtmp->msleep = 0;
if(mtmp->mtame)
EDOG(mtmp)->whistletime = moves;
}
mtmp = mtmp->nmon;
}
}
break;
#endif
#ifdef SPIDERS
case WEB:
/* Our luckless adventurer has stepped into a web. */
pline("You've stumbled into a spider web!");
u.utraptype = TT_WEB;
/* Time stuck in the web depends on your strength. */
if (u.ustr == 3) u.utrap = rn1(6,6);
else if (u.ustr < 6) u.utrap = rn1(6,4);
else if (u.ustr < 9) u.utrap = rn1(4,4);
else if (u.ustr < 12) u.utrap = rn1(4,2);
else if (u.ustr < 15) u.utrap = rn1(2,2);
else if (u.ustr < 18) u.utrap = rnd(2);
else if (u.ustr < 69) u.utrap = 1;
else {
u.utrap = 0;
pline("You tear through the web!");
deltrap(trap);
}
break;
#endif
default:
impossible("You hit a trap of type %u", trap->ttyp);
}
}
}
mintrap(mtmp) register struct monst *mtmp; {
register struct trap *trap = t_at(mtmp->mx, mtmp->my);
register int wasintrap = mtmp->mtrapped;
if(!trap) {
mtmp->mtrapped = 0; /* perhaps teleported? */
} else if(wasintrap) {
if(!rn2(40)) mtmp->mtrapped = 0;
} else {
register int tt = trap->ttyp;
#ifdef DGK
/* A bug fix for dumb messages by ab@unido.
*/
int in_sight = cansee(mtmp->mx,mtmp->my)
&& (!mtmp->minvis || See_invisible);
#else
int in_sight = cansee(mtmp->mx,mtmp->my);
#endif
extern char mlarge[];
if(mtmp->mtrapseen & (1 << tt)) {
/* he has been in such a trap - perhaps he escapes */
if(rn2(4)) return(0);
}
mtmp->mtrapseen |= (1 << tt);
switch (tt) {
case BEAR_TRAP:
if(index(mlarge, mtmp->data->mlet)) {
if(in_sight)
pline("%s is caught in a bear trap!",
Monnam(mtmp));
else
if(mtmp->data->mlet == 'o')
pline("You hear the roaring of an angry bear!");
mtmp->mtrapped = 1;
}
break;
#ifdef KAA
# ifdef RPH
case POLY_TRAP:
if(!resist(mtmp, '/', 0, NOTELL))
newcham(mtmp,&mons[rn2(CMNUM)]);
break;
# endif
case RUST_TRAP:
if(in_sight)
pline("A gush of water hits %s!",monnam(mtmp));
break;
#endif
case PIT:
#ifdef NEWCLASS
case SPIKED_PIT:
#endif
/* there should be a mtmp/data -> floating */
if(!index("EywBIfk'& ", mtmp->data->mlet)) { /* ab */
mtmp->mtrapped = 1;
if(in_sight)
pline("%s falls into a pit!", Monnam(mtmp));
}
break;
case SLP_GAS_TRAP:
if(!mtmp->msleep && !mtmp->mfroz) {
mtmp->msleep = 1;
if(in_sight)
pline("%s suddenly falls asleep!",
Monnam(mtmp));
}
break;
case TELEP_TRAP:
#ifdef NEWCLASS
case LEVEL_TELEP:
#endif
rloc(mtmp);
if(in_sight && !cansee(mtmp->mx,mtmp->my))
pline("%s suddenly disappears!",
Monnam(mtmp));
break;
case ARROW_TRAP:
if(in_sight)
pline("%s is hit by an arrow!", Monnam(mtmp));
mtmp->mhp -= 3;
break;
case DART_TRAP:
if(in_sight)
pline("%s is hit by a dart!", Monnam(mtmp));
mtmp->mhp -= 2;
/* not mondied here !! */
break;
case TRAPDOOR:
if(!xdnstair) {
mtmp->mhp -= 10;
if(in_sight)
pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
break;
}
if(!index("EywBIfk", mtmp->data->mlet)){
fall_down(mtmp);
if(in_sight)
pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
return(2); /* no longer on this level */
}
break;
case PIERC:
break;
#ifdef NEWTRAPS
case MGTRP:
/* A magic trap. Monsters immune. */
break;
case SQBRD: {
register struct monst *ztmp = fmon;
if(index("EyBIfk", mtmp->data->mlet)) break;
/* Stepped on a squeaky board. */
if (in_sight)
pline("%s steps on a squeaky board.", Monnam(mtmp));
else
pline("You hear a distant squeak.");
/* Wake up nearby monsters. */
while(ztmp) {
if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
if(ztmp->msleep) ztmp->msleep = 0;
ztmp = ztmp->nmon;
}
break;
}
#endif
#ifdef SPIDERS
case WEB:
/* Monster in a web. */
/* in_sight check and confused bear by Eric Backus */
if(mtmp->data->mlet != 's') {
if(in_sight)
pline("%s is caught in a web!", Monnam(mtmp));
else
if(mtmp->data->mlet == 'o')
pline("You hear the roaring of a confused bear!");
mtmp->mtrapped = 1;
}
break;
#endif
#ifdef SPELLS
case ANTI_MAGIC: break;
#endif
default:
impossible("Some monster encountered a strange trap of type %d.",tt);
}
}
return(mtmp->mtrapped);
}
selftouch(arg) char *arg; {
if(uwep && uwep->otyp == DEAD_COCKATRICE){
pline("%s touch the dead cockatrice.", arg);
pline("You turn to stone.");
pline("You die...");
killer = objects[uwep->otyp].oc_name;
done("died");
}
}
float_up(){
if(u.utrap) {
if(u.utraptype == TT_PIT) {
u.utrap = 0;
pline("You float up, out of the pit!");
} else {
pline("You float up, only your leg is still stuck.");
}
} else
if (Hallucination)
pline("Oh wow! You're floating in the air!");
else
pline("You start to float in the air!");
}
float_down(){
register struct trap *trap;
/* check for falling into pool - added by GAN 10/20/86 */
if(IS_POOL(levl[u.ux][u.uy].typ) && !Levitation)
drown();
pline("You float gently to the ground.");
if(trap = t_at(u.ux,u.uy))
switch(trap->ttyp) {
case PIERC:
break;
case TRAPDOOR:
if(!xdnstair || u.ustuck) break;
/* fall into next case */
default:
dotrap(trap);
}
pickup(1);
}
#include "mkroom.h"
vtele() {
register struct mkroom *croom;
for(croom = &rooms[0]; croom->hx >= 0; croom++)
if(croom->rtype == VAULT) {
register x,y;
x = rn2(2) ? croom->lx : croom->hx;
y = rn2(2) ? croom->ly : croom->hy;
if(teleok(x,y)) {
teleds(x,y);
return;
}
}
tele();
}
#ifdef BVH
int has_amulet() {
register struct obj *otmp;
for(otmp = invent; otmp; otmp = otmp->nobj)
if(otmp->olet == AMULET_SYM && otmp->spe >= 0)
return(1);
return(0);
}
#endif
tele() {
coord cc;
register int nux,nuy;
#ifdef BVH
if(has_amulet() && rn2(3)) {
pline("You feel disoriented for a moment.");
return;
}
#endif
if(Teleport_control) {
#ifdef KAA
if (multi < 0 && (!nomovemsg ||
!strncmp(nomovemsg,"You awake", 9) ||
!strncmp(nomovemsg,"You regain con", 15) ||
!strncmp(nomovemsg,"You are consci", 15)))
pline("Being unconscious, you cannot control your teleport.");
else {
#endif
pline("To what position do you want to be teleported?");
getpos(&cc, 1, "the desired position"); /* 1: force valid */
/* possible extensions: introduce a small error if
magic power is low; allow transfer to solid rock */
if(teleok(cc.x, cc.y)){
teleds(cc.x, cc.y);
return;
}
pline("Sorry ...");
#ifdef KAA
}
#endif
}
do {
nux = rnd(COLNO-1);
nuy = rn2(ROWNO);
} while(!teleok(nux, nuy));
teleds(nux, nuy);
}
teleds(nux, nuy)
register int nux,nuy;
{
if(Punished) unplacebc();
unsee();
u.utrap = 0;
u.ustuck = 0;
u.ux = nux;
u.uy = nuy;
setsee();
if(Punished) placebc(1);
if(u.uswallow){
u.uswldtim = u.uswallow = 0;
docrt();
}
nomul(0);
if(IS_POOL(levl[nux][nuy].typ) && !Levitation)
drown();
(void) inshop();
pickup(1);
read_engr_at(u.ux,u.uy);
}
teleok(x,y) register int x,y; { /* might throw him into a POOL
* removed by GAN 10/20/86
*/
#ifdef STUPID
boolean tmp1, tmp2, tmp3;
tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y);
tmp2 = !sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y);
tmp3 = !(IS_POOL(levl[x][y].typ) && !Levitation);
return(tmp1 && tmp2 && tmp3);
#else
return( isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y) &&
!sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y) &&
!(IS_POOL(levl[x][y].typ) && !Levitation)
);
#endif
/* Note: gold is permitted (because of vaults) */
}
dotele() {
extern char pl_character[];
if((!index("LNt",u.usym)) &&
#ifdef WIZARD
!wizard &&
#endif
(!Teleportation || u.ulevel < 6 ||
(pl_character[0] != 'W' && u.ulevel < 10))) {
pline("You are not able to teleport at will.");
return(0);
}
if(u.uhunger <= 100 || u.ustr < 6) {
pline("You miss the strength for a teleport spell.");
#ifdef WIZARD
if(!wizard)
#endif
return(1);
}
tele();
morehungry(100);
return(1);
}
placebc(attach) int attach; {
if(!uchain || !uball){
impossible("Where are your chain and ball??");
return;
}
uball->ox = uchain->ox = u.ux;
uball->oy = uchain->oy = u.uy;
if(attach){
uchain->nobj = fobj;
fobj = uchain;
if(!carried(uball)){
uball->nobj = fobj;
fobj = uball;
}
}
}
unplacebc(){
if(!carried(uball)){
freeobj(uball);
unpobj(uball);
}
freeobj(uchain);
unpobj(uchain);
}
level_tele() {
register int newlevel;
#ifdef BVH
if(has_amulet() && rn2(5)) {
pline("You feel very disoriented for a moment.");
return;
}
#endif
if(Teleport_control) {
char buf[BUFSZ];
do {
pline("To what level do you want to teleport? [type a number] ");
getlin(buf);
} while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
newlevel = atoi(buf);
} else {
#ifdef DGKMOD
newlevel = rn2(5) | !Fire_resistance ? rnz(dlevel + 3) : 30;
#else
newlevel = rnz(dlevel + 3); /* 5 - 24 */
#endif
if(dlevel == newlevel)
if(!xdnstair) newlevel--; else newlevel++;
}
if(newlevel >= 30) {
if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;
pline("You arrive at the center of the earth ...");
pline("Unfortunately it is here that hell is located.");
#ifdef DGK
fflush(stdout);
#endif
if(Fire_resistance) {
pline("But the fire doesn't seem to harm you.");
} else {
pline("You burn to a crisp.");
pline("You die...");
dlevel = maxdlevel = newlevel;
killer = "visit to hell";
done("burned");
}
}
if(newlevel < 0) {
if(newlevel <= -10) {
pline("You arrive in heaven.");
pline("\"You are here a bit early, but we'll let you in.\"");
killer = "visit to heaven";
done("died");
} else if (newlevel == -9) {
pline("You feel deliriously happy. ");
pline("(In fact, you're on Cloud 9!) ");
more();
} else newlevel = 0;
pline("You are now high above the clouds ...");
if(Levitation) {
pline("You float gently down to earth.");
done("escaped");
}
pline("Unfortunately, you don't know how to fly.");
pline("You plummet a few thousand feet to your death.");
dlevel = 0;
killer = "long fall";
done("died");
}
goto_level(newlevel, FALSE); /* calls done("escaped") if newlevel==0 */
}
#ifdef NEWTRAPS
domagictrap()
{
register int fate = rnd(20);
/* What happened to the poor sucker? */
if (fate < 10) {
/* Most of the time, it creates some monsters. */
register int cnt = rnd(4);
/* below checks for blindness added by GAN 10/30/86 */
if (!Blind) {
pline("You are momentarily blinded by a flash of light!");
Blinded += rn1(5,10);
seeoff(0);
} else
pline("You hear a deafening roar!");
while(cnt--)
(void) makemon((struct permonst *) 0, u.ux, u.uy);
}
else
switch (fate) {
case 10:
case 11:
/* sometimes nothing happens */
break;
case 12:
/* a flash of fire */
{
register int num;
/* changed to be in conformance with
* SCR_FIRE by GAN 11/02/86
*/
pline("A tower of flame bursts from the floor!");
if(Fire_resistance)
pline("You are uninjured.");
else {
num = rnd(6);
u.uhpmax -= num;
losehp(num,"a burst of flame");
break;
}
}
/* odd feelings */
case 13: pline("A shiver runs up and down your spine!");
break;
case 14: pline("You hear distant howling.");
break;
case 15: pline("You suddenly yearn for your distant homeland.");
break;
case 16: pline("Your pack shakes violently!");
break;
/* very occasionally something nice happens. */
case 19:
/* tame nearby monsters */
{ register int i,j;
register boolean confused = (Confusion != 0);
register int bd = confused ? 5 : 1;
register struct monst *mtmp;
/* below pline added by GAN 10/30/86 */
pline("You feel charismatic.");
for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
if(mtmp = m_at(u.ux+i, u.uy+j))
(void) tamedog(mtmp, (struct obj *) 0);
break;
}
case 20:
/* uncurse stuff */
{ register struct obj *obj;
register boolean confused = (Confusion != 0);
/* below plines added by GAN 10/30/86 */
if (confused)
if (Hallucination)
pline("You feel the power of the Force against you!");
else
pline("You feel like you need some help.");
else
if (Hallucination)
pline("You feel in touch with the Universal Oneness.");
else
pline("You feel like someone is helping you.");
for(obj = invent; obj ; obj = obj->nobj)
if(obj->owornmask)
obj->cursed = confused;
if(Punished && !confused) {
Punished = 0;
freeobj(uchain);
unpobj(uchain);
free((char *) uchain);
uball->spe = 0;
uball->owornmask &= ~W_BALL;
uchain = uball = (struct obj *) 0;
}
break;
}
default: break;
}
}
#endif /* NEWTRAPS /**/
drown()
{
pline("You fall into a pool!");
pline("You can't swim!");
if(
#ifdef WIZARD
wizard ||
#endif
rn2(3) < u.uluck+2) {
/* most scrolls become unreadable */
register struct obj *obj;
for(obj = invent; obj; obj = obj->nobj)
if(obj->olet == SCROLL_SYM && rn2(12) > u.uluck)
obj->otyp = SCR_BLANK_PAPER;
/* we should perhaps merge these scrolls ? */
pline("You attempt a teleport spell."); /* utcsri!carroll */
(void) dotele();
if(!IS_POOL(levl[u.ux][u.uy].typ)) return;
}
pline("You drown.");
pline("You die...");
killer = "pool of water";
done("drowned");
}