OSDN Git Service

[Fix] #40514 effect_player_lite() と effect_player_dark() 内の盲目判定バグ修正. / Fixed blind...
[hengband/hengband.git] / src / specific-object / monster-ball.c
1 #include "specific-object/monster-ball.h"
2 #include "effect/spells-effect-util.h"
3 #include "floor/geometry.h"
4 #include "game-option/input-options.h"
5 #include "monster-floor/monster-generator.h"
6 #include "monster-floor/place-monster-types.h"
7 #include "monster-race/monster-race.h"
8 #include "monster/monster-info.h"
9 #include "monster/monster-util.h"
10 #include "object-activation/activation-util.h"
11 #include "racial/racial-android.h"
12 #include "spell-kind/spells-launcher.h"
13 #include "spell/spell-types.h"
14 #include "system/floor-type-definition.h"
15 #include "system/monster-type-definition.h"
16 #include "system/object-type-definition.h"
17 #include "target/target-getter.h"
18 #include "util/quarks.h"
19 #include "view/display-messages.h"
20
21 static void inscribe_nickname(ae_type *ae_ptr)
22 {
23     if (!cap_nickname)
24         return;
25
26     concptr t;
27     char *s;
28     char buf[80] = "";
29     if (ae_ptr->o_ptr->inscription)
30         strcpy(buf, quark_str(ae_ptr->o_ptr->inscription));
31
32     s = buf;
33     for (s = buf; *s && (*s != '#'); s++) {
34 #ifdef JP
35         if (iskanji(*s))
36             s++;
37 #endif
38     }
39
40     *s = '#';
41     s++;
42 #ifdef JP
43 #else
44     *s++ = '\'';
45 #endif
46     t = quark_str(cap_nickname);
47     while (*t) {
48         *s = *t;
49         s++;
50         t++;
51     }
52 #ifdef JP
53 #else
54     *s++ = '\'';
55 #endif
56     *s = '\0';
57     ae_ptr->o_ptr->inscription = quark_add(buf);
58 }
59
60 static bool set_activation_target(player_type *user_ptr, ae_type *ae_ptr)
61 {
62     bool old_target_pet = target_pet;
63     target_pet = TRUE;
64     if (!get_aim_dir(user_ptr, &ae_ptr->dir)) {
65         target_pet = old_target_pet;
66         return FALSE;
67     }
68
69     target_pet = old_target_pet;
70     if (!fire_ball(user_ptr, GF_CAPTURE, ae_ptr->dir, 0, 0))
71         return TRUE;
72
73     ae_ptr->o_ptr->pval = (PARAMETER_VALUE)cap_mon;
74     ae_ptr->o_ptr->xtra3 = (XTRA8)cap_mspeed;
75     ae_ptr->o_ptr->xtra4 = (XTRA16)cap_hp;
76     ae_ptr->o_ptr->xtra5 = (XTRA16)cap_maxhp;
77     inscribe_nickname(ae_ptr);
78     return TRUE;
79 }
80
81 static void add_quark_to_inscription(player_type *user_ptr, ae_type *ae_ptr, concptr t, char *buf)
82 {
83     if (!*t)
84         return;
85
86     char *s = buf;
87     t++;
88 #ifdef JP
89 #else
90     bool quote = FALSE;
91     if (*t == '\'') {
92         t++;
93         quote = TRUE;
94     }
95 #endif
96
97     while (*t) {
98         *s = *t;
99         t++;
100         s++;
101     }
102
103 #ifdef JP
104 #else
105     if (quote && *(s - 1) == '\'')
106         s--;
107 #endif
108
109     *s = '\0';
110     user_ptr->current_floor_ptr->m_list[hack_m_idx_ii].nickname = quark_add(buf);
111     t = quark_str(ae_ptr->o_ptr->inscription);
112     s = buf;
113     while (*t && (*t != '#')) {
114         *s = *t;
115         t++;
116         s++;
117     }
118
119     *s = '\0';
120     ae_ptr->o_ptr->inscription = quark_add(buf);
121 }
122
123 static void check_inscription_value(player_type *user_ptr, ae_type *ae_ptr)
124 {
125     if (ae_ptr->o_ptr->inscription == 0)
126         return;
127
128     char buf[80];
129     concptr t = quark_str(ae_ptr->o_ptr->inscription);
130     for (t = quark_str(ae_ptr->o_ptr->inscription); *t && (*t != '#'); t++) {
131 #ifdef JP
132         if (iskanji(*t))
133             t++;
134 #endif
135     }
136
137     add_quark_to_inscription(user_ptr, ae_ptr, t, buf);
138 }
139
140 static void check_monster_ball_use(player_type *user_ptr, ae_type *ae_ptr)
141 {
142     if (!monster_can_enter(user_ptr, user_ptr->y + ddy[ae_ptr->dir], user_ptr->x + ddx[ae_ptr->dir], &r_info[ae_ptr->o_ptr->pval], 0))
143         return;
144
145     if (!place_monster_aux(user_ptr, 0, user_ptr->y + ddy[ae_ptr->dir], user_ptr->x + ddx[ae_ptr->dir], ae_ptr->o_ptr->pval, PM_FORCE_PET | PM_NO_KAGE))
146         return;
147
148     floor_type *floor_ptr = user_ptr->current_floor_ptr;
149     if (ae_ptr->o_ptr->xtra3)
150         floor_ptr->m_list[hack_m_idx_ii].mspeed = ae_ptr->o_ptr->xtra3;
151
152     if (ae_ptr->o_ptr->xtra5)
153         floor_ptr->m_list[hack_m_idx_ii].max_maxhp = ae_ptr->o_ptr->xtra5;
154
155     if (ae_ptr->o_ptr->xtra4)
156         floor_ptr->m_list[hack_m_idx_ii].hp = ae_ptr->o_ptr->xtra4;
157
158     floor_ptr->m_list[hack_m_idx_ii].maxhp = floor_ptr->m_list[hack_m_idx_ii].max_maxhp;
159     check_inscription_value(user_ptr, ae_ptr);
160     ae_ptr->o_ptr->pval = 0;
161     ae_ptr->o_ptr->xtra3 = 0;
162     ae_ptr->o_ptr->xtra4 = 0;
163     ae_ptr->o_ptr->xtra5 = 0;
164     ae_ptr->success = TRUE;
165 }
166
167 bool exe_monster_capture(player_type *user_ptr, ae_type *ae_ptr)
168 {
169     if (ae_ptr->o_ptr->tval != TV_CAPTURE)
170         return FALSE;
171
172     if (ae_ptr->o_ptr->pval == 0) {
173         if (!set_activation_target(user_ptr, ae_ptr))
174             return TRUE;
175
176         calc_android_exp(user_ptr);
177         return TRUE;
178     }
179
180     ae_ptr->success = FALSE;
181     if (!get_direction(user_ptr, &ae_ptr->dir, FALSE, FALSE))
182         return TRUE;
183
184     check_monster_ball_use(user_ptr, ae_ptr);
185     if (!ae_ptr->success)
186         msg_print(_("\82¨\82Á\82Æ\81A\89ð\95ú\82É\8e¸\94s\82µ\82½\81B", "Oops.  You failed to release your pet."));
187
188     calc_android_exp(user_ptr);
189     return TRUE;
190 }