/** * Helper function used with ranged_helper by do_cmd_fire. */ public static attack_result make_ranged_shot(Object.Object o_ptr, int y, int x) { attack_result result = new attack_result(false, 0, 0, "hit"); Object.Object j_ptr = Misc.p_ptr.inventory[Misc.INVEN_BOW]; Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]); Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx]; int bonus = Misc.p_ptr.state.to_h + o_ptr.to_h + j_ptr.to_h; int chance = Misc.p_ptr.state.skills[(int)Skill.TO_HIT_BOW] + bonus * Misc.BTH_PLUS_ADJ; int chance2 = chance - Cave.distance(Misc.p_ptr.py, Misc.p_ptr.px, y, x); int multiplier = Misc.p_ptr.state.ammo_mult; Slay best_s_ptr = null; /* Did we hit it (penalize distance travelled) */ if (!test_hit(chance2, r_ptr.ac, m_ptr.ml)) { return(result); } result.success = true; Slay.improve_attack_modifier(o_ptr, m_ptr, ref best_s_ptr, true, false); Slay.improve_attack_modifier(j_ptr, m_ptr, ref best_s_ptr, true, false); /* If we have a slay, modify the multiplier appropriately */ if (best_s_ptr != null) { result.hit_verb = best_s_ptr.range_verb; multiplier += best_s_ptr.mult; } /* Apply damage: multiplier, slays, criticals, bonuses */ result.dmg = Random.damroll(o_ptr.dd, o_ptr.ds); result.dmg += o_ptr.to_d + j_ptr.to_d; result.dmg *= multiplier; result.dmg = critical_shot(o_ptr.weight, o_ptr.to_h, result.dmg, ref result.msg_type); Misc.p_ptr.inventory[Misc.INVEN_BOW].notice_attack_plusses(); return(result); }
/** * Attack the monster at the given location with a single blow. */ static bool py_attack_real(int y, int x, ref bool fear) { /* Information about the target of the attack */ Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]); Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx]; //char m_name[80]; string m_name; bool stop = false; /* The weapon used */ Object.Object o_ptr = Misc.p_ptr.inventory[Misc.INVEN_WIELD]; /* Information about the attack */ int bonus = Misc.p_ptr.state.to_h + o_ptr.to_h; int chance = Misc.p_ptr.state.skills[(int)Skill.TO_HIT_MELEE] + bonus * Misc.BTH_PLUS_ADJ; bool do_quake = false; bool success = false; /* Default to punching for one damage */ string hit_verb = "punch"; int dmg = 1; Message_Type msg_type = Message_Type.MSG_HIT; /* Extract monster name (or "it") */ m_name = m_ptr.monster_desc(0); /* Auto-Recall if possible and visible */ if (m_ptr.ml) { Cave.monster_race_track(m_ptr.r_idx); } /* Track a new monster */ if (m_ptr.ml) { Cave.health_track(Misc.p_ptr, Cave.cave.m_idx[y][x]); } /* Handle player fear (only for invisible monsters) */ if (Misc.p_ptr.check_state(Object_Flag.AFRAID, Misc.p_ptr.state.flags)) { Utilities.msgt(Message_Type.MSG_AFRAID, "You are too afraid to attack {0}!", m_name); return(false); } /* Disturb the monster */ Monster.Monster.mon_clear_timed(Cave.cave.m_idx[y][x], (int)Misc.MON_TMD.SLEEP, Misc.MON_TMD_FLG_NOMESSAGE, false); /* See if the player hit */ success = test_hit(chance, (int)r_ptr.ac, m_ptr.ml); /* If a miss, skip this hit */ if (!success) { Utilities.msgt(Message_Type.MSG_MISS, "You miss {0}.", m_name); return(false); } /* Handle normal weapon */ if (o_ptr.kind != null) { int i; Slay best_s_ptr = null; hit_verb = "hit"; /* Get the best attack from all slays or * brands on all non-launcher equipment */ for (i = Misc.INVEN_LEFT; i < Misc.INVEN_TOTAL; i++) { Object.Object obj = Misc.p_ptr.inventory[i]; if (obj.kind != null) { Slay.improve_attack_modifier(obj, m_ptr, ref best_s_ptr, true, false); } } Slay.improve_attack_modifier(o_ptr, m_ptr, ref best_s_ptr, true, false); if (best_s_ptr != null) { hit_verb = best_s_ptr.melee_verb; } dmg = Random.damroll(o_ptr.dd, o_ptr.ds); dmg *= (best_s_ptr == null) ? 1 : best_s_ptr.mult; dmg += o_ptr.to_d; dmg = critical_norm(o_ptr.weight, o_ptr.to_h, dmg, ref msg_type); /* Learn by use for the weapon */ o_ptr.notice_attack_plusses(); if (Misc.p_ptr.check_state(Object_Flag.IMPACT, Misc.p_ptr.state.flags) && dmg > 50) { do_quake = true; Object.Object.wieldeds_notice_flag(Misc.p_ptr, Object_Flag.IMPACT.value); } } /* Learn by use for other equipped items */ Object.Object.wieldeds_notice_on_attack(); /* Apply the player damage bonuses */ dmg += Misc.p_ptr.state.to_d; /* No negative damage */ if (dmg <= 0) { dmg = 0; } /* Tell the player what happened */ if (dmg <= 0) { Utilities.msgt(Message_Type.MSG_MISS, "You fail to harm {0}.", m_name); } else if (msg_type == Message_Type.MSG_HIT) { Utilities.msgt(Message_Type.MSG_HIT, "You {0} {1}.", hit_verb, m_name); } else if (msg_type == Message_Type.MSG_HIT_GOOD) { Utilities.msgt(Message_Type.MSG_HIT_GOOD, "You {0} {1}. {2}", hit_verb, m_name, "It was a good hit!"); } else if (msg_type == Message_Type.MSG_HIT_GREAT) { Utilities.msgt(Message_Type.MSG_HIT_GREAT, "You {0} {1}. {2}", hit_verb, m_name, "It was a great hit!"); } else if (msg_type == Message_Type.MSG_HIT_SUPERB) { Utilities.msgt(Message_Type.MSG_HIT_SUPERB, "You {0} {1}. {2}", hit_verb, m_name, "It was a superb hit!"); } else if (msg_type == Message_Type.MSG_HIT_HI_GREAT) { Utilities.msgt(Message_Type.MSG_HIT_HI_GREAT, "You {0} {1}. {2}", hit_verb, m_name, "It was a *GREAT* hit!"); } else if (msg_type == Message_Type.MSG_HIT_HI_SUPERB) { Utilities.msgt(Message_Type.MSG_HIT_HI_SUPERB, "You {0} {1}. {2}", hit_verb, m_name, "It was a *SUPERB* hit!"); } /* Complex message */ if (Misc.p_ptr.wizard) { Utilities.msg("You do {0} (out of {1}) damage.", dmg, m_ptr.hp); } /* Confusion attack */ if (Misc.p_ptr.confusing != 0) { Misc.p_ptr.confusing = 0; //false; Utilities.msg("Your hands stop glowing."); Monster.Monster.mon_inc_timed(Cave.cave.m_idx[y][x], Misc.MON_TMD.CONF, (10 + Random.randint0(Misc.p_ptr.lev) / 10), Misc.MON_TMD_FLG_NOTIFY, false); } /* Damage, check for fear and death */ stop = Monster.Monster_Make.mon_take_hit(Cave.cave.m_idx[y][x], dmg, ref fear, null); if (stop) { fear = false; } /* Apply earthquake brand */ if (do_quake) { throw new NotImplementedException(); //earthquake(Misc.p_ptr.py, Misc.p_ptr.px, 10); //if (Cave.cave.m_idx[y][x] == 0) stop = true; } return(stop); }