private static void ProcessPerkFeats(NWCreature self) { // Bail early if any of the following is true: // - Creature has a weapon skill queued. // - Creature does not have a PerkFeat cache. // - There are no perk feats in the cache. // - Creature has no target. if (self.GetLocalInt("ACTIVE_WEAPON_SKILL") > 0) { return; } if (!self.Data.ContainsKey("PERK_FEATS")) { return; } Dictionary <int, AIPerkDetails> cache = self.Data["PERK_FEATS"]; if (cache.Count <= 0) { return; } NWObject target = _.GetAttackTarget(self); if (!target.IsValid) { return; } // Pull back whatever concentration effect is currently active, if any. var concentration = AbilityService.GetActiveConcentrationEffect(self); // Exclude any concentration effects, if necessary, then randomize potential feats to use. var randomizedFeatIDs = concentration.Type == PerkType.Unknown ? cache.Values // No concentration exclusions : cache.Values.Where(x => x.ExecutionType != PerkExecutionType.ConcentrationAbility); // Exclude concentration abilities randomizedFeatIDs = randomizedFeatIDs.OrderBy(o => RandomService.Random()); foreach (var perkDetails in randomizedFeatIDs) { // Move to next feat if this creature cannot use this one. if (!AbilityService.CanUsePerkFeat(self, target, perkDetails.FeatID)) { continue; } self.AssignCommand(() => { _.ActionUseFeat(perkDetails.FeatID, target); }); break; } }
private static void ProcessPerkFeats(NWCreature self) { // Bail early if any of the following is true: // - Creature has a weapon skill queued. // - Creature does not have a PerkFeat cache. // - There are no perk feats in the cache. // - Creature has no target. if (self.GetLocalInt("ACTIVE_WEAPON_SKILL") > 0) { return; } if (!self.Data.ContainsKey("PERK_FEATS")) { return; } Dictionary <int, AIPerkDetails> cache = self.Data["PERK_FEATS"]; if (cache.Count <= 0) { return; } NWObject target = _.GetAttackTarget(self); if (!target.IsValid) { return; } // todo: GetEffectType() returns EFFECT_TYPE_INVALIDEFFECT for knockdown effects. // todo: The following code is causing a segfault crash... look into other solutions or figure out what's causing that. // target.Effects.Any(x => NWNXEffect.UnpackEffect(x).Type == (int)EffectTypeEngine.Knockdown) || // Potential workaround: if (target.GetLocalBool("KNOCKDOWN")) return; if (target.GetLocalBool("KNOCKDOWN")) { return; } if (target.Effects.Any(x => _.GetEffectTag(x) == "TRANQUILIZER_EFFECT")) { return; } // Pull back whatever concentration effect is currently active, if any. var concentration = AbilityService.GetActiveConcentrationEffect(self); // Exclude any concentration effects, if necessary, then randomize potential feats to use. var randomizedFeatIDs = concentration.Type == PerkType.Unknown ? cache.Values // No concentration exclusions : cache.Values.Where(x => x.ExecutionType != PerkExecutionType.ConcentrationAbility); // Exclude concentration abilities randomizedFeatIDs = randomizedFeatIDs.OrderBy(o => RandomService.Random()); foreach (var perkDetails in randomizedFeatIDs) { // Move to next feat if this creature cannot use this one. if (!AbilityService.CanUsePerkFeat(self, target, (Feat)perkDetails.FeatID)) { continue; } self.AssignCommand(() => { _.ActionUseFeat((Feat)perkDetails.FeatID, target); }); break; } }