M:WY:66
# Maximum number of monsters in r_info.txt
-M:R:1067
+M:R:1068
# Maximum number of items in k_info.txt
M:K:654
D:µðÂç¤Ç¤È¤Æ¤â¶¯ÎϤʥɥ饴¥ó¤À¡£·ã¤·¤¯¾øµ¤¤ò¿á¤¤À¤¹»À¤òÃÏÌ̤ËÅ©¤é¤»¡¢
D:Å©¤Ã¤¿»À¤Ï¥À¥ó¥¸¥ç¥ó¤Î´äÀФò¤¢¤Ã¤È¤¤¤¦´Ö¤ËÍϲò¤··ê¤ò¶õ¤±¤Æ¤¤¤ë¡Ä
D:¤³¤ì¤¬¤¢¤Ê¤¿¤ËÅö¤¿¤Ã¤¿¤é¤É¤¦¤Ê¤ë¤³¤È¤«¡ª
+
+N:1067:¤¿¤Ì¤
+E:Tanuki
+G:q:U
+I:120:30d20:18:5:40
+W:24:10:0:200:0:0
+B:HIT:HURT:1d5
+B:CRUSH:HURT:1d6
+F:TAKE_ITEM | OPEN_DOOR | DROP_CORPSE | RAND_25
+F:ANIMAL | TANUKI
+D:$Tanuki (raccoon dog) is thought to bewitch people in Japanese.
+D:$Tanuki can disguise as human beings by putting a magic leaf on his/her head.
+D:ÆüËܤÎÅÁÀâ¤Ç¤Ï¡¢¤¿¤Ì¤¤Ï¿Í¤ò²½¤«¤¹¤ÈÅÁ¤¨¤é¤ì¤Æ¤¤¤ë¡£
+D:ËâË¡¤ÎÌÚ¤ÎÍÕ¤òƬ¤ËºÜ¤»¤Æ¿Í¤Ë²½¤±¤ë¤Î¤À¡£
***************************************
- ** Hengband 1.0.10 English version **
+ ** Hengband 1.0.12 English version **
***************************************
Based on Moria: Copyright (c) 1985 Robert Alan Koeneke
***************************************
- ** ÊѶòÈÚÅÜ 1.0.10 **
+ ** ÊѶòÈÚÅÜ 1.0.12 **
***************************************
Based on Moria: Copyright (c) 1985 Robert Alan Koeneke
if (m_ptr->ml)
{
monster_race *r_ptr;
- if (m_ptr->mflag2 & MFLAG_KAGE) r_ptr = &r_info[MON_KAGE];
- else r_ptr = &r_info[m_ptr->r_idx];
+ r_ptr = &r_info[m_ptr->ap_r_idx];
/* Desired attr */
a = r_ptr->x_attr;
/*
* Hack -- track the given monster race
*/
-void monster_race_track(bool kage, int r_idx)
+void monster_race_track(int r_idx)
{
- if (kage) r_idx = MON_KAGE;
-
/* Save this monster ID */
p_ptr->monster_race_idx = r_idx;
monster_desc(m_name, m_ptr, 0);
/* Auto-Recall if possible and visible */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Track a new monster */
if (m_ptr->ml) health_track(c_ptr->m_idx);
monster_desc(m_name, m_ptr, 0);
/* Auto-Recall if possible and visible */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Track a new monster */
if (m_ptr->ml) health_track(c_ptr->m_idx);
/* Hack -- Track this monster race */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Hack -- Track this monster */
if (m_ptr->ml) health_track(c_ptr->m_idx);
/* Hack -- Track this monster race */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Hack -- Track this monster */
if (m_ptr->ml) health_track(c_ptr->m_idx);
r_idx = who[i];
/* Hack -- Auto-recall */
- monster_race_track(FALSE, r_idx);
+ monster_race_track(r_idx);
/* Hack -- Handle stuff */
handle_stuff();
#define FAKE_VERSION 0
#define FAKE_VER_MAJOR 11
#define FAKE_VER_MINOR 0
-#define FAKE_VER_PATCH 11
+#define FAKE_VER_PATCH 12
#define ANGBAND_2_8_1
#define ZANGBAND
#define RF7_CAN_FLY 0x00000004 /* Monster can fly */
#define RF7_FRIENDLY 0x00000008 /* Monster is friendly */
#define RF7_UNIQUE_7 0x00000010 /* Is a "Nazgul" unique */
-#define RF7_UNIQUE2 0x00000020 /* uso unique */
-#define RF7_RIDING 0x00000040 /* Can riding */
+#define RF7_UNIQUE2 0x00000020 /* Fake unique */
+#define RF7_RIDING 0x00000040 /* Good for riding */
#define RF7_KAGE 0x00000080 /* Is kage */
#define RF7_HAS_LITE_1 0x00000100 /* Monster carries light */
#define RF7_SELF_LITE_1 0x00000200 /* Monster lights itself */
#define RF7_HAS_LITE_2 0x00000400 /* Monster carries light */
#define RF7_SELF_LITE_2 0x00000800 /* Monster lights itself */
-#define RF7_GUARDIAN 0x00001000
-#define RF7_CHAMELEON 0x00002000
-#define RF7_KILL_EXP 0x00004000
+#define RF7_GUARDIAN 0x00001000 /* Guardian of a dungeon */
+#define RF7_CHAMELEON 0x00002000 /* Chameleon can change */
+#define RF7_KILL_EXP 0x00004000 /* No exp until you kill it */
+#define RF7_TANUKI 0x00008000 /* Tanuki disguise */
/*
* Monster race flags
#define MON_TOPAZ_MONK 1047
#define MON_LOUSY 1063
#define MON_JIZOTAKO 1065
+#define MON_TANUKI 1067
#define MAX_AUTOPICK 1009
#define DO_AUTOPICK 0x01
extern bool projectable(int y1, int x1, int y2, int x2);
extern void scatter(int *yp, int *xp, int y, int x, int d, int mode);
extern void health_track(int m_idx);
-extern void monster_race_track(bool kage, int r_idx);
+extern void monster_race_track(int r_idx);
extern void object_kind_track(int k_idx);
extern void disturb(int stop_search, int flush_output);
cave[cy][cx].m_idx = m_idx;
m_ptr->r_idx = party_mon[i].r_idx;
+ m_ptr->ap_r_idx = party_mon[i].ap_r_idx;
m_ptr->fy = cy;
m_ptr->fx = cx;
m_ptr->cdis = party_mon[i].cdis;
"GUARDIAN",
"CHAMELEON",
"KILL_EXP",
- "XXX7X15",
+ "TANUKI",
"XXX7X16",
"XXX7X17",
"XXX7X18",
/* Read the monster race */
rd_s16b(&m_ptr->r_idx);
+ if (z_older_than(11, 0, 12))
+ m_ptr->ap_r_idx = m_ptr->r_idx;
+ else
+ rd_s16b(&m_ptr->ap_r_idx);
+
/* Read the other information */
rd_byte(&m_ptr->fy);
rd_byte(&m_ptr->fx);
rd_byte(&m_ptr->mflag2);
}
+ if (z_older_than(11, 0, 12))
+ {
+ if (m_ptr->mflag2 & MFLAG_KAGE)
+ m_ptr->ap_r_idx = MON_KAGE;
+ }
+
if (z_older_than(10, 1, 3))
{
m_ptr->nickname = 0;
if (!p_ptr->inside_battle)
{
/* Hack! "Cyber" monster makes noise... */
- if (m_ptr->r_idx == MON_CYBER &&
+ if (m_ptr->ap_r_idx == MON_CYBER &&
one_in_(CYBERNOISE) &&
!m_ptr->ml && (m_ptr->cdis <= MAX_SIGHT))
{
}
/* Some monsters can speak */
- if ((r_ptr->flags2 & RF2_CAN_SPEAK) && aware &&
+ if ((r_info[m_ptr->ap_r_idx].flags2 & RF2_CAN_SPEAK) && aware &&
one_in_(SPEAK_CHANCE) &&
player_has_los_bold(oy, ox))
{
/* Get the monster line */
- if (get_rnd_line(filename, m_ptr->r_idx, monmessage) == 0)
+ if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0)
{
/* Say something */
#ifdef JP
monster_desc(m_name, m_ptr, 0);
m_ptr->r_idx = r_ptr->next_r_idx;
+ m_ptr->ap_r_idx = m_ptr->r_idx;
r_ptr = &r_info[m_ptr->r_idx];
if (r_ptr->flags1 & RF1_FORCE_MAXHP)
{
* 0x40 --> Assume the monster is hidden
* 0x80 --> Assume the monster is visible
* 0x100 --> Chameleon's true name
- * 0x200 --> Ignore hallucination
+ * 0x200 --> Ignore hallucination, and penetrate shape change
*
* Useful Modes:
* 0x00 --> Full nominative name ("the kobold") or "it"
bool seen, pron;
bool named = FALSE;
- if (m_ptr->mflag2 & MFLAG_KAGE) r_ptr = &r_info[MON_KAGE];
- else r_ptr = &r_info[m_ptr->r_idx];
+ r_ptr = &r_info[m_ptr->ap_r_idx];
if ((mode & 0x100) && (m_ptr->mflag2 & MFLAG_CHAMELEON))
{
/* Handle all other visible monster requests */
else
{
+ /* Tanuki? */
+ if (is_pet(m_ptr) && m_ptr->ap_r_idx != m_ptr->r_idx)
+ {
+#ifdef JP
+ char *t;
+ strcpy(buf, name);
+ t = buf;
+ while(strncmp(t, "¡Ù", 2) && *t) t++;
+ if (*t)
+ {
+ *t = '\0';
+ (void)sprintf(desc, "%s¡©¡Ù", buf);
+ }
+ else
+ (void)sprintf(desc, "%s¡©", name);
+#else
+ (void)sprintf(desc, "%s?", name);
+#endif
+ }
+ else
+
/* It could be a Unique */
if ((r_ptr->flags1 & RF1_UNIQUE) && !(p_ptr->image && !(mode & 0x200)))
{
#endif
(void)strcat(desc, name);
-
- if (m_ptr->nickname)
- {
-#ifdef JP
- sprintf(buf,"¡Ö%s¡×",quark_str(m_ptr->nickname));
-#else
- sprintf(buf," called %s",quark_str(m_ptr->nickname));
-#endif
- strcat(desc,buf);
- }
}
/* It could be a normal, definite, monster */
#endif
(void)strcat(desc, name);
+ }
- if (m_ptr->nickname)
- {
+ if (m_ptr->nickname)
+ {
#ifdef JP
- sprintf(buf,"¡Ö%s¡×",quark_str(m_ptr->nickname));
+ sprintf(buf,"¡Ö%s¡×",quark_str(m_ptr->nickname));
#else
- sprintf(buf," called %s",quark_str(m_ptr->nickname));
+ sprintf(buf," called %s",quark_str(m_ptr->nickname));
#endif
- strcat(desc,buf);
- }
+ strcat(desc,buf);
+ }
- if ((m_ptr->fy == py) && (m_ptr->fx == px))
+ if ((m_ptr->fy == py) && (m_ptr->fx == px))
+ {
#ifdef JP
- strcat(desc,"(¾èÇÏÃæ)");
+ strcat(desc,"(¾èÇÏÃæ)");
#else
- strcat(desc,"(riding)");
+ strcat(desc,"(riding)");
#endif
- if ((mode & 0x200) && (m_ptr->mflag2 & MFLAG_CHAMELEON))
+ }
+
+ if ((mode & 0x200) && (m_ptr->mflag2 & MFLAG_CHAMELEON))
+ {
+ if (r_ptr->flags1 & RF1_UNIQUE)
{
- if (r_ptr->flags1 & RF1_UNIQUE)
#ifdef JP
- strcat(desc,"(¥«¥á¥ì¥ª¥ó¤Î²¦)");
+ strcat(desc,"(¥«¥á¥ì¥ª¥ó¤Î²¦)");
#else
- strcat(desc,"(Chameleon Lord)");
+ strcat(desc,"(Chameleon Lord)");
#endif
- else
+ }
+ else
+ {
#ifdef JP
- strcat(desc,"(¥«¥á¥ì¥ª¥ó)");
+ strcat(desc,"(¥«¥á¥ì¥ª¥ó)");
#else
- strcat(desc,"(Chameleon)");
+ strcat(desc,"(Chameleon)");
#endif
}
}
+ if ((mode & 0x200) && m_ptr->ap_r_idx != m_ptr->r_idx)
+ {
+ strcat(desc, format("(%s)", r_name + r_info[m_ptr->r_idx].name));
+ }
+
/* Handle the Possessive as a special afterthought */
if (mode & 0x02)
{
/* XXX Check for trailing "s" */
-
+
/* Simply append "apostrophe" and "s" */
#ifdef JP
(void)strcat(desc, "¤Î");
if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
/* Hack -- Count "fresh" sightings */
- if ((m_ptr->mflag2 & MFLAG_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
+ if ((m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
r_info[MON_KAGE].r_sights++;
- else if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
+ else if (m_ptr->ap_r_idx == m_ptr->r_idx &&
+ r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
/* Eldritch Horror */
if (r_ptr->flags2 & RF2_ELDRITCH_HORROR)
}
m_ptr->r_idx = r_idx;
+ m_ptr->ap_r_idx = r_idx;
update_mon(m_idx, FALSE);
lite_spot(m_ptr->fy, m_ptr->fx);
if (born) return;
m_ptr->hp = (long)(m_ptr->hp * m_ptr->max_maxhp) / oldmaxhp;
}
+/*
+ * Set initial racial appearance of a monster
+ */
+static int initial_r_appearance(int r_idx)
+{
+ int ap_r_idx;
+ int min = MIN(base_level-5, 50);
+
+ if (!(r_info[r_idx].flags7 & RF7_TANUKI))
+ return r_idx;
+
+ get_mon_num_prep(monster_hook_chameleon, NULL);
+
+ while (1)
+ {
+ ap_r_idx = get_mon_num(base_level + 10);
+ if (r_info[ap_r_idx].flags7 & RF7_AQUATIC) continue;
+ if (r_info[ap_r_idx].level >= min) break;
+ }
+ return ap_r_idx;
+}
+
/*
* Attempt to place a monster of the given race at the given location.
/* Save the race */
m_ptr->r_idx = r_idx;
+ m_ptr->ap_r_idx = initial_r_appearance(r_idx);
/* Place the monster at the location */
m_ptr->fy = y;
m_ptr->mflag2 |= MFLAG_CHAMELEON;
rating++;
}
- else if (is_kage) m_ptr->mflag2 |= MFLAG_KAGE;
+ else if (is_kage)
+ {
+ m_ptr->ap_r_idx = MON_KAGE;
+ m_ptr->mflag2 |= MFLAG_KAGE;
+ }
+
if (no_pet) m_ptr->mflag2 |= MFLAG_NOPET;
/* Not visible */
static void wr_monster(monster_type *m_ptr)
{
wr_s16b(m_ptr->r_idx);
+ wr_s16b(m_ptr->ap_r_idx);
wr_byte(m_ptr->fy);
wr_byte(m_ptr->fx);
wr_s16b(m_ptr->hp);
monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
/* Hack -- auto-recall */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Hack - auto-track */
if (m_ptr->ml) health_track(cave[project_m_y][project_m_x].m_idx);
monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
/* Hack -- auto-recall */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Hack - auto-track */
if (m_ptr->ml) health_track(cave[project_m_y][project_m_x].m_idx);
monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
/* Hack -- auto-recall */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Hack - auto-track */
if (m_ptr->ml) health_track(cave[project_m_y][project_m_x].m_idx);
monster_type *m_ptr = &m_list[cave[y][x].m_idx];
/* Hack -- auto-recall */
- if (m_ptr->ml) monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx);
/* Hack - auto-track */
if (m_ptr->ml) health_track(cave[y][x].m_idx);
if (!probe) {msg_print("Probing...");msg_print(NULL);}
#endif
- if (m_ptr->mflag2 & MFLAG_KAGE)
+ if (m_ptr->ap_r_idx != m_ptr->r_idx)
{
- m_ptr->mflag2 &= ~(MFLAG_KAGE);
+ if (m_ptr->mflag2 & MFLAG_KAGE)
+ m_ptr->mflag2 &= ~(MFLAG_KAGE);
+
+ m_ptr->ap_r_idx = m_ptr->r_idx;
lite_spot(m_ptr->fy, m_ptr->fx);
}
/* Get "the monster" or "something" */
struct monster_type
{
s16b r_idx; /* Monster race index */
+ s16b ap_r_idx; /* Monster race appearance index */
byte fy; /* Y location on map */
byte fx; /* X location on map */
{
char m_name[80];
+ if (r_info[m_ptr->r_idx].flags7 & RF7_TANUKI)
+ {
+ r_ptr = &r_info[m_ptr->r_idx];
+ m_ptr->ap_r_idx = m_ptr->r_idx;
+ if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
+ }
+
/* Extract monster name */
monster_desc(m_name, m_ptr, 0x100);
else if (r_ptr->r_tkills < MAX_SHORT) r_ptr->r_tkills++;
/* Hack -- Auto-recall */
- monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ monster_race_track(m_ptr->ap_r_idx);
}
if ((m_ptr->r_idx == MON_BANOR) || (m_ptr->r_idx == MON_LUPART))
monster_desc(m_name, m_ptr, 0x08);
/* Hack -- track this monster race */
- monster_race_track((bool)(m_ptr->mflag2 & MFLAG_KAGE), m_ptr->r_idx);
+ monster_race_track(m_ptr->ap_r_idx);
/* Hack -- health bar for this monster */
health_track(c_ptr->m_idx);
screen_save();
/* Recall on screen */
- if (m_ptr->mflag2 & MFLAG_KAGE) screen_roff(MON_KAGE,0);
- else screen_roff(m_ptr->r_idx, 0);
+ screen_roff(m_ptr->ap_r_idx, 0);
/* Hack -- Complete the prompt (again) */
#ifdef JP
else if (p_ptr->riding)
{
monster_type *m_ptr = &m_list[p_ptr->riding];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];
if (m_ptr->confused)
{