/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.trap.c version 1.0.1 - added dotele(); */ #include "hack.h" #include "def.trap.h" extern struct monst *makemon(); char vowels[] = "aeiou"; char *traps[] = { " bear trap", "n arrow trap", " dart trap", " trapdoor", " teleportation trap", " pit", " sleeping gas trap", " piercer", " mimic" }; dotrap(trap) register struct gen *trap; { nomul(0); if(trap->gflag&SEEN && !rn2(5)) pline("You escape a%s.",traps[trap->gflag & TRAPTYPE]); else { trap->gflag |= SEEN; switch(trap->gflag & TRAPTYPE) { 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!"); break; case PIERC: deltrap(trap); if(makemon(PM_PIERC,u.ux,u.uy)) { pline("A piercer suddenly drops from the ceiling!"); 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(WEAPON_SYM, 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"); } 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; } 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(WEAPON_SYM, DART, u.ux, u.uy); fobj->quan = 1; } break; case TELEP_TRAP: if(trap->gflag & ONCE) { deltrap(trap); newsym(u.ux,u.uy); vtele(); } else { newsym(u.ux,u.uy); tele(); } break; case PIT: if(Levitation) { 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; default: pline("You hit a trap of type %d",trap->gflag); impossible(); } } } mintrap(mtmp) register struct monst *mtmp; { register struct gen *gen = g_at(mtmp->mx, mtmp->my, ftrap); register int wasintrap = mtmp->mtrapped; if(!gen) { mtmp->mtrapped = 0; /* perhaps teleported? */ } else if(wasintrap) { if(!rn2(40)) mtmp->mtrapped = 0; } else { register int tt = (gen->gflag & TRAPTYPE); int in_sight = cansee(mtmp->mx,mtmp->my); 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(strchr(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; case PIT: if(!strchr("Eyw", mtmp->data->mlet)) { mtmp->mtrapped = 1; if(in_sight) pline("%s falls in 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: 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(mtmp->data->mlet != 'w'){ 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; default: pline("Some monster encountered an impossible trap."); impossible(); } } 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."); 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 pline("You start to float in the air!"); } float_down(){ register struct gen *trap; pline("You float gently to the ground."); if(trap = g_at(u.ux,u.uy,ftrap)) switch(trap->gflag & TRAPTYPE) { case PIERC: break; case TRAPDOOR: if(!xdnstair || u.ustuck) break; /* fall into next case */ default: dotrap(trap); } pickup(); } vtele() { #define VAULT 6 register struct mkroom *croom; for(croom = &rooms[0]; croom->hx >= 0; croom++) if(croom->rtype == VAULT) { register int 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(); } tele() { extern coord getpos(); coord cc; register int nux,nuy; if(Teleport_control) { pline("To what position do you want to be teleported?"); cc = getpos(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 ..."); } 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); (void) inshop(); pickup(); if(!Blind) read_engr_at(u.ux,u.uy); } teleok(x,y) register int x,y; { return( isok(x,y) && levl[x][y].typ > DOOR && !m_at(x,y) && !sobj_at(ENORMOUS_ROCK,x,y) && !g_at(x,y,ftrap) ); /* Note: gold is permitted (because of vaults) */ } dotele() { extern char pl_character[]; if( #ifdef WIZARD !wizard && #endif WIZARD (!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."); return(1); } tele(); morehungry(100); return(1); } placebc(attach) int attach; { if(!uchain || !uball){ pline("Where are your chain and ball??"); impossible(); 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 = 5 + rn2(20); /* 5 - 24 */ if(dlevel == newlevel) if(!xdnstair) newlevel--; else newlevel++; goto_level(newlevel, FALSE); }