/** * Remove slays which are duplicates, i.e. they have exactly the same "monster * flag" and the same "resist flag". The one with highest multiplier is kept. * * \param flags is the flagset from which to remove duplicates. * count is the number of dups removed. */ public static int dedup_slays(ref Bitflag flags) { int i, j; int count = 0; for (i = 0; i < list.Count(); i++) { Slay s_ptr = list[i]; if (flags.has(s_ptr.object_flag.value)) { for (j = i + 1; j < list.Count(); j++) { Slay t_ptr = list[j]; if (flags.has(t_ptr.object_flag.value) && (t_ptr.monster_flag == s_ptr.monster_flag) && (t_ptr.resist_flag == s_ptr.resist_flag) && (t_ptr.mult != s_ptr.mult)) { count++; if (t_ptr.mult > s_ptr.mult) { flags.off(s_ptr.object_flag.value); } else { flags.off(t_ptr.object_flag.value); } } } } } return(count); }
/* * Remove the "bad" spells from a spell list */ static void remove_bad_spells(int m_idx, Bitflag f) { Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx); Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx]; Bitflag f2 = new Bitflag(Monster_Spell_Flag.SIZE); Bitflag ai_flags = new Bitflag(Object_Flag.SIZE); int i; uint smart = 0; /* Stupid monsters act randomly */ if (r_ptr.flags.has(Monster_Flag.STUPID.value)) { return; } /* Take working copy of spell flags */ f2.copy(f); /* Don't heal if full */ if (m_ptr.hp >= m_ptr.maxhp) { f2.off(Monster_Spell_Flag.HEAL.value); } /* Don't haste if hasted with time remaining */ if (m_ptr.m_timed[(int)Misc.MON_TMD.FAST] > 10) { f2.off(Monster_Spell_Flag.HASTE.value); } /* Don't teleport to if the player is already next to us */ if (m_ptr.cdis == 1) { f2.off(Monster_Spell_Flag.TELE_TO.value); } /* Update acquired knowledge */ ai_flags.wipe(); if (Option.birth_ai_learn.value) { /* Occasionally forget player status */ if (Random.one_in_(100)) { m_ptr.known_pflags.wipe(); } /* Use the memorized flags */ smart = m_ptr.smart; ai_flags.copy(m_ptr.known_pflags); } /* Cheat if requested */ if (Option.birth_ai_cheat.value) { for (i = 0; i < Object_Flag.MAX.value; i++) { if (Misc.p_ptr.check_state(Object_Flag.list[i], Misc.p_ptr.state.flags)) { ai_flags.on(i); } } if (Misc.p_ptr.msp == 0) { smart |= Misc.SM_IMM_MANA; } } /* Cancel out certain flags based on knowledge */ if (!ai_flags.is_empty()) { throw new NotImplementedException(); //unset_spells(f2, ai_flags, r_ptr); } if ((smart & Misc.SM_IMM_MANA) != 0 && Random.randint0(100) < 50 * (r_ptr.flags.has(Monster_Flag.SMART.value) ? 2 : 1)) { f2.off(Monster_Spell_Flag.DRAIN_MANA.value); } /* use working copy of spell flags */ f.copy(f2); }
/** * Add a pval to an object, rearranging flags as necessary. Returns true * if the number of pvals is now different, false if it is the same. * * \param o_ptr is the object we're adjusting * \param pval is the pval we are adding * \param flag is the flag to which we are adding the pval */ bool add_pval(int pval, int flag) { Bitflag f = new Bitflag(Object_Flag.SIZE); int a = -1, best_pval; /* Sanity check (we may be called with 0 - see ticket #1451) */ if (pval == 0) return false; Object_Flag.create_mask(f, false, Object_Flag.object_flag_type.PVAL, Object_Flag.object_flag_type.STAT); if (flags.has(flag)) { /* See if any other flags are associated with this pval */ a = which_pval(flag); f.off(flag); f.inter(pval_flags[a]); if (f.is_empty()) { /* Safe to increment and finish */ this.pval[a] += (short)pval; if (this.pval[a] == 0) { /* Remove the flag */ flags.off(flag); pval_flags[a].off(flag); } return (object_dedup_pvals()); } } /* So it doesn't have the flag, or it does but that pval also has others */ /* Create a new pval if we can */ if (this.num_pvals < Misc.MAX_PVALS) { this.pval[this.num_pvals] = (short)pval; this.pval_flags[this.num_pvals].on(flag); if (a != -1) { /* then we need to move the flag to the new pval */ this.pval[this.num_pvals] += this.pval[a]; this.pval_flags[a].off(flag); } else /* We need to add it to object_flags */ this.flags.on(flag); this.num_pvals++; /* We do this last because pvals start from zero */ /* We invert the logic because we've already added a pval */ return (!object_dedup_pvals()); } else { /* we use the closest existing pval */ best_pval = object_closest_pval((pval + (a == -1 ? 0 : this.pval[a]))); if (best_pval != a) { /* turn on the flag on the new pval */ this.pval_flags[best_pval].on(flag); if(a != -1) /* turn it off on its old pval */ this.pval_flags[a].off(flag); else /* add it to object_flags */ this.flags.on(flag); } return false; /* We haven't changed any pvals, so no need to de-dup */ } }
/* * Remove the "bad" spells from a spell list */ static void remove_bad_spells(int m_idx, Bitflag f) { Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx); Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx]; Bitflag f2 = new Bitflag(Monster_Spell_Flag.SIZE); Bitflag ai_flags = new Bitflag(Object_Flag.SIZE); int i; uint smart = 0; /* Stupid monsters act randomly */ if (r_ptr.flags.has(Monster_Flag.STUPID.value)) return; /* Take working copy of spell flags */ f2.copy(f); /* Don't heal if full */ if (m_ptr.hp >= m_ptr.maxhp) f2.off(Monster_Spell_Flag.HEAL.value); /* Don't haste if hasted with time remaining */ if (m_ptr.m_timed[(int)Misc.MON_TMD.FAST] > 10) f2.off(Monster_Spell_Flag.HASTE.value); /* Don't teleport to if the player is already next to us */ if (m_ptr.cdis == 1) f2.off(Monster_Spell_Flag.TELE_TO.value); /* Update acquired knowledge */ ai_flags.wipe(); if (Option.birth_ai_learn.value) { /* Occasionally forget player status */ if (Random.one_in_(100)) m_ptr.known_pflags.wipe(); /* Use the memorized flags */ smart = m_ptr.smart; ai_flags.copy(m_ptr.known_pflags); } /* Cheat if requested */ if (Option.birth_ai_cheat.value) { for (i = 0; i < Object_Flag.MAX.value; i++) if (Misc.p_ptr.check_state(Object_Flag.list[i], Misc.p_ptr.state.flags)) ai_flags.on(i); if (Misc.p_ptr.msp == 0) smart |= Misc.SM_IMM_MANA; } /* Cancel out certain flags based on knowledge */ if(!ai_flags.is_empty()) { throw new NotImplementedException(); //unset_spells(f2, ai_flags, r_ptr); } if ((smart & Misc.SM_IMM_MANA) != 0 && Random.randint0(100) < 50 * (r_ptr.flags.has(Monster_Flag.SMART.value) ? 2 : 1)) f2.off(Monster_Spell_Flag.DRAIN_MANA.value); /* use working copy of spell flags */ f.copy(f2); }
/** * Remove slays which are duplicates, i.e. they have exactly the same "monster * flag" and the same "resist flag". The one with highest multiplier is kept. * * \param flags is the flagset from which to remove duplicates. * count is the number of dups removed. */ public static int dedup_slays(ref Bitflag flags) { int i, j; int count = 0; for (i = 0; i < list.Count(); i++) { Slay s_ptr = list[i]; if (flags.has(s_ptr.object_flag.value)) { for (j = i + 1; j < list.Count(); j++) { Slay t_ptr = list[j]; if (flags.has(t_ptr.object_flag.value) && (t_ptr.monster_flag == s_ptr.monster_flag) && (t_ptr.resist_flag == s_ptr.resist_flag) && (t_ptr.mult != s_ptr.mult)) { count++; if (t_ptr.mult > s_ptr.mult) flags.off(s_ptr.object_flag.value); else flags.off(t_ptr.object_flag.value); } } } } return count; }