void dighole() { struct trap *ttmp = t_at(u.ux, u.uy); if(!xdnstair) { pline("The floor here seems too hard to dig in."); } else { if(ttmp) ttmp->ttyp = TRAPDOOR; else ttmp = maketrap(u.ux, u.uy, TRAPDOOR); ttmp->tseen = 1; pline("You've made a hole in the floor."); if(!u.ustuck) { if(inshop()) shopdig(1); pline("You fall through ..."); if(u.utraptype == TT_PIT) { u.utrap = 0; u.utraptype = 0; } goto_level(dlevel+1, FALSE); } } }
static void makeniche(bool with_trap) { struct mkroom *aroom; struct rm *rm; int vct = 8; coord dd; int dy,xx,yy; struct trap *ttmp; if(doorindex < DOORMAX) while(vct--) { aroom = &rooms[rn2(nroom-1)]; if(aroom->rtype != 0) continue; /* not an ordinary room */ if(aroom->doorct == 1 && rn2(5)) continue; if(rn2(2)) { dy = 1; dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1); } else { dy = -1; dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1); } xx = dd.x; yy = dd.y; if((rm = &levl[xx][yy+dy])->typ) continue; if(with_trap || !rn2(4)) { rm->typ = SCORR; rm->scrsym = ' '; if(with_trap) { ttmp = maketrap(xx, yy+dy, TELEP_TRAP); ttmp->once = 1; make_engr_at(xx, yy-dy, "ad ae?ar um"); } dosdoor(xx, yy, aroom, SDOOR); } else { rm->typ = CORR; rm->scrsym = CORR_SYM; if(rn2(7)) dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); else { mksobj_at(SCR_TELEPORTATION, xx, yy+dy); if(!rn2(3)) mkobj_at(0, xx, yy+dy); } } return; } }
int dospinweb(void) { struct trap *ttmp = t_at(level, u.ux, u.uy); if (Levitation || Is_airlevel(&u.uz) || Underwater || Is_waterlevel(&u.uz)) { pline("You must be on the ground to spin a web."); return 0; } if (u.uswallow) { pline("You release web fluid inside %s.", mon_nam(u.ustuck)); if (is_animal(u.ustuck->data)) { expels(u.ustuck, u.ustuck->data, TRUE); return 0; } if (is_whirly(u.ustuck->data)) { int i; for (i = 0; i < NATTK; i++) if (u.ustuck->data->mattk[i].aatyp == AT_ENGL) break; if (i == NATTK) impossible("Swallower has no engulfing attack?"); else { char sweep[30]; sweep[0] = '\0'; switch(u.ustuck->data->mattk[i].adtyp) { case AD_FIRE: strcpy(sweep, "ignites and "); break; case AD_ELEC: strcpy(sweep, "fries and "); break; case AD_COLD: strcpy(sweep, "freezes, shatters and "); break; } pline("The web %sis swept away!", sweep); } return 0; } /* default: a nasty jelly-like creature */ pline("The web dissolves into %s.", mon_nam(u.ustuck)); return 0; } if (u.utrap) { pline("You cannot spin webs while stuck in a trap."); return 0; } exercise(A_DEX, TRUE); if (ttmp) switch (ttmp->ttyp) { case PIT: case SPIKED_PIT: pline("You spin a web, covering up the pit."); deltrap(ttmp); bury_objs(u.ux, u.uy); newsym(u.ux, u.uy); return 1; case SQKY_BOARD: pline("The squeaky board is muffled."); deltrap(ttmp); newsym(u.ux, u.uy); return 1; case TELEP_TRAP: case LEVEL_TELEP: case MAGIC_PORTAL: case VIBRATING_SQUARE: pline("Your webbing vanishes!"); return 0; case WEB: pline("You make the web thicker."); return 1; case HOLE: case TRAPDOOR: pline("You web over the %s.", (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole"); deltrap(ttmp); newsym(u.ux, u.uy); return 1; case ROLLING_BOULDER_TRAP: pline("You spin a web, jamming the trigger."); deltrap(ttmp); newsym(u.ux, u.uy); return 1; case ARROW_TRAP: case DART_TRAP: case BEAR_TRAP: case ROCKTRAP: case FIRE_TRAP: case LANDMINE: case SLP_GAS_TRAP: case RUST_TRAP: case MAGIC_TRAP: case ANTI_MAGIC: case POLY_TRAP: pline("You have triggered a trap!"); dotrap(ttmp, 0); return 1; default: impossible("Webbing over trap type %d?", ttmp->ttyp); return 0; } else if (On_stairs(u.ux, u.uy)) { /* cop out: don't let them hide the stairs */ pline("Your web fails to impede access to the %s.", (level->locations[u.ux][u.uy].typ == STAIRS) ? "stairs" : "ladder"); return 1; } ttmp = maketrap(level, u.ux, u.uy, WEB); if (ttmp) { ttmp->tseen = 1; ttmp->madeby_u = 1; } newsym(u.ux, u.uy); return 1; }
/* make a trap somewhere (in croom if mazeflag = 0) */ void mktrap(int num, int mazeflag, struct mkroom *croom) { struct trap *ttmp; int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0; xchar mx,my; if(!num || num >= TRAPNUM) { nopierc = (dlevel < 4) ? 1 : 0; nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; if(index(fut_geno, 'M')) nomimic = 1; kind = rn2(TRAPNUM - nopierc - nomimic); /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */ } else kind = num; if(kind == MIMIC) { struct monst *mtmp; fakedoor = (!rn2(3) && !mazeflag); fakegold = (!fakedoor && !rn2(2)); if(fakegold) goldseen = TRUE; do { if(++tryct > 200) return; if(fakedoor) { /* note: fakedoor maybe on actual door */ if(rn2(2)){ if(rn2(2)) mx = croom->hx+1; else mx = croom->lx-1; my = somey(); } else { if(rn2(2)) my = croom->hy+1; else my = croom->ly-1; mx = somex(); } } else if(mazeflag) { coord mm; mm = mazexy(); mx = mm.x; my = mm.y; } else { mx = somex(); my = somey(); } } while(m_at(mx,my) || levl[mx][my].typ == STAIRS); if((mtmp = makemon(PM_MIMIC,mx,my))) { mtmp->mimic = 1; mtmp->mappearance = fakegold ? '$' : fakedoor ? '+' : (mazeflag && rn2(2)) ? AMULET_SYM : "=/)%?![<>" [ rn2(9) ]; } return; } do { if(++tryct > 200) return; if(mazeflag){ coord mm; mm = mazexy(); mx = mm.x; my = mm.y; } else { mx = somex(); my = somey(); } } while(t_at(mx, my) || levl[mx][my].typ == STAIRS); ttmp = maketrap(mx, my, kind); if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC) ttmp->tseen = 1; }
/* Generate earthquake :-) of desired force. That is: create random chasms (pits). Currently assumes that the player created it (you'll need to change at least messages, angering, and kill credit if you generalize it). */ static void do_earthquake(int force) { int x, y; struct monst *mtmp; struct obj *otmp; struct trap *chasm, *oldtrap; int start_x, start_y, end_x, end_y; start_x = youmonst.mx - (force * 2); start_y = youmonst.my - (force * 2); end_x = youmonst.mx + (force * 2); end_y = youmonst.my + (force * 2); if (start_x < 0) start_x = 0; if (start_y < 0) start_y = 0; if (end_x >= COLNO) end_x = COLNO - 1; if (end_y >= ROWNO) end_y = ROWNO - 1; for (x = start_x; x <= end_x; x++) for (y = start_y; y <= end_y; y++) { if ((mtmp = m_at(level, x, y)) != 0) { wakeup(mtmp, FALSE); /* peaceful monster will become hostile */ if (mtmp->mundetected && is_hider(mtmp->data)) { mtmp->mundetected = 0; if (cansee(x, y)) pline(msgc_youdiscover, "%s is shaken loose from %s!", Amonnam(mtmp), mtmp->data == &mons[PM_TRAPPER] ? "its hiding place" : the(ceiling(youmonst.mx, youmonst.my))); else You_hear(msgc_levelsound, "a thumping sound."); if (x == youmonst.mx && y == youmonst.my && mtmp->data != &mons[PM_TRAPPER]) pline(msgc_moncombatgood, "You easily dodge the falling %s.", mon_nam(mtmp)); newsym(x, y); } } if (!rn2(14 - force)) switch (level->locations[x][y].typ) { case FOUNTAIN: /* Make the fountain disappear */ if (cansee(x, y)) pline(msgc_consequence, "The fountain falls into a chasm."); goto do_pit; case SINK: if (cansee(x, y)) pline(msgc_consequence, "The kitchen sink falls into a chasm."); goto do_pit; case ALTAR: if (level->locations[x][y].altarmask & AM_SANCTUM) break; if (cansee(x, y)) pline(msgc_consequence, "The altar falls into a chasm."); goto do_pit; case GRAVE: if (cansee(x, y)) pline(msgc_consequence, "The headstone topples into a chasm."); goto do_pit; case THRONE: if (cansee(x, y)) pline(msgc_consequence, "The throne falls into a chasm."); /* Falls into next case */ case ROOM: case CORR: /* Try to make a pit */ /* Pits, spiked pits, holes, trapdoors, vibrating squares, magic portals are immune. A bear trap will leave the trap in the pit. It would be kind of cool to make landmines detonate, but that's more trouble than it's worth. */ if ((oldtrap = t_at(level, x, y))) { if (oldtrap->ttyp == PIT || oldtrap->ttyp == SPIKED_PIT || oldtrap->ttyp == HOLE || oldtrap->ttyp == TRAPDOOR || oldtrap->ttyp == VIBRATING_SQUARE || oldtrap->ttyp == MAGIC_PORTAL) break; if (oldtrap->ttyp == BEAR_TRAP) { if (mtmp) mtmp->mtrapped = 0; cnv_trap_obj(level, BEARTRAP, 1, oldtrap); } } do_pit: chasm = maketrap(level, x, y, PIT, rng_main); if (!chasm) break; /* no pit if portal at that location */ chasm->tseen = 1; level->locations[x][y].doormask = 0; mtmp = m_at(level, x, y); if ((otmp = sobj_at(BOULDER, level, x, y)) != 0) { if (cansee(x, y)) pline(msgc_consequence, "KADOOM! The boulder falls into a chasm%s!", ((x == youmonst.mx) && (y == youmonst.my)) ? " below you" : ""); if (mtmp) mtmp->mtrapped = 0; obj_extract_self(otmp); flooreffects(otmp, x, y, ""); break; } /* We have to check whether monsters or player falls in a chasm... */ if (mtmp) { if (!flying(mtmp) && !levitates(mtmp) && !is_clinger(mtmp->data)) { mtmp->mtrapped = 1; if (cansee(x, y)) pline(combat_msgc(&youmonst, mtmp, cr_hit), "%s falls into a chasm!", Monnam(mtmp)); else if (humanoid(mtmp->data)) You_hear(msgc_levelsound, "a scream!"); mselftouch(mtmp, "Falling, ", &youmonst); if (!DEADMONSTER(mtmp)) if ((mtmp->mhp -= rnd(6)) <= 0) { if (!cansee(x, y)) pline(msgc_kill, "It is destroyed!"); else { pline(msgc_petfatal, "You destroy %s!", mtmp->mtame ? x_monnam(mtmp, ARTICLE_THE, "poor", mx_name(mtmp) ? SUPPRESS_SADDLE : 0, FALSE) : mon_nam(mtmp)); } xkilled(mtmp, 0); } } } else if (!u.utrap && x == youmonst.mx && y == youmonst.my) { if (Levitation || Flying || is_clinger(youmonst.data)) { pline(msgc_noconsequence, "A chasm opens up under you!"); pline(msgc_noconsequence, "You don't fall in!"); } else { pline(msgc_badidea, "You fall into a chasm!"); u.utrap = rn1(6, 2); u.utraptype = TT_PIT; turnstate.vision_full_recalc = TRUE; losehp(rnd(6), "fell into a chasm"); selftouch("Falling, you", "falling into a chasm while wielding"); } } else newsym(x, y); break; case DOOR: /* Make the door collapse */ if (level->locations[x][y].doormask == D_NODOOR) goto do_pit; if (cansee(x, y)) pline(msgc_consequence, "The door collapses."); if (*in_rooms(level, x, y, SHOPBASE)) add_damage(x, y, 0L); level->locations[x][y].doormask = D_NODOOR; unblock_point(x, y); newsym(x, y); break; } } }
static int dig() { struct rm *lev; int dpx = dig_pos.x, dpy = dig_pos.y; /* perhaps a nymph stole his pick-axe while he was busy digging */ /* or perhaps he teleported away */ if(u.uswallow || !uwep || uwep->otyp != PICK_AXE || dig_level != dlevel || ((dig_down && (dpx != u.ux || dpy != u.uy)) || (!dig_down && dist(dpx,dpy) > 2))) return(0); dig_effort += 10 + abon() + uwep->spe + rn2(5); if(dig_down) { if(!xdnstair) { pline("The floor here seems too hard to dig in."); return(0); } if(dig_effort > 250) { dighole(); return(0); /* done with digging */ } if(dig_effort > 50) { struct trap *ttmp = t_at(dpx,dpy); if(!ttmp) { ttmp = maketrap(dpx,dpy,PIT); ttmp->tseen = 1; pline("You have dug a pit."); u.utrap = rn1(4,2); u.utraptype = TT_PIT; return(0); } } } else if (dig_effort > 100) { char *digtxt; struct obj *obj; lev = &levl[dpx][dpy]; if ((obj = sobj_at(ENORMOUS_ROCK, dpx, dpy))) { fracture_rock(obj); digtxt = "The rock falls apart."; } else if(!lev->typ || lev->typ == SCORR) { lev->typ = CORR; digtxt = "You succeeded in cutting away some rock."; } else if(lev->typ == HWALL || lev->typ == VWALL || lev->typ == SDOOR) { lev->typ = xdnstair ? DOOR : ROOM; digtxt = "You just made an opening in the wall."; } else digtxt = "Now what exactly was it that you were digging in?"; mnewsym(dpx, dpy); prl(dpx, dpy); pline(digtxt); /* after mnewsym & prl */ return(0); } else { if(IS_WALL(levl[dpx][dpy].typ)) { int rno = inroom(dpx,dpy); if(rno >= 0 && rooms[rno].rtype >= 8) { pline("This wall seems too hard to dig into."); return(0); } } pline("You hit the rock with all your might."); } return(1); }