void CControlAnimationBase::on_event(ControlCom::EEventType type, ControlCom::IEventData *data) { switch (type) { case ControlCom::eventAnimationEnd: select_animation(true); m_state_attack = false; break; case ControlCom::eventAnimationSignal: { SAnimationSignalEventData *event_data = (SAnimationSignalEventData *)data; if (event_data->event_id == CControlAnimation::eAnimationHit) check_hit(event_data->motion,event_data->time_perc); break; } } }
void BulletFlame::process_idle() { // Sprite::process_idle(); if( ++cur_frame <= cur_sprite_stop()->frame_count ) { // ----- warn/ attack target every frame -------// warn_target(); check_hit(); } else { cur_action = SPRITE_DIE; cur_frame = 1; } }
void BulletProgram::process_move() { cur_frame ++; //----- if the sprite has reach the destintion ----// if( ++cur_step > total_step + delay_step ) { check_hit(); cur_action = SPRITE_DIE; // Explosion cur_frame = 0; } else if( total_step - cur_step == 1 ) { warn_target(); } }
void Bullet::process_move() { //-------------- update position -----------------// // // If it gets very close to the destination, fit it // to the destination ingoring the normal vector. // //------------------------------------------------// cur_x = origin_x + (int)(go_x-origin_x) * cur_step / total_step; cur_y = origin_y + (int)(go_y-origin_y) * cur_step / total_step; //cur_step++; //------- update frame id. --------// if( ++cur_frame > cur_sprite_move()->frame_count ) cur_frame = 1; //----- if the sprite has reach the destintion ----// //if( cur_step > total_step ) if( ++cur_step > total_step ) { check_hit(); cur_action = SPRITE_DIE; // Explosion // ###### begin Gilbert 17/5 #########// // if it has die frame, adjust cur_x, cur_y to be align with the target_x_loc, target_y_loc if( sprite_info->die.first_frame_recno ) { next_x = cur_x = target_x_loc * ZOOM_LOC_WIDTH; next_y =cur_y = target_y_loc * ZOOM_LOC_HEIGHT; } // ###### end Gilbert 17/5 #########// cur_frame = 1; } else if( total_step - cur_step == 1 ) { warn_target(); } }
/** * Returns 0 if miss, -id if sunk, +id if hit (not sunk) */ int do_receive(const int sock) { int nbytes,res; BMesg *buf; buf = CreateEmptyBMesg(); if ( (nbytes = recv(sock, buf, MAX_MSG, 0) == -1) ) { /*recv error*/ cleanup_ncurses(); perror("recv error"); exit(EXIT_FAILURE); } //we successfully returned from recv //printw("Received %d bytes of data...Such as %s\n", nbytes, buf->code); refresh(); //parse buf to see if it was a hit and respond if ( (res = check_hit(buf)) != 0 ) { /*it was a hit*/ if (check_game_over()) { /*the game is over*/ send_hit(sock, GAME_OVER); return 100; //magic number...i know it's bad but i'm ready to be done. } else { if (res < 0) { send_hit(sock, SUNK); return res; } else if (res > 0) { send_hit(sock, NULL); return res; } else { cleanup_ncurses(); perror("Unexpected case in do_receive"); exit(EXIT_FAILURE); } } } else { send_miss(sock); return res; //res==0 } //At this point we should have sent exactly 1 response to the other user *and returned* //WE SHOULD NEVER GET HERE cleanup_ncurses(); perror("Reached unexpected worlds...."); exit(EXIT_FAILURE); return -1; //just to make the compiler happy }
/** * Process a monster spell * * \param index is the monster spell flag (RSF_FOO) * \param mon is the attacking monster * \param seen is whether the player can see the monster at this moment */ void do_mon_spell(int index, struct monster *mon, bool seen) { char m_name[80]; bool ident, hits = FALSE; /* Extract the monster level */ int rlev = ((mon->race->level >= 1) ? mon->race->level : 1); const struct monster_spell *spell = monster_spell_by_index(index); /* Get the monster name (or "it") */ monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD); /* See if it hits */ if (spell->hit == 100) hits = TRUE; else if (spell->hit == 0) hits = FALSE; else hits = check_hit(player, spell->hit, rlev); /* Tell the player what's going on */ disturb(player, 1); spell_message(mon, spell, seen, hits); if (!hits) return; /* Try a saving throw if available */ if (spell->save_message && randint0(100) < player->state.skills[SKILL_SAVE]) { msg("%s", spell->save_message); return; } /* Do effects */ effect_do(spell->effect, NULL, &ident, TRUE, 0, 0, 0); return; }
/* * Attack the player via physical attacks. */ bool make_attack_normal(int m_idx) { monster_type *m_ptr = &mon_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; monster_lore *l_ptr = &l_list[m_ptr->r_idx]; int ap_cnt; int i, k, tmp, ac, rlev; int do_cut, do_stun; s32b gold; object_type *o_ptr; char o_name[80]; char m_name[80]; char ddesc[80]; bool blinked; /* 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); /* Get the monster name (or "it") */ monster_desc(m_name, sizeof(m_name), m_ptr, 0); /* Get the "died from" information (i.e. "a kobold") */ monster_desc(ddesc, sizeof(ddesc), m_ptr, 0x88); /* Assume no blink */ blinked = FALSE; /* Scan through all blows */ for (ap_cnt = 0; ap_cnt < MONSTER_BLOW_MAX; 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; /* 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_HALLU: power = 10; break; } /* 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 */ if (m_ptr->ml) { l_ptr->flags3 |= (RF3_EVIL); } /* Message */ msg_format("%^s is repelled.", m_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; break; } case RBM_TOUCH: { act = "touches you."; break; } case RBM_PUNCH: { act = "punches you."; do_stun = 1; break; } case RBM_KICK: { act = "kicks you."; do_stun = 1; break; } case RBM_CLAW: { act = "claws you."; do_cut = 1; break; } case RBM_BITE: { act = "bites you."; do_cut = 1; break; } case RBM_STING: { act = "stings you."; break; } case RBM_XXX1: { act = "XXX1's you."; break; } case RBM_BUTT: { act = "butts you."; do_stun = 1; break; } case RBM_CRUSH: { act = "crushes you."; do_stun = 1; break; } case RBM_ENGULF: { act = "engulfs you."; break; } case RBM_XXX2: { act = "XXX2's you."; break; } case RBM_CRAWL: { act = "crawls on you."; break; } case RBM_DROOL: { act = "drools on you."; break; } case RBM_SPIT: { act = "spits on you."; break; } case RBM_XXX3: { act = "XXX3's on you."; break; } case RBM_GAZE: { act = "gazes at you."; break; } case RBM_WAIL: { act = "wails at you."; break; } case RBM_SPORE: { act = "releases spores at you."; break; } case RBM_XXX4: { act = "projects XXX4's at you."; break; } case RBM_BEG: { act = "begs you for money."; break; } case RBM_INSULT: { act = desc_insult[rand_int(MAX_DESC_INSULT)]; break; } case RBM_MOAN: { act = desc_moan[rand_int(MAX_DESC_MOAN)]; break; } case RBM_XXX5: { act = "XXX5's you."; break; } } /* Message */ if (act) msg_format("%^s %s", m_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 */ take_hit(damage, ddesc); break; } case RBE_POISON: { /* Take 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_RES_POIS); break; } case RBE_UN_BONUS: { /* Take 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_RES_DISEN); break; } case RBE_UN_POWER: { /* Take 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 = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Drain charged wands/staffs */ if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) && (o_ptr->pval > 0)) { /* Calculate healed hitpoints */ int heal = rlev * o_ptr->pval * o_ptr->number; /* Don't heal more than max hp */ heal = MIN(heal, m_ptr->maxhp - m_ptr->hp); /* Message */ msg_print("Energy drains from your pack!"); /* Obvious */ obvious = TRUE; /* Heal */ m_ptr->hp += heal; /* Redraw (later) if needed */ if (p_ptr->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 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!"); } /* Redraw gold */ p_ptr->redraw |= (PR_GOLD); /* Window stuff */ p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Blink away */ blinked = TRUE; } break; } case RBE_EAT_ITEM: { /* Take 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++) { object_type *i_ptr; object_type object_type_body; /* Pick an item */ i = rand_int(INVEN_PACK); /* Obtain the item */ o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Skip artifacts */ if (artifact_p(o_ptr)) continue; /* Get a description */ object_desc(o_name, sizeof(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)); /* Get local object */ i_ptr = &object_type_body; /* Obtain local object */ object_copy(i_ptr, o_ptr); /* Modify number */ i_ptr->number = 1; /* Carry the object */ (void)monster_carry(m_idx, i_ptr); /* Steal the items */ inven_item_increase(i, -1); inven_item_optimize(i); /* Obvious */ obvious = TRUE; /* Blink away */ blinked = TRUE; /* Done */ break; } break; } case RBE_EAT_FOOD: { /* Take 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 = &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, sizeof(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 */ inven_item_increase(i, -1); inven_item_optimize(i); /* Obvious */ obvious = TRUE; /* Done */ break; } break; } case RBE_EAT_LITE: { /* Take damage */ take_hit(damage, ddesc); /* Get the lite */ o_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_RES_ACID); break; } case RBE_ELEC: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are struck by electricity!"); /* Take damage (special) */ elec_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_ELEC); break; } case RBE_FIRE: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are enveloped in flames!"); /* Take damage (special) */ fire_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_FIRE); break; } case RBE_COLD: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are covered with frost!"); /* Take damage (special) */ cold_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_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_RES_BLIND); break; } case RBE_CONFUSE: { /* Take damage */ take_hit(damage, ddesc); /* Increase "confused" */ if (!p_ptr->resist_confu) { if (set_confused(p_ptr->confused + 3 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_CONFU); 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_RES_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: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_STR)) obvious = TRUE; break; } case RBE_LOSE_INT: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_INT)) obvious = TRUE; break; } case RBE_LOSE_WIS: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_WIS)) obvious = TRUE; break; } case RBE_LOSE_DEX: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_DEX)) obvious = TRUE; break; } case RBE_LOSE_CON: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_CON)) obvious = TRUE; break; } case RBE_LOSE_CHR: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_CHR)) obvious = TRUE; break; } case RBE_LOSE_ALL: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stats) */ if (do_dec_stat(A_STR)) obvious = TRUE; if (do_dec_stat(A_DEX)) obvious = TRUE; if (do_dec_stat(A_CON)) obvious = TRUE; if (do_dec_stat(A_INT)) obvious = TRUE; if (do_dec_stat(A_WIS)) obvious = TRUE; if (do_dec_stat(A_CHR)) 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) 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_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_RES_CHAOS); 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; /* 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; /* 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); } } /* 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_XXX2: /* 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 || (l_ptr->blows[ap_cnt] > 10)) { /* Count attacks of this type */ if (l_ptr->blows[ap_cnt] < MAX_UCHAR) { l_ptr->blows[ap_cnt]++; } } } } /* Blink away */ if (blinked) { msg_print("There is a puff of smoke!"); teleport_away(m_idx, MAX_SIGHT * 2 + 5); } /* Always notice cause of death */ if (p_ptr->is_dead && (l_ptr->deaths < MAX_SHORT)) { l_ptr->deaths++; } /* Assume we attacked */ return (TRUE); }
/** Handle message from agent socket. */ int connhipd_handle_msg(struct hip_common *msg, struct sockaddr_un *addr) { /* Variables. */ struct hip_tlv_common *param = NULL, *param2 = NULL; struct hip_common *emsg; hip_hdr_type_t type; HIT_Remote hit, *r; HIT_Local *l; socklen_t alen; struct in6_addr *lhit, *rhit; int err = 0, ret, n, direction, check; char chit[128], *type_s; struct in6_addr hitr ; type = hip_get_msg_type(msg); if (type == SO_HIP_AGENT_PING_REPLY) { HIP_DEBUG("Received ping reply from daemon. Connection to daemon established.\n"); gui_set_info(lang_get("gui-info-000")); hip_agent_connected = 1; } else if (type == SO_HIP_SET_NAT_ON) { gui_update_nat(1); HIP_DEBUG("NAT extensions on.\n"); } else if (type == SO_HIP_SET_NAT_OFF) { gui_update_nat(0); HIP_DEBUG("NAT extensions off.\n"); } else if (type == SO_HIP_DAEMON_QUIT) { HIP_DEBUG("Daemon quit. Waiting daemon to wake up again...\n"); gui_set_info(lang_get("gui-info-001")); hip_agent_connected = 0; } else if (type == SO_HIP_ADD_DB_HI) { HIP_DEBUG("Message received successfully from daemon with type" " HIP_ADD_DB_HI (%d).\n", type); n = 0; while((param = hip_get_next_param(msg, param))) { if (hip_get_param_type(param) == HIP_PARAM_HIT) { lhit = (struct in6_addr *)hip_get_param_contents_direct(param); HIP_HEXDUMP("Adding local HIT:", lhit, 16); print_hit_to_buffer(chit, lhit); hit_db_add_local(chit, lhit); n++; } } } else if (type == SO_HIP_UPDATE_HIU) { n = 0; gui_hiu_clear(); while((param = hip_get_next_param(msg, param))) { /*param2 = hip_get_next_param(msg, param); if (param2 == NULL) break;*/ if (hip_get_param_type(param) == HIP_PARAM_HIT)/* && hip_get_param_type(param2) == HIP_PARAM_HIT)*/ { rhit = (struct in6_addr *)hip_get_param_contents_direct(param); //lhit = hip_get_param_contents_direct(param2); r = hit_db_find(NULL, rhit); if (r) { gui_hiu_add(r); n++; } } } gui_hiu_count(n); } else if (type == HIP_I1 || type == HIP_R1) { NAMECPY(hit.name, ""); URLCPY(hit.url, "<notset>"); URLCPY(hit.port, ""); HIP_DEBUG("Message from daemon, %d bytes.\n", hip_get_msg_total_len(msg)); /* Get original message, which is encapsulated inside received one. */ emsg = (struct hip_common *)hip_get_param_contents(msg, HIP_PARAM_ENCAPS_MSG); HIP_IFEL(!emsg, -1, "Could not get msg parameter!\n"); HIP_HEXDUMP("msg->hits: ", &emsg->hits, 16); HIP_HEXDUMP("msg->hitr: ", &emsg->hitr, 16); /* Find out, which of the HITs in the message is local HIT. */ l = hit_db_find_local(NULL, &emsg->hits); if (!l) { l = hit_db_find_local(NULL, &emsg->hitr); if (l) { memcpy(&hit.hit, &emsg->hits, sizeof(hit.hit)); } HIP_IFEL(!l, -1, "Did not find local HIT for message!\n"); } else { memcpy(&hit.hit, &emsg->hitr, sizeof(hit.hit)); } HIP_DEBUG("Received %s %s from daemon.\n", "incoming", type == HIP_I1 ? "I1" : "R1"); /* Check the remote HIT from database. */ if (l) { memcpy(&hitr,&hit.hit, sizeof(struct in6_addr)); ret = check_hit(&hit, 0); /*Send our hits -- peer hit to daemon*/ if (ret == 1) ret = 0; /*hit already exist in the database and is accepted so no need to send it to daemon*/ else if (ret == 0) connhipd_send_hitdata_to_daemon (msg, &hitr, &hit.g->l->lhit) ; /* Reset local HIT, if outgoing I1. */ /*HIP_HEXDUMP("Old local HIT: ", &msg->hits, 16); HIP_HEXDUMP("New local HIT: ", &hit.g->l->lhit, 16); HIP_HEXDUMP("Old remote HIT: ", &msg->hitr, 16); HIP_HEXDUMP("New remote HIT: ", &hit.hit, 16);*/ } /* If neither HIT in message was local HIT, then drop the packet! */ else { HIP_DEBUG("Failed to find local HIT from database for packet." " Rejecting packet automatically.\n"); HIP_HEXDUMP("msg->hits: ", &msg->hits, 16); HIP_HEXDUMP("msg->hitr: ", &msg->hits, 16); ret = -1; } /* Now either reject or accept the packet, according to previous results. */ if (ret == 0) { HIP_DEBUG("Message accepted, sending back to daemon, %d bytes.\n", hip_get_msg_total_len(msg)); n = hip_send_recv_daemon_info((char *)msg, 1, hip_agent_sock); HIP_IFEL(n < 0, -1, "Could not send message back to daemon" " (%d: %s).\n", errno, strerror(errno)); HIP_DEBUG("Reply sent successfully.\n"); } else if (type == HIP_R1) { HIP_DEBUG("Message rejected.\n"); n = 1; HIP_IFE(hip_build_param_contents(msg, &n, HIP_PARAM_AGENT_REJECT, sizeof(n)), -1); n = hip_send_recv_daemon_info((char *)msg, 1, hip_agent_sock); HIP_IFEL(n < 0, -1, "Could not send message back to daemon" " (%d: %s).\n", errno, strerror(errno)); HIP_DEBUG("Reply sent successfully.\n"); } else { HIP_DEBUG("Message rejected.\n"); } } out_err: // HIP_DEBUG("Message handled.\n"); return (err); }
/** * Process a monster spell * * \param spell is the monster spell flag (RSF_FOO) * \param m_idx is the attacking monster * \param seen is whether the player can see the monster at this moment */ void do_mon_spell(int spell, int m_idx, bool seen) { const struct mon_spell *rs_ptr = &mon_spell_table[spell]; monster_type *m_ptr = cave_monster(cave, m_idx); monster_race *r_ptr = &r_info[m_ptr->r_idx]; char m_name[80], ddesc[80]; bool hits = FALSE; int dam = 0, flag = 0, rad = 0; /* Extract the monster level */ int rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); /* Get the monster name (or "it") */ monster_desc(m_name, sizeof(m_name), m_ptr, 0x00); /* See if it hits */ if (rs_ptr->hit == 100) hits = TRUE; else if (rs_ptr->hit == 0) hits = FALSE; else hits = check_hit(p_ptr, rs_ptr->hit, rlev); /* Tell the player what's going on */ disturb(p_ptr, 1,0); if (!seen) msg("Something %s.", rs_ptr->blind_verb); else if (!hits) { msg("%^s %s %s, but misses.", m_name, rs_ptr->verb, rs_ptr->desc); return; } else if (rs_ptr->msgt) msgt(rs_ptr->msgt, "%^s %s %s.", m_name, rs_ptr->verb, rs_ptr->desc); else msg("%^s %s %s.", m_name, rs_ptr->verb, rs_ptr->desc); /* Try a saving throw if available */ if (rs_ptr->save && randint0(100) < p_ptr->state.skills[SKILL_SAVE]) { msg("You avoid the effects!"); return; } /* Calculate the damage */ dam = mon_spell_dam(spell, m_ptr->hp, rlev, RANDOMISE); /* Get the "died from" name in case this attack kills @ */ monster_desc(ddesc, sizeof(ddesc), m_ptr, MDESC_SHOW | MDESC_IND2); /* Display the attack, adjust for resists and apply effects */ if (rs_ptr->type & RST_BOLT) flag = PROJECT_STOP | PROJECT_KILL; else if (rs_ptr->type & (RST_BALL | RST_BREATH)) { flag = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL; rad = rf_has(r_ptr->flags, RF_POWERFUL) ? 3 : 2; } if (rs_ptr->gf) { (void)project(m_idx, rad, p_ptr->py, p_ptr->px, dam, rs_ptr->gf, flag); monster_learn_resists(m_ptr, p_ptr, rs_ptr->gf); } else /* Note that non-projectable attacks are unresistable */ take_hit(p_ptr, dam, ddesc); do_side_effects(spell, dam, m_idx, seen); return; }
/** * Attack the player via physical attacks. */ bool make_attack_normal(struct monster *mon, struct player *p) { struct monster_lore *lore = get_lore(mon->race); int ap_cnt; int k, tmp, ac, rlev; char m_name[80]; char ddesc[80]; bool blinked; /* Not allowed to attack */ if (rf_has(mon->race->flags, RF_NEVER_BLOW)) return (false); /* Total armor */ ac = p->state.ac + p->state.to_a; /* Extract the effective monster level */ rlev = ((mon->race->level >= 1) ? mon->race->level : 1); /* Get the monster name (or "it") */ monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD); /* Get the "died from" information (i.e. "a kobold") */ monster_desc(ddesc, sizeof(ddesc), mon, MDESC_SHOW | MDESC_IND_VIS); /* Assume no blink */ blinked = false; /* Scan through all blows */ for (ap_cnt = 0; ap_cnt < z_info->mon_blows_max; ap_cnt++) { bool visible = false; bool obvious = false; bool do_break = false; int power = 0; int damage = 0; int do_cut = 0; int do_stun = 0; int sound_msg = MSG_GENERIC; const char *act = NULL; /* Extract the attack infomation */ int effect = mon->race->blow[ap_cnt].effect; int method = mon->race->blow[ap_cnt].method; random_value dice = mon->race->blow[ap_cnt].dice; /* Hack -- no more attacks */ if (!method) break; /* Handle "leaving" */ if (p->is_dead || p->upkeep->generate_level) break; /* Extract visibility (before blink) */ if (mflag_has(mon->mflag, MFLAG_VISIBLE)) visible = true; /* Extract visibility from carrying light */ if (rf_has(mon->race->flags, RF_HAS_LIGHT)) visible = true; /* Extract the attack "power" */ power = monster_blow_effect_power(effect); /* Monster hits player */ if (!effect || check_hit(p, power, rlev)) { melee_effect_handler_f effect_handler; /* Always disturbing */ disturb(p, 1); /* Hack -- Apply "protection from evil" */ if (p->timed[TMD_PROTEVIL] > 0) { /* Learn about the evil flag */ if (mflag_has(mon->mflag, MFLAG_VISIBLE)) rf_on(lore->flags, RF_EVIL); if (rf_has(mon->race->flags, RF_EVIL) && p->lev >= rlev && randint0(100) + p->lev > 50) { /* Message */ msg("%s is repelled.", m_name); /* Hack -- Next attack */ continue; } } /* Describe the attack method */ act = monster_blow_method_action(method); do_cut = monster_blow_method_cut(method); do_stun = monster_blow_method_stun(method); sound_msg = monster_blow_method_message(method); /* Message */ if (act) msgt(sound_msg, "%s %s", m_name, act); /* Hack -- assume all attacks are obvious */ obvious = true; /* Roll dice */ damage = randcalc(dice, rlev, RANDOMISE); /* Perform the actual effect. */ effect_handler = melee_handler_for_blow_effect(effect); if (effect_handler != NULL) { melee_effect_handler_context_t context = { p, mon, rlev, method, ac, ddesc, obvious, blinked, do_break, damage, }; effect_handler(&context); /* Save any changes made in the handler for later use. */ obvious = context.obvious; blinked = context.blinked; damage = context.damage; do_break = context.do_break; } else { msg("ERROR: Effect handler not found for %d.", effect); } /* Don't cut or stun if player is dead */ if (p->is_dead) { do_cut = false; do_stun = false; } /* Hack -- only one of cut or stun */ if (do_cut && do_stun) { /* Cancel cut */ if (randint0(100) < 50) do_cut = 0; /* Cancel stun */ else do_stun = 0; } /* Handle cut */ if (do_cut) { /* Critical hit (zero if non-critical) */ tmp = monster_critical(dice, rlev, damage); /* Roll for damage */ switch (tmp) { case 0: k = 0; break; case 1: k = randint1(5); break; case 2: k = randint1(5) + 5; break; case 3: k = randint1(20) + 20; break; case 4: k = randint1(50) + 50; break; case 5: k = randint1(100) + 100; break; case 6: k = 300; break; default: k = 500; break; } /* Apply the cut */ if (k) (void)player_inc_timed(p, TMD_CUT, k, true, true); } /* Handle stun */ if (do_stun) { /* Critical hit (zero if non-critical) */ tmp = monster_critical(dice, rlev, damage); /* Roll for damage */ switch (tmp) { case 0: k = 0; break; case 1: k = randint1(5); break; case 2: k = randint1(10) + 10; break; case 3: k = randint1(20) + 20; break; case 4: k = randint1(30) + 30; break; case 5: k = randint1(40) + 40; break; case 6: k = 100; break; default: k = 200; break; } /* Apply the stun */ if (k) (void)player_inc_timed(p, TMD_STUN, k, true, true); } } else { /* Visible monster missed player, so notify if appropriate. */ if (mflag_has(mon->mflag, MFLAG_VISIBLE) && monster_blow_method_miss(method)) { /* Disturbing */ disturb(p, 1); msg("%s misses you.", m_name); } } /* Analyze "visible" monsters only */ if (visible) { /* Count "obvious" attacks (and ones that cause damage) */ if (obvious || damage || (lore->blows[ap_cnt].times_seen > 10)) { /* Count attacks of this type */ if (lore->blows[ap_cnt].times_seen < UCHAR_MAX) lore->blows[ap_cnt].times_seen++; } } /* Skip the other blows if necessary */ if (do_break) break; } /* Blink away */ if (blinked) { char dice[5]; msg("There is a puff of smoke!"); strnfmt(dice, sizeof(dice), "%d", z_info->max_sight * 2 + 5); effect_simple(EF_TELEPORT, dice, 0, 0, 0, NULL); } /* Always notice cause of death */ if (p->is_dead && (lore->deaths < SHRT_MAX)) lore->deaths++; /* Learn lore */ lore_update(mon->race, lore); /* Assume we attacked */ return (true); }
// --------- begin of function BulletHoming::process_move --------// void BulletHoming::process_move() { int actualStep = total_step; if(target_type == BULLET_TARGET_UNIT) { Unit *unitPtr; if( unit_array.is_deleted(target_recno) || !(unitPtr = unit_array[target_recno]) || !unitPtr->is_visible() ) { // target lost/die, proceed to Bullet::process_move target_type = BULLET_TARGET_NONE; } else { // ---- calculate new target_x_loc, target_y_loc -----// target_x_loc = unitPtr->next_x_loc(); target_y_loc = unitPtr->next_y_loc(); // ---- re-calculate go_x, go_y ------// // go_x/y and origin2_x/y are pointing at the centre of the bullet bitmap // it is different from Bullet go_x = unitPtr->cur_x + ZOOM_LOC_WIDTH / 2; go_y = unitPtr->cur_y + ZOOM_LOC_HEIGHT /2; //---------- set bullet movement steps -----------// SpriteFrame *spriteFrame = cur_sprite_frame(); int adjX = spriteFrame->offset_x+spriteFrame->width/2; int adjY = spriteFrame->offset_y+spriteFrame->height/2; int xStep = abs(go_x - (cur_x+adjX))/speed; int yStep = abs(go_y - (cur_y+adjY))/speed; total_step = cur_step + MAX(xStep, yStep); // a homing bullet has a limited range, if the target go outside the // the limit, the bullet can't attack the target // in this case, actualStep is the number step from the source // to the target; total_step is the max_step // otherwise, actualStep is as same as total_step actualStep = total_step; if( total_step > max_step ) { total_step = max_step; // target_x_loc and target_y_loc is limited also target_x_loc = (cur_x + adjX) + (int)(go_x-(cur_x+adjX)) / (actualStep - total_step) / ZOOM_LOC_WIDTH; target_x_loc = (cur_y + adjY) + (int)(go_y-(cur_y+adjY)) / (actualStep - total_step) / ZOOM_LOC_HEIGHT; } } } // origin2_x = origin_x; // origin2_y = origin_y; // origin_x/y and origin2_x/y are pointing at the centre of the bullet bitmap // SpriteFrame *spriteFrame = cur_sprite_frame(); short adjX = spriteFrame->offset_x + spriteFrame->width/2; short adjY = spriteFrame->offset_y + spriteFrame->height/2; origin_x = cur_x + adjX; origin_y = cur_y + adjY; cur_x = origin_x + (int)(go_x-origin_x) / (actualStep + 1 - cur_step); cur_y = origin_y + (int)(go_y-origin_y) / (actualStep + 1 - cur_step); // cur_x, cur_y is temporary pointing at the centre of bullet bitmap // detect changing direction if( cur_step > 3 ) // not allow changing direction so fast set_dir(origin2_x, origin2_y, cur_x, cur_y); // change cur_x, cur_y to bitmap reference point spriteFrame= cur_sprite_frame(); adjX = spriteFrame->offset_x + spriteFrame->width/2; adjY = spriteFrame->offset_y + spriteFrame->height/2; cur_x -= adjX; cur_y -= adjY; cur_step++; //------- update frame id. --------// if( ++cur_frame > cur_sprite_move()->frame_count ) cur_frame = 1; //----- if the sprite has reach the destintion ----// if( cur_step > total_step ) { check_hit(); cur_action = SPRITE_DIE; // Explosion // ###### begin Gilbert 17/5 ########// // if it has die frame, adjust cur_x, cur_y to be align with the target_x_loc, target_y_loc if( sprite_info->die.first_frame_recno ) { next_x = cur_x = target_x_loc * ZOOM_LOC_WIDTH; next_y = cur_y = target_y_loc * ZOOM_LOC_HEIGHT; } // ###### end Gilbert 17/5 ########// cur_frame = 1; } // change of total_step may not call warn_target, so call more warn_target else if( total_step - cur_step <= 1 ) { warn_target(); } }
/* * Attack the player via physical attacks. */ bool make_attack_normal(int m_idx) { monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; monster_lore *l_ptr = &l_list[m_ptr->r_idx]; int ap_cnt; int tmp, ac, rlev; int do_cut, do_stun, touched; char m_name[80]; char ddesc[80]; bool blinked; /* 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); /* Get the monster name (or "it") */ monster_desc(m_name, m_ptr, 0); /* Get the "died from" information (i.e. "a goblin") */ 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 = 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; /* Handle "leaving" */ if (p_ptr->leaving) break; /* Extract visibility (before blink) */ if (m_ptr->ml) visible = TRUE; /* Skip 'tricky' attacks */ if (method > RBM_MAX_NORMAL) continue; /* Assume no cut or stun or touched */ do_cut = do_stun = touched = 0; /* Extract the attack "power". Elemental attacks upgraded. */ switch (effect) { case GF_HURT: power = 60; break; case GF_WOUND: power = 60; break; case GF_BATTER: power = 60; break; case GF_SHATTER: power = 60; break; case GF_UN_BONUS: power = 20; break; case GF_UN_POWER: power = 15; break; case GF_LOSE_MANA: power = 45; break; case GF_EAT_GOLD: power = 5; break; case GF_EAT_ITEM: power = 5; break; case GF_EAT_FOOD: power = 45; break; case GF_EAT_LITE: power = 45; break; case GF_HUNGER: power = 45; break; case GF_POIS: power = 25; break; case GF_ACID: power = 50; break; case GF_ELEC: power = 50; break; case GF_FIRE: power = 50; break; case GF_COLD: power = 50; break; case GF_BLIND: power = 5; break; case GF_CONFUSION: power = 10; break; case GF_TERRIFY: power = 10; break; case GF_PARALYZE: power = 5; break; case GF_HALLU: power = 10; break; case GF_DISEASE: power = 10; break; case GF_LOSE_STR: power = 0; break; case GF_LOSE_DEX: power = 0; break; case GF_LOSE_CON: power = 0; break; case GF_LOSE_INT: power = 0; break; case GF_LOSE_WIS: power = 0; break; case GF_LOSE_CHR: power = 0; break; case GF_LOSE_ALL: power = 2; break; case GF_EXP_10: power = 5; break; case GF_EXP_20: power = 5; break; case GF_EXP_40: power = 5; break; case GF_EXP_80: power = 5; break; /* Need to add extra flavours in here */ } /* Roll out the damage */ damage = damroll(d_dice, d_side); /* Describe the attack method */ switch (method) { case RBM_HIT: { /* Handle special effect types */ if (effect == GF_WOUND) { if (damage >= 30) act = "gouges you"; else if (damage >= 20) act = "slashes you"; else if (damage >= 5) act = "cuts you"; else act = "scratches you"; /* Usually don't stun */ if (!rand_int(5)) do_stun = 1; do_cut = touched = 1; } else if (effect == GF_BATTER) { if (damage >= 30) act = "bludgeons you"; else if (damage >= 20) act = "batters you"; else if (damage >= 5) act = "bashes you"; else act = "hits you"; /* Usually don't cut */ if (!rand_int(5)) do_cut = 1; do_stun = touched = 1; } else { act = "hits you"; do_cut = do_stun = touched = 1; } break; } case RBM_TOUCH: { act = "touches you"; touched = 1; break; } case RBM_PUNCH: { act = "punches you"; do_stun = touched = 1; break; } case RBM_KICK: { act = "kicks you"; do_stun = touched = 1; break; } case RBM_CLAW: { if (damage >= 25) act = "slashes you"; else if (damage >= 5) act = "claws you"; else act = "scratches you"; do_cut = touched = 1; break; } case RBM_BITE: { if (damage >= 5) act = "bites you"; else act = "nips you"; do_cut = touched = 1; break; } case RBM_PECK: { act = "pecks you"; do_stun = touched = 1; break; } case RBM_STING: { act = "stings you"; touched = 1; break; } case RBM_VOMIT: { act = "vomits on you"; touched = 1; break; } case RBM_BUTT: { if (damage >= rand_range(10, 20)) act = "tramples you"; else act = "butts you"; do_stun = touched = 1; break; } case RBM_CRUSH: { if (damage >= 10) act = "crushes you"; else act = "squeezes you"; do_stun = touched = 1; break; } case RBM_ENGULF: { if (damage >= randint(50)) act = "envelops you"; else act = "engulfs you"; touched = 1; break; } case RBM_CRAWL: { act = "crawls on you"; touched = 1; break; } case RBM_DROOL: { act = "drools on you"; break; } case RBM_SLIME: { act = "slimes you!"; break; } case RBM_SPIT: { act = "spits on you"; break; } case RBM_GAZE: { if (damage >= rand_range(20, 30)) act = "glares at you terribly"; else if (damage >= rand_range(5, 30)) act = "gazes upon you"; else act = "gazes at you"; break; } case RBM_WAIL: { act = "wails horribly"; break; } case RBM_SPORE: { act = "releases a cloud of spores"; break; } case RBM_LASH: { act = "lashes you with a whip"; touched = 1; break; } case RBM_BEG: { act = "begs you for money"; break; } case RBM_INSULT: { act = desc_insult[rand_int(8)]; break; } case RBM_MOAN: { act = desc_moan[rand_int(4)]; break; } } /* Monster hits player */ if (!effect || check_hit(power, rlev, m_idx)) { /* 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 */ if (m_ptr->ml) { l_ptr->flags3 |= (RF3_EVIL); } /* Message */ msg_format("%^s is repelled.", m_name); /* Hack -- Next attack */ continue; } /* Message */ if (act) { if (damage > p_ptr->chp / 3) msg_format("%^s %s!", m_name, act); else msg_format("%^s %s.", m_name, act); } /* Check for usage */ if (rand_int(100)<damage) { int slot; /* Pick a (possibly empty) inventory slot */ switch (randint(6)) { case 1: slot = INVEN_BODY; break; case 2: slot = INVEN_ARM; break; case 3: slot = INVEN_OUTER; break; case 4: slot = INVEN_HANDS; break; case 5: slot = INVEN_HEAD; break; case 6: slot = INVEN_FEET; break; } /* Object used? */ object_usage(INVEN_WIELD); } if (effect) { /* New result routine */ obvious = project_p(m_idx,0,p_ptr->py,p_ptr->px,damage,effect); } else { obvious = TRUE; } /* 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; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage, effect); /* 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; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage, effect); /* Roll for damage */ switch (tmp) { case 0: k = 0; break; case 1: k = randint(5); break; case 2: k = randint(8) + 8; break; case 3: k = randint(15) + 15; break; case 4: k = randint(25) + 25; break; case 5: k = randint(35) + 35; break; case 6: k = randint(45) + 45; break; default: k = 100; break; } /* Apply the stun */ if (k) (void)set_stun(p_ptr->stun + k); } } /* Monster missed player */ else if (touched) { /* Visible monsters */ if (m_ptr->ml) { /* Disturbing */ disturb(1, 0); /* Message */ msg_format("%^s misses you.", m_name); } } /* Analyze "visible" monsters only */ if (visible) { /* Count "obvious" attacks (and ones that cause damage) */ if (obvious || damage || (l_ptr->blows[ap_cnt] > 10)) { /* Count attacks of this type */ if (l_ptr->blows[ap_cnt] < MAX_UCHAR) { l_ptr->blows[ap_cnt]++; } } } } /* Blink away */ if (blinked) { msg_print("There is a puff of smoke!"); teleport_away(m_idx, MAX_SIGHT * 2 + 5); } /* Always notice cause of death */ if (p_ptr->is_dead && (l_ptr->deaths < MAX_SHORT)) { l_ptr->deaths++; } /* Assume we attacked */ return (TRUE); }