/* set hit=true if a party or Object.has been struck return true if the missile has not been interupted */ bool Missile::enterTile(struct place *place, int x, int y) { if (! (flags & MISSILE_IGNORE_LOS)) { return ! obstructed(place, x, y); } if (! (flags & MISSILE_HIT_PARTY)) return true; struck = place_get_Party(place, x, y); if (struck != NULL) { hit = true; return false; } // fugly hack... if (player_party->getPlace() == place && player_party->getX() == x && player_party->getY() == y) { struck = player_party; hit = true; return false; } /* Allow wilderness-scale weapons to destroy empty vehicles. */ struck = place_get_vehicle(place, x, y); if (struck != NULL) { hit = true; return false; } return true; }
/* returns true if something happened */ boolean doorlock(struct obj * otmp, int x, int y) { struct rm *door = &level->locations[x][y]; boolean res = TRUE; int loudness = 0; int wandlevel = 0; if (otmp->oclass == WAND_CLASS) wandlevel = getwandlevel(&youmonst, otmp); /* Not completely right, but works since monsters wont use knock/wizlock */ const char *msg = NULL; const char *dustcloud = "A cloud of dust"; const char *quickly_dissipates = "quickly dissipates"; if (door->typ == SDOOR) { switch (otmp->otyp) { case WAN_OPENING: case SPE_KNOCK: case WAN_STRIKING: case SPE_FORCE_BOLT: door->typ = DOOR; door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); newsym(x, y); if (cansee(x, y)) pline(msgc_youdiscover, "A door appears in the wall!"); if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK) return TRUE; break; /* striking: continue door handling below */ case WAN_LOCKING: case SPE_WIZARD_LOCK: default: return FALSE; } } switch (otmp->otyp) { case WAN_LOCKING: case SPE_WIZARD_LOCK: if (Is_rogue_level(&u.uz)) { boolean vis = cansee(x, y); /* Can't have real locking in Rogue, so just hide doorway */ if (vis) pline(msgc_actionok, "%s springs up in the older, more primitive doorway.", dustcloud); else You_hear(msgc_actionok, "a swoosh."); if (obstructed(x, y, msgc_yafm)) { if (vis) pline(msgc_yafm, "The cloud %s.", quickly_dissipates); return FALSE; } block_point(x, y); door->typ = SDOOR; if (vis) pline(msgc_actionok, "The doorway vanishes!"); newsym(x, y); return TRUE; } if (obstructed(x, y, msgc_yafm)) return FALSE; /* Don't allow doors to close over traps. This is for pits */ /* & trap doors, but is it ever OK for anything else? */ if (t_at(level, x, y)) { /* maketrap() clears doormask, so it should be NODOOR */ pline(msgc_yafm, "%s springs up in the doorway, but %s.", dustcloud, quickly_dissipates); return FALSE; } if (wandlevel == P_MASTER) { pline(msgc_yafm, "%s springs up in the doorway and conceals it!", dustcloud); door->typ = SDOOR; newsym(x, y); return TRUE; } switch (door->doormask & ~D_TRAPPED) { case D_CLOSED: msg = "The door locks!"; break; case D_ISOPEN: msg = "The door swings shut, and locks!"; break; case D_BROKEN: msg = "The broken door reassembles and locks!"; break; case D_NODOOR: msg = "A cloud of dust springs up and assembles itself into a door!"; break; default: res = FALSE; break; } block_point(x, y); door->doormask = D_LOCKED | (door->doormask & D_TRAPPED); newsym(x, y); break; case WAN_OPENING: case SPE_KNOCK: if (door->doormask & D_LOCKED) { msg = "The door unlocks!"; door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); } else res = FALSE; break; case WAN_STRIKING: case SPE_FORCE_BOLT: if (door->doormask & (D_LOCKED | D_CLOSED)) { if (door->doormask & D_TRAPPED) { if (MON_AT(level, x, y)) mb_trapped(m_at(level, x, y)); else { if (cansee(x, y)) pline(msgc_substitute, "KABOOM!! You see a door explode."); else You_hear(msgc_levelsound, "a distant explosion."); } door->doormask = D_NODOOR; unblock_point(x, y); newsym(x, y); loudness = 40; break; } door->doormask = D_BROKEN; if (cansee(x, y)) pline(msgc_actionok, "The door crashes open!"); else You_hear(msgc_levelsound, "a crashing sound."); unblock_point(x, y); newsym(x, y); /* force vision recalc before printing more messages */ if (turnstate.vision_full_recalc) vision_recalc(0); loudness = 20; } else res = FALSE; break; default: impossible("magic (%d) attempted on door.", otmp->otyp); break; } if (msg && cansee(x, y)) { pline(msgc_actionok, "%s", msg); /* we know whether it's locked now */ level->locations[x][y].mem_door_l = 1; map_background(x, y, TRUE); } if (loudness > 0) { /* door was destroyed */ wake_nearto(x, y, loudness); if (*in_rooms(level, x, y, SHOPBASE)) add_damage(x, y, 0L); } return res; }
/* try to close a door */ int doclose(const struct nh_cmd_arg *arg) { struct rm *door; struct monst *mtmp; coord cc; schar dx, dy, dz; if (nohands(youmonst.data)) { pline(msgc_cancelled, "You can't close anything -- you have no hands!"); return 0; } if (u.utrap && u.utraptype == TT_PIT) { pline(msgc_cancelled, "You can't reach over the edge of the pit."); return 0; } if (!getargdir(arg, NULL, &dx, &dy, &dz)) return 0; cc.x = youmonst.mx + dx; cc.y = youmonst.my + dy; if (!isok(cc.x, cc.y)) return 0; if ((cc.x == youmonst.mx) && (cc.y == youmonst.my)) { pline(msgc_cancelled1, "You are in the way!"); return 1; } if ((mtmp = m_at(level, cc.x, cc.y)) && mtmp->m_ap_type == M_AP_FURNITURE && (mtmp->mappearance == S_hcdoor || mtmp->mappearance == S_vcdoor) && !Protection_from_shape_changers) { stumble_onto_mimic(mtmp, dx, dy); return 1; } door = &level->locations[cc.x][cc.y]; if (!IS_DOOR(door->typ)) { if (door->typ == DRAWBRIDGE_DOWN) pline(msgc_cancelled, "There is no obvious way to close the drawbridge."); else pline(msgc_mispaste, "You %s no door there.", Blind ? "feel" : "see"); return 0; } if (door->doormask == D_NODOOR) { pline(msgc_cancelled, "This doorway has no door."); return 0; } if (obstructed(cc.x, cc.y, msgc_cancelled)) return 0; if (door->doormask == D_BROKEN) { pline(msgc_cancelled, "This door is broken."); return 0; } if (door->doormask & (D_CLOSED | D_LOCKED)) { pline(msgc_cancelled, "This door is already closed."); return 0; } if (door->doormask == D_ISOPEN) { if (verysmall(youmonst.data) && !u.usteed) { pline(msgc_cancelled, "You're too small to push the door closed."); return 0; } if (u.usteed || rn2(25) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) { pline(msgc_actionok, "The door closes."); door->doormask = D_CLOSED; door->mem_door_l = 1; /* map_background here sets the mem_door flags correctly; and it's redundant to both feel_location and newsym with a door. Exception: if we remember an invisible monster on the door square, but in this case, we want to set the memory of a door there anyway because we know there's a door there because we just closed it, and in Nitro this doesn't clash with keeping the I there. */ map_background(cc.x, cc.y, TRUE); if (Blind) feel_location(cc.x, cc.y); /* the hero knows she closed it */ else newsym(cc.x, cc.y); block_point(cc.x, cc.y); /* vision: no longer see there */ } else { exercise(A_STR, TRUE); pline(msgc_failrandom, "The door resists!"); } } return 1; }