damage_instance::damage_instance( damage_type dt, float a, int rp, float rm, float mul ) { add_damage( dt, a, rp, rm, mul ); }
/* Called every turn during lock-picking. The caller must set u.utracked[tos_lock] appropriately: &zeroobj for a door, an object for a box. For a door, u.utracked_location[tl_lock] must also be set. */ static int picklock(void) { int chance = get_unlock_chance(); int x = u.utracked_location[tl_lock].x; int y = u.utracked_location[tl_lock].y; struct rm *door = NULL; if (u.utracked[tos_lock] != &zeroobj) { if (!obj_with_u(u.utracked[tos_lock])) return reset_pick(); } else { /* door */ door = &(level->locations[x][y]); switch (door->doormask) { case D_NODOOR: pline(msgc_cancelled, "This doorway has no door."); return reset_pick(); case D_ISOPEN: pline(msgc_cancelled, "You cannot lock an open door."); return reset_pick(); case D_BROKEN: pline(msgc_cancelled, "This door is broken."); return reset_pick(); } } if (!chance) { pline(msgc_interrupted, "You seem to have lost your unlocking tools."); return reset_pick(); } if (u.uoccupation_progress[tos_lock]++ >= 50 || nohands(youmonst.data)) { pline(msgc_failrandom, "You give up your attempt at %s.", lock_action()); if (!nohands(youmonst.data)) exercise(A_DEX, TRUE); /* even if you don't succeed */ return reset_pick(); } if (rn2(100) >= chance) return 1; /* still busy */ pline(msgc_actionok, "You succeed in %s.", lock_action()); if (door) { if (door->doormask & D_TRAPPED) { b_trapped("door", FINGER); door->doormask = D_NODOOR; unblock_point(x, y); if (*in_rooms(level, x, y, SHOPBASE)) add_damage(x, y, 0L); } else if (door->doormask & D_LOCKED) door->doormask = D_CLOSED; else door->doormask = D_LOCKED; /* player now knows the door's open/closed status, and its locked/unlocked status, and also that it isn't trapped (it would have exploded otherwise); thus, we can safely fully spoil the door's stats (the door is the background of the door's location) */ magic_map_background(x, y, TRUE); } else { u.utracked[tos_lock]->olocked = !u.utracked[tos_lock]->olocked; if (u.utracked[tos_lock]->otrapped) chest_trap(&youmonst, u.utracked[tos_lock], FINGER, FALSE); } exercise(A_DEX, TRUE); return reset_pick(); }
/* 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; } } }