public attack_result(bool success, int dmg, Message_Type message_type, string verb) { this.success = success; this.dmg = dmg; this.msg_type = message_type; this.hit_verb = verb; }
/** * Determine damage for critical hits from shooting. * * Factor in item weight, total plusses, and player level. */ static int critical_shot(int weight, int plus, int dam, ref Message_Type msg_type) { int chance = weight + (Misc.p_ptr.state.to_h + plus) * 4 + Misc.p_ptr.lev * 2; int power = weight + Random.randint1(500); if (Random.randint1(5000) > chance) { msg_type = Message_Type.MSG_SHOOT_HIT; return(dam); } else if (power < 500) { msg_type = Message_Type.MSG_HIT_GOOD; return(2 * dam + 5); } else if (power < 1000) { msg_type = Message_Type.MSG_HIT_GREAT; return(2 * dam + 10); } else { msg_type = Message_Type.MSG_HIT_SUPERB; return(3 * dam + 15); } }
public Message(string to_id, string msg, string time) { this.to_id = to_id; this.msg = msg; this.time = time; this.mt = Message_Type.Send; }
public timed_effect(string a, string b, string c, string d, uint e, uint f, Message_Type g, Object_Flag h) { on_begin = a; on_end = b; on_increase = c; on_decrease = d; flag_redraw = e; flag_update = f; msg = g; resist = h; }
public void On_Message_Type_Change(int value) { message_type = (Message_Type)value; title_message.transform.parent.gameObject.SetActive(value > 1); Utils.InvokeNextFrame(() => { gameObject.SetActive(false); Utils.InvokeNextFrame(() => { gameObject.SetActive(true); }); }); }
public void SendGameMessage <T>(Message_Type type, Weapon_Type weapon) { switch (type) { case Message_Type.EnemyGetHit: if (_enemy) { _enemy.SendMessage("GetHit", weapon); } break; } }
public RBM(string name, string text, int value, bool docut, bool dostun, Message_Type sound_msg, string action) { this.name = name; this.text = text; this.value = value; this.do_cut = docut; this.do_stun = dostun; this.action = action; this.sound_msg = sound_msg; list.Add(this); }
public void SendGameMessageToPlayer <T>(Message_Type type, int damage) { switch (type) { case Message_Type.PlayerGetHit: if (_player) { _player.SendMessage("GetHit", damage); } break; } }
/** Message type changes **/ /** * Returns the colour for the message type `type`. */ public static ConsoleColor type_color(Message_Type type) { Message_Color mc; ConsoleColor color = ConsoleColor.White; if (messages != null) { mc = messages.colors; while (mc != null && mc.type != type) { mc = mc.next; } if (mc != null && (mc.color != ConsoleColor.Black)) { color = mc.color; } } return(color); }
/** * Save a new message into the memory buffer, with text `str` and type `type`. * The type should be one of the MSG_ constants defined above. * * The new message may not be saved if it is identical to the one saved before * it, in which case the "count" of the message will be increased instead. * This count can be fetched using the message_count() function. */ public static void add(string str, Message_Type type) { if (messages.head != null && messages.head.typ == type && messages.head.text == str) { messages.head.cnt++; return; } Message m = new Message(); m.text = str; m.typ = type; m.cnt = 1; m.older = messages.head; if (messages.head != null) { messages.head.newer = m; } messages.head = m; messages.count++; if (messages.tail == null) { messages.tail = m; } if (messages.count > messages.max) { Message old_tail = messages.tail; messages.tail = old_tail.newer; messages.tail.older = null; //FREE(old_tail.str); //FREE(old_tail); messages.count--; } }
/// <summary> /// 收到玩家信息进行处理 /// </summary> /// <param name="message"></param> private void _UserMessageHandle(string message) { JsonData jsonData = JsonTools.GetJsonData(message); //取得消息的头部, Message_Type type = (Message_Type)(int)jsonData["type"]; Debug.LogError("消息类型" + type); switch (type) { case Message_Type.TryLogin: string UserId = jsonData["userId"].ToString(); LoginInfo tempLoginInfo = PlayerModule.Instance.GetTryLogininfo(UserId); MsgTryLoginRes resMsg = new MsgTryLoginRes(); if (tempLoginInfo == null) { resMsg.SetMessage(-1, 0, 0); } else { resMsg.SetMessage(-1, 0, 0); } if (TryLoginIn != null) { TryLoginIn(jsonData); } break; case Message_Type.Login: if (LoginIn != null) { LoginIn(jsonData); } break; default: break; } }
/** * Defines the color `color` for the message type `type`. */ public static void color_define(Message_Type type, ConsoleColor color) { Message_Color mc; if (messages.colors != null) { messages.colors = new Message_Color(); messages.colors.type = type; messages.colors.color = color; } mc = messages.colors; Message_Color last = null; while (mc != null) { if (mc.type == type) { mc.color = color; } last = mc; mc = mc.next; } if (last != null) { last.next = new Message_Color(); last.next.type = type; last.next.color = color; } else { messages.colors = new Message_Color(); messages.colors.type = type; messages.colors.color = color; } }
/** * Determine damage for critical hits from melee. * * Factor in weapon weight, total plusses, player level. */ static int critical_norm(int weight, int plus, int dam, ref Message_Type msg_type) { int chance = weight + (Misc.p_ptr.state.to_h + plus) * 5 + Misc.p_ptr.lev * 3; int power = weight + Random.randint1(650); if (Random.randint1(5000) > chance) { msg_type = Message_Type.MSG_HIT; return(dam); } else if (power < 400) { msg_type = Message_Type.MSG_HIT_GOOD; return(2 * dam + 5); } else if (power < 700) { msg_type = Message_Type.MSG_HIT_GREAT; return(2 * dam + 10); } else if (power < 900) { msg_type = Message_Type.MSG_HIT_SUPERB; return(3 * dam + 15); } else if (power < 1300) { msg_type = Message_Type.MSG_HIT_HI_GREAT; return(3 * dam + 20); } else { msg_type = Message_Type.MSG_HIT_HI_SUPERB; return(4 * dam + 20); } }
public MessageModel(string p_caption, string p_message, Message_Type p_type = Message_Type.Information) { caption = p_caption; type = p_type; message = p_message; }
/** * 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); }
/** * This is a helper function used by do_cmd_throw and do_cmd_fire. * * It abstracts out the projectile path, display code, identify and clean up * logic, while using the 'attack' parameter to do work particular to each * kind of attack. */ public static void ranged_helper(int item, int dir, int range, int shots, ranged_attack attack) { /* Get the ammo */ Object.Object o_ptr = Object.Object.object_from_item_idx(item); int i, j; ConsoleColor missile_attr = o_ptr.object_attr(); char missile_char = o_ptr.object_char(); //object_type object_type_body; Object.Object i_ptr = new Object.Object(); //&object_type_body; //char o_name[80]; string o_name; int path_n; List <ushort> path_g = new List <ushort>(); //[256]; int msec = Player.Player_Other.instance.delay_factor; /* Start at the player */ int x = Misc.p_ptr.px; int y = Misc.p_ptr.py; /* Predict the "target" location */ short ty = (short)(y + 99 * Misc.ddy[dir]); short tx = (short)(x + 99 * Misc.ddx[dir]); bool hit_target = false; /* Check for target validity */ if ((dir == 5) && Target.okay()) { int taim; //char msg[80]; string msg; Target.get(out tx, out ty); taim = Cave.distance(y, x, ty, tx); if (taim > range) { msg = String.Format("Target out of range by {0} squares. Fire anyway? ", taim - range); if (!Utilities.get_check(msg)) { return; } } } /* Sound */ //sound(MSG_SHOOT); //later o_ptr.notice_on_firing(); /* Describe the object */ o_name = o_ptr.object_desc(Object.Object.Detail.FULL | Object.Object.Detail.SINGULAR); /* Actually "fire" the object -- Take a partial turn */ Misc.p_ptr.energy_use = (short)(100 / shots); /* Calculate the path */ path_n = Cave.project_path(out path_g, range, y, x, ty, tx, 0); /* Hack -- Handle stuff */ Misc.p_ptr.handle_stuff(); /* Start at the player */ x = Misc.p_ptr.px; y = Misc.p_ptr.py; /* Project along the path */ for (i = 0; i < path_n; ++i) { int ny = Cave.GRID_Y(path_g[i]); int nx = Cave.GRID_X(path_g[i]); /* Hack -- Stop before hitting walls */ if (!Cave.cave_floor_bold(ny, nx)) { break; } /* Advance */ x = nx; y = ny; /* Only do visuals if the player can "see" the missile */ if (Cave.player_can_see_bold(y, x)) { Cave.print_rel(missile_char, missile_attr, y, x); Cave.move_cursor_relative(y, x); Term.fresh(); if (Misc.p_ptr.redraw != 0) { Misc.p_ptr.redraw_stuff(); } Term.xtra(TERM_XTRA.DELAY, msec); Cave.cave_light_spot(Cave.cave, y, x); Term.fresh(); if (Misc.p_ptr.redraw != 0) { Misc.p_ptr.redraw_stuff(); } } else { /* Delay anyway for consistency */ Term.xtra(TERM_XTRA.DELAY, msec); } /* Handle monster */ if (Cave.cave.m_idx[y][x] > 0) { break; } } /* Try the attack on the monster at (x, y) if any */ if (Cave.cave.m_idx[y][x] > 0) { 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]; bool visible = m_ptr.ml; bool fear = false; //char m_name[80]; string m_name; string note_dies = r_ptr.monster_is_unusual() ? " is destroyed." : " dies."; attack_result result = attack(o_ptr, y, x); int dmg = result.dmg; Message_Type msg_type = result.msg_type; string hit_verb = result.hit_verb; if (result.success) { hit_target = true; /* Get "the monster" or "it" */ m_name = m_ptr.monster_desc(0); o_ptr.notice_attack_plusses(); /* No negative damage; change verb if no damage done */ if (dmg <= 0) { dmg = 0; hit_verb = "fail to harm"; } if (!visible) { /* Invisible monster */ Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} finds a mark.", o_name); } else { /* Visible monster */ if ((Message_Type)msg_type == Message_Type.MSG_SHOOT_HIT) { Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} {1} {2}.", o_name, hit_verb, m_name); } else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GOOD) { Utilities.msgt(Message_Type.MSG_HIT_GOOD, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name, "It was a good hit!"); } else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GREAT) { Utilities.msgt(Message_Type.MSG_HIT_GREAT, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name, "It was a great hit!"); } else if ((Message_Type)msg_type == Message_Type.MSG_HIT_SUPERB) { Utilities.msgt(Message_Type.MSG_HIT_SUPERB, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name, "It was a superb hit!"); } /* Track this monster */ if (m_ptr.ml) { Cave.monster_race_track(m_ptr.r_idx); } if (m_ptr.ml) { Cave.health_track(Misc.p_ptr, Cave.cave.m_idx[y][x]); } } /* Complex message */ if (Misc.p_ptr.wizard) { Utilities.msg("You do {0} (out of {1}) damage.", dmg, m_ptr.hp); } /* Hit the monster, check for death */ if (!Monster_Make.mon_take_hit(Cave.cave.m_idx[y][x], dmg, ref fear, note_dies)) { Monster_Message.message_pain(Cave.cave.m_idx[y][x], dmg); if (fear && m_ptr.ml) { Monster_Message.add_monster_message(m_name, Cave.cave.m_idx[y][x], MON_MSG.FLEE_IN_TERROR, true); } } } } /* Obtain a local object */ i_ptr = o_ptr.copy(); i_ptr.split(o_ptr, 1); /* See if the ammunition broke or not */ j = i_ptr.breakage_chance(hit_target); /* Drop (or break) near that location */ Object.Object.drop_near(Cave.cave, i_ptr, j, y, x, true); if (item >= 0) { /* The ammo is from the inventory */ Object.Object.inven_item_increase(item, -1); Object.Object.inven_item_describe(item); Object.Object.inven_item_optimize(item); } else { /* The ammo is from the floor */ Object.Object.floor_item_increase(0 - item, -1); Object.Object.floor_item_optimize(0 - item); } }
/** * Determine damage for critical hits from shooting. * * Factor in item weight, total plusses, and player level. */ static int critical_shot(int weight, int plus, int dam, ref Message_Type msg_type) { int chance = weight + (Misc.p_ptr.state.to_h + plus) * 4 + Misc.p_ptr.lev * 2; int power = weight + Random.randint1(500); if (Random.randint1(5000) > chance) { msg_type = Message_Type.MSG_SHOOT_HIT; return dam; } else if (power < 500) { msg_type = Message_Type.MSG_HIT_GOOD; return 2 * dam + 5; } else if (power < 1000) { msg_type = Message_Type.MSG_HIT_GREAT; return 2 * dam + 10; } else { msg_type = Message_Type.MSG_HIT_SUPERB; return 3 * dam + 15; } }
static bool _vShowMessage(Message_Type flag, string message = "") { if (message == "") { Error("Empty string passed to _vShowMessage()"); return(false); } if ((flag == Message_Type.MSG_INFORMATION && msg_silent == 1) || (flag == Message_Type.MSG_STATUS && msg_silent == 2) || (flag == Message_Type.MSG_NOTICE && msg_silent == 4) || (flag == Message_Type.MSG_WARNING && msg_silent == 8) || (flag == Message_Type.MSG_ERROR && msg_silent == 16) || (flag == Message_Type.MSG_SQL && msg_silent == 16) || (flag == Message_Type.MSG_DEBUG && msg_silent == 32)) { return(false); // Do Not WriteLine it. } string prefix = ""; Color color = Color.CL_GREY; switch (flag) { case Message_Type.MSG_NONE: // direct WriteLine replacement. break; case Message_Type.MSG_STATUS: // Bright Green (To inform about good things) prefix = DateTime.Now.ToString("[yyyy/MM/dd HH:mm:ss] "); color = Color.CL_GREEN; break; case Message_Type.MSG_SQL: // Bright Violet (For dumping out anything related with SQL) prefix = "[SQL]"; color = Color.CL_MAGENTA; break; case Message_Type.MSG_INFORMATION: // Bright White (Variable information) prefix = "[Info]"; color = Color.CL_WHITE; break; case Message_Type.MSG_NOTICE: // Bright White (Less than a warning) prefix = "[Notice]"; color = Color.CL_WHITE; break; case Message_Type.MSG_WARNING: // Bright Yellow prefix = "[Warning]"; color = Color.CL_YELLOW; break; case Message_Type.MSG_DEBUG: // Bright Cyan, important stuff! prefix = "[Debug] => "; color = Color.CL_CYAN; break; case Message_Type.MSG_ERROR: // Bright Red (Regular errors) prefix = "[Error]"; color = Color.CL_RED; break; case Message_Type.MSG_FATALERROR: // Bright Red (Fatal errors, abort(); If possible) prefix = ""; color = Color.CL_RED; break; default: Error(String.Format("In function _vShowMessage() -> Invalid flag ({0}) passed.", flag)); return(false); } Console.ForegroundColor = (ConsoleColor)Color.CL_GREY; char[] letters = prefix.ToCharArray(); foreach (char c in letters) { Console.ForegroundColor = (ConsoleColor)color; Console.Write(c); } Console.ForegroundColor = (ConsoleColor)Color.CL_GREY; if (prefix != "") { Console.Write(" "); } letters = message.ToCharArray(); foreach (char c in letters) { Console.Write(c); } Console.WriteLine(); return(true); }
/* * Identify an item. * * `item` is used to print the slot occupied by an object in equip/inven. * Any negative value assigned to "item" can be used for specifying an object * on the floor. */ public static void do_ident_item(int item, Object.Object o_ptr) { string o_name = ""; //80 Message_Type msg_type = (Message_Type)0; int i; bool bad = true; /* Identify it */ o_ptr.flavor_aware(); o_ptr.notice_everything(); /* Apply an autoinscription, if necessary */ Squelch.apply_autoinscription(o_ptr); /* Set squelch flag */ Misc.p_ptr.notice |= (int)Misc.PN_SQUELCH; /* Recalculate bonuses */ Misc.p_ptr.update |= (Misc.PU_BONUS); /* Combine / Reorder the pack (later) */ Misc.p_ptr.notice |= (int)(Misc.PN_COMBINE | Misc.PN_REORDER | Misc.PN_SORT_QUIVER); /* Window stuff */ Misc.p_ptr.redraw |= (Misc.PR_INVEN | Misc.PR_EQUIP); /* Description */ o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL); /* Determine the message type. */ /* CC: we need to think more carefully about how we define "bad" with * multiple pvals - currently using "all nonzero pvals < 0" */ for (i = 0; i < o_ptr.num_pvals; i++) { if (o_ptr.pval[i] > 0) { bad = false; } } if (bad) { msg_type = Message_Type.MSG_IDENT_BAD; } else if (o_ptr.artifact != null) { msg_type = Message_Type.MSG_IDENT_ART; } else if (o_ptr.ego != null) { msg_type = Message_Type.MSG_IDENT_EGO; } else { msg_type = Message_Type.MSG_GENERIC; } /* Log artifacts to the history list. */ if (o_ptr.artifact != null) { History.add_artifact(o_ptr.artifact, true, true); } /* Describe */ if (item >= Misc.INVEN_WIELD) { Utilities.msgt(msg_type, "{0}: {1} ({2}).", Object.Object.describe_use(item), o_name, Object.Object.index_to_label(item)); //Utilities.msgt(msg_type, "%^s: %s (%c).", describe_use(item), o_name, index_to_label(item)); } else if (item >= 0) { Utilities.msgt(msg_type, "In your pack: {0} ({1}).", o_name, Object.Object.index_to_label(item)); //Utilities.msgt(msg_type, "In your pack: %s (%c).", o_name, index_to_label(item)); } else { Utilities.msgt(msg_type, "On the ground: {0}.", o_name); } }
/* * Attack the player via physical attacks. */ //TODO: Submit this function to the Guiness book of world records for "Longest f*****g function" //TODO: Refactor this. Refactor this so f*****g hard. public bool make_attack_normal(Player.Player p) { Monster_Race r_ptr = Misc.r_info[r_idx]; Monster_Lore l_ptr = Misc.l_list[r_idx]; int i, tmp; short gold; string o_name; // Not allowed to attack if (r_ptr.flags.has(Monster_Flag.NEVER_BLOW.value)) { return(false); } // Total armor int ac = p.state.ac + p.state.to_a; // Extract the effective monster level int rlev = ((r_ptr.level >= 1) ? r_ptr.level : 1); // Get the monster name (or "it") string m_name = monster_desc(0); // Get the "died from" information (i.e. "a kobold") string ddesc = monster_desc(Desc.SHOW | Desc.IND2); // Assume no blink bool blinked = false; // Scan through all blows for (int ap_cnt = 0; ap_cnt < Monster_Blow.MONSTER_BLOW_MAX; ap_cnt++) { bool visible = false; bool obvious = false; bool do_break = false; int power = 0; int damage = 0; string act = null; if (r_ptr.blow[ap_cnt] == null) { continue; } // Extract the attack infomation RBE effect = r_ptr.blow[ap_cnt].effect; RBM 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 == RBM.NONE) { break; } // Handle "leaving" if (p.leaving) { break; } // Extract visibility (before blink) if (ml) { visible = true; } // Extract visibility from carrying light if (r_ptr.flags.has(Monster_Flag.HAS_LIGHT.value)) { visible = true; } power = effect.power; // Monster hits player if (effect == null || check_hit(p, power, rlev)) { // Always disturbing Cave.disturb(p, 1, 0); // Hack -- Apply "protection from evil" if (p.timed[(int)Timed_Effect.PROTEVIL] > 0) { // Learn about the evil flag if (ml) { l_ptr.flags.on(Monster_Flag.EVIL.value); } if (r_ptr.flags.has(Monster_Flag.EVIL.value) && p.lev >= rlev && Random.randint0(100) + p.lev > 50) { // Message Utilities.msg("%^s is repelled.", m_name); // Hack -- Next attack continue; } } // Assume no cut or stun bool do_cut = method.do_cut; bool do_stun = method.do_stun; // Assume no sound Message_Type sound_msg = method.sound_msg; act = method.action; // Describe the attack method if (method == RBM.INSULT) { throw new NotImplementedException(); //act = desc_insult[Random.randint0(Misc.MAX_DESC_INSULT)]; } else if (method == RBM.MOAN) { throw new NotImplementedException(); //act = desc_moan[Random.randint0(Misc.MAX_DESC_MOAN)]; } // Message if (act != null) { string name = Char.ToUpper(m_name[0]) + m_name.Substring(1); Utilities.msgt(sound_msg, "{0} {1}", name, act); } // Hack -- assume all attacks are obvious obvious = true; // Roll out the damage if (d_dice > 0 && d_side > 0) { damage = Random.damroll(d_dice, d_side); } else { damage = 0; } // Apply appropriate damage if (effect.value == 0) { // Hack -- Assume obvious obvious = true; // Hack -- No damage damage = 0; } else if (effect.value == RBE.HURT.value) { // Obvious obvious = true; // Hack -- Player armor reduces total damage damage -= (damage * ((ac < 240) ? ac : 240) / 400); // Take damage Spell.take_hit(p, damage, ddesc); } else if (effect.value == RBE.POISON.value) { damage = Spell.adjust_dam(p, GF.POIS, damage, aspect.RANDOMISE, Spell.check_for_resist(p, GF.POIS, p.state.flags, true)); // Take damage Spell.take_hit(p, damage, ddesc); // Take "poison" effect if (p.inc_timed(Timed_Effect.POISONED, Random.randint1(rlev) + 5, true, true)) { obvious = true; } // Learn about the player monster_learn_resists(p, GF.POIS); } else if (effect.value == RBE.UN_BONUS.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Allow complete resist //if (!check_state(p, OF_RES_DISEN, p.state.flags)) //{ // // Apply disenchantment // if (apply_disenchant(0)) obvious = true; //} //// Learn about the player //monster_learn_resists(m_ptr, p, GF_DISEN); } else if (effect.value == RBE.UN_POWER.value) { throw new NotImplementedException(); //int unpower = 0, newcharge; //// Take damage //take_hit(p, damage, ddesc); //// Find an item //for (k = 0; k < 10; k++) //{ // // Pick an item // i = randint0(INVEN_PACK); // // Obtain the item // o_ptr = &p.inventory[i]; // // Skip non-objects // if (!o_ptr.kind) continue; // // Drain charged wands/staves // if ((o_ptr.tval == TV_STAFF) || // (o_ptr.tval == TV_WAND)) // { // // Charged? // if (o_ptr.pval[DEFAULT_PVAL]) // { // // Get number of charge to drain // unpower = (rlev / (o_ptr.kind.level + 2)) + 1; // // Get new charge value, don't allow negative // newcharge = MAX((o_ptr.pval[DEFAULT_PVAL] // - unpower),0); // // Remove the charges // o_ptr.pval[DEFAULT_PVAL] = newcharge; // } // } // if (unpower) // { // int heal = rlev * unpower; // msg("Energy drains from your pack!"); // obvious = true; // // Don't heal more than max hp // heal = MIN(heal, maxhp - hp); // // Heal // hp += heal; // // Redraw (later) if needed // if (cave_monster(cave, p.health_who) == m_ptr) // p.redraw |= (PR_HEALTH); // // Combine / Reorder the pack // p.notice |= (PN_COMBINE | PN_REORDER); // // Redraw stuff // p.redraw |= (PR_INVEN); // // Affect only a single inventory slot // break; // } //} } else if (effect.value == RBE.EAT_GOLD.value) { // Take damage Spell.take_hit(p, damage, ddesc); // Obvious obvious = true; // Saving throw (unless paralyzed) based on dex and level if (p.timed[(int)Timed_Effect.PARALYZED] == 0 && (Random.randint0(100) < (Player.Player.adj_dex_safe[p.state.stat_ind[(int)Stat.Dex]] + p.lev))) { // Saving throw message Utilities.msg("You quickly protect your money pouch!"); // Occasional blink anyway if (Random.randint0(3) != 0) { blinked = true; } } // Eat gold else { gold = (short)((p.au / 10) + Random.randint1(25)); if (gold < 2) { gold = 2; } if (gold > 5000) { gold = (short)((p.au / 20) + Random.randint1(3000)); } if (gold > p.au) { gold = (short)p.au; } p.au -= gold; if (gold <= 0) { Utilities.msg("Nothing was stolen."); break; } // Let the player know they were robbed Utilities.msg("Your purse feels lighter."); if (p.au != 0) { Utilities.msg("{0} coins were stolen!", (long)gold); } else { Utilities.msg("All of your coins were stolen!"); } // While we have gold, put it in objects while (gold > 0) { int amt; // Create a new temporary object //object_type o; //object_wipe(&o); Object.Object o = new Object.Object(); o.prep(Object.Object_Kind.objkind_get(TVal.TV_GOLD, (int)SVal.sval_gold.SV_GOLD), 0, aspect.MINIMISE); // Amount of gold to put in this object amt = gold > Misc.MAX_PVAL ? Misc.MAX_PVAL : gold; o.pval[Misc.DEFAULT_PVAL] = (short)amt; gold -= (short)amt; // Set origin to stolen, so it is not confused with // dropped treasure in monster_death o.origin = Origin.STOLEN; // Give the gold to the monster carry(o); } // Redraw gold p.redraw |= (Misc.PR_GOLD); // Blink away blinked = true; } } else if (effect.value == RBE.EAT_ITEM.value) { // Take damage Spell.take_hit(p, damage, ddesc); // Saving throw (unless paralyzed) based on dex and level if (p.timed[(int)Timed_Effect.PARALYZED] == 0 && (Random.randint0(100) < (Player.Player.adj_dex_safe[p.state.stat_ind[(int)Stat.Dex]] + p.lev))) { // Saving throw message Utilities.msg("You grab hold of your backpack!"); // Occasional "blink" anyway blinked = true; // Obvious obvious = true; // Done break; } // Find an item for (int k = 0; k < 10; k++) { Object.Object i_ptr; //object_type object_type_body; // Pick an item i = Random.randint0(Misc.INVEN_PACK); // Obtain the item Object.Object o_ptr = p.inventory[i]; // Skip non-objects if (o_ptr.kind == null) { continue; } // Skip artifacts if (o_ptr.artifact != null) { continue; } // Get a description o_name = o_ptr.object_desc(Object.Object.Detail.FULL); // Message Utilities.msg("{0}our {1} ({2}) was stolen!", ((o_ptr.number > 1) ? "One of y" : "Y"), o_name, Object.Object.index_to_label(i)); // Get local object i_ptr = new Object.Object(); //&object_type_body; // Obtain local object i_ptr = o_ptr.copy(); // Modify number i_ptr.number = 1; // Hack -- If a rod, staff, or wand, allocate total // maximum timeouts or charges between those // stolen and those missed. -LM- o_ptr.distribute_charges(i_ptr, 1); // Carry the object carry(i_ptr); // Steal the items Object.Object.inven_item_increase(i, -1); Object.Object.inven_item_optimize(i); // Obvious obvious = true; // Blink away blinked = true; // Done break; } } else if (effect.value == RBE.EAT_FOOD.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Steal some food //for (k = 0; k < 10; k++) //{ // // Pick an item from the pack // i = randint0(INVEN_PACK); // // Get the item // o_ptr = &p.inventory[i]; // // Skip non-objects // if (!o_ptr.kind) continue; // // Skip non-food objects // if (o_ptr.tval != TV_FOOD) continue; // // Get a description // object_desc(o_name, sizeof(o_name), o_ptr, // ODESC_PREFIX | ODESC_BASE); // // Message // msg("%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; //} } else if (effect.value == RBE.EAT_LIGHT.value) { throw new NotImplementedException(); //bitflag f[OF_SIZE]; //// Take damage //take_hit(p, damage, ddesc); //// Get the light, and its flags //o_ptr = &p.inventory[INVEN_LIGHT]; //object_flags(o_ptr, f); //// Drain fuel where applicable //if (!of_has(f, OF_NO_FUEL) && (o_ptr.timeout > 0)) //{ // // Reduce fuel // o_ptr.timeout -= (250 + randint1(250)); // if (o_ptr.timeout < 1) o_ptr.timeout = 1; // // Notice // if (!p.timed[TMD_BLIND]) // { // msg("Your light dims."); // obvious = true; // } // // Redraw stuff // p.redraw |= (PR_EQUIP); //} } else if (effect.value == RBE.ACID.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Message //msg("You are covered in acid!"); //// Special damage //damage = adjust_dam(p, GF_ACID, damage, RANDOMISE, // check_for_resist(p, GF_ACID, p.state.flags, true)); //if (damage) { // take_hit(p, damage, ddesc); // inven_damage(p, GF_ACID, MIN(damage * 5, 300)); //} //// Learn about the player //monster_learn_resists(m_ptr, p, GF_ACID); } else if (effect.value == RBE.ELEC.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Message //msg("You are struck by electricity!"); //// Take damage (special) //damage = adjust_dam(p, GF_ELEC, damage, RANDOMISE, // check_for_resist(p, GF_ELEC, p.state.flags, true)); //if (damage) { // take_hit(p, damage, ddesc); // inven_damage(p, GF_ELEC, MIN(damage * 5, 300)); //} //// Learn about the player //monster_learn_resists(m_ptr, p, GF_ELEC); } else if (effect.value == RBE.FIRE.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Message //msg("You are enveloped in flames!"); //// Take damage (special) //damage = adjust_dam(p, GF_FIRE, damage, RANDOMISE, // check_for_resist(p, GF_FIRE, p.state.flags, true)); //if (damage) { // take_hit(p, damage, ddesc); // inven_damage(p, GF_FIRE, MIN(damage * 5, 300)); //} //// Learn about the player //monster_learn_resists(m_ptr, p, GF_FIRE); } else if (effect.value == RBE.COLD.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Message //msg("You are covered with frost!"); //// Take damage (special) //damage = adjust_dam(p, GF_COLD, damage, RANDOMISE, // check_for_resist(p, GF_COLD, p.state.flags, true)); //if (damage) { // take_hit(p, damage, ddesc); // inven_damage(p, GF_COLD, MIN(damage * 5, 300)); //} //// Learn about the player //monster_learn_resists(m_ptr, p, GF_COLD); } else if (effect.value == RBE.BLIND.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Increase "blind" //if (player_inc_timed(p, TMD_BLIND, 10 + randint1(rlev), true, true)) // obvious = true; //// Learn about the player //update_smart_learn(m_ptr, p, OF_RES_BLIND); } else if (effect.value == RBE.CONFUSE.value) { // Take damage Spell.take_hit(p, damage, ddesc); // Increase "confused" if (p.inc_timed(Timed_Effect.CONFUSED, 3 + Random.randint1(rlev), true, true)) { obvious = true; } // Learn about the player update_smart_learn(p, Object.Object_Flag.RES_CONFU); } else if (effect.value == RBE.TERRIFY.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Increase "afraid" //if (randint0(100) < p.state.skills[SKILL_SAVE]) //{ // msg("You stand your ground!"); // obvious = true; //} //else //{ // if (player_inc_timed(p, TMD_AFRAID, 3 + randint1(rlev), true, // true)) // obvious = true; //} //// Learn about the player //update_smart_learn(m_ptr, p, OF_RES_FEAR); } else if (effect.value == RBE.PARALYZE.value) { // Hack -- Prevent perma-paralysis via damage if (p.timed[(int)Timed_Effect.PARALYZED] != 0 && (damage < 1)) { damage = 1; } // Take damage Spell.take_hit(p, damage, ddesc); // Increase "paralyzed" if (Random.randint0(100) < p.state.skills[(int)Skill.SAVE]) { Utilities.msg("You resist the effects!"); obvious = true; } else { if (p.inc_timed(Timed_Effect.PARALYZED, 3 + Random.randint1(rlev), true, true)) { obvious = true; } } // Learn about the player update_smart_learn(p, Object_Flag.FREE_ACT); } else if (effect.value == RBE.LOSE_STR.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Damage (stat) //if (do_dec_stat(A_STR, false)) obvious = true; } else if (effect.value == RBE.LOSE_INT.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Damage (stat) //if (do_dec_stat(A_INT, false)) obvious = true; } else if (effect.value == RBE.LOSE_WIS.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Damage (stat) //if (do_dec_stat(A_WIS, false)) obvious = true; } else if (effect.value == RBE.LOSE_DEX.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Damage (stat) //if (do_dec_stat(A_DEX, false)) obvious = true; } else if (effect.value == RBE.LOSE_CON.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Damage (stat) //if (do_dec_stat(A_CON, false)) obvious = true; } else if (effect.value == RBE.LOSE_CHR.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Damage (stat) //if (do_dec_stat(A_CHR, false)) obvious = true; } else if (effect.value == RBE.LOSE_ALL.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Damage (stats) //if (do_dec_stat(A_STR, false)) obvious = true; //if (do_dec_stat(A_DEX, false)) obvious = true; //if (do_dec_stat(A_CON, false)) obvious = true; //if (do_dec_stat(A_INT, false)) obvious = true; //if (do_dec_stat(A_WIS, false)) obvious = true; //if (do_dec_stat(A_CHR, false)) obvious = true; } else if (effect.value == RBE.SHATTER.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Hack -- Reduce damage based on the player armor class //damage -= (damage * ((ac < 240) ? ac : 240) / 400); //// Take damage //take_hit(p, damage, ddesc); //// Radius 8 earthquake centered at the monster //if (damage > 23) //{ // int px_old = p.px; // int py_old = p.py; // earthquake(fy, fx, 8); // // Stop the blows if the player is pushed away // if ((px_old != p.px) || // (py_old != p.py)) // do_break = true; //} } else if (effect.value == RBE.EXP_10.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Take damage //take_hit(p, damage, ddesc); //update_smart_learn(m_ptr, p_ptr, OF_HOLD_LIFE); //if (check_state(p, OF_HOLD_LIFE, p.state.flags) && (randint0(100) < 95)) //{ // msg("You keep hold of your life force!"); //} //else //{ // s32b d = damroll(10, 6) + (p.exp/100) * MON_DRAIN_LIFE; // if (check_state(p, OF_HOLD_LIFE, p.state.flags)) // { // msg("You feel your life slipping away!"); // player_exp_lose(p, d / 10, false); // } // else // { // msg("You feel your life draining away!"); // player_exp_lose(p, d, false); // } //} } else if (effect.value == RBE.EXP_20.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Take damage //take_hit(p, damage, ddesc); //update_smart_learn(m_ptr, p_ptr, OF_HOLD_LIFE); //if (check_state(p, OF_HOLD_LIFE, p.state.flags) && (randint0(100) < 90)) //{ // msg("You keep hold of your life force!"); //} //else //{ // s32b d = damroll(20, 6) + (p.exp / 100) * MON_DRAIN_LIFE; // if (check_state(p, OF_HOLD_LIFE, p.state.flags)) // { // msg("You feel your life slipping away!"); // player_exp_lose(p, d / 10, false); // } // else // { // msg("You feel your life draining away!"); // player_exp_lose(p, d, false); // } //} } else if (effect.value == RBE.EXP_40.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Take damage //take_hit(p, damage, ddesc); //update_smart_learn(m_ptr, p_ptr, OF_HOLD_LIFE); //if (check_state(p, OF_HOLD_LIFE, p.state.flags) && (randint0(100) < 75)) //{ // msg("You keep hold of your life force!"); //} //else //{ // s32b d = damroll(40, 6) + (p.exp / 100) * MON_DRAIN_LIFE; // if (check_state(p, OF_HOLD_LIFE, p.state.flags)) // { // msg("You feel your life slipping away!"); // player_exp_lose(p, d / 10, false); // } // else // { // msg("You feel your life draining away!"); // player_exp_lose(p, d, false); // } //} } else if (effect.value == RBE.EXP_80.value) { throw new NotImplementedException(); //// Obvious //obvious = true; //// Take damage //take_hit(p, damage, ddesc); //update_smart_learn(m_ptr, p_ptr, OF_HOLD_LIFE); //if (check_state(p, OF_HOLD_LIFE, p.state.flags) && (randint0(100) < 50)) //{ // msg("You keep hold of your life force!"); //} //else //{ // s32b d = damroll(80, 6) + (p.exp / 100) * MON_DRAIN_LIFE; // if (check_state(p, OF_HOLD_LIFE, p.state.flags)) // { // msg("You feel your life slipping away!"); // player_exp_lose(p, d / 10, false); // } // else // { // msg("You feel your life draining away!"); // player_exp_lose(p, d, false); // } //} } else if (effect.value == RBE.HALLU.value) { throw new NotImplementedException(); //// Take damage //take_hit(p, damage, ddesc); //// Increase "image" //if (player_inc_timed(p, TMD_IMAGE, 3 + randint1(rlev / 2), true, true)) // obvious = true; //// Learn about the player //monster_learn_resists(m_ptr, p, GF_CHAOS); } else { throw new NotImplementedException(); } // Hack -- only one of cut or stun if (do_cut && do_stun) { // Cancel cut if (Random.randint0(100) < 50) { do_cut = false; } // Cancel stun else { do_stun = false; } } // 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 = Random.randint1(5); break; case 2: k = Random.randint1(5) + 5; break; case 3: k = Random.randint1(20) + 20; break; case 4: k = Random.randint1(50) + 50; break; case 5: k = Random.randint1(100) + 100; break; case 6: k = 300; break; default: k = 500; break; } // Apply the cut if (k != 0) { p.inc_timed(Timed_Effect.CUT, k, true, true); } } // 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 = Random.randint1(5); break; case 2: k = Random.randint1(10) + 10; break; case 3: k = Random.randint1(20) + 20; break; case 4: k = Random.randint1(30) + 30; break; case 5: k = Random.randint1(40) + 40; break; case 6: k = 100; break; default: k = 200; break; } // Apply the stun if (k != 0) { p.inc_timed(Timed_Effect.STUN, k, true, true); } } } // Monster missed player else { // Analyze failed attacks if (method == RBM.HIT || method == RBM.TOUCH || method == RBM.PUNCH || method == RBM.KICK || method == RBM.CLAW || method == RBM.BITE || method == RBM.STING || method == RBM.BUTT || method == RBM.CRUSH || method == RBM.ENGULF) { // Visible monsters if (ml) { // Disturbing Cave.disturb(p, 1, 0); // Message //Utilities.msg("%^s misses you.", m_name); Utilities.msg("{0} misses you.", m_name); } } } // Analyze "visible" monsters only if (visible) { // Count "obvious" attacks (and ones that cause damage) if (obvious || damage != 0 || (l_ptr.blows[ap_cnt] > 10)) { // Count attacks of this type if (l_ptr.blows[ap_cnt] < byte.MaxValue) { l_ptr.blows[ap_cnt]++; } } } // Skip the other blows if necessary if (do_break) { break; } } // Blink away if (blinked) { Utilities.msg("There is a puff of smoke!"); throw new NotImplementedException(); //teleport_away(m_ptr, MAX_SIGHT * 2 + 5); } // Always notice cause of death if (p.is_dead && (l_ptr.deaths < short.MaxValue)) { l_ptr.deaths++; } // Assume we attacked // Nick: Because, based on the length of this function, // literally a million other things could have happened return(true); }
/** * Determine damage for critical hits from melee. * * Factor in weapon weight, total plusses, player level. */ static int critical_norm(int weight, int plus, int dam, ref Message_Type msg_type) { int chance = weight + (Misc.p_ptr.state.to_h + plus) * 5 + Misc.p_ptr.lev * 3; int power = weight + Random.randint1(650); if (Random.randint1(5000) > chance) { msg_type = Message_Type.MSG_HIT; return dam; } else if (power < 400) { msg_type = Message_Type.MSG_HIT_GOOD; return 2 * dam + 5; } else if (power < 700) { msg_type = Message_Type.MSG_HIT_GREAT; return 2 * dam + 10; } else if (power < 900) { msg_type = Message_Type.MSG_HIT_SUPERB; return 3 * dam + 15; } else if (power < 1300) { msg_type = Message_Type.MSG_HIT_HI_GREAT; return 3 * dam + 20; } else { msg_type = Message_Type.MSG_HIT_HI_SUPERB; return 4 * dam + 20; } }