private int CalculateBAB(NWPlayer oPC, NWItem ignoreItem) { NWItem weapon = oPC.RightHand; // The unequip event fires before the item is actually unequipped, so we need // to have additional checks to make sure we're not getting the weapon that's about to be // unequipped. if (weapon.Equals(ignoreItem)) { weapon = null; NWItem offHand = oPC.LeftHand; if (offHand.CustomItemType == CustomItemType.Blade || offHand.CustomItemType == CustomItemType.FinesseBlade || offHand.CustomItemType == CustomItemType.Blunt || offHand.CustomItemType == CustomItemType.HeavyBlade || offHand.CustomItemType == CustomItemType.HeavyBlunt || offHand.CustomItemType == CustomItemType.Polearm || offHand.CustomItemType == CustomItemType.TwinBlade || offHand.CustomItemType == CustomItemType.MartialArtWeapon || offHand.CustomItemType == CustomItemType.Bow || offHand.CustomItemType == CustomItemType.Crossbow || offHand.CustomItemType == CustomItemType.Throwing) { weapon = offHand; } } if (weapon == null || !weapon.IsValid) { weapon = oPC.Arms; } if (!weapon.IsValid) { return(0); } int weaponSkillID = GetWeaponSkillID(weapon); PCSkill skill = GetPCSkill(oPC, weaponSkillID); if (skill == null) { return(0); } int skillBAB = skill.Rank / 10; int perkBAB = 0; if (weaponSkillID == (int)SkillType.Throwing) { perkBAB += _perk.GetPCPerkLevel(oPC, PerkType.TossAccuracy); } return(1 + skillBAB + perkBAB); // Note: Always add 1 to BAB. 0 will cause a crash in NWNX. }
private void ApplyFeatChanges(NWPlayer oPC, NWItem oItem) { NWItem equipped = oItem ?? oPC.Chest; if (equipped.Equals(oItem) || equipped.CustomItemType != CustomItemType.LightArmor) { _nwnxCreature.RemoveFeat(oPC, NWScript.FEAT_DODGE); return; } _nwnxCreature.AddFeat(oPC, NWScript.FEAT_DODGE); }
private void ApplyFeatChanges(NWCreature creature, NWItem oItem) { NWItem equipped = oItem ?? creature.Chest; if (equipped.Equals(oItem) || equipped.CustomItemType != CustomItemType.LightArmor) { NWNXCreature.RemoveFeat(creature, Feat.Mobility); return; } NWNXCreature.AddFeat(creature, Feat.Mobility); }
private void ApplyFeatChanges(NWPlayer oPC, NWItem oItem) { NWItem equipped = oItem ?? oPC.Chest; if (equipped.Equals(oItem) || equipped.CustomItemType != CustomItemType.HeavyArmor) { _nwnxCreature.RemoveFeat(oPC, (int)CustomFeatType.Provoke); return; } _nwnxCreature.AddFeat(oPC, (int)CustomFeatType.Provoke); }
private void ApplyFeatChanges(NWCreature creature, NWItem oItem) { NWItem equipped = oItem ?? creature.Chest; if (equipped.Equals(oItem) || equipped.CustomItemType != CustomItemType.HeavyArmor) { NWNXCreature.RemoveFeat(creature, (int)CustomFeatType.Provoke); return; } NWNXCreature.AddFeat(creature, (int)CustomFeatType.Provoke); }
private void ApplyFeatChanges(NWCreature creature, NWItem oItem) { NWItem equipped = oItem ?? creature.Chest; if (equipped.Equals(oItem) || equipped.CustomItemType != CustomItemType.HeavyArmor) { NWNXCreature.RemoveFeat(creature, _.FEAT_EXPERTISE); return; } NWNXCreature.AddFeat(creature, _.FEAT_EXPERTISE); }
private void ApplyFeatChanges(NWPlayer oPC, NWItem oItem) { NWItem equipped = oItem ?? oPC.Chest; if (equipped.Equals(oItem) || equipped.CustomItemType != CustomItemType.LightArmor) { NWNXCreature.RemoveFeat(oPC, _.FEAT_MOBILITY); return; } NWNXCreature.AddFeat(oPC, _.FEAT_MOBILITY); }
private void ApplyFeatChanges(NWCreature creature, NWItem oItem) { NWItem equippedWeapon = oItem ?? creature.RightHand; if (equippedWeapon.Equals(oItem) || equippedWeapon.CustomItemType != CustomItemType.BlasterPistol) { NWNXCreature.RemoveFeat(creature, Feat.RapidShot); return; } NWNXCreature.AddFeat(creature, Feat.RapidShot); }
private void ApplyFeatChanges(NWCreature creature, NWItem oItem) { NWItem equipped = oItem ?? creature.RightHand; if (equipped.Equals(oItem) || (equipped.CustomItemType != CustomItemType.BlasterPistol && equipped.CustomItemType != CustomItemType.BlasterRifle)) { NWNXCreature.RemoveFeat(creature, _.FEAT_ZEN_ARCHERY); return; } NWNXCreature.AddFeat(creature, _.FEAT_ZEN_ARCHERY); }
private void ApplyFeatChanges(NWPlayer oPC, NWItem oItem) { NWItem equipped = oItem ?? oPC.RightHand; if (equipped.Equals(oItem) || (equipped.CustomItemType != CustomItemType.Bow && equipped.CustomItemType != CustomItemType.Crossbow)) { _nwnxCreature.RemoveFeat(oPC, FEAT_ZEN_ARCHERY); return; } _nwnxCreature.AddFeat(oPC, FEAT_ZEN_ARCHERY); }
private void ApplyFeatChanges(NWPlayer oPC, NWItem oItem) { NWItem equipped = oItem ?? oPC.RightHand; if (equipped.Equals(oItem) || (equipped.CustomItemType != CustomItemType.BlasterPistol && equipped.CustomItemType != CustomItemType.BlasterRifle)) { _nwnxCreature.RemoveFeat(oPC, NWScript.FEAT_ZEN_ARCHERY); return; } _nwnxCreature.AddFeat(oPC, NWScript.FEAT_ZEN_ARCHERY); }
private void ApplyFeatChanges(NWCreature creature, NWItem oItem) { NWItem equippedArmor = oItem ?? creature.Chest; NWItem equippedWeapon = oItem ?? creature.RightHand; if (equippedArmor.Equals(oItem) || equippedWeapon.Equals(oItem) || equippedArmor.CustomItemType != CustomItemType.LightArmor || equippedWeapon.CustomItemType != CustomItemType.BlasterPistol) { NWNXCreature.RemoveFeat(creature, _.FEAT_RAPID_SHOT); return; } NWNXCreature.AddFeat(creature, _.FEAT_RAPID_SHOT); }
private void ApplyFeatChanges(NWPlayer oPC, NWItem oItem) { NWItem equippedArmor = oItem ?? oPC.Chest; NWItem equippedWeapon = oItem ?? oPC.RightHand; if (equippedArmor.Equals(oItem) || equippedWeapon.Equals(oItem) || equippedArmor.CustomItemType != CustomItemType.LightArmor || equippedWeapon.CustomItemType != CustomItemType.BlasterPistol) { _nwnxCreature.RemoveFeat(oPC, NWScript.FEAT_RAPID_RELOAD); return; } _nwnxCreature.AddFeat(oPC, NWScript.FEAT_RAPID_RELOAD); }
private int CalculateItemAC(NWPlayer oPC, NWItem ignoreItem) { int ac = 0; for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++) { NWItem oItem = NWItem.Wrap(_.GetItemInSlot(slot, oPC.Object)); if (oItem.Equals(ignoreItem)) { continue; } if (oItem.IsValid) { int itemAC = oItem.AC; ac += itemAC; } } return(ac); }
public int EffectiveMaxHitPoints(NWPlayer player, NWItem ignoreItem) { int hp = 25 + player.ConstitutionModifier * 5; int equippedItemHPBonus = 0; var skills = _data.Where <PCSkill>(x => x.PlayerID == player.GlobalID) .Select(x => new { x.SkillID, x.Rank }).ToDictionary(x => x.SkillID, x => x.Rank); float effectPercentBonus = _customEffect.CalculateEffectHPBonusPercent(player); for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++) { NWItem item = _.GetItemInSlot(slot, player); if (item.Equals(ignoreItem)) { continue; } var skillType = _item.GetSkillTypeForItem(item); int rank = skills[(int)skillType]; equippedItemHPBonus += CalculateAdjustedValue(item.HPBonus, item.RecommendedLevel, rank, 0); } hp += _perk.GetPCPerkLevel(player, PerkType.Health) * 5; hp += equippedItemHPBonus; hp = hp + (int)(hp * effectPercentBonus); if (hp > 1275) { hp = 1275; } if (hp < 20) { hp = 20; } return(hp); }
public int EffectiveMaxFP(NWPlayer player, NWItem ignoreItem) { int equippedItemFPBonus = 0; var skills = _data.Where <PCSkill>(x => x.PlayerID == player.GlobalID) .Select(x => new { x.SkillID, x.Rank }).ToDictionary(x => x.SkillID, x => x.Rank); for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++) { NWItem item = _.GetItemInSlot(slot, player.Object); if (item.Equals(ignoreItem)) { continue; } var skillType = _item.GetSkillTypeForItem(item); int rank = skills[(int)skillType]; equippedItemFPBonus += CalculateAdjustedValue(item.FPBonus, item.RecommendedLevel, rank, 0); } int fp = 20; fp += (player.IntelligenceModifier + player.WisdomModifier + player.CharismaModifier) * 5; fp += _perk.GetPCPerkLevel(player, PerkType.FP) * 5; fp += equippedItemFPBonus; if (fp < 0) { fp = 0; } return(fp); }
public static EffectiveItemStats GetPlayerItemEffectiveStats(NWPlayer player, NWItem ignoreItem = null) { int heavyRank = DataService.PCSkill.GetByPlayerIDAndSkillID(player.GlobalID, (int)SkillType.HeavyArmor).Rank; int lightRank = DataService.PCSkill.GetByPlayerIDAndSkillID(player.GlobalID, (int)SkillType.LightArmor).Rank; int forceRank = DataService.PCSkill.GetByPlayerIDAndSkillID(player.GlobalID, (int)SkillType.ForceArmor).Rank; int martialRank = DataService.PCSkill.GetByPlayerIDAndSkillID(player.GlobalID, (int)SkillType.MartialArts).Rank; EffectiveItemStats stats = new EffectiveItemStats(); stats.EnmityRate = 1.0f; HashSet <NWItem> processed = new HashSet <NWItem>(); for (int itemSlot = 0; itemSlot < NumberOfInventorySlots; itemSlot++) { NWItem item = _.GetItemInSlot((InventorySlot)itemSlot, player); if (!item.IsValid || item.Equals(ignoreItem)) { continue; } // Have we already processed this particular item? Skip over it. // NWN likes to include the same weapon in multiple slots for some reasons, so this works around that. // If someone has a better solution to this please feel free to change it. if (processed.Contains(item)) { continue; } processed.Add(item); SkillType skill = ItemService.GetSkillTypeForItem(item); var rank = DataService.PCSkill.GetByPlayerIDAndSkillID(player.GlobalID, (int)skill).Rank; stats.CooldownRecovery += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_COOLDOWN_RECOVERY"); stats.EnmityRate += item.GetLocalFloat("STAT_EFFECTIVE_LEVEL_ENMITY_RATE"); stats.Luck += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_LUCK_BONUS"); stats.Meditate += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_MEDITATE_BONUS"); stats.Rest += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_REST_BONUS"); stats.Medicine += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_MEDICINE_BONUS"); stats.HPRegen += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_HP_REGEN_BONUS"); stats.FPRegen += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_FP_REGEN_BONUS"); stats.Weaponsmith += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_WEAPONSMITH_BONUS"); stats.Cooking += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_COOKING_BONUS"); stats.Engineering += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_ENGINEERING_BONUS"); stats.Fabrication += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_FABRICATION_BONUS"); stats.Armorsmith += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_ARMORSMITH_BONUS"); stats.Harvesting += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_HARVESTING_BONUS"); stats.Piloting += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_PILOTING_BONUS"); stats.Scavenging += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_SCAVENGING_BONUS"); stats.SneakAttack += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_SNEAK_ATTACK_BONUS"); stats.Strength += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_STRENGTH_BONUS"); stats.Dexterity += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_DEXTERITY_BONUS"); stats.Constitution += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_CONSTITUTION_BONUS"); stats.Wisdom += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_WISDOM_BONUS"); stats.Intelligence += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_INTELLIGENCE_BONUS"); stats.Charisma += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_CHARISMA_BONUS"); stats.HP += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_HP_BONUS"); stats.FP += item.GetLocalInt("STAT_EFFECTIVE_LEVEL_FP_BONUS"); // Calculate base attack bonus if (ItemService.WeaponBaseItemTypes.Contains(item.BaseItemType)) { int itemLevel = item.RecommendedLevel; int delta = itemLevel - rank; int itemBAB = item.BaseAttackBonus; if (delta >= 1) { itemBAB--; } if (delta > 0) { itemBAB = itemBAB - delta / 5; } if (itemBAB <= 0) { itemBAB = 0; } stats.BAB += itemBAB; } // Calculate AC if (ItemService.ArmorBaseItemTypes.Contains(item.BaseItemType)) { int skillRankToUse; int maxAC = 0; if (item.CustomItemType == CustomItemType.HeavyArmor) { skillRankToUse = heavyRank; maxAC = 10; } else if (item.CustomItemType == CustomItemType.LightArmor) { skillRankToUse = lightRank; maxAC = 13; } else if (item.CustomItemType == CustomItemType.ForceArmor) { skillRankToUse = forceRank; maxAC = 11; } else if (item.CustomItemType == CustomItemType.MartialArtWeapon) { skillRankToUse = martialRank; } else { continue; } int itemAC = item.CustomAC; itemAC = CalculateAdjustedValue(itemAC, item.RecommendedLevel, skillRankToUse, 0); if (itemAC > maxAC) { item.CustomAC = maxAC; } stats.AC += itemAC; } } // Final casting speed adjustments if (stats.CooldownRecovery < -99) { stats.CooldownRecovery = -99; } else if (stats.CooldownRecovery > 99) { stats.CooldownRecovery = 99; } // Final enmity adjustments if (stats.EnmityRate < 0.5f) { stats.EnmityRate = 0.5f; } else if (stats.EnmityRate > 1.5f) { stats.EnmityRate = 1.5f; } var stance = CustomEffectService.GetCurrentStanceType(player); if (stance == CustomEffectType.ShieldOath) { stats.EnmityRate = stats.EnmityRate + 0.2f; } return(stats); }
private static int CalculateBAB(NWPlayer oPC, NWItem ignoreItem, EffectiveItemStats stats) { NWItem weapon = oPC.RightHand; // The unequip event fires before the item is actually unequipped, so we need // to have additional checks to make sure we're not getting the weapon that's about to be // unequipped. if (weapon.Equals(ignoreItem)) { weapon = null; NWItem offHand = oPC.LeftHand; if (offHand.CustomItemType == CustomItemType.Vibroblade || offHand.CustomItemType == CustomItemType.FinesseVibroblade || offHand.CustomItemType == CustomItemType.Baton || offHand.CustomItemType == CustomItemType.HeavyVibroblade || offHand.CustomItemType == CustomItemType.Saberstaff || offHand.CustomItemType == CustomItemType.Polearm || offHand.CustomItemType == CustomItemType.TwinBlade || offHand.CustomItemType == CustomItemType.MartialArtWeapon || offHand.CustomItemType == CustomItemType.BlasterPistol || offHand.CustomItemType == CustomItemType.BlasterRifle || offHand.CustomItemType == CustomItemType.Throwing) { weapon = offHand; } } if (weapon == null || !weapon.IsValid) { weapon = oPC.Arms; } if (!weapon.IsValid) { return(0); } SkillType itemSkill = ItemService.GetSkillTypeForItem(weapon); if (itemSkill == SkillType.Unknown || itemSkill == SkillType.LightArmor || itemSkill == SkillType.HeavyArmor || itemSkill == SkillType.ForceArmor || itemSkill == SkillType.Shields) { return(0); } int weaponSkillID = (int)itemSkill; PCSkill skill = DataService.PCSkill.GetByPlayerIDAndSkillID(oPC.GlobalID, weaponSkillID); if (skill == null) { return(0); } int skillBAB = skill.Rank / 10; int perkBAB = 0; int backgroundBAB = 0; BackgroundType background = (BackgroundType)oPC.Class1; bool receivesBackgroundBonus = false; switch (weapon.CustomItemType) { case CustomItemType.FinesseVibroblade: receivesBackgroundBonus = background == BackgroundType.Duelist; break; case CustomItemType.Baton: receivesBackgroundBonus = background == BackgroundType.SecurityOfficer; break; case CustomItemType.HeavyVibroblade: receivesBackgroundBonus = background == BackgroundType.Soldier; break; case CustomItemType.TwinBlade: receivesBackgroundBonus = background == BackgroundType.Berserker; break; case CustomItemType.MartialArtWeapon: receivesBackgroundBonus = background == BackgroundType.TerasKasi; break; case CustomItemType.BlasterPistol: receivesBackgroundBonus = background == BackgroundType.Smuggler; break; case CustomItemType.BlasterRifle: receivesBackgroundBonus = background == BackgroundType.Sharpshooter || background == BackgroundType.Mandalorian; break; } if (receivesBackgroundBonus) { backgroundBAB = background == BackgroundType.Mandalorian ? 1 : 2; } return(1 + skillBAB + perkBAB + stats.BAB + backgroundBAB); // Note: Always add 1 to BAB. 0 will cause a crash in NWNX. }
public bool Run(params object[] args) { NWPlaceable oSite = NWPlaceable.Wrap(Object.OBJECT_SELF); NWPlayer oPC = NWPlayer.Wrap(_.GetLastAttacker(oSite.Object)); int constructionSiteID = _structure.GetConstructionSiteID(oSite); if (constructionSiteID <= 0) { oPC.FloatingText("You must select a blueprint before you can build."); oPC.ClearAllActions(); return(true); } NWItem weapon = NWItem.Wrap(_.GetLastWeaponUsed(oPC.Object)); int weaponType = weapon.BaseItemType; if (weaponType != BASE_ITEM_LIGHTHAMMER) { oPC.FloatingText("A hammer must be equipped to build this structure."); oPC.ClearAllActions(); return(true); } // Offhand weapons don't contribute to building. if (weapon.Equals(oPC.LeftHand)) { return(true); } if (!_structure.IsConstructionSiteValid(oSite)) { oPC.FloatingText("Construction site is invalid. Please click the construction site to find out more."); oPC.ClearAllActions(); return(true); } Data.Entities.ConstructionSite entity = _structure.GetConstructionSiteByID(constructionSiteID); if (weapon.CraftTierLevel < entity.StructureBlueprint.CraftTierLevel) { oPC.FloatingText("Your hammer cannot be used with this blueprint. (Required Tool Level: " + entity.StructureBlueprint.CraftTierLevel + ")"); oPC.ClearAllActions(); return(true); } int rank = _skill.GetPCSkill(oPC, SkillType.Construction).Rank; int mangleChance = CalculateMangleChance(oPC, entity.StructureBlueprint.Level, rank); bool isMangle = _random.Random(100) + 1 <= mangleChance; bool foundResource = false; string updateMessage = "You lack the necessary resources..."; int totalAmount = 0; foreach (ConstructionSiteComponent comp in entity.ConstructionSiteComponents) { if (comp.Quantity > 0 && !foundResource) { NWItem item = NWItem.Wrap(_.GetItemPossessedBy(oPC.Object, comp.StructureComponent.Resref)); if (item.IsValid) { int reuseChance = isMangle ? 0 : _perk.GetPCPerkLevel(oPC, PerkType.ConservativeConstruction) * 2 + _perk.GetPCPerkLevel(oPC, PerkType.Lucky); if (_random.Random(100) + 1 <= reuseChance) { oPC.SendMessage("You conserve a resource..."); } else { item.ReduceItemStack(); } if (isMangle) { oPC.SendMessage(_color.Red("You mangle a resource due to your lack of skill...")); return(true); } string name = _item.GetNameByResref(comp.StructureComponent.Resref); comp.Quantity--; updateMessage = "You need " + comp.Quantity + " " + name + " to complete this project."; foundResource = true; } } totalAmount += comp.Quantity; } oPC.DelayCommand(() => oPC.SendMessage(updateMessage), 0.75f); if (totalAmount <= 0) { _structure.CompleteStructure(oSite); } else if (foundResource) { _structure.SaveChanges(); _durability.RunItemDecay(oPC, weapon); if (entity.StructureBlueprint.GivesSkillXP) { int xp = (int)_skill.CalculateSkillAdjustedXP(100, 0, rank); _skill.GiveSkillXP(oPC, SkillType.Construction, xp); } // Speedy Builder - Grants haste for 8 seconds int hasteChance = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyBuilder) * 10; if (hasteChance > 0) { hasteChance += _perk.GetPCPerkLevel(oPC, PerkType.Lucky) * 2; } PlayerCharacter pcEntity = _player.GetPlayerEntity(oPC); if (pcEntity.BackgroundID == (int)BackgroundType.ConstructionBuilder) { hasteChance += 10; } if (_random.Random(100) + 1 <= hasteChance) { _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectHaste(), oPC.Object, 8.0f); } } else { oPC.ClearAllActions(); } return(true); }
private int CalculateBAB(NWPlayer oPC, NWItem ignoreItem, EffectiveItemStats stats) { NWItem weapon = oPC.RightHand; // The unequip event fires before the item is actually unequipped, so we need // to have additional checks to make sure we're not getting the weapon that's about to be // unequipped. if (weapon.Equals(ignoreItem)) { weapon = null; NWItem offHand = oPC.LeftHand; if (offHand.CustomItemType == CustomItemType.Vibroblade || offHand.CustomItemType == CustomItemType.FinesseVibroblade || offHand.CustomItemType == CustomItemType.Baton || offHand.CustomItemType == CustomItemType.HeavyVibroblade || offHand.CustomItemType == CustomItemType.Saberstaff || offHand.CustomItemType == CustomItemType.Polearm || offHand.CustomItemType == CustomItemType.TwinBlade || offHand.CustomItemType == CustomItemType.MartialArtWeapon || offHand.CustomItemType == CustomItemType.BlasterPistol || offHand.CustomItemType == CustomItemType.BlasterRifle || offHand.CustomItemType == CustomItemType.Throwing) { weapon = offHand; } } if (weapon == null || !weapon.IsValid) { weapon = oPC.Arms; } if (!weapon.IsValid) { return(0); } SkillType itemSkill = _item.GetSkillTypeForItem(weapon); if (itemSkill == SkillType.Unknown || itemSkill == SkillType.LightArmor || itemSkill == SkillType.HeavyArmor || itemSkill == SkillType.ForceArmor || itemSkill == SkillType.Shields) { return(0); } int weaponSkillID = (int)itemSkill; PCSkill skill = _data.Single <PCSkill>(x => x.PlayerID == oPC.GlobalID && x.SkillID == weaponSkillID); if (skill == null) { return(0); } int skillBAB = skill.Rank / 10; int perkBAB = 0; int backgroundBAB = 0; BackgroundType background = (BackgroundType)oPC.Class1; bool receivesBackgroundBonus = false; // Apply increased BAB if player is using a weapon for which they have a proficiency. PerkType proficiencyPerk = PerkType.Unknown; SkillType proficiencySkill = SkillType.Unknown; switch (weapon.CustomItemType) { case CustomItemType.Vibroblade: proficiencyPerk = PerkType.VibrobladeProficiency; proficiencySkill = SkillType.OneHanded; break; case CustomItemType.FinesseVibroblade: proficiencyPerk = PerkType.FinesseVibrobladeProficiency; proficiencySkill = SkillType.OneHanded; receivesBackgroundBonus = background == BackgroundType.Duelist; break; case CustomItemType.Baton: proficiencyPerk = PerkType.BatonProficiency; proficiencySkill = SkillType.OneHanded; receivesBackgroundBonus = background == BackgroundType.SecurityOfficer; break; case CustomItemType.HeavyVibroblade: proficiencyPerk = PerkType.HeavyVibrobladeProficiency; proficiencySkill = SkillType.TwoHanded; receivesBackgroundBonus = background == BackgroundType.Soldier; break; case CustomItemType.Saberstaff: proficiencyPerk = PerkType.SaberstaffProficiency; proficiencySkill = SkillType.Lightsaber; break; case CustomItemType.Polearm: proficiencyPerk = PerkType.PolearmProficiency; proficiencySkill = SkillType.TwoHanded; break; case CustomItemType.TwinBlade: proficiencyPerk = PerkType.TwinVibrobladeProficiency; proficiencySkill = SkillType.TwinBlades; receivesBackgroundBonus = background == BackgroundType.Berserker; break; case CustomItemType.MartialArtWeapon: proficiencyPerk = PerkType.MartialArtsProficiency; proficiencySkill = SkillType.MartialArts; receivesBackgroundBonus = background == BackgroundType.TerasKasi; break; case CustomItemType.BlasterPistol: proficiencyPerk = PerkType.BlasterPistolProficiency; proficiencySkill = SkillType.Firearms; receivesBackgroundBonus = background == BackgroundType.Smuggler; break; case CustomItemType.BlasterRifle: proficiencyPerk = PerkType.BlasterRifleProficiency; proficiencySkill = SkillType.Firearms; receivesBackgroundBonus = background == BackgroundType.Sharpshooter || background == BackgroundType.Mandalorian; break; case CustomItemType.Throwing: proficiencyPerk = PerkType.ThrowingProficiency; proficiencySkill = SkillType.Throwing; break; case CustomItemType.Lightsaber: proficiencyPerk = PerkType.LightsaberProficiency; proficiencySkill = SkillType.Lightsaber; break; } if (weapon.GetLocalInt("LIGHTSABER") == TRUE) { proficiencyPerk = PerkType.LightsaberProficiency; proficiencySkill = SkillType.Lightsaber; } if (proficiencyPerk != PerkType.Unknown && proficiencySkill != SkillType.Unknown) { perkBAB += _perk.GetPCPerkLevel(oPC, proficiencyPerk); } if (receivesBackgroundBonus) { backgroundBAB = background == BackgroundType.Mandalorian ? 1 : 2; } return(1 + skillBAB + perkBAB + stats.BAB + backgroundBAB); // Note: Always add 1 to BAB. 0 will cause a crash in NWNX. }
public EffectiveItemStats GetPlayerItemEffectiveStats(NWPlayer player, NWItem ignoreItem = null) { using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats")) { List <PCSkill> pcArmorSkills; using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::GetPCArmorSkills")) { pcArmorSkills = _data.Where <PCSkill>(x => x.PlayerID == player.GlobalID && (x.SkillID == (int)SkillType.HeavyArmor || x.SkillID == (int)SkillType.LightArmor || x.SkillID == (int)SkillType.ForceArmor)) .ToList(); } int heavyRank = pcArmorSkills.Single(x => x.SkillID == (int)SkillType.HeavyArmor).Rank; int lightRank = pcArmorSkills.Single(x => x.SkillID == (int)SkillType.LightArmor).Rank; int forceRank = pcArmorSkills.Single(x => x.SkillID == (int)SkillType.ForceArmor).Rank; EffectiveItemStats stats = new EffectiveItemStats(); stats.EnmityRate = 1.0f; using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::ItemLoop")) { HashSet <NWItem> processed = new HashSet <NWItem>(); for (int itemSlot = 0; itemSlot < NUM_INVENTORY_SLOTS; itemSlot++) { NWItem item = _.GetItemInSlot(itemSlot, player); if (!item.IsValid || item.Equals(ignoreItem)) { continue; } SkillType skill = _item.GetSkillTypeForItem(item); int rank; // Have we already processed this particular item? Skip over it. // NWN likes to include the same weapon in multiple slots for some reasons, so this works around that. // If someone has a better solution to this please feel free to change it. if (processed.Contains(item)) { continue; } processed.Add(item); using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::ItemLoop::GetRank")) { rank = _data.Single <PCSkill>(x => x.PlayerID == player.GlobalID && x.SkillID == (int)skill).Rank; } using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::ItemLoop::StatAdjustments")) { // Only scale casting speed if it's a bonus. Penalties remain regardless of skill level difference. if (item.CastingSpeed > 0) { stats.CastingSpeed += CalculateAdjustedValue(item.CastingSpeed, item.RecommendedLevel, rank, 1); } else { stats.CastingSpeed += item.CastingSpeed; } stats.EnmityRate += CalculateAdjustedValue(0.01f * item.EnmityRate, item.RecommendedLevel, rank, 0.00f); stats.DarkAbility += CalculateAdjustedValue(item.DarkAbilityBonus, item.RecommendedLevel, rank, 0); stats.LightAbility += CalculateAdjustedValue(item.LightAbilityBonus, item.RecommendedLevel, rank, 0); stats.Luck += CalculateAdjustedValue(item.LuckBonus, item.RecommendedLevel, rank, 0); stats.Meditate += CalculateAdjustedValue(item.MeditateBonus, item.RecommendedLevel, rank, 0); stats.Rest += CalculateAdjustedValue(item.RestBonus, item.RecommendedLevel, rank, 0); stats.Medicine += CalculateAdjustedValue(item.MedicineBonus, item.RecommendedLevel, rank, 0); stats.HPRegen += CalculateAdjustedValue(item.HPRegenBonus, item.RecommendedLevel, rank, 0); stats.FPRegen += CalculateAdjustedValue(item.FPRegenBonus, item.RecommendedLevel, rank, 0); stats.Weaponsmith += CalculateAdjustedValue(item.CraftBonusWeaponsmith, item.RecommendedLevel, rank, 0); stats.Cooking += CalculateAdjustedValue(item.CraftBonusCooking, item.RecommendedLevel, rank, 0); stats.Engineering += CalculateAdjustedValue(item.CraftBonusEngineering, item.RecommendedLevel, rank, 0); stats.Fabrication += CalculateAdjustedValue(item.CraftBonusFabrication, item.RecommendedLevel, rank, 0); stats.Armorsmith += CalculateAdjustedValue(item.CraftBonusArmorsmith, item.RecommendedLevel, rank, 0); stats.Harvesting += CalculateAdjustedValue(item.HarvestingBonus, item.RecommendedLevel, rank, 0); stats.SneakAttack += CalculateAdjustedValue(item.SneakAttackBonus, item.RecommendedLevel, rank, 0); stats.Strength += CalculateAdjustedValue(item.StrengthBonus, item.RecommendedLevel, rank, 0); stats.Dexterity += CalculateAdjustedValue(item.DexterityBonus, item.RecommendedLevel, rank, 0); stats.Constitution += CalculateAdjustedValue(item.ConstitutionBonus, item.RecommendedLevel, rank, 0); stats.Wisdom += CalculateAdjustedValue(item.WisdomBonus, item.RecommendedLevel, rank, 0); stats.Intelligence += CalculateAdjustedValue(item.IntelligenceBonus, item.RecommendedLevel, rank, 0); stats.Charisma += CalculateAdjustedValue(item.CharismaBonus, item.RecommendedLevel, rank, 0); stats.HP += CalculateAdjustedValue(item.HPBonus, item.RecommendedLevel, rank, 0); stats.FP += CalculateAdjustedValue(item.FPBonus, item.RecommendedLevel, rank, 0); } using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::ItemLoop::CalcBAB")) { // Calculate base attack bonus int itemLevel = item.RecommendedLevel; int delta = itemLevel - rank; int itemBAB = item.BaseAttackBonus; if (delta >= 1) { itemBAB--; } if (delta > 0) { itemBAB = itemBAB - delta / 5; } if (itemBAB <= 0) { itemBAB = 0; } stats.BAB += itemBAB; } using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::ItemLoop::CalcAC")) { // Calculate AC if (ACBaseItemTypes.Contains(item.BaseItemType)) { int skillRankToUse; if (item.CustomItemType == CustomItemType.HeavyArmor) { skillRankToUse = heavyRank; } else if (item.CustomItemType == CustomItemType.LightArmor) { skillRankToUse = lightRank; } else if (item.CustomItemType == CustomItemType.ForceArmor) { skillRankToUse = forceRank; } else { continue; } int itemAC = item.CustomAC; itemAC = CalculateAdjustedValue(itemAC, item.RecommendedLevel, skillRankToUse, 0); stats.AC += itemAC; } } } } using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::FinalAdjustments")) { // Final casting speed adjustments if (stats.CastingSpeed < -99) { stats.CastingSpeed = -99; } else if (stats.CastingSpeed > 99) { stats.CastingSpeed = 99; } // Final enmity adjustments if (stats.EnmityRate < 0.5f) { stats.EnmityRate = 0.5f; } else if (stats.EnmityRate > 1.5f) { stats.EnmityRate = 1.5f; } var stance = _customEffect.GetCurrentStanceType(player); if (stance == CustomEffectType.ShieldOath) { stats.EnmityRate = stats.EnmityRate + 0.2f; } return(stats); } } }
private int CalculateBAB(NWPlayer oPC, NWItem ignoreItem) { NWItem weapon = oPC.RightHand; // The unequip event fires before the item is actually unequipped, so we need // to have additional checks to make sure we're not getting the weapon that's about to be // unequipped. if (weapon.Equals(ignoreItem)) { weapon = null; NWItem offHand = oPC.LeftHand; if (offHand.CustomItemType == CustomItemType.Vibroblade || offHand.CustomItemType == CustomItemType.FinesseVibroblade || offHand.CustomItemType == CustomItemType.Baton || offHand.CustomItemType == CustomItemType.HeavyVibroblade || offHand.CustomItemType == CustomItemType.Saberstaff || offHand.CustomItemType == CustomItemType.Polearm || offHand.CustomItemType == CustomItemType.TwinBlade || offHand.CustomItemType == CustomItemType.MartialArtWeapon || offHand.CustomItemType == CustomItemType.BlasterPistol || offHand.CustomItemType == CustomItemType.BlasterRifle || offHand.CustomItemType == CustomItemType.Throwing) { weapon = offHand; } } if (weapon == null || !weapon.IsValid) { weapon = oPC.Arms; } if (!weapon.IsValid) { return(0); } SkillType itemSkill = _item.GetSkillTypeForItem(weapon); if (itemSkill == SkillType.Unknown || itemSkill == SkillType.LightArmor || itemSkill == SkillType.HeavyArmor || itemSkill == SkillType.ForceArmor || itemSkill == SkillType.Shields) { return(0); } int weaponSkillID = (int)itemSkill; PCSkill skill = _data.Single <PCSkill>(x => x.PlayerID == oPC.GlobalID && x.SkillID == weaponSkillID); if (skill == null) { return(0); } int skillBAB = skill.Rank / 10; int perkBAB = 0; int backgroundBAB = 0; BackgroundType background = (BackgroundType)oPC.Class1; bool receivesBackgroundBonus = false; // Apply increased BAB if player is using a weapon for which they have a proficiency. PerkType proficiencyPerk = PerkType.Unknown; SkillType proficiencySkill = SkillType.Unknown; switch (weapon.CustomItemType) { case CustomItemType.Vibroblade: proficiencyPerk = PerkType.VibrobladeProficiency; proficiencySkill = SkillType.OneHanded; break; case CustomItemType.FinesseVibroblade: proficiencyPerk = PerkType.FinesseVibrobladeProficiency; proficiencySkill = SkillType.OneHanded; receivesBackgroundBonus = background == BackgroundType.Duelist; break; case CustomItemType.Baton: proficiencyPerk = PerkType.BatonProficiency; proficiencySkill = SkillType.OneHanded; receivesBackgroundBonus = background == BackgroundType.SecurityOfficer; break; case CustomItemType.HeavyVibroblade: proficiencyPerk = PerkType.HeavyVibrobladeProficiency; proficiencySkill = SkillType.TwoHanded; receivesBackgroundBonus = background == BackgroundType.Soldier; break; case CustomItemType.Saberstaff: proficiencyPerk = PerkType.SaberstaffProficiency; proficiencySkill = SkillType.TwoHanded; break; case CustomItemType.Polearm: proficiencyPerk = PerkType.PolearmProficiency; proficiencySkill = SkillType.TwoHanded; break; case CustomItemType.TwinBlade: proficiencyPerk = PerkType.TwinVibrobladeProficiency; proficiencySkill = SkillType.TwinBlades; receivesBackgroundBonus = background == BackgroundType.Berserker; break; case CustomItemType.MartialArtWeapon: proficiencyPerk = PerkType.MartialArtsProficiency; proficiencySkill = SkillType.MartialArts; receivesBackgroundBonus = background == BackgroundType.TerasKasi; break; case CustomItemType.BlasterPistol: proficiencyPerk = PerkType.BlasterPistolProficiency; proficiencySkill = SkillType.Firearms; receivesBackgroundBonus = background == BackgroundType.Smuggler; break; case CustomItemType.BlasterRifle: proficiencyPerk = PerkType.BlasterRifleProficiency; proficiencySkill = SkillType.Firearms; receivesBackgroundBonus = background == BackgroundType.Sharpshooter; break; case CustomItemType.Throwing: proficiencyPerk = PerkType.ThrowingProficiency; proficiencySkill = SkillType.Throwing; break; case CustomItemType.Lightsaber: proficiencyPerk = PerkType.LightsaberProficiency; proficiencySkill = SkillType.OneHanded; break; } if (proficiencyPerk != PerkType.Unknown && proficiencySkill != SkillType.Unknown) { perkBAB += _perk.GetPCPerkLevel(oPC, proficiencyPerk); } if (receivesBackgroundBonus) { backgroundBAB = 2; } int equipmentBAB = 0; for (int x = 0; x < NUM_INVENTORY_SLOTS; x++) { NWItem equipped = (_.GetItemInSlot(x, oPC.Object)); int itemLevel = equipped.RecommendedLevel; SkillType equippedSkill = _item.GetSkillTypeForItem(equipped); int rank = _data.Single <PCSkill>(s => s.PlayerID == oPC.GlobalID && s.SkillID == (int)equippedSkill).Rank; int delta = itemLevel - rank; // -20 int itemBAB = equipped.BaseAttackBonus; if (delta >= 1) { itemBAB--; } if (delta > 0) { itemBAB = itemBAB - delta / 5; } if (itemBAB <= 0) { itemBAB = 0; } equipmentBAB += itemBAB; } return(1 + skillBAB + perkBAB + equipmentBAB + backgroundBAB); // Note: Always add 1 to BAB. 0 will cause a crash in NWNX. }
public EffectiveItemStats GetPlayerItemEffectiveStats(NWPlayer player, NWItem ignoreItem = null) { EffectiveItemStats stats = new EffectiveItemStats(); stats.EnmityRate = 1.0f; for (int itemSlot = 0; itemSlot < NUM_INVENTORY_SLOTS; itemSlot++) { NWItem item = _.GetItemInSlot(itemSlot, player); if (!item.IsValid || item.Equals(ignoreItem)) { continue; } SkillType skill = _item.GetSkillTypeForItem(item); int rank = _data.Single <PCSkill>(x => x.PlayerID == player.GlobalID && x.SkillID == (int)skill).Rank; // Only scale casting speed if it's a bonus. Penalties remain regardless of skill level difference. if (item.CastingSpeed > 0) { stats.CastingSpeed += CalculateAdjustedValue(item.CastingSpeed, item.RecommendedLevel, rank); } else { stats.CastingSpeed += item.CastingSpeed; } stats.EnmityRate += CalculateAdjustedValue(0.01f * item.EnmityRate, item.RecommendedLevel, rank, 0.00f); stats.DarkAbility += CalculateAdjustedValue(item.DarkAbilityBonus, item.RecommendedLevel, rank, 0); stats.LightAbility += CalculateAdjustedValue(item.LightAbilityBonus, item.RecommendedLevel, rank, 0); stats.Luck += CalculateAdjustedValue(item.LuckBonus, item.RecommendedLevel, rank, 0); stats.Meditate += CalculateAdjustedValue(item.MeditateBonus, item.RecommendedLevel, rank, 0); stats.Rest += CalculateAdjustedValue(item.RestBonus, item.RecommendedLevel, rank, 0); stats.Medicine += CalculateAdjustedValue(item.MedicineBonus, item.RecommendedLevel, rank, 0); stats.HPRegen += CalculateAdjustedValue(item.HPRegenBonus, item.RecommendedLevel, rank, 0); stats.FPRegen += CalculateAdjustedValue(item.FPRegenBonus, item.RecommendedLevel, rank, 0); stats.Weaponsmith += CalculateAdjustedValue(item.CraftBonusWeaponsmith, item.RecommendedLevel, rank, 0); stats.Cooking += CalculateAdjustedValue(item.CraftBonusCooking, item.RecommendedLevel, rank, 0); stats.Engineering += CalculateAdjustedValue(item.CraftBonusEngineering, item.RecommendedLevel, rank, 0); stats.Fabrication += CalculateAdjustedValue(item.CraftBonusFabrication, item.RecommendedLevel, rank, 0); stats.Armorsmith += CalculateAdjustedValue(item.CraftBonusArmorsmith, item.RecommendedLevel, rank, 0); stats.Harvesting += CalculateAdjustedValue(item.HarvestingBonus, item.RecommendedLevel, rank, 0); stats.SneakAttack += CalculateAdjustedValue(item.SneakAttackBonus, item.RecommendedLevel, rank, 0); stats.Strength += CalculateAdjustedValue(item.StrengthBonus, item.RecommendedLevel, rank, 0); stats.Dexterity += CalculateAdjustedValue(item.DexterityBonus, item.RecommendedLevel, rank, 0); stats.Constitution += CalculateAdjustedValue(item.ConstitutionBonus, item.RecommendedLevel, rank, 0); stats.Wisdom += CalculateAdjustedValue(item.WisdomBonus, item.RecommendedLevel, rank, 0); stats.Intelligence += CalculateAdjustedValue(item.IntelligenceBonus, item.RecommendedLevel, rank, 0); stats.Charisma += CalculateAdjustedValue(item.CharismaBonus, item.RecommendedLevel, rank, 0); } // Final casting speed adjustments if (stats.CastingSpeed < -99) { stats.CastingSpeed = -99; } else if (stats.CastingSpeed > 99) { stats.CastingSpeed = 99; } // Final enmity adjustments if (stats.EnmityRate < 0.5f) { stats.EnmityRate = 0.5f; } else if (stats.EnmityRate > 1.5f) { stats.EnmityRate = 1.5f; } var stance = _customEffect.GetCurrentStanceType(player); if (stance == CustomEffectType.ShieldOath) { stats.EnmityRate = stats.EnmityRate + 0.2f; } return(stats); }
public int EffectiveArmorClass(NWPlayer player, NWItem ignoreItem) { int[] skills = { (int)SkillType.HeavyArmor, (int)SkillType.LightArmor, (int)SkillType.ForceArmor }; var armorSkills = _data.Where <PCSkill>(x => x.PlayerID == player.GlobalID && skills.Contains(x.SkillID)).ToList(); int heavyRank = armorSkills.Single(x => x.SkillID == (int)SkillType.HeavyArmor).Rank; int lightRank = armorSkills.Single(x => x.SkillID == (int)SkillType.LightArmor).Rank; int forceRank = armorSkills.Single(x => x.SkillID == (int)SkillType.ForceArmor).Rank; int baseAC = 0; for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++) { NWItem oItem = _.GetItemInSlot(slot, player.Object); if (oItem.Equals(ignoreItem)) { continue; } if (!oItem.IsValid) { continue; } if (!_item.ArmorBaseItemTypes.Contains(oItem.BaseItemType)) { continue; } if (oItem.CustomItemType != CustomItemType.HeavyArmor && oItem.CustomItemType != CustomItemType.LightArmor && oItem.CustomItemType != CustomItemType.ForceArmor) { continue; } int skillRankToUse = 0; if (oItem.CustomItemType == CustomItemType.HeavyArmor && oItem.RecommendedLevel > heavyRank) { skillRankToUse = heavyRank; } else if (oItem.CustomItemType == CustomItemType.LightArmor && oItem.RecommendedLevel > lightRank) { skillRankToUse = lightRank; } else if (oItem.CustomItemType == CustomItemType.ForceArmor && oItem.RecommendedLevel > forceRank) { skillRankToUse = forceRank; } int itemAC = oItem.CustomAC; itemAC = CalculateAdjustedValue(itemAC, oItem.RecommendedLevel, skillRankToUse, 0); baseAC += itemAC; } baseAC = baseAC + _customEffect.CalculateEffectAC(player); int totalAC = _.GetAC(player) - baseAC; // Shield Oath and Sword Oath affect a percentage of the TOTAL armor class on a creature. var stance = _customEffect.GetCurrentStanceType(player); if (stance == CustomEffectType.ShieldOath) { int bonus = (int)(totalAC * 0.2f); baseAC = baseAC + bonus; } else if (stance == CustomEffectType.SwordOath) { int penalty = (int)(totalAC * 0.3f); baseAC = baseAC - penalty; } return(baseAC); }
public void ApplyStatChanges(NWPlayer player, NWItem ignoreItem) { if (!player.IsPlayer) { return; } if (!player.IsInitializedAsPlayer) { return; } PlayerCharacter pcEntity = _db.PlayerCharacters.Single(x => x.PlayerID == player.GlobalID); List <PCSkill> skills = _db.PCSkills.Where(x => x.PlayerID == player.GlobalID && x.Skill.IsActive).ToList(); float strBonus = 0.0f; float dexBonus = 0.0f; float conBonus = 0.0f; float intBonus = 0.0f; float wisBonus = 0.0f; float chaBonus = 0.0f; foreach (PCSkill pcSkill in skills) { Skill skill = pcSkill.Skill; CustomAttribute primary = (CustomAttribute)skill.Primary; CustomAttribute secondary = (CustomAttribute)skill.Secondary; CustomAttribute tertiary = (CustomAttribute)skill.Tertiary; // Primary Bonuses if (primary == CustomAttribute.STR) { strBonus += PrimaryIncrease * pcSkill.Rank; } else if (primary == CustomAttribute.DEX) { dexBonus += PrimaryIncrease * pcSkill.Rank; } else if (primary == CustomAttribute.CON) { conBonus += PrimaryIncrease * pcSkill.Rank; } else if (primary == CustomAttribute.INT) { intBonus += PrimaryIncrease * pcSkill.Rank; } else if (primary == CustomAttribute.WIS) { wisBonus += PrimaryIncrease * pcSkill.Rank; } else if (primary == CustomAttribute.CHA) { chaBonus += PrimaryIncrease * pcSkill.Rank; } // Secondary Bonuses if (secondary == CustomAttribute.STR) { strBonus += SecondaryIncrease * pcSkill.Rank; } else if (secondary == CustomAttribute.DEX) { dexBonus += SecondaryIncrease * pcSkill.Rank; } else if (secondary == CustomAttribute.CON) { conBonus += SecondaryIncrease * pcSkill.Rank; } else if (secondary == CustomAttribute.INT) { intBonus += SecondaryIncrease * pcSkill.Rank; } else if (secondary == CustomAttribute.WIS) { wisBonus += SecondaryIncrease * pcSkill.Rank; } else if (secondary == CustomAttribute.CHA) { chaBonus += SecondaryIncrease * pcSkill.Rank; } // Tertiary Bonuses if (tertiary == CustomAttribute.STR) { strBonus += TertiaryIncrease * pcSkill.Rank; } else if (tertiary == CustomAttribute.DEX) { dexBonus += TertiaryIncrease * pcSkill.Rank; } else if (tertiary == CustomAttribute.CON) { conBonus += TertiaryIncrease * pcSkill.Rank; } else if (tertiary == CustomAttribute.INT) { intBonus += TertiaryIncrease * pcSkill.Rank; } else if (tertiary == CustomAttribute.WIS) { wisBonus += TertiaryIncrease * pcSkill.Rank; } else if (tertiary == CustomAttribute.CHA) { chaBonus += TertiaryIncrease * pcSkill.Rank; } } // Check caps. if (strBonus > MaxAttributeBonus) { strBonus = MaxAttributeBonus; } if (dexBonus > MaxAttributeBonus) { dexBonus = MaxAttributeBonus; } if (conBonus > MaxAttributeBonus) { conBonus = MaxAttributeBonus; } if (intBonus > MaxAttributeBonus) { intBonus = MaxAttributeBonus; } if (wisBonus > MaxAttributeBonus) { wisBonus = MaxAttributeBonus; } if (chaBonus > MaxAttributeBonus) { chaBonus = MaxAttributeBonus; } if (pcEntity.BackgroundID == (int)BackgroundType.Archer || pcEntity.BackgroundID == (int)BackgroundType.Crossbowman) { dexBonus++; wisBonus++; } if (pcEntity.BackgroundID == (int)BackgroundType.Guard || pcEntity.BackgroundID == (int)BackgroundType.Berserker) { strBonus++; conBonus++; } if (pcEntity.BackgroundID == (int)BackgroundType.TwinBladeSpecialist) { dexBonus++; conBonus++; } if (pcEntity.BackgroundID == (int)BackgroundType.MartialArtist) { strBonus++; dexBonus++; } // Apply attributes _nwnxCreature.SetRawAbilityScore(player, ABILITY_STRENGTH, (int)strBonus + pcEntity.STRBase); _nwnxCreature.SetRawAbilityScore(player, ABILITY_DEXTERITY, (int)dexBonus + pcEntity.DEXBase); _nwnxCreature.SetRawAbilityScore(player, ABILITY_CONSTITUTION, (int)conBonus + pcEntity.CONBase); _nwnxCreature.SetRawAbilityScore(player, ABILITY_INTELLIGENCE, (int)intBonus + pcEntity.INTBase); _nwnxCreature.SetRawAbilityScore(player, ABILITY_WISDOM, (int)wisBonus + pcEntity.WISBase); _nwnxCreature.SetRawAbilityScore(player, ABILITY_CHARISMA, (int)chaBonus + pcEntity.CHABase); // Apply AC int ac = CalculateItemAC(player, ignoreItem) + _customEffect.CalculateEffectAC(player); _nwnxCreature.SetBaseAC(player, ac); // Apply BAB int bab = CalculateBAB(player, ignoreItem); _nwnxCreature.SetBaseAttackBonus(player, bab); int equippedItemHPBonus = 0; int equippedItemManaBonus = 0; for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++) { NWItem item = NWItem.Wrap(_.GetItemInSlot(slot, player.Object)); if (item.Equals(ignoreItem)) { continue; } equippedItemHPBonus += item.HPBonus; equippedItemManaBonus += item.ManaBonus; } // Apply HP int hp = 30 + player.ConstitutionModifier * 5; hp += _perk.GetPCPerkLevel(player, PerkType.Health) * 5; hp += equippedItemHPBonus; if (pcEntity.BackgroundID == (int)BackgroundType.Knight) { hp += 10; } if (hp > 255) { hp = 255; } if (hp < 20) { hp = 20; } _nwnxCreature.SetMaxHitPointsByLevel(player, 1, hp); if (player.CurrentHP > player.MaxHP) { int amount = player.CurrentHP - player.MaxHP; Effect damage = _.EffectDamage(amount); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, player.Object); } // Apply Mana int mana = 20; mana += (player.IntelligenceModifier + player.WisdomModifier + player.CharismaModifier) * 5; mana += _perk.GetPCPerkLevel(player, PerkType.Mana) * 5; mana += equippedItemManaBonus; if (pcEntity.BackgroundID == (int)BackgroundType.Wizard || pcEntity.BackgroundID == (int)BackgroundType.Cleric) { mana += 10; } if (mana < 0) { mana = 0; } pcEntity.MaxMana = mana; _db.SaveChanges(); }