if (o_ptr->tval != TV_STAFF && o_ptr->tval != TV_WAND)
return FALSE;
- if (is_specific_player_race(creature_ptr, RACE_SKELETON) || is_specific_player_race(creature_ptr, RACE_GOLEM)
- || is_specific_player_race(creature_ptr, RACE_ZOMBIE) || is_specific_player_race(creature_ptr, RACE_SPECTRE)) {
+ if (player_race_food(creature_ptr) == PlayerRaceFood::MANA) {
concptr staff;
if (o_ptr->tval == TV_STAFF && (item < 0) && (o_ptr->number > 1)) {
return;
}
+ auto food_type = player_race_food(creature_ptr);
+
/* Balrogs change humanoid corpses to energy */
- if ((is_specific_player_race(creature_ptr, RACE_BALROG) || (mimic_info[creature_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_DEMON))
- && (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_CORPSE && angband_strchr("pht", r_info[o_ptr->pval].d_char))) {
+ if (food_type == PlayerRaceFood::CORPSE && (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_CORPSE && angband_strchr("pht", r_info[o_ptr->pval].d_char))) {
GAME_TEXT o_name[MAX_NLEN];
describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
msg_format(_("%sは燃え上り灰になった。精力を吸収した気がする。", "%^s is burnt to ashes. You absorb its vitality!"), o_name);
} else {
msg_print(_("食べ物がアゴを素通りして落ち、消えた!", "The food falls through your jaws and vanishes!"));
}
- } else if (is_specific_player_race(creature_ptr, RACE_VAMPIRE) || (creature_ptr->mimic_form == MIMIC_VAMPIRE)) {
+ } else if (food_type == PlayerRaceFood::BLOOD) {
/* Vampires are filled only by bloods, so reduced nutritional benefit */
(void)set_food(creature_ptr, creature_ptr->food + (o_ptr->pval / 10));
msg_print(_("あなたのような者にとって食糧など僅かな栄養にしかならない。", "Mere victuals hold scant sustenance for a being such as yourself."));
if (creature_ptr->food < PY_FOOD_ALERT) /* Hungry */
msg_print(_("あなたの飢えは新鮮な血によってのみ満たされる!", "Your hunger can only be satisfied with fresh blood!"));
- } else if (player_race_life(creature_ptr) != PlayerRaceLife::LIVING || (mimic_info[creature_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING)) {
+ } else if (food_type == PlayerRaceFood::WATER) {
+ msg_print(_("動物の食物はあなたにとってほとんど栄養にならない。", "The food of animals is poor sustenance for you."));
+ set_food(creature_ptr, creature_ptr->food + ((o_ptr->pval) / 20));
+ } else if (food_type != PlayerRaceFood::RATION) {
msg_print(_("生者の食物はあなたにとってほとんど栄養にならない。", "The food of mortals is poor sustenance for you."));
set_food(creature_ptr, creature_ptr->food + ((o_ptr->pval) / 20));
} else {
case SV_STAFF_NOTHING: {
msg_print(_("何も起らなかった。", "Nothing happens."));
- if (is_specific_player_race(creature_ptr, RACE_SKELETON) || is_specific_player_race(creature_ptr, RACE_GOLEM)
- || is_specific_player_race(creature_ptr, RACE_ZOMBIE) || is_specific_player_race(creature_ptr, RACE_SPECTRE))
+ if (player_race_food(creature_ptr) == PlayerRaceFood::MANA)
msg_print(_("もったいない事をしたような気がする。食べ物は大切にしなくては。", "What a waste. It's your food!"));
break;
}
if (o_ptr->tval == TV_FOOD)
return TRUE;
- if (is_specific_player_race(player_ptr, RACE_SKELETON) || is_specific_player_race(player_ptr, RACE_GOLEM)
- || is_specific_player_race(player_ptr, RACE_ZOMBIE) || is_specific_player_race(player_ptr, RACE_SPECTRE)) {
+ auto food_type = player_race_food(player_ptr);
+ if (food_type == PlayerRaceFood::MANA) {
if (o_ptr->tval == TV_STAFF || o_ptr->tval == TV_WAND)
return TRUE;
- } else if (is_specific_player_race(player_ptr, RACE_BALROG) || (mimic_info[player_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_DEMON)) {
+ } else if (food_type == PlayerRaceFood::CORPSE) {
if (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_CORPSE && angband_strchr("pht", r_info[o_ptr->pval].d_char))
return TRUE;
}
if (o_ptr->tval == TV_POTION)
return TRUE;
- if (is_specific_player_race(player_ptr, RACE_ANDROID) && (o_ptr->tval == TV_FLASK) && (o_ptr->sval == SV_FLASK_OIL))
+ if (player_race_food(player_ptr) == PlayerRaceFood::OIL && o_ptr->tval == TV_FLASK && o_ptr->sval == SV_FLASK_OIL)
return TRUE;
return FALSE;
* Quaff a potion (from the pack or the floor)
* @param creature_ptr プレーヤーへの参照ポインタ
* @param item 飲む薬オブジェクトの所持品ID
+ * @details
+ * 効果発動のあと、食料タイプによって空腹度を少し充足する。
*/
void exe_quaff_potion(player_type *creature_ptr, INVENTORY_IDX item)
{
case SV_POTION_SALT_WATER:
msg_print(_("うぇ!思わず吐いてしまった。", "The potion makes you vomit!"));
- if (!(is_specific_player_race(creature_ptr, RACE_GOLEM) || is_specific_player_race(creature_ptr, RACE_ZOMBIE)
- || is_specific_player_race(creature_ptr, RACE_BALROG) || is_specific_player_race(creature_ptr, RACE_ANDROID)
- || is_specific_player_race(creature_ptr, RACE_SPECTRE) || (mimic_info[creature_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING))) {
- /* Only living creatures get thirsty */
+ switch (player_race_food(creature_ptr)) {
+ case PlayerRaceFood::RATION:
+ case PlayerRaceFood::WATER:
+ case PlayerRaceFood::BLOOD:
(void)set_food(creature_ptr, PY_FOOD_STARVE - 1);
+ break;
+ default:
+ break;
}
(void)set_poisoned(creature_ptr, 0);
creature_ptr->window_flags |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
- /* Potions can feed the player */
- switch (creature_ptr->mimic_form) {
- case MIMIC_NONE:
- switch (creature_ptr->prace) {
- case RACE_VAMPIRE:
- (void)set_food(creature_ptr, creature_ptr->food + (q_ptr->pval / 10));
- break;
- case RACE_SKELETON:
- /* Do nothing */
- break;
- case RACE_GOLEM:
- case RACE_ZOMBIE:
- case RACE_BALROG:
- case RACE_SPECTRE:
+ if (is_specific_player_race(creature_ptr, RACE_SKELETON))
+ return; //!< @note スケルトンは水分で飢えを満たせない
+
+ switch (player_race_food(creature_ptr)) {
+ case PlayerRaceFood::WATER:
+ msg_print(_("水分を取り込んだ。", "You are moistened."));
+ set_food(creature_ptr, MIN(creature_ptr->food + q_ptr->pval + MAX(0, q_ptr->pval * 10) + 2000, PY_FOOD_MAX - 1));
+ break;
+ case PlayerRaceFood::OIL:
+ if (q_ptr->tval == TV_FLASK) {
+ msg_print(_("オイルを補給した。", "You replenish yourself with the oil."));
+ set_food(creature_ptr, creature_ptr->food + 5000);
+ } else {
set_food(creature_ptr, creature_ptr->food + ((q_ptr->pval) / 20));
- break;
- case RACE_ANDROID:
- if (q_ptr->tval == TV_FLASK) {
- msg_print(_("オイルを補給した。", "You replenish yourself with the oil."));
- set_food(creature_ptr, creature_ptr->food + 5000);
- } else {
- set_food(creature_ptr, creature_ptr->food + ((q_ptr->pval) / 20));
- }
- break;
- case RACE_ENT:
- msg_print(_("水分を取り込んだ。", "You are moistened."));
- set_food(creature_ptr, MIN(creature_ptr->food + q_ptr->pval + MAX(0, q_ptr->pval * 10) + 2000, PY_FOOD_MAX - 1));
- break;
- default:
- (void)set_food(creature_ptr, creature_ptr->food + q_ptr->pval);
- break;
}
break;
- case MIMIC_DEMON:
- case MIMIC_DEMON_LORD:
- set_food(creature_ptr, creature_ptr->food + ((q_ptr->pval) / 20));
- break;
- case MIMIC_VAMPIRE:
+ case PlayerRaceFood::BLOOD:
(void)set_food(creature_ptr, creature_ptr->food + (q_ptr->pval / 10));
break;
+ case PlayerRaceFood::MANA:
+ case PlayerRaceFood::CORPSE:
+ set_food(creature_ptr, creature_ptr->food + ((q_ptr->pval) / 20));
+ break;
default:
(void)set_food(creature_ptr, creature_ptr->food + q_ptr->pval);
break;
0,
0x000000,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{ },
},
{
5,
0x000003,
PlayerRaceLife::DEMON,
+ PlayerRaceFood::CORPSE,
{
{ TR_RES_FIRE },
{ TR_RES_NETHER },
20,
0x000003,
PlayerRaceLife::DEMON,
+ PlayerRaceFood::CORPSE,
{
{ TR_IM_FIRE },
{ TR_RES_COLD },
5,
0x000005,
PlayerRaceLife::UNDEAD,
+ PlayerRaceFood::BLOOD,
{
{ TR_RES_COLD },
{ TR_RES_POIS },
auto race_ptr = get_player_race_info(creature_ptr, base_race);
return race_ptr->life;
}
+
+/*!
+ * @brief 種族の食料形態を返す
+ * @param creature_ptr プレイヤー情報への参照ポインタ
+ * @param base_race ミミック中も元種族の情報を返すならtrue
+ * @return 食料形態
+ */
+PlayerRaceFood player_race_food(player_type *creature_ptr, bool base_race)
+{
+ auto race_ptr = get_player_race_info(creature_ptr, base_race);
+ return race_ptr->food;
+}
#pragma once
+#include <optional>
#include <unordered_map>
#include <vector>
-#include <optional>
#include "object-enchant/tr-types.h"
#include "player-ability/player-ability-types.h"
#define MIMIC_IS_UNDEAD 0x00000004
/*!
- * プレイヤー種族の生命形態
+ * @brief プレイヤー種族の生命形態
*/
enum class PlayerRaceLife {
- LIVING = 0, //生きている
- UNDEAD = 1, //不死
- DEMON = 2, //悪魔
- NONLIVING = 3, //生きてない
+ LIVING = 0, //!< 生きている
+ UNDEAD = 1, //!< 不死
+ DEMON = 2, //!< 悪魔
+ NONLIVING = 3, //!< 生きてない
MAX
};
+/*!
+ * @brief プレイヤー種族の食料形態
+ */
+enum class PlayerRaceFood {
+ RATION = 0, //!< 食料
+ WATER = 1, //!< 水
+ OIL = 2, //!< 油
+ BLOOD = 3, //!< 血
+ MANA = 4, //!< 魔力
+ CORPSE = 5, //!< 死体(捧げる)
+ MAX
+};
+
+/*!
+ * @brief プレイヤー種族の条件設定構造体
+ */
struct player_race_condition {
tr_type type{};
PLAYER_LEVEL level{};
std::optional<player_class_type> pclass{};
bool not_class{};
- player_race_condition(tr_type t, PLAYER_LEVEL l = 1, const std::optional<player_class_type>& c = std::nullopt, bool nc = false)
- : type(t), level(l), pclass(c), not_class(nc) {}
+ player_race_condition(tr_type t, PLAYER_LEVEL l = 1, const std::optional<player_class_type> &c = std::nullopt, bool nc = false)
+ : type(t)
+ , level(l)
+ , pclass(c)
+ , not_class(nc)
+ {
+ }
};
/*!
- * p@brief プレイヤー種族構造体 / Player racial info
+ * @brief プレイヤー種族構造体 / Player racial info
*/
struct player_race {
concptr title{}; //!< 種族名 / Title of race
byte m_m_wt{}; //!< 体重加算範囲(男) / mod weight (males)
byte f_b_ht{}; //!< 身長最小値(女) / base height (females)
- byte f_m_ht{}; //!< 身長加算範囲(女) / mod height (females)
+ byte f_m_ht{}; //!< 身長加算範囲(女) / mod height (females)
byte f_b_wt{}; //!< 体重最小値(女) / base weight (females)
byte f_m_wt{}; //!< 体重加算範囲(女) / mod weight (females)
u32b choice{}; //!< 似つかわしい職業(ミミック時はミミック種族属性) / Legal class choices
PlayerRaceLife life{}; //!< 生命の形態
+ PlayerRaceFood food{}; //!< 食料の形態
std::vector<player_race_condition> extra_flags;
};
bool player_race_has_flag(player_type *creature_ptr, tr_type flag, bool base_race = false);
void add_player_race_flags(player_type *creature_ptr, BIT_FLAGS *flags, bool base_race = false);
PlayerRaceLife player_race_life(player_type *creature_ptr, bool base_race = false);
+PlayerRaceFood player_race_food(player_type *creature_ptr, bool base_race = false);
0,
0x1FFFFFFF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{},
},
{
2,
0x1E77E7FF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{},
},
{
3,
0x1E77E75B,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_LITE },
},
4,
0x1F6FFC0B,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_HOLD_EXP },
},
4,
0x1F67D60F,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_FREE_ACT },
},
5,
0x11890005,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_BLIND },
},
3,
0x1DD8818D,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_DARK },
},
3,
0x00880005,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_SUST_STR },
{ TR_REGEN, 15 },
0,
0x1FFFF7FF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_SUST_CON },
{ TR_REGEN },
4,
0x1F77E75B,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_LITE },
{ TR_SEE_INVIS },
0,
0x05C0A09D,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_FEAR },
},
3,
0x10A80407,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_SUST_STR },
{ TR_RES_DARK },
3,
0x08880011,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_SUST_STR },
{ TR_RES_SHARDS },
0,
0x123D4727,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_CHAOS },
},
1,
0x00888005,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_SOUND },
},
2,
0x1667360F,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_ACID },
{ TR_IM_ACID, 20 },
2,
0x004D8011,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_ACID },
{ TR_RES_CONF },
3,
0x1444A009,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_POIS },
},
5,
0x1569040F,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_DARK },
{ TR_RES_DISEN },
5,
0x1E77C7DF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_DARK },
{ TR_SEE_INVIS, 20 },
2,
0x07FFE757,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_FIRE, 5 },
{ TR_RES_COLD, 10 },
4,
0x12334746,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_SUST_INT },
{ TR_SUST_WIS },
3,
0x1DB537CB,
PlayerRaceLife::DEMON,
+ PlayerRaceFood::RATION,
{
{ TR_RES_FIRE },
{ TR_SEE_INVIS, 10 },
4,
0x00800001,
PlayerRaceLife::NONLIVING,
+ PlayerRaceFood::MANA,
{
{ TR_RES_POIS },
{ TR_SEE_INVIS },
2,
0x0234070F,
PlayerRaceLife::UNDEAD,
+ PlayerRaceFood::MANA,
{
{ TR_RES_COLD, 10 },
{ TR_RES_POIS },
2,
0x00800001,
PlayerRaceLife::UNDEAD,
+ PlayerRaceFood::MANA,
{
{ TR_RES_COLD, 5 },
{ TR_RES_POIS },
5,
0x067DC7FF,
PlayerRaceLife::UNDEAD,
+ PlayerRaceFood::BLOOD,
{
{ TR_RES_COLD },
{ TR_RES_POIS },
5,
0x0631474A,
PlayerRaceLife::UNDEAD,
+ PlayerRaceFood::MANA,
{
{ TR_RES_COLD },
{ TR_RES_POIS },
4,
0x1623F65E,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_LITE },
{ TR_LEVITATION },
0,
0x057887CF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_CONF },
{ TR_RES_SOUND },
0,
0x10010005,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::WATER,
{
{ TR_VUL_FIRE }
},
3,
0x1779F777,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_SEE_INVIS },
{ TR_LEVITATION },
5,
0x07EDC4DB,
PlayerRaceLife::DEMON,
+ PlayerRaceFood::CORPSE,
{
{ TR_RES_FIRE },
{ TR_RES_NETHER },
0,
0x1FFFF7FF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_SUST_CON },
},
4,
0x1E33C7DF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_VUL_LITE },
{ TR_LEVITATION },
0,
0x0C18B7AD,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_CONF },
},
0,
0x00800001,
PlayerRaceLife::NONLIVING,
+ PlayerRaceFood::OIL,
{
{ TR_VUL_ELEC },
{ TR_RES_POIS },
2,
0x1E77E7FF,
PlayerRaceLife::LIVING,
+ PlayerRaceFood::RATION,
{
{ TR_RES_WATER },
},