private static void HandleApplySneakAttackDamage() { DamageEventData data = NWNXDamage.GetDamageEventData(); if (data.Total <= 0) { return; } NWObject damager = data.Damager; int sneakAttackType = damager.GetLocalInt("SNEAK_ATTACK_ACTIVE"); if (damager.IsPlayer && sneakAttackType > 0) { NWPlayer player = damager.Object; NWCreature target = _.OBJECT_SELF; var pcPerk = PerkService.GetPCPerkByID(damager.GlobalID, (int)PerkType.SneakAttack); int perkRank = pcPerk?.PerkLevel ?? 0; int perkBonus = 1; // Rank 4 increases damage bonus by 2x (total: 3x) if (perkRank == 4) { perkBonus = 2; } float perkRate; if (sneakAttackType == 1) // Player is behind target. { perkRate = 1.0f * perkBonus; } else // Player is anywhere else. { perkRate = 0.5f * perkBonus; } var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(player); float damageRate = 1.0f + perkRate + effectiveStats.SneakAttack * 0.05f; data.Base = (int)(data.Base * damageRate); if (target.IsNPC) { EnmityService.AdjustEnmity(target, player, 5 * data.Base); } NWNXDamage.SetDamageEventData(data); } damager.DeleteLocalInt("SNEAK_ATTACK_ACTIVE"); }
public static void ApplyEnmity(NWCreature attacker, NWCreature target, Data.Entity.Perk perk) { switch ((EnmityAdjustmentRuleType)perk.EnmityAdjustmentRuleID) { case EnmityAdjustmentRuleType.AllTaggedTargets: EnmityService.AdjustEnmityOnAllTaggedCreatures(attacker, perk.Enmity); break; case EnmityAdjustmentRuleType.TargetOnly: if (target.IsValid) { EnmityService.AdjustEnmity(target, attacker, perk.Enmity); } break; case EnmityAdjustmentRuleType.Custom: var handler = PerkService.GetPerkHandler(perk.ID); handler.OnCustomEnmityRule(attacker, perk.Enmity); break; } }
public static void RegisterPCToAllCombatTargetsForSkill(NWPlayer player, SkillType skillType, NWCreature target) { int skillID = (int)skillType; if (!player.IsPlayer) { return; } if (skillID <= 0) { return; } List <NWPlayer> members = player.PartyMembers.ToList(); int nth = 1; NWCreature creature = _.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, 1, player.Object, nth, CREATURE_TYPE_PLAYER_CHAR, 0); while (creature.IsValid) { if (_.GetDistanceBetween(player.Object, creature.Object) > 20.0f) { break; } // Check NPC's enmity table EnmityTable enmityTable = EnmityService.GetEnmityTable(creature); foreach (var member in members) { if (enmityTable.ContainsKey(member.GlobalID) || (target != null && target.IsValid && target == creature)) { RegisterPCToNPCForSkill(player, creature, skillID); break; } } nth++; creature = _.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, 1, player.Object, nth, CREATURE_TYPE_PLAYER_CHAR, 0); } }