X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmelee2.c;h=2666196654274ca4d3b5b5242391eaefc3f78990;hb=808c288f896ea243ab6a0565da8ebd55c36a9c90;hp=5165de40ee7a0455de15f1ec8b142880ad595c8c;hpb=51f5abd01dda2fdf9331cc2d076578a01df81e81;p=hengband%2Fhengband.git diff --git a/src/melee2.c b/src/melee2.c index 5165de40e..266619665 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) @@ -2188,13 +2162,21 @@ msg_format("%s 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 * @@ -2308,6 +2290,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); @@ -2463,7 +2453,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]; @@ -2478,13 +2468,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++; } } @@ -2872,12 +2859,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) { @@ -2891,25 +2892,6 @@ 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; - must_alter_to_move = TRUE; - - /* Monster destroyed a wall (later) */ - did_kill_wall = TRUE; } /* Handle doors and secret doors */ @@ -2960,13 +2942,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) */ @@ -2986,9 +2975,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 */ @@ -3198,14 +3197,32 @@ msg_format("%^s%s", m_name, monmessage); { 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("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£"); + msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£"); #else - msg_print("There is a grinding sound."); + 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 */ @@ -3249,14 +3266,12 @@ msg_format("%^s%s", m_name, monmessage); /* Creature has been allowed move */ if (do_move) { - s16b this_o_idx, next_o_idx; - /* Take a turn */ do_turn = TRUE; 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(); } @@ -3306,7 +3321,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 */ @@ -3314,39 +3329,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; + s16b this_o_idx, next_o_idx; + bool do_take = (r_ptr->flags2 & RF2_TAKE_ITEM) ? TRUE : FALSE; - /* 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; - - /* 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]; + + /* Acquire object */ + object_type *o_ptr = &o_list[this_o_idx]; - u32b flg2 = 0L; - u32b flg3 = 0L; + /* Acquire next object */ + next_o_idx = o_ptr->next_o_idx; - char m_name[80]; - char o_name[MAX_NLEN]; + 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); @@ -3358,12 +3372,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); @@ -3376,12 +3390,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; @@ -3400,7 +3420,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; @@ -3420,7 +3440,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; @@ -4223,7 +4243,7 @@ static void process_monsters_mtimed_aux(int m_idx, int mtimed_idx) else { /* Notice the "waking up" */ - if (is_seen(m_ptr)) + if (m_ptr->ml) { char m_name[80]; @@ -4601,14 +4621,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 + hallu_race->name); +#else + 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); + 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); + 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;