heng_th_katte_1_1_95/src/files.c


/* File: files.c */

/*
* Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
*
* This software may be copied and distributed for educational, research,
* and not for profit purposes provided that this copyright and statement
* are included in all such copies. Other copyrights may also apply.
*/

/* Purpose: code dealing with files (and death) */

#include "angband.h"


/*
* You may or may not want to use the following "#undef".
*/
/* #undef _POSIX_SAVED_IDS */


/*
* Hack -- drop permissions
*/
void safe_setuid_drop(void)
{

#ifdef SET_UID

# ifdef SAFE_SETUID

# ifdef SAFE_SETUID_POSIX

if (setuid(getuid()) != 0)
{
#ifdef JP
quit("setuid(): 正しく許可が取れません!");
#else
quit("setuid(): cannot set permissions correctly!");
#endif

}
if (setgid(getgid()) != 0)
{
#ifdef JP
quit("setgid(): 正しく許可が取れません!");
#else
quit("setgid(): cannot set permissions correctly!");
#endif

}

# else

if (setreuid(geteuid(), getuid()) != 0)
{
#ifdef JP
quit("setreuid(): 正しく許可が取れません!");
#else
quit("setreuid(): cannot set permissions correctly!");
#endif

}
if (setregid(getegid(), getgid()) != 0)
{
#ifdef JP
quit("setregid(): 正しく許可が取れません!");
#else
quit("setregid(): cannot set permissions correctly!");
#endif

}

# endif

# endif

#endif

}


/*
* Hack -- grab permissions
*/
/*:::たぶんUnixやLinux用の権限確認 */
void safe_setuid_grab(void)
{

#ifdef SET_UID

# ifdef SAFE_SETUID

# ifdef SAFE_SETUID_POSIX

if (setuid(player_euid) != 0)
{
#ifdef JP
quit("setuid(): 正しく許可が取れません!");
#else
quit("setuid(): cannot set permissions correctly!");
#endif

}
if (setgid(player_egid) != 0)
{
#ifdef JP
quit("setgid(): 正しく許可が取れません!");
#else
quit("setgid(): cannot set permissions correctly!");
#endif

}

# else

if (setreuid(geteuid(), getuid()) != 0)
{
#ifdef JP
quit("setreuid(): 正しく許可が取れません!");
#else
quit("setreuid(): cannot set permissions correctly!");
#endif

}
if (setregid(getegid(), getgid()) != 0)
{
#ifdef JP
quit("setregid(): 正しく許可が取れません!");
#else
quit("setregid(): cannot set permissions correctly!");
#endif

}

# endif /* SAFE_SETUID_POSIX */

# endif /* SAFE_SETUID */

#endif /* SET_UID */

}


/*
* Extract the first few "tokens" from a buffer
*
* This function uses "colon" and "slash" as the delimeter characters.
*
* We never extract more than "num" tokens. The "last" token may include
* "delimeter" characters, allowing the buffer to include a "string" token.
*
* We save pointers to the tokens in "tokens", and return the number found.
*
* Hack -- Attempt to handle the 'c' character formalism
*
* Hack -- An empty buffer, or a final delimeter, yields an "empty" token.
*
* Hack -- We will always extract at least one token
*/
/*::: ":"か"/"で区切られた文字列を分割して**tokenに格納し、その数を返す num以上の部分は無視される */
s16b tokenize(char *buf, s16b num, char **tokens, int mode)
{
int i = 0;

char *s = buf;


/* Process */
while (i < num - 1)
{
char *t;

/* Scan the string */
for (t = s; *t; t++)
{
/* Found a delimiter */
if ((*t == ':') || (*t == '/')) break;

/* Handle single quotes */
/*:::TOKENIZE_CHECKQUOTE=0x01*/
/*:::modeにこの数値が入っているときは'や\に何らかの処理をするらしい?どんなふうに使うのかどうも分からん*/
if ((mode & TOKENIZE_CHECKQUOTE) && (*t == '\''))
{
/* Advance */
t++;

/* Handle backslash */
if (*t == '\\') t++;

/* Require a character */
if (!*t) break;

/* Advance */
t++;

/* Hack -- Require a close quote */
if (*t != '\'') *t = '\'';
}

/* Handle back-slash */
if (*t == '\\') t++;
}

/* Nothing left */
if (!*t) break;

/* Nuke and advance */
/*:::ここでsに\0が入ってtokens一つ分が一つの文字列として独立した?*/
*t++ = '\0';

/* Save the token */
tokens[i++] = s;

/* Advance */
s = t;
}

/* Save the token */
tokens[i++] = s;

/* Number found */
return (i);
}


/* A number with a name */
typedef struct named_num named_num;

struct named_num
{
cptr name; /* The name of this thing */
int num; /* A number associated with it */
};

///mod131229 GF_xxxの追加
//spell.xx.prfの記述と内部的なGF_XXXの値を対応付けるための表
//GF_XXXの順番どおりでなくてもいいがなるべく揃えときたい
/* Index of spell type names */
static named_num gf_desc[] =
{
{"GF_ELEC", GF_ELEC },
{"GF_POIS", GF_POIS },
{"GF_ACID", GF_ACID },
{"GF_COLD", GF_COLD },
{"GF_FIRE", GF_FIRE },
{"GF_PSY_SPEAR", GF_PSY_SPEAR },
{"GF_MISSILE", GF_MISSILE },
{"GF_ARROW", GF_ARROW },
{"GF_PLASMA", GF_PLASMA },
{"GF_WATER", GF_WATER },
{"GF_LITE", GF_LITE },
{"GF_DARK", GF_DARK },
{"GF_LITE_WEAK", GF_LITE_WEAK },
{"GF_DARK_WEAK", GF_DARK_WEAK },
{"GF_SHARDS", GF_SHARDS },
{"GF_SOUND", GF_SOUND },
{"GF_CONFUSION", GF_CONFUSION },
{"GF_FORCE", GF_FORCE },
{"GF_INACT", GF_INACT },
{"GF_MANA", GF_MANA },
{"GF_METEOR", GF_METEOR },
{"GF_ICE", GF_ICE },
{"GF_CHAOS", GF_CHAOS },
//30
{"GF_NETHER", GF_NETHER },
{"GF_DISENCHANT", GF_DISENCHANT },
{"GF_NEXUS", GF_NEXUS },
{"GF_TIME", GF_TIME },
{"GF_GRAVITY", GF_GRAVITY },
{"GF_DEC_ATK", GF_DEC_ATK },
{"GF_DEC_DEF", GF_DEC_DEF },
{"GF_DEC_MAG", GF_DEC_MAG },
{"GF_DEC_ALL", GF_DEC_ALL },
{"GF_KILL_WALL", GF_KILL_WALL },
{"GF_KILL_DOOR", GF_KILL_DOOR },
{"GF_KILL_TRAP", GF_KILL_TRAP },
{ "GF_NO_MOVE", GF_NO_MOVE },
{ "GF_BERSERK", GF_BERSERK },
{ "GF_SUPER_EGO", GF_SUPER_EGO },

{"GF_MAKE_DOOR", GF_MAKE_DOOR },
{"GF_MAKE_TRAP", GF_MAKE_TRAP },
{"GF_MAKE_TREE", GF_MAKE_TREE },
{ "GF_DIG_OIL", GF_DIG_OIL },
{ "GF_ALCOHOL", GF_ALCOHOL },

{"GF_OLD_CLONE", GF_OLD_CLONE },
{"GF_OLD_POLY", GF_OLD_POLY },
{"GF_OLD_HEAL", GF_OLD_HEAL },
{"GF_OLD_SPEED", GF_OLD_SPEED },
{"GF_OLD_SLOW", GF_OLD_SLOW },
{"GF_OLD_CONF", GF_OLD_CONF },
{"GF_OLD_SLEEP", GF_OLD_SLEEP },
{"GF_OLD_DRAIN", GF_OLD_DRAIN },
{"GF_AWAY_UNDEAD", GF_AWAY_UNDEAD },
{"GF_AWAY_EVIL", GF_AWAY_EVIL },
{"GF_AWAY_ALL", GF_AWAY_ALL },
{"GF_TURN_UNDEAD", GF_TURN_UNDEAD },
{"GF_TURN_EVIL", GF_TURN_EVIL },
{"GF_TURN_ALL", GF_TURN_ALL },
{"GF_DISP_UNDEAD", GF_DISP_UNDEAD },
{"GF_DISP_EVIL", GF_DISP_EVIL },
{"GF_DISP_ALL", GF_DISP_ALL },
{"GF_DISP_DEMON", GF_DISP_DEMON },
{"GF_DISP_LIVING", GF_DISP_LIVING },
{"GF_ROCKET", GF_ROCKET },
{"GF_NUKE", GF_NUKE },
{"GF_MAKE_GLYPH", GF_MAKE_GLYPH },
{"GF_STASIS", GF_STASIS },
{"GF_STONE_WALL", GF_STONE_WALL },
{"GF_DEATH_RAY", GF_DEATH_RAY },
{"GF_STUN", GF_STUN },
{"GF_HOLY_FIRE", GF_HOLY_FIRE },
{"GF_HELL_FIRE", GF_HELL_FIRE },
{"GF_DISINTEGRATE", GF_DISINTEGRATE },
{"GF_CHARM", GF_CHARM },
{"GF_CONTROL_UNDEAD", GF_CONTROL_UNDEAD },
{"GF_CONTROL_ANIMAL", GF_CONTROL_ANIMAL },
{"GF_PSI", GF_PSI },
{"GF_PSI_DRAIN", GF_PSI_DRAIN },
{"GF_TELEKINESIS", GF_TELEKINESIS },
{"GF_JAM_DOOR", GF_JAM_DOOR },
{"GF_DOMINATION", GF_DOMINATION },
{"GF_DISP_GOOD", GF_DISP_GOOD },
{"GF_DRAIN_MANA", GF_DRAIN_MANA },
{"GF_MIND_BLAST", GF_MIND_BLAST },
{"GF_BRAIN_SMASH", GF_BRAIN_SMASH },
{"GF_CAUSE_1", GF_CAUSE_1 },
{"GF_CAUSE_2", GF_CAUSE_2 },
{"GF_CAUSE_3", GF_CAUSE_3 },
{"GF_CAUSE_4", GF_CAUSE_4 },
{"GF_HAND_DOOM", GF_HAND_DOOM },
{"GF_CAPTURE", GF_CAPTURE },
{"GF_ANIM_DEAD", GF_ANIM_DEAD },
{"GF_CONTROL_LIVING", GF_CONTROL_LIVING },
{"GF_IDENTIFY", GF_IDENTIFY },
{"GF_ATTACK", GF_ATTACK },
{"GF_ENGETSU", GF_ENGETSU },
{"GF_GENOCIDE", GF_GENOCIDE },
{"GF_PHOTO", GF_PHOTO },
{"GF_CONTROL_DEMON", GF_CONTROL_DEMON },
{"GF_LAVA_FLOW", GF_LAVA_FLOW },
{"GF_BLOOD_CURSE", GF_BLOOD_CURSE },
{"GF_SEEKER", GF_SEEKER },
{"GF_SUPER_RAY", GF_SUPER_RAY },
{"GF_STAR_HEAL", GF_STAR_HEAL },
{"GF_WATER_FLOW", GF_WATER_FLOW },
{"GF_CRUSADE", GF_CRUSADE },
{"GF_STASIS_EVIL", GF_STASIS_EVIL },
{"GF_WOUNDS", GF_WOUNDS },
{"GF_DISTORTION", GF_DISTORTION },
{"GF_COSMIC_HORROR", GF_COSMIC_HORROR },
{"GF_PUNISH_1", GF_PUNISH_1 },
{"GF_PUNISH_2", GF_PUNISH_2 },
{"GF_PUNISH_3", GF_PUNISH_3 },
{"GF_PUNISH_4", GF_PUNISH_4 },
{"GF_POLLUTE", GF_POLLUTE },
{"GF_TORNADO", GF_TORNADO },
{"GF_KYUTTOSHITEDOKA_N",GF_KYUTTOSHITEDOKA_N},
{"GF_WINDCUTTER", GF_WINDCUTTER },
{"GF_REDEYE", GF_REDEYE },
{"GF_RYUURI", GF_RYUURI },
{"GF_POSSESSION", GF_POSSESSION },
{"GF_SOULSTEAL", GF_SOULSTEAL },
{"GF_NIGHTMARE", GF_NIGHTMARE },
{"GF_TRAIN", GF_TRAIN },
{"GF_DISP_KWAI", GF_DISP_KWAI },
{"GF_NORTHERN", GF_NORTHERN },
{"GF_BANKI_BEAM", GF_BANKI_BEAM },
{"GF_N_E_P", GF_N_E_P },
{"GF_HOUTOU", GF_HOUTOU },
{"GF_BANKI_BEAM2", GF_BANKI_BEAM2 },
{"GF_CHARM_PALADIN", GF_CHARM_PALADIN },
{"GF_SATORI", GF_SATORI },
{"GF_MAKE_FLOWER", GF_MAKE_FLOWER },
{"GF_KOKORO", GF_KOKORO },
{"GF_MOSES", GF_MOSES },
{"GF_REDMAGIC", GF_REDMAGIC },
{"GF_GUNGNIR", GF_GUNGNIR },
{"GF_WALL_TO_DOOR", GF_WALL_TO_DOOR },
{"GF_STASIS_DRAGON", GF_STASIS_DRAGON },
{"GF_CHARM_C", GF_CHARM_C },
{"GF_CHARM_J", GF_CHARM_J },
{"GF_CHARM_B", GF_CHARM_B },
{"GF_MAKE_SPIDER_NEST", GF_MAKE_SPIDER_NEST},
{"GF_THROW_PLATE", GF_THROW_PLATE},
{"GF_BLAZINGSTAR", GF_BLAZINGSTAR},
{"GF_SOULSCULPTURE", GF_SOULSCULPTURE},
{"GF_YAKU", GF_YAKU},
{"GF_STEAM", GF_STEAM},
{"GF_SEIRAN_BEAM", GF_SEIRAN_BEAM},
{"GF_PURIFY", GF_PURIFY},
{"GF_SPECIAL_SHOT", GF_SPECIAL_SHOT},
{"GF_YOUMU", GF_YOUMU},
{"GF_STASIS_LIVING", GF_STASIS_LIVING },
{ "GF_LUNATIC_TORCH", GF_LUNATIC_TORCH },
{ "GF_BRAIN_FINGER_PRINT", GF_BRAIN_FINGER_PRINT },
{ "GF_RAINBOW", GF_RAINBOW },
{ "GF_CONTROL_FISH", GF_CONTROL_FISH },
{ "GF_MAKE_BLIZZARD", GF_MAKE_BLIZZARD },
{ "GF_MAKE_POISON_PUDDLE", GF_MAKE_POISON_PUDDLE },
{ "GF_MAKE_ACID_PUDDLE", GF_MAKE_ACID_PUDDLE },
{ "GF_MAKE_STORM", GF_MAKE_STORM },



{NULL, 0 }
};


/*
* Parse a sub-file of the "extra info" (format shown below)
*
* Each "action" line has an "action symbol" in the first column,
* followed by a colon, followed by some command specific info,
* usually in the form of "tokens" separated by colons or slashes.
*
* Blank lines, lines starting with white space, and lines starting
* with pound signs ("#") are ignored (as comments).
*
* Note the use of "tokenize()" to allow the use of both colons and
* slashes as delimeters, while still allowing final tokens which
* may contain any characters including "delimiters".
*
* Note the use of "strtol()" to allow all "integers" to be encoded
* in decimal, hexidecimal, or octal form.
*
* Note that "monster zero" is used for the "player" attr/char, "object
* zero" will be used for the "stack" attr/char, and "feature zero" is
* used for the "nothing" attr/char.
*
* Parse another file recursively, see below for details
* %:<filename>
*
* Specify the attr/char values for "monsters" by race index
* R:<num>:<a>:<c>
*
* Specify the attr/char values for "objects" by kind index
* K:<num>:<a>:<c>
*
* Specify the attr/char values for "features" by feature index
* F:<num>:<a>:<c>
*
* Specify the attr/char values for unaware "objects" by kind tval
* U:<tv>:<a>:<c>
*
* Specify the attr/char values for inventory "objects" by kind tval
* E:<tv>:<a>:<c>
*
* Define a macro action, given an encoded macro action
* A:<str>
*
* Create a normal macro, given an encoded macro trigger
* P:<str>
*
* Create a command macro, given an encoded macro trigger
* C:<str>
*
* Create a keyset mapping
* S:<key>:<key>:<dir>
*
* Turn an option off, given its name
* X:<str>
*
* Turn an option on, given its name
* Y:<str>
*
* Specify visual information, given an index, and some data
* V:<num>:<kv>:<rv>:<gv>:<bv>
*
* Specify the set of colors to use when drawing a zapped spell
* Z:<type>:<str>
*
* Specify a macro trigger template and macro trigger names.
* T:<template>:<modifier chr>:<modifier name1>:<modifier name2>:...
* T:<trigger>:<keycode>:<shift-keycode>
*
*/

/*:::設定変更コマンドの解釈部*/
errr process_pref_file_command(char *buf)
{
int i, j, n1, n2;

char *zz[16];


/* Require "?:*" format */
if (buf[1] != ':') return 1;


switch (buf[0])
{
/* Mega-Hack -- read external player's history file */
/* Process "H:<history>" */
case 'H':
add_history_from_pref_line(buf + 2);
return 0;

/* Process "R:<num>:<a>/<c>" -- attr/char for monster races */
case 'R':
if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
{
monster_race *r_ptr;
i = (huge)strtol(zz[0], NULL, 0);
n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
if (i >= max_r_idx) return 1;
r_ptr = &r_info[i];
if (n1 || (!(n2 & 0x80) && n2)) r_ptr->x_attr = n1; /* Allow TERM_DARK text */
if (n2) r_ptr->x_char = n2;
return 0;
}
break;

/* Process "K:<num>:<a>/<c>" -- attr/char for object kinds */
case 'K':
if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
{
object_kind *k_ptr;
i = (huge)strtol(zz[0], NULL, 0);
n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
if (i >= max_k_idx) return 1;
k_ptr = &k_info[i];
if (n1 || (!(n2 & 0x80) && n2)) k_ptr->x_attr = n1; /* Allow TERM_DARK text */
if (n2) k_ptr->x_char = n2;
return 0;
}
break;

/* Process "F:<num>:<a>/<c>" -- attr/char for terrain features */
/* "F:<num>:<a>/<c>" */
/* "F:<num>:<a>/<c>:LIT" */
/* "F:<num>:<a>/<c>:<la>/<lc>:<da>/<dc>" */
case 'F':
{
feature_type *f_ptr;
int num = tokenize(buf + 2, F_LIT_MAX * 2 + 1, zz, TOKENIZE_CHECKQUOTE);

if ((num != 3) && (num != 4) && (num != F_LIT_MAX * 2 + 1)) return 1;
else if ((num == 4) && !streq(zz[3], "LIT")) return 1;

i = (huge)strtol(zz[0], NULL, 0);
if (i >= max_f_idx) return 1;
f_ptr = &f_info[i];

n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
if (n1 || (!(n2 & 0x80) && n2)) f_ptr->x_attr[F_LIT_STANDARD] = n1; /* Allow TERM_DARK text */
if (n2) f_ptr->x_char[F_LIT_STANDARD] = n2;

/* Mega-hack -- feat supports lighting */
switch (num)
{
/* No lighting support */
case 3:
n1 = f_ptr->x_attr[F_LIT_STANDARD];
n2 = f_ptr->x_char[F_LIT_STANDARD];
for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
{
f_ptr->x_attr[j] = n1;
f_ptr->x_char[j] = n2;
}
break;

/* Use default lighting */
case 4:
apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
break;

/* Use desired lighting */
case F_LIT_MAX * 2 + 1:
for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
{
n1 = strtol(zz[j * 2 + 1], NULL, 0);
n2 = strtol(zz[j * 2 + 2], NULL, 0);
if (n1 || (!(n2 & 0x80) && n2)) f_ptr->x_attr[j] = n1; /* Allow TERM_DARK text */
if (n2) f_ptr->x_char[j] = n2;
}
break;
}
}
return 0;

/* Process "S:<num>:<a>/<c>" -- attr/char for special things */
case 'S':
if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
{
j = (byte)strtol(zz[0], NULL, 0);
n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
misc_to_attr[j] = n1;
misc_to_char[j] = n2;
return 0;
}
break;

/* Process "U:<tv>:<a>/<c>" -- attr/char for unaware items */
case 'U':
if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
{
j = (huge)strtol(zz[0], NULL, 0);
n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
for (i = 1; i < max_k_idx; i++)
{
object_kind *k_ptr = &k_info[i];
if (k_ptr->tval == j)
{
if (n1) k_ptr->d_attr = n1;
if (n2) k_ptr->d_char = n2;
}
}
return 0;
}
break;

/* Process "E:<tv>:<a>" -- attribute for inventory objects */
case 'E':
if (tokenize(buf+2, 2, zz, TOKENIZE_CHECKQUOTE) == 2)
{
j = (byte)strtol(zz[0], NULL, 0) % 128;
n1 = strtol(zz[1], NULL, 0);
if (n1) tval_to_attr[j] = n1;
return 0;
}
break;

/* Process "A:<str>" -- save an "action" for later */
case 'A':
text_to_ascii(macro__buf, buf+2);
return 0;

/* Process "P:<str>" -- normal macro */
case 'P':
{
char tmp[1024];

text_to_ascii(tmp, buf+2);
macro_add(tmp, macro__buf);
return 0;
}

/* Process "C:<str>" -- create keymap */
case 'C':
{
int mode;
char tmp[1024];

if (tokenize(buf+2, 2, zz, TOKENIZE_CHECKQUOTE) != 2) return 1;

mode = strtol(zz[0], NULL, 0);
if ((mode < 0) || (mode >= KEYMAP_MODES)) return 1;

text_to_ascii(tmp, zz[1]);
if (!tmp[0] || tmp[1]) return 1;
i = (byte)(tmp[0]);

string_free(keymap_act[mode][i]);

keymap_act[mode][i] = string_make(macro__buf);

return 0;
}

/* Process "V:<num>:<kv>:<rv>:<gv>:<bv>" -- visual info */
case 'V':
if (tokenize(buf+2, 5, zz, TOKENIZE_CHECKQUOTE) == 5)
{
i = (byte)strtol(zz[0], NULL, 0);
angband_color_table[i][0] = (byte)strtol(zz[1], NULL, 0);
angband_color_table[i][1] = (byte)strtol(zz[2], NULL, 0);
angband_color_table[i][2] = (byte)strtol(zz[3], NULL, 0);
angband_color_table[i][3] = (byte)strtol(zz[4], NULL, 0);
return 0;
}
break;

/* Process "X:<str>" -- turn option off */
/* Process "Y:<str>" -- turn option on */
case 'X':
case 'Y':
for (i = 0; option_info[i].o_desc; i++)
{
if (option_info[i].o_var &&
option_info[i].o_text &&
streq(option_info[i].o_text, buf + 2))
{
int os = option_info[i].o_set;
int ob = option_info[i].o_bit;

if ((p_ptr->playing || character_xtra) &&
(OPT_PAGE_BIRTH == option_info[i].o_page) && !p_ptr->wizard)
{
#ifdef JP
msg_format("初期オプションは変更できません! '%s'", buf);
#else
msg_format("Birth options can not changed! '%s'", buf);
#endif
msg_print(NULL);
return 0;
}

if (buf[0] == 'X')
{
/* Clear */
option_flag[os] &= ~(1L << ob);
(*option_info[i].o_var) = FALSE;
}
else
{
/* Set */
option_flag[os] |= (1L << ob);
(*option_info[i].o_var) = TRUE;
}
return 0;
}
}

/* don't know that option. ignore it.*/
#ifdef JP
msg_format("オプションの名前が正しくありません: %s", buf);
#else
msg_format("Ignored invalid option: %s", buf);
#endif
msg_print(NULL);
return 0;

/* Process "Z:<type>:<str>" -- set spell color */
/*:::魔法などの属性ごとの色設定部分 spell-xx.prf*/
case 'Z':
{
/* Find the colon */
char *t = my_strchr(buf + 2, ':');

/* Oops */
if (!t) return 1;

/* Nuke the colon */
*(t++) = '\0';

for (i = 0; gf_desc[i].name; i++)
{
/* Match this type */
if (streq(gf_desc[i].name, buf + 2))
{
/* Remember this color set */
gf_color[gf_desc[i].num] = quark_add(t);

/* Success */
return 0;
}
}

break;
}

/* Initialize macro trigger names and a template */
/* Process "T:<trigger>:<keycode>:<shift-keycode>" */
/* Process "T:<template>:<modifier chr>:<modifier name>:..." */
case 'T':
{
int tok = tokenize(buf+2, 2+MAX_MACRO_MOD, zz, 0);

/* Process "T:<template>:<modifier chr>:<modifier name>:..." */
if (tok >= 4)
{
int num;

if (macro_template != NULL)
{
num = strlen(macro_modifier_chr);

/* Kill the template string */
string_free(macro_template);
macro_template = NULL;

/* Kill flag characters of modifier keys */
string_free(macro_modifier_chr);

/* Kill corresponding modifier names */
for (i = 0; i < num; i++)
{
string_free(macro_modifier_name[i]);
}

/* Kill trigger name strings */
for (i = 0; i < max_macrotrigger; i++)
{
string_free(macro_trigger_name[i]);
string_free(macro_trigger_keycode[0][i]);
string_free(macro_trigger_keycode[1][i]);
}

max_macrotrigger = 0;
}

if (*zz[0] == '\0') return 0; /* clear template */

/* Number of modifier flags */
num = strlen(zz[1]);

/* Limit the number */
num = MIN(MAX_MACRO_MOD, num);

/* Stop if number of modifier is not correct */
if (2 + num != tok) return 1;

/* Get a template string */
macro_template = string_make(zz[0]);

/* Get flag characters of modifier keys */
macro_modifier_chr = string_make(zz[1]);

/* Get corresponding modifier names */
for (i = 0; i < num; i++)
{
macro_modifier_name[i] = string_make(zz[2+i]);
}
}

/* Process "T:<trigger>:<keycode>:<shift-keycode>" */
else if (tok >= 2)
{
char buf2[1024];
int m;
char *t, *s;
if (max_macrotrigger >= MAX_MACRO_TRIG)
{
#ifdef JP
msg_print("マクロトリガーの設定が多すぎます!");
#else
msg_print("Too many macro triggers!");
#endif
return 1;
}
m = max_macrotrigger;
max_macrotrigger++;

/* Take into account the escape character */
t = buf2;
s = zz[0];
while (*s)
{
if ('\\' == *s) s++;
*t++ = *s++;
}
*t = '\0';

/* Get a trigger name */
macro_trigger_name[m] = string_make(buf2);

/* Get the corresponding key code */
macro_trigger_keycode[0][m] = string_make(zz[1]);

if (tok == 3)
{
/* Key code of a combination of it with the shift key */
macro_trigger_keycode[1][m] = string_make(zz[2]);
}
else
{
macro_trigger_keycode[1][m] = string_make(zz[1]);
}
}

/* No error */
return 0;
}
}

/* Failure */
return 1;
}


/*
* Helper function for "process_pref_file()"
*
* Input:
* v: output buffer array
* f: final character
*
* Output:
* result
*/
/*:::設定ファイルの行の?:[条件式]の解釈をする 条件が一致したら'0'以外が返るはず*/
cptr process_pref_file_expr(char **sp, char *fp)
{
cptr v;

char *b;
char *s;

char b1 = '[';
char b2 = ']';

char f = ' ';
static char tmp[10];

/* Initial */
s = (*sp);

/* Skip spaces */
/*:::///patch131222本家rev3510の修正を適用?*/
#ifdef PATCH_ORIGIN
while (iswspace(*s)) s++;
#else
while (isspace(*s)) s++;
#endif
/* Save start */
b = s;

/* Default */
v = "?o?o?";

/* Analyze */
if (*s == b1)
{
const char *p;
const char *t;

/* Skip b1 */
s++;

/* First */
t = process_pref_file_expr(&s, &f);

/* Oops */
if (!*t)
{
/* Nothing */
}

/* Function: IOR */
else if (streq(t, "IOR"))
{
v = "0";
while (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
if (*t && !streq(t, "0")) v = "1";
}
}

/* Function: AND */
else if (streq(t, "AND"))
{
v = "1";
while (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
if (*t && streq(t, "0")) v = "0";
}
}

/* Function: NOT */
else if (streq(t, "NOT"))
{
v = "1";
while (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
if (*t && streq(t, "1")) v = "0";
}
}

/* Function: EQU */
else if (streq(t, "EQU"))
{
v = "0";
if (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
}
while (*s && (f != b2))
{
p = process_pref_file_expr(&s, &f);
if (streq(t, p)) v = "1";
}
}

/* Function: LEQ */
else if (streq(t, "LEQ"))
{
v = "1";
if (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
}
while (*s && (f != b2))
{
p = t;
t = process_pref_file_expr(&s, &f);
if (*t && atoi(p) > atoi(t)) v = "0";
}
}

/* Function: GEQ */
else if (streq(t, "GEQ"))
{
v = "1";
if (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
}
while (*s && (f != b2))
{
p = t;
t = process_pref_file_expr(&s, &f);

/* Compare two numbers instead of string */
if (*t && atoi(p) < atoi(t)) v = "0";
}
}

/* Oops */
else
{
while (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
}
}

/* Verify ending */
if (f != b2) v = "?x?x?";

/* Extract final and Terminate */
if ((f = *s) != '\0') *s++ = '\0';
}

/* Other */
else
{
/* Accept all printables except spaces and brackets */
#ifdef JP
while (iskanji(*s) || (isprint(*s) && !my_strchr(" []", *s)))
{
if (iskanji(*s)) s++;
s++;
}
#else
while (isprint(*s) && !my_strchr(" []", *s)) ++s;
#endif

/* Extract final and Terminate */
if ((f = *s) != '\0') *s++ = '\0';

/* Variable */
if (*b == '$')
{
/* System */
if (streq(b+1, "SYS"))
{
v = ANGBAND_SYS;
}

else if (streq(b+1, "KEYBOARD"))
{
v = ANGBAND_KEYBOARD;
}

/* Graphics */
else if (streq(b+1, "GRAF"))
{
v = ANGBAND_GRAF;
}

/* Monochrome mode */
else if (streq(b+1, "MONOCHROME"))
{
if (arg_monochrome)
v = "ON";
else
v = "OFF";
}

/* Race */
else if (streq(b+1, "RACE"))
{
#ifdef JP
v = rp_ptr->E_title;
#else
v = rp_ptr->title;
#endif
}

/* Class */
else if (streq(b+1, "CLASS"))
{
#ifdef JP
v = cp_ptr->E_title;
#else
v = cp_ptr->title;
#endif
}

//v1.1.70 性格追加
else if (streq(b + 1, "PERSONALITY"))
{
v = ap_ptr->E_title;
}

/* Player */
else if (streq(b+1, "PLAYER"))
{
static char tmp_player_name[32];
char *pn, *tpn;
for (pn = player_name, tpn = tmp_player_name; *pn; pn++, tpn++)
{
#ifdef JP
if (iskanji(*pn))
{
*(tpn++) = *(pn++);
*tpn = *pn;
continue;
}
#endif
*tpn = my_strchr(" []", *pn) ? '_' : *pn;
}
*tpn = '\0';
v = tmp_player_name;
}

/* First realm */
else if (streq(b+1, "REALM1"))
{
#ifdef JP
v = E_realm_names[p_ptr->realm1];
#else
v = realm_names[p_ptr->realm1];
#endif
}

/* Second realm */
else if (streq(b+1, "REALM2"))
{
#ifdef JP
v = E_realm_names[p_ptr->realm2];
#else
v = realm_names[p_ptr->realm2];
#endif
}

/* Level */
else if (streq(b+1, "LEVEL"))
{
sprintf(tmp, "%02d", p_ptr->lev);
v = tmp;
}

/* Autopick auto-register is in-use or not? */
else if (streq(b+1, "AUTOREGISTER"))
{
if (p_ptr->autopick_autoregister)
v = "1";
else
v = "0";
}
else if (streq(b+1, "EXTRA_MODE"))
{
if (EXTRA_MODE)
v = "ON";
else
v = "OFF";
}
else if (streq(b+1, "BERSERKER"))
{
if (p_ptr->pseikaku == SEIKAKU_BERSERK)
v = "ON";
else
v = "OFF";
}

/* Money */
else if (streq(b+1, "MONEY"))
{
sprintf(tmp, "%09ld", (long int)p_ptr->au);
v = tmp;
}
}

/* Constant */
else
{
v = b;
}
}

/* Save */
(*fp) = f;

/* Save */
(*sp) = s;

/* Result */
return (v);
}


#define PREF_TYPE_NORMAL 0
#define PREF_TYPE_AUTOPICK 1
#define PREF_TYPE_HISTPREF 2

/*
* Open the "user pref file" and parse it.
*/
/*:::設定ファイルの読み込みと解釈*/
static errr process_pref_file_aux(cptr name, int preftype)
{
FILE *fp;

char buf[1024];

char old[1024];

int line = -1;

errr err = 0;

bool bypass = FALSE;


/* Open the file */
fp = my_fopen(name, "r");

/* No such file */
if (!fp) return (-1);

/* Process the file */
while (0 == my_fgets(fp, buf, sizeof(buf)))
{
/* Count lines */
line++;

/* Skip "empty" lines */
if (!buf[0]) continue;

/* Skip "blank" lines */
#ifdef JP
if (!iskanji(buf[0]))
#endif
/*:::///patch131222本家rev3510の修正を適用?*/
#ifdef PATCH_ORIGIN
if (iswspace(buf[0])) continue;
#else
if (isspace(buf[0])) continue;
#endif
/* Skip comments */
if (buf[0] == '#') continue;


/* Save a copy */
strcpy(old, buf);


/* Process "?:<expr>" */
if ((buf[0] == '?') && (buf[1] == ':'))
{
char f;
cptr v;
char *s;

/* Start */
s = buf + 2;

/* Parse the expr */
v = process_pref_file_expr(&s, &f);

/* Set flag */
bypass = (streq(v, "0") ? TRUE : FALSE);

/* Continue */
continue;
}

/* Apply conditionals */
if (bypass) continue;


/* Process "%:<file>" */
if (buf[0] == '%')
{
static int depth_count = 0;

/* Ignore if deeper than 20 level */
if (depth_count > 20) continue;

/* Count depth level */
depth_count++;

/* Process that file if allowed */
switch (preftype)
{
case PREF_TYPE_AUTOPICK:
(void)process_autopick_file(buf + 2);
break;
case PREF_TYPE_HISTPREF:
(void)process_histpref_file(buf + 2);
break;
default:
(void)process_pref_file(buf + 2);
break;
}

/* Set back depth level */
depth_count--;

/* Continue */
continue;
}


/* Process the line */
err = process_pref_file_command(buf);

/* This is not original pref line... */
if (err)
{
if (preftype != PREF_TYPE_AUTOPICK)
break;
err = process_autopick_file_command(buf);
}
}


/* Error */
if (err)
{
/* Print error message */
/* ToDo: Add better error messages */
#ifdef JP
msg_format("ファイル'%s'の%d行でエラー番号%dのエラー。", name, line, err);
msg_format("('%s'を解析中)", old);
#else
msg_format("Error %d in line %d of file '%s'.", err, line, name);
msg_format("Parsing '%s'", old);
#endif
msg_print(NULL);
}

/* Close the file */
my_fclose(fp);

/* Result */
return (err);
}



/*
* Process the "user pref file" with the given name
*
* See the functions above for a list of legal "commands".
*
* We also accept the special "?" and "%" directives, which
* allow conditional evaluation and filename inclusion.
*/
/*:::*.prfの設定ファイルを読み込む*/
errr process_pref_file(cptr name)
{
char buf[1024];

errr err1, err2;

/* Build the filename */
path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, name);

/* Process the system pref file */
err1 = process_pref_file_aux(buf, PREF_TYPE_NORMAL);

/* Stop at parser errors, but not at non-existing file */
if (err1 > 0) return err1;


/* Build the filename */
path_build(buf, sizeof(buf), ANGBAND_DIR_USER, name);

/* Process the user pref file */
err2 = process_pref_file_aux(buf, PREF_TYPE_NORMAL);


/* User file does not exist, but read system pref file */
if (err2 < 0 && !err1)
return -2;

/* Result of user file processing */
return err2;
}



#ifdef CHECK_TIME

/*
* Operating hours for ANGBAND (defaults to non-work hours)
*/
static char days[7][29] =
{
"SUN:XXXXXXXXXXXXXXXXXXXXXXXX",
"MON:XXXXXXXX.........XXXXXXX",
"TUE:XXXXXXXX.........XXXXXXX",
"WED:XXXXXXXX.........XXXXXXX",
"THU:XXXXXXXX.........XXXXXXX",
"FRI:XXXXXXXX.........XXXXXXX",
"SAT:XXXXXXXXXXXXXXXXXXXXXXXX"
};

/*
* Restict usage (defaults to no restrictions)
*/
static bool check_time_flag = FALSE;

#endif


/*
* Handle CHECK_TIME
*/
///sysdel
/*:::アングバンドの門処理で使われているらしい  と思いきやmain.cからも呼ばれてる?どちらにしても使われていないか*/
errr check_time(void)
{

#ifdef CHECK_TIME

time_t c;
struct tm *tp;

/* No restrictions */
if (!check_time_flag) return (0);

/* Check for time violation */
c = time((time_t *)0);
tp = localtime(&c);

/* Violation */
if (days[tp->tm_wday][tp->tm_hour + 4] != 'X') return (1);

#endif

/* Success */
return (0);
}



/*
* Initialize CHECK_TIME
*/
errr check_time_init(void)
{

#ifdef CHECK_TIME

FILE *fp;

char buf[1024];


/* Build the filename */
path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "time.txt");

/* Open the file */
fp = my_fopen(buf, "r");

/* No file, no restrictions */
if (!fp) return (0);

/* Assume restrictions */
check_time_flag = TRUE;

/* Parse the file */
while (0 == my_fgets(fp, buf, sizeof(buf)))
{
/* Skip comments and blank lines */
if (!buf[0] || (buf[0] == '#')) continue;

/* Chop the buffer */
buf[29] = '\0';

/* Extract the info */
if (prefix(buf, "SUN:")) strcpy(days[0], buf);
if (prefix(buf, "MON:")) strcpy(days[1], buf);
if (prefix(buf, "TUE:")) strcpy(days[2], buf);
if (prefix(buf, "WED:")) strcpy(days[3], buf);
if (prefix(buf, "THU:")) strcpy(days[4], buf);
if (prefix(buf, "FRI:")) strcpy(days[5], buf);
if (prefix(buf, "SAT:")) strcpy(days[6], buf);
}

/* Close it */
my_fclose(fp);

#endif

/* Success */
return (0);
}



#ifdef CHECK_LOAD

#ifndef MAXHOSTNAMELEN
# define MAXHOSTNAMELEN 64
#endif

typedef struct statstime statstime;

struct statstime
{
int cp_time[4];
int dk_xfer[4];
unsigned int v_pgpgin;
unsigned int v_pgpgout;
unsigned int v_pswpin;
unsigned int v_pswpout;
unsigned int v_intr;
int if_ipackets;
int if_ierrors;
int if_opackets;
int if_oerrors;
int if_collisions;
unsigned int v_swtch;
long avenrun[3];
struct timeval boottime;
struct timeval curtime;
};

/*
* Maximal load (if any).
*/
static int check_load_value = 0;

#endif


/*
* Handle CHECK_LOAD
*/
/*:::アングバンドへの門処理でのみ使われている 消してしまおう・・と思いきやmain.c()からも使われてる?どちらにしても使われていないか*/
///sysdel
errr check_load(void)
{

#ifdef CHECK_LOAD

struct statstime st;

/* Success if not checking */
if (!check_load_value) return (0);

/* Check the load */
if (0 == rstat("localhost", &st))
{
long val1 = (long)(st.avenrun[2]);
long val2 = (long)(check_load_value) * FSCALE;

/* Check for violation */
if (val1 >= val2) return (1);
}

#endif

/* Success */
return (0);
}


/*
* Initialize CHECK_LOAD
*/
errr check_load_init(void)
{

#ifdef CHECK_LOAD

FILE *fp;

char buf[1024];

char temphost[MAXHOSTNAMELEN+1];
char thishost[MAXHOSTNAMELEN+1];


/* Build the filename */
path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "load.txt");

/* Open the "load" file */
fp = my_fopen(buf, "r");

/* No file, no restrictions */
if (!fp) return (0);

/* Default load */
check_load_value = 100;

/* Get the host name */
(void)gethostname(thishost, (sizeof thishost) - 1);

/* Parse it */
while (0 == my_fgets(fp, buf, sizeof(buf)))
{
int value;

/* Skip comments and blank lines */
if (!buf[0] || (buf[0] == '#')) continue;

/* Parse, or ignore */
if (sscanf(buf, "%s%d", temphost, &value) != 2) continue;

/* Skip other hosts */
if (!streq(temphost, thishost) &&
!streq(temphost, "localhost")) continue;

/* Use that value */
check_load_value = value;

/* Done */
break;
}

/* Close the file */
my_fclose(fp);

#endif

/* Success */
return (0);
}


#define ENTRY_BARE_HAND 0
#define ENTRY_TWO_HANDS 1
#define ENTRY_RIGHT_HAND1 2
#define ENTRY_LEFT_HAND1 3
#define ENTRY_LEFT_HAND2 4
#define ENTRY_RIGHT_HAND2 5
#define ENTRY_POSTURE 6
#define ENTRY_SHOOT_HIT_DAM 7
#define ENTRY_SHOOT_POWER 8
#define ENTRY_SPEED 9
#define ENTRY_BASE_AC 10
#define ENTRY_LEVEL 11
#define ENTRY_CUR_EXP 12
#define ENTRY_MAX_EXP 13
#define ENTRY_EXP_TO_ADV 14
#define ENTRY_GOLD 15
#define ENTRY_DAY 16
#define ENTRY_HP 17
#define ENTRY_SP 18
#define ENTRY_PLAY_TIME 19
#define ENTRY_SKILL_FIGHT 20
#define ENTRY_SKILL_SHOOT 21
#define ENTRY_SKILL_SAVING 22
#define ENTRY_SKILL_STEALTH 23
#define ENTRY_SKILL_PERCEP 24
#define ENTRY_SKILL_SEARCH 25
#define ENTRY_SKILL_DISARM 26
#define ENTRY_SKILL_DEVICE 27
#define ENTRY_BLOWS 28
#define ENTRY_SHOTS 29
#define ENTRY_AVG_DMG 30
#define ENTRY_INFRA 31

#define ENTRY_NAME 32
#define ENTRY_SEX 33
#define ENTRY_RACE 34
#define ENTRY_CLASS 35
#define ENTRY_REALM 36
#define ENTRY_PATRON 37
#define ENTRY_AGE 38
#define ENTRY_HEIGHT 39
#define ENTRY_WEIGHT 40
#define ENTRY_SOCIAL 41
#define ENTRY_ALIGN 42

#define ENTRY_EXP_ANDR 43
#define ENTRY_EXP_TO_ADV_ANDR 44
#define ENTRY_ALICE_DOLL_ATTACK 45
#define ENTRY_METAMORPHOSIS 46
#define ENTRY_MONSTER_ATTACK 47
#define ENTRY_GUN_CHANCE_RIGHT 48
#define ENTRY_GUN_CHANCE_BOTH 49
#define ENTRY_GUN_CHARGE_RIGHT 50
#define ENTRY_GUN_CHANCE_LEFT 51
#define ENTRY_GUN_CHARGE_LEFT 52
#define ENTRY_HECATIA_BODY 53
#define ENTRY_ANIMAL_GHOST_STRIFE 54


///sys ステータス画面の項目とそれぞれの表示位置
static struct
{
int col;
int row;
int len;
///mod150208 何か警告出てるので20→24に変えた
char header[24];
} disp_player_line[]
#ifdef JP
= {
{ 1, 10, 25, "打撃修正(格闘)"},
{ 1, 10, 25, "打撃修正(両手)"},
{ 1, 10, 25, "打撃修正(右手)"},
{ 1, 10, 25, "打撃修正(左手)"},
{ 1, 11, 25, "打撃修正(左手)"},
{ 1, 11, 25, "打撃修正(右手)"},
{ 1, 11, 25, ""},
{ 1, 15, 25, "射撃攻撃修正"},
{ 1, 16, 25, "射撃武器倍率"},
{ 1, 20, 25, "加速"},
{ 1, 19, 25, "AC"},
{29, 13, 21, "レベル"},
{29, 14, 21, "経験値"},
{29, 15, 21, "最大経験"},
{29, 16, 21, "次レベル"},
{29, 17, 21, "所持金"},
{29, 19, 21, "日付"},
{29, 10, 21, "HP"},
{29, 11, 21, "MP"},
{29, 20, 21, "プレイ時間"},
{53, 10, -1, "打撃攻撃 :"},
{53, 11, -1, "射撃攻撃 :"},
{53, 12, -1, "魔法防御 :"},
{53, 13, -1, "隠密行動 :"},
{53, 15, -1, "知覚 :"},
{53, 16, -1, "探索 :"},
{53, 17, -1, "解除 :"},
{53, 18, -1, "魔法道具 :"},
{ 1, 12, 25, "打撃回数"},
{ 1, 17, 25, "射撃回数"},
{ 1, 13, 25, "平均ダメージ"},
{53, 20, -1, "赤外線視力:"},
// {26, 1, -1, "名前 : "},
{16, 1, -1, "名前 : "},
{ 1, 3, -1, "性別 : "},
{ 1, 4, -1, "種族 : "},
{ 1, 5, -1, "職業 : "},
{ 1, 6, -1, "魔法 : "},
{ 1, 7, -1, "守護魔神 : "},
{29, 3, 21, "年齢"},
{29, 4, 21, "身長"},
{29, 5, 21, "体重"},
//{29, 6, 21, "社会的地位"},
//{29, 7, 21, "属性"},
{29, 6, 21, "難易度"},
{29, 7, 21, "スコア"},
{29, 14, 21, "強化度"},
{29, 16, 21, "次レベル"},
{ 1, 10, 25, "打撃修正(人形)"},
{ 1, 8, -1, "変身   : "},
{ 1, 10, 25, "打撃修正(特殊)"},
{ 1, 15, 25, "銃(右手)成功率"},
{ 1, 15, 25, "銃(両手)成功率"},
{ 1, 16, 25, "装填時間"},
{ 1, 17, 25, "銃(左手)成功率"},
{ 1, 18, 25, "装填時間"},
{ 1, 7, -1, "体    : "},
{ 1, 7, -1, "所属勢力 : " },
};
#else
= {
{ 1, 10, 25, "Bare hand"},
{ 1, 10, 25, "Two hands"},
{ 1, 10, 25, "Right hand"},
{ 1, 10, 25, "Left hand"},
{ 1, 11, 25, "Left hand"},
{ 1, 11, 25, "Right hand"},
{ 1, 11, 25, "Posture"},
{ 1, 15, 25, "Shooting"},
{ 1, 16, 25, "Multiplier"},
{ 1, 20, 25, "Speed"},
{ 1, 19, 25, "AC"},
{29, 13, 21, "Level"},
{29, 14, 21, "Experience"},
{29, 15, 21, "Max Exp"},
{29, 16, 21, "Exp to Adv"},
{29, 17, 21, "Gold"},
{29, 19, 21, "Time"},
{29, 10, 21, "Hit point"},
{29, 11, 21, "SP (Mana)"},
{29, 20, 21, "Play time"},
{53, 10, -1, "Fighting : "},
{53, 11, -1, "Bows/Throw : "},
{53, 12, -1, "SavingThrow: "},
{53, 13, -1, "Stealth : "},
{53, 15, -1, "Perception : "},
{53, 16, -1, "Searching : "},
{53, 17, -1, "Disarming : "},
{53, 18, -1, "MagicDevice: "},
{ 1, 12, 25, "Blows/Round"},
{ 1, 17, 25, "Shots/Round"},
{ 1, 13, 25, "AverageDmg/Rnd"},
{53, 20, -1, "Infra-Vision: "},
{26, 1, -1, "Name : "},
{ 1, 3, -1, "Sex : "},
{ 1, 4, -1, "Race : "},
{ 1, 5, -1, "Class : "},
{ 1, 6, -1, "Magic : "},
{ 1, 7, -1, "Patron : "},
{29, 3, 21, "Age"},
{29, 4, 21, "Height"},
{29, 5, 21, "Weight"},
{29, 6, 21, "Social Class"},
{29, 7, 21, "Align"},
{29, 14, 21, "Construction"},
{29, 16, 21, "Const to Adv"},
};
#endif

static void display_player_one_line(int entry, cptr val, byte attr)
{
char buf[40];

int row = disp_player_line[entry].row;
int col = disp_player_line[entry].col;
int len = disp_player_line[entry].len;
cptr head = disp_player_line[entry].header;

int head_len = strlen(head);

Term_putstr(col, row, -1, TERM_WHITE, head);

if (!val)
return;

if (len > 0)
{
int val_len = len - head_len;
sprintf(buf, "%*.*s", val_len, val_len, val);
Term_putstr(col + head_len, row, -1, attr, buf);
}
else
{
Term_putstr(col + head_len, row, -1, attr, val);
}

return;
}

/*:::攻撃力表示*/
static void display_player_melee_bonus(int hand, int hand_entry)
{
char buf[160];
//int show_tohit = p_ptr->dis_to_h[hand];
//v1.1.71 攻撃命中率表示に近接技能の値を反映
int show_tohit = p_ptr->dis_to_h[hand] + p_ptr->skill_thn / BTH_PLUS_ADJ;
int show_todam = p_ptr->dis_to_d[hand];
object_type *o_ptr = &inventory[INVEN_RARM + hand];


//アリスの武器熟練度を適当に計算して加算
if (p_ptr->pclass == CLASS_ALICE && !p_ptr->do_martialarts)
{
int i,attack_doll_num = 0, skill_sum=0,to_h_sum=0,to_d_sum=0;
for(i=0;i<INVEN_DOLL_NUM_MAX;i++)
{
int blow_num_temp;
o_ptr = &inven_add[i];
if(!o_ptr->k_idx) continue;
if(!object_is_melee_weapon(o_ptr)) continue;
blow_num_temp = calc_doll_blow_num(i);
attack_doll_num+= blow_num_temp;

skill_sum += ref_skill_exp(o_ptr->tval) * blow_num_temp;

if (object_is_known(o_ptr))
{
to_h_sum += o_ptr->to_h * blow_num_temp;
to_d_sum += o_ptr->to_d * blow_num_temp;
}

}
if(!attack_doll_num){msg_print("ERROR:アリス攻撃回数計算がおかしい"); return;}
show_tohit += (skill_sum/attack_doll_num - WEAPON_EXP_BEGINNER)/200 + to_h_sum / attack_doll_num;
show_todam += to_d_sum / attack_doll_num;
}
else if(!p_ptr->do_martialarts)
{
/* Hack -- add in weapon info if known */
if (object_is_known(o_ptr) && !check_invalidate_inventory(INVEN_RARM + hand)) show_tohit += o_ptr->to_h;
if (object_is_known(o_ptr) && !check_invalidate_inventory(INVEN_RARM + hand)) show_todam += o_ptr->to_d;
}

/* Melee attacks */
sprintf(buf, "(%+d,%+d)", show_tohit, show_todam);

/* Dump the bonuses to hit/dam */
//アリスの武器熟練度を適当に計算して加算
if(IS_METAMORPHOSIS)
display_player_one_line(ENTRY_MONSTER_ATTACK, "(---,---)", TERM_L_BLUE);
else if (p_ptr->pclass == CLASS_ALICE && !p_ptr->do_martialarts)
display_player_one_line(ENTRY_ALICE_DOLL_ATTACK, buf, TERM_L_BLUE);
else if (!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM))
display_player_one_line(ENTRY_BARE_HAND, buf, TERM_L_BLUE);
else if (p_ptr->ryoute)
display_player_one_line(ENTRY_TWO_HANDS, buf, TERM_L_BLUE);
else
display_player_one_line(hand_entry, buf, TERM_L_BLUE);
}


/*
* Prints the following information on the screen.
*/
///sys Cコマンドによる@の情報 1ページ目中 スキルや攻撃力など
///mod140308 弓枠廃止処理関連
///mod160508 銃仕様変更に伴い射撃関係の表記変更
static void display_player_middle(void)
{
char buf[160];

/* Base skill */
int show_tohit = p_ptr->dis_to_h_b;
int show_todam = 0;
bool bow1=FALSE,bow2=FALSE;
/* Range weapon */
//object_type *o_ptr = &inventory[INVEN_BOW];
object_type *o_ptr;

int tmul = 0;
int e;
int tester;
bool flag_use_gun = FALSE;

//v1.1.71 射撃技能を反映...しようとしたらもう書いてた。
/*
if (object_is_shooting_weapon(&inventory[INVEN_RARM]))
{
bow1 = TRUE;
o_ptr = &inventory[INVEN_RARM];
}
if (object_is_shooting_weapon(&inventory[INVEN_LARM]))
{
bow2 = TRUE;
o_ptr = &inventory[INVEN_LARM];
}

show_tohit += p_ptr->skill_thb / BTH_PLUS_ADJ;
//射撃武器熟練度の値も反映。どちらかの手に射撃武器を持っているときのみ。
//do_cmd_fire_aux()と同じ計算式を記述。射撃技能値は投擲技能値と共同なので技能値にまとめることはできない。
if (bow1 && !bow2 || !bow1 && bow2)
{
if (o_ptr->tval == TV_CROSSBOW)
show_tohit += ref_skill_exp(TV_CROSSBOW) / 400;
else if (o_ptr->tval == TV_BOW)
show_tohit += (ref_skill_exp(TV_BOW) - (WEAPON_EXP_MASTER / 2)) / 200;

}
*/

if(CHECK_USE_GUN) flag_use_gun = TRUE;

o_ptr = &inventory[INVEN_PACK + shootable(&tester)];

if (p_ptr->migite)
{
display_player_melee_bonus(0, left_hander ? ENTRY_LEFT_HAND1 : ENTRY_RIGHT_HAND1);
}

if (p_ptr->hidarite)
{
display_player_melee_bonus(1, left_hander ? ENTRY_RIGHT_HAND2: ENTRY_LEFT_HAND2);
}
///sysdel 修行僧の構え表示
else if ((p_ptr->pclass == CLASS_MONK) && (empty_hands(TRUE) & EMPTY_HAND_RARM))
{
int i;
if (p_ptr->special_defense & KAMAE_MASK)
{
for (i = 0; i < MAX_KAMAE; i++)
{
if ((p_ptr->special_defense >> i) & KAMAE_GENBU) break;
}
if (i < MAX_KAMAE)
#ifdef JP
display_player_one_line(ENTRY_POSTURE, format("%sの構え", kamae_shurui[i].desc), TERM_YELLOW);
#else
display_player_one_line(ENTRY_POSTURE, format("%s form", kamae_shurui[i].desc), TERM_YELLOW);
#endif
}
else
#ifdef JP
display_player_one_line(ENTRY_POSTURE, "構えなし", TERM_YELLOW);
#else
display_player_one_line(ENTRY_POSTURE, "none", TERM_YELLOW);
#endif
}

/* Apply weapon bonuses */
if (object_is_known(o_ptr)) show_tohit += o_ptr->to_h;
if (object_is_known(o_ptr)) show_todam += o_ptr->to_d;

if(flag_use_gun)
{
int chance;
int timeout;

if(inventory[INVEN_RARM].tval == TV_GUN)
{
int kyouten_card_num = 0;
chance = calc_gun_fire_chance(INVEN_RARM);
timeout = calc_gun_timeout(&inventory[INVEN_RARM]) * calc_gun_charge_mult(INVEN_RARM);

//v1.1.87d 法力経典による充填ブースト反映
kyouten_card_num = count_ability_card(ABL_CARD_KYOUTEN);
if (kyouten_card_num)
{
timeout = timeout * 100 / (100+CALC_ABL_KYOUTEN_RECHARGE_BONUS(kyouten_card_num));
}

//銃両手持ち
if(!inventory[INVEN_LARM].k_idx)
{
display_player_one_line(ENTRY_GUN_CHANCE_BOTH, format("(%d%%)", chance), TERM_L_BLUE);
display_player_one_line(ENTRY_GUN_CHARGE_RIGHT, format("%d.%02dturn", timeout/100, timeout%100), TERM_L_BLUE);
}
else if(left_hander)
{
display_player_one_line(ENTRY_GUN_CHANCE_LEFT, format("(%d%%)", chance), TERM_L_BLUE);
display_player_one_line(ENTRY_GUN_CHARGE_LEFT, format("%d.%02dturn", timeout/100, timeout%100), TERM_L_BLUE);
}
else
{
display_player_one_line(ENTRY_GUN_CHANCE_RIGHT, format("(%d%%)", chance), TERM_L_BLUE);
display_player_one_line(ENTRY_GUN_CHARGE_RIGHT, format("%d.%02dturn", timeout/100, timeout%100), TERM_L_BLUE);
}

}
if(inventory[INVEN_LARM].tval == TV_GUN)
{
chance = calc_gun_fire_chance(INVEN_LARM);
timeout = calc_gun_timeout(&inventory[INVEN_LARM]) * calc_gun_charge_mult(INVEN_LARM);
//銃両手持ち(右手に武器左手に銃→銃呪われる→武器外す、で左手両手持ちにもなりうるはず?)
if(!inventory[INVEN_RARM].k_idx)
{
display_player_one_line(ENTRY_GUN_CHANCE_BOTH, format("(%d%%)", chance), TERM_L_BLUE);
display_player_one_line(ENTRY_GUN_CHARGE_LEFT, format("%d.%02dturn", timeout/100, timeout%100), TERM_L_BLUE);
}
else if(left_hander)
{
display_player_one_line(ENTRY_GUN_CHANCE_RIGHT, format("(%d%%)", chance), TERM_L_BLUE);
display_player_one_line(ENTRY_GUN_CHARGE_RIGHT, format("%d.%02dturn", timeout/100, timeout%100), TERM_L_BLUE);
}
else
{
display_player_one_line(ENTRY_GUN_CHANCE_LEFT, format("(%d%%)", chance), TERM_L_BLUE);
display_player_one_line(ENTRY_GUN_CHARGE_LEFT, format("%d.%02dturn", timeout/100, timeout%100), TERM_L_BLUE);
}
}
}
else
{
///item 弓の命中率とクロスボウの命中ボーナス ステータス画面用
///mod131227 skill tval 射撃命中率
///item もし銃を実装したらここで命中率計算要
if (o_ptr->tval == TV_CROSSBOW)
show_tohit += ref_skill_exp(TV_CROSSBOW) / 400;
else
show_tohit += (ref_skill_exp(TV_BOW) - (WEAPON_EXP_MASTER / 2)) / 200;
/* Range attacks */
display_player_one_line(ENTRY_SHOOT_HIT_DAM, format("(%+d,%+d)", show_tohit, show_todam), TERM_L_BLUE);

if(o_ptr->tval == TV_BOW || o_ptr->tval == TV_CROSSBOW)
{
tmul = bow_tmul(o_ptr->tval, o_ptr->sval);
if (p_ptr->xtra_might) tmul++;
tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
}

/* shoot power */
display_player_one_line(ENTRY_SHOOT_POWER, format("x%d.%02d", tmul/100, tmul%100), TERM_L_BLUE);

}


/* Dump the armor class */
display_player_one_line(ENTRY_BASE_AC, format("[%d,%+d]", p_ptr->dis_ac, p_ptr->dis_to_a), TERM_L_BLUE);

/* Dump speed */
{
int tmp_speed = 0;
byte attr;
int i;

i = p_ptr->pspeed-110;

/* Hack -- Visually "undo" the Search Mode Slowdown */
if (p_ptr->action == ACTION_SEARCH) i += 10;

if (i > 0)
{
if (!p_ptr->riding)
attr = TERM_L_GREEN;
else
attr = TERM_GREEN;
}
else if (i == 0)
{
if (!p_ptr->riding)
attr = TERM_L_BLUE;
else
attr = TERM_GREEN;
}
else
{
if (!p_ptr->riding)
attr = TERM_L_UMBER;
else
attr = TERM_RED;
}

if (!p_ptr->riding || CLASS_RIDING_BACKDANCE)
{
if(p_ptr->pclass == CLASS_MARTIAL_ARTIST && p_ptr->tim_general[0]) tmp_speed += 20;
else if (IS_FAST()) tmp_speed += 10;
if (p_ptr->slow) tmp_speed -= 10;
if (p_ptr->lightspeed) tmp_speed = 99;
}
else
{
if (MON_FAST(&m_list[p_ptr->riding])) tmp_speed += 10;
if (MON_SLOW(&m_list[p_ptr->riding])) tmp_speed -= 10;
}

if (tmp_speed)
{
if (!p_ptr->riding || CLASS_RIDING_BACKDANCE)
sprintf(buf, "(%+d%+d)", i-tmp_speed, tmp_speed);
else
#ifdef JP
sprintf(buf, "乗馬中 (%+d%+d)", i-tmp_speed, tmp_speed);
#else
sprintf(buf, "Riding (%+d%+d)", i-tmp_speed, tmp_speed);
#endif

if (tmp_speed > 0)
attr = TERM_YELLOW;
else
attr = TERM_VIOLET;
}
else
{
if (!p_ptr->riding || CLASS_RIDING_BACKDANCE)
sprintf(buf, "(%+d)", i);
else
#ifdef JP
sprintf(buf, "乗馬中 (%+d)", i);
#else
sprintf(buf, "Riding (%+d)", i);
#endif
}

display_player_one_line(ENTRY_SPEED, buf, attr);
}

/* Dump character level */
display_player_one_line(ENTRY_LEVEL, format("%d", p_ptr->lev), TERM_L_GREEN);

/* Dump experience */
if (p_ptr->prace == RACE_ANDROID) e = ENTRY_EXP_ANDR;
else e = ENTRY_CUR_EXP;

if (p_ptr->exp >= p_ptr->max_exp)
display_player_one_line(e, format("%ld", p_ptr->exp), TERM_L_GREEN);
else
display_player_one_line(e, format("%ld", p_ptr->exp), TERM_YELLOW);

/* Dump max experience */
if (p_ptr->prace == RACE_ANDROID)
/* Nothing */;
else
display_player_one_line(ENTRY_MAX_EXP, format("%ld", p_ptr->max_exp), TERM_L_GREEN);

/* Dump exp to advance */
if (p_ptr->prace == RACE_ANDROID) e = ENTRY_EXP_TO_ADV_ANDR;
else e = ENTRY_EXP_TO_ADV;

if (p_ptr->lev >= PY_MAX_LEVEL)
display_player_one_line(e, "*****", TERM_L_GREEN);
else if (p_ptr->prace == RACE_ANDROID)
display_player_one_line(e, format("%ld", (s32b)(player_exp_a[p_ptr->lev - 1] * p_ptr->expfact / 100L)), TERM_L_GREEN);
else
display_player_one_line(e, format("%ld", (s32b)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L)), TERM_L_GREEN);

/* Dump gold */
display_player_one_line(ENTRY_GOLD, format("%ld", p_ptr->au), TERM_L_GREEN);

/* Dump Day */
{
int day, hour, min;
extract_day_hour_min(&day, &hour, &min);

#ifdef JP
if (day < MAX_DAYS) sprintf(buf, "%d日目 %2d:%02d", day, hour, min);
else sprintf(buf, "*****日目 %2d:%02d", hour, min);
#else
if (day < MAX_DAYS) sprintf(buf, "Day %d %2d:%02d", day, hour, min);
else sprintf(buf, "Day ***** %2d:%02d", hour, min);
#endif
}
display_player_one_line(ENTRY_DAY, buf, TERM_L_GREEN);

if(p_ptr->pclass == CLASS_CLOWNPIECE)
{
if (p_ptr->magic_num1[0] < 10000)
display_player_one_line(ENTRY_HP, format("%5d", p_ptr->mhp), TERM_L_GREEN);
else if (p_ptr->magic_num1[0] < 20000)
display_player_one_line(ENTRY_HP, format("%5d", p_ptr->mhp), TERM_YELLOW);
else
display_player_one_line(ENTRY_HP, format("%5d", p_ptr->mhp), TERM_RED);
}
else
{
/* Dump hit point */
if (p_ptr->chp >= p_ptr->mhp)
display_player_one_line(ENTRY_HP, format("%4d/%4d", p_ptr->chp , p_ptr->mhp), TERM_L_GREEN);
else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10)
display_player_one_line(ENTRY_HP, format("%4d/%4d", p_ptr->chp , p_ptr->mhp), TERM_YELLOW);
else
display_player_one_line(ENTRY_HP, format("%4d/%4d", p_ptr->chp , p_ptr->mhp), TERM_RED);
}

/* Dump mana power */
if (p_ptr->csp >= p_ptr->msp)
display_player_one_line(ENTRY_SP, format("%4d/%4d", p_ptr->csp , p_ptr->msp), TERM_L_GREEN);
else if (p_ptr->csp > (p_ptr->msp * mana_warn) / 10)
display_player_one_line(ENTRY_SP, format("%4d/%4d", p_ptr->csp , p_ptr->msp), TERM_YELLOW);
else
display_player_one_line(ENTRY_SP, format("%4d/%4d", p_ptr->csp , p_ptr->msp), TERM_RED);

/* Dump play time */
display_player_one_line(ENTRY_PLAY_TIME, format("%.2lu:%.2lu:%.2lu", playtime/(60*60), (playtime/60)%60, playtime%60), TERM_L_GREEN);
}


/*
* Hack -- pass color info around this file
*/
static byte likert_color = TERM_WHITE;


/*
* Returns a "rating" of x depending on y
*/
//v1.1.81 本家の「技能値に実値を表示する」オプションを追加
static cptr likert(int x, int y)
{
static char dummy[40] = "";

/* Paranoia */
if (y <= 0) y = 1;

/* Negative value */
if (x < 0)
{
likert_color = TERM_L_DARK;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-最低", x);
else
sprintf(dummy, "最低");
return dummy;
#else
return "Very Bad";
#endif
}

/* Analyze the value */
switch ((x / y))
{
case 0:
case 1:
likert_color = TERM_RED;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-悪い", x);
else
sprintf(dummy, "悪い");
return dummy;
#else
return "Bad";
#endif

case 2:
likert_color = TERM_L_RED;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-劣る", x);
else
sprintf(dummy, "劣る");
return dummy;
#else
return "Poor";
#endif

case 3:
case 4:
likert_color = TERM_ORANGE;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-普通", x);
else
sprintf(dummy, "普通");
return dummy;
#else
return "Fair";
#endif

case 5:
likert_color = TERM_YELLOW;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-良い", x);
else
sprintf(dummy, "良い");
return dummy;
#else
return "Good";
#endif

case 6:
likert_color = TERM_YELLOW;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-大変良い", x);
else
sprintf(dummy, "大変良い");
return dummy;
#else
return "Very Good";
#endif

case 7:
case 8:
likert_color = TERM_L_GREEN;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-卓越", x);
else
sprintf(dummy, "卓越");
return dummy;
#else
return "Excellent";
#endif

case 9:
case 10:
case 11:
case 12:
case 13:
likert_color = TERM_GREEN;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-超越", x);
else
sprintf(dummy, "超越");
return dummy;
#else
return "Superb";
#endif

case 14:
case 15:
case 16:
case 17:
likert_color = TERM_BLUE;
#ifdef JP
if (show_actual_value)
sprintf(dummy, "%3d-英雄的", x);
else
sprintf(dummy, "英雄的");
return dummy;
#else
return "Heroic";
#endif

default:
likert_color = TERM_VIOLET;
#ifdef JP
if(show_actual_value)
sprintf(dummy, "%3d-伝説的[%d]",x, (int)((((x / y) - 17) * 5) / 2));
else
sprintf(dummy, "伝説的[%d]", (int)((((x / y) - 17) * 5) / 2));
#else
sprintf(dummy, "Legendary[%d]", (int)((((x / y) - 17) * 5) / 2));
#endif
return dummy;
}
}

///mod140223 格闘攻撃の威力(100発分合計)を概算する。一行動ごとの攻撃回数は掛けられていない。
//本家では職や構えごとの専用テーブルを使ってたが職と攻撃手段の増加で不可能になったためpy_attack_aux()の計算処理を100回試行して合計することにした。
//Cコマンドを実行するたびに値がずれるが仕方ない。
//v1.1.65 display_player_various()内にあったが別関数に分離
int calc_martialarts_dam_x100(hand_idx)
{
int sum=0;
int num = 100;
int count;

if (!p_ptr->do_martialarts)
{
msg_print("ERROR:格闘でないときにcalc_martialarts_dam()が呼ばれた");
return 0;
}

if (hand_idx == 0 && !p_ptr->migite || hand_idx == 1 && !p_ptr->hidarite)
return 0;

for (count = 0; count<num; count++)
{
const martial_arts_new *ma_ptr = &ma_blows_new[0], *old_ptr = &ma_blows_new[0];
int times;
int martial_arts_method = find_martial_arts_method(0);//ここではmodeは常に0
int max_times = ref_skill_exp(SKILL_MARTIALARTS) / 2000 + 1; //格闘熟練度による、攻撃種類選定試行数。攻撃回数ではない
for (times = 0; times < max_times; times++)
{
int min_level = 1;
do
{
int mode_pick[50];
int mode_cnt = 0;
int j;
for (j = 0; (ma_blows_new[j].method != 0 && mode_cnt < 50); j++)
if (ma_blows_new[j].method == martial_arts_method)mode_pick[mode_cnt++] = j;

if (!mode_cnt) return 0;//v1.1.92 専用格闘攻撃を設定し忘れてキャラメイク画面でクラッシュしたので追加

ma_ptr = &ma_blows_new[mode_pick[randint0(mode_cnt)]];
min_level = ma_ptr->min_level;
} while ((min_level > p_ptr->lev) || (randint1(p_ptr->lev) < ma_ptr->chance));

if ((ma_ptr->min_level >= old_ptr->min_level)) old_ptr = ma_ptr;
else ma_ptr = old_ptr;
}
if (p_ptr->pclass == CLASS_KISUME) sum += calc_kisume_bonus();
sum += ((ma_ptr->dd + p_ptr->to_dd[hand_idx]) * (ma_ptr->ds + p_ptr->to_ds[hand_idx] + 1)) / 2;
}

sum += p_ptr->dis_to_d[hand_idx] * num;

return sum;

}


/*
* Prints ratings on certain abilities
*
* This code is "imitated" elsewhere to "dump" a character sheet.
*/
/*:::ステータス画面 @のスキルや変異攻撃など*/
///sys @のスキルや変異攻撃など表示
///mod140308 弓枠廃止処理関連
///mod140323 変異格闘など記述変更
static void display_player_various(void)
{
int tmp, damage[2], to_h[2], blows1, blows2, i, basedam;
int xthn, xthb, xfos, xsrh;
int xdis, xdev, xsav, xstl;
cptr desc;
///mod140323 変異格闘の攻撃回数だったが追加格闘全般の回数として使うことにした
int muta_att = 0;
u32b flgs[TR_FLAG_SIZE];
int shots, shot_frac,tester;
bool dokubari;
bool alice = (p_ptr->pclass == CLASS_ALICE && !p_ptr->do_martialarts);
bool flag_use_gun = FALSE;

object_type *o_ptr;

if(CHECK_USE_GUN) flag_use_gun = TRUE;

if((!check_invalidate_inventory(INVEN_RARM) && inventory[INVEN_RARM].tval == TV_SHIELD || !check_invalidate_inventory(INVEN_LARM) && inventory[INVEN_LARM].tval == TV_SHIELD) && ref_skill_exp(SKILL_SHIELD) > 3200) muta_att++;
if (p_ptr->muta2 & MUT2_HARDHEAD || (buki_motteruka(INVEN_RARM) && ref_skill_exp(SKILL_MARTIALARTS) > 3200)) muta_att++;
if (p_ptr->muta2 & MUT2_HORNS) muta_att++;
if (p_ptr->muta2 & MUT2_BIGHORN) muta_att++;
if (p_ptr->muta2 & MUT2_BIGTAIL) muta_att++;
if (p_ptr->muta3 & MUT3_FISH_TAIL) muta_att++;
if(inventory[INVEN_RARM].k_idx && inventory[INVEN_RARM].tval == TV_STICK && p_ptr->ryoute)
{
int num_xtra = 0;
if(p_ptr->pclass == CLASS_MARTIAL_ARTIST) num_xtra++;
if(ref_skill_exp(SKILL_MARTIALARTS) > 3000) num_xtra++;
if(ref_skill_exp(SKILL_MARTIALARTS) > 4500) num_xtra++;
if(ref_skill_exp(SKILL_MARTIALARTS) > 6000) num_xtra++;
if(heavy_armor()) num_xtra /= 2;
if(num_xtra) muta_att++;
}
xthn = p_ptr->skill_thn + (p_ptr->to_h_m * BTH_PLUS_ADJ);
xthb = p_ptr->skill_thb + (p_ptr->to_h_b * BTH_PLUS_ADJ);

///mod160508 銃使用時には射撃速度パラメータを表示しない。display_player_middle()で発動成功率や充填速度などを表示する
if(!flag_use_gun)
{
/* Shooting Skill (with current bow and normal missile) */
//o_ptr = &inventory[INVEN_BOW];
o_ptr = &inventory[INVEN_PACK + shootable(&tester)];
///160508 今の今まで知らなかったんだが射撃の技能値表示には武器の命中率も含まれるらしい。銃の表記と整合性を取りにくいが適当に計算しよう
xthb += (o_ptr->to_h * BTH_PLUS_ADJ);

/* If the player is wielding one? */
if (tester > SHOOT_UNSUITABLE && o_ptr->k_idx)
{
s16b energy_fire = bow_energy(o_ptr->tval, o_ptr->sval);

/* Calculate shots per round */
shots = p_ptr->num_fire * 100;
shot_frac = (shots * 100 / energy_fire) % 100;
shots = shots / energy_fire;
#if 0
//アーチャーのクリムゾン連射処理を廃止した
if (o_ptr->name1 == ART_CRIMSON)
{
shots = 1;
shot_frac = 0;
if (p_ptr->pclass == CLASS_ARCHER)
{
/* Extra shot at level 10 */
if (p_ptr->lev >= 10) shots++;

/* Extra shot at level 30 */
if (p_ptr->lev >= 30) shots++;

/* Extra shot at level 45 */
if (p_ptr->lev >= 45) shots++;
}
}
#endif
}
else
{
shots = 0;
shot_frac = 0;
}
}

if(alice)//アリス隣接攻撃の特殊処理
{
blows1 = 0;
damage[0] = 0;
for(i=0;i<INVEN_DOLL_NUM_MAX;i++)
{
int tmp_blows = calc_doll_blow_num(i);
if(!tmp_blows) continue;
blows1 += tmp_blows;
dokubari = FALSE;

o_ptr = &inven_add[i];
if((o_ptr->tval == TV_KNIFE) && (o_ptr->sval == SV_WEAPON_DOKUBARI)) dokubari = TRUE;

if(dokubari)
damage[0] += 100; //あとで100で割る
else
{
basedam = ((int)(o_ptr->dd) * (int)(o_ptr->ds + 1)) * 50;
object_flags_known(o_ptr, flgs);

if (have_flag(flgs, TR_EX_VORPAL))
basedam = basedam * 5 / 3;
else if (have_flag(flgs, TR_VORPAL))
basedam = basedam * 11 / 9;
basedam = calc_expect_crit(o_ptr->weight, o_ptr->to_h, basedam, p_ptr->dis_to_h[0], dokubari);

damage[0] += basedam * tmp_blows;
damage[0] += p_ptr->dis_to_d[0] * tmp_blows * 100;

if (object_is_known(o_ptr))
damage[0] += o_ptr->to_d * tmp_blows * 100;
}

}


}
else if(IS_METAMORPHOSIS) //モンスター変身時
{
monster_race *r_ptr = &r_info[MON_EXTRA_FIELD];
damage[0] = 0;
blows1 = 0;
for(i=0;i<4;i++)
{
if(!r_ptr->blow[i].method) continue;
if(r_ptr->blow[i].method == RBM_SHOOT) continue;
if(r_ptr->blow[i].effect == RBE_DR_MANA) continue;
damage[0] += r_ptr->blow[i].d_dice * (r_ptr->blow[i].d_side+1) / 2;
blows1++;
}
}
else if (p_ptr->do_martialarts)//普通の格闘 v1.1.65で別関数に分離した
{
for (i = 0; i < 2; i++)
{
damage[i] = calc_martialarts_dam_x100(i);
}
blows1 = p_ptr->migite ? p_ptr->num_blow[0] : 0;
blows2 = p_ptr->hidarite ? p_ptr->num_blow[1] : 0;

}
else//武器攻撃
{
for(i = 0; i < 2; i++)
{
damage[i] = p_ptr->dis_to_d[i] * 100;
o_ptr = &inventory[INVEN_RARM + i];

/* Average damage per round */

if (o_ptr->k_idx)
{
to_h[i] = 0;
dokubari = FALSE;
int vorpal = 0; //v1.1.45 ネムノの包丁研ぎで一時切れ味付加したときステータス画面に反映
///item 毒針
///mod131223
if((o_ptr->tval == TV_KNIFE) && (o_ptr->sval == SV_WEAPON_DOKUBARI)) dokubari = TRUE;
if (object_is_known(o_ptr))
{
damage[i] += o_ptr->to_d * 100;
to_h[i] += o_ptr->to_h;
}
//basedam = ((o_ptr->dd + p_ptr->to_dd[i]) * (o_ptr->ds + p_ptr->to_ds[i] + 1)) * 50;
basedam = ((int)(o_ptr->dd + p_ptr->to_dd[i]) * (int)(o_ptr->ds + p_ptr->to_ds[i] + 1)) * 50;
object_flags_known(o_ptr, flgs);

basedam = calc_expect_crit(o_ptr->weight, to_h[i], basedam, p_ptr->dis_to_h[i], dokubari);
//if ((o_ptr->ident & IDENT_MENTAL) && ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)))
if (have_flag(flgs, TR_EX_VORPAL)) vorpal = 2;
else if (have_flag(flgs, TR_VORPAL)) vorpal = 1;

if (object_has_a_blade(o_ptr) && p_ptr->special_attack & ATTACK_VORPAL) vorpal++;

if(vorpal >= 2)
{
/* vorpal blade */
basedam *= 5;
basedam /= 3;
}
else if(vorpal == 1)
{
/* vorpal flag only */
basedam *= 11;
basedam /= 9;
}



if ((p_ptr->pclass != CLASS_SAMURAI) && (p_ptr->pclass != CLASS_MARTIAL_ARTIST) && (have_flag(flgs, TR_FORCE_WEAPON) || p_ptr->special_attack & ATTACK_FORCE )&& (p_ptr->csp > (o_ptr->dd * o_ptr->ds / 5)))
basedam = basedam * 7 / 2;
}
else basedam = 0;

damage[i] += basedam;

if (!p_ptr->do_martialarts && (o_ptr->tval == TV_KNIFE) && (o_ptr->sval == SV_WEAPON_DOKUBARI)) damage[i] = 1;
if (damage[i] < 0) damage[i] = 0;
}
blows1 = p_ptr->migite ? p_ptr->num_blow[0]: 0;
blows2 = p_ptr->hidarite ? p_ptr->num_blow[1] : 0;
}
/* Basic abilities */

xdis = p_ptr->skill_dis;
xdev = p_ptr->skill_dev;
xsav = p_ptr->skill_sav;
xstl = p_ptr->skill_stl;
xsrh = p_ptr->skill_srh;
xfos = p_ptr->skill_fos;

desc = likert(xthn, 12);
display_player_one_line(ENTRY_SKILL_FIGHT, desc, likert_color);

desc = likert(xthb, 12);
display_player_one_line(ENTRY_SKILL_SHOOT, desc, likert_color);

desc = likert(xsav, 7);
display_player_one_line(ENTRY_SKILL_SAVING, desc, likert_color);

/* Hack -- 0 is "minimum stealth value", so print "Very Bad" */
desc = likert((xstl > 0) ? xstl : -1, 1);
display_player_one_line(ENTRY_SKILL_STEALTH, desc, likert_color);

/*:::*/
desc = likert(xfos, 6);
//display_player_one_line(ENTRY_SKILL_PERCEP, desc, likert_color);

desc = likert(xsrh, 6);
display_player_one_line(ENTRY_SKILL_SEARCH, desc, likert_color);

desc = likert(xdis, 8);
display_player_one_line(ENTRY_SKILL_DISARM, desc, likert_color);

desc = likert(xdev, 6);
display_player_one_line(ENTRY_SKILL_DEVICE, desc, likert_color);

if(!flag_use_gun)
display_player_one_line(ENTRY_SHOTS, format("%d.%02d", shots, shot_frac), TERM_L_BLUE);

if(alice)
{
if (!muta_att)
display_player_one_line(ENTRY_BLOWS, format("%d", blows1), TERM_L_BLUE);
else
display_player_one_line(ENTRY_BLOWS, format("%d+α", blows1), TERM_L_BLUE);

if(!muta_att)
desc = format("%d", damage[0] / 100);//アリスのdamage[0]は攻撃回数分合計済み
else
desc = format("%d+α", damage[0] / 100);

}
else if(IS_METAMORPHOSIS)
{
display_player_one_line(ENTRY_BLOWS, format("%d", blows1), TERM_L_BLUE);
desc = format("%d", damage[0]);

}
else
{
//py_attack()の追加攻撃不可条件と一致すること
if((mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_NO_EXATACK)
|| p_ptr->pclass == CLASS_3_FAIRIES ) muta_att = 0;

if (!muta_att)
display_player_one_line(ENTRY_BLOWS, format("%d+%d", blows1, blows2), TERM_L_BLUE);
else
display_player_one_line(ENTRY_BLOWS, format("%d+%d+α", blows1, blows2), TERM_L_BLUE);

if ((damage[0]+damage[1]) == 0)
desc = "(攻撃不可)";
else if(!muta_att)
desc = format("%d+%d", blows1 * damage[0] / 100, blows2 * damage[1] / 100);
///mod140323 変異部位や追加格闘のダメージは近似値計算するのも面倒なので+αでごまかすことにした
else
desc = format("%d+%d+α", blows1 * damage[0] / 100, blows2 * damage[1] / 100);
}


display_player_one_line(ENTRY_AVG_DMG, desc, TERM_L_BLUE);

if(p_ptr->do_martialarts && p_ptr->pclass == CLASS_MEIRIN)
{
int num = 100 / p_ptr->magic_num1[0];
int num_flac = 10000 / p_ptr->magic_num1[0] % 100;
Term_putstr(1, 11, -1, TERM_WHITE, "攻撃速度");
Term_putstr(21, 11, -1, TERM_L_BLUE, format("x%d.%02d",num,num_flac));
}
else if(p_ptr->pclass == CLASS_RAIKO && music_singing(MUSIC_NEW_RAIKO_PRISTINE))
{
int need = MAX((75 - p_ptr->concent * 5),25);
int num = 100 / need;
int num_flac = 10000 / need % 100;
Term_putstr(1, 14, -1, TERM_WHITE, "攻撃速度");
Term_putstr(21, 14, -1, TERM_L_BLUE, format("x%d.%02d",num,num_flac));
}

display_player_one_line(ENTRY_INFRA, format("%d feet", p_ptr->see_infra * 10), TERM_WHITE);
}



/*
* Obtain the "flags" for the player as if he was an item
*/
/*:::@の能力をフラグとしてまとめる ステータス画面での一覧表示用*/
static void player_flags(u32b flgs[TR_FLAG_SIZE])
{
int i;
int plev = p_ptr->lev;

//アリスと座敷わらしが使う
u32b doll_flgs[TR_FLAG_MAX];
object_type *o_ptr;

/* Clear */
for (i = 0; i < TR_FLAG_SIZE; i++)
flgs[i] = 0L;

/* Classes */
switch (p_ptr->pclass)
{
case CLASS_WARRIOR:
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 44) add_flag(flgs, TR_REGEN);
break;

case CLASS_PRIEST:
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 44) add_flag(flgs, TR_RES_INSANITY);
if (p_ptr->lev > 39)
{
if(is_good_realm(p_ptr->realm1)) add_flag(flgs, TR_RES_HOLY);
else add_flag(flgs, TR_RES_NETHER);
}
break;

case CLASS_HIGH_MAGE:
if(p_ptr->lev > 19 && p_ptr->realm1 == TV_BOOK_FORESEE) add_flag(flgs, TR_WARNING);
if(p_ptr->lev > 19 && (p_ptr->realm1 == TV_BOOK_TRANSFORM || p_ptr->realm1 == TV_BOOK_LIFE)) add_flag(flgs, TR_REGEN);

if(p_ptr->lev > 39 && p_ptr->realm1 == TV_BOOK_OCCULT) add_flag(flgs, TR_RES_INSANITY);
break;



case CLASS_ARCHER:
if (p_ptr->lev > 19) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_BLIND);
break;

case CLASS_SAMURAI:
if (p_ptr->lev > 29)
add_flag(flgs, TR_RES_FEAR);
break;
case CLASS_PALADIN:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_HOLY);
break;
case CLASS_MAID:
if (p_ptr->lev > 24) add_flag(flgs, TR_SUST_DEX);
if (p_ptr->lev > 24) add_flag(flgs, TR_SUST_CON);
if (p_ptr->lev > 39)add_flag(flgs, TR_RES_FEAR);
break;
case CLASS_ROGUE:
if (p_ptr->lev > 29) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 39) add_flag(flgs, TR_THROW);
break;
case CLASS_RANGER:
if (p_ptr->lev > 19) add_flag(flgs, TR_FREE_ACT);
if (p_ptr->lev > 29) add_flag(flgs, TR_ESP_ANIMAL);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_POIS);
break;
/*
case CLASS_CHAOS_WARRIOR:
if (p_ptr->lev > 29)
add_flag(flgs, TR_RES_CHAOS);
if (p_ptr->lev > 39)
add_flag(flgs, TR_RES_FEAR);
break;
*/
case CLASS_MONK:
case CLASS_FORCETRAINER:
if ((p_ptr->lev > 9) && !heavy_armor())
add_flag(flgs, TR_SPEED);
if ((p_ptr->lev>24) && !heavy_armor())
add_flag(flgs, TR_FREE_ACT);
break;
case CLASS_NINJA:
if (p_ptr->lev > 4) add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_SLOW_DIGEST);
if (p_ptr->lev > 9) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 14) add_flag(flgs, TR_FREE_ACT);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_POIS);
if (p_ptr->lev > 19) add_flag(flgs, TR_SPEEDSTER);
if (p_ptr->lev > 24) add_flag(flgs, TR_SUST_DEX);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 34) add_flag(flgs, TR_THROW);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_DARK);
break;
case CLASS_MINDCRAFTER:
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 19) add_flag(flgs, TR_SUST_WIS);
if (p_ptr->lev > 24) add_flag(flgs, TR_LEVITATION);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 39) add_flag(flgs, TR_TELEPATHY);
break;
case CLASS_BARD:
add_flag(flgs, TR_RES_SOUND);
break;
/*
case CLASS_BERSERKER:
add_flag(flgs, TR_SUST_STR);
add_flag(flgs, TR_SUST_DEX);
add_flag(flgs, TR_SUST_CON);
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_SPEED);
if (p_ptr->lev > 39) add_flag(flgs, TR_REFLECT);
break;
*/
case CLASS_MIRROR_MASTER:
if(p_ptr->lev > 39)add_flag(flgs, TR_REFLECT);
break;

case CLASS_TSUKUMO_MASTER:
if(p_ptr->lev > 9)add_flag(flgs, TR_SEE_INVIS);
break;

case CLASS_SYUGEN:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 44 && is_good_realm(p_ptr->realm1)) add_flag(flgs, TR_RES_HOLY);
break;

case CLASS_MAGIC_KNIGHT:
if (p_ptr->lev > 19) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 29) add_flag(flgs, TR_REGEN);
break;

case CLASS_RESEARCHER:
if (p_ptr->lev > 14) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_BLIND);

break;

case CLASS_ENGINEER:
case CLASS_NITORI:
add_flag(flgs, TR_LEVITATION);
if (p_ptr->lev > 24) add_flag(flgs, TR_RES_BLIND);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_SHARDS);
break;
case CLASS_JEWELER:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_BLIND);
break;


case CLASS_RUMIA:
add_flag(flgs, TR_RES_DARK);
break;
case CLASS_YOUMU:
if (p_ptr->lev > 24) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 29) add_flag(flgs, TR_SPEEDSTER);
break;
case CLASS_TEWI:
if (p_ptr->lev > 9) add_flag(flgs, TR_FREE_ACT);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_HOLY);
break;
case CLASS_UDONGE:
add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_SOUND);
if (p_ptr->lev > 24) add_flag(flgs, TR_RES_INSANITY);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_LITE);
if (p_ptr->lev > 39) add_flag(flgs, TR_TELEPATHY);
break;
case CLASS_IKU:
add_flag(flgs, TR_RES_ELEC);
break;

case CLASS_KOMACHI:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_WATER);
if (p_ptr->lev > 29) add_flag(flgs, TR_SPEEDSTER);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_TIME);
break;
case CLASS_KOGASA:
add_flag(flgs, TR_RES_WATER);
break;


case CLASS_KASEN:
if (is_special_seikaku(SEIKAKU_SPECIAL_KASEN))
{
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_SEE_INVIS);
}
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_RES_DARK);
if (p_ptr->lev > 19)add_flag(flgs, TR_SUST_STR);
if (p_ptr->lev > 19) add_flag(flgs, TR_SUST_CON);
if (p_ptr->lev > 34) add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_SUIKA:
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_REGEN);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_SOUND);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_SHARDS);
break;
case CLASS_KOISHI:
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_RES_INSANITY);
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_FREE_ACT);
if(p_ptr->lev > 29) add_flag(flgs, TR_RES_CHAOS);
break;
case CLASS_MOMIZI:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_BLIND);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_FEAR);
break;
case CLASS_SEIGA:
if (p_ptr->lev > 14) add_flag(flgs, TR_RES_DARK);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_NETHER);
break;
case CLASS_CIRNO:
add_flag(flgs, TR_RES_COLD);
if (p_ptr->lev > 34) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 44) add_flag(flgs, TR_RES_INSANITY);
//v1.1.32
if(is_special_seikaku(SEIKAKU_SPECIAL_CIRNO))
{
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_FEAR);
}

break;
case CLASS_ORIN:
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_RES_FIRE);
if (p_ptr->lev > 9) add_flag(flgs, TR_ESP_UNDEAD);
if (p_ptr->lev > 19) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 44) add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_SHINMYOUMARU:
add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 29) add_flag(flgs, TR_SPEEDSTER);
break;
case CLASS_NAZRIN:
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_HOLY);
break;
case CLASS_LETTY:
add_flag(flgs, TR_RES_COLD);
break;
case CLASS_PATCHOULI:
add_flag(flgs, TR_LEVITATION);
if (p_ptr->lev > 4) add_flag(flgs, TR_RES_FIRE);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_COLD);
if (p_ptr->lev > 14) add_flag(flgs, TR_RES_ELEC);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_ACID);
break;
case CLASS_AYA:
add_flag(flgs, TR_SPEED);
if (p_ptr->lev > 9) add_flag(flgs, TR_SPEEDSTER);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_SOUND);
break;
case CLASS_BANKI:
add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_FEAR);
break;
case CLASS_MYSTIA:
add_flag(flgs, TR_LEVITATION);
if (p_ptr->lev > 14) add_flag(flgs, TR_SPEED);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_SOUND);
break;
case CLASS_FLAN:
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_SHOU:
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_RES_HOLY);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 34) add_flag(flgs, TR_RES_NETHER);
break;

case CLASS_YUYUKO:
add_flag(flgs, TR_ESP_UNDEAD);
break;
case CLASS_SATORI:
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 24) add_flag(flgs, TR_TELEPATHY);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_KYOUKO:
add_flag(flgs, TR_RES_SOUND);
if (p_ptr->lev > 39) add_flag(flgs, TR_REFLECT);
break;

case CLASS_TOZIKO:
add_flag(flgs, TR_RES_ELEC);
break;
case CLASS_LILY_WHITE:
add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_KISUME:
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_FIRE);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_WATER);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_NETHER);
break;
case CLASS_HATATE:
add_flag(flgs, TR_SEE_INVIS);
break;
case CLASS_MIKO:
add_flag(flgs, TR_RES_HOLY);
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_FREE_ACT);
if (p_ptr->lev > 4) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 9) add_flag(flgs, TR_ESP_HUMAN);
if (p_ptr->lev > 14) add_flag(flgs, TR_LEVITATION);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_LITE);
if (p_ptr->lev > 24) add_flag(flgs, TR_WARNING);
if (p_ptr->lev > 29) add_flag(flgs, TR_TELEPATHY);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_TIME);
break;
case CLASS_KOKORO:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_WRIGGLE:
add_flag(flgs, TR_LITE);
if (p_ptr->lev > 24) add_flag(flgs, TR_WARNING);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_LITE);
break;
case CLASS_YUUKA:
add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_LITE);
break;
case CLASS_CHEN:
if(!p_ptr->magic_num1[0])
{
add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_SPEEDSTER);
}
break;
case CLASS_MURASA:
add_flag(flgs, TR_RES_WATER);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_ACID);
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_SEE_INVIS);
if(p_ptr->lev > 19) add_flag(flgs, TR_FREE_ACT);
if(p_ptr->lev > 29) add_flag(flgs, TR_RES_POIS);
if(p_ptr->lev > 39) add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_KEINE:
if(p_ptr->lev > 9) add_flag(flgs, TR_SEE_INVIS);
if(p_ptr->lev > 19) add_flag(flgs, TR_RES_CONF);
if(p_ptr->lev > 34) add_flag(flgs, TR_SUST_INT);
if(p_ptr->lev > 34) add_flag(flgs, TR_SUST_WIS);
break;
case CLASS_YUGI:
if(p_ptr->lev > 9) add_flag(flgs, TR_RES_FIRE);
if(p_ptr->lev > 14) add_flag(flgs, TR_RES_COLD);
if(p_ptr->lev > 19) add_flag(flgs, TR_SUST_STR);
if(p_ptr->lev > 29) add_flag(flgs, TR_RES_LITE);

break;
case CLASS_REIMU:
{
int rank = osaisen_rank();
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_HOLY);
if(rank > 2) add_flag(flgs, TR_SEE_INVIS);
if(rank > 7) add_flag(flgs, TR_DEC_MANA);
if(rank > 8)
{
add_flag(flgs, TR_RES_ACID);
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_ELEC);
add_flag(flgs, TR_RES_POIS);
}
if(plev > 4 && rank > 3) add_flag(flgs, TR_SLOW_DIGEST);
if(plev > 4 && rank > 6) add_flag(flgs, TR_REGEN);
if(plev > 9 && rank > 4) add_flag(flgs, TR_FREE_ACT);
if(plev > 14 && rank > 3) add_flag(flgs, TR_RES_FEAR);
if(plev > 19) add_flag(flgs, TR_ESP_KWAI);
if(plev > 19 && rank > 4) add_flag(flgs, TR_RES_CONF);
if(plev > 24 && rank > 1) add_flag(flgs, TR_ESP_UNDEAD);
if(plev > 24 && rank > 5) add_flag(flgs, TR_RES_NETHER);
if(plev > 29 && rank > 2) add_flag(flgs, TR_ESP_DEMON);
if(plev > 34 && rank > 5) add_flag(flgs, TR_ESP_EVIL);
if(plev > 34 && rank > 4) add_flag(flgs, TR_RES_LITE);
if(plev > 39 && rank > 8) add_flag(flgs, TR_RES_TIME);
if(plev > 39 && rank > 6) add_flag(flgs, TR_RES_CHAOS);
if(plev > 44 && rank > 7) add_flag(flgs, TR_RES_INSANITY);
}
break;
case CLASS_KAGEROU:
if(p_ptr->lev > 19) add_flag(flgs, TR_SEE_INVIS);
if(p_ptr->lev > 39) add_flag(flgs, TR_SPEEDSTER);
break;
case CLASS_SANAE:
if(p_ptr->lev > 9) add_flag(flgs, TR_ESP_DEITY);
if(p_ptr->lev > 19) add_flag(flgs, TR_LEVITATION);
if(p_ptr->lev > 39) add_flag(flgs, TR_RES_HOLY);
break;
case CLASS_REMY:
add_flag(flgs, TR_LEVITATION);
if(p_ptr->lev > 19) add_flag(flgs, TR_RES_FEAR);
break;
case CLASS_BYAKUREN:
add_flag(flgs, TR_RES_HOLY);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_FEAR);
if(p_ptr->tim_general[0]) //白蓮強化時
{
add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_LITE);
if(p_ptr->lev > 4) add_flag(flgs, TR_RES_FIRE);
if(p_ptr->lev > 4) add_flag(flgs, TR_RES_COLD);
if(p_ptr->lev > 9) add_flag(flgs, TR_RES_ELEC);
if(p_ptr->lev > 9) add_flag(flgs, TR_RES_ACID);
if(p_ptr->lev > 19) add_flag(flgs, TR_RES_POIS);
if(p_ptr->lev > 24) add_flag(flgs, TR_SUST_STR);
if(p_ptr->lev > 24) add_flag(flgs, TR_SUST_CON);
if(p_ptr->lev > 24) add_flag(flgs, TR_SUST_DEX);
if(p_ptr->lev > 29) add_flag(flgs, TR_RES_LITE);
if(p_ptr->lev > 34) add_flag(flgs, TR_THROW);
if(p_ptr->lev > 34) add_flag(flgs, TR_SPEEDSTER);
if(p_ptr->lev > 39) add_flag(flgs, TR_RES_CHAOS);
if(p_ptr->lev > 39) add_flag(flgs, TR_RES_DISEN);
if(p_ptr->lev > 44) add_flag(flgs, TR_IM_FIRE);
}
break;
case CLASS_SEIJA:
if(plev > 39) add_flag(flgs, TR_RES_TIME);
break;
case CLASS_UTSUHO:
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_LITE);
if(plev > 19) add_flag(flgs, TR_SH_FIRE);
if(plev > 24) add_flag(flgs, TR_RES_BLIND);
if(plev > 29) add_flag(flgs, TR_RES_DARK);
if(plev > 34) add_flag(flgs, TR_IM_FIRE);
break;

case CLASS_YAMAME:
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_TUNNEL);

if(plev > 9) add_flag(flgs, TR_FREE_ACT);
if(plev > 24) add_flag(flgs, TR_SEE_INVIS);
if(plev > 39) add_flag(flgs, TR_RES_DARK);
break;

case CLASS_MARTIAL_ARTIST:
if(!heavy_armor() && plev > 9)
add_flag(flgs, TR_SPEED);
if(plev > 19) add_flag(flgs, TR_RES_FEAR);
if(plev > 29) add_flag(flgs, TR_SUST_STR);
if(plev > 39) add_flag(flgs, TR_LEVITATION);
break;

case CLASS_SUWAKO:
add_flag(flgs, TR_RES_WATER);
add_flag(flgs, TR_SEE_INVIS);
if(plev > 9) add_flag(flgs, TR_RES_NETHER);
if(plev > 19) add_flag(flgs, TR_RES_FEAR);
if(plev > 29) add_flag(flgs, TR_RES_DARK);
if(plev > 39) add_flag(flgs, TR_RES_CHAOS);
break;
case CLASS_RAN:
if(plev > 4) add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_RES_POIS);
break;
case CLASS_EIKI:
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_HOLY);
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_RES_INSANITY);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_ESP_UNIQUE);
if(plev > 29) add_flag(flgs, TR_RES_CHAOS);
if(plev > 39) add_flag(flgs, TR_TELEPATHY);
break;

case CLASS_MEIRIN:
add_flag(flgs, TR_REGEN);
if(plev > 4)add_flag(flgs, TR_RES_FIRE);
if(plev > 14)add_flag(flgs, TR_SEE_INVIS);
if(plev > 24)add_flag(flgs, TR_FREE_ACT);
if(plev > 34)add_flag(flgs, TR_RES_LITE);

break;
case CLASS_PARSEE:
add_flag(flgs, TR_RES_WATER);
add_flag(flgs, TR_RES_ACID);
if(plev > 19) add_flag(flgs, TR_RES_FEAR);
if(plev > 34) add_flag(flgs, TR_RES_NETHER);
break;
case CLASS_SHINMYOU_2:
add_flag(flgs, TR_RES_WATER);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_LEVITATION);
if(prace_is_(RACE_KOBITO)) add_flag(flgs, TR_SPEEDSTER);
if(plev > 9) add_flag(flgs, TR_SPEED);
break;
case CLASS_SUMIREKO:
add_flag(flgs, TR_LEVITATION);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_FIRE);
if (p_ptr->lev > 19) add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_TIME);
break;
case CLASS_ICHIRIN:
add_flag(flgs, TR_WARNING);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_ELEC);
if (p_ptr->lev > 34) add_flag(flgs, TR_RES_LITE);
break;
case CLASS_MOKOU:
add_flag(flgs, TR_RES_FIRE);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_LITE);
break;
case CLASS_KANAKO:
{
int rank = kanako_rank();
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_SEE_INVIS);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_ELEC);
if (p_ptr->lev > 14) add_flag(flgs, TR_FREE_ACT);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_POIS);
if (rank > 2) add_flag(flgs, TR_RES_FEAR);
if (rank > 4) add_flag(flgs, TR_REGEN);
if (rank > 4) add_flag(flgs, TR_SLOW_DIGEST);
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_HIZIRIN) add_flag(flgs, TR_RES_HOLY);;
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_MIMIMI) add_flag(flgs, TR_RES_LITE);;
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_REIMU) add_flag(flgs, TR_RES_TIME);
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_CTHULHU) add_flag(flgs, TR_RES_WATER);
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_OBERON) add_flag(flgs, TR_RES_DISEN);
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_AZAT) add_flag(flgs, TR_RES_INSANITY);
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_MORGOTH) add_flag(flgs, TR_RES_DARK);
if(p_ptr->magic_num2[0] & KANAKO_BEAT_0_J) add_flag(flgs, TR_RES_CHAOS);

break;
}
case CLASS_FUTO:
if (p_ptr->lev > 4) add_flag(flgs, TR_RES_FIRE);
if (p_ptr->lev > 14) add_flag(flgs, TR_RES_WATER);
if (p_ptr->lev > 24) add_flag(flgs, TR_LEVITATION);
if (p_ptr->lev > 34) add_flag(flgs, TR_WARNING);
break;
case CLASS_SUNNY:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_LITE);
if (p_ptr->magic_num1[0])add_flag(flgs, TR_LITE);//v1.1.59
if (p_ptr->magic_num1[0] >= SUNNY_CHARGE_SUNLIGHT_3) add_flag(flgs, TR_SH_FIRE);
break;
case CLASS_LUNAR:
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_DARK);
if (p_ptr->lev > 29) add_flag(flgs, TR_RES_SOUND);
break;
case CLASS_STAR:
if(plev > 19) add_flag(flgs, TR_RES_CONF);
break;

case CLASS_3_FAIRIES:
if (p_ptr->lev > 24) add_flag(flgs, TR_RES_LITE);
if (p_ptr->lev > 34) add_flag(flgs, TR_RES_SOUND);
if (is_special_seikaku(SEIKAKU_SPECIAL_3_FAIRIES))
{
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_FREE_ACT);
}
if (p_ptr->magic_num1[0])add_flag(flgs, TR_LITE);//v1.1.59

break;

case CLASS_ALICE:
//アリスの人形が装備している盾
for(i=0;i<INVEN_DOLL_NUM_MAX;i++)
{
if(!inven_add[i].k_idx) continue;
o_ptr = &inven_add[i];
if(object_is_melee_weapon(o_ptr)) continue;
object_flags(o_ptr, doll_flgs);

if (have_flag(doll_flgs, TR_RES_ACID)) add_flag(flgs, TR_RES_ACID);
if (have_flag(doll_flgs, TR_RES_ELEC)) add_flag(flgs, TR_RES_ELEC);
if (have_flag(doll_flgs, TR_RES_FIRE)) add_flag(flgs, TR_RES_FIRE);
if (have_flag(doll_flgs, TR_RES_COLD)) add_flag(flgs, TR_RES_COLD);
if (have_flag(doll_flgs, TR_RES_POIS)) add_flag(flgs, TR_RES_POIS);
if (have_flag(doll_flgs, TR_RES_LITE)) add_flag(flgs, TR_RES_LITE);
if (have_flag(doll_flgs, TR_RES_DARK)) add_flag(flgs, TR_RES_DARK);
if (have_flag(doll_flgs, TR_RES_SHARDS)) add_flag(flgs, TR_RES_SHARDS);
if (have_flag(doll_flgs, TR_RES_WATER)) add_flag(flgs, TR_RES_WATER);
if (have_flag(doll_flgs, TR_RES_HOLY)) add_flag(flgs, TR_RES_HOLY);
if (have_flag(doll_flgs, TR_RES_SOUND)) add_flag(flgs, TR_RES_SOUND);
if (have_flag(doll_flgs, TR_RES_NETHER)) add_flag(flgs, TR_RES_NETHER);
if (have_flag(doll_flgs, TR_RES_CHAOS)) add_flag(flgs, TR_RES_CHAOS);
if (have_flag(doll_flgs, TR_RES_DISEN)) add_flag(flgs, TR_RES_DISEN);
if (have_flag(doll_flgs, TR_RES_TIME)) add_flag(flgs, TR_RES_TIME);

if (have_flag(doll_flgs, TR_FREE_ACT)) add_flag(flgs, TR_FREE_ACT);
if (have_flag(doll_flgs, TR_RES_BLIND)) add_flag(flgs, TR_RES_BLIND);
if (have_flag(doll_flgs, TR_RES_FEAR)) add_flag(flgs, TR_RES_FEAR);
if (have_flag(doll_flgs, TR_RES_CONF)) add_flag(flgs, TR_RES_CONF);
if (have_flag(doll_flgs, TR_RES_INSANITY)) add_flag(flgs, TR_RES_INSANITY);

if (have_flag(doll_flgs, TR_REFLECT)) add_flag(flgs, TR_REFLECT);
}
break;
case CLASS_MARISA:
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_POIS);
if(plev > 6) add_flag(flgs, TR_SPEED);
if(plev > 9) add_flag(flgs, TR_RES_FIRE);
if(plev > 19) add_flag(flgs, TR_FREE_ACT);
if(plev > 24) add_flag(flgs, TR_SPEEDSTER);
if(plev > 29) add_flag(flgs, TR_RES_LITE);
break;

case CLASS_LUNASA:
add_flag(flgs, TR_RES_SOUND);
if(plev > 19) add_flag(flgs, TR_RES_CONF);
if(plev > 34) add_flag(flgs, TR_WARNING);

break;

case CLASS_MERLIN:
add_flag(flgs, TR_RES_SOUND);
if(plev > 19) add_flag(flgs, TR_RES_FEAR);
if(plev > 34) add_flag(flgs, TR_RES_INSANITY);
break;

case CLASS_LYRICA:
add_flag(flgs, TR_RES_SOUND);
if(plev > 19) add_flag(flgs, TR_RES_BLIND);
break;

case CLASS_CLOWNPIECE:
add_flag(flgs, TR_RES_INSANITY);
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_NETHER);
if(plev > 19) add_flag(flgs, TR_RES_CONF);
if(plev > 8) add_flag(flgs, TR_SPEED);
break;
case CLASS_DOREMY:
add_flag(flgs, TR_FREE_ACT);
if(plev > 14) add_flag(flgs, TR_SEE_INVIS);
if(plev > 24) add_flag(flgs, TR_RES_CHAOS);
if(plev > 39) add_flag(flgs, TR_RES_INSANITY);
if(IN_DREAM_WORLD) add_flag(flgs, TR_TELEPATHY);
break;

case CLASS_YATSUHASHI:
case CLASS_BENBEN:
if(plev > 19) add_flag(flgs, TR_RES_SOUND);
break;
case CLASS_HINA:
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_DARK);
add_flag(flgs, TR_RES_NETHER);
if(plev > 24) add_flag(flgs, TR_RES_POIS);
if(p_ptr->magic_num1[0] > 14999) add_flag(flgs, TR_RES_INSANITY);
if(p_ptr->magic_num1[0] > 19999) add_flag(flgs, TR_REFLECT);
break;

case CLASS_SAKUYA:
add_flag(flgs, TR_FREE_ACT);
if(plev > 9) add_flag(flgs, TR_SLOW_DIGEST);
if(plev > 14) add_flag(flgs, TR_RES_TIME);
if(plev > 24) add_flag(flgs, TR_RES_FEAR);
if(plev > 39) add_flag(flgs, TR_SPEEDSTER);
if(plev > 7) add_flag(flgs, TR_SPEED);
break;
case CLASS_RAIKO:
add_flag(flgs, TR_RES_ELEC);
if(plev > 9) add_flag(flgs, TR_RES_SOUND);
if(plev > 19) add_flag(flgs, TR_RES_CONF);
if(plev > 34) add_flag(flgs, TR_LEVITATION);

break;
case CLASS_CHEMIST:
if(plev > 14) add_flag(flgs, TR_FREE_ACT);
if(plev > 29) add_flag(flgs, TR_RES_POIS);
break;

case CLASS_MAMIZOU:
add_flag(flgs, TR_SEE_INVIS);
if(plev > 14) add_flag(flgs, TR_FREE_ACT);
if(plev > 24) add_flag(flgs, TR_RES_CONF);
if(plev > 34) add_flag(flgs, TR_RES_CHAOS);
if(plev > 39) add_flag(flgs, TR_TELEPATHY);
break;

case CLASS_YUKARI:
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_RES_CONF);
if (p_ptr->lev > 14) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_CHAOS);
if (p_ptr->lev > 29) add_flag(flgs, TR_REFLECT);
break;
case CLASS_RINGO:
if(plev > 9) add_flag(flgs, TR_SEE_INVIS);
if(plev > 19) add_flag(flgs, TR_WARNING);
if(plev > 29) add_flag(flgs, TR_RES_CONF);
if(plev > 39) add_flag(flgs, TR_SUST_WIS);
if(plev > 39) add_flag(flgs, TR_SUST_INT);
break;

case CLASS_SEIRAN:
if(plev > 14) add_flag(flgs, TR_SEE_INVIS);
if(plev > 44) add_flag(flgs, TR_RES_TIME);
break;

case CLASS_EIRIN:
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_SUST_INT);
add_flag(flgs, TR_SUST_WIS);
if(plev > 14) add_flag(flgs, TR_SEE_INVIS);
if(plev > 34) add_flag(flgs, TR_RES_INSANITY);
break;
case CLASS_KAGUYA:
add_flag(flgs, TR_SUST_CHR);
if(plev > 9) add_flag(flgs, TR_LITE);
if(plev > 19) add_flag(flgs, TR_RES_DISEN);
if(plev > 29) add_flag(flgs, TR_RES_TIME);
if(plev > 39) add_flag(flgs, TR_RES_INSANITY);
break;

case CLASS_TOYOHIME:
add_flag(flgs, TR_RES_WATER);
if(plev > 19) add_flag(flgs, TR_RES_TIME);
if(plev > 34) add_flag(flgs, TR_ESP_EVIL);
break;

case CLASS_YORIHIME:
add_flag(flgs, TR_RES_WATER);
if(plev > 9) add_flag(flgs, TR_RES_LITE);
if(plev > 19) add_flag(flgs, TR_RES_DARK);
if(plev > 29) add_flag(flgs, TR_RES_SHARDS);
break;
case CLASS_HECATIA:
{
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_LITE);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_RES_FIRE);
if(plev > 19) add_flag(flgs, TR_RES_CONF);
if(plev > 29) add_flag(flgs, TR_RES_INSANITY);
if(plev > 39) add_flag(flgs, TR_EASY_SPELL);

if(hecatia_body_is_(HECATE_BODY_OTHER))
{
if(plev > 24) add_flag(flgs, TR_RES_CHAOS);
if(plev > 44) add_flag(flgs, TR_RES_TIME);
}
if(hecatia_body_is_(HECATE_BODY_MOON))
{
if(plev > 24) add_flag(flgs, TR_RES_DARK);
if(plev > 34) add_flag(flgs, TR_RES_LITE);
}
if(hecatia_body_is_(HECATE_BODY_EARTH))
{
if(plev > 24) add_flag(flgs, TR_RES_ACID);
if(plev > 24) add_flag(flgs, TR_RES_COLD);
if(plev > 24) add_flag(flgs, TR_RES_ELEC);
if(plev > 34) add_flag(flgs, TR_RES_POIS);
}
}
break;
case CLASS_JUNKO:
add_flag(flgs, TR_RES_HOLY);
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_RES_INSANITY);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_FREE_ACT);
break;

case CLASS_SOLDIER:
if(plev > 19) add_flag(flgs, TR_RES_FIRE);
if(plev > 29) add_flag(flgs, TR_RES_FEAR);
if(plev > 39) add_flag(flgs, TR_WARNING);

if(HAVE_SOLDIER_SKILL(SOLDIER_SKILL_SHOOT,SS_S_HAWK_EYE))
add_flag(flgs, TR_SEE_INVIS);
break;

case CLASS_NEMUNO:
if(IS_NEMUNO_IN_SANCTUARY)
{
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_SPEED);

}

if(plev > 24) add_flag(flgs, TR_RES_FEAR);
if(plev > 34) add_flag(flgs, TR_RES_WATER);
break;
case CLASS_AUNN:
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_ESP_DEITY);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_RES_HOLY);
if(plev > 14) add_flag(flgs, TR_ESP_KWAI);
if(plev > 14) add_flag(flgs, TR_ESP_DEMON);
if(plev > 19) add_flag(flgs, TR_SEE_INVIS);
if(plev > 24) add_flag(flgs, TR_RES_POIS);
if(plev > 29) add_flag(flgs, TR_ESP_EVIL);
if(plev > 34) add_flag(flgs, TR_RES_FEAR);

break;
case CLASS_NARUMI:
add_flag(flgs, TR_RES_HOLY);
if(is_special_seikaku(SEIKAKU_SPECIAL_NARUMI)) add_flag(flgs, TR_REGEN);
break;

case CLASS_LARVA:
if (plev > 29) add_flag(flgs, TR_SUST_CON);
if (plev > 39) add_flag(flgs, TR_RES_POIS);

break;

case CLASS_MAI:
case CLASS_SATONO:
if (plev > 9) add_flag(flgs, TR_SUST_CHR);
if (plev > 19) add_flag(flgs, TR_RES_CONF);
if (plev > 29) add_flag(flgs, TR_RES_CHAOS);
if (plev > 39) add_flag(flgs, TR_RES_INSANITY);

break;

case CLASS_VFS_CLOWNPIECE:
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_NETHER);
if (plev > 19) add_flag(flgs, TR_RES_INSANITY);
break;

case CLASS_JYOON:
if (plev > 14) add_flag(flgs, TR_LITE);
if (plev > 19) add_flag(flgs, TR_FREE_ACT);
if (plev > 34) add_flag(flgs, TR_RES_LITE);
break;

case CLASS_SHION:
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_LEVITATION);
if (plev > 9) add_flag(flgs, TR_SEE_INVIS);
if (plev > 19) add_flag(flgs, TR_RES_CONF);
if (plev > 29) add_flag(flgs, TR_RES_CHAOS);
break;

case CLASS_OKINA:
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_LEVITATION);
if (plev > 9) add_flag(flgs, TR_RES_CONF);
if (plev > 19) add_flag(flgs, TR_RES_DARK);
if (plev > 24) add_flag(flgs, TR_RES_ACID);
if (plev > 24) add_flag(flgs, TR_RES_ELEC);
if (plev > 24) add_flag(flgs, TR_RES_FIRE);
if (plev > 24) add_flag(flgs, TR_RES_COLD);
if (plev > 29) add_flag(flgs, TR_RES_CHAOS);
if (plev > 39) add_flag(flgs, TR_RES_TIME);
break;

case CLASS_MAYUMI:
add_flag(flgs, TR_SUST_CON);
add_flag(flgs, TR_RES_FEAR);
if (plev > 19) add_flag(flgs, TR_RES_CONF);
if (plev > 29) add_flag(flgs, TR_RES_COLD);

break;

case CLASS_KUTAKA:
add_flag(flgs, TR_WARNING);
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_POIS);
if (plev > 19) add_flag(flgs, TR_RES_WATER);
break;

case CLASS_URUMI:
add_flag(flgs, TR_RES_WATER);
if (plev > 19) add_flag(flgs, TR_RES_FEAR);
break;

case CLASS_SAKI:
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_RES_DARK);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_SPEED);
if (plev>9) add_flag(flgs, TR_RES_ELEC);
if (plev>19) add_flag(flgs, TR_ESP_UNDEAD);
if (plev>19) add_flag(flgs, TR_SUST_STR);
break;

case CLASS_YACHIE:
add_flag(flgs, TR_RES_WATER);
if (plev >14)add_flag(flgs, TR_RES_FIRE);
if (plev >19)add_flag(flgs, TR_RES_ELEC);
if (plev >24)add_flag(flgs, TR_RES_ACID);

if (plev >19)add_flag(flgs, TR_ESP_UNDEAD);
if (plev >29)add_flag(flgs, TR_RES_CONF);
break;

case CLASS_KEIKI:
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_WATER);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_SUST_DEX);
if (plev > 24) add_flag(flgs, TR_ESP_NONLIVING);
break;

case CLASS_MIKE:
if(plev > 29) add_flag(flgs, TR_RES_HOLY);

break;
case CLASS_TAKANE:

if (plev > 24) add_flag(flgs, TR_RES_CONF);
if (plev > 44) add_flag(flgs, TR_ESP_UNIQUE);
break;

case CLASS_SANNYO:

if (plev > 19) add_flag(flgs, TR_RES_FEAR);
if (plev > 29) add_flag(flgs, TR_RES_CONF);

break;

case CLASS_MOMOYO:
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_TUNNEL);

if(plev > 29)add_flag(flgs, TR_RES_NETHER);
if (plev > 34)add_flag(flgs, TR_SUST_STR);
if (plev > 34)add_flag(flgs, TR_SUST_DEX);
if (plev > 34)add_flag(flgs, TR_SUST_CON);

if (plev > 34)add_flag(flgs, TR_BRAND_POIS);

if (plev > 23) add_flag(flgs, TR_BLOWS);

break;


default:
break; /* Do nothing */
}





/* Races */
if (p_ptr->mimic_form && p_ptr->mimic_form != MIMIC_GIGANTIC)
{
switch(p_ptr->mimic_form)
{
case MIMIC_DEMON:
//add_flag(flgs, TR_HOLD_LIFE);
add_flag(flgs, TR_RES_CHAOS);
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_SPEED);
break;
case MIMIC_DEMON_LORD:
//add_flag(flgs, TR_HOLD_LIFE);
add_flag(flgs, TR_RES_CHAOS);
add_flag(flgs, TR_RES_NETHER);
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_ELEC);
add_flag(flgs, TR_RES_ACID);
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_RES_DISEN);
//add_flag(flgs, TR_RES_NEXUS);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_IM_FIRE);
add_flag(flgs, TR_SH_FIRE);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_TELEPATHY);
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_SPEED);
break;
case MIMIC_VAMPIRE:
//add_flag(flgs, TR_HOLD_LIFE);
add_flag(flgs, TR_RES_DARK);
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_NETHER);
if (p_ptr->pclass != CLASS_NINJA) add_flag(flgs, TR_LITE);
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_SPEED);
break;
case MIMIC_BEAST:
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_ELEC);
add_flag(flgs, TR_RES_ACID);
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_SPEEDSTER);
add_flag(flgs, TR_WARNING);
break;
case MIMIC_SLIME:
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_ELEC);
add_flag(flgs, TR_RES_ACID);
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_RES_CONF);
add_flag(flgs, TR_RES_FEAR);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_RES_INSANITY);
add_flag(flgs, TR_RES_BLIND);
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_RES_SHARDS);
add_flag(flgs, TR_RES_SOUND);
add_flag(flgs, TR_RES_WATER);
break;
case MIMIC_MARISA:
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_SPEEDSTER);
break;
case MIMIC_MIST:
{
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_RES_BLIND);
add_flag(flgs, TR_RES_SHARDS);
add_flag(flgs, TR_RES_SOUND);
break;
}
case MIMIC_DRAGON:
{
int rank =p_ptr->mimic_dragon_rank;
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_ELEC);
add_flag(flgs, TR_RES_ACID);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_SPEED);

if(rank > 99) add_flag(flgs, TR_RES_POIS);
if(rank > 99) add_flag(flgs, TR_LEVITATION);
if(rank > 99) add_flag(flgs, TR_SEE_INVIS);

if(rank > 102) add_flag(flgs, TR_RES_FEAR);
if(rank > 104) add_flag(flgs, TR_REGEN);
if(rank > 106) add_flag(flgs, TR_RES_CONF);

if(rank > 110) add_flag(flgs, TR_RES_CHAOS);
if(rank > 112) add_flag(flgs, TR_RES_WATER);
if(rank > 114) add_flag(flgs, TR_RES_BLIND);

if(rank > 116) add_flag(flgs, TR_SUST_STR);
if(rank > 117) add_flag(flgs, TR_SUST_CON);
if(rank > 118) add_flag(flgs, TR_SUST_DEX);
if(rank > 119) add_flag(flgs, TR_RES_LITE);
if(rank > 120) add_flag(flgs, TR_RES_DARK);

if(rank > 124) add_flag(flgs, TR_TELEPATHY);
if(rank > 126) add_flag(flgs, TR_RES_SHARDS);

if(rank > 127) add_flag(flgs, TR_RES_SOUND);
if(rank > 128) add_flag(flgs, TR_RES_NETHER);

/*:::一時強化抜きではrankの限界は130まで*/
if(rank > 134) add_flag(flgs, TR_RES_DISEN);
if(rank > 134) add_flag(flgs, TR_SUST_INT);
if(rank > 134) add_flag(flgs, TR_SUST_WIS);
if(rank > 134) add_flag(flgs, TR_SUST_CHR);

if(rank >139) add_flag(flgs, TR_RES_TIME);
if(rank >144) add_flag(flgs, TR_RES_HOLY);
if(rank >144) add_flag(flgs, TR_SPEEDSTER);

if(rank > 149) add_flag(flgs, TR_RES_INSANITY);
break;
}
case MIMIC_CAT:
add_flag(flgs, TR_RES_FIRE);
add_flag(flgs, TR_RES_COLD);
add_flag(flgs, TR_RES_ELEC);
add_flag(flgs, TR_RES_ACID);
add_flag(flgs, TR_RES_POIS);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_REGEN);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_SPEED);
add_flag(flgs, TR_SPEEDSTER);
add_flag(flgs, TR_WARNING);
break;
case MIMIC_NUE:
add_flag(flgs, TR_LEVITATION);
add_flag(flgs, TR_RES_DARK);
add_flag(flgs, TR_FREE_ACT);
add_flag(flgs, TR_SEE_INVIS);
add_flag(flgs, TR_RES_POIS);
if (p_ptr->lev > 4) add_flag(flgs, TR_RES_FIRE);
if (p_ptr->lev > 9) add_flag(flgs, TR_RES_COLD);
if (p_ptr->lev > 14) add_flag(flgs, TR_RES_ELEC);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_ACID);
if (p_ptr->lev > 19) add_flag(flgs, TR_RES_CHAOS);
if (p_ptr->lev > 24) add_flag(flgs, TR_RES_NETHER);
if (p_ptr->lev > 29) add_flag(flgs, TR_SPEEDSTER);
if (p_ptr->lev > 34) add_flag(flgs, TR_RES_FEAR);
if (p_ptr->lev > 39) add_flag(flgs, TR_REGEN);
if (p_ptr->lev > 39) add_flag(flgs, TR_SLOW_DIGEST);
if (p_ptr->lev > 39) add_flag(flgs, TR_RES_INSANITY);
break;


case MIMIC_METAMORPHOSE_NORMAL:
case MIMIC_METAMORPHOSE_MONST:
case MIMIC_METAMORPHOSE_GIGANTIC:
{
monster_race *r_ptr = &r_info[MON_EXTRA_FIELD];

if(r_ptr->flags2 & RF2_REFLECTING) add_flag(flgs, TR_REFLECT);
if(r_ptr->flags2 & RF2_REGENERATE) add_flag(flgs, TR_REGEN);
if(r_ptr->flags2 & RF2_ELDRITCH_HORROR || r_ptr->flags3 & (RF3_UNDEAD | RF3_DEMON)) add_flag(flgs, TR_RES_INSA
お知らせ
実務でも趣味でも役に立つ多機能Webツールサイト【無限ツールズ】で、日常をちょっと便利にしちゃいましょう!
無限ツールズ

 
writening