F:RES_COLD | RES_POIS | RES_NETHER | SH_COLD | ESP_UNDEAD
F:IGNORE_COLD | XTRA_H_RES
F:CURSED | RANDOM_CURSE2 | ADD_L_CURSE | DRAIN_EXP
+G:1/3:HEAVY_CURSE
+G:1/9:TY_CURSE
+G:1/3:ADD_H_CURSE
+G:1/6:AGGRAVATE
+G:1/9:NO_MAGIC
+G:1/9:NO_TELE
N:5:悪魔の
E:of Demon
F:STR | INT | CON |
F:RES_FIRE | RES_NETHER | ESP_DEMON | SH_FIRE | CURSED | RANDOM_CURSE2 | POWERFUL |
F:IGNORE_FIRE | XTRA_RES
+G:1/1:DRAIN_EXP | DRAIN_MANA | DRAIN_HP
+G:1/3:HEAVY_CURSE
+G:1/3:AGGRAVATE
+G:1/3:ADD_L_CURSE
+G:1/5:ADD_H_CURSE
+G:1/5:TY_CURSE
+G:1/5:CALL_DEMON
N:6:ドルイドの
E:of Druid
C:0:0:10:0
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | XTRA_H_RES
+G:1/4:RES_POIS
# OnePower
C:0:0:10:0
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
+G:2/3:XTRA_H_RES
+G:1/4:RES_POIS
#JZ#
N:21:反射の
F:CON|
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | XTRA_E_RES
+
### Crowns and Helms ###
N:23:闇の
F:INT | SEE_INVIS |
F:RES_FIRE | RES_NETHER | ESP_DEMON | SH_FIRE | CURSED | RANDOM_CURSE2 | POWERFUL |
F:IGNORE_FIRE | XTRA_RES
+G:1/1:DRAIN_EXP | DRAIN_MANA | DRAIN_HP
+G:1/3:HEAVY_CURSE
+G:1/3:AGGRAVATE
+G:1/3:ADD_L_CURSE
+G:1/3:ADD_H_CURSE
+G:1/5:TY_CURSE
+G:1/5:CALL_DEMON
# OneAbility
W:0:18:0:500
F:LITE_3 | RES_LITE | ACTIVATE
U:LIGHT
+G:1/3:LITE
+G:1/3:LITE_2
N:33:テレパシーの
E:of Telepathy
F:RES_COLD | RES_POIS | RES_NEXUS | RES_NETHER |
F:SH_COLD | SEE_INVIS | LITE_M1 | XTRA_H_RES | XTRA_POWER | ADD_H_CURSE |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
+G:1/3:NO_MAGIC
+G:1/3:NO_TELE
+G:1/3:TY_CURSE
+G:1/3:DRAIN_EXP
+G:1/3:DRAIN_MANA
+G:1/3:DRAIN_HP
N:39:疾病の
E:of Sickliness
F:SEE_INVIS | RES_COLD | RES_NETHER | SLOW_DIGEST |
F:CURSED | HEAVY_CURSE | ADD_H_CURSE | ACTIVATE |
U:WRAITH
+G:1/3:COWARDICE
+G:1/3:CALL_UNDEAD
+G:1/3:SLOW_REGEN
+G:1/3:DRAIN_EXP
### Gloves ###
X:35:7
W:0:4:0:250
F:LEVITATION
+G:1/2:XTRA_H_RES
#J0#
#J0# 岸さんの訳です
F:WIS |
F:SLAY_EVIL | SLAY_UNDEAD | SLAY_DEMON |
F:SEE_INVIS | BLESSED | RES_FEAR | ONE_SUSTAIN
+G:1/4:BLOWS
# OneSustain
F:FREE_ACT | SEE_INVIS | LEVITATION | REGEN |
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | ONE_SUSTAIN | XTRA_H_RES |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
+G:1/3:RES_POIS
+G:1/3:WARNING
# OneAbility
F:SLAY_ORC | SLAY_TROLL | SLAY_GIANT |
F:ESP_ORC | ESP_TROLL | ESP_GIANT |
F:FREE_ACT | SEE_INVIS
+G:1/3:RES_FEAR
N:69:追加攻撃の
E:of Extra Attacks
X:24:15
W:0:18:0:500
C:0:0:0:0
+G:1/5:BRAND_POIS
+G:1/3:VORPAL
N:71:理力の
E:of Force
W:0:40:0:7000
C:0:0:0:3
F:CON | SLAY_DRAGON | KILL_DRAGON | XTRA_E_RES | XTRA_D_RES | ESP_DRAGON
+G:1/3:RES_POIS
#JZ#
N:96:(吸血)
X:24:25
W:0:18:0:10000
F:VAMPIRIC | HOLD_EXP
+G:1/5:SLAY_HUMAN
N:97:虹色の
E:of Prism
F:SLAY_EVIL | TELEPORT | FREE_ACT | SEARCH |
F:REGEN | SLOW_DIGEST | RES_NEXUS | ACTIVATE | XTRA_H_RES
U:TELEPORT
+G:1/5:SLAY_DEMON
+G:1/7:XTRA_POWER
#JZ#
N:99:(パターン)
F:STR | CON |
F:SLAY_EVIL | SLAY_DEMON | SLAY_UNDEAD |
F:FREE_ACT | SEE_INVIS | XTRA_H_RES
+G:1/3:HOLD_EXP
+G:1/3:DEX
+G:1/5:RES_FEAR
#J0#
#J0# 岸さんの訳です
C:6:6:-20:4
F:INT | BRAND_FIRE | CURSED | POWERFUL |
F:RES_FIRE | RES_NETHER | SEE_INVIS | ESP_DEMON | XTRA_DICE
+G:1/1:DRAIN_EXP | DRAIN_MANA | DRAIN_HP
+G:1/3:HEAVY_CURSE
+G:1/3:CHAOTIC
+G:1/4:BLOWS
+G:1/5:ADD_H_CURSE
+G:1/5:CALL_DEMON
N:102:モルグルの
E:of Morgul
F:RES_COLD | RES_NETHER | SH_COLD
F:SEE_INVIS | ESP_UNDEAD | AGGRAVATE
F:RANDOM_CURSE2 | XTRA_DICE | XTRA_POWER
+G:1/3:HEAVY_CURSE
+G:1/6:TY_CURSE
N:103:人喰いの
E:of Slay Human
#include "util/string-processor.h"
#include "view/display-messages.h"
#include <string>
+#include <utility>
/*!
* @brief テキストトークンを走査してフラグを一つ得る(エゴ用) /
return 1;
}
+static bool grab_ego_generate_flags(ego_generate_type &xtra, concptr what)
+{
+ for (int i = 0; i < TR_FLAG_MAX; i++) {
+ if (streq(what, k_info_flags[i])) {
+ xtra.tr_flags.push_back(static_cast<tr_type>(i));
+ return false;
+ }
+ }
+
+ auto it = k_info_gen_flags.find(what);
+ if (it != k_info_gen_flags.end()) {
+ xtra.trg_flags.push_back(it->second);
+ return false;
+ }
+
+ return true;
+}
+
+
/*!
* @brief アイテムエゴ情報(e_info)のパース関数 /
* Initialize the "e_info" array, by parsing an ascii "template" file
s = t;
}
+ } else if (buf[0] == 'G') {
+ ego_generate_type xtra;
+
+ s = angband_strstr(buf + 2, ":");
+ if (!s)
+ return 1;
+
+ *s++ = '\0';
+
+ if (2 != sscanf(buf + 2, "%d/%d", &xtra.mul, &xtra.dev))
+ return 1;
+
+ for (; *s;) {
+ for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
+ ;
+
+ if (*t) {
+ *t++ = '\0';
+ while ((*t == ' ') || (*t == '|'))
+ t++;
+ }
+
+ if (grab_ego_generate_flags(xtra, s))
+ return 5;
+
+ s = t;
+ }
+
+ e_ptr->xtra_flags.push_back(std::move(xtra));
} else {
return 6;
}
}
switch (o_ptr->name2) {
- case EGO_RESISTANCE:
- if (one_in_(4))
- add_flag(o_ptr->art_flags, TR_RES_POIS);
- break;
case EGO_DWARVEN:
o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
o_ptr->ac = k_info[o_ptr->k_idx].ac + 5;
switch (o_ptr->name2) {
case EGO_A_DEMON:
- if (one_in_(3))
- o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
- one_in_(3) ? add_flag(o_ptr->art_flags, TR_DRAIN_EXP)
- : one_in_(2) ? add_flag(o_ptr->art_flags, TR_DRAIN_HP) : add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
-
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_AGGRAVATE);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_ADD_L_CURSE);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_DRAIN_HP);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_TY_CURSE);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_CALL_DEMON);
- break;
case EGO_A_MORGUL:
- if (one_in_(3))
- o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
- if (one_in_(9))
- add_flag(o_ptr->art_flags, TR_TY_CURSE);
- if (one_in_(4))
- add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
- if (one_in_(6))
- add_flag(o_ptr->art_flags, TR_AGGRAVATE);
- if (one_in_(9))
- add_flag(o_ptr->art_flags, TR_NO_MAGIC);
- if (one_in_(9))
- add_flag(o_ptr->art_flags, TR_NO_TELE);
break;
default:
msg_print(_("エラー:適した呪い鎧エゴがみつかりませんでした.", "Error:Suitable cursed armor ego not found."));
}
switch (o_ptr->name2) {
- case EGO_ENDURANCE:
- if (!one_in_(3))
- one_high_resistance(o_ptr);
- if (one_in_(4))
- add_flag(o_ptr->art_flags, TR_RES_POIS);
- break;
case EGO_REFLECTION:
if (o_ptr->sval == SV_MIRROR_SHIELD)
o_ptr->name2 = 0;
break;
-
case EGO_S_DWARVEN:
o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
o_ptr->ac = k_info[o_ptr->k_idx].ac + 3;
break;
+ default:
+ break;
}
}
}
o_ptr->name2 = get_random_ego(INVEN_FEET, TRUE);
- switch (o_ptr->name2) {
- case EGO_SLOW_DESCENT:
- if (one_in_(2)) {
- one_high_resistance(o_ptr);
- }
-
- break;
- }
} else if (power < -1) {
o_ptr->name2 = get_random_ego(INVEN_FEET, FALSE);
}
case EGO_H_DEMON:
ok_flag = false;
break;
- case EGO_ANCIENT_CURSE:
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_NO_MAGIC);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_NO_TELE);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_TY_CURSE);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_DRAIN_HP);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
+ default:
break;
}
case EGO_DARK:
case EGO_INFRAVISION:
case EGO_H_PROTECTION:
+ case EGO_LITE:
break;
case EGO_SEEING:
if (one_in_(7)) {
else
add_esp_weak(o_ptr, FALSE);
}
-
- break;
- case EGO_LITE:
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_LITE_1);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_LITE_2);
break;
default:
/* not existing helm (Magi, Might, etc...)*/
o_ptr->name2 = get_random_ego(INVEN_HEAD, FALSE);
switch (o_ptr->name2) {
- case EGO_H_DEMON:
- if (one_in_(3))
- o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
- one_in_(3) ? add_flag(o_ptr->art_flags, TR_DRAIN_EXP)
- : one_in_(2) ? add_flag(o_ptr->art_flags, TR_DRAIN_HP) : add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
-
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_AGGRAVATE);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_ADD_L_CURSE);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_DRAIN_HP);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_TY_CURSE);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_CALL_DEMON);
- break;
case EGO_ANCIENT_CURSE:
ok_flag = FALSE;
break;
+ default:
+ break;
}
if (ok_flag)
case EGO_NAZGUL:
o_ptr->to_d -= 3;
o_ptr->to_h -= 3;
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_COWARDICE);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_CALL_UNDEAD);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_SLOW_REGEN);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
break;
}
}
switch (o_ptr->name2) {
- case EGO_HA:
- if (one_in_(4) && (level > 40))
- add_flag(o_ptr->art_flags, TR_BLOWS);
- break;
- case EGO_DF:
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_RES_POIS);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_WARNING);
- break;
- case EGO_KILL_DRAGON:
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_RES_POIS);
- break;
- case EGO_WEST:
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_RES_FEAR);
- break;
case EGO_SLAYING_WEAPON:
if (one_in_(3))
o_ptr->dd *= 2;
o_ptr->ds++;
} while (one_in_(o_ptr->ds));
}
-
- if (one_in_(5)) {
- add_flag(o_ptr->art_flags, TR_BRAND_POIS);
- }
- if (o_ptr->tval == TV_SWORD && one_in_(3)) {
- add_flag(o_ptr->art_flags, TR_VORPAL);
- }
- break;
- case EGO_TRUMP:
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_SLAY_DEMON);
- if (one_in_(7))
- one_ability(o_ptr);
- break;
- case EGO_PATTERN:
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_HOLD_EXP);
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_DEX);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_RES_FEAR);
break;
case EGO_SHARPNESS:
o_ptr->pval = (PARAMETER_VALUE)m_bonus(5, level) + 1;
else
o_ptr->pval = (PARAMETER_VALUE)m_bonus(3, level);
break;
- case EGO_VAMPIRIC:
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_SLAY_HUMAN);
+ default:
break;
}
break;
}
-
- switch (o_ptr->name2) {
- case EGO_MORGUL:
- if (one_in_(6))
- add_flag(o_ptr->art_flags, TR_TY_CURSE);
- if (one_in_(3))
- o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
- break;
- case EGO_DEMON:
-
- if (one_in_(3))
- o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
- one_in_(3) ? add_flag(o_ptr->art_flags, TR_DRAIN_EXP)
- : one_in_(2) ? add_flag(o_ptr->art_flags, TR_DRAIN_HP) : add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
-
- if (one_in_(3))
- add_flag(o_ptr->art_flags, TR_CHAOTIC);
- if (one_in_(4))
- add_flag(o_ptr->art_flags, TR_BLOWS);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
- if (one_in_(5))
- add_flag(o_ptr->art_flags, TR_CALL_DEMON);
- break;
- }
}
}
#include "object-enchant/apply-magic-others.h"
#include "object-enchant/apply-magic-weapon.h"
#include "object-enchant/item-apply-magic.h"
-#include "object-enchant/object-boost.h"
#include "object-enchant/object-curse.h"
#include "object-enchant/object-ego.h"
#include "object-enchant/special-object-flags.h"
#include "object-enchant/tr-types.h"
#include "object-enchant/trc-types.h"
#include "object-enchant/trg-types.h"
-#include "object-hook/hook-checker.h"
#include "object-hook/hook-enchant.h"
#include "object/object-kind.h"
#include "player/player-status-flags.h"
#include "world/world.h"
/*!
- * @brief 0 および負数に対応した randint1()
- * @param n
- *
- * n == 0 のとき、常に 0 を返す。
- * n > 0 のとき、[1, n] の乱数を返す。
- * n < 0 のとき、[n,-1] の乱数を返す。
- */
-static int randint1_signed(const int n)
-{
- if (n == 0)
- return 0;
-
- return n > 0 ? randint1(n) : -randint1(-n);
-}
-
-/*!
* @brief 生成されたベースアイテムに魔法的な強化を与えるメインルーチン
* Complete the "creation" of an object by applying "magic" to the item
* @param owner_ptr プレーヤーへの参照ポインタ
}
if (object_is_ego(o_ptr)) {
- ego_item_type *e_ptr = &e_info[o_ptr->name2];
- if (!e_ptr->cost)
- o_ptr->ident |= (IDENT_BROKEN);
-
- if (e_ptr->gen_flags.has(TRG::CURSED))
- o_ptr->curse_flags |= (TRC_CURSED);
- if (e_ptr->gen_flags.has(TRG::HEAVY_CURSE))
- o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
- if (e_ptr->gen_flags.has(TRG::PERMA_CURSE))
- o_ptr->curse_flags |= (TRC_PERMA_CURSE);
- if (e_ptr->gen_flags.has(TRG::RANDOM_CURSE0))
- o_ptr->curse_flags |= get_curse(owner_ptr, 0, o_ptr);
- if (e_ptr->gen_flags.has(TRG::RANDOM_CURSE1))
- o_ptr->curse_flags |= get_curse(owner_ptr, 1, o_ptr);
- if (e_ptr->gen_flags.has(TRG::RANDOM_CURSE2))
- o_ptr->curse_flags |= get_curse(owner_ptr, 2, o_ptr);
-
- if (e_ptr->gen_flags.has(TRG::ONE_SUSTAIN))
- one_sustain(o_ptr);
- if (e_ptr->gen_flags.has(TRG::XTRA_POWER))
- one_ability(o_ptr);
- if (e_ptr->gen_flags.has(TRG::XTRA_H_RES))
- one_high_resistance(o_ptr);
- if (e_ptr->gen_flags.has(TRG::XTRA_E_RES))
- one_ele_resistance(o_ptr);
- if (e_ptr->gen_flags.has(TRG::XTRA_D_RES))
- one_dragon_ele_resistance(o_ptr);
- if (e_ptr->gen_flags.has(TRG::XTRA_L_RES))
- one_lordly_high_resistance(o_ptr);
- if (e_ptr->gen_flags.has(TRG::XTRA_RES))
- one_resistance(o_ptr);
- if (e_ptr->gen_flags.has(TRG::XTRA_DICE)) {
- do {
- o_ptr->dd++;
- } while (one_in_(o_ptr->dd));
-
- if (o_ptr->dd > 9)
- o_ptr->dd = 9;
- }
-
- if (e_ptr->act_idx)
- o_ptr->xtra2 = (XTRA8)e_ptr->act_idx;
-
- bool is_powerful = e_ptr->gen_flags.has(TRG::POWERFUL);
-
- if ((object_is_cursed(o_ptr) || object_is_broken(o_ptr)) && !is_powerful) {
- if (e_ptr->max_to_h)
- o_ptr->to_h -= randint1(e_ptr->max_to_h);
- if (e_ptr->max_to_d)
- o_ptr->to_d -= randint1(e_ptr->max_to_d);
- if (e_ptr->max_to_a)
- o_ptr->to_a -= randint1(e_ptr->max_to_a);
- if (e_ptr->max_pval)
- o_ptr->pval -= randint1(e_ptr->max_pval);
- } else {
- if (is_powerful) {
- if (e_ptr->max_to_h > 0 && o_ptr->to_h < 0)
- o_ptr->to_h = 0 - o_ptr->to_h;
- if (e_ptr->max_to_d > 0 && o_ptr->to_d < 0)
- o_ptr->to_d = 0 - o_ptr->to_d;
- if (e_ptr->max_to_a > 0 && o_ptr->to_a < 0)
- o_ptr->to_a = 0 - o_ptr->to_a;
- }
-
- o_ptr->to_h += (HIT_PROB)randint1_signed(e_ptr->max_to_h);
- o_ptr->to_d += randint1_signed(e_ptr->max_to_d);
- o_ptr->to_a += (ARMOUR_CLASS)randint1_signed(e_ptr->max_to_a);
-
- if (o_ptr->name2 == EGO_ACCURACY) {
- while (o_ptr->to_h < o_ptr->to_d + 10) {
- o_ptr->to_h += 5;
- o_ptr->to_d -= 5;
- }
- o_ptr->to_h = MAX(o_ptr->to_h, 15);
- }
-
- if (o_ptr->name2 == EGO_VELOCITY) {
- while (o_ptr->to_d < o_ptr->to_h + 10) {
- o_ptr->to_d += 5;
- o_ptr->to_h -= 5;
- }
- o_ptr->to_d = MAX(o_ptr->to_d, 15);
- }
-
- if ((o_ptr->name2 == EGO_PROTECTION) || (o_ptr->name2 == EGO_S_PROTECTION) || (o_ptr->name2 == EGO_H_PROTECTION)) {
- o_ptr->to_a = MAX(o_ptr->to_a, 15);
- }
-
- if (e_ptr->max_pval) {
- if ((o_ptr->name2 == EGO_HA) && (has_flag(o_ptr->art_flags, TR_BLOWS))) {
- o_ptr->pval++;
- if ((lev > 60) && one_in_(3) && ((o_ptr->dd * (o_ptr->ds + 1)) < 15))
- o_ptr->pval++;
- } else if (o_ptr->name2 == EGO_DEMON) {
- if (has_flag(o_ptr->art_flags, TR_BLOWS)) {
- o_ptr->pval += randint1(2);
- } else {
- o_ptr->pval += randint1(e_ptr->max_pval);
- }
- } else if (o_ptr->name2 == EGO_ATTACKS) {
- o_ptr->pval = randint1(e_ptr->max_pval * lev / 100 + 1);
- if (o_ptr->pval > 3)
- o_ptr->pval = 3;
- if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA))
- o_ptr->pval += randint1(2);
- } else if (o_ptr->name2 == EGO_BAT) {
- o_ptr->pval = randint1(e_ptr->max_pval);
- if (o_ptr->sval == SV_ELVEN_CLOAK)
- o_ptr->pval += randint1(2);
- } else if (o_ptr->name2 == EGO_A_DEMON || o_ptr->name2 == EGO_DRUID || o_ptr->name2 == EGO_OLOG) {
- o_ptr->pval = randint1(e_ptr->max_pval);
- } else {
- if (e_ptr->max_pval > 0)
- o_ptr->pval += randint1(e_ptr->max_pval);
- else if (e_ptr->max_pval < 0)
- o_ptr->pval -= randint1(0 - e_ptr->max_pval);
- }
- }
-
- if ((o_ptr->name2 == EGO_SPEED) && (lev < 50)) {
- o_ptr->pval = randint1(o_ptr->pval);
- }
-
- if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA) && (o_ptr->pval > 2) && (o_ptr->name2 != EGO_ATTACKS))
- o_ptr->pval = 2;
- }
-
+ apply_ego(owner_ptr, o_ptr, lev);
return;
}
* @details Ego-Item indexes (see "lib/edit/e_info.txt")
*/
#include "object-enchant/object-ego.h"
-#include "object-enchant/trg-types.h"
+#include "object-enchant/object-boost.h"
+#include "object-enchant/object-curse.h"
+#include "object-enchant/special-object-flags.h"
+#include "object-enchant/trc-types.h"
+#include "object-hook/hook-checker.h"
+#include "sv-definition/sv-protector-types.h"
+#include "sv-definition/sv-weapon-types.h"
#include "util/bit-flags-calculator.h"
#include "util/probability-table.h"
#include <vector>
return (EGO_IDX)0;
}
+
+static void ego_invest_curse(player_type* player_ptr, object_type* o_ptr, FlagGroup<TRG>& gen_flags)
+{
+ if (gen_flags.has(TRG::CURSED))
+ o_ptr->curse_flags |= (TRC_CURSED);
+ if (gen_flags.has(TRG::HEAVY_CURSE))
+ o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
+ if (gen_flags.has(TRG::PERMA_CURSE))
+ o_ptr->curse_flags |= (TRC_PERMA_CURSE);
+ if (gen_flags.has(TRG::RANDOM_CURSE0))
+ o_ptr->curse_flags |= get_curse(player_ptr, 0, o_ptr);
+ if (gen_flags.has(TRG::RANDOM_CURSE1))
+ o_ptr->curse_flags |= get_curse(player_ptr, 1, o_ptr);
+ if (gen_flags.has(TRG::RANDOM_CURSE2))
+ o_ptr->curse_flags |= get_curse(player_ptr, 2, o_ptr);
+}
+
+static void ego_invest_extra_abilities(object_type *o_ptr, FlagGroup<TRG> &gen_flags)
+{
+ if (gen_flags.has(TRG::ONE_SUSTAIN))
+ one_sustain(o_ptr);
+ if (gen_flags.has(TRG::XTRA_POWER))
+ one_ability(o_ptr);
+ if (gen_flags.has(TRG::XTRA_H_RES))
+ one_high_resistance(o_ptr);
+ if (gen_flags.has(TRG::XTRA_E_RES))
+ one_ele_resistance(o_ptr);
+ if (gen_flags.has(TRG::XTRA_D_RES))
+ one_dragon_ele_resistance(o_ptr);
+ if (gen_flags.has(TRG::XTRA_L_RES))
+ one_lordly_high_resistance(o_ptr);
+ if (gen_flags.has(TRG::XTRA_RES))
+ one_resistance(o_ptr);
+ if (gen_flags.has(TRG::XTRA_DICE)) {
+ do {
+ o_ptr->dd++;
+ } while (one_in_(o_ptr->dd));
+
+ if (o_ptr->dd > 9)
+ o_ptr->dd = 9;
+ }
+}
+
+static void ego_interpret_extra_abilities(object_type *o_ptr, ego_item_type *e_ptr, FlagGroup<TRG> &gen_flags)
+{
+ for (auto& xtra : e_ptr->xtra_flags) {
+ if (xtra.mul == 0 || xtra.dev == 0)
+ continue;
+
+ if (randint0(xtra.dev) >= xtra.mul) //! @note mul/devで適用
+ continue;
+
+ auto n = xtra.tr_flags.size();
+ if (n > 0) {
+ auto f = xtra.tr_flags[randint0(n)];
+ auto except = (f == TR_VORPAL && o_ptr->tval != TV_SWORD);
+ if (!except)
+ add_flag(o_ptr->art_flags, f);
+ }
+
+ for (auto f : xtra.trg_flags)
+ gen_flags.set(f);
+ }
+}
+
+/*!
+ * @brief 0 および負数に対応した randint1()
+ * @param n
+ *
+ * n == 0 のとき、常に 0 を返す。
+ * n > 0 のとき、[1, n] の乱数を返す。
+ * n < 0 のとき、[n,-1] の乱数を返す。
+ */
+static int randint1_signed(const int n)
+{
+ if (n == 0)
+ return 0;
+
+ return n > 0 ? randint1(n) : -randint1(-n);
+}
+
+void apply_ego(player_type *player_ptr, object_type *o_ptr, DEPTH lev)
+{
+ auto e_ptr = &e_info[o_ptr->name2];
+ auto gen_flags = e_ptr->gen_flags;
+
+ ego_interpret_extra_abilities(o_ptr, e_ptr, gen_flags);
+
+ if (!e_ptr->cost)
+ o_ptr->ident |= (IDENT_BROKEN);
+
+ ego_invest_curse(player_ptr, o_ptr, gen_flags);
+ ego_invest_extra_abilities(o_ptr, gen_flags);
+
+ if (e_ptr->act_idx)
+ o_ptr->xtra2 = (XTRA8)e_ptr->act_idx;
+
+ auto is_powerful = e_ptr->gen_flags.has(TRG::POWERFUL);
+ auto is_cursed = (object_is_cursed(o_ptr) || object_is_broken(o_ptr)) && !is_powerful;
+ if (is_cursed) {
+ if (e_ptr->max_to_h)
+ o_ptr->to_h -= randint1(e_ptr->max_to_h);
+ if (e_ptr->max_to_d)
+ o_ptr->to_d -= randint1(e_ptr->max_to_d);
+ if (e_ptr->max_to_a)
+ o_ptr->to_a -= randint1(e_ptr->max_to_a);
+ if (e_ptr->max_pval)
+ o_ptr->pval -= randint1(e_ptr->max_pval);
+ } else {
+ if (is_powerful) {
+ if (e_ptr->max_to_h > 0 && o_ptr->to_h < 0)
+ o_ptr->to_h = 0 - o_ptr->to_h;
+ if (e_ptr->max_to_d > 0 && o_ptr->to_d < 0)
+ o_ptr->to_d = 0 - o_ptr->to_d;
+ if (e_ptr->max_to_a > 0 && o_ptr->to_a < 0)
+ o_ptr->to_a = 0 - o_ptr->to_a;
+ }
+
+ o_ptr->to_h += (HIT_PROB)randint1_signed(e_ptr->max_to_h);
+ o_ptr->to_d += randint1_signed(e_ptr->max_to_d);
+ o_ptr->to_a += (ARMOUR_CLASS)randint1_signed(e_ptr->max_to_a);
+ if (o_ptr->name2 == EGO_ACCURACY) {
+ while (o_ptr->to_h < o_ptr->to_d + 10) {
+ o_ptr->to_h += 5;
+ o_ptr->to_d -= 5;
+ }
+ o_ptr->to_h = MAX(o_ptr->to_h, 15);
+ }
+
+ if (o_ptr->name2 == EGO_VELOCITY) {
+ while (o_ptr->to_d < o_ptr->to_h + 10) {
+ o_ptr->to_d += 5;
+ o_ptr->to_h -= 5;
+ }
+ o_ptr->to_d = MAX(o_ptr->to_d, 15);
+ }
+
+ if ((o_ptr->name2 == EGO_PROTECTION) || (o_ptr->name2 == EGO_S_PROTECTION) || (o_ptr->name2 == EGO_H_PROTECTION)) {
+ o_ptr->to_a = MAX(o_ptr->to_a, 15);
+ }
+
+ if (e_ptr->max_pval) {
+ if ((o_ptr->name2 == EGO_HA) && (has_flag(o_ptr->art_flags, TR_BLOWS))) {
+ o_ptr->pval++;
+ if ((lev > 60) && one_in_(3) && ((o_ptr->dd * (o_ptr->ds + 1)) < 15))
+ o_ptr->pval++;
+ } else if (o_ptr->name2 == EGO_DEMON) {
+ if (has_flag(o_ptr->art_flags, TR_BLOWS)) {
+ o_ptr->pval += randint1(2);
+ } else {
+ o_ptr->pval += randint1(e_ptr->max_pval);
+ }
+ } else if (o_ptr->name2 == EGO_ATTACKS) {
+ o_ptr->pval = randint1(e_ptr->max_pval * lev / 100 + 1);
+ if (o_ptr->pval > 3)
+ o_ptr->pval = 3;
+ if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA))
+ o_ptr->pval += randint1(2);
+ } else if (o_ptr->name2 == EGO_BAT) {
+ o_ptr->pval = randint1(e_ptr->max_pval);
+ if (o_ptr->sval == SV_ELVEN_CLOAK)
+ o_ptr->pval += randint1(2);
+ } else if (o_ptr->name2 == EGO_A_DEMON || o_ptr->name2 == EGO_DRUID || o_ptr->name2 == EGO_OLOG) {
+ o_ptr->pval = randint1(e_ptr->max_pval);
+ } else {
+ if (e_ptr->max_pval > 0)
+ o_ptr->pval += randint1(e_ptr->max_pval);
+ else if (e_ptr->max_pval < 0)
+ o_ptr->pval -= randint1(0 - e_ptr->max_pval);
+ }
+ }
+
+ if ((o_ptr->name2 == EGO_SPEED) && (lev < 50)) {
+ o_ptr->pval = randint1(o_ptr->pval);
+ }
+
+ if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA) && (o_ptr->pval > 2) && (o_ptr->name2 != EGO_ATTACKS))
+ o_ptr->pval = 2;
+ }
+}
#include "system/angband.h"
+#include "object-enchant/tr-types.h"
#include "object-enchant/trg-types.h"
#include "system/object-type-definition.h"
#include "util/flag-group.h"
#define EGO_AMU_NAIVETY 237
// MAX 240
+struct ego_generate_type {
+ int mul{}; //<! 確率分子
+ int dev{}; //<! 確率分母
+ std::vector<tr_type> tr_flags{};
+ std::vector<TRG> trg_flags{};
+};
+
/*
* Information about "ego-items".
*/
-typedef struct ego_item_type {
- std::string name; /* Name (offset) */
- std::string text; /* Text (offset) */
+struct ego_item_type {
+ std::string name; //!< エゴの名前
+ std::string text; //!< フレーバーテキスト
- INVENTORY_IDX slot{}; /*!< 装備部位 / Standard slot value */
- PRICE rating{}; /*!< ベースアイテムからの価値加速 / Rating boost */
+ INVENTORY_IDX slot{}; //!< 装備部位 / Standard slot value
+ PRICE rating{}; //!< レーティングボーナス(雰囲気に影響) / Rating boost
- DEPTH level{}; /* Minimum level */
- RARITY rarity{}; /* Object rarity */
+ DEPTH level{}; //!< 生成レベル
+ RARITY rarity{}; //<! レアリティ
- HIT_PROB max_to_h{}; /* Maximum to-hit bonus */
- HIT_POINT max_to_d{}; /* Maximum to-dam bonus */
- ARMOUR_CLASS max_to_a{}; /* Maximum to-ac bonus */
+ HIT_PROB max_to_h{}; //!< 最大ボーナス命中修正
+ HIT_POINT max_to_d{}; //!< 最大ボーナスダメージ修正
+ ARMOUR_CLASS max_to_a{}; //!< 最大ボーナスAC修正
- PARAMETER_VALUE max_pval{}; /* Maximum pval */
+ PARAMETER_VALUE max_pval{}; //!< 最大pval
- PRICE cost{}; /* Ego-item "cost" */
+ PRICE cost{}; //!< コスト
- BIT_FLAGS flags[TR_FLAG_SIZE]{}; /* Ego-Item Flags */
- FlagGroup<TRG> gen_flags; /* flags for generate */
+ BIT_FLAGS flags[TR_FLAG_SIZE]{}; //!< 能力/耐性フラグ
+ FlagGroup<TRG> gen_flags; //!< 生成時適用フラグ
+ std::vector<ego_generate_type> xtra_flags{}; //!< 追加能力/耐性フラグ
- IDX act_idx{}; /* Activative ability index */
-} ego_item_type;
+ IDX act_idx{}; //!< 発動番号 / Activative ability index
+};
extern EGO_IDX max_e_idx;
extern std::vector<ego_item_type> e_info;
byte get_random_ego(byte slot, bool good);
+void apply_ego(player_type *player_ptr, object_type *o_ptr, DEPTH lev);