OSDN Git Service

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