/** * Remove traps. * * If called with t_idx < 0, will remove all traps in the location given. * Otherwise, will remove all traps with the given kind. * * Return TRUE if no traps now exist in this grid. */ bool square_remove_trap(struct chunk *c, int y, int x, bool domsg, int t_idx) { bool trap_exists; struct trap **trap_slot = &c->squares[y][x].trap; struct trap *next_trap; /* Look at the traps in this grid */ while (*trap_slot) { /* Get the next trap (may be NULL) */ next_trap = (*trap_slot)->next; /* If called with a specific index, skip others */ if ((t_idx >= 0) && (t_idx != (*trap_slot)->t_idx)) { if (!next_trap) break; trap_slot = &next_trap; continue; } /* Remove it */ remove_trap_aux(c, *trap_slot, y, x, domsg); /* Replace with the next trap */ *trap_slot = next_trap; } /* Refresh grids that the character can see */ if (square_isseen(c, y, x)) square_light_spot(c, y, x); /* Verify traps (remove marker if appropriate) */ trap_exists = square_verify_trap(c, y, x, 0); /* Report whether any traps exist in this grid */ return (!trap_exists); }
/** * Hit a trap. */ extern void hit_trap(int y, int x) { bool ident; struct trap *trap; struct effect *effect; /* Count the hidden traps here */ int num = num_traps(cave, y, x, -1); /* Oops. We've walked right into trouble. */ if (num == 1) msg("You stumble upon a trap!"); else if (num > 1) msg("You stumble upon some traps!"); /* Look at the traps in this grid */ for (trap = cave->squares[y][x].trap; trap; trap = trap->next) { /* Require that trap be capable of affecting the character */ if (!trf_has(trap->kind->flags, TRF_TRAP)) continue; /* Disturb the player */ disturb(player, 0); /* Fire off the trap */ effect = trap->kind->effect; effect_do(effect, &ident, FALSE, 0, 0, 0); /* Trap becomes visible (always XXX) */ trf_on(trap->flags, TRF_VISIBLE); sqinfo_on(cave->squares[y][x].info, SQUARE_MARK); } /* Verify traps (remove marker if appropriate) */ (void)square_verify_trap(cave, y, x, 0); }
/** * Remove traps. * * If called with t_idx < 0, will remove all traps in the location given. * Otherwise, will remove all traps with the given kind. * * Return true if no traps now exist in this grid. */ bool square_set_trap_timeout(struct chunk *c, int y, int x, bool domsg, int t_idx, int time) { bool trap_exists; struct trap *current_trap = NULL; /* Bounds check */ assert(square_in_bounds(c, y, x)); /* Look at the traps in this grid */ current_trap = c->squares[y][x].trap; while (current_trap) { /* Get the next trap (may be NULL) */ struct trap *next_trap = current_trap->next; /* If called with a specific index, skip others */ if ((t_idx >= 0) && (t_idx != current_trap->t_idx)) { if (!next_trap) break; current_trap = next_trap; continue; } /* Set the timer */ current_trap->timeout = time; /* Message if requested */ msg("You have disabled the %s.", current_trap->kind->name); /* Replace with the next trap */ current_trap = next_trap; } /* Refresh grids that the character can see */ if (square_isseen(c, y, x)) square_light_spot(c, y, x); /* Verify traps (remove marker if appropriate) */ trap_exists = square_verify_trap(c, y, x, 0); /* Report whether any traps exist in this grid */ return (!trap_exists); }
/** * Remove traps. * * If called with t_idx < 0, will remove all traps in the location given. * Otherwise, will remove all traps with the given kind. * * Return true if traps were removed. */ bool square_remove_trap(struct chunk *c, int y, int x, int t_idx_remove) { assert(square_in_bounds(c, y, x)); bool removed = false; /* Look at the traps in this grid */ struct trap *prev_trap = NULL; struct trap *trap = c->squares[y][x].trap; while (trap) { struct trap *next_trap = trap->next; if (t_idx_remove == trap->t_idx) { mem_free(trap); removed = true; if (prev_trap) { prev_trap->next = next_trap; } else { c->squares[y][x].trap = next_trap; } break; } prev_trap = trap; trap = next_trap; } /* Refresh grids that the character can see */ if (square_isseen(c, y, x)) square_light_spot(c, y, x); (void)square_verify_trap(c, y, x, 0); return removed; }
/** * Remove all traps from a grid. * * Return true if traps were removed. */ bool square_remove_all_traps(struct chunk *c, int y, int x) { assert(square_in_bounds(c, y, x)); struct trap *trap = c->squares[y][x].trap; bool were_there_traps = trap == NULL ? false : true; while (trap) { struct trap *next_trap = trap->next; mem_free(trap); trap = next_trap; } c->squares[y][x].trap = NULL; /* Refresh grids that the character can see */ if (square_isseen(c, y, x)) { square_light_spot(c, y, x); } (void)square_verify_trap(c, y, x, 0); return were_there_traps; }
/** * Hit a trap. */ extern void hit_trap(int y, int x) { bool ident = false; struct trap *trap; struct effect *effect; /* Count the hidden traps here */ int num = num_traps(cave, y, x, -1); /* The player is safe from all traps */ if (player_is_trapsafe(player)) return; /* Oops. We've walked right into trouble. */ if (num == 1) msg("You stumble upon a trap!"); else if (num > 1) msg("You stumble upon some traps!"); /* Look at the traps in this grid */ for (trap = square_trap(cave, y, x); trap; trap = trap->next) { int flag; bool saved = false; /* Require that trap be capable of affecting the character */ if (!trf_has(trap->kind->flags, TRF_TRAP)) continue; if (trap->timeout) continue; /* Disturb the player */ disturb(player, 0); /* Give a message */ if (trap->kind->msg) msg(trap->kind->msg); /* Test for save due to flag */ for (flag = of_next(trap->kind->save_flags, FLAG_START); flag != FLAG_END; flag = of_next(trap->kind->save_flags, flag + 1)) if (player_of_has(player, flag)) { saved = true; equip_learn_flag(player, flag); } /* Test for save due to armor */ if (trf_has(trap->kind->flags, TRF_SAVE_ARMOR) && !trap_check_hit(125)) saved = true; /* Test for save due to saving throw */ if (trf_has(trap->kind->flags, TRF_SAVE_THROW) && (randint0(100) < player->state.skills[SKILL_SAVE])) saved = true; /* Save, or fire off the trap */ if (saved) { if (trap->kind->msg_good) msg(trap->kind->msg_good); } else { if (trap->kind->msg_bad) msg(trap->kind->msg_bad); effect = trap->kind->effect; effect_do(effect, source_trap(trap), NULL, &ident, false, 0, 0, 0); /* Do any extra effects */ if (trap->kind->effect_xtra && one_in_(2)) { if (trap->kind->msg_xtra) msg(trap->kind->msg_xtra); effect = trap->kind->effect_xtra; effect_do(effect, source_trap(trap), NULL, &ident, false, 0, 0, 0); } } /* Some traps drop you a dungeon level */ if (trf_has(trap->kind->flags, TRF_DOWN)) dungeon_change_level(player, dungeon_get_next_level(player->depth, 1)); /* Some traps drop you onto them */ if (trf_has(trap->kind->flags, TRF_PIT)) monster_swap(player->py, player->px, trap->fy, trap->fx); /* Some traps disappear after activating, all have a chance to */ if (trf_has(trap->kind->flags, TRF_ONETIME) || one_in_(3)) { square_destroy_trap(cave, y, x); square_forget(cave, y, x); } /* Trap may have gone */ if (!square_trap(cave, y, x)) break; /* Trap becomes visible (always XXX) */ trf_on(trap->flags, TRF_VISIBLE); square_memorize(cave, y, x); } /* Verify traps (remove marker if appropriate) */ (void)square_verify_trap(cave, y, x, 0); }