OSDN Git Service

Modify travel command
[hengband/hengband.git] / src / cmd2.c
index 11355bf..1d24fc5 100644 (file)
 
 #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
@@ -46,6 +74,10 @@ void do_cmd_go_up(void)
        /* 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))
@@ -63,6 +95,11 @@ void do_cmd_go_up(void)
                /* 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;
                }
 
@@ -77,6 +114,9 @@ void do_cmd_go_up(void)
 
                p_ptr->oldpx = 0;
                p_ptr->oldpy = 0;
+               
+               /* Hack -- take a turn */
+               energy_use = 100;
 
                /* End the command */
                return;
@@ -88,26 +128,7 @@ void do_cmd_go_up(void)
        }
        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 */
@@ -228,6 +249,9 @@ void do_cmd_go_down(void)
        /* 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("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª");
@@ -237,14 +261,19 @@ void do_cmd_go_down(void)
                        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;
                }
 
@@ -259,6 +288,10 @@ void do_cmd_go_down(void)
 
                p_ptr->oldpx = 0;
                p_ptr->oldpy = 0;
+               
+               
+        /* Hack -- take a turn */
+        energy_use = 100;
        }
 
        else
@@ -415,7 +448,7 @@ void do_cmd_search(void)
 /*
  * 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];
 
@@ -436,8 +469,13 @@ static s16b chest_check(int y, int 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 */
@@ -1009,7 +1047,7 @@ static int count_chests(int *y, int *x, bool trapped)
                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];
@@ -1238,7 +1276,7 @@ void do_cmd_open(void)
                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)
@@ -2175,7 +2213,7 @@ void do_cmd_disarm(void)
                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)
@@ -3371,7 +3409,7 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
 {
        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;
 
@@ -3414,7 +3452,7 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
        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);
@@ -3432,11 +3470,8 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
        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;
@@ -3706,6 +3741,10 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
                        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)
@@ -4090,7 +4129,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken)
        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;
@@ -4118,7 +4157,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken)
                set_action(ACTION_NONE);
        }
 
-       if (shuriken)
+       if (shuriken >= 0)
        {
                item = shuriken;
        }
@@ -4211,6 +4250,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int 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);
@@ -4237,7 +4277,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken)
        /* 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;
@@ -4425,7 +4465,10 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken)
                                }
 
                                /* 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);
@@ -4515,6 +4558,9 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken)
                }
        }
 
+       /* 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);
 
@@ -4721,7 +4767,7 @@ msg_print("
  */
 void do_cmd_throw(void)
 {
-       do_cmd_throw_aux(1, FALSE, 0);
+       do_cmd_throw_aux(1, FALSE, -1);
 }
 
 
@@ -4747,24 +4793,63 @@ void forget_travel_flow(void)
                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) ||
@@ -4772,16 +4857,21 @@ static bool travel_flow_aux(int y, int x, int n, bool 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;
@@ -4793,7 +4883,7 @@ static bool travel_flow_aux(int y, int x, int n, bool wall)
        /* Hack -- notice overflow by forgetting new entry */
        if (flow_head == flow_tail) flow_head = old_head;
 
-       return wall;
+       return;
 }
 
 
@@ -4801,15 +4891,16 @@ static void travel_flow(int ty, int tx)
 {
        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)
@@ -4821,11 +4912,14 @@ static void travel_flow(int ty, int tx)
                /* 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);
                }
        }
 
@@ -4839,7 +4933,13 @@ void do_cmd_travel(void)
        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))
        {
@@ -4866,12 +4966,12 @@ void do_cmd_travel(void)
                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;