S:HEAL | INVULNER | BLINK | TPORT | WORLD | TELE_TO | TELE_AWAY | TELE_LEVEL |
S:PSY_SPEAR | DARKNESS | TRAPS | FORGET | ANIM_DEAD | S_KIN | S_CYBER | S_MONSTER |
S:S_MONSTERS | S_ANT | S_SPIDER | S_HOUND | S_HYDRA | S_DEMON | S_UNDEAD |
-S:S_DRAGON | S_HI_UNDEAD | S_AMBERITES | S_UNIQUE | BA_LITE
+S:S_DRAGON | S_HI_UNDEAD | S_AMBERITES | S_UNIQUE | BA_LITE | S_DEAD_UNIQUE
V:133
D:$You don't know what it is.
D:それは何が何だか分からない。
V:150
D:$It's a abyssal whirlpool.
D:深淵の渦巻きだ。
+
+N:1353:破壊と憎悪の化身『サルーイン』
+E:Saruin, The avatar of destruction and hatred
+G:P:w
+I:135:90d100:100:175:0
+W:82:3:0:66666:0:0
+B:HIT:HURT:11d13
+B:HIT:HURT:11d13
+B:HIT:HURT:11d13
+B:HIT:HURT:11d13
+F:UNIQUE | MALE | DROP_CORPSE | NONLIVING |
+F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GREAT |
+F:PREVENT_SUDDEN_MAGIC | FORCE_MAXHP | SMART |
+F:OPEN_DOOR | BASH_DOOR |
+F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS |
+F:RES_WATE | RES_SHAR | RES_LITE | RES_DARK |
+F:NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | RES_TELE
+S:1_IN_3 | S_DEAD_UNIQUE |
+S:BA_FIRE | BA_WATE | BA_ACID | ROCKET | DISPEL | BLIND | BO_MANA |
+S:HOLD | HEAL | HASTE | CONF | BRAIN_SMASH
+D:$He was born from the heart of Sayva, the goddess of destruction.
+D:$ Apparently, some foolish adventurer had given away all the Destiny Stones.
+D:破壊の女神サイヴァの心臓から生まれた存在だ。
+D:どうやら愚かなる冒険者がすべてのデステニィストーンを捧げてしまったらしい。
#include "floor/floor-object.h"
#include "inventory/inventory-object.h"
#include "inventory/inventory-slot-types.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race-hook.h"
#include "monster/monster-list.h"
#include "monster/monster-util.h"
get_mon_num_prep(player_ptr, monster_hook_human, nullptr);
for (int i = rand_range(3, 4); i > 0; i--) {
q_ptr->prep(lookup_baseitem_id({ ItemKindType::CORPSE, SV_CORPSE }));
- q_ptr->pval = enum2i(get_mon_num(player_ptr, 0, 2, 0));
+ q_ptr->pval = enum2i(get_mon_num(player_ptr, 0, 2, PM_NONE));
if (q_ptr->pval) {
q_ptr->number = 1;
add_outfit(player_ptr, q_ptr);
return cast_blue_summon_amberite(player_ptr, bmc_ptr);
case MonsterAbilityType::S_UNIQUE:
return cast_blue_summon_unique(player_ptr, bmc_ptr);
+ case MonsterAbilityType::S_DEAD_UNIQUE:
+ return cast_blue_summon_dead_unique(player_ptr, bmc_ptr);
default:
msg_print("hoge?");
return true;
return true;
}
+
+bool cast_blue_summon_dead_unique(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+ int count = 0;
+ msg_print(_("特別な強敵を蘇らせた!", "You summon a special dead opponent!"));
+ for (int k = 0; k < 1; k++) {
+ if (summon_specific(player_ptr, (bmc_ptr->pet ? -1 : 0), player_ptr->y, player_ptr->x, bmc_ptr->summon_lev, SUMMON_DEAD_UNIQUE,
+ (bmc_ptr->g_mode | bmc_ptr->p_mode | PM_ALLOW_UNIQUE | PM_CLONE))) {
+ count++;
+ if (!bmc_ptr->pet) {
+ msg_print(_("蘇生されたユニーク・モンスターは怒っている!", "The summoned special dead opponent is angry!"));
+ }
+ }
+ }
+
+ if (!count) {
+ bmc_ptr->no_trump = true;
+ }
+
+ return true;
+}
bool cast_blue_summon_high_dragon(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_summon_amberite(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_summon_unique(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_summon_dead_unique(PlayerType *player_ptr, bmc_type *bmc_ptr);
}
break;
}
+ case MonsterAbilityType::S_DEAD_UNIQUE: {
+ int k, count = 0;
+ if (!target_set(player_ptr, TARGET_KILL)) {
+ return false;
+ }
+ msg_print(_("特別な強敵を蘇生した!", "You summon special dead opponents!"));
+ for (k = 0; k < 4; k++) {
+ if (summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_DEAD_UNIQUE, (mode | PM_ALLOW_UNIQUE | PM_CLONE))) {
+ count++;
+ }
+ }
+ break;
+ }
default:
msg_print("hoge?");
}
auto *floor_ptr = player_ptr->current_floor_ptr;
const auto wild_level = wilderness[player_ptr->wilderness_y][player_ptr->wilderness_x].level;
const auto level = floor_ptr->is_in_dungeon() ? floor_ptr->dun_level : wild_level;
- const auto r_idx = get_mon_num(player_ptr, 0, level, 0);
+ const auto r_idx = get_mon_num(player_ptr, 0, level, PM_NONE);
msg_print(nullptr);
if (MonsterRace(r_idx).is_valid() && one_in_(2)) {
POSITION y, x;
#include "locale/english.h"
#include "main/music-definitions-table.h"
#include "main/sound-of-music.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race-hook.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags1.h"
get_mon_num_prep(player_ptr, mon_hook_quest, nullptr);
MonsterRaceId r_idx;
while (true) {
- r_idx = get_mon_num(player_ptr, 0, q_ptr->level + 5 + randint1(q_ptr->level / 10), GMN_ARENA);
+ r_idx = get_mon_num(player_ptr, 0, q_ptr->level + 5 + randint1(q_ptr->level / 10), PM_ARENA);
const auto &monrace = monraces_info[r_idx];
if (monrace.kind_flags.has_not(MonsterKindType::UNIQUE)) {
continue;
{"S_HI_DRAGON", MonsterAbilityType::S_HI_DRAGON },
{"S_AMBERITES", MonsterAbilityType::S_AMBERITES },
{"S_UNIQUE", MonsterAbilityType::S_UNIQUE },
+ {"S_DEAD_UNIQUE", MonsterAbilityType::S_DEAD_UNIQUE },
};
/* clang-format on */
lore_ptr->vp[lore_ptr->vn] = _("ユニーク・モンスター召喚", "summon Unique Monsters");
lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
}
+
+ if (lore_ptr->ability_flags.has(MonsterAbilityType::S_DEAD_UNIQUE)) {
+ lore_ptr->vp[lore_ptr->vn] = _("ユニーク・モンスター口寄せ", "animate Unique Monsters");
+ lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
+ }
}
#include "market/arena-info-table.h"
#include "market/building-actions-table.h"
#include "market/building-util.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race-hook.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags-resistance.h"
int j;
while (true) {
get_mon_num_prep(player_ptr, monster_can_entry_arena, nullptr);
- r_idx = get_mon_num(player_ptr, 0, mon_level, GMN_ARENA);
+ r_idx = get_mon_num(player_ptr, 0, mon_level, PM_ARENA);
if (!MonsterRace(r_idx).is_valid()) {
continue;
}
#include "io/input-key-acceptor.h"
#include "market/bounty-prize-table.h"
#include "market/building-util.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race-hook.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags1.h"
get_mon_num_prep_bounty(player_ptr);
while (true) {
- w_ptr->today_mon = get_mon_num(player_ptr, std::min(max_dl / 2, 40), max_dl, GMN_ARENA);
+ w_ptr->today_mon = get_mon_num(player_ptr, std::min(max_dl / 2, 40), max_dl, PM_ARENA);
MonsterRaceInfo *r_ptr;
r_ptr = &monraces_info[w_ptr->today_mon];
// 賞金首とするモンスターの種族IDのリストを生成
std::vector<MonsterRaceId> bounty_r_idx_list;
while (bounty_r_idx_list.size() < std::size(w_ptr->bounties)) {
- auto r_idx = get_mon_num(player_ptr, 0, MAX_DEPTH - 1, GMN_ARENA);
+ auto r_idx = get_mon_num(player_ptr, 0, MAX_DEPTH - 1, PM_ARENA);
if (!is_suitable_for_bounty(r_idx)) {
continue;
}
drop_numbers += damroll(4, 2);
}
- if (md_ptr->cloned && md_ptr->r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
+ // クローンは、クローン地獄内のユニークモンスター以外はドロップしない
+ if (md_ptr->cloned && !(md_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE) && (player_ptr->current_floor_ptr->quest_number == QuestId::CLONE))) {
drop_numbers = 0;
}
get_mon_num_prep(player_ptr, get_monster_hook(player_ptr), get_monster_hook2(player_ptr, y, x));
MonsterRaceId r_idx;
do {
- r_idx = get_mon_num(player_ptr, 0, player_ptr->current_floor_ptr->monster_level, 0);
+ r_idx = get_mon_num(player_ptr, 0, player_ptr->current_floor_ptr->monster_level, PM_NONE);
} while ((mode & PM_NO_QUEST) && (monraces_info[r_idx].flags8 & RF8_NO_QUEST));
if (!MonsterRace(r_idx).is_valid()) {
const auto *floor_ptr = player_ptr->current_floor_ptr;
for (auto attempts = 1000; attempts > 0; --attempts) {
- auto r_idx = get_mon_num(player_ptr, 0, floor_ptr->monster_level, 0);
+ auto r_idx = get_mon_num(player_ptr, 0, floor_ptr->monster_level, PM_NONE);
if (!MonsterRace(r_idx).is_valid()) {
return std::nullopt;
}
get_mon_num_prep(player_ptr, summon_specific_okay, get_monster_hook2(player_ptr, y, x));
DEPTH dlev = get_dungeon_or_wilderness_level(player_ptr);
- MonsterRaceId r_idx = get_mon_num(player_ptr, 0, (dlev + lev) / 2 + 5, 0);
+ MonsterRaceId r_idx = get_mon_num(player_ptr, 0, (dlev + lev) / 2 + 5, mode);
if (!MonsterRace(r_idx).is_valid()) {
summon_specific_type = SUMMON_NONE;
return false;
int attempts = 1000;
DEPTH min = std::min(floor_ptr->base_level - 5, 50);
while (--attempts) {
- auto ap_r_idx = get_mon_num(player_ptr, 0, floor_ptr->base_level + 10, 0);
+ auto ap_r_idx = get_mon_num(player_ptr, 0, floor_ptr->base_level + 10, PM_NONE);
if (monraces_info[ap_r_idx].level >= min) {
return ap_r_idx;
}
* @param r_idx 生成モンスター種族
* @return ユニークの生成が不可能な条件ならFALSE、それ以外はTRUE
*/
-static bool check_unique_placeable(PlayerType *player_ptr, MonsterRaceId r_idx)
+static bool check_unique_placeable(PlayerType *player_ptr, MonsterRaceId r_idx, BIT_FLAGS mode)
{
if (player_ptr->phase_out) {
return true;
}
+ if (any_bits(mode, PM_CLONE)) {
+ return true;
+ }
+
auto *r_ptr = &monraces_info[r_idx];
if ((r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)) && (r_ptr->cur_num >= r_ptr->max_num)) {
return false;
return false;
}
- if (!check_unique_placeable(player_ptr, r_idx) || !check_quest_placeable(floor, r_idx) || !check_procection_rune(player_ptr, r_idx, y, x)) {
+ if (!check_unique_placeable(player_ptr, r_idx, mode) || !check_quest_placeable(floor, r_idx) || !check_procection_rune(player_ptr, r_idx, y, x)) {
return false;
}
PM_JURAL = 0x00000800, /*!< モンスター生成フラグ: ジュラル星人として誤認生成する */
PM_NO_QUEST = 0x00001000, /*!< モンスター生成フラグ: クエスト除外モンスターを生成しない */
PM_CLONE = 0x00002000, /*!< モンスター生成フラグ: クローンとして生成する */
+ PM_ARENA = 0x00004000, /*!< モンスター生成フラグ: アリーナ用の生成 */
+
};
#include "monster-race/monster-race-hook.h"
#include "monster-attack/monster-attack-effect.h"
#include "monster-attack/monster-attack-table.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-ability-mask.h"
#include "monster-race/race-flags-resistance.h"
void vault_prep_clone(PlayerType *player_ptr)
{
get_mon_num_prep(player_ptr, vault_aux_simple, nullptr);
- vault_aux_race = get_mon_num(player_ptr, 0, player_ptr->current_floor_ptr->dun_level + 10, 0);
+ vault_aux_race = get_mon_num(player_ptr, 0, player_ptr->current_floor_ptr->dun_level + 10, PM_NONE);
get_mon_num_prep(player_ptr, nullptr, nullptr);
}
void vault_prep_symbol(PlayerType *player_ptr)
{
get_mon_num_prep(player_ptr, vault_aux_simple, nullptr);
- MonsterRaceId r_idx = get_mon_num(player_ptr, 0, player_ptr->current_floor_ptr->dun_level + 10, 0);
+ MonsterRaceId r_idx = get_mon_num(player_ptr, 0, player_ptr->current_floor_ptr->dun_level + 10, PM_NONE);
get_mon_num_prep(player_ptr, nullptr, nullptr);
vault_aux_char = monraces_info[r_idx].d_char;
}
S_HI_DRAGON = 93, /* Summon Ancient Dragon */
S_AMBERITES = 94, /* Summon Amberites */
S_UNIQUE = 95, /* Summon Unique Monster */
+ S_DEAD_UNIQUE = 96, /* Summon Dead Unique Monster */
BO_VOID = 97, /*!< モンスター能力: ヴォイド・ボルト / Void Bolt */
BO_ABYSS = 98, /*!< モンスター能力: アビス・ボルト / Abyss Bolt */
BR_VOID = 99, /*!< モンスター能力: 虚無のブレス / Breathe Void */
MonsterAbilityType::S_ANT, MonsterAbilityType::S_SPIDER, MonsterAbilityType::S_HOUND, MonsterAbilityType::S_HYDRA,
MonsterAbilityType::S_ANGEL, MonsterAbilityType::S_DEMON, MonsterAbilityType::S_UNDEAD, MonsterAbilityType::S_DRAGON,
MonsterAbilityType::S_HI_UNDEAD, MonsterAbilityType::S_HI_DRAGON, MonsterAbilityType::S_AMBERITES, MonsterAbilityType::S_UNIQUE,
+ MonsterAbilityType::S_DEAD_UNIQUE,
};
/* Choose "intelligent" spells when desperate Including "summon" spells */
#include "game-option/cheat-options.h"
#include "grid/grid.h"
#include "monster-floor/monster-summon.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-kind-mask.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-brightness-mask.h"
#include "system/monster-race-info.h"
#include "system/player-type-definition.h"
#include "system/redrawing-flags-updater.h"
+#include "util/bit-flags-calculator.h"
#include "util/probability-table.h"
#include "view/display-messages.h"
#include "world/world.h"
* @return 選択されたモンスター生成種族
* @details nasty生成 (ゲーム内経過日数に応じて、現在フロアより深いフロアのモンスターを出現させる仕様)は
*/
-MonsterRaceId get_mon_num(PlayerType *player_ptr, DEPTH min_level, DEPTH max_level, BIT_FLAGS option)
+MonsterRaceId get_mon_num(PlayerType *player_ptr, DEPTH min_level, DEPTH max_level, BIT_FLAGS mode)
{
/* town max_level : same delay as 10F, no nasty mons till day18 */
auto delay = static_cast<int>(std::sqrt(max_level * 10000)) + (max_level * 5);
}
/* Boost the max_level */
- if ((option & GMN_ARENA) || dungeon.flags.has_not(DungeonFeatureType::BEGINNER)) {
+ if (any_bits(mode, PM_ARENA) || dungeon.flags.has_not(DungeonFeatureType::BEGINNER)) {
/* Nightmare mode allows more out-of depth monsters */
if (ironman_nightmare && !randint0(chance_nasty)) {
/* What a bizarre calculation */
} // sorted by depth array,
auto r_idx = i2enum<MonsterRaceId>(entry.index);
auto r_ptr = &monraces_info[r_idx];
- if (!(option & GMN_ARENA) && !chameleon_change_m_idx) {
- if ((r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)) && (r_ptr->cur_num >= r_ptr->max_num)) {
+ if (none_bits(mode, PM_ARENA) && !chameleon_change_m_idx) {
+ if ((r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)) && (r_ptr->cur_num >= r_ptr->max_num) && none_bits(mode, PM_CLONE)) {
continue;
}
#include "system/angband.h"
-#define GMN_ARENA 0x00000001 //!< 賭け闘技場向け生成
-
enum class MonsterRaceId : int16_t;
class FloorType;
class MonsterRaceInfo;
class PlayerType;
MONSTER_IDX m_pop(FloorType *floor_ptr);
-MonsterRaceId get_mon_num(PlayerType *player_ptr, DEPTH min_level, DEPTH max_level, BIT_FLAGS option);
+MonsterRaceId get_mon_num(PlayerType *player_ptr, DEPTH min_level, DEPTH max_level, BIT_FLAGS mode);
void choose_new_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool born, MonsterRaceId r_idx);
byte get_mspeed(FloorType *player_ptr, MonsterRaceInfo *r_ptr);
int get_monster_crowd_number(FloorType *floor_ptr, MONSTER_IDX m_idx);
case MonsterAbilityType::S_HI_DRAGON: return spell_RF6_S_HI_DRAGON(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_HI_DRAGON */
case MonsterAbilityType::S_AMBERITES: return spell_RF6_S_AMBERITES(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_AMBERITES */
case MonsterAbilityType::S_UNIQUE: return spell_RF6_S_UNIQUE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_UNIQUE */
+ case MonsterAbilityType::S_DEAD_UNIQUE: return spell_RF6_S_DEAD_UNIQUE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_DEAD_UNIQUE */
default: break;
}
// clang-format on
case MonsterAbilityType::S_HI_DRAGON: return spell_RF6_S_HI_DRAGON(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_HI_DRAGON */
case MonsterAbilityType::S_AMBERITES: return spell_RF6_S_AMBERITES(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_AMBERITES */
case MonsterAbilityType::S_UNIQUE: return spell_RF6_S_UNIQUE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_UNIQUE */
+ case MonsterAbilityType::S_DEAD_UNIQUE: return spell_RF6_S_DEAD_UNIQUE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_DEAD_UNIQUE */
default: break;
}
// clang-format on
{ MonsterAbilityType::S_HI_DRAGON, { 46, 90, 85, 0, 45, A_INT, _("古代ドラゴンの召喚", "summon Ancient Dragon") } },
{ MonsterAbilityType::S_AMBERITES, { 48, 120, 90, 0, 50, A_INT, _("アンバーの王族の召喚", "summon Lords of Amber") } },
{ MonsterAbilityType::S_UNIQUE, { 50, 150, 95, 0, 50, A_INT, _("ユニークモンスターの召喚", "summon Unique Monsters") } },
+ { MonsterAbilityType::S_DEAD_UNIQUE, { 50, 150, 95, 0, 50, A_INT, _("ユニークモンスターの口寄せ", "summon Dead Unique Monsters") } },
};
/*!
{ MonsterAbilityType::S_HI_DRAGON, _("古代ドラゴン", "Ancient Dragon") },
{ MonsterAbilityType::S_AMBERITES, _("アンバーの王族", "Lords of Amber") },
{ MonsterAbilityType::S_UNIQUE, _("ユニーク", "Unique monsters") },
+ { MonsterAbilityType::S_DEAD_UNIQUE, _("黄泉のユニーク", "Dead unique monsters") },
};
return -1;
case MonsterAbilityType::S_UNIQUE:
return -1;
+ case MonsterAbilityType::S_DEAD_UNIQUE:
+ return -1;
case MonsterAbilityType::MAX:
return -1;
}
*/
static bool spell_summon(MonsterAbilityType spell)
{
- return spell_in_between(spell, MonsterAbilityType::S_KIN, MonsterAbilityType::S_UNIQUE);
+ return spell_in_between(spell, MonsterAbilityType::S_KIN, MonsterAbilityType::S_DEAD_UNIQUE);
}
/*!
return res;
}
+
+/*!
+ * @brief RF6_S_DEAD_UNIQUEの処理。撃破済みユニーク・モンスターをクローンとして召喚。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーが対象ならラーニング可。
+ */
+MonsterSpellResult spell_RF6_S_DEAD_UNIQUE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
+{
+ auto *floor_ptr = player_ptr->current_floor_ptr;
+ auto rlev = monster_level_idx(floor_ptr, m_idx);
+ auto mon_to_mon = (target_type == MONSTER_TO_MONSTER);
+ auto mon_to_player = (target_type == MONSTER_TO_PLAYER);
+ auto see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
+ auto known = monster_near_player(floor_ptr, m_idx, t_idx);
+
+ mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
+ _("%s^が魔法で特別な強敵を蘇らせた!", "%^s magically animates special opponents!"),
+ _("%s^が魔法で特別な強敵を蘇らせた!", "%^s magically animates special opponents!"));
+
+ monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
+ summon_disturb(player_ptr, target_type, known, see_either);
+
+ auto count = 0;
+ for (auto k = 0; k < S_NUM_4; k++) {
+ count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_DEAD_UNIQUE, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_CLONE));
+ }
+
+ if (player_ptr->effects()->blindness()->is_blind() && count && mon_to_player) {
+ msg_format(_("多くの力強いものが間近に蘇った音が聞こえる。", "You hear many powerful things animate nearby."));
+ }
+
+ if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon) {
+ floor_ptr->monster_noise = true;
+ }
+
+ auto res = MonsterSpellResult::make_valid();
+ res.learnable = target_type == MONSTER_TO_PLAYER;
+
+ return res;
+}
MonsterSpellResult spell_RF6_S_HI_DRAGON(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type);
MonsterSpellResult spell_RF6_S_AMBERITES(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type);
MonsterSpellResult spell_RF6_S_UNIQUE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type);
+MonsterSpellResult spell_RF6_S_DEAD_UNIQUE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type);
is_match |= (r_idx == MonsterRaceId::SHALLOW_PUDDLE) || (r_idx == MonsterRaceId::DEEP_PUDDLE) || (r_idx == MonsterRaceId::SKY_WHALE);
return is_match;
}
+ case SUMMON_DEAD_UNIQUE: {
+ return monrace.kind_flags.has(MonsterKindType::UNIQUE) && monrace.max_num == 0;
+ }
default:
return false;
}
#include "artifact/random-art-generator.h"
#include "game-option/cheat-options.h"
#include "inventory/inventory-slot-types.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race-hook.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-indice-types.h"
auto *floor_ptr = this->player_ptr->current_floor_ptr;
MonsterRaceId r_idx;
while (true) {
- r_idx = get_mon_num(this->player_ptr, 0, floor_ptr->dun_level, 0);
+ r_idx = get_mon_num(this->player_ptr, 0, floor_ptr->dun_level, PM_NONE);
auto &r_ref = monraces_info[r_idx];
auto check = (floor_ptr->dun_level < r_ref.level) ? (r_ref.level - floor_ptr->dun_level) : 0;
const auto sval = this->o_ptr->bi_key.sval();
#include "player/eldritch-horror.h"
#include "core/stuff-handler.h"
#include "locale/english.h"
+#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race-hook.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags1.h"
}
} else if (!necro) {
get_mon_num_prep(player_ptr, get_nightmare, nullptr);
- auto *r_ptr = &monraces_info[get_mon_num(player_ptr, 0, MAX_DEPTH, 0)];
+ auto *r_ptr = &monraces_info[get_mon_num(player_ptr, 0, MAX_DEPTH, PM_NONE)];
power = r_ptr->level + 10;
const auto &desc = r_ptr->name;
get_mon_num_prep(player_ptr, nullptr, nullptr);
auto select_r_idx = [player_ptr, floor_ptr, &align]() -> std::optional<MonsterRaceId> {
for (auto attempts = 100; attempts > 0; attempts--) {
/* Get a (hard) monster type */
- auto r_idx = get_mon_num(player_ptr, 0, floor_ptr->dun_level + 11, 0);
+ auto r_idx = get_mon_num(player_ptr, 0, floor_ptr->dun_level + 11, PM_NONE);
auto *r_ptr = &monraces_info[r_idx];
/* Decline incorrect alignment */
while (attempts--) {
/* Get a (hard) monster type */
- r_idx = get_mon_num(player_ptr, 0, floor_ptr->dun_level + 11, 0);
+ r_idx = get_mon_num(player_ptr, 0, floor_ptr->dun_level + 11, PM_NONE);
r_ptr = &monraces_info[r_idx];
/* Decline incorrect alignment */
while (attempts--) {
/* Get a (hard) monster type */
- r_idx = get_mon_num(player_ptr, 0, floor_ptr->dun_level + 0, 0);
+ r_idx = get_mon_num(player_ptr, 0, floor_ptr->dun_level + 0, PM_NONE);
r_ptr = &monraces_info[r_idx];
/* Decline incorrect alignment */
DEPTH lev2 = r_ptr->level + ((randint1(20) / randint1(9)) + 1);
MonsterRaceId r;
for (int i = 0; i < 1000; i++) {
- r = get_mon_num(player_ptr, 0, (player_ptr->current_floor_ptr->dun_level + r_ptr->level) / 2 + 5, 0);
+ r = get_mon_num(player_ptr, 0, (player_ptr->current_floor_ptr->dun_level + r_ptr->level) / 2 + 5, PM_NONE);
if (!MonsterRace(r).is_valid()) {
break;
}
SUMMON_APOCRYPHA_DRAGONS = 69, /*!< 召喚タイプ: 強力な古代ドラゴン */
SUMMON_VESPOID = 70, /*!< 召喚タイプ: ランゴスタ */
SUMMON_ANTI_TIGERS = 71, /*!< 召喚タイプ: トラ以外 */
+ SUMMON_DEAD_UNIQUE = 72, /*!< 召喚タイプ: 撃破済みユニーク */
};