OSDN Git Service

[fix] #41503 超能力者でゲームを開始しようとするとクラッシュ
[hengband/hengband.git] / src / mind / mind-mirror-master.c
1 #include "mind/mind-mirror-master.h"
2 #include "cmd-action/cmd-pet.h"
3 #include "core/disturbance.h"
4 #include "core/player-redraw-types.h"
5 #include "core/player-update-types.h"
6 #include "core/stuff-handler.h"
7 #include "effect/effect-characteristics.h"
8 #include "effect/effect-feature.h"
9 #include "effect/effect-item.h"
10 #include "effect/effect-monster.h"
11 #include "effect/effect-processor.h"
12 #include "effect/spells-effect-util.h"
13 #include "floor/cave.h"
14 #include "game-option/disturbance-options.h"
15 #include "game-option/special-options.h"
16 #include "grid/feature.h"
17 #include "io/cursor.h"
18 #include "io/screen-util.h"
19 #include "mind/mind-magic-resistance.h"
20 #include "mind/mind-numbers.h"
21 #include "spell-kind/spells-detection.h"
22 #include "spell-kind/spells-floor.h"
23 #include "spell-kind/spells-launcher.h"
24 #include "spell-kind/spells-lite.h"
25 #include "spell-kind/spells-sight.h"
26 #include "spell-kind/spells-teleport.h"
27 #include "spell-kind/spells-world.h"
28 #include "spell/spell-types.h"
29 #include "status/body-improvement.h"
30 #include "status/buff-setter.h"
31 #include "status/sight-setter.h"
32 #include "system/floor-type-definition.h"
33 #include "target/grid-selector.h"
34 #include "target/projection-path-calculator.h"
35 #include "target/target-getter.h"
36 #include "term/gameterm.h"
37 #include "util/bit-flags-calculator.h"
38 #include "view/display-messages.h"
39 #include "world/world.h"
40
41 /*
42  * @brief Multishadow effects is determined by turn
43  */
44 bool check_multishadow(player_type *creature_ptr) { return (creature_ptr->multishadow != 0) && ((current_world_ptr->game_turn & 1) != 0); }
45
46 /*!
47  * 静水
48  * @param creature_ptr プレーヤーへの参照ポインタ
49  * @return ペットを操っている場合を除きTRUE
50  */
51 bool mirror_concentration(player_type *creature_ptr)
52 {
53     if (total_friends) {
54         msg_print(_("今はペットを操ることに集中していないと。", "Your pets demand all of your attention."));
55         return FALSE;
56     }
57
58     if (!is_mirror_grid(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])) {
59         msg_print(_("鏡の上でないと集中できない!", "There's no mirror here!"));
60         return TRUE;
61     }
62
63     msg_print(_("少し頭がハッキリした。", "You feel your head clear a little."));
64
65     creature_ptr->csp += (5 + creature_ptr->lev * creature_ptr->lev / 100);
66     if (creature_ptr->csp >= creature_ptr->msp) {
67         creature_ptr->csp = creature_ptr->msp;
68         creature_ptr->csp_frac = 0;
69     }
70
71     creature_ptr->redraw |= PR_MANA;
72     return TRUE;
73 }
74
75 /*!
76  * @brief 全鏡の消去 / Remove all mirrors in this floor
77  * @param caster_ptr プレーヤーへの参照ポインタ
78  * @param explode 爆発処理を伴うならばTRUE
79  * @return なし
80  */
81 void remove_all_mirrors(player_type *caster_ptr, bool explode)
82 {
83     for (POSITION x = 0; x < caster_ptr->current_floor_ptr->width; x++) {
84         for (POSITION y = 0; y < caster_ptr->current_floor_ptr->height; y++) {
85             if (!is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]))
86                 continue;
87
88             remove_mirror(caster_ptr, y, x);
89             if (!explode)
90                 continue;
91
92             project(caster_ptr, 0, 2, y, x, caster_ptr->lev / 2 + 5, GF_SHARDS,
93                 (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
94         }
95     }
96 }
97
98 /*!
99  * @brief 鏡魔法「封魔結界」の効果処理
100  * @param dam ダメージ量
101  * @return 効果があったらTRUEを返す
102  */
103 bool binding_field(player_type *caster_ptr, HIT_POINT dam)
104 {
105     POSITION mirror_x[10], mirror_y[10]; /* 鏡はもっと少ない */
106     int mirror_num = 0; /* 鏡の数 */
107     int msec = delay_factor * delay_factor * delay_factor;
108
109     /* 三角形の頂点 */
110     POSITION point_x[3];
111     POSITION point_y[3];
112
113     /* Default target of monsterspell is player */
114     monster_target_y = caster_ptr->y;
115     monster_target_x = caster_ptr->x;
116
117     for (POSITION x = 0; x < caster_ptr->current_floor_ptr->width; x++) {
118         for (POSITION y = 0; y < caster_ptr->current_floor_ptr->height; y++) {
119             if (is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]) && distance(caster_ptr->y, caster_ptr->x, y, x) <= get_max_range(caster_ptr)
120                 && distance(caster_ptr->y, caster_ptr->x, y, x) != 0 && player_has_los_bold(caster_ptr, y, x)
121                 && projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y, x)) {
122                 mirror_y[mirror_num] = y;
123                 mirror_x[mirror_num] = x;
124                 mirror_num++;
125             }
126         }
127     }
128
129     if (mirror_num < 2)
130         return FALSE;
131
132     point_x[0] = randint0(mirror_num);
133     do {
134         point_x[1] = randint0(mirror_num);
135     } while (point_x[0] == point_x[1]);
136
137     point_y[0] = mirror_y[point_x[0]];
138     point_x[0] = mirror_x[point_x[0]];
139     point_y[1] = mirror_y[point_x[1]];
140     point_x[1] = mirror_x[point_x[1]];
141     point_y[2] = caster_ptr->y;
142     point_x[2] = caster_ptr->x;
143
144     POSITION x = point_x[0] + point_x[1] + point_x[2];
145     POSITION y = point_y[0] + point_y[1] + point_y[2];
146
147     POSITION centersign = (point_x[0] * 3 - x) * (point_y[1] * 3 - y) - (point_y[0] * 3 - y) * (point_x[1] * 3 - x);
148     if (centersign == 0)
149         return FALSE;
150
151     POSITION x1 = point_x[0] < point_x[1] ? point_x[0] : point_x[1];
152     x1 = x1 < point_x[2] ? x1 : point_x[2];
153     POSITION y1 = point_y[0] < point_y[1] ? point_y[0] : point_y[1];
154     y1 = y1 < point_y[2] ? y1 : point_y[2];
155
156     POSITION x2 = point_x[0] > point_x[1] ? point_x[0] : point_x[1];
157     x2 = x2 > point_x[2] ? x2 : point_x[2];
158     POSITION y2 = point_y[0] > point_y[1] ? point_y[0] : point_y[1];
159     y2 = y2 > point_y[2] ? y2 : point_y[2];
160
161     for (y = y1; y <= y2; y++) {
162         for (x = x1; x <= x2; x++) {
163             if (centersign * ((point_x[0] - x) * (point_y[1] - y) - (point_y[0] - y) * (point_x[1] - x)) >= 0
164                 && centersign * ((point_x[1] - x) * (point_y[2] - y) - (point_y[1] - y) * (point_x[2] - x)) >= 0
165                 && centersign * ((point_x[2] - x) * (point_y[0] - y) - (point_y[2] - y) * (point_x[0] - x)) >= 0) {
166                 if (player_has_los_bold(caster_ptr, y, x) && projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y, x)) {
167                     if (!(caster_ptr->blind) && panel_contains(y, x)) {
168                         u16b p = bolt_pict(y, x, y, x, GF_MANA);
169                         print_rel(caster_ptr, PICT_C(p), PICT_A(p), y, x);
170                         move_cursor_relative(y, x);
171                         if (need_term_fresh(caster_ptr)) {
172                             term_fresh();
173                             term_xtra(TERM_XTRA_DELAY, msec);
174                         }
175                     }
176                 }
177             }
178         }
179     }
180
181     for (y = y1; y <= y2; y++) {
182         for (x = x1; x <= x2; x++) {
183             if (centersign * ((point_x[0] - x) * (point_y[1] - y) - (point_y[0] - y) * (point_x[1] - x)) >= 0
184                 && centersign * ((point_x[1] - x) * (point_y[2] - y) - (point_y[1] - y) * (point_x[2] - x)) >= 0
185                 && centersign * ((point_x[2] - x) * (point_y[0] - y) - (point_y[2] - y) * (point_x[0] - x)) >= 0) {
186                 if (player_has_los_bold(caster_ptr, y, x) && projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y, x)) {
187                     (void)affect_feature(caster_ptr, 0, 0, y, x, dam, GF_MANA);
188                 }
189             }
190         }
191     }
192
193     for (y = y1; y <= y2; y++) {
194         for (x = x1; x <= x2; x++) {
195             if (centersign * ((point_x[0] - x) * (point_y[1] - y) - (point_y[0] - y) * (point_x[1] - x)) >= 0
196                 && centersign * ((point_x[1] - x) * (point_y[2] - y) - (point_y[1] - y) * (point_x[2] - x)) >= 0
197                 && centersign * ((point_x[2] - x) * (point_y[0] - y) - (point_y[2] - y) * (point_x[0] - x)) >= 0) {
198                 if (player_has_los_bold(caster_ptr, y, x) && projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y, x)) {
199                     (void)affect_item(caster_ptr, 0, 0, y, x, dam, GF_MANA);
200                 }
201             }
202         }
203     }
204
205     for (y = y1; y <= y2; y++) {
206         for (x = x1; x <= x2; x++) {
207             if (centersign * ((point_x[0] - x) * (point_y[1] - y) - (point_y[0] - y) * (point_x[1] - x)) >= 0
208                 && centersign * ((point_x[1] - x) * (point_y[2] - y) - (point_y[1] - y) * (point_x[2] - x)) >= 0
209                 && centersign * ((point_x[2] - x) * (point_y[0] - y) - (point_y[2] - y) * (point_x[0] - x)) >= 0) {
210                 if (player_has_los_bold(caster_ptr, y, x) && projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y, x)) {
211                     (void)affect_monster(caster_ptr, 0, 0, y, x, dam, GF_MANA, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP), TRUE);
212                 }
213             }
214         }
215     }
216
217     if (one_in_(7)) {
218         msg_print(_("鏡が結界に耐えきれず、壊れてしまった。", "The field broke a mirror"));
219         remove_mirror(caster_ptr, point_y[0], point_x[0]);
220     }
221
222     return TRUE;
223 }
224
225 /*!
226  * @brief 鏡魔法「鏡の封印」の効果処理
227  * @param dam ダメージ量
228  * @return 効果があったらTRUEを返す
229  */
230 void seal_of_mirror(player_type *caster_ptr, HIT_POINT dam)
231 {
232     for (POSITION x = 0; x < caster_ptr->current_floor_ptr->width; x++) {
233         for (POSITION y = 0; y < caster_ptr->current_floor_ptr->height; y++) {
234             if (!is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]))
235                 continue;
236
237             if (!affect_monster(caster_ptr, 0, 0, y, x, dam, GF_GENOCIDE, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP), TRUE))
238                 continue;
239
240             if (!caster_ptr->current_floor_ptr->grid_array[y][x].m_idx) {
241                 remove_mirror(caster_ptr, y, x);
242             }
243         }
244     }
245 }
246
247 /*!
248  * 幻惑の光 @ 鏡使いだけでなく混沌の戦士も使える
249  * @param creature_ptr プレーヤーへの参照ポインタ
250  * @return 常にTRUE
251  */
252 bool confusing_light(player_type *creature_ptr)
253 {
254     msg_print(_("辺りを睨んだ...", "You glare at nearby monsters..."));
255     slow_monsters(creature_ptr, creature_ptr->lev);
256     stun_monsters(creature_ptr, creature_ptr->lev * 4);
257     confuse_monsters(creature_ptr, creature_ptr->lev * 4);
258     turn_monsters(creature_ptr, creature_ptr->lev * 4);
259     stasis_monsters(creature_ptr, creature_ptr->lev * 4);
260     return TRUE;
261 }
262
263 /*!
264  * @brief 鏡設置処理
265  * @return 実際に設置が行われた場合TRUEを返す
266  */
267 bool place_mirror(player_type *caster_ptr)
268 {
269     if (!cave_clean_bold(caster_ptr->current_floor_ptr, caster_ptr->y, caster_ptr->x)) {
270         msg_print(_("床上のアイテムが呪文を跳ね返した。", "The object resists the spell."));
271         return FALSE;
272     }
273
274     /* Create a mirror */
275     caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].info |= CAVE_OBJECT;
276     caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].mimic = feat_mirror;
277
278     /* Turn on the light */
279     caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].info |= CAVE_GLOW;
280
281     note_spot(caster_ptr, caster_ptr->y, caster_ptr->x);
282     lite_spot(caster_ptr, caster_ptr->y, caster_ptr->x);
283     update_local_illumination(caster_ptr, caster_ptr->y, caster_ptr->x);
284
285     return TRUE;
286 }
287
288 /*!
289  * @brief 鏡抜け処理のメインルーチン /
290  * Mirror Master's Dimension Door
291  * @param caster_ptr プレーヤーへの参照ポインタ
292  * @return ターンを消費した場合TRUEを返す
293  */
294 bool mirror_tunnel(player_type *caster_ptr)
295 {
296     POSITION x = 0, y = 0;
297     if (!tgt_pt(caster_ptr, &x, &y))
298         return FALSE;
299     if (exe_dimension_door(caster_ptr, x, y))
300         return TRUE;
301
302     msg_print(_("鏡の世界をうまく通れなかった!", "You could not enter the mirror!"));
303     return TRUE;
304 }
305
306 /*
307  * Set "multishadow", notice observable changes
308  */
309 bool set_multishadow(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
310 {
311     bool notice = FALSE;
312     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
313
314     if (creature_ptr->is_dead)
315         return FALSE;
316
317     if (v) {
318         if (creature_ptr->multishadow && !do_dec) {
319             if (creature_ptr->multishadow > v)
320                 return FALSE;
321         } else if (!creature_ptr->multishadow) {
322             msg_print(_("あなたの周りに幻影が生まれた。", "Your Shadow enveloped you."));
323             notice = TRUE;
324         }
325     } else {
326         if (creature_ptr->multishadow) {
327             msg_print(_("幻影が消えた。", "Your Shadow disappears."));
328             notice = TRUE;
329         }
330     }
331
332     creature_ptr->multishadow = v;
333     creature_ptr->redraw |= (PR_STATUS);
334
335     if (!notice)
336         return FALSE;
337
338     if (disturb_state)
339         disturb(creature_ptr, FALSE, FALSE);
340     creature_ptr->update |= (PU_BONUS);
341     handle_stuff(creature_ptr);
342     return TRUE;
343 }
344
345 /*!
346  * @brief 一時的破片のオーラの継続時間をセットする / Set "dustrobe", notice observable changes
347  * @param v 継続時間
348  * @param do_dec 現在の継続時間より長い値のみ上書きする
349  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
350  */
351 bool set_dustrobe(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
352 {
353     bool notice = FALSE;
354     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
355
356     if (creature_ptr->is_dead)
357         return FALSE;
358
359     if (v) {
360         if (creature_ptr->dustrobe && !do_dec) {
361             if (creature_ptr->dustrobe > v)
362                 return FALSE;
363         } else if (!creature_ptr->dustrobe) {
364             msg_print(_("体が鏡のオーラで覆われた。", "You are enveloped by mirror shards."));
365             notice = TRUE;
366         }
367     } else {
368         if (creature_ptr->dustrobe) {
369             msg_print(_("鏡のオーラが消えた。", "The mirror shards disappear."));
370             notice = TRUE;
371         }
372     }
373
374     creature_ptr->dustrobe = v;
375     creature_ptr->redraw |= (PR_STATUS);
376
377     if (!notice)
378         return FALSE;
379
380     if (disturb_state)
381         disturb(creature_ptr, FALSE, FALSE);
382     creature_ptr->update |= (PU_BONUS);
383     handle_stuff(creature_ptr);
384     return TRUE;
385 }
386
387 /*!
388  * @brief 現在フロアに存在している鏡の数を数える / calculate mirrors
389  * @return 鏡の枚数
390  */
391 static int number_of_mirrors(floor_type *floor_ptr)
392 {
393     int val = 0;
394     for (POSITION x = 0; x < floor_ptr->width; x++) {
395         for (POSITION y = 0; y < floor_ptr->height; y++) {
396             if (is_mirror_grid(&floor_ptr->grid_array[y][x]))
397                 val++;
398         }
399     }
400
401     return val;
402 }
403
404 /*!
405  * @brief 鏡魔法の発動 /
406  * do_cmd_cast calls this function if the player's class is 'Mirror magic'.
407  * @param spell 発動する特殊技能のID
408  * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。
409  */
410 bool cast_mirror_spell(player_type *caster_ptr, mind_mirror_master_type spell)
411 {
412     DIRECTION dir;
413     PLAYER_LEVEL plev = caster_ptr->lev;
414     int tmp;
415     TIME_EFFECT t;
416     POSITION x, y;
417     switch (spell) {
418     case MIRROR_SEEING:
419         tmp = is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x]) ? 4 : 0;
420         if (plev + tmp > 4)
421             detect_monsters_normal(caster_ptr, DETECT_RAD_DEFAULT);
422         if (plev + tmp > 18)
423             detect_monsters_invis(caster_ptr, DETECT_RAD_DEFAULT);
424         if (plev + tmp > 28)
425             set_tim_esp(caster_ptr, (TIME_EFFECT)plev, FALSE);
426         if (plev + tmp > 38)
427             map_area(caster_ptr, DETECT_RAD_MAP);
428         if (tmp == 0 && plev < 5) {
429             msg_print(_("鏡がなくて集中できなかった!", "You need a mirror to concentrate!"));
430         }
431         break;
432     case MAKE_MIRROR:
433         if (number_of_mirrors(caster_ptr->current_floor_ptr) < 4 + plev / 10)
434             place_mirror(caster_ptr);
435         else
436             msg_format(_("これ以上鏡は制御できない!", "There are too many mirrors to control!"));
437
438         break;
439     case DRIP_LIGHT:
440         if (!get_aim_dir(caster_ptr, &dir))
441             return FALSE;
442
443         if (plev > 9 && is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x]))
444             fire_beam(caster_ptr, GF_LITE, dir, damroll(3 + ((plev - 1) / 5), 4));
445         else
446             fire_bolt(caster_ptr, GF_LITE, dir, damroll(3 + ((plev - 1) / 5), 4));
447
448         break;
449     case WRAPPED_MIRROR:
450         teleport_player(caster_ptr, 10, TELEPORT_SPONTANEOUS);
451         break;
452     case MIRROR_LIGHT:
453         (void)lite_area(caster_ptr, damroll(2, (plev / 2)), (plev / 10) + 1);
454         break;
455     case WANDERING_MIRROR:
456         teleport_player(caster_ptr, plev * 5, TELEPORT_SPONTANEOUS);
457         break;
458     case ROBE_DUST:
459         set_dustrobe(caster_ptr, 20 + randint1(20), FALSE);
460         break;
461     case BANISHING_MIRROR:
462         if (!get_aim_dir(caster_ptr, &dir))
463             return FALSE;
464
465         (void)fire_beam(caster_ptr, GF_AWAY_ALL, dir, plev);
466         break;
467     case MIRROR_CRASHING:
468         if (!get_aim_dir(caster_ptr, &dir))
469             return FALSE;
470
471         fire_ball(caster_ptr, GF_SHARDS, dir, damroll(8 + ((plev - 5) / 4), 8), (plev > 20 ? (plev - 20) / 8 + 1 : 0));
472         break;
473     case SLEEPING_MIRROR:
474         for (x = 0; x < caster_ptr->current_floor_ptr->width; x++)
475             for (y = 0; y < caster_ptr->current_floor_ptr->height; y++)
476                 if (is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]))
477                     project(caster_ptr, 0, 2, y, x, (HIT_POINT)plev, GF_OLD_SLEEP,
478                         (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
479
480         break;
481     case SEEKER_RAY:
482         if (!get_aim_dir(caster_ptr, &dir))
483             return FALSE;
484
485         fire_beam(caster_ptr, GF_SEEKER, dir, damroll(11 + (plev - 5) / 4, 8));
486         break;
487     case SEALING_MIRROR:
488         seal_of_mirror(caster_ptr, plev * 4 + 100);
489         break;
490     case WATER_SHIELD:
491         t = 20 + randint1(20);
492         set_shield(caster_ptr, t, FALSE);
493         if (plev > 31)
494             set_tim_reflect(caster_ptr, t, FALSE);
495
496         if (plev > 39)
497             set_resist_magic(caster_ptr, t, FALSE);
498
499         break;
500     case SUPER_RAY:
501         if (!get_aim_dir(caster_ptr, &dir))
502             return FALSE;
503
504         fire_beam(caster_ptr, GF_SUPER_RAY, dir, 150 + randint1(2 * plev));
505         break;
506     case ILLUSION_LIGHT:
507         tmp = is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x]) ? 4 : 3;
508         slow_monsters(caster_ptr, plev);
509         stun_monsters(caster_ptr, plev * tmp * 2);
510         confuse_monsters(caster_ptr, plev * tmp);
511         turn_monsters(caster_ptr, plev * tmp);
512         stasis_monsters(caster_ptr, plev * tmp);
513         break;
514     case MIRROR_SHIFT:
515         if (!is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x])) {
516             msg_print(_("鏡の国の場所がわからない!", "You cannot find out where the mirror is!"));
517             break;
518         }
519
520         reserve_alter_reality(caster_ptr, randint0(21) + 15);
521         break;
522     case MIRROR_TUNNEL:
523         msg_print(_("鏡の世界を通り抜け…  ", "You try to enter the mirror..."));
524         return mirror_tunnel(caster_ptr);
525     case RECALL_MIRROR:
526         return recall_player(caster_ptr, randint0(21) + 15);
527     case MULTI_SHADOW:
528         set_multishadow(caster_ptr, 6 + randint1(6), FALSE);
529         break;
530     case BINDING_FIELD:
531         if (!binding_field(caster_ptr, plev * 11 + 5))
532             msg_print(_("適当な鏡を選べなかった!", "You were not able to choose suitable mirrors!"));
533
534         break;
535     case RUFFNOR_MIRROR:
536         (void)set_invuln(caster_ptr, randint1(4) + 4, FALSE);
537         break;
538     default:
539         msg_print(_("なに?", "Zap?"));
540         break;
541     }
542
543     caster_ptr->magic_num1[0] = 0;
544     return TRUE;
545 }