/** * Extract the multiplier from a given object hitting a given monster. * * \param o_ptr is the object being used to attack * \param m_ptr is the monster being attacked * \param best_s_ptr is the best applicable slay_table entry, or null if no * slay already known * \param real is whether this is a real attack (where we update lore) or a * simulation (where we don't) * \param known_only is whether we are using all the object flags, or only * the ones we *already* know about */ //Best_s_ptr was slay** public static void improve_attack_modifier(Object o_ptr, Monster.Monster m_ptr, ref Slay best_s_ptr, bool real, bool known_only) { Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx]; Monster_Lore l_ptr = Misc.l_list[m_ptr.r_idx]; Bitflag f = new Bitflag(Object_Flag.SIZE); Bitflag known_f = new Bitflag(Object_Flag.SIZE); Bitflag note_f = new Bitflag(Object_Flag.SIZE); int i; o_ptr.object_flags(ref f); o_ptr.object_flags_known(ref known_f); for (i = 0; i < Slay.MAX.value; i++) { Slay s_ptr = list[i]; if ((known_only && !known_f.has(s_ptr.object_flag.value)) || (!known_only && !f.has(s_ptr.object_flag.value))) { continue; } /* In a real attack, learn about monster resistance or slay match if: * EITHER the slay flag on the object is known, * OR the monster is vulnerable to the slay/brand */ if (real && (known_f.has(s_ptr.object_flag.value) || (s_ptr.monster_flag != Monster_Flag.NONE && r_ptr.flags.has(s_ptr.monster_flag.value)) || (s_ptr.resist_flag != Monster_Flag.NONE && !r_ptr.flags.has(s_ptr.resist_flag.value)))) { /* notice any brand or slay that would affect monster */ note_f.wipe(); note_f.on(s_ptr.object_flag.value); object_notice_slays(o_ptr, note_f); if (m_ptr.ml && s_ptr.monster_flag != Monster_Flag.NONE) { l_ptr.flags.on(s_ptr.monster_flag.value); } if (m_ptr.ml && s_ptr.resist_flag != Monster_Flag.NONE) { l_ptr.flags.on(s_ptr.resist_flag.value); } } /* If the monster doesn't resist or the slay flag matches */ if ((s_ptr.brand != null && s_ptr.brand.Length != 0 && !r_ptr.flags.has(s_ptr.resist_flag.value)) || (s_ptr.monster_flag != Monster_Flag.NONE && r_ptr.flags.has(s_ptr.monster_flag.value))) { /* compare multipliers to determine best attack */ if ((best_s_ptr == null) || ((best_s_ptr).mult < s_ptr.mult)) { best_s_ptr = s_ptr; } } } }
/** * Notice a given special flag on wielded items. * * \param flag is the flag to notice */ public static void wieldeds_notice_flag(Player.Player p, int flag) { int i; /* Sanity check */ if (flag == 0) { return; } /* XXX Eddie need different naming conventions for starting wieldeds at INVEN_WIELD vs INVEN_WIELD+2 */ for (i = Misc.INVEN_WIELD; i < Misc.ALL_INVEN_TOTAL; i++) { Object o_ptr = p.inventory[i]; Bitflag f = new Bitflag(Object_Flag.SIZE); if (o_ptr.kind == null) { continue; } o_ptr.object_flags(ref f); if (f.has(flag) && !o_ptr.known_flags.has(flag)) { //char o_name[80]; string o_name = o_ptr.object_desc(Detail.BASE); /* Notice the flag */ o_ptr.notice_flag(flag); /* XXX Eddie should this go before noticing the flag to avoid learning twice? */ if (EASY_LEARN && o_ptr.is_jewelry()) { /* XXX Eddie EASY_LEARN Possible concern: gets =teleportation just from +2 speed */ o_ptr.flavor_aware(); o_ptr.check_for_ident(); } /* Message */ Object_Flag.flag_message(flag, o_name); } else { /* Notice that flag is absent */ o_ptr.notice_flag(flag); } /* XXX Eddie should not need this, should be done in noticing, but will remove later */ o_ptr.check_for_ident(); } return; }
static int obj_desc_light(Object o_ptr, ref string buf, int max, int end) { Bitflag f = new Bitflag(Object_Flag.SIZE); o_ptr.object_flags(ref f); /* Fuelled light sources get number of remaining turns appended */ if ((o_ptr.tval == TVal.TV_LIGHT) && !f.has(Object_Flag.NO_FUEL.value)) { buf += String.Format(" ({0} turns)", o_ptr.timeout); } return(buf.Length); }
static int obj_desc_pval(Object o_ptr, string buf, int max, int end, bool spoil) { Bitflag f = new Bitflag(Object_Flag.SIZE); Bitflag f2 = new Bitflag(Object_Flag.SIZE); int i; o_ptr.object_flags(ref f); Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.PVAL, Object_Flag.object_flag_type.STAT); if (!f.is_inter(f2)) { return(end); } buf += " <"; //strnfcat(buf, max, &end, " <"); for (i = 0; i < o_ptr.num_pvals; i++) { if (spoil || o_ptr.this_pval_is_visible(i)) { if (i > 0) { buf += ", "; //strnfcat(buf, max, &end, ", "); } buf += o_ptr.pval[i] > 0 ? "+" + o_ptr.pval[i] : o_ptr.pval[i].ToString(); //strnfcat(buf, max, &end, "%+d", o_ptr.pval[i]); } } buf += ">"; end = buf.Length; //f**k it. //strnfcat(buf, max, &end, ">"); return(end); }
static int obj_desc_combat(Object o_ptr, ref string buf, int max, int end, bool spoil) { Bitflag flags = new Bitflag(Object_Flag.SIZE); Bitflag flags_known = new Bitflag(Object_Flag.SIZE); o_ptr.object_flags(ref flags); o_ptr.object_flags_known(ref flags_known); if (flags.has(Object_Flag.SHOW_DICE.value)) { /* Only display the real damage dice if the combat stats are known */ if (spoil || o_ptr.attack_plusses_are_visible()) { buf = buf + " (" + o_ptr.dd + "d" + o_ptr.ds + ")"; } else { buf = buf + " (" + o_ptr.kind.dd + "d" + o_ptr.kind.ds + ")"; } } if (flags.has(Object_Flag.SHOW_MULT.value)) { /* Display shooting power as part of the multiplier */ if (flags.has(Object_Flag.MIGHT.value) && (spoil || o_ptr.object_flag_is_known(Object_Flag.MIGHT.value))) { buf = buf + " (x" + (o_ptr.sval % 10) + o_ptr.pval[o_ptr.which_pval(Object_Flag.MIGHT.value)] + ")"; } else { buf = buf + " (x" + o_ptr.sval % 10 + ")"; } } /* Show weapon bonuses */ if (spoil || o_ptr.attack_plusses_are_visible()) { if (flags.has(Object_Flag.SHOW_MODS.value) || o_ptr.to_d != 0 || o_ptr.to_h != 0) { /* Make an exception for body armor with only a to-hit penalty */ if (o_ptr.to_h < 0 && o_ptr.to_d == 0 && (o_ptr.tval == TVal.TV_SOFT_ARMOR || o_ptr.tval == TVal.TV_HARD_ARMOR || o_ptr.tval == TVal.TV_DRAG_ARMOR)) { buf = buf + " (" + (o_ptr.to_h > 0 ? "+" : "-") + o_ptr.to_h + ")"; } /* Otherwise, always use the full tuple */ else { buf = buf + " (" + (o_ptr.to_h > 0 ? "+" : "-") + o_ptr.to_h + "," + (o_ptr.to_d > 0 ? "+" : "-") + o_ptr.to_d + ")"; } } } /* Show armor bonuses */ if (spoil || o_ptr.defence_plusses_are_visible()) { if (obj_desc_show_armor(o_ptr)) { buf = buf + " [" + o_ptr.ac + "," + (o_ptr.to_a > 0?"+":"-") + o_ptr.to_a + "]"; } else if (o_ptr.to_a != 0) { buf = buf + " [" + (o_ptr.to_a > 0?"+":"-") + o_ptr.to_a + "]"; } } else if (obj_desc_show_armor(o_ptr)) { buf = buf + " [" + (o_ptr.was_sensed() ? o_ptr.ac : o_ptr.kind.ac) + "]"; } return(end); }
/* * Add an object to a real stores inventory. * * If the object is "worthless", it is thrown away (except in the home). * * If the object cannot be combined with an object already in the inventory, * make a new slot for it, and calculate its "per item" price. Note that * this price will be negative, since the price will not be "fixed" yet. * Adding an object to a "fixed" price stack will not change the fixed price. * * In all cases, return the slot (or -1) where the object was placed */ int carry(Object.Object o_ptr) { int slot; int value, j_value; Object.Object j_ptr; Object_Kind kind = o_ptr.kind; /* Evaluate the object */ value = o_ptr.value(1, false); /* Cursed/Worthless items "disappear" when sold */ if (value <= 0) return (-1); /* Erase the inscription & pseudo-ID bit */ o_ptr.note = null; /* Some item types require maintenance */ switch (o_ptr.tval) { /* Refuel lights to the standard amount */ case TVal.TV_LIGHT: { Bitflag f = new Bitflag(Object_Flag.SIZE); o_ptr.object_flags(ref f); if (!f.has(Object_Flag.NO_FUEL.value)) { if (o_ptr.sval == SVal.SV_LIGHT_TORCH) o_ptr.timeout = Misc.DEFAULT_TORCH; else if (o_ptr.sval == SVal.SV_LIGHT_LANTERN) o_ptr.timeout = Misc.DEFAULT_LAMP; } break; } /* Recharge rods */ case TVal.TV_ROD: { o_ptr.timeout = 0; break; } /* Possibly recharge wands and staves */ case TVal.TV_STAFF: case TVal.TV_WAND: { bool recharge = false; /* Recharge without fail if the store normally carries that type */ for (int i = 0; i < table_num; i++) { if (table[i] == o_ptr.kind) recharge = true; } if (recharge) { int charges = 0; /* Calculate the recharged number of charges */ for (int i = 0; i < o_ptr.number; i++) charges += Random.randcalc(kind.charge, 0, aspect.RANDOMISE); /* Use recharged value only if greater */ if (charges > o_ptr.pval[Misc.DEFAULT_PVAL]) o_ptr.pval[Misc.DEFAULT_PVAL] = (short)charges; } break; } } /* Check each existing object (try to combine) */ for (slot = 0; slot < stock_num; slot++) { /* Get the existing object */ j_ptr = stock[slot]; /* Can the existing items be incremented? */ if (j_ptr.similar(o_ptr, Object.Object.object_stack_t.OSTACK_STORE)) { /* Absorb (some of) the object */ store_object_absorb(ref j_ptr, ref o_ptr); /* All done */ return (slot); } } /* No space? */ if (stock_num >= stock_size) { return (-1); } /* Check existing slots to see if we must "slide" */ for (slot = 0; slot < stock_num; slot++) { /* Get that object */ j_ptr = stock[slot]; /* Objects sort by decreasing type */ if (o_ptr.tval > j_ptr.tval) break; if (o_ptr.tval < j_ptr.tval) continue; /* Objects sort by increasing sval */ if (o_ptr.sval < j_ptr.sval) break; if (o_ptr.sval > j_ptr.sval) continue; /* Evaluate that slot */ j_value = j_ptr.value(1, false); /* Objects sort by decreasing value */ if (value > j_value) break; if (value < j_value) continue; } /* Slide the others up */ for (int i = stock_num; i > slot; i--) { stock[i] = stock[i - 1]; /* Hack -- slide the objects */ //object_copy(&store.stock[i], &store.stock[i-1]); } /* More stuff now */ stock_num++; /* Hack -- Insert the new object */ stock[slot] = o_ptr; //object_copy(&store.stock[slot], o_ptr); /* Return the location */ return (slot); }
static int obj_desc_pval(Object o_ptr, string buf, int max, int end, bool spoil) { Bitflag f = new Bitflag(Object_Flag.SIZE); Bitflag f2 = new Bitflag(Object_Flag.SIZE); int i; o_ptr.object_flags(ref f); Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.PVAL, Object_Flag.object_flag_type.STAT); if (!f.is_inter(f2)) return end; buf += " <"; //strnfcat(buf, max, &end, " <"); for (i = 0; i < o_ptr.num_pvals; i++) { if (spoil || o_ptr.this_pval_is_visible(i)) { if(i > 0) { buf += ", "; //strnfcat(buf, max, &end, ", "); } buf += o_ptr.pval[i] > 0 ? "+" + o_ptr.pval[i] : o_ptr.pval[i].ToString(); //strnfcat(buf, max, &end, "%+d", o_ptr.pval[i]); } } buf += ">"; end = buf.Length; //f**k it. //strnfcat(buf, max, &end, ">"); return end; }
static int obj_desc_light(Object o_ptr, ref string buf, int max, int end) { Bitflag f = new Bitflag(Object_Flag.SIZE); o_ptr.object_flags(ref f); /* Fuelled light sources get number of remaining turns appended */ if ((o_ptr.tval == TVal.TV_LIGHT) && !f.has(Object_Flag.NO_FUEL.value)) buf += String.Format(" ({0} turns)", o_ptr.timeout); return buf.Length; }
static int obj_desc_combat(Object o_ptr, ref string buf, int max, int end, bool spoil) { Bitflag flags = new Bitflag(Object_Flag.SIZE); Bitflag flags_known = new Bitflag(Object_Flag.SIZE); o_ptr.object_flags(ref flags); o_ptr.object_flags_known(ref flags_known); if (flags.has(Object_Flag.SHOW_DICE.value)) { /* Only display the real damage dice if the combat stats are known */ if(spoil || o_ptr.attack_plusses_are_visible()) buf = buf + " (" + o_ptr.dd + "d" + o_ptr.ds + ")"; else buf = buf + " (" + o_ptr.kind.dd + "d" + o_ptr.kind.ds + ")"; } if (flags.has(Object_Flag.SHOW_MULT.value)) { /* Display shooting power as part of the multiplier */ if (flags.has(Object_Flag.MIGHT.value) && (spoil || o_ptr.object_flag_is_known(Object_Flag.MIGHT.value))) buf = buf + " (x" + (o_ptr.sval % 10) + o_ptr.pval[o_ptr.which_pval(Object_Flag.MIGHT.value)] + ")"; else buf = buf + " (x" + o_ptr.sval % 10 + ")"; } /* Show weapon bonuses */ if (spoil || o_ptr.attack_plusses_are_visible()) { if (flags.has(Object_Flag.SHOW_MODS.value) || o_ptr.to_d != 0 || o_ptr.to_h != 0) { /* Make an exception for body armor with only a to-hit penalty */ if(o_ptr.to_h < 0 && o_ptr.to_d == 0 && (o_ptr.tval == TVal.TV_SOFT_ARMOR || o_ptr.tval == TVal.TV_HARD_ARMOR || o_ptr.tval == TVal.TV_DRAG_ARMOR)) buf = buf + " (" + (o_ptr.to_h > 0 ? "+" : "-") + o_ptr.to_h + ")"; /* Otherwise, always use the full tuple */ else buf = buf + " (" + (o_ptr.to_h > 0 ? "+" : "-") + o_ptr.to_h + "," + (o_ptr.to_d > 0 ? "+" : "-") + o_ptr.to_d + ")"; } } /* Show armor bonuses */ if (spoil || o_ptr.defence_plusses_are_visible()) { if (obj_desc_show_armor(o_ptr)) buf = buf + " [" + o_ptr.ac + "," + (o_ptr.to_a > 0?"+":"-") + o_ptr.to_a + "]"; else if (o_ptr.to_a != 0) buf = buf + " [" + (o_ptr.to_a > 0?"+":"-") + o_ptr.to_a + "]"; } else if (obj_desc_show_armor(o_ptr)) { buf = buf + " [" + (o_ptr.was_sensed() ? o_ptr.ac : o_ptr.kind.ac) + "]"; } return end; }
/* * Acid has hit the player, attempt to affect some armor. * * Note that the "base armor" of an object never changes. * * If any armor is damaged (or resists), the player takes less damage. */ static bool minus_ac(Player.Player p) { Object.Object o_ptr = null; Bitflag f = new Bitflag(Object.Object_Flag.SIZE); //char o_name[80]; string o_name; /* Avoid crash during monster power calculations */ if (p.inventory == null) { return(false); } /* Pick a (possibly empty) inventory slot */ switch (Random.randint1(6)) { case 1: o_ptr = p.inventory[Misc.INVEN_BODY]; break; case 2: o_ptr = p.inventory[Misc.INVEN_ARM]; break; case 3: o_ptr = p.inventory[Misc.INVEN_OUTER]; break; case 4: o_ptr = p.inventory[Misc.INVEN_HANDS]; break; case 5: o_ptr = p.inventory[Misc.INVEN_HEAD]; break; case 6: o_ptr = p.inventory[Misc.INVEN_FEET]; break; //default: Misc.assert(0); //Nick: DA FUQ is this doing here C??? } /* Nothing to damage */ if (o_ptr.kind == null) { return(false); } /* No damage left to be done */ if (o_ptr.ac + o_ptr.to_a <= 0) { return(false); } /* Describe */ o_name = o_ptr.object_desc(Object.Object.Detail.BASE); //object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); /* Extract the flags */ o_ptr.object_flags(ref f); /* Object resists */ if (f.has(Object.Object_Flag.IGNORE_ACID.value)) { Utilities.msg("Your %s is unaffected!", o_name); return(true); } /* Message */ Utilities.msg("Your %s is damaged!", o_name); /* Damage the item */ o_ptr.to_a--; p.update |= Misc.PU_BONUS; p.redraw |= (Misc.PR_EQUIP); /* Item was damaged */ return(true); }
/** * Extract the multiplier from a given object hitting a given monster. * * \param o_ptr is the object being used to attack * \param m_ptr is the monster being attacked * \param best_s_ptr is the best applicable slay_table entry, or null if no * slay already known * \param real is whether this is a real attack (where we update lore) or a * simulation (where we don't) * \param known_only is whether we are using all the object flags, or only * the ones we *already* know about */ //Best_s_ptr was slay** public static void improve_attack_modifier(Object o_ptr, Monster.Monster m_ptr, ref Slay best_s_ptr, bool real, bool known_only) { Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx]; Monster_Lore l_ptr = Misc.l_list[m_ptr.r_idx]; Bitflag f = new Bitflag(Object_Flag.SIZE); Bitflag known_f = new Bitflag(Object_Flag.SIZE); Bitflag note_f = new Bitflag(Object_Flag.SIZE); int i; o_ptr.object_flags(ref f); o_ptr.object_flags_known(ref known_f); for (i = 0; i < Slay.MAX.value; i++) { Slay s_ptr = list[i]; if ((known_only && !known_f.has(s_ptr.object_flag.value)) || (!known_only && !f.has(s_ptr.object_flag.value))) continue; /* In a real attack, learn about monster resistance or slay match if: * EITHER the slay flag on the object is known, * OR the monster is vulnerable to the slay/brand */ if (real && (known_f.has(s_ptr.object_flag.value) || (s_ptr.monster_flag != Monster_Flag.NONE && r_ptr.flags.has(s_ptr.monster_flag.value)) || (s_ptr.resist_flag != Monster_Flag.NONE && !r_ptr.flags.has(s_ptr.resist_flag.value)))) { /* notice any brand or slay that would affect monster */ note_f.wipe(); note_f.on(s_ptr.object_flag.value); object_notice_slays(o_ptr, note_f); if (m_ptr.ml && s_ptr.monster_flag != Monster_Flag.NONE) l_ptr.flags.on(s_ptr.monster_flag.value); if (m_ptr.ml && s_ptr.resist_flag != Monster_Flag.NONE) l_ptr.flags.on(s_ptr.resist_flag.value); } /* If the monster doesn't resist or the slay flag matches */ if ((s_ptr.brand != null && s_ptr.brand.Length != 0 && !r_ptr.flags.has(s_ptr.resist_flag.value)) || (s_ptr.monster_flag != Monster_Flag.NONE && r_ptr.flags.has(s_ptr.monster_flag.value))) { /* compare multipliers to determine best attack */ if ((best_s_ptr == null) || ((best_s_ptr).mult < s_ptr.mult)) best_s_ptr = s_ptr; } } }