OSDN Git Service

[Feature/Refactor] ハードコーディングされているエゴ生成フラグをe_info.txtで定義できる
authoriks <iks3@users.noreply.github.com>
Fri, 9 Apr 2021 14:11:37 +0000 (23:11 +0900)
committeriks <iks3@users.noreply.github.com>
Fri, 9 Apr 2021 16:38:00 +0000 (01:38 +0900)
一部未対応ものあり。追加攻撃の制御未対応。

lib/edit/e_info.txt
src/info-reader/ego-reader.cpp
src/object-enchant/apply-magic-armor.cpp
src/object-enchant/apply-magic-weapon.cpp
src/object-enchant/apply-magic.cpp
src/object-enchant/object-ego.cpp
src/object-enchant/object-ego.h

index c6c0365..4033ffe 100644 (file)
@@ -71,6 +71,12 @@ F:INT | WIS |
 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
@@ -80,6 +86,13 @@ C:0:0:11:3
 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
@@ -104,6 +117,7 @@ W:0:25:0:12500
 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
 
@@ -197,6 +211,8 @@ W:0:18:0:12500
 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:反射の
@@ -229,6 +245,7 @@ C:0:0:8:2
 F:CON|
 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | XTRA_E_RES
 
+
 ### Crowns and Helms ###
 
 N:23:闇の
@@ -261,6 +278,13 @@ W:0:30:0:12000
 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
 
@@ -311,6 +335,8 @@ X:33:6
 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
@@ -362,6 +388,12 @@ F:STR | INT | WIS | DEX | CON | CHR | HEAVY_CURSE | CURSED | RANDOM_CURSE2 |
 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
@@ -451,6 +483,10 @@ F:STR | CON | CHR |
 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 ###
@@ -519,6 +555,7 @@ E:of Levitation
 X:35:7
 W:0:4:0:250
 F:LEVITATION
+G:1/2:XTRA_H_RES
 
 #J0#
 #J0# 岸さんの訳です
@@ -583,6 +620,7 @@ C:6:6:4:4
 F:WIS | 
 F:SLAY_EVIL | SLAY_UNDEAD | SLAY_DEMON | 
 F:SEE_INVIS | BLESSED | RES_FEAR | ONE_SUSTAIN
+G:1/4:BLOWS
 
 # OneSustain
 
@@ -595,6 +633,8 @@ F:STEALTH |
 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
 
@@ -617,6 +657,7 @@ F:STR | DEX | CON |
 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
@@ -630,6 +671,8 @@ E:of Slaying
 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
@@ -780,6 +823,7 @@ X:24:20
 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:(吸血)
@@ -787,6 +831,7 @@ E:(Vampiric)
 X:24:25
 W:0:18:0:10000
 F:VAMPIRIC | HOLD_EXP
+G:1/5:SLAY_HUMAN
 
 N:97:虹色の
 E:of Prism
@@ -804,6 +849,8 @@ C:4:4:0:2
 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:(パターン)
@@ -814,6 +861,9 @@ C:6:6:0:2
 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# 岸さんの訳です
@@ -834,6 +884,12 @@ W:0:30:0:15000
 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
@@ -845,6 +901,8 @@ F:SLAY_UNDEAD | BRAND_COLD | BRAND_POIS
 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
index 7a08c88..df694b1 100644 (file)
@@ -7,6 +7,7 @@
 #include "util/string-processor.h"
 #include "view/display-messages.h"
 #include <string>
+#include <utility>
 
 /*!
  * @brief テキストトークンを走査してフラグを一つ得る(エゴ用) /
@@ -31,6 +32,25 @@ static bool grab_one_ego_item_flag(ego_item_type *e_ptr, concptr what)
     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
@@ -132,6 +152,35 @@ errr parse_e_info(char *buf, angband_header *head)
 
             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;
     }
index c5f0063..0c30730 100644 (file)
@@ -105,10 +105,6 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
             }
 
             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;
@@ -123,41 +119,7 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
 
                 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."));
@@ -196,21 +158,16 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
             }
 
             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;
             }
         }
 
@@ -252,14 +209,6 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
             }
 
             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);
         }
@@ -318,19 +267,7 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
                 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;
                 }
 
@@ -363,6 +300,7 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
                 case EGO_DARK:
                 case EGO_INFRAVISION:
                 case EGO_H_PROTECTION:
+                case EGO_LITE:
                     break;
                 case EGO_SEEING:
                     if (one_in_(7)) {
@@ -371,13 +309,6 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
                         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...)*/
@@ -395,32 +326,11 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
                 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)
@@ -447,14 +357,6 @@ void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
             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;
             }
 
index 0a20dee..3980a24 100644 (file)
@@ -100,24 +100,6 @@ void apply_magic_weapon(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
             }
 
             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;
@@ -130,27 +112,6 @@ void apply_magic_weapon(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
                         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;
@@ -161,9 +122,7 @@ void apply_magic_weapon(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
                 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;
             }
 
@@ -184,31 +143,6 @@ void apply_magic_weapon(player_type *owner_ptr, object_type *o_ptr, DEPTH level,
 
                     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;
-                }
             }
         }
 
index 36a5231..fbb2d71 100644 (file)
 #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 プレーヤーへの参照ポインタ
@@ -195,133 +177,7 @@ void apply_magic(player_type *owner_ptr, object_type *o_ptr, DEPTH lev, BIT_FLAG
     }
 
     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;
     }
 
index 5f468bd..e1da37a 100644 (file)
@@ -5,7 +5,13 @@
  * @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>
@@ -48,3 +54,183 @@ byte get_random_ego(byte slot, bool good)
 
     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;
+    }
+}
index bc2def3..30fba5c 100644 (file)
@@ -2,6 +2,7 @@
 
 #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);