#include "monster-floor/monster-summon.h"
+#include "dungeon/dungeon-flag-types.h"
#include "dungeon/dungeon.h"
+#include "floor/wild.h"
#include "main/sound-definitions-table.h"
#include "main/sound-of-music.h"
#include "monster-floor/monster-generator.h"
#include "monster/monster-list.h"
#include "monster/monster-util.h"
#include "mspell/summon-checker.h"
-#include "spell/spells-summon.h"
+#include "spell/summon-types.h"
#include "system/floor-type-definition.h"
#include "system/monster-type-definition.h"
static bool summon_specific_okay(player_type *player_ptr, MONRACE_IDX r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
- monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[summon_specific_who];
if (!mon_hook_dungeon(player_ptr, r_idx))
return FALSE;
if (summon_specific_who > 0) {
+ monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[summon_specific_who];
if (monster_has_hostile_align(player_ptr, m_ptr, 0, 0, r_ptr))
return FALSE;
} else if (summon_specific_who < 0) {
- if (monster_has_hostile_align(player_ptr, NULL, 10, -10, r_ptr)) {
- if (!one_in_(ABS(player_ptr->align) / 2 + 1))
- return FALSE;
- }
+ if (monster_has_hostile_align(player_ptr, NULL, 10, -10, r_ptr) && !one_in_(ABS(player_ptr->align) / 2 + 1))
+ return FALSE;
}
if (!summon_unique_okay && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)))
if (!summon_specific_type)
return TRUE;
- if ((summon_specific_who < 0) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) && monster_has_hostile_align(player_ptr, NULL, 10, -10, r_ptr))
+ if ((summon_specific_who < 0) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL))
+ && monster_has_hostile_align(player_ptr, NULL, 10, -10, r_ptr))
return FALSE;
if ((r_ptr->flags7 & RF7_CHAMELEON) && (d_info[player_ptr->dungeon_idx].flags1 & DF1_CHAMELEON))
return TRUE;
- return (check_summon_specific(player_ptr, m_ptr->r_idx, r_idx));
+ if (summon_specific_who > 0) {
+ monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[summon_specific_who];
+ return check_summon_specific(player_ptr, m_ptr->r_idx, r_idx);
+ } else {
+ return check_summon_specific(player_ptr, 0, r_idx);
+ }
+}
+
+/*!
+ * @brief モンスター死亡時に召喚されうるモンスターかどうかの判定
+ * @param type モンスター種族ID
+ * @return 召喚されうるならばTRUE (あやしい影として生成されない)
+ */
+static bool is_dead_summoning(summon_type type)
+{
+ bool summoning = type == SUMMON_BLUE_HORROR;
+ summoning |= type == SUMMON_DAWN;
+ summoning |= type == SUMMON_TOTEM_MOAI;
+ return summoning;
+}
+
+/*!
+ * @brief 荒野のレベルを含めた階層レベルを返す
+ * @param player_ptr プレーヤーへの参照ポインタ
+ * @return 階層レベル
+ * @detail
+ * ダンジョン及びクエストはdun_level>0となる。
+ * 荒野はdun_level==0なので、その場合荒野レベルを返す。
+ */
+DEPTH get_dungeon_or_wilderness_level(player_type *player_ptr)
+{
+ floor_type *floor_ptr = player_ptr->current_floor_ptr;
+ if (floor_ptr->dun_level > 0)
+ return floor_ptr->dun_level;
+
+ return wilderness[player_ptr->wilderness_y][player_ptr->wilderness_x].level;
}
/*!
* @param mode 生成オプション
* @return 召喚できたらtrueを返す
*/
-bool summon_specific(player_type *player_ptr, MONSTER_IDX who, POSITION y1, POSITION x1, DEPTH lev, int type, BIT_FLAGS mode)
+bool summon_specific(player_type *player_ptr, MONSTER_IDX who, POSITION y1, POSITION x1, DEPTH lev, summon_type type, BIT_FLAGS mode)
{
floor_type *floor_ptr = player_ptr->current_floor_ptr;
if (floor_ptr->inside_arena)
summon_specific_who = who;
summon_specific_type = type;
- summon_unique_okay = (mode & PM_ALLOW_UNIQUE) ? TRUE : FALSE;
+ summon_unique_okay = (mode & PM_ALLOW_UNIQUE) != 0;
get_mon_num_prep(player_ptr, summon_specific_okay, get_monster_hook2(player_ptr, y, x));
- MONRACE_IDX r_idx = get_mon_num(player_ptr, (floor_ptr->dun_level + lev) / 2 + 5, 0);
+ DEPTH dlev = get_dungeon_or_wilderness_level(player_ptr);
+ MONRACE_IDX r_idx = get_mon_num(player_ptr, 0, (dlev + lev) / 2 + 5, 0);
if (!r_idx) {
summon_specific_type = 0;
return FALSE;
}
- if ((type == SUMMON_BLUE_HORROR) || (type == SUMMON_DAWN))
+ if (is_dead_summoning(type))
mode |= PM_NO_KAGE;
if (!place_monster_aux(player_ptr, who, y, x, r_idx, mode)) {
return FALSE;
POSITION x, y;
- if (player_ptr->current_floor_ptr->inside_arena)
- return FALSE;
-
- if (!mon_scatter(player_ptr, r_idx, &y, &x, oy, ox, 2))
+ if (player_ptr->current_floor_ptr->inside_arena || !mon_scatter(player_ptr, r_idx, &y, &x, oy, ox, 2))
return FALSE;
return place_monster_aux(player_ptr, who, y, x, r_idx, (mode | PM_NO_KAGE));