#include "angband.h"
+bool confirm_leave_level(bool down_stair)
+{
+ quest_type *q_ptr = &quest[p_ptr->inside_quest];
+
+ /* Confirm leaving from once only quest */
+ if (confirm_quest && p_ptr->inside_quest &&
+ (q_ptr->type == QUEST_TYPE_RANDOM ||
+ (q_ptr->flags & QUEST_FLAG_ONCE &&
+ q_ptr->status != QUEST_STATUS_COMPLETED) ||
+ (q_ptr->flags & QUEST_FLAG_TOWER &&
+ ((q_ptr->status != QUEST_STATUS_STAGE_COMPLETED) ||
+ (down_stair && (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED))))))
+ {
+#ifdef JP
+ msg_print("¤³¤Î³¬¤ò°ìÅÙµî¤ë¤ÈÆóÅÙ¤ÈÌá¤Ã¤ÆÍè¤é¤ì¤Þ¤»¤ó¡£");
+ if (get_check("ËÜÅö¤Ë¤³¤Î³¬¤òµî¤ê¤Þ¤¹¤«¡©")) return TRUE;
+#else
+ msg_print("You can't come back here once you leave this floor.");
+ if (get_check("Really leave this floor? ")) return TRUE;
+#endif
+ }
+ else
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
* Go up one level
/* Quest up stairs */
if (have_flag(f_ptr->flags, FF_QUEST))
{
+ /* Cancel the command */
+ if (!confirm_leave_level(FALSE)) return;
+
+
/* Success */
#ifdef JP
if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
/* Activate the quest */
if (!quest[p_ptr->inside_quest].status)
{
+ if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
+ {
+ init_flags = INIT_ASSIGN;
+ process_dungeon_file("q_info.txt", 0, 0, 0, 0);
+ }
quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
}
p_ptr->oldpx = 0;
p_ptr->oldpy = 0;
+
+ /* Hack -- take a turn */
+ energy_use = 100;
/* End the command */
return;
}
else
{
- quest_type *q_ptr = &quest[p_ptr->inside_quest];
-
- /* Confirm leaving from once only quest */
- if (confirm_quest && p_ptr->inside_quest &&
- (q_ptr->type == QUEST_TYPE_RANDOM ||
- (q_ptr->flags & QUEST_FLAG_ONCE &&
- q_ptr->status != QUEST_STATUS_COMPLETED)))
- {
-#ifdef JP
- msg_print("¤³¤Î³¬¤ò°ìÅÙµî¤ë¤ÈÆóÅÙ¤ÈÌá¤Ã¤ÆÍè¤é¤ì¤Þ¤»¤ó¡£");
- if (get_check("ËÜÅö¤Ë¤³¤Î³¬¤òµî¤ê¤Þ¤¹¤«¡©")) go_up = TRUE;
-#else
- msg_print("You can't come back here once you leave this floor.");
- if (get_check("Really leave this floor? ")) go_up = TRUE;
-#endif
- }
- else
- {
- go_up = TRUE;
- }
+ go_up = confirm_leave_level(FALSE);
}
/* Cancel the command */
/* Quest down stairs */
else if (have_flag(f_ptr->flags, FF_QUEST))
{
+ /* Confirm Leaving */
+ if(!confirm_leave_level(TRUE)) return;
+
#ifdef JP
if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª");
msg_print("You enter the down staircase.");
#endif
-
leave_quest_check();
+ leave_tower_check();
p_ptr->inside_quest = c_ptr->special;
/* Activate the quest */
if (!quest[p_ptr->inside_quest].status)
{
+ if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
+ {
+ init_flags = INIT_ASSIGN;
+ process_dungeon_file("q_info.txt", 0, 0, 0, 0);
+ }
quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
}
p_ptr->oldpx = 0;
p_ptr->oldpy = 0;
+
+
+ /* Hack -- take a turn */
+ energy_use = 100;
}
else
/*
* Determine if a grid contains a chest
*/
-static s16b chest_check(int y, int x)
+static s16b chest_check(int y, int x, bool trapped)
{
cave_type *c_ptr = &cave[y][x];
/* Skip unknown chests XXX XXX */
/* if (!(o_ptr->marked & OM_FOUND)) continue; */
- /* Check for chest */
- if (o_ptr->tval == TV_CHEST) return (this_o_idx);
+ /* Check for non empty chest */
+ if ((o_ptr->tval == TV_CHEST) &&
+ (((!trapped) && (o_ptr->pval)) || /* non empty */
+ ((trapped) && (o_ptr->pval > 0)))) /* trapped only */
+ {
+ return (this_o_idx);
+ }
}
/* No chest */
int xx = px + ddx_ddd[d];
/* No (visible) chest is there */
- if ((o_idx = chest_check(yy, xx)) == 0) continue;
+ if ((o_idx = chest_check(yy, xx, FALSE)) == 0) continue;
/* Grab the object */
o_ptr = &o_list[o_idx];
feat = get_feat_mimic(c_ptr);
/* Check for chest */
- o_idx = chest_check(y, x);
+ o_idx = chest_check(y, x, FALSE);
/* Nothing useful */
if (!have_flag(f_info[feat].flags, FF_OPEN) && !o_idx)
feat = get_feat_mimic(c_ptr);
/* Check for chests */
- o_idx = chest_check(y, x);
+ o_idx = chest_check(y, x, TRUE);
/* Disarm a trap */
if (!is_trap(feat) && !o_idx)
{
int dir;
int i, j, y, x, ny, nx, ty, tx, prev_y, prev_x;
- int tdam, tdis, thits, tmul;
+ int tdam_base, tdis, thits, tmul;
int bonus, chance;
int cur_dis, visible;
tdis = 10;
/* Base damage from thrown object plus launcher bonus */
- tdam = damroll(o_ptr->dd, o_ptr->ds) + o_ptr->to_d + j_ptr->to_d;
+ tdam_base = damroll(o_ptr->dd, o_ptr->ds) + o_ptr->to_d + j_ptr->to_d;
/* Actually "fire" the object */
bonus = (p_ptr->to_h_b + o_ptr->to_h + j_ptr->to_h);
tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
/* Boost the damage */
- tdam *= tmul;
- tdam /= 100;
-
- /* Get extra damage from concentration */
- if (p_ptr->concent) tdam = boost_concentration_damage(tdam);
+ tdam_base *= tmul;
+ tdam_base /= 100;
/* Base range */
tdis = 13 + tmul/80;
if (test_hit_fire(chance - cur_dis, armour, m_ptr->ml))
{
bool fear = FALSE;
+ int tdam = tdam_base;
+
+ /* Get extra damage from concentration */
+ if (p_ptr->concent) tdam = boost_concentration_damage(tdam);
/* Handle unseen monster */
if (!visible)
int i, j, y, x, ty, tx, prev_y, prev_x;
int ny[19], nx[19];
int chance, tdam, tdis;
- int mul, div;
+ int mul, div, dd, ds;
int cur_dis, visible;
object_type forge;
set_action(ACTION_NONE);
}
- if (shuriken)
+ if (shuriken >= 0)
{
item = shuriken;
}
/* Extract the thrown object's flags. */
object_flags(q_ptr, flgs);
+ torch_flags(q_ptr, flgs);
/* Distribute the charges of rods/wands between the stacks */
distribute_charges(o_ptr, q_ptr, 1);
/* Max distance of 10-18 */
if (tdis > mul) tdis = mul;
- if (shuriken)
+ if (shuriken >= 0)
{
ty = randint0(101)-50+py;
tx = randint0(101)-50+px;
}
/* Hack -- Base damage from thrown object */
- tdam = damroll(q_ptr->dd, q_ptr->ds);
+ dd = q_ptr->dd;
+ ds = q_ptr->ds;
+ torch_dice(q_ptr, &dd, &ds); /* throwing a torch */
+ tdam = damroll(dd, ds);
/* Apply special damage XXX XXX XXX */
tdam = tot_dam_aux(q_ptr, tdam, m_ptr, 0, TRUE);
tdam = critical_shot(q_ptr->weight, q_ptr->to_h, tdam);
}
}
+ /* decrease toach's fuel */
+ if (hit_body) torch_lost_fuel(q_ptr);
+
/* Chance of breakage (during attacks) */
j = (hit_body ? breakage_chance(q_ptr) : 0);
*/
void do_cmd_throw(void)
{
- do_cmd_throw_aux(1, FALSE, 0);
+ do_cmd_throw_aux(1, FALSE, -1);
}
for (x = 0; x < cur_wid; x++)
{
/* Forget the old data */
- travel.cost[y][x] = TRAVEL_UNABLE;
+ travel.cost[y][x] = MAX_SHORT;
}
}
+
+ travel.y = travel.x = 0;
}
-static bool travel_flow_aux(int y, int x, int n, bool wall)
+static int travel_flow_cost(int y, int x)
+{
+ feature_type *f_ptr = &f_info[cave[y][x].feat];
+ int cost = 1;
+
+ /* Avoid obstacles (ex. trees) */
+ if (have_flag(f_ptr->flags, FF_AVOID_RUN)) cost += 1;
+
+ /* Water */
+ if (have_flag(f_ptr->flags, FF_WATER))
+ {
+ if (have_flag(f_ptr->flags, FF_DEEP) && !p_ptr->levitation) cost += 5;
+ }
+
+ /* Lava */
+ if (have_flag(f_ptr->flags, FF_LAVA))
+ {
+ int lava = 2;
+ if (!p_ptr->resist_fire) lava *= 2;
+ if (!p_ptr->levitation) lava *= 2;
+ if (have_flag(f_ptr->flags, FF_DEEP)) lava *= 2;
+
+ cost += lava;
+ }
+
+ /* Detected traps and doors */
+ if (cave[y][x].info & (CAVE_MARK))
+ {
+ if (have_flag(f_ptr->flags, FF_DOOR)) cost += 1;
+ if (have_flag(f_ptr->flags, FF_TRAP)) cost += 10;
+ }
+
+ return (cost);
+}
+
+static void travel_flow_aux(int y, int x, int n, bool wall)
{
cave_type *c_ptr = &cave[y][x];
feature_type *f_ptr = &f_info[c_ptr->feat];
int old_head = flow_head;
-
- n = n % TRAVEL_UNABLE;
+ int add_cost = 1;
+ int base_cost = (n % TRAVEL_UNABLE);
+ int from_wall = (n / TRAVEL_UNABLE);
+ int cost;
/* Ignore out of bounds */
- if (!in_bounds(y, x)) return wall;
+ if (!in_bounds(y, x)) return;
- /* Ignore "pre-stamped" entries */
- if (travel.cost[y][x] != TRAVEL_UNABLE) return wall;
+ /* Ignore unknown grid except in wilderness */
+ if (dun_level > 0 && !(c_ptr->info & CAVE_KNOWN)) return;
/* Ignore "walls" and "rubble" (include "secret doors") */
if (have_flag(f_ptr->flags, FF_WALL) ||
(have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic) ||
(!have_flag(f_ptr->flags, FF_MOVE) && have_flag(f_ptr->flags, FF_CAN_FLY) && !p_ptr->levitation))
{
- if (!wall) return wall;
+ if (!wall || !from_wall) return;
+ add_cost += TRAVEL_UNABLE;
}
else
{
- wall = FALSE;
+ add_cost = travel_flow_cost(y, x);
}
+ cost = base_cost + add_cost;
+
+ /* Ignore lower cost entries */
+ if (travel.cost[y][x] <= cost) return;
+
/* Save the flow cost */
- travel.cost[y][x] = n;
- if (wall) travel.cost[y][x] += TRAVEL_UNABLE;
+ travel.cost[y][x] = cost;
/* Enqueue that entry */
temp2_y[flow_head] = y;
/* Hack -- notice overflow by forgetting new entry */
if (flow_head == flow_tail) flow_head = old_head;
- return wall;
+ return;
}
{
int x, y, d;
bool wall = FALSE;
- feature_type *f_ptr = &f_info[cave[ty][tx].feat];
+ feature_type *f_ptr = &f_info[cave[py][px].feat];
/* Reset the "queue" */
flow_head = flow_tail = 0;
+ /* is player in the wall? */
if (!have_flag(f_ptr->flags, FF_MOVE)) wall = TRUE;
- /* Add the player's grid to the queue */
- wall = travel_flow_aux(ty, tx, 0, wall);
+ /* Start at the target grid */
+ travel_flow_aux(ty, tx, 0, wall);
/* Now process the queue */
while (flow_head != flow_tail)
/* Forget that entry */
if (++flow_tail == MAX_SHORT) flow_tail = 0;
+ /* Ignore too far entries */
+ //if (distance(ty, tx, y, x) > 100) continue;
+
/* Add the "children" */
for (d = 0; d < 8; d++)
{
/* Add that child if "legal" */
- wall = travel_flow_aux(y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x] + 1, wall);
+ travel_flow_aux(y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x], wall);
}
}
int dx, dy, sx, sy;
feature_type *f_ptr;
- if (!tgt_pt(&x, &y)) return;
+ if (travel.x != 0 && travel.y != 0 &&
+ get_check(_("¥È¥é¥Ù¥ë¤ò·Ñ³¤·¤Þ¤¹¤«¡©", "Do you continue to travel?")))
+ {
+ y = travel.y;
+ x = travel.x;
+ }
+ else if (!tgt_pt(&x, &y)) return;
if ((x == px) && (y == py))
{
return;
}
- travel.x = x;
- travel.y = y;
-
forget_travel_flow();
travel_flow(y, x);
+ travel.x = x;
+ travel.y = y;
+
/* Travel till 255 steps */
travel.run = 255;