OSDN Git Service

[Refactor] #37353 REALM_* 定義を realm.h へ移動.
[hengband/hengband.git] / src / avatar.c
1 /*!
2     @file avatar.c
3     @brief ウルティマ4を参考にした徳のシステムの実装 / Enable an Ultima IV style "avatar" game where you try to achieve perfection in various virtues.
4     @date 2013/12/23
5     @author
6     Topi Ylinen 1998\n
7     f1toyl@uta.fi\n
8     topi.ylinen@noodi.fi\n
9     \n
10     Copyright (c) 1989 James E. Wilson, Christopher J. Stuart
11     This software may be copied and distributed for educational, research, and
12     not for profit purposes provided that this copyright and statement are
13     included in all such copies.
14 */
15
16 #include "angband.h"
17 #include "avatar.h"
18 #include "realm.h"
19
20 /*!
21  * 徳の名称 / The names of the virtues
22  */
23 concptr virtue[MAX_VIRTUE] =
24 {
25         _("情", "Compassion"),
26         _("誉", "Honour"),
27         _("正", "Justice"),
28         _("犠", "Sacrifice"),
29         _("識", "Knowledge"),
30         _("誠", "Faith"),
31         _("啓", "Enlightenment"),
32         _("秘", "Mysticism"),
33         _("運", "Chance"),
34         _("然", "Nature"),
35         _("調", "Harmony"),
36         _("活", "Vitality"),
37         _("死", "Unlife"),
38         _("忍", "Patience"),
39         _("節", "Temperance"),
40         _("勤", "Diligence"),
41         _("勇", "Valour"),
42         _("個", "Individualism"),
43 };
44
45 /*!
46  * @brief 該当の徳がプレイヤーに指定されているか否かに応じつつ、大小を比較する。
47  * @details 徳がない場合は値0として比較する。
48  * @param type 比較したい徳のID
49  * @param num 比較基準値
50  * @param tekitou VIRTUE_LARGE = 基準値より大きいか / VIRTUE_SMALL = 基準値より小さいか
51  * @return 比較の真偽値を返す
52  * @todo 引数名を直しておく
53  */
54 bool compare_virtue(int type, int num, int tekitou)
55 {
56         int vir;
57         if (virtue_number(type))
58                 vir = p_ptr->virtues[virtue_number(type) - 1];
59         else
60                 vir = 0;
61
62         switch (tekitou)
63         {
64         case VIRTUE_LARGE:
65                 if (vir > num) return TRUE;
66                 else return FALSE;
67         case VIRTUE_SMALL:
68                 if (vir < num) return TRUE;
69                 else return FALSE;
70         }
71
72         return FALSE;
73 }
74
75 /*!
76  * @brief プレイヤーの指定の徳が何番目のスロットに登録されているかを返す。 / Aux function
77  * @param type 確認したい徳のID
78  * @return スロットがあるならばスロットのID(0~7)+1、ない場合は0を返す。
79  */
80 int virtue_number(int type)
81 {
82         int i;
83
84         /* Search */
85         for (i = 0; i < 8; i++)
86         {
87                 if (p_ptr->vir_types[i] == type) return i + 1;
88         }
89
90         /* No match */
91         return 0;
92 }
93
94 /*!
95  * @brief プレイヤーの職業や種族に依存しないランダムな徳を取得する / Aux function
96  * @param which 確認したい徳のID
97  * @return なし
98  */
99 static void get_random_virtue(int which)
100 {
101         int type = 0;
102
103         /* Randomly choose a type */
104         while (!(type) || virtue_number(type))
105         {
106                 switch (randint1(29))
107                 {
108                 case 1: case 2: case 3:
109                         type = V_SACRIFICE;
110                         break;
111                 case 4: case 5: case 6:
112                         type = V_COMPASSION;
113                         break;
114                 case 7: case 8: case 9: case 10: case 11: case 12:
115                         type = V_VALOUR;
116                         break;
117                 case 13: case 14: case 15: case 16: case 17:
118                         type = V_HONOUR;
119                         break;
120                 case 18: case 19: case 20: case 21:
121                         type = V_JUSTICE;
122                         break;
123                 case 22: case 23:
124                         type = V_TEMPERANCE;
125                         break;
126                 case 24: case 25:
127                         type = V_HARMONY;
128                         break;
129                 case 26: case 27: case 28:
130                         type = V_PATIENCE;
131                         break;
132                 default:
133                         type = V_DILIGENCE;
134                         break;
135                 }
136         }
137
138         /* Chosen */
139         p_ptr->vir_types[which] = (s16b)type;
140 }
141
142 /*!
143  * @brief プレイヤーの選んだ魔法領域に応じて対応する徳を返す。
144  * @param realm 魔法領域のID
145  * @return 対応する徳のID
146  */
147 static VIRTUES_IDX get_realm_virtues(REALM_IDX realm)
148 {
149         switch (realm)
150         {
151         case REALM_LIFE:
152                 if (virtue_number(V_VITALITY)) return V_TEMPERANCE;
153                 else return V_VITALITY;
154         case REALM_SORCERY:
155                 if (virtue_number(V_KNOWLEDGE)) return V_ENCHANT;
156                 else return V_KNOWLEDGE;
157         case REALM_NATURE:
158                 if (virtue_number(V_NATURE)) return V_HARMONY;
159                 else return V_NATURE;
160         case REALM_CHAOS:
161                 if (virtue_number(V_CHANCE)) return V_INDIVIDUALISM;
162                 else return V_CHANCE;
163         case REALM_DEATH:
164                 return V_UNLIFE;
165         case REALM_TRUMP:
166                 return V_KNOWLEDGE;
167         case REALM_ARCANE:
168                 return 0;
169         case REALM_CRAFT:
170                 if (virtue_number(V_ENCHANT)) return V_INDIVIDUALISM;
171                 else return V_ENCHANT;
172         case REALM_DAEMON:
173                 if (virtue_number(V_JUSTICE)) return V_FAITH;
174                 else return V_JUSTICE;
175         case REALM_CRUSADE:
176                 if (virtue_number(V_JUSTICE)) return V_HONOUR;
177                 else return V_JUSTICE;
178         case REALM_HEX:
179                 if (virtue_number(V_COMPASSION)) return V_JUSTICE;
180                 else return V_COMPASSION;
181         };
182
183         return 0;
184 }
185
186
187 /*!
188  * @brief 作成中のプレイヤーキャラクターに徳8種類を与える。 / Select virtues & reset values for a new character
189  * @details 職業に応じて1~4種が固定、種族に応じて1種類が与えられ、後は重複なくランダムに選択される。
190  * @return なし
191  */
192 void get_virtues(void)
193 {
194         int i = 0, j = 0;
195         s16b tmp_vir;
196
197         /* Reset */
198         for (i = 0; i < 8; i++)
199         {
200                 p_ptr->virtues[i] = 0;
201                 p_ptr->vir_types[i] = 0;
202         }
203
204         i = 0;
205
206         /* Get pre-defined types */
207         /* 1 or more virtues based on class */
208         switch (p_ptr->pclass)
209         {
210         case CLASS_WARRIOR:
211         case CLASS_SAMURAI:
212                 p_ptr->vir_types[i++] = V_VALOUR;
213                 p_ptr->vir_types[i++] = V_HONOUR;
214                 break;
215         case CLASS_MAGE:
216                 p_ptr->vir_types[i++] = V_KNOWLEDGE;
217                 p_ptr->vir_types[i++] = V_ENCHANT;
218                 break;
219         case CLASS_PRIEST:
220                 p_ptr->vir_types[i++] = V_FAITH;
221                 p_ptr->vir_types[i++] = V_TEMPERANCE;
222                 break;
223         case CLASS_ROGUE:
224         case CLASS_SNIPER:
225                 p_ptr->vir_types[i++] = V_HONOUR;
226                 break;
227         case CLASS_RANGER:
228         case CLASS_ARCHER:
229                 p_ptr->vir_types[i++] = V_NATURE;
230                 p_ptr->vir_types[i++] = V_TEMPERANCE;
231                 break;
232         case CLASS_PALADIN:
233                 p_ptr->vir_types[i++] = V_JUSTICE;
234                 p_ptr->vir_types[i++] = V_VALOUR;
235                 p_ptr->vir_types[i++] = V_HONOUR;
236                 p_ptr->vir_types[i++] = V_FAITH;
237                 break;
238         case CLASS_WARRIOR_MAGE:
239         case CLASS_RED_MAGE:
240                 p_ptr->vir_types[i++] = V_ENCHANT;
241                 p_ptr->vir_types[i++] = V_VALOUR;
242                 break;
243         case CLASS_CHAOS_WARRIOR:
244                 p_ptr->vir_types[i++] = V_CHANCE;
245                 p_ptr->vir_types[i++] = V_INDIVIDUALISM;
246                 break;
247         case CLASS_MONK:
248         case CLASS_FORCETRAINER:
249                 p_ptr->vir_types[i++] = V_FAITH;
250                 p_ptr->vir_types[i++] = V_HARMONY;
251                 p_ptr->vir_types[i++] = V_TEMPERANCE;
252                 p_ptr->vir_types[i++] = V_PATIENCE;
253                 break;
254         case CLASS_MINDCRAFTER:
255         case CLASS_MIRROR_MASTER:
256                 p_ptr->vir_types[i++] = V_HARMONY;
257                 p_ptr->vir_types[i++] = V_ENLIGHTEN;
258                 p_ptr->vir_types[i++] = V_PATIENCE;
259                 break;
260         case CLASS_HIGH_MAGE:
261         case CLASS_SORCERER:
262                 p_ptr->vir_types[i++] = V_ENLIGHTEN;
263                 p_ptr->vir_types[i++] = V_ENCHANT;
264                 p_ptr->vir_types[i++] = V_KNOWLEDGE;
265                 break;
266         case CLASS_TOURIST:
267                 p_ptr->vir_types[i++] = V_ENLIGHTEN;
268                 p_ptr->vir_types[i++] = V_CHANCE;
269                 break;
270         case CLASS_IMITATOR:
271                 p_ptr->vir_types[i++] = V_CHANCE;
272                 break;
273         case CLASS_BLUE_MAGE:
274                 p_ptr->vir_types[i++] = V_CHANCE;
275                 p_ptr->vir_types[i++] = V_KNOWLEDGE;
276                 break;
277         case CLASS_BEASTMASTER:
278                 p_ptr->vir_types[i++] = V_NATURE;
279                 p_ptr->vir_types[i++] = V_CHANCE;
280                 p_ptr->vir_types[i++] = V_VITALITY;
281                 break;
282         case CLASS_MAGIC_EATER:
283                 p_ptr->vir_types[i++] = V_ENCHANT;
284                 p_ptr->vir_types[i++] = V_KNOWLEDGE;
285                 break;
286         case CLASS_BARD:
287                 p_ptr->vir_types[i++] = V_HARMONY;
288                 p_ptr->vir_types[i++] = V_COMPASSION;
289                 break;
290         case CLASS_CAVALRY:
291                 p_ptr->vir_types[i++] = V_VALOUR;
292                 p_ptr->vir_types[i++] = V_HARMONY;
293                 break;
294         case CLASS_BERSERKER:
295                 p_ptr->vir_types[i++] = V_VALOUR;
296                 p_ptr->vir_types[i++] = V_INDIVIDUALISM;
297                 break;
298         case CLASS_SMITH:
299                 p_ptr->vir_types[i++] = V_HONOUR;
300                 p_ptr->vir_types[i++] = V_KNOWLEDGE;
301                 break;
302         case CLASS_NINJA:
303                 p_ptr->vir_types[i++] = V_PATIENCE;
304                 p_ptr->vir_types[i++] = V_KNOWLEDGE;
305                 p_ptr->vir_types[i++] = V_FAITH;
306                 p_ptr->vir_types[i++] = V_UNLIFE;
307                 break;
308         };
309
310         /* Get one virtue based on race */
311         switch (p_ptr->prace)
312         {
313         case RACE_HUMAN: case RACE_HALF_ELF: case RACE_DUNADAN:
314                 p_ptr->vir_types[i++] = V_INDIVIDUALISM;
315                 break;
316         case RACE_ELF: case RACE_SPRITE: case RACE_ENT:
317                 p_ptr->vir_types[i++] = V_NATURE;
318                 break;
319         case RACE_HOBBIT: case RACE_HALF_OGRE:
320                 p_ptr->vir_types[i++] = V_TEMPERANCE;
321                 break;
322         case RACE_DWARF: case RACE_KLACKON: case RACE_ANDROID:
323                 p_ptr->vir_types[i++] = V_DILIGENCE;
324                 break;
325         case RACE_GNOME: case RACE_CYCLOPS:
326                 p_ptr->vir_types[i++] = V_KNOWLEDGE;
327                 break;
328         case RACE_HALF_ORC: case RACE_AMBERITE: case RACE_KOBOLD:
329                 p_ptr->vir_types[i++] = V_HONOUR;
330                 break;
331         case RACE_HALF_TROLL: case RACE_BARBARIAN:
332                 p_ptr->vir_types[i++] = V_VALOUR;
333                 break;
334         case RACE_HIGH_ELF: case RACE_KUTAR:
335                 p_ptr->vir_types[i++] = V_VITALITY;
336                 break;
337         case RACE_HALF_GIANT: case RACE_GOLEM: case RACE_ANGEL: case RACE_DEMON:
338                 p_ptr->vir_types[i++] = V_JUSTICE;
339                 break;
340         case RACE_HALF_TITAN:
341                 p_ptr->vir_types[i++] = V_HARMONY;
342                 break;
343         case RACE_YEEK:
344                 p_ptr->vir_types[i++] = V_SACRIFICE;
345                 break;
346         case RACE_MIND_FLAYER:
347                 p_ptr->vir_types[i++] = V_ENLIGHTEN;
348                 break;
349         case RACE_DARK_ELF: case RACE_DRACONIAN: case RACE_S_FAIRY:
350                 p_ptr->vir_types[i++] = V_ENCHANT;
351                 break;
352         case RACE_NIBELUNG:
353                 p_ptr->vir_types[i++] = V_PATIENCE;
354                 break;
355         case RACE_IMP:
356                 p_ptr->vir_types[i++] = V_FAITH;
357                 break;
358         case RACE_ZOMBIE: case RACE_SKELETON:
359         case RACE_VAMPIRE: case RACE_SPECTRE:
360                 p_ptr->vir_types[i++] = V_UNLIFE;
361                 break;
362         case RACE_BEASTMAN:
363                 p_ptr->vir_types[i++] = V_CHANCE;
364                 break;
365         }
366
367         /* Get a virtue for realms */
368         if (p_ptr->realm1)
369         {
370                 tmp_vir = get_realm_virtues(p_ptr->realm1);
371                 if (tmp_vir) p_ptr->vir_types[i++] = tmp_vir;
372         }
373         if (p_ptr->realm2)
374         {
375                 tmp_vir = get_realm_virtues(p_ptr->realm2);
376                 if (tmp_vir) p_ptr->vir_types[i++] = tmp_vir;
377         }
378
379         /* Eliminate doubles */
380         for (i = 0; i < 8; i++)
381         {
382                 for (j = i + 1; j < 8; j++)
383                 {
384                         if ((p_ptr->vir_types[j] != 0) && (p_ptr->vir_types[j] == p_ptr->vir_types[i]))
385                                 p_ptr->vir_types[j] = 0;
386                 }
387         }
388
389         /* Fill in the blanks */
390         for (i = 0; i < 8; i++)
391         {
392                 if (p_ptr->vir_types[i] == 0) get_random_virtue(i);
393         }
394 }
395
396 /*!
397  * @brief 対応する徳をプレイヤーがスロットに登録している場合に加減を行う。
398  * @details 範囲は-125~125、基本的に絶対値が大きいほど絶対値が上がり辛くなる。
399  * @param virtue 徳のID
400  * @param amount 加減量
401  * @return なし
402  */
403 void chg_virtue(int virtue_id, int amount)
404 {
405         int i = 0;
406
407         for (i = 0; i < 8; i++)
408         {
409                 if (p_ptr->vir_types[i] == virtue_id)
410                 {
411                         if (amount > 0)
412                         {
413                                 if ((amount + p_ptr->virtues[i] > 50) && one_in_(2))
414                                 {
415                                         p_ptr->virtues[i] = MAX(p_ptr->virtues[i], 50);
416                                         return;
417                                 }
418                                 if ((amount + p_ptr->virtues[i] > 80) && one_in_(2))
419                                 {
420                                         p_ptr->virtues[i] = MAX(p_ptr->virtues[i], 80);
421                                         return;
422                                 }
423                                 if ((amount + p_ptr->virtues[i] > 100) && one_in_(2))
424                                 {
425                                         p_ptr->virtues[i] = MAX(p_ptr->virtues[i], 100);
426                                         return;
427                                 }
428                                 if (amount + p_ptr->virtues[i] > 125)
429                                         p_ptr->virtues[i] = 125;
430                                 else
431                                         p_ptr->virtues[i] = p_ptr->virtues[i] + amount;
432                         }
433                         else
434                         {
435                                 if ((amount + p_ptr->virtues[i] < -50) && one_in_(2))
436                                 {
437                                         p_ptr->virtues[i] = MIN(p_ptr->virtues[i], -50);
438                                         return;
439                                 }
440                                 if ((amount + p_ptr->virtues[i] < -80) && one_in_(2))
441                                 {
442                                         p_ptr->virtues[i] = MIN(p_ptr->virtues[i], -80);
443                                         return;
444                                 }
445                                 if ((amount + p_ptr->virtues[i] < -100) && one_in_(2))
446                                 {
447                                         p_ptr->virtues[i] = MIN(p_ptr->virtues[i], -100);
448                                         return;
449                                 }
450                                 if (amount + p_ptr->virtues[i] < -125)
451                                         p_ptr->virtues[i] = -125;
452                                 else
453                                         p_ptr->virtues[i] = p_ptr->virtues[i] + amount;
454                         }
455                         p_ptr->update |= (PU_BONUS);
456                         return;
457                 }
458         }
459 }
460
461 /*!
462  * @brief 対応する徳をプレイヤーがスロットに登録している場合に固定値をセットする。
463  * @param virtue 徳のID
464  * @param amount セットしたい値。
465  * @return なし
466  */
467 void set_virtue(int virtue_id, int amount)
468 {
469         int i = 0;
470
471         for (i = 0; i < 8; i++)
472         {
473                 if (p_ptr->vir_types[i] == virtue_id)
474                 {
475                         p_ptr->virtues[i] = (s16b)amount;
476                         return;
477                 }
478         }
479 }
480
481 /*!
482  * @brief 徳のダンプ表示を行う。
483  * @param OutFile ファイルポインタ。
484  * @return なし
485  */
486 void dump_virtues(FILE *OutFile)
487 {
488         int v_nr = 0;
489
490         if (!OutFile) return;
491
492         for (v_nr = 0; v_nr < 8; v_nr++)
493         {
494                 GAME_TEXT vir_name [20];
495                 int tester = p_ptr->virtues[v_nr];
496
497                 strcpy(vir_name, virtue[(p_ptr->vir_types[v_nr])-1]);
498
499                 if (p_ptr->vir_types[v_nr] == 0 || p_ptr->vir_types[v_nr] > MAX_VIRTUE)
500                         fprintf(OutFile, _("おっと。%sの情報なし。", "Oops. No info about %s."), vir_name);
501
502                 else if (tester < -100)
503                         fprintf(OutFile, _("[%s]の対極", "You are the polar opposite of %s."), vir_name);
504                 else if (tester < -80)
505                         fprintf(OutFile, _("[%s]の大敵", "You are an arch-enemy of %s."), vir_name);
506                 else if (tester < -60)
507                         fprintf(OutFile, _("[%s]の強敵", "You are a bitter enemy of %s."), vir_name);
508                 else if (tester < -40)
509                         fprintf(OutFile, _("[%s]の敵", "You are an enemy of %s."), vir_name);
510                 else if (tester < -20)
511                         fprintf(OutFile, _("[%s]の罪者", "You have sinned against %s."), vir_name);
512                 else if (tester < 0)
513                         fprintf(OutFile, _("[%s]の迷道者", "You have strayed from the path of %s."), vir_name);
514                 else if (tester == 0)
515                         fprintf(OutFile,_("[%s]の中立者", "You are neutral to %s."), vir_name);
516                 else if (tester < 20)
517                         fprintf(OutFile,_("[%s]の小徳者", "You are somewhat virtuous in %s."), vir_name);
518                 else if (tester < 40)
519                         fprintf(OutFile,_("[%s]の中徳者", "You are virtuous in %s."), vir_name);
520                 else if (tester < 60)
521                         fprintf(OutFile,_("[%s]の高徳者", "You are very virtuous in %s."), vir_name);
522                 else if (tester < 80)
523                         fprintf(OutFile,_("[%s]の覇者", "You are a champion of %s."), vir_name);
524                 else if (tester < 100)
525                         fprintf(OutFile,_("[%s]の偉大な覇者", "You are a great champion of %s."), vir_name);
526                 else
527                         fprintf(OutFile,_("[%s]の具現者", "You are the living embodiment of %s."), vir_name);
528
529             fprintf(OutFile, "\n");
530         }
531 }