diff options
Diffstat (limited to 'src/melee1.c')
-rw-r--r-- | src/melee1.c | 3065 |
1 files changed, 0 insertions, 3065 deletions
diff --git a/src/melee1.c b/src/melee1.c deleted file mode 100644 index 4e5d3208..00000000 --- a/src/melee1.c +++ /dev/null @@ -1,3065 +0,0 @@ -/* File: melee1.c */ - -/* Purpose: Monster attacks */ - -/* - * Copyright (c) 1989 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. - */ - -#include "angband.h" - - - -/* - * Critical blow. All hits that do 95% of total possible damage, - * and which also do at least 20 damage, or, sometimes, N damage. - * This is used only to determine "cuts" and "stuns". - */ -static int monster_critical(int dice, int sides, int dam) -{ - int max = 0; - int total = dice * sides; - - /* Must do at least 95% of perfect */ - if (dam < total * 19 / 20) return (0); - - /* Weak blows rarely work */ - if ((dam < 20) && (rand_int(100) >= dam)) return (0); - - /* Perfect damage */ - if (dam == total) max++; - - /* Super-charge */ - if (dam >= 20) - { - while (rand_int(100) < 2) max++; - } - - /* Critical damage */ - if (dam > 45) return (6 + max); - if (dam > 33) return (5 + max); - if (dam > 25) return (4 + max); - if (dam > 18) return (3 + max); - if (dam > 11) return (2 + max); - return (1 + max); -} - - - - - -/* - * Determine if a monster attack against the player succeeds. - * Always miss 5% of the time, Always hit 5% of the time. - * Otherwise, match monster power against player armor. - */ -static int check_hit(int power, int level) -{ - int i, k, ac; - - /* Percentile dice */ - k = rand_int(100); - - /* Hack -- Always miss or hit */ - if (k < 10) return (k < 5); - - /* Calculate the "attack quality" */ - i = (power + (level * 3)); - - /* Total armor */ - ac = p_ptr->ac + p_ptr->to_a; - - /* Power and Level compete against Armor */ - if ((i > 0) && (randint(i - luck( -10, 10)) > ((ac * 3) / 4))) return (TRUE); - - /* Assume miss */ - return (FALSE); -} - - - -/* - * Hack -- possible "insult" messages - */ -static cptr desc_insult[] = -{ - "insults you!", - "insults your mother!", - "jumps around you!", - "humiliates you!", - "defiles you!", - "dances around you!", - "makes obnoxious gestures!", - "pokes you!!!" -}; - - - -/* - * Hack -- possible "insult" messages - */ -static cptr desc_moan[] = -{ - "seems sad about something.", - "asks if you have seen his dogs.", - "tells you to get off his land.", - "mumbles something about mushrooms.", - - /* Mathilde's sentence */ - "giggles at you.", - "asks you if you want to giggle with her.", - "says she is always happy." -}; - - -/* - * Get the "power" of an attack of given effect type. - */ -int get_attack_power(int effect) -{ - switch (effect) - { - case RBE_HURT: - return 60; - case RBE_POISON: - return 5; - case RBE_UN_BONUS: - return 20; - case RBE_UN_POWER: - return 15; - case RBE_EAT_GOLD: - return 5; - case RBE_EAT_ITEM: - return 5; - case RBE_EAT_FOOD: - return 5; - case RBE_EAT_LITE: - return 5; - case RBE_ACID: - return 0; - case RBE_ELEC: - return 10; - case RBE_FIRE: - return 10; - case RBE_COLD: - return 10; - case RBE_BLIND: - return 2; - case RBE_CONFUSE: - return 10; - case RBE_TERRIFY: - return 10; - case RBE_PARALYZE: - return 2; - case RBE_LOSE_STR: - return 0; - case RBE_LOSE_DEX: - return 0; - case RBE_LOSE_CON: - return 0; - case RBE_LOSE_INT: - return 0; - case RBE_LOSE_WIS: - return 0; - case RBE_LOSE_CHR: - return 0; - case RBE_LOSE_ALL: - return 2; - case RBE_SHATTER: - return 60; - case RBE_EXP_10: - return 5; - case RBE_EXP_20: - return 5; - case RBE_EXP_40: - return 5; - case RBE_EXP_80: - return 5; - case RBE_DISEASE: - return 5; - case RBE_TIME: - return 5; - case RBE_SANITY: - return 60; - case RBE_HALLU: - return 10; - case RBE_PARASITE: - return 5; - case RBE_ABOMINATION: - return 30; - } - /* Unknown effects have no power */ - return 0; -} - -/* - * Attack the player via physical attacks. - */ -bool_ carried_make_attack_normal(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - int ap_cnt; - - int k, tmp, ac, rlev; - int do_cut, do_stun; - - char ddesc[80] = "your symbiote"; - cptr sym_name = symbiote_name(TRUE); - - bool_ touched = FALSE, alive = TRUE; - - /* Not allowed to attack */ - if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE); - - /* Total armor */ - ac = p_ptr->ac + p_ptr->to_a; - - /* Extract the effective monster level */ - rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); - - /* Scan through all four blows */ - for (ap_cnt = 0; ap_cnt < 4; ap_cnt++) - { - bool_ visible = FALSE; - bool_ obvious = FALSE; - - int power = 0; - int damage = 0; - - cptr act = NULL; - - /* Extract the attack infomation */ - int effect = r_ptr->blow[ap_cnt].effect; - int method = r_ptr->blow[ap_cnt].method; - int d_dice = r_ptr->blow[ap_cnt].d_dice; - int d_side = r_ptr->blow[ap_cnt].d_side; - - - /* Hack -- no more attacks */ - if (!method) break; - - - /* Stop if player is dead or gone */ - if (!alive || death) break; - - /* Handle "leaving" */ - if (p_ptr->leaving) break; - - /* Extract visibility (before blink) */ - visible = TRUE; - - /* Extract the attack "power" */ - power = get_attack_power(effect); - - - /* Monster hits player */ - if (!effect || check_hit(power, rlev)) - { - /* Always disturbing */ - disturb(1, 0); - - /* Hack -- Apply "protection from evil" */ - if ((p_ptr->protevil > 0) && - (r_ptr->flags3 & (RF3_EVIL)) && - (p_ptr->lev >= rlev) && - ((rand_int(100) + p_ptr->lev) > 50)) - { - /* Remember the Evil-ness */ - r_ptr->r_flags3 |= (RF3_EVIL); - - /* Message */ - msg_format("%s is repelled.", sym_name); - - /* Hack -- Next attack */ - continue; - } - - /* Hack -- Apply "protection from good" */ - if ((p_ptr->protgood > 0) && - (r_ptr->flags3 & (RF3_GOOD)) && - (p_ptr->lev >= rlev) && - ((rand_int(100) + p_ptr->lev) > 50)) - { - /* Remember the Good-ness */ - r_ptr->r_flags3 |= (RF3_GOOD); - - /* Message */ - msg_format("%s is repelled.", sym_name); - - /* Hack -- Next attack */ - continue; - } - - /* Assume no cut or stun */ - do_cut = do_stun = 0; - - /* Describe the attack method */ - switch (method) - { - case RBM_HIT: - { - act = "hits you."; - do_cut = do_stun = 1; - touched = TRUE; - sound(SOUND_HIT); - break; - } - - case RBM_TOUCH: - { - act = "touches you."; - touched = TRUE; - sound(SOUND_TOUCH); - break; - } - - case RBM_PUNCH: - { - act = "punches you."; - touched = TRUE; - do_stun = 1; - sound(SOUND_HIT); - break; - } - - case RBM_KICK: - { - act = "kicks you."; - touched = TRUE; - do_stun = 1; - sound(SOUND_HIT); - break; - } - - case RBM_CLAW: - { - act = "claws you."; - touched = TRUE; - do_cut = 1; - sound(SOUND_CLAW); - break; - } - - case RBM_BITE: - { - act = "bites you."; - do_cut = 1; - touched = TRUE; - sound(SOUND_BITE); - break; - } - - case RBM_STING: - { - act = "stings you."; - touched = TRUE; - sound(SOUND_STING); - break; - } - - case RBM_XXX1: - { - act = "XXX1's you."; - break; - } - - case RBM_BUTT: - { - act = "butts you."; - do_stun = 1; - touched = TRUE; - sound(SOUND_HIT); - break; - } - - case RBM_CRUSH: - { - act = "crushes you."; - do_stun = 1; - touched = TRUE; - sound(SOUND_CRUSH); - break; - } - - case RBM_ENGULF: - { - act = "engulfs you."; - touched = TRUE; - sound(SOUND_CRUSH); - break; - } - - case RBM_CHARGE: - { - act = "charges you."; - touched = TRUE; - sound(SOUND_BUY); /* Note! This is "charges", not "charges at". */ - break; - } - - case RBM_CRAWL: - { - act = "crawls on you."; - touched = TRUE; - sound(SOUND_SLIME); - break; - } - - case RBM_DROOL: - { - act = "drools on you."; - sound(SOUND_SLIME); - break; - } - - case RBM_SPIT: - { - act = "spits on you."; - sound(SOUND_SLIME); - break; - } - - case RBM_EXPLODE: - { - act = "explodes."; - break; - } - - case RBM_GAZE: - { - act = "gazes at you."; - break; - } - - case RBM_WAIL: - { - act = "wails at you."; - sound(SOUND_WAIL); - break; - } - - case RBM_SPORE: - { - act = "releases spores at you."; - sound(SOUND_SLIME); - break; - } - - case RBM_XXX4: - { - act = "projects XXX4's at you."; - break; - } - - case RBM_BEG: - { - act = "begs you for money."; - sound(SOUND_MOAN); - break; - } - - case RBM_INSULT: - { - act = desc_insult[rand_int(8)]; - sound(SOUND_MOAN); - break; - } - - case RBM_MOAN: - { - act = desc_moan[rand_int(4)]; - sound(SOUND_MOAN); - break; - } - - case RBM_SHOW: - { - if (randint(3) == 1) - act = "sings 'We are a happy family.'"; - else - act = "sings 'I love you, you love me.'"; - sound(SOUND_SHOW); - break; - } - } - - /* Message */ - if (act) msg_format("%s %s", sym_name, act); - - - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - - /* Roll out the damage */ - damage = damroll(d_dice, d_side); - - /* Apply appropriate damage */ - switch (effect) - { - case 0: - { - /* Hack -- Assume obvious */ - obvious = TRUE; - - /* Hack -- No damage */ - damage = 0; - - break; - } - - case RBE_HURT: - { - /* Obvious */ - obvious = TRUE; - - /* Hack -- Player armor reduces total damage */ - damage -= (damage * ((ac < 150) ? ac : 150) / 250); - - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - break; - } - - case RBE_ABOMINATION: - { - /* Obvious */ - obvious = TRUE; - - /* Morph, but let mimicry skill have a chance to stop this */ - if (magik(60 - get_skill(SKILL_MIMICRY))) - { - /* Message */ - cmsg_print(TERM_VIOLET, "You feel the dark powers twisting your body!"); - - set_mimic(damage, resolve_mimic_name("Abomination"), 50); - } - else - { - /* Message */ - cmsg_print(TERM_VIOLET, "You feel the dark powers trying to twisting your body, but they fail."); - } - - break; - } - - case RBE_SANITY: - { - obvious = TRUE; - - take_sanity_hit(damage, ddesc); - break; - } - - case RBE_POISON: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Take "poison" effect */ - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } - } - - break; - } - - case RBE_UN_BONUS: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Allow complete resist */ - if (!p_ptr->resist_disen) - { - /* Apply disenchantment */ - if (apply_disenchant(0)) obvious = TRUE; - } - - break; - } - - case RBE_UN_POWER: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - break; - } - - case RBE_EAT_GOLD: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - break; - } - - case RBE_EAT_ITEM: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - break; - } - - case RBE_EAT_FOOD: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - break; - } - - case RBE_EAT_LITE: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - break; - } - - case RBE_ACID: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are covered in acid!"); - - /* Special damage */ - carried_monster_hit = TRUE; - acid_dam(damage, ddesc); - - break; - } - - case RBE_ELEC: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are struck by electricity!"); - - /* Special damage */ - carried_monster_hit = TRUE; - elec_dam(damage, ddesc); - - - break; - } - - case RBE_FIRE: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are enveloped in flames!"); - - /* Special damage */ - carried_monster_hit = TRUE; - fire_dam(damage, ddesc); - - - break; - } - - case RBE_COLD: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are covered with frost!"); - - /* Special damage */ - carried_monster_hit = TRUE; - cold_dam(damage, ddesc); - - - break; - } - - case RBE_BLIND: - { - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Increase "blind" */ - if (!p_ptr->resist_blind) - { - if (set_blind(p_ptr->blind + 10 + randint(rlev))) - { - obvious = TRUE; - } - } - - - break; - } - - case RBE_CONFUSE: - { - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Increase "confused" */ - if (!p_ptr->resist_conf) - { - if (set_confused(p_ptr->confused + 3 + randint(rlev))) - { - obvious = TRUE; - } - } - - - break; - } - - case RBE_TERRIFY: - { - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Increase "afraid" */ - if (p_ptr->resist_fear) - { - msg_print("You stand your ground!"); - obvious = TRUE; - } - else if (rand_int(100) < p_ptr->skill_sav) - { - msg_print("You stand your ground!"); - obvious = TRUE; - } - else - { - if (set_afraid(p_ptr->afraid + 3 + randint(rlev))) - { - obvious = TRUE; - } - } - - - break; - } - - case RBE_PARALYZE: - { - /* Hack -- Prevent perma-paralysis via damage */ - if (p_ptr->paralyzed && (damage < 1)) damage = 1; - - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Increase "paralyzed" */ - if (p_ptr->free_act) - { - msg_print("You are unaffected!"); - obvious = TRUE; - } - else if (rand_int(100) < p_ptr->skill_sav) - { - msg_print("You resist the effects!"); - obvious = TRUE; - } - else - { - if (set_paralyzed(p_ptr->paralyzed + 3 + randint(rlev))) - { - obvious = TRUE; - } - } - - - break; - } - - case RBE_LOSE_STR: - { - /* Damage (physical) */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_INT: - { - /* Damage (physical) */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_WIS: - { - /* Damage (physical) */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_DEX: - { - /* Damage (physical) */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_CON: - { - /* Damage (physical) */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_CHR: - { - /* Damage (physical) */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_ALL: - { - /* Damage (physical) */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Damage (stats) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_SHATTER: - { - /* Obvious */ - obvious = TRUE; - - /* Hack -- Reduce damage based on the player armor class */ - damage -= (damage * ((ac < 150) ? ac : 150) / 250); - - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Radius 8 earthquake centered at the monster */ - if (damage > 23) - { - /* Prevent destruction of quest levels and town */ - if (!is_quest(dun_level) && dun_level) - earthquake(p_ptr->py, p_ptr->px, 8); - } - - break; - } - - case RBE_EXP_10: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 95)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(10, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_EXP_20: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 90)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(20, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_EXP_40: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 75)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(40, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_EXP_80: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 50)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(80, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_DISEASE: - { - /* Take some damage */ - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - - /* Take "poison" effect */ - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } - } - - /* Damage CON (10% chance)*/ - if (randint(100) < 11) - { - /* 1% chance for perm. damage */ - bool_ perm = (randint(10) == 1); - if (dec_stat(A_CON, randint(10), perm)) obvious = TRUE; - } - - break; - } - case RBE_PARASITE: - { - /* Obvious */ - obvious = TRUE; - - if (!p_ptr->parasite) set_parasite(damage, r_idx); - - break; - } - case RBE_HALLU: - { - /* Take damage */ - take_hit(damage, ddesc); - - /* Increase "image" */ - if (!p_ptr->resist_chaos) - { - if (set_image(p_ptr->image + 3 + randint(rlev / 2))) - { - obvious = TRUE; - } - } - break; - - } - case RBE_TIME: - { - switch (randint(10)) - { - case 1: - case 2: - case 3: - case 4: - case 5: - { - msg_print("You feel life has clocked back."); - lose_exp(100 + (p_ptr->exp / 100) * MON_DRAIN_LIFE); - break; - } - - case 6: - case 7: - case 8: - case 9: - { - int stat = rand_int(6); - - switch (stat) - { - case A_STR: - act = "strong"; - break; - case A_INT: - act = "bright"; - break; - case A_WIS: - act = "wise"; - break; - case A_DEX: - act = "agile"; - break; - case A_CON: - act = "hardy"; - break; - case A_CHR: - act = "beautiful"; - break; - } - - msg_format("You're not as %s as you used to be...", act); - - p_ptr->stat_cur[stat] = (p_ptr->stat_cur[stat] * 3) / 4; - if (p_ptr->stat_cur[stat] < 3) p_ptr->stat_cur[stat] = 3; - p_ptr->update |= (PU_BONUS); - break; - } - - case 10: - { - msg_print("You're not as powerful as you used to be..."); - - for (k = 0; k < 6; k++) - { - p_ptr->stat_cur[k] = (p_ptr->stat_cur[k] * 3) / 4; - if (p_ptr->stat_cur[k] < 3) p_ptr->stat_cur[k] = 3; - } - p_ptr->update |= (PU_BONUS); - break; - } - } - carried_monster_hit = TRUE; - take_hit(damage, ddesc); - break; - } - } - - - /* Hack -- only one of cut or stun */ - if (do_cut && do_stun) - { - /* Cancel cut */ - if (rand_int(100) < 50) - { - do_cut = 0; - } - - /* Cancel stun */ - else - { - do_stun = 0; - } - } - - /* Handle cut */ - if (do_cut) - { - int k = 0; - - /* Critical hit (zero if non-critical) */ - tmp = monster_critical(d_dice, d_side, damage); - - /* Roll for damage */ - switch (tmp) - { - case 0: - k = 0; - break; - case 1: - k = randint(5); - break; - case 2: - k = randint(5) + 5; - break; - case 3: - k = randint(20) + 20; - break; - case 4: - k = randint(50) + 50; - break; - case 5: - k = randint(100) + 100; - break; - case 6: - k = 300; - break; - default: - k = 500; - break; - } - - /* Apply the cut */ - if (k) (void)set_cut(p_ptr->cut + k); - } - - /* Handle stun */ - if (do_stun) - { - int k = 0; - - /* Critical hit (zero if non-critical) */ - tmp = monster_critical(d_dice, d_side, damage); - - /* Roll for damage */ - switch (tmp) - { - case 0: - k = 0; - break; - case 1: - k = randint(5); - break; - case 2: - k = randint(10) + 10; - break; - case 3: - k = randint(20) + 20; - break; - case 4: - k = randint(30) + 30; - break; - case 5: - k = randint(40) + 40; - break; - case 6: - k = 100; - break; - default: - k = 200; - break; - } - - /* Apply the stun */ - if (k) (void)set_stun(p_ptr->stun + k); - } - - if (touched) - { - if (p_ptr->sh_fire && alive) - { - r_ptr->r_flags3 |= RF3_IM_FIRE; - } - - if (p_ptr->sh_elec && alive) - { - r_ptr->r_flags3 |= RF3_IM_ELEC; - } - touched = FALSE; - } - } - - /* Monster missed player */ - else - { - /* Analyze failed attacks */ - switch (method) - { - case RBM_HIT: - case RBM_TOUCH: - case RBM_PUNCH: - case RBM_KICK: - case RBM_CLAW: - case RBM_BITE: - case RBM_STING: - case RBM_XXX1: - case RBM_BUTT: - case RBM_CRUSH: - case RBM_ENGULF: - case RBM_CHARGE: - - /* Disturbing */ - disturb(1, 0); - - /* Message */ - msg_format("%s misses you.", sym_name); - - break; - } - } - - - /* Analyze "visible" monsters only */ - if (visible) - { - /* Count "obvious" attacks (and ones that cause damage) */ - if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10)) - { - /* Count attacks of this type */ - if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR) - { - r_ptr->r_blows[ap_cnt]++; - } - } - } - } - /* Assume we attacked */ - return (TRUE); -} - -/* - * Give unprotected player the Black Breath with a 1 in (chance) probability - * - */ -void black_breath_attack(int chance) -{ - if (!p_ptr->protundead && randint(chance) == 1) - { - msg_print("Your foe calls upon your soul!"); - msg_print("You feel the Black Breath slowly draining you of life..."); - p_ptr->black_breath = TRUE; - } -} - -/* - * Attack the player via physical attacks. - */ -bool_ make_attack_normal(int m_idx, byte divis) -{ - monster_type *m_ptr = &m_list[m_idx]; - - monster_race *r_ptr = race_inf(m_ptr); - - int ap_cnt; - - int i, j, k, tmp, ac, rlev; - int do_cut, do_stun, do_vampire; - - s32b gold; - - object_type *o_ptr; - - char o_name[80]; - - char m_name[80]; - - char ddesc[80]; - - bool_ blinked; - bool_ touched = FALSE, fear = FALSE, alive = TRUE; - bool_ explode = FALSE; - - /* Not allowed to attack */ - if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE); - - /* ...nor if friendly */ - if (is_friend(m_ptr) >= 0) - { - if (p_ptr->control == m_idx) swap_position(m_ptr->fy, m_ptr->fx); - return FALSE; - } - - /* Cannot attack the player if mortal and player fated to never die by the ... */ - if ((r_ptr->flags7 & RF7_MORTAL) && (p_ptr->no_mortal)) return (FALSE); - - /* Total armor */ - ac = p_ptr->ac + p_ptr->to_a; - - /* Extract the effective monster level */ - rlev = ((m_ptr->level >= 1) ? m_ptr->level : 1); - - - /* Get the monster name (or "it") */ - monster_desc(m_name, m_ptr, 0); - - /* Get the "died from" information (i.e. "a kobold") */ - monster_desc(ddesc, m_ptr, 0x88); - - - /* Assume no blink */ - blinked = FALSE; - - /* Scan through all four blows */ - for (ap_cnt = 0; ap_cnt < 4; ap_cnt++) - { - bool_ visible = FALSE; - bool_ obvious = FALSE; - - int power = 0; - int damage = 0; - - cptr act = NULL; - - /* Extract the attack infomation */ - int effect = m_ptr->blow[ap_cnt].effect; - int method = m_ptr->blow[ap_cnt].method; - int d_dice = m_ptr->blow[ap_cnt].d_dice; - int d_side = m_ptr->blow[ap_cnt].d_side; - - - /* Hack -- no more attacks */ - if (!method) break; - - - /* Stop if player is dead or gone */ - if (!alive || death) break; - - /* Handle "leaving" */ - if (p_ptr->leaving) break; - - /* Extract visibility (before blink) */ - if (m_ptr->ml) visible = TRUE; - - /* Extract the attack "power" */ - switch (effect) - { - case RBE_HURT: - power = 60; - break; - case RBE_POISON: - power = 5; - break; - case RBE_UN_BONUS: - power = 20; - break; - case RBE_UN_POWER: - power = 15; - break; - case RBE_EAT_GOLD: - power = 5; - break; - case RBE_EAT_ITEM: - power = 5; - break; - case RBE_EAT_FOOD: - power = 5; - break; - case RBE_EAT_LITE: - power = 5; - break; - case RBE_ACID: - power = 0; - break; - case RBE_ELEC: - power = 10; - break; - case RBE_FIRE: - power = 10; - break; - case RBE_COLD: - power = 10; - break; - case RBE_BLIND: - power = 2; - break; - case RBE_CONFUSE: - power = 10; - break; - case RBE_TERRIFY: - power = 10; - break; - case RBE_PARALYZE: - power = 2; - break; - case RBE_LOSE_STR: - power = 0; - break; - case RBE_LOSE_DEX: - power = 0; - break; - case RBE_LOSE_CON: - power = 0; - break; - case RBE_LOSE_INT: - power = 0; - break; - case RBE_LOSE_WIS: - power = 0; - break; - case RBE_LOSE_CHR: - power = 0; - break; - case RBE_LOSE_ALL: - power = 2; - break; - case RBE_SHATTER: - power = 60; - break; - case RBE_EXP_10: - power = 5; - break; - case RBE_EXP_20: - power = 5; - break; - case RBE_EXP_40: - power = 5; - break; - case RBE_EXP_80: - power = 5; - break; - case RBE_DISEASE: - power = 5; - break; - case RBE_TIME: - power = 5; - break; - case RBE_SANITY: - power = 60; - break; - case RBE_HALLU: - power = 10; - break; - case RBE_PARASITE: - power = 5; - break; - case RBE_ABOMINATION: - power = 20; - break; - } - - - /* Monster hits player */ - if (!effect || check_hit(power, rlev)) - { - int chance = p_ptr->dodge_chance - ((rlev * 5) / 6); - - /* Always disturbing */ - disturb(1, 0); - - if ((chance > 0) && magik(chance)) - { - char m_poss[80]; - monster_desc(m_poss, m_ptr, 0x06); - msg_format("You dodge %s attack!", m_poss); - continue; - } - - /* Eru can help you */ - PRAY_GOD(GOD_ERU) - { - s32b chance = p_ptr->grace; - - if (chance > 50000) chance = 50000; - chance -= rlev * 300; - - if ((randint(100000) < chance) && (r_ptr->flags3 & (RF3_EVIL))) - { - /* Remember the Evil-ness */ - r_ptr->r_flags3 |= (RF3_EVIL); - - /* Message */ - msg_format("The hand of Eru Iluvatar stops %s blow.", m_name); - - /* Hack -- Next attack */ - continue; - } - } - - /* Hack -- Apply "protection from evil" */ - if ((p_ptr->protevil > 0) && - (r_ptr->flags3 & (RF3_EVIL)) && - (p_ptr->lev >= rlev) && - ((rand_int(100) + p_ptr->lev) > 50)) - { - /* Remember the Evil-ness */ - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_EVIL); - } - - /* Message */ - msg_format("%^s is repelled.", m_name); - - /* Hack -- Next attack */ - continue; - } - - /* Hack -- Apply "protection from good" */ - if ((p_ptr->protgood > 0) && - (r_ptr->flags3 & (RF3_GOOD)) && - (p_ptr->lev >= rlev) && - ((rand_int(100) + p_ptr->lev) > 50)) - { - /* Remember the Good-ness */ - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_GOOD); - } - - /* Message */ - msg_format("%^s is repelled.", m_name); - - /* Hack -- Next attack */ - continue; - } - - /* Assume no cut or stun */ - do_cut = do_stun = do_vampire = 0; - - /* Describe the attack method */ - switch (method) - { - case RBM_HIT: - { - act = "hits you."; - do_cut = do_stun = 1; - touched = TRUE; - sound(SOUND_HIT); - break; - } - - case RBM_TOUCH: - { - act = "touches you."; - touched = TRUE; - sound(SOUND_TOUCH); - break; - } - - case RBM_PUNCH: - { - act = "punches you."; - touched = TRUE; - do_stun = 1; - sound(SOUND_HIT); - break; - } - - case RBM_KICK: - { - act = "kicks you."; - touched = TRUE; - do_stun = 1; - sound(SOUND_HIT); - break; - } - - case RBM_CLAW: - { - act = "claws you."; - touched = TRUE; - do_cut = 1; - sound(SOUND_CLAW); - break; - } - - case RBM_BITE: - { - act = "bites you."; - do_cut = 1; - if (magik(5) && (strstr(r_name + r_ptr->name, "Vampire") || strstr(r_name + r_ptr->name, "vampire"))) - do_vampire = TRUE; - touched = TRUE; - sound(SOUND_BITE); - break; - } - - case RBM_STING: - { - act = "stings you."; - touched = TRUE; - sound(SOUND_STING); - break; - } - - case RBM_XXX1: - { - act = "XXX1's you."; - break; - } - - case RBM_BUTT: - { - act = "butts you."; - do_stun = 1; - touched = TRUE; - sound(SOUND_HIT); - break; - } - - case RBM_CRUSH: - { - act = "crushes you."; - do_stun = 1; - touched = TRUE; - sound(SOUND_CRUSH); - break; - } - - case RBM_ENGULF: - { - act = "engulfs you."; - touched = TRUE; - sound(SOUND_CRUSH); - break; - } - - case RBM_CHARGE: - { - act = "charges you."; - touched = TRUE; - sound(SOUND_BUY); /* Note! This is "charges", not "charges at". */ - break; - } - - case RBM_CRAWL: - { - act = "crawls on you."; - touched = TRUE; - sound(SOUND_SLIME); - break; - } - - case RBM_DROOL: - { - act = "drools on you."; - sound(SOUND_SLIME); - break; - } - - case RBM_SPIT: - { - act = "spits on you."; - sound(SOUND_SLIME); - break; - } - - case RBM_EXPLODE: - { - act = "explodes."; - explode = TRUE; - break; - } - - case RBM_GAZE: - { - act = "gazes at you."; - break; - } - - case RBM_WAIL: - { - act = "wails at you."; - sound(SOUND_WAIL); - break; - } - - case RBM_SPORE: - { - act = "releases spores at you."; - sound(SOUND_SLIME); - break; - } - - case RBM_XXX4: - { - act = "projects XXX4's at you."; - break; - } - - case RBM_BEG: - { - act = "begs you for money."; - sound(SOUND_MOAN); - break; - } - - case RBM_INSULT: - { - act = desc_insult[rand_int(8)]; - sound(SOUND_MOAN); - break; - } - - case RBM_MOAN: - { - if (strstr((r_name + r_ptr->name), "Mathilde, the Science Student")) - act = desc_moan[rand_int(3) + 4]; - else - act = desc_moan[rand_int(4)]; - sound(SOUND_MOAN); - break; - } - - case RBM_SHOW: - { - if (randint(3) == 1) - act = "sings 'We are a happy family.'"; - else - act = "sings 'I love you, you love me.'"; - sound(SOUND_SHOW); - break; - } - } - - /* Message */ - if (act) msg_format("%^s %s", m_name, act); - - /* The undead can give the player the Black Breath with - * a successful blow. Uniques have a better chance. -LM- - * Nazgul have a 25% chance - */ - if (r_ptr->flags7 & RF7_NAZGUL) - { - black_breath_attack(4); - } - else if ((m_ptr->level >= 35) && (r_ptr->flags3 & (RF3_UNDEAD)) && - (r_ptr->flags1 & (RF1_UNIQUE))) - { - black_breath_attack(300 - m_ptr->level); - } - else if ((m_ptr->level >= 40) && (r_ptr->flags3 & (RF3_UNDEAD))) - { - black_breath_attack(450 - m_ptr->level); - } - - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - - /* Roll out the damage */ - damage = damroll(d_dice, d_side); - - /* Sometime reduce the damage */ - damage /= divis; - - /* Apply appropriate damage */ - switch (effect) - { - case 0: - { - /* Hack -- Assume obvious */ - obvious = TRUE; - - /* Hack -- No damage */ - damage = 0; - - break; - } - - case RBE_HURT: - { - /* Obvious */ - obvious = TRUE; - - /* Hack -- Player armor reduces total damage */ - damage -= (damage * ((ac < 150) ? ac : 150) / 250); - - /* Take damage */ - take_hit(damage, ddesc); - - break; - } - - case RBE_ABOMINATION: - { - /* Obvious */ - obvious = TRUE; - - /* Morph, but let mimicry skill have a chance to stop this */ - if (magik(60 - get_skill(SKILL_MIMICRY))) - { - /* Message */ - cmsg_print(TERM_VIOLET, "You feel the dark powers twisting your body!"); - - set_mimic(damage, resolve_mimic_name("Abomination"), 50); - } - else - { - /* Message */ - cmsg_print(TERM_VIOLET, "You feel the dark powers trying to twisting your body, but they fail."); - } - - break; - } - - case RBE_SANITY: - { - obvious = TRUE; - - take_sanity_hit(damage, ddesc); - break; - } - - case RBE_POISON: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Take "poison" effect */ - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } - } - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_POIS); - - break; - } - - case RBE_UN_BONUS: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Allow complete resist */ - if (!p_ptr->resist_disen) - { - /* Apply disenchantment */ - if (apply_disenchant(0)) obvious = TRUE; - } - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_DISEN); - - break; - } - - case RBE_UN_POWER: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Find an item */ - for (k = 0; k < 10; k++) - { - /* Pick an item */ - i = rand_int(INVEN_PACK); - - /* Obtain the item */ - o_ptr = &p_ptr->inventory[i]; - - /* Skip non-objects */ - if (!o_ptr->k_idx) continue; - - /* Drain charged wands/staffs - Hack -- don't let artifacts get drained */ - if (((o_ptr->tval == TV_STAFF) || - (o_ptr->tval == TV_WAND)) && - (o_ptr->pval) && - !artifact_p(o_ptr)) - { - /* Message */ - msg_print("Energy drains from your pack!"); - - /* Obvious */ - obvious = TRUE; - - /* Heal */ - j = rlev; - m_ptr->hp += j * o_ptr->pval * o_ptr->number; - if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp; - - /* Redraw (later) if needed */ - if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); - - /* Uncharge */ - o_ptr->pval = 0; - - /* Combine / Reorder the pack */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN); - - /* Done */ - break; - } - } - - break; - } - - case RBE_EAT_GOLD: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Obvious */ - obvious = TRUE; - - /* Saving throw (unless paralyzed) based on dex and level */ - if (!p_ptr->paralyzed && - (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + - p_ptr->lev))) - { - /* Saving throw message */ - msg_print("You quickly protect your money pouch!"); - - /* Occasional blink anyway */ - if (rand_int(3)) blinked = TRUE; - } - - /* Eat gold */ - else - { - gold = (p_ptr->au / 10) + randint(25); - if (gold < 2) gold = 2; - if (gold > 5000) gold = (p_ptr->au / 20) + randint(3000); - if (gold > p_ptr->au) gold = p_ptr->au; - p_ptr->au -= gold; - if (gold <= 0) - { - msg_print("Nothing was stolen."); - } - else if (p_ptr->au) - { - msg_print("Your purse feels lighter."); - msg_format("%ld coins were stolen!", (long)gold); - } - else - { - msg_print("Your purse feels lighter."); - msg_print("All of your coins were stolen!"); - } - - while (gold > 0) - { - object_type forge, *j_ptr = &forge; - - /* Wipe the object */ - object_wipe(j_ptr); - - /* Prepare a gold object */ - object_prep(j_ptr, lookup_kind(TV_GOLD, 9)); - - /* Determine how much the treasure is "worth" */ - j_ptr->pval = (gold >= 15000) ? 15000 : gold; - - monster_carry(m_ptr, m_idx, j_ptr); - - gold -= 15000; - } - - /* Redraw gold */ - p_ptr->redraw |= (PR_GOLD); - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - - /* Blink away */ - blinked = TRUE; - } - - break; - } - - case RBE_EAT_ITEM: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Saving throw (unless paralyzed) based on dex and level */ - if (!p_ptr->paralyzed && - (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + - p_ptr->lev))) - { - /* Saving throw message */ - msg_print("You grab hold of your backpack!"); - - /* Occasional "blink" anyway */ - blinked = TRUE; - - /* Obvious */ - obvious = TRUE; - - /* Done */ - break; - } - - /* Find an item */ - for (k = 0; k < 10; k++) - { - /* Pick an item */ - i = rand_int(INVEN_PACK); - - /* Obtain the item */ - o_ptr = &p_ptr->inventory[i]; - - /* Skip non-objects */ - if (!o_ptr->k_idx) continue; - - /* Skip artifacts */ - if (artifact_p(o_ptr) || o_ptr->art_name) continue; - - /* Get a description */ - object_desc(o_name, o_ptr, FALSE, 3); - - /* Message */ - msg_format("%sour %s (%c) was stolen!", - ((o_ptr->number > 1) ? "One of y" : "Y"), - o_name, index_to_label(i)); - - /* Option */ - if (testing_carry) - { - s16b o_idx; - - /* Make an object */ - o_idx = o_pop(); - - /* Success */ - if (o_idx) - { - object_type *j_ptr; - - /* Get new object */ - j_ptr = &o_list[o_idx]; - - /* Copy object */ - object_copy(j_ptr, o_ptr); - - /* Modify number */ - j_ptr->number = 1; - - /* Hack -- If a wand, allocate total - * maximum timeouts or charges between those - * stolen and those missed. -LM- - */ - if (o_ptr->tval == TV_WAND) - { - j_ptr->pval = o_ptr->pval / o_ptr->number; - o_ptr->pval -= j_ptr->pval; - } - - /* Forget mark */ - j_ptr->marked = FALSE; - - /* Memorize monster */ - j_ptr->held_m_idx = m_idx; - - /* Build stack */ - j_ptr->next_o_idx = m_ptr->hold_o_idx; - - /* Build stack */ - m_ptr->hold_o_idx = o_idx; - } - } - else - { - if (strstr((r_name + r_ptr->name), "black market") - && randint(2) != 1) - { - s16b o_idx; - - /* Make an object */ - o_idx = o_pop(); - - /* Success */ - if (o_idx) - { - object_type *j_ptr; - if (cheat_xtra || cheat_peek) - msg_print("Moving object to black market..."); - - /* Get new object */ - j_ptr = &o_list[o_idx]; - - /* Copy object */ - object_copy(j_ptr, o_ptr); - - /* Modify number */ - j_ptr->number = 1; - - /* Forget mark */ - j_ptr->marked = FALSE; - - move_to_black_market(j_ptr); - } - } - } - - /* Steal the items */ - inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE); - - /* Obvious */ - obvious = TRUE; - - /* Blink away */ - blinked = TRUE; - - /* Done */ - break; - } - - break; - } - - case RBE_EAT_FOOD: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Steal some food */ - for (k = 0; k < 10; k++) - { - /* Pick an item from the pack */ - i = rand_int(INVEN_PACK); - - /* Get the item */ - o_ptr = &p_ptr->inventory[i]; - - /* Skip non-objects */ - if (!o_ptr->k_idx) continue; - - /* Skip non-food objects */ - if (o_ptr->tval != TV_FOOD) continue; - - /* Get a description */ - object_desc(o_name, o_ptr, FALSE, 0); - - /* Message */ - msg_format("%sour %s (%c) was eaten!", - ((o_ptr->number > 1) ? "One of y" : "Y"), - o_name, index_to_label(i)); - - /* Steal the items */ - inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE); - - /* Obvious */ - obvious = TRUE; - - /* Done */ - break; - } - - break; - } - - case RBE_EAT_LITE: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Access the lite */ - o_ptr = &p_ptr->inventory[INVEN_LITE]; - - /* Drain fuel */ - if ((o_ptr->pval > 0) && (!artifact_p(o_ptr))) - { - /* Reduce fuel */ - o_ptr->pval -= (250 + randint(250)); - if (o_ptr->pval < 1) o_ptr->pval = 1; - - /* Notice */ - if (!p_ptr->blind) - { - msg_print("Your light dims."); - obvious = TRUE; - } - - /* Window stuff */ - p_ptr->window |= (PW_EQUIP); - } - - break; - } - - case RBE_ACID: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are covered in acid!"); - - /* Special damage */ - acid_dam(damage, ddesc); - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_ACID); - - break; - } - - case RBE_ELEC: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are struck by electricity!"); - - /* Special damage */ - elec_dam(damage, ddesc); - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_ELEC); - - break; - } - - case RBE_FIRE: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are enveloped in flames!"); - - /* Special damage */ - fire_dam(damage, ddesc); - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_FIRE); - - break; - } - - case RBE_COLD: - { - /* Obvious */ - obvious = TRUE; - - /* Message */ - msg_print("You are covered with frost!"); - - /* Special damage */ - cold_dam(damage, ddesc); - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_COLD); - - break; - } - - case RBE_BLIND: - { - /* Take damage */ - take_hit(damage, ddesc); - - /* Increase "blind" */ - if (!p_ptr->resist_blind) - { - if (set_blind(p_ptr->blind + 10 + randint(rlev))) - { - obvious = TRUE; - } - } - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_BLIND); - - break; - } - - case RBE_CONFUSE: - { - /* Take damage */ - take_hit(damage, ddesc); - - /* Increase "confused" */ - if (!p_ptr->resist_conf) - { - if (set_confused(p_ptr->confused + 3 + randint(rlev))) - { - obvious = TRUE; - } - } - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_CONF); - - break; - } - - case RBE_TERRIFY: - { - /* Take damage */ - take_hit(damage, ddesc); - - /* Increase "afraid" */ - if (p_ptr->resist_fear) - { - msg_print("You stand your ground!"); - obvious = TRUE; - } - else if (rand_int(100) < p_ptr->skill_sav) - { - msg_print("You stand your ground!"); - obvious = TRUE; - } - else - { - if (set_afraid(p_ptr->afraid + 3 + randint(rlev))) - { - obvious = TRUE; - } - } - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_FEAR); - - break; - } - - case RBE_PARALYZE: - { - /* Hack -- Prevent perma-paralysis via damage */ - if (p_ptr->paralyzed && (damage < 1)) damage = 1; - - /* Take damage */ - take_hit(damage, ddesc); - - /* Increase "paralyzed" */ - if (p_ptr->free_act) - { - msg_print("You are unaffected!"); - obvious = TRUE; - } - else if (rand_int(100) < p_ptr->skill_sav) - { - msg_print("You resist the effects!"); - obvious = TRUE; - } - else - { - if (set_paralyzed(p_ptr->paralyzed + 3 + randint(rlev))) - { - obvious = TRUE; - } - } - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_FREE); - - break; - } - - case RBE_LOSE_STR: - { - /* Damage (physical) */ - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_INT: - { - /* Damage (physical) */ - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_WIS: - { - /* Damage (physical) */ - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_DEX: - { - /* Damage (physical) */ - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_CON: - { - /* Damage (physical) */ - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_CHR: - { - /* Damage (physical) */ - take_hit(damage, ddesc); - - /* Damage (stat) */ - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_LOSE_ALL: - { - /* Damage (physical) */ - take_hit(damage, ddesc); - - /* Damage (stats) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; - - break; - } - - case RBE_SHATTER: - { - /* Obvious */ - obvious = TRUE; - - /* Hack -- Reduce damage based on the player armor class */ - damage -= (damage * ((ac < 150) ? ac : 150) / 250); - - /* Take damage */ - take_hit(damage, ddesc); - - /* Radius 8 earthquake centered at the monster */ - if (damage > 23) - { - /* Prevent destruction of quest levels and town */ - if (!is_quest(dun_level) && dun_level) - earthquake(m_ptr->fy, m_ptr->fx, 8); - } - - break; - } - - case RBE_EXP_10: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 95)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(10, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_EXP_20: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 90)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(20, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_EXP_40: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 75)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(40, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_EXP_80: - { - /* Obvious */ - obvious = TRUE; - - /* Take damage */ - take_hit(damage, ddesc); - - if (p_ptr->hold_life && (rand_int(100) < 50)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(80, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - break; - } - - case RBE_DISEASE: - { - /* Take some damage */ - take_hit(damage, ddesc); - - /* Take "poison" effect */ - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } - } - - /* Damage CON (10% chance)*/ - if (randint(100) < 11) - { - /* 1% chance for perm. damage */ - bool_ perm = (randint(10) == 1); - if (dec_stat(A_CON, randint(10), perm)) obvious = TRUE; - } - - break; - } - case RBE_HALLU: - { - /* Take damage */ - take_hit(damage, ddesc); - - /* Increase "image" */ - if (!p_ptr->resist_chaos) - { - if (set_image(p_ptr->image + 3 + randint(rlev / 2))) - { - obvious = TRUE; - } - } - - /* Learn about the player */ - update_smart_learn(m_idx, DRS_CHAOS); - - break; - - } - case RBE_TIME: - { - switch (randint(10)) - { - case 1: - case 2: - case 3: - case 4: - case 5: - { - msg_print("You feel life has clocked back."); - lose_exp(100 + (p_ptr->exp / 100) * MON_DRAIN_LIFE); - break; - } - - case 6: - case 7: - case 8: - case 9: - { - int stat = rand_int(6); - - switch (stat) - { - case A_STR: - act = "strong"; - break; - case A_INT: - act = "bright"; - break; - case A_WIS: - act = "wise"; - break; - case A_DEX: - act = "agile"; - break; - case A_CON: - act = "hardy"; - break; - case A_CHR: - act = "beautiful"; - break; - } - - msg_format("You're not as %s as you used to be...", act); - - p_ptr->stat_cur[stat] = (p_ptr->stat_cur[stat] * 3) / 4; - if (p_ptr->stat_cur[stat] < 3) p_ptr->stat_cur[stat] = 3; - p_ptr->update |= (PU_BONUS); - break; - } - - case 10: - { - msg_print("You're not as powerful as you used to be..."); - - for (k = 0; k < 6; k++) - { - p_ptr->stat_cur[k] = (p_ptr->stat_cur[k] * 3) / 4; - if (p_ptr->stat_cur[k] < 3) p_ptr->stat_cur[k] = 3; - } - p_ptr->update |= (PU_BONUS); - break; - } - } - take_hit(damage, ddesc); - break; - } - case RBE_PARASITE: - { - /* Obvious */ - obvious = TRUE; - - if (!p_ptr->parasite) set_parasite(damage, m_ptr->r_idx); - - break; - } - } - - - /* Hack -- only one of cut or stun */ - if (do_cut && do_stun) - { - /* Cancel cut */ - if (rand_int(100) < 50) - { - do_cut = 0; - } - - /* Cancel stun */ - else - { - do_stun = 0; - } - } - - /* Handle cut */ - if (do_cut) - { - int k = 0; - - /* Critical hit (zero if non-critical) */ - tmp = monster_critical(d_dice, d_side, damage); - - /* Roll for damage */ - switch (tmp) - { - case 0: - k = 0; - break; - case 1: - k = randint(5); - break; - case 2: - k = randint(5) + 5; - break; - case 3: - k = randint(20) + 20; - break; - case 4: - k = randint(50) + 50; - break; - case 5: - k = randint(100) + 100; - break; - case 6: - k = 300; - break; - default: - k = 500; - break; - } - - /* Apply the cut */ - if (k) (void)set_cut(p_ptr->cut + k); - } - - /* Handle stun */ - if (do_stun) - { - int k = 0; - - /* Critical hit (zero if non-critical) */ - tmp = monster_critical(d_dice, d_side, damage); - - /* Roll for damage */ - switch (tmp) - { - case 0: - k = 0; - break; - case 1: - k = randint(5); - break; - case 2: - k = randint(10) + 10; - break; - case 3: - k = randint(20) + 20; - break; - case 4: - k = randint(30) + 30; - break; - case 5: - k = randint(40) + 40; - break; - case 6: - k = 100; - break; - default: - k = 200; - break; - } - - /* Apply the stun */ - if (k) (void)set_stun(p_ptr->stun + k); - } - - /* Do vampiric thingies */ - if (do_vampire) - { - /* Change to resist(but never total protection) */ -/* if (magik(3) || (magik(m_ptr->level - (p_ptr->lev / 2)))) - call_lua("gain_corruption", "(s)", "", "Vampire");*/ - } - - if (explode) - { - sound(SOUND_EXPLODE); - if (mon_take_hit(m_idx, m_ptr->hp + 1, &fear, NULL)) - { - blinked = FALSE; - alive = FALSE; - } - } - - if (touched) - { - if (p_ptr->sh_fire && alive) - { - if (!(r_ptr->flags3 & RF3_IM_FIRE)) - { - msg_format("%^s is suddenly very hot!", m_name); - if (mon_take_hit(m_idx, damroll(2, 6), &fear, - " turns into a pile of ash.")) - { - blinked = FALSE; - alive = FALSE; - } - } - else - { - if (m_ptr->ml) - r_ptr->r_flags3 |= RF3_IM_FIRE; - } - } - - if (p_ptr->sh_elec && alive) - { - if (!(r_ptr->flags3 & RF3_IM_ELEC)) - { - msg_format("%^s gets zapped!", m_name); - if (mon_take_hit(m_idx, damroll(2, 6), &fear, - " turns into a pile of cinder.")) - { - blinked = FALSE; - alive = FALSE; - } - } - else - { - if (m_ptr->ml) - r_ptr->r_flags3 |= RF3_IM_ELEC; - } - } - if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_COUNTER) && alive) - { - msg_format("%^s gets bashed by your mystic shield!", m_name); - if (mon_take_hit(m_idx, damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2), &fear, - " is bashed by your mystic shield.")) - { - blinked = FALSE; - alive = FALSE; - } - } - if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_FIRE) && alive) - { - if (!(r_ptr->flags3 & RF3_IM_FIRE)) - { - msg_format("%^s gets burned by your fiery shield!", m_name); - if (mon_take_hit(m_idx, damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2), &fear, - " is burned by your fiery shield.")) - { - blinked = FALSE; - alive = FALSE; - } - } - else - { - if (m_ptr->ml) - r_ptr->r_flags3 |= RF3_IM_FIRE; - } - } - if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_GREAT_FIRE) && alive) - { - msg_format("%^s gets burned by your fiery shield!", m_name); - if (mon_take_hit(m_idx, damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2), &fear, - " is burned by your fiery shield.")) - { - blinked = FALSE; - alive = FALSE; - } - } - if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_FEAR) && alive) - { - int tmp; - - if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2) - m_ptr->level > 0)) - { - msg_format("%^s gets scared away!", m_name); - - /* Increase fear */ - tmp = m_ptr->monfear + p_ptr->shield_power_opt; - fear = TRUE; - - /* Set fear */ - m_ptr->monfear = (tmp < 200) ? tmp : 200; - } - } - - touched = FALSE; - } - } - - /* Monster missed player */ - else - { - /* Analyze failed attacks */ - switch (method) - { - case RBM_HIT: - case RBM_TOUCH: - case RBM_PUNCH: - case RBM_KICK: - case RBM_CLAW: - case RBM_BITE: - case RBM_STING: - case RBM_XXX1: - case RBM_BUTT: - case RBM_CRUSH: - case RBM_ENGULF: - case RBM_CHARGE: - - /* Visible monsters */ - if (m_ptr->ml) - { - /* Disturbing */ - disturb(1, 0); - - /* Message */ - msg_format("%^s misses you.", m_name); - } - - break; - } - } - - - /* Analyze "visible" monsters only */ - if (visible) - { - /* Count "obvious" attacks (and ones that cause damage) */ - if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10)) - { - /* Count attacks of this type */ - if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR) - { - r_ptr->r_blows[ap_cnt]++; - } - } - } - } - - - /* Blink away */ - if (blinked) - { - msg_print("The thief flees laughing!"); - teleport_away(m_idx, MAX_SIGHT * 2 + 5); - } - - - /* Always notice cause of death */ - if (death && (r_ptr->r_deaths < MAX_SHORT)) - { - r_ptr->r_deaths++; - } - - if (m_ptr->ml && fear) - { - sound (SOUND_FLEE); - msg_format("%^s flees in terror!", m_name); - } - - /* Assume we attacked */ - return (TRUE); -} - - |