X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmelee2.c;h=793690c82de6767d7da9d2fbeda9407f6ee45673;hb=8ec899bfb474d74c5f45ef49a2d9ed8f5d1703b5;hp=23891d9e66892f3cf18ab7dc7475b8d08b0f9219;hpb=ac972acc48180ee4630a4e796fd7dcf320110132;p=hengband%2Fhengband.git diff --git a/src/melee2.c b/src/melee2.c index 23891d9e6..793690c82 100644 --- a/src/melee2.c +++ b/src/melee2.c @@ -1416,6 +1416,12 @@ static int check_hit2(int power, int level, int ac, int stun) } +#define BLOW_EFFECT_TYPE_NONE 0 +#define BLOW_EFFECT_TYPE_FEAR 1 +#define BLOW_EFFECT_TYPE_SLEEP 2 +#define BLOW_EFFECT_TYPE_HEAL 3 + + /* Monster attacks monster */ static bool monst_attack_monst(int m_idx, int t_idx) { @@ -1428,11 +1434,12 @@ static bool monst_attack_monst(int m_idx, int t_idx) int ap_cnt; int ac, rlev, pt; char m_name[80], t_name[80]; - char temp[80]; - bool blinked, heal_effect; + char temp[MAX_NLEN]; + bool blinked; bool explode = FALSE, touched = FALSE, fear = FALSE; int y_saver = t_ptr->fy; int x_saver = t_ptr->fx; + int effect_type; bool see_m = is_seen(m_ptr); bool see_t = is_seen(t_ptr); @@ -1832,8 +1839,8 @@ act = "%s /* Roll out the damage */ damage = damroll(d_dice, d_side); - /* Assume no healing effect */ - heal_effect = FALSE; + /* Assume no effect */ + effect_type = BLOW_EFFECT_TYPE_NONE; pt = GF_MISSILE; @@ -1841,147 +1848,103 @@ act = "%s switch (effect) { case 0: - { - damage = 0; - pt = 0; - break; - } + case RBE_DR_MANA: + damage = pt = 0; + break; case RBE_SUPERHURT: + if ((randint1(rlev*2+250) > (ac+200)) || one_in_(13)) { - if ((randint1(rlev*2+250) > (ac+200)) || one_in_(13)) { - int tmp_damage = damage-(damage*((ac < 150) ? ac : 150)/250); - damage = MAX(damage, tmp_damage*2); - break; - } - } - case RBE_HURT: - { - damage -= (damage * ((ac < 150) ? ac : 150) / 250); + int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250); + damage = MAX(damage, tmp_damage * 2); break; } + /* Fall through */ + + case RBE_HURT: + damage -= (damage * ((ac < 150) ? ac : 150) / 250); + break; + case RBE_POISON: case RBE_DISEASE: - { - pt = GF_POIS; - break; - } + pt = GF_POIS; + break; case RBE_UN_BONUS: case RBE_UN_POWER: - { - pt = GF_DISENCHANT; - break; - } - - case RBE_EAT_FOOD: - case RBE_EAT_LITE: - case RBE_DR_MANA: - { - pt = damage = 0; - break; - } + pt = GF_DISENCHANT; + break; case RBE_EAT_ITEM: case RBE_EAT_GOLD: - { - pt = damage = 0; - if ((p_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE; - break; - } + if ((p_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE; + break; + + case RBE_EAT_FOOD: + case RBE_EAT_LITE: + case RBE_BLIND: + case RBE_LOSE_STR: + case RBE_LOSE_INT: + case RBE_LOSE_WIS: + case RBE_LOSE_DEX: + case RBE_LOSE_CON: + case RBE_LOSE_CHR: + case RBE_LOSE_ALL: + break; case RBE_ACID: - { - pt = GF_ACID; - break; - } + pt = GF_ACID; + break; case RBE_ELEC: - { - pt = GF_ELEC; - break; - } + pt = GF_ELEC; + break; case RBE_FIRE: - { - pt = GF_FIRE; - break; - } + pt = GF_FIRE; + break; case RBE_COLD: - { - pt = GF_COLD; - break; - } - - case RBE_BLIND: - { - break; - } + pt = GF_COLD; + break; case RBE_CONFUSE: - { - pt = GF_CONFUSION; - break; - } + pt = GF_CONFUSION; + break; case RBE_TERRIFY: - { - pt = GF_TURN_ALL; - break; - } + effect_type = BLOW_EFFECT_TYPE_FEAR; + break; case RBE_PARALYZE: - { - pt = GF_OLD_SLEEP; /* sort of close... */ - break; - } + effect_type = BLOW_EFFECT_TYPE_SLEEP; + break; - case RBE_LOSE_STR: - case RBE_LOSE_INT: - case RBE_LOSE_WIS: - case RBE_LOSE_DEX: - case RBE_LOSE_CON: - case RBE_LOSE_CHR: - case RBE_LOSE_ALL: - { - break; - } case RBE_SHATTER: - { - damage -= (damage * ((ac < 150) ? ac : 150) / 250); - if (damage > 23) - { - earthquake(m_ptr->fy, m_ptr->fx, 8); - } - break; - } + damage -= (damage * ((ac < 150) ? ac : 150) / 250); + if (damage > 23) earthquake_aux(m_ptr->fy, m_ptr->fx, 8, m_idx); + break; + case RBE_EXP_10: case RBE_EXP_20: case RBE_EXP_40: case RBE_EXP_80: - { - pt = GF_NETHER; - break; - } + pt = GF_NETHER; + break; + case RBE_TIME: - { - pt = GF_TIME; - break; - } + pt = GF_TIME; + break; + case RBE_EXP_VAMP: - { - pt = GF_OLD_DRAIN; - heal_effect = TRUE; - break; - } + pt = GF_OLD_DRAIN; + effect_type = BLOW_EFFECT_TYPE_HEAL; + break; default: - { - pt = 0; - break; - } + pt = 0; + break; } if (pt) @@ -1990,11 +1953,22 @@ act = "%s if (!explode) { project(m_idx, 0, t_ptr->fy, t_ptr->fx, - (pt == GF_OLD_SLEEP ? r_ptr->level : damage), pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1); + damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1); } - if (heal_effect) + switch (effect_type) { + case BLOW_EFFECT_TYPE_FEAR: + project(m_idx, 0, t_ptr->fy, t_ptr->fx, + damage, GF_TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1); + break; + + case BLOW_EFFECT_TYPE_SLEEP: + project(m_idx, 0, t_ptr->fy, t_ptr->fx, + r_ptr->level, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1); + break; + + case BLOW_EFFECT_TYPE_HEAL: if ((monster_living(tr_ptr)) && (damage > 2)) { bool did_heal = FALSE; @@ -2013,13 +1987,13 @@ act = "%s if (see_m && did_heal) { #ifdef JP -msg_format("%s¤ÏÂÎÎϤò²óÉü¤·¤¿¤è¤¦¤À¡£", m_name); + msg_format("%s¤ÏÂÎÎϤò²óÉü¤·¤¿¤è¤¦¤À¡£", m_name); #else msg_format("%^s appears healthier.", m_name); #endif - } } + break; } if (touched) @@ -2175,26 +2149,52 @@ msg_format("%s /* Blink away */ if (blinked && m_ptr->r_idx) { - if (see_m) + if (teleport_barrier(m_idx)) { + if (see_m) + { #ifdef JP - msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²¤¿¡ª"); + msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²...¤è¤¦¤È¤·¤¿¤¬¥Ð¥ê¥¢¤ËËɤ¬¤ì¤¿¡£"); #else - msg_print("The thief flees laughing!"); + msg_print("The thief flees laughing...? But magic barrier obstructs it."); #endif + } + else if (known) + { + mon_fight = TRUE; + } } - else if (known) + else { - mon_fight = TRUE; - } + if (see_m) + { +#ifdef JP + msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²¤¿¡ª"); +#else + msg_print("The thief flees laughing!"); +#endif + } + else if (known) + { + mon_fight = TRUE; + } - teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE, FALSE); + teleport_away(m_idx, MAX_SIGHT * 2 + 5, 0L); + } } return TRUE; } +static bool check_hp_for_feat_destruction(feature_type *f_ptr, monster_type *m_ptr) +{ + return !have_flag(f_ptr->flags, FF_GLASS) || + (r_info[m_ptr->r_idx].flags2 & RF2_STUPID) || + (m_ptr->hp >= MAX(m_ptr->maxhp / 3, 200)); +} + + /* * Process a monster * @@ -2239,6 +2239,7 @@ static void process_monster(int m_idx) bool do_turn; bool do_move; bool do_view; + bool must_alter_to_move; bool did_open_door; bool did_bash_door; @@ -2307,6 +2308,14 @@ static void process_monster(int m_idx) #endif } + if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname) + { + char m_name[80]; + + monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE); + do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name); + } + /* Delete the monster */ delete_monster_idx(m_idx); @@ -2462,7 +2471,7 @@ static void process_monster(int m_idx) (void)set_monster_csleep(m_idx, 0); /* Notice the "waking up" */ - if (see_m) + if (m_ptr->ml) { char m_name[80]; @@ -2477,13 +2486,10 @@ static void process_monster(int m_idx) #endif } - if (m_ptr->ml) + /* Hack -- Count the wakings */ + if (is_original_ap_and_seen(m_ptr) && (r_ptr->r_wake < MAX_UCHAR)) { - /* Hack -- Count the wakings */ - if ((r_ptr->r_wake < MAX_UCHAR) && is_original_ap(m_ptr)) - { - r_ptr->r_wake++; - } + r_ptr->r_wake++; } } @@ -2552,6 +2558,9 @@ static void process_monster(int m_idx) } } + /* Hex */ + if (multiply_barrier(m_idx)) k = 8; + /* Hack -- multiply slower in crowded areas */ if ((k < 4) && (!k || !randint0(k * MON_MULT_ADJ))) { @@ -2829,6 +2838,7 @@ msg_format("%^s%s", m_name, monmessage); do_turn = FALSE; do_move = FALSE; do_view = FALSE; + must_alter_to_move = FALSE; /* Assume nothing */ did_open_door = FALSE; @@ -2870,12 +2880,26 @@ msg_format("%^s%s", m_name, monmessage); do_move = TRUE; } + /* Possibly a monster to attack */ else if (c_ptr->m_idx) { - /* Possibly a monster to attack */ do_move = TRUE; } + /* Monster destroys walls (and doors) */ + else if ((r_ptr->flags2 & RF2_KILL_WALL) && + (can_cross ? !have_flag(f_ptr->flags, FF_LOS) : !is_riding_mon) && + have_flag(f_ptr->flags, FF_HURT_DISI) && !have_flag(f_ptr->flags, FF_PERMANENT) && + check_hp_for_feat_destruction(f_ptr, m_ptr)) + { + /* Eat through walls/doors/rubble */ + do_move = TRUE; + if (!can_cross) must_alter_to_move = TRUE; + + /* Monster destroyed a wall (later) */ + did_kill_wall = TRUE; + } + /* Floor is open? */ else if (can_cross) { @@ -2889,31 +2913,12 @@ msg_format("%^s%s", m_name, monmessage); /* Monster went through a wall */ did_pass_wall = TRUE; } - - if ((r_ptr->flags2 & RF2_KILL_WALL) && have_flag(f_ptr->flags, FF_TUNNEL) && - !have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_PERMANENT)) - { - /* Monster destroyed a wall (later) */ - did_kill_wall = TRUE; - } - } - - /* Monster destroys walls (and doors) */ - else if ((r_ptr->flags2 & RF2_KILL_WALL) && !is_riding_mon && - have_flag(f_ptr->flags, FF_TUNNEL) && !have_flag(f_ptr->flags, FF_PERMANENT)) - { - /* Eat through walls/doors/rubble */ - do_move = TRUE; - - /* Monster destroyed a wall (later) */ - did_kill_wall = TRUE; } /* Handle doors and secret doors */ else if (is_closed_door(c_ptr->feat)) { bool may_bash = TRUE; - feature_type *f_ptr = &f_info[c_ptr->feat]; /* Assume no move allowed */ do_move = FALSE; @@ -2958,13 +2963,20 @@ msg_format("%^s%s", m_name, monmessage); (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_OPEN_DOORS))) { /* Attempt to Bash XXX XXX XXX */ - if (randint0(m_ptr->hp / 10) > f_ptr->power) + if (check_hp_for_feat_destruction(f_ptr, m_ptr) && (randint0(m_ptr->hp / 10) > f_ptr->power)) { /* Message */ + if (have_flag(f_ptr->flags, FF_GLASS)) #ifdef JP - msg_print("¥É¥¢¤ò᤭³«¤±¤ë²»¤¬¤·¤¿¡ª"); + msg_print("¥¬¥é¥¹¤¬ºÕ¤±¤ë²»¤¬¤·¤¿¡ª"); #else - msg_print("You hear a door burst open!"); + msg_print("You hear a glass was crashed!"); +#endif + else +#ifdef JP + msg_print("¥É¥¢¤ò᤭³«¤±¤ë²»¤¬¤·¤¿¡ª"); +#else + msg_print("You hear a door burst open!"); #endif /* Disturb (sometimes) */ @@ -2975,6 +2987,7 @@ msg_format("%^s%s", m_name, monmessage); /* Hack -- fall into doorway */ do_move = TRUE; + must_alter_to_move = TRUE; } } @@ -2983,9 +2996,19 @@ msg_format("%^s%s", m_name, monmessage); if (did_open_door || did_bash_door) { /* Break down the door */ - if (did_bash_door && ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat))) + if (did_bash_door && ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS))) { cave_alter_feat(ny, nx, FF_BASH); + + if (!m_ptr->r_idx) /* Killed by shards of glass, etc. */ + { + /* Update some things */ + p_ptr->update |= (PU_FLOW); + p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_BASH_DOOR); + + return; + } } /* Open the door */ @@ -2994,6 +3017,8 @@ msg_format("%^s%s", m_name, monmessage); cave_alter_feat(ny, nx, FF_OPEN); } + f_ptr = &f_info[c_ptr->feat]; + /* Handle viewable doors */ do_view = TRUE; } @@ -3184,6 +3209,59 @@ msg_format("%^s%s", m_name, monmessage); } } + if (is_riding_mon) + { + if (!p_ptr->riding_ryoute && !MON_MONFEAR(&m_list[p_ptr->riding])) do_move = FALSE; + } + + if (did_kill_wall && do_move) + { + if (one_in_(GRINDNOISE)) + { + if (have_flag(f_ptr->flags, FF_GLASS)) +#ifdef JP + msg_print("²¿¤«¤ÎºÕ¤±¤ë²»¤¬Ê¹¤³¤¨¤ë¡£"); +#else + msg_print("There is a crashing sound."); +#endif + else +#ifdef JP + msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£"); +#else + msg_print("There is a grinding sound."); +#endif + } + + cave_alter_feat(ny, nx, FF_HURT_DISI); + + if (!m_ptr->r_idx) /* Killed by shards of glass, etc. */ + { + /* Update some things */ + p_ptr->update |= (PU_FLOW); + p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_WALL); + + return; + } + + f_ptr = &f_info[c_ptr->feat]; + + /* Note changes to viewable region */ + do_view = TRUE; + + /* Take a turn */ + do_turn = TRUE; + } + + if (must_alter_to_move && (r_ptr->flags7 & RF7_AQUATIC)) + { + if (!monster_can_cross_terrain(c_ptr->feat, r_ptr, is_riding_mon ? CEM_RIDING : 0)) + { + /* Assume no move allowed */ + do_move = FALSE; + } + } + /* * Check if monster can cross terrain * This is checked after the normal attacks @@ -3199,45 +3277,22 @@ msg_format("%^s%s", m_name, monmessage); /* Some monsters never move */ if (do_move && (r_ptr->flags1 & RF1_NEVER_MOVE)) { - /* Hack -- memorize lack of attacks */ + /* Hack -- memorize lack of moves */ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags1 |= (RF1_NEVER_MOVE); /* Do not move */ do_move = FALSE; } - if (is_riding_mon) - { - if (!p_ptr->riding_ryoute && !MON_MONFEAR(&m_list[p_ptr->riding])) do_move = FALSE; - } - /* Creature has been allowed move */ if (do_move) { - s16b this_o_idx, next_o_idx; - /* Take a turn */ do_turn = TRUE; - if (did_kill_wall) - { - if (one_in_(GRINDNOISE)) - { -#ifdef JP - msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£"); -#else - msg_print("There is a grinding sound."); -#endif - } - - cave_alter_feat(ny, nx, FF_HURT_DISI); - - /* Note changes to viewable region */ - do_view = TRUE; - } - else if (have_flag(f_ptr->flags, FF_TREE)) + if (have_flag(f_ptr->flags, FF_TREE)) { - if (!(r_ptr->flags7 & RF7_CAN_FLY) && (!is_riding_mon || !p_ptr->levitation) && !(r_ptr->flags8 & RF8_WILD_WOOD)) + if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD)) { m_ptr->energy_need += ENERGY_NEED(); } @@ -3287,7 +3342,7 @@ msg_format("%^s%s", m_name, monmessage); /* Possible disturb */ if (m_ptr->ml && (disturb_move || - (disturb_near && (m_ptr->mflag & MFLAG_VIEW)) || + (disturb_near && (m_ptr->mflag & MFLAG_VIEW) && projectable(py, px, m_ptr->fy, m_ptr->fx)) || (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= p_ptr->lev))) { /* Disturb */ @@ -3295,39 +3350,38 @@ msg_format("%^s%s", m_name, monmessage); disturb(0, 0); } - /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + /* Take or Kill objects on the floor */ + if (c_ptr->o_idx && (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) && + (!is_pet(m_ptr) || ((p_ptr->pet_extra_flags & PF_PICKUP_ITEMS) && (r_ptr->flags2 & RF2_TAKE_ITEM)))) { - object_type *o_ptr; - - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - - /* Skip gold */ - if (o_ptr->tval == TV_GOLD) continue; - - /* - * Skip "real" corpses and statues, to avoid extreme - * silliness like a novice rogue pockets full of statues - * and corpses. - */ - if ((o_ptr->tval == TV_CORPSE) || - (o_ptr->tval == TV_STATUE)) continue; + s16b this_o_idx, next_o_idx; + bool do_take = (r_ptr->flags2 & RF2_TAKE_ITEM) ? TRUE : FALSE; - /* Take or Kill objects on the floor */ - if ((r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) && - (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_PICKUP_ITEMS))) + /* Scan all objects in the grid */ + for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) { - u32b flgs[TR_FLAG_SIZE]; + u32b flgs[TR_FLAG_SIZE], flg2 = 0L, flg3 = 0L, flgr = 0L; + char m_name[80], o_name[MAX_NLEN]; - u32b flg2 = 0L; - u32b flg3 = 0L; + /* Acquire object */ + object_type *o_ptr = &o_list[this_o_idx]; - char m_name[80]; - char o_name[MAX_NLEN]; + /* Acquire next object */ + next_o_idx = o_ptr->next_o_idx; + + if (do_take) + { + /* Skip gold */ + if (o_ptr->tval == TV_GOLD) continue; + + /* + * Skip "real" corpses and statues, to avoid extreme + * silliness like a novice rogue pockets full of statues + * and corpses. + */ + if ((o_ptr->tval == TV_CORPSE) || + (o_ptr->tval == TV_STATUE)) continue; + } /* Extract some flags */ object_flags(o_ptr, flgs); @@ -3339,12 +3393,12 @@ msg_format("%^s%s", m_name, monmessage); monster_desc(m_name, m_ptr, MD_INDEF_HIDDEN); /* React to objects that hurt the monster */ - if (have_flag(flgs, TR_KILL_DRAGON)) flg3 |= (RF3_DRAGON); if (have_flag(flgs, TR_SLAY_DRAGON)) flg3 |= (RF3_DRAGON); + if (have_flag(flgs, TR_KILL_DRAGON)) flg3 |= (RF3_DRAGON); if (have_flag(flgs, TR_SLAY_TROLL)) flg3 |= (RF3_TROLL); if (have_flag(flgs, TR_KILL_TROLL)) flg3 |= (RF3_TROLL); - if (have_flag(flgs, TR_KILL_GIANT)) flg3 |= (RF3_GIANT); if (have_flag(flgs, TR_SLAY_GIANT)) flg3 |= (RF3_GIANT); + if (have_flag(flgs, TR_KILL_GIANT)) flg3 |= (RF3_GIANT); if (have_flag(flgs, TR_SLAY_ORC)) flg3 |= (RF3_ORC); if (have_flag(flgs, TR_KILL_ORC)) flg3 |= (RF3_ORC); if (have_flag(flgs, TR_SLAY_DEMON)) flg3 |= (RF3_DEMON); @@ -3357,12 +3411,18 @@ msg_format("%^s%s", m_name, monmessage); if (have_flag(flgs, TR_KILL_EVIL)) flg3 |= (RF3_EVIL); if (have_flag(flgs, TR_SLAY_HUMAN)) flg2 |= (RF2_HUMAN); if (have_flag(flgs, TR_KILL_HUMAN)) flg2 |= (RF2_HUMAN); + if (have_flag(flgs, TR_BRAND_ACID)) flgr |= (RFR_IM_ACID); + if (have_flag(flgs, TR_BRAND_ELEC)) flgr |= (RFR_IM_ELEC); + if (have_flag(flgs, TR_BRAND_FIRE)) flgr |= (RFR_IM_FIRE); + if (have_flag(flgs, TR_BRAND_COLD)) flgr |= (RFR_IM_COLD); + if (have_flag(flgs, TR_BRAND_POIS)) flgr |= (RFR_IM_POIS); /* The object cannot be picked up by the monster */ - if (object_is_artifact(o_ptr) || (r_ptr->flags3 & flg3) || (r_ptr->flags2 & flg2)) + if (object_is_artifact(o_ptr) || (r_ptr->flags3 & flg3) || (r_ptr->flags2 & flg2) || + ((~(r_ptr->flagsr) & flgr) && !(r_ptr->flagsr & RFR_RES_ALL))) { /* Only give a message for "take_item" */ - if ((r_ptr->flags2 & (RF2_TAKE_ITEM)) && (r_ptr->flags2 & (RF2_STUPID))) + if (do_take && (r_ptr->flags2 & RF2_STUPID)) { /* Take note */ did_take_item = TRUE; @@ -3381,7 +3441,7 @@ msg_format("%^s%s", m_name, monmessage); } /* Pick up the item */ - else if (r_ptr->flags2 & RF2_TAKE_ITEM) + else if (do_take) { /* Take note */ did_take_item = TRUE; @@ -3401,7 +3461,7 @@ msg_format("%^s%s", m_name, monmessage); excise_object_idx(this_o_idx); /* Forget mark */ - o_ptr->marked = 0; + o_ptr->marked &= OM_TOUCHED; /* Forget location */ o_ptr->iy = o_ptr->ix = 0; @@ -3777,27 +3837,30 @@ void process_monsters(void) } -static void mproc_add(int m_idx, int mproc_type) +int get_mproc_idx(int m_idx, int mproc_type) { - if (mproc_max[mproc_type] < max_m_idx) + s16b *cur_mproc_list = mproc_list[mproc_type]; + int i; + + for (i = mproc_max[mproc_type] - 1; i >= 0; i--) { - m_list[m_idx].mproc_idx[mproc_type] = mproc_max[mproc_type]; - mproc_list[mproc_type][mproc_max[mproc_type]++] = m_idx; + if (cur_mproc_list[i] == m_idx) return i; } + + return -1; } -void mproc_remove(int m_idx, int mproc_type) +static void mproc_add(int m_idx, int mproc_type) { - s16b *mproc_idx = &(m_list[m_idx].mproc_idx[mproc_type]); + if (mproc_max[mproc_type] < max_m_idx) mproc_list[mproc_type][mproc_max[mproc_type]++] = m_idx; +} - if (mproc_max[mproc_type] > 1) - { - mproc_list[mproc_type][*mproc_idx] = mproc_list[mproc_type][--mproc_max[mproc_type]]; - m_list[mproc_list[mproc_type][*mproc_idx]].mproc_idx[mproc_type] = *mproc_idx; - } - *mproc_idx = 0; +static void mproc_remove(int m_idx, int mproc_type) +{ + int mproc_idx = get_mproc_idx(m_idx, mproc_type); + if (mproc_idx >= 0) mproc_list[mproc_type][mproc_idx] = mproc_list[mproc_type][--mproc_max[mproc_type]]; } @@ -3810,7 +3873,7 @@ void mproc_init(void) int i, cmi; /* Reset "mproc_max[]" */ - for (cmi = 0; cmi < MAX_MTIMED; cmi++) mproc_max[cmi] = 1; + for (cmi = 0; cmi < MAX_MTIMED; cmi++) mproc_max[cmi] = 0; /* Process the monsters (backwards) */ for (i = m_max - 1; i >= 1; i--) @@ -3824,7 +3887,6 @@ void mproc_init(void) for (cmi = 0; cmi < MAX_MTIMED; cmi++) { if (m_ptr->mtimed[cmi]) mproc_add(i, cmi); - else m_ptr->mproc_idx[cmi] = 0; } } } @@ -3915,7 +3977,7 @@ bool set_monster_fast(int m_idx, int v) if (!notice) return FALSE; - if (p_ptr->riding == m_idx) p_ptr->update |= (PU_BONUS); + if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS); return TRUE; } @@ -3957,7 +4019,7 @@ bool set_monster_slow(int m_idx, int v) if (!notice) return FALSE; - if (p_ptr->riding == m_idx) p_ptr->update |= (PU_BONUS); + if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS); return TRUE; } @@ -4134,37 +4196,20 @@ bool set_monster_invulner(int m_idx, int v, bool energy_need) } -/* - * Process the counters of monsters (once per 10 game turns) - * - * These functions are to process monsters' counters same as player's. - */ +static u32b csleep_noise; - -/* Handle "sleep" */ -void process_monsters_csleep(void) +static void process_monsters_mtimed_aux(int m_idx, int mtimed_idx) { - int m_idx, i; - monster_type *m_ptr; - monster_race *r_ptr; - bool test; - s16b *cur_mproc_list = mproc_list[MTIMED_CSLEEP]; - - u32b noise; /* Hack -- local "player stealth" value */ - - /* Hack -- calculate the "player noise" */ - noise = (1L << (30 - p_ptr->skill_stl)); + monster_type *m_ptr = &m_list[m_idx]; - /* Process the monsters (backwards) */ - for (i = mproc_max[MTIMED_CSLEEP] - 1; i >= 1; i--) + switch (mtimed_idx) { - /* Access the monster */ - m_idx = cur_mproc_list[i]; - m_ptr = &m_list[m_idx]; - r_ptr = &r_info[m_ptr->r_idx]; + case MTIMED_CSLEEP: + { + monster_race *r_ptr = &r_info[m_ptr->r_idx]; /* Assume does not wake up */ - test = FALSE; + bool test = FALSE; /* Hack -- Require proximity */ if (m_ptr->cdis < AAF_LIMIT) @@ -4192,7 +4237,7 @@ void process_monsters_csleep(void) if (ironman_nightmare) notice /= 2; /* Hack -- See if monster "notices" player */ - if ((notice * notice * notice) <= noise) + if ((notice * notice * notice) <= csleep_noise) { /* Hack -- amount of "waking" */ /* Wake up faster near the player */ @@ -4219,7 +4264,7 @@ void process_monsters_csleep(void) else { /* Notice the "waking up" */ - if (is_seen(m_ptr)) + if (m_ptr->ml) { char m_name[80]; @@ -4242,24 +4287,10 @@ void process_monsters_csleep(void) } } } + break; } -} - - -/* Handle fast */ -void process_monsters_fast(void) -{ - int m_idx, i; - monster_type *m_ptr; - s16b *cur_mproc_list = mproc_list[MTIMED_FAST]; - - /* Process the monsters (backwards) */ - for (i = mproc_max[MTIMED_FAST] - 1; i >= 1; i--) - { - /* Access the monster */ - m_idx = cur_mproc_list[i]; - m_ptr = &m_list[m_idx]; + case MTIMED_FAST: /* Reduce by one, note if expires */ if (set_monster_fast(m_idx, MON_FAST(m_ptr) - 1)) { @@ -4278,24 +4309,9 @@ void process_monsters_fast(void) #endif } } - } -} - - -/* Handle slow */ -void process_monsters_slow(void) -{ - int m_idx, i; - monster_type *m_ptr; - s16b *cur_mproc_list = mproc_list[MTIMED_SLOW]; - - /* Process the monsters (backwards) */ - for (i = mproc_max[MTIMED_SLOW] - 1; i >= 1; i--) - { - /* Access the monster */ - m_idx = cur_mproc_list[i]; - m_ptr = &m_list[m_idx]; + break; + case MTIMED_SLOW: /* Reduce by one, note if expires */ if (set_monster_slow(m_idx, MON_SLOW(m_ptr) - 1)) { @@ -4314,28 +4330,13 @@ void process_monsters_slow(void) #endif } } - } -} - - -/* Handle "stun" */ -void process_monsters_stunned(void) -{ - int m_idx, i, rlev; - monster_type *m_ptr; - s16b *cur_mproc_list = mproc_list[MTIMED_STUNNED]; + break; - /* Process the monsters (backwards) */ - for (i = mproc_max[MTIMED_STUNNED] - 1; i >= 1; i--) + case MTIMED_STUNNED: { - /* Access the monster */ - m_idx = cur_mproc_list[i]; - m_ptr = &m_list[m_idx]; - rlev = r_info[m_ptr->r_idx].level; - - /* Hack -- Recover from stun */ + int rlev = r_info[m_ptr->r_idx].level; - /* Fully recover */ + /* Recover from stun */ if (set_monster_stunned(m_idx, (randint0(10000) <= rlev * rlev) ? 0 : (MON_STUNNED(m_ptr) - 1))) { /* Message if visible */ @@ -4354,27 +4355,11 @@ void process_monsters_stunned(void) #endif } } + break; } -} - - -/* Handle confusion */ -void process_monsters_confused(void) -{ - int m_idx, i; - monster_type *m_ptr; - s16b *cur_mproc_list = mproc_list[MTIMED_CONFUSED]; - - /* Process the monsters (backwards) */ - for (i = mproc_max[MTIMED_CONFUSED] - 1; i >= 1; i--) - { - /* Access the monster */ - m_idx = cur_mproc_list[i]; - m_ptr = &m_list[m_idx]; + case MTIMED_CONFUSED: /* Reduce the confusion */ - - /* Recovered */ if (set_monster_confused(m_idx, MON_CONFUSED(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1))) { /* Message if visible */ @@ -4393,27 +4378,10 @@ void process_monsters_confused(void) #endif } } - } -} - - -/* Handle "fear" */ -void process_monsters_monfear(void) -{ - int m_idx, i; - monster_type *m_ptr; - s16b *cur_mproc_list = mproc_list[MTIMED_MONFEAR]; - - /* Process the monsters (backwards) */ - for (i = mproc_max[MTIMED_MONFEAR] - 1; i >= 1; i--) - { - /* Access the monster */ - m_idx = cur_mproc_list[i]; - m_ptr = &m_list[m_idx]; + break; + case MTIMED_MONFEAR: /* Reduce the fear */ - - /* Recover from fear, take note if seen */ if (set_monster_monfear(m_idx, MON_MONFEAR(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1))) { /* Visual note */ @@ -4438,24 +4406,9 @@ void process_monsters_monfear(void) #endif } } - } -} - - -/* Handle Invulnerability */ -void process_monsters_invulner(void) -{ - int m_idx, i; - monster_type *m_ptr; - s16b *cur_mproc_list = mproc_list[MTIMED_INVULNER]; - - /* Process the monsters (backwards) */ - for (i = mproc_max[MTIMED_INVULNER] - 1; i >= 1; i--) - { - /* Access the monster */ - m_idx = cur_mproc_list[i]; - m_ptr = &m_list[m_idx]; + break; + case MTIMED_INVULNER: /* Reduce by one, note if expires */ if (set_monster_invulner(m_idx, MON_INVULNER(m_ptr) - 1, TRUE)) { @@ -4474,6 +4427,29 @@ void process_monsters_invulner(void) #endif } } + break; + } +} + + +/* + * Process the counters of monsters (once per 10 game turns) + * + * These functions are to process monsters' counters same as player's. + */ +void process_monsters_mtimed(int mtimed_idx) +{ + int i; + s16b *cur_mproc_list = mproc_list[mtimed_idx]; + + /* Hack -- calculate the "player noise" */ + if (mtimed_idx == MTIMED_CSLEEP) csleep_noise = (1L << (30 - p_ptr->skill_stl)); + + /* Process the monsters (backwards) */ + for (i = mproc_max[mtimed_idx] - 1; i >= 0; i--) + { + /* Access the monster */ + process_monsters_mtimed_aux(cur_mproc_list[i], mtimed_idx); } } @@ -4595,11 +4571,22 @@ bool process_the_world(int num, int who, bool vs_player) void monster_gain_exp(int m_idx, int s_idx) { - monster_type *m_ptr = &m_list[m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; - monster_race *s_ptr = &r_info[s_idx]; + monster_type *m_ptr; + monster_race *r_ptr; + monster_race *s_ptr; int new_exp; + /* Paranoia */ + if (m_idx <= 0 || s_idx <= 0) return; + + m_ptr = &m_list[m_idx]; + + /* Paranoia -- Skip dead monsters */ + if (!m_ptr->r_idx) return; + + r_ptr = &r_info[m_ptr->r_idx]; + s_ptr = &r_info[s_idx]; + if (p_ptr->inside_battle) return; if (!r_ptr->next_exp) return; @@ -4666,14 +4653,33 @@ void monster_gain_exp(int m_idx, int s_idx) { if (!ignore_unview || player_can_see_bold(m_ptr->fy, m_ptr->fx)) { + if (p_ptr->image) + { + monster_race *hallu_race; + + do + { + hallu_race = &r_info[randint1(max_r_idx - 1)]; + } + while (!hallu_race->name || (hallu_race->flags1 & RF1_UNIQUE)); + #ifdef JP - msg_format("%s¤Ï%s¤Ë¿Ê²½¤·¤¿¡£", m_name, r_name + r_ptr->name); + msg_format("%s¤Ï%s¤Ë¿Ê²½¤·¤¿¡£", m_name, r_name + hallu_race->name); #else - msg_format("%^s evolved into %s.", m_name, r_name + r_ptr->name); + msg_format("%^s evolved into %s.", m_name, r_name + hallu_race->name); #endif + } + else + { +#ifdef JP + msg_format("%s¤Ï%s¤Ë¿Ê²½¤·¤¿¡£", m_name, r_name + r_ptr->name); +#else + msg_format("%^s evolved into %s.", m_name, r_name + r_ptr->name); +#endif + } } - r_info[old_r_idx].r_xtra1 |= MR1_SINKA; + if (!p_ptr->image) r_info[old_r_idx].r_xtra1 |= MR1_SINKA; /* Now you feel very close to this pet. */ m_ptr->parent_m_idx = 0;