2 * @brief ランダムアーティファクトの生成 / Artifact code
7 #include "artifact/random-art-generator.h"
8 #include "artifact/random-art-activation.h"
9 #include "artifact/random-art-bias-types.h"
10 #include "artifact/random-art-characteristics.h"
11 #include "artifact/random-art-misc.h"
12 #include "artifact/random-art-pval-investor.h"
13 #include "artifact/random-art-resistance.h"
14 #include "artifact/random-art-slay.h"
15 #include "core/asking-player.h"
16 #include "core/window-redrawer.h"
17 #include "flavor/object-flavor.h"
18 #include "game-option/cheat-types.h"
19 #include "object-enchant/special-object-flags.h"
20 #include "object-enchant/tr-types.h"
21 #include "object-hook/hook-armor.h"
22 #include "object-hook/hook-checker.h"
23 #include "object-hook/hook-weapon.h"
24 #include "object/object-flags.h"
25 #include "object/object-kind-hook.h"
26 #include "object/object-kind.h"
27 #include "object/object-value-calc.h"
28 #include "perception/identification.h"
29 #include "perception/object-perception.h"
30 #include "player/avatar.h"
31 #include "sv-definition/sv-weapon-types.h"
32 #include "util/bit-flags-calculator.h"
33 #include "util/quarks.h"
34 #include "view/display-messages.h"
35 #include "wizard/artifact-bias-table.h"
36 #include "wizard/wizard-messages.h"
37 #include "world/world.h"
39 static bool weakening_artifact(player_type *player_ptr, object_type *o_ptr)
41 KIND_OBJECT_IDX k_idx = lookup_kind(o_ptr->tval, o_ptr->sval);
42 object_kind *k_ptr = &k_info[k_idx];
43 BIT_FLAGS flgs[TR_FLAG_SIZE];
44 object_flags(player_ptr, o_ptr, flgs);
46 if (have_flag(flgs, TR_KILL_EVIL)) {
47 remove_flag(o_ptr->art_flags, TR_KILL_EVIL);
48 add_flag(o_ptr->art_flags, TR_SLAY_EVIL);
52 if (k_ptr->dd < o_ptr->dd) {
57 if (k_ptr->ds < o_ptr->ds) {
62 if (o_ptr->to_d > 10) {
63 o_ptr->to_d = o_ptr->to_d - damroll(1, 6);
64 if (o_ptr->to_d < 10) {
74 static void set_artifact_bias(player_type *player_ptr, object_type *o_ptr, int *warrior_artifact_bias)
76 switch (player_ptr->pclass) {
83 o_ptr->artifact_bias = BIAS_WARRIOR;
88 case CLASS_MAGIC_EATER:
90 o_ptr->artifact_bias = BIAS_MAGE;
93 o_ptr->artifact_bias = BIAS_PRIESTLY;
97 o_ptr->artifact_bias = BIAS_ROGUE;
98 *warrior_artifact_bias = 25;
102 o_ptr->artifact_bias = BIAS_RANGER;
103 *warrior_artifact_bias = 30;
106 o_ptr->artifact_bias = BIAS_PRIESTLY;
107 *warrior_artifact_bias = 40;
109 case CLASS_WARRIOR_MAGE:
111 o_ptr->artifact_bias = BIAS_MAGE;
112 *warrior_artifact_bias = 40;
114 case CLASS_CHAOS_WARRIOR:
115 o_ptr->artifact_bias = BIAS_CHAOS;
116 *warrior_artifact_bias = 40;
119 case CLASS_FORCETRAINER:
120 o_ptr->artifact_bias = BIAS_PRIESTLY;
122 case CLASS_MINDCRAFTER:
125 o_ptr->artifact_bias = BIAS_PRIESTLY;
129 o_ptr->artifact_bias = BIAS_WARRIOR;
133 o_ptr->artifact_bias = BIAS_RANGER;
135 case CLASS_BEASTMASTER:
136 o_ptr->artifact_bias = BIAS_CHR;
137 *warrior_artifact_bias = 50;
139 case CLASS_MIRROR_MASTER:
141 o_ptr->artifact_bias = BIAS_MAGE;
143 o_ptr->artifact_bias = BIAS_ROGUE;
149 static bool decide_random_art_cursed(const bool a_scroll, object_type *o_ptr)
151 if (!a_scroll && one_in_(A_CURSED))
154 if (((o_ptr->tval == TV_AMULET) || (o_ptr->tval == TV_RING)) && object_is_cursed(o_ptr))
160 static int decide_random_art_power(const bool a_cursed)
162 int powers = randint1(5) + 1;
163 while (one_in_(powers) || one_in_(7) || one_in_(10))
166 if (!a_cursed && one_in_(WEIRD_LUCK))
175 static void invest_powers(player_type *player_ptr, object_type *o_ptr, int *powers, bool *has_pval, const bool a_cursed)
177 int max_type = object_is_weapon_ammo(o_ptr) ? 7 : 5;
178 while ((*powers)--) {
179 switch (randint1(max_type)) {
187 if (one_in_(2) && object_is_weapon_ammo(o_ptr) && (o_ptr->tval != TV_BOW)) {
188 if (a_cursed && !one_in_(13))
191 if (one_in_(o_ptr->ds + 4))
194 if (one_in_(o_ptr->dd + 1))
198 random_resistance(o_ptr);
202 random_misc(player_ptr, o_ptr);
209 if (current_world_ptr->wizard)
210 msg_print("Switch error in become_random_artifact!");
217 static void strengthen_pval(object_type *o_ptr)
219 if (have_flag(o_ptr->art_flags, TR_BLOWS)) {
220 o_ptr->pval = randint1(2);
221 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA))
226 } while (o_ptr->pval < randint1(5) || one_in_(o_ptr->pval));
229 if ((o_ptr->pval > 4) && !one_in_(WEIRD_LUCK))
234 * @brief 防具ならばAC修正、武具なら殺戮修正を付与する
235 * @param player_ptr プレーヤーへの参照ポインタ
236 * @param o_ptr ランダムアーティファクトを示すアイテムへの参照ポインタ
239 static void invest_modified_value(player_type *player_ptr, object_type *o_ptr)
241 if (object_is_armour(player_ptr, o_ptr)) {
242 o_ptr->to_a += randint1(o_ptr->to_a > 19 ? 1 : 20 - o_ptr->to_a);
246 if (!object_is_weapon_ammo(o_ptr))
249 o_ptr->to_h += randint1(o_ptr->to_h > 19 ? 1 : 20 - o_ptr->to_h);
250 o_ptr->to_d += randint1(o_ptr->to_d > 19 ? 1 : 20 - o_ptr->to_d);
251 if ((have_flag(o_ptr->art_flags, TR_WIS)) && (o_ptr->pval > 0))
252 add_flag(o_ptr->art_flags, TR_BLESSED);
256 * @brief ランダムアーティファクト生成のメインルーチン
257 * @details 既に生成が済んでいるオブジェクトの構造体を、アーティファクトとして強化する。
258 * @param player_ptr プレーヤーへの参照ポインタ
259 * @param o_ptr 対象のオブジェクト構造体ポインタ
260 * @param a_scroll アーティファクト生成の巻物上の処理。呪いのアーティファクトが生成対象外となる。
261 * @return 常にTRUE(1)を返す
263 bool become_random_artifact(player_type *player_ptr, object_type *o_ptr, bool a_scroll)
265 o_ptr->artifact_bias = 0;
268 for (int i = 0; i < TR_FLAG_SIZE; i++)
269 o_ptr->art_flags[i] |= k_info[o_ptr->k_idx].flags[i];
271 bool has_pval = o_ptr->pval != 0;
272 int warrior_artifact_bias = 0;
273 if (a_scroll && one_in_(4))
274 set_artifact_bias(player_ptr, o_ptr, &warrior_artifact_bias);
276 if (a_scroll && (randint1(100) <= warrior_artifact_bias))
277 o_ptr->artifact_bias = BIAS_WARRIOR;
279 GAME_TEXT new_name[1024];
280 strcpy(new_name, "");
282 bool a_cursed = decide_random_art_cursed(a_scroll, o_ptr);
283 int powers = decide_random_art_power(a_cursed);
284 int max_powers = powers;
285 invest_powers(player_ptr, o_ptr, &powers, &has_pval, a_cursed);
287 strengthen_pval(o_ptr);
289 invest_modified_value(player_ptr, o_ptr);
290 add_flag(o_ptr->art_flags, TR_IGNORE_ACID);
291 add_flag(o_ptr->art_flags, TR_IGNORE_ELEC);
292 add_flag(o_ptr->art_flags, TR_IGNORE_FIRE);
293 add_flag(o_ptr->art_flags, TR_IGNORE_COLD);
295 s32b total_flags = flag_cost(player_ptr, o_ptr, o_ptr->pval);
297 curse_artifact(player_ptr, o_ptr);
299 if (!a_cursed && one_in_(object_is_armour(player_ptr, o_ptr) ? ACTIVATION_CHANCE * 2 : ACTIVATION_CHANCE)) {
301 give_activation_power(o_ptr);
304 if (object_is_armour(player_ptr, o_ptr)) {
305 while ((o_ptr->to_d + o_ptr->to_h) > 20) {
306 if (one_in_(o_ptr->to_d) && one_in_(o_ptr->to_h))
308 o_ptr->to_d -= (HIT_POINT)randint0(3);
309 o_ptr->to_h -= (HIT_PROB)randint0(3);
311 while ((o_ptr->to_d + o_ptr->to_h) > 10) {
312 if (one_in_(o_ptr->to_d) || one_in_(o_ptr->to_h))
314 o_ptr->to_d -= (HIT_POINT)randint0(3);
315 o_ptr->to_h -= (HIT_PROB)randint0(3);
319 if (((o_ptr->artifact_bias == BIAS_MAGE) || (o_ptr->artifact_bias == BIAS_INT)) && (o_ptr->tval == TV_GLOVES))
320 add_flag(o_ptr->art_flags, TR_FREE_ACT);
322 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) {
325 remove_flag(o_ptr->art_flags, TR_BLOWS);
326 remove_flag(o_ptr->art_flags, TR_FORCE_WEAPON);
327 remove_flag(o_ptr->art_flags, TR_SLAY_ANIMAL);
328 remove_flag(o_ptr->art_flags, TR_SLAY_EVIL);
329 remove_flag(o_ptr->art_flags, TR_SLAY_UNDEAD);
330 remove_flag(o_ptr->art_flags, TR_SLAY_DEMON);
331 remove_flag(o_ptr->art_flags, TR_SLAY_ORC);
332 remove_flag(o_ptr->art_flags, TR_SLAY_TROLL);
333 remove_flag(o_ptr->art_flags, TR_SLAY_GIANT);
334 remove_flag(o_ptr->art_flags, TR_SLAY_DRAGON);
335 remove_flag(o_ptr->art_flags, TR_KILL_DRAGON);
336 remove_flag(o_ptr->art_flags, TR_SLAY_HUMAN);
337 remove_flag(o_ptr->art_flags, TR_VORPAL);
338 remove_flag(o_ptr->art_flags, TR_BRAND_POIS);
339 remove_flag(o_ptr->art_flags, TR_BRAND_ACID);
340 remove_flag(o_ptr->art_flags, TR_BRAND_ELEC);
341 remove_flag(o_ptr->art_flags, TR_BRAND_FIRE);
342 remove_flag(o_ptr->art_flags, TR_BRAND_COLD);
346 if (!object_is_weapon_ammo(o_ptr)) {
349 else if (total_flags < 15000)
351 else if (total_flags < 35000)
358 else if (total_flags < 20000)
360 else if (total_flags < 45000)
366 while (has_extreme_damage_rate(player_ptr, o_ptr) && !one_in_(SWORDFISH_LUCK))
367 weakening_artifact(player_ptr, o_ptr);
370 GAME_TEXT dummy_name[MAX_NLEN] = "";
371 concptr ask_msg = _("このアーティファクトを何と名付けますか?", "What do you want to call the artifact? ");
372 object_aware(player_ptr, o_ptr);
374 o_ptr->ident |= IDENT_FULL_KNOWN;
375 o_ptr->art_name = quark_add("");
376 (void)screen_object(player_ptr, o_ptr, 0L);
377 if (!get_string(ask_msg, dummy_name, sizeof dummy_name) || !dummy_name[0]) {
380 get_table_sindarin_aux(dummy_name);
382 get_table_name_aux(dummy_name);
386 sprintf(new_name, _("《%s》", "'%s'"), dummy_name);
387 chg_virtue(player_ptr, V_INDIVIDUALISM, 2);
388 chg_virtue(player_ptr, V_ENCHANT, 5);
390 get_random_name(o_ptr, new_name, object_is_armour(player_ptr, o_ptr), power_level);
393 o_ptr->art_name = quark_add(new_name);
394 msg_format_wizard(player_ptr, CHEAT_OBJECT,
395 _("パワー %d で 価値%ld のランダムアーティファクト生成 バイアスは「%s」", "Random artifact generated - Power:%d Value:%d Bias:%s."), max_powers,
396 total_flags, artifact_bias_name[o_ptr->artifact_bias]);
397 player_ptr->window |= PW_INVEN | PW_EQUIP;