protected static void Recalculate(NWGameObject player) { var playerID = GetGlobalID(player); var playerEntity = PlayerRepo.Get(playerID); var @class = GetClassByPosition(ClassPosition.First, player); var level = GetLevelByPosition(ClassPosition.First, player); var jobDefinition = JobRegistry.Get(@class); // Retrieve the rating chart for the stat, then retrieve the value for that stat at this player's level. var hp = RatingRegistry.Get(jobDefinition.HPRating).Get(RatingStat.HP, level); var mp = RatingRegistry.Get(jobDefinition.MPRating).Get(RatingStat.MP, level); var ac = RatingRegistry.Get(jobDefinition.ACRating).Get(RatingStat.AC, level); var bab = RatingRegistry.Get(jobDefinition.BABRating).Get(RatingStat.BAB, level); var str = RatingRegistry.Get(jobDefinition.STRRating).Get(RatingStat.STR, level); var dex = RatingRegistry.Get(jobDefinition.DEXRating).Get(RatingStat.DEX, level); var con = RatingRegistry.Get(jobDefinition.CONRating).Get(RatingStat.CON, level); var wis = RatingRegistry.Get(jobDefinition.WISRating).Get(RatingStat.WIS, level); var @int = RatingRegistry.Get(jobDefinition.INTRating).Get(RatingStat.INT, level); var cha = RatingRegistry.Get(jobDefinition.CHARating).Get(RatingStat.CHA, level); // Now apply the changes to the player. ApplyHP(player, hp); playerEntity.MaxHP = hp; playerEntity.MaxMP = mp; playerEntity.HP = hp; playerEntity.MP = mp; NWNXCreature.SetBaseAC(player, ac); NWNXCreature.SetBaseAttackBonus(player, bab); NWNXCreature.SetRawAbilityScore(player, Ability.Strength, str); NWNXCreature.SetRawAbilityScore(player, Ability.Dexterity, dex); NWNXCreature.SetRawAbilityScore(player, Ability.Constitution, con); NWNXCreature.SetRawAbilityScore(player, Ability.Wisdom, wis); NWNXCreature.SetRawAbilityScore(player, Ability.Intelligence, @int); NWNXCreature.SetRawAbilityScore(player, Ability.Charisma, cha); PlayerRepo.Set(playerEntity); DelayCommand(1.0f, () => NWNXPlayer.UpdateCharacterSheet(player)); }
public static void ApplyStatChanges(NWPlayer player, NWItem ignoreItem, bool isInitialization = false) { if (!player.IsPlayer) { return; } if (!player.IsInitializedAsPlayer) { return; } if (player.GetLocalInt("IS_SHIP") == 1) { return; } // Don't fire for ammo as it reapplies bonuses **just** removed from blasters. if (ignoreItem != null && (ignoreItem.BaseItemType == BASE_ITEM_BOLT || ignoreItem.BaseItemType == BASE_ITEM_ARROW || ignoreItem.BaseItemType == BASE_ITEM_BULLET)) { return; } Player pcEntity = DataService.Get <Player>(player.GlobalID); List <PCSkill> skills = DataService.Where <PCSkill>(x => x.PlayerID == player.GlobalID && x.Rank > 0).ToList(); EffectiveItemStats itemBonuses = GetPlayerItemEffectiveStats(player, ignoreItem); float strBonus = 0.0f; float dexBonus = 0.0f; float conBonus = 0.0f; float intBonus = 0.0f; float wisBonus = 0.0f; float chaBonus = 0.0f; using (new Profiler("PlayerStatService::ApplyStatChanges::AttributeApplication")) { foreach (PCSkill pcSkill in skills) { Skill skill = DataService.Get <Skill>(pcSkill.SkillID); 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; } // Apply item bonuses strBonus += itemBonuses.Strength; dexBonus += itemBonuses.Dexterity; conBonus += itemBonuses.Constitution; wisBonus += itemBonuses.Wisdom; intBonus += itemBonuses.Intelligence; chaBonus += itemBonuses.Charisma; // Check final caps if (strBonus > 100) { strBonus = 100; } if (dexBonus > 100) { dexBonus = 100; } if (conBonus > 100) { conBonus = 100; } if (intBonus > 100) { intBonus = 100; } if (wisBonus > 100) { wisBonus = 100; } if (chaBonus > 100) { chaBonus = 100; } // 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 using (new Profiler("PlayerStatService::ApplyStatChanges::CalcAC")) { int ac = EffectiveArmorClass(itemBonuses, player); NWNXCreature.SetBaseAC(player, ac); } // Apply BAB using (new Profiler("PlayerStatService::ApplyStatChanges::CalcBAB")) { int bab = CalculateBAB(player, ignoreItem, itemBonuses); NWNXCreature.SetBaseAttackBonus(player, bab); } // Apply HP using (new Profiler("PlayerStatService::ApplyStatChanges::CalcHP")) { int hp = EffectiveMaxHitPoints(player, itemBonuses); for (int level = 1; level <= 5; level++) { hp--; NWNXCreature.SetMaxHitPointsByLevel(player, level, 1); } for (int level = 1; level <= 5; level++) { if (hp > 255) // Levels can only contain a max of 255 HP { NWNXCreature.SetMaxHitPointsByLevel(player, level, 255); hp = hp - 254; } else // Remaining value gets set to the level. (<255 hp) { NWNXCreature.SetMaxHitPointsByLevel(player, level, hp + 1); break; } } } if (player.CurrentHP > player.MaxHP) { int amount = player.CurrentHP - player.MaxHP; Effect damage = _.EffectDamage(amount); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, player.Object); } // Apply FP using (new Profiler("PlayerStatService::ApplyStatChanges::CalcFP")) { pcEntity.MaxFP = EffectiveMaxFP(player, itemBonuses); if (isInitialization) { pcEntity.CurrentFP = pcEntity.MaxFP; } DataService.SubmitDataChange(pcEntity, DatabaseActionType.Update); } }
public static void ApplyStatChanges(NWPlayer player, NWItem ignoreItem, bool isInitialization = false) { if (!player.IsPlayer) { return; } if (!player.IsInitializedAsPlayer) { return; } if (player.GetLocalInt("IS_SHIP") == 1) { return; } // Don't fire for ammo as it reapplies bonuses we **just** removed from blasters. if (ignoreItem != null && (ignoreItem.BaseItemType == BaseItem.Bolt || ignoreItem.BaseItemType == BaseItem.Arrow || ignoreItem.BaseItemType == BaseItem.Bullet)) { return; } Player pcEntity = DataService.Player.GetByID(player.GlobalID); List <PCSkill> skills = DataService.PCSkill .GetAllByPlayerID(player.GlobalID) .Where(x => x.Rank > 0).ToList(); EffectiveItemStats itemBonuses = GetPlayerItemEffectiveStats(player, ignoreItem); 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 = DataService.Skill.GetByID(pcSkill.SkillID); 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; } // Apply item bonuses strBonus += itemBonuses.Strength; dexBonus += itemBonuses.Dexterity; conBonus += itemBonuses.Constitution; wisBonus += itemBonuses.Wisdom; intBonus += itemBonuses.Intelligence; chaBonus += itemBonuses.Charisma; // Check final caps if (strBonus > 55) { strBonus = 55; } if (dexBonus > 55) { dexBonus = 55; } if (conBonus > 55) { conBonus = 55; } if (intBonus > 55) { intBonus = 55; } if (wisBonus > 55) { wisBonus = 55; } if (chaBonus > 55) { chaBonus = 55; } // Apply attributes NWNXCreature.SetRawAbilityScore(player, AbilityType.Strength, (int)strBonus + pcEntity.STRBase); NWNXCreature.SetRawAbilityScore(player, AbilityType.Dexterity, (int)dexBonus + pcEntity.DEXBase); NWNXCreature.SetRawAbilityScore(player, AbilityType.Constitution, (int)conBonus + pcEntity.CONBase); NWNXCreature.SetRawAbilityScore(player, AbilityType.Intelligence, (int)intBonus + pcEntity.INTBase); NWNXCreature.SetRawAbilityScore(player, AbilityType.Wisdom, (int)wisBonus + pcEntity.WISBase); NWNXCreature.SetRawAbilityScore(player, AbilityType.Charisma, (int)chaBonus + pcEntity.CHABase); // Apply AC int ac = EffectiveArmorClass(player, ignoreItem, itemBonuses); NWNXCreature.SetBaseAC(player, ac); // Apply BAB int bab = CalculateBAB(player, ignoreItem, itemBonuses); NWNXCreature.SetBaseAttackBonus(player, bab); // Apply HP int hp = EffectiveMaxHitPoints(player, itemBonuses); for (int level = 1; level <= 5; level++) { hp--; NWNXCreature.SetMaxHitPointsByLevel(player, level, 1); } for (int level = 1; level <= 5; level++) { if (hp >= 255) // Levels can only contain a max of 255 HP { NWNXCreature.SetMaxHitPointsByLevel(player, level, 255); hp = hp - 254; } else // Remaining value gets set to the level. (<255 hp) { NWNXCreature.SetMaxHitPointsByLevel(player, level, hp + 1); break; } } if (player.CurrentHP > player.MaxHP) { int amount = player.CurrentHP - player.MaxHP; var damage = _.EffectDamage(amount); _.ApplyEffectToObject(DurationType.Instant, damage, player.Object); } // Apply FP pcEntity.MaxFP = EffectiveMaxFP(player, itemBonuses); if (isInitialization) { pcEntity.CurrentFP = pcEntity.MaxFP; } DataService.SubmitDataChange(pcEntity, DatabaseActionType.Update); // Attempt a refresh of the character sheet UI in a second. _.DelayCommand(1.0f, () => { NWNXPlayer.UpdateCharacterSheet(player); }); }
public static void InitializePlayer(NWPlayer player) { if (player == null) { throw new ArgumentNullException(nameof(player)); } if (!player.IsPlayer) { return; } // Player is initialized but not in the DB. Wipe the tag and rerun them through initialization - something went wrong before. if (player.IsInitializedAsPlayer) { if (!DataService.Player.ExistsByID(player.GlobalID)) { SetTag(player, string.Empty); } } if (!player.IsInitializedAsPlayer) { player.DestroyAllInventoryItems(); player.InitializePlayer(); AssignCommand(player, () => _.TakeGoldFromCreature(GetGold(player), player, true)); DelayCommand(0.5f, () => { GiveGoldToCreature(player, 100); }); // Capture original stats before we level up the player. int str = NWNXCreature.GetRawAbilityScore(player, AbilityType.Strength); int con = NWNXCreature.GetRawAbilityScore(player, AbilityType.Constitution); int dex = NWNXCreature.GetRawAbilityScore(player, AbilityType.Dexterity); int @int = NWNXCreature.GetRawAbilityScore(player, AbilityType.Intelligence); int wis = NWNXCreature.GetRawAbilityScore(player, AbilityType.Wisdom); int cha = NWNXCreature.GetRawAbilityScore(player, AbilityType.Charisma); // Take player to level 5 in NWN levels so that we have access to more HP slots GiveXPToCreature(player, 10000); for (int level = 1; level <= 5; level++) { LevelUpHenchman(player, player.Class1); } // Set stats back to how they were on entry. NWNXCreature.SetRawAbilityScore(player, AbilityType.Strength, str); NWNXCreature.SetRawAbilityScore(player, AbilityType.Constitution, con); NWNXCreature.SetRawAbilityScore(player, AbilityType.Dexterity, dex); NWNXCreature.SetRawAbilityScore(player, AbilityType.Intelligence, @int); NWNXCreature.SetRawAbilityScore(player, AbilityType.Wisdom, wis); NWNXCreature.SetRawAbilityScore(player, AbilityType.Charisma, cha); NWItem knife = (CreateItemOnObject("survival_knife", player)); knife.Name = player.Name + "'s Survival Knife"; knife.IsCursed = true; DurabilityService.SetMaxDurability(knife, 5); DurabilityService.SetDurability(knife, 5); NWItem book = (CreateItemOnObject("player_guide", player)); book.Name = player.Name + "'s Player Guide"; book.IsCursed = true; NWItem dyeKit = (CreateItemOnObject("tk_omnidye", player)); dyeKit.IsCursed = true; int numberOfFeats = NWNXCreature.GetFeatCount(player); for (int currentFeat = numberOfFeats; currentFeat >= 0; currentFeat--) { NWNXCreature.RemoveFeat(player, NWNXCreature.GetFeatByIndex(player, currentFeat - 1)); } NWNXCreature.AddFeatByLevel(player, Feat.ArmorProficiencyLight, 1); NWNXCreature.AddFeatByLevel(player, Feat.ArmorProficiencyMedium, 1); NWNXCreature.AddFeatByLevel(player, Feat.ArmorProficiencyHeavy, 1); NWNXCreature.AddFeatByLevel(player, Feat.ShieldProficiency, 1); NWNXCreature.AddFeatByLevel(player, Feat.WeaponProficiencyExotic, 1); NWNXCreature.AddFeatByLevel(player, Feat.WeaponProficiencyMartial, 1); NWNXCreature.AddFeatByLevel(player, Feat.WeaponProficiencySimple, 1); NWNXCreature.AddFeatByLevel(player, Feat.UncannyDodge1, 1); NWNXCreature.AddFeatByLevel(player, Feat.StructureManagementTool, 1); NWNXCreature.AddFeatByLevel(player, Feat.OpenRestMenu, 1); NWNXCreature.AddFeatByLevel(player, Feat.RenameCraftedItem, 1); NWNXCreature.AddFeatByLevel(player, Feat.ChatCommandTargeter, 1); foreach (var skillType in Enum.GetValues(typeof(Skill))) { var skill = (Skill)skillType; if (skill == Skill.Invalid || skill == Skill.AllSkills) { continue; } NWNXCreature.SetSkillRank(player, skill, 0); } SetFortitudeSavingThrow(player, 0); SetReflexSavingThrow(player, 0); SetWillSavingThrow(player, 0); var classType = GetClassByPosition(1, player); for (int index = 0; index <= 255; index++) { NWNXCreature.RemoveKnownSpell(player, classType, 0, index); } Player entity = CreateDBPCEntity(player); DataService.SubmitDataChange(entity, DatabaseActionType.Insert); var skills = DataService.Skill.GetAll(); foreach (var skill in skills) { var pcSkill = new PCSkill { IsLocked = false, SkillID = skill.ID, PlayerID = entity.ID, Rank = 0, XP = 0 }; DataService.SubmitDataChange(pcSkill, DatabaseActionType.Insert); } RaceService.ApplyDefaultAppearance(player); NWNXCreature.SetAlignmentLawChaos(player, 50); NWNXCreature.SetAlignmentGoodEvil(player, 50); BackgroundService.ApplyBackgroundBonuses(player); PlayerStatService.ApplyStatChanges(player, null, true); LanguageService.InitializePlayerLanguages(player); DelayCommand(1.0f, () => ApplyEffectToObject(DurationType.Instant, EffectHeal(999), player)); InitializeHotBar(player); } }
public static void InitializePlayer(NWPlayer player) { if (player == null) { throw new ArgumentNullException(nameof(player)); } if (player.Object == null) { throw new ArgumentNullException(nameof(player.Object)); } if (!player.IsPlayer) { return; } // Player is initialized but not in the DB. Wipe the tag and rerun them through initialization - something went wrong before. if (player.IsInitializedAsPlayer) { if (DataService.GetAll <Player>().SingleOrDefault(x => x.ID == player.GlobalID) == null) { _.SetTag(player, string.Empty); } } if (!player.IsInitializedAsPlayer) { player.DestroyAllInventoryItems(); player.InitializePlayer(); _.AssignCommand(player, () => _.TakeGoldFromCreature(_.GetGold(player), player, 1)); _.DelayCommand(0.5f, () => { _.GiveGoldToCreature(player, 100); }); // Capture original stats before we level up the player. int str = NWNXCreature.GetRawAbilityScore(player, ABILITY_STRENGTH); int con = NWNXCreature.GetRawAbilityScore(player, ABILITY_CONSTITUTION); int dex = NWNXCreature.GetRawAbilityScore(player, ABILITY_DEXTERITY); int @int = NWNXCreature.GetRawAbilityScore(player, ABILITY_INTELLIGENCE); int wis = NWNXCreature.GetRawAbilityScore(player, ABILITY_WISDOM); int cha = NWNXCreature.GetRawAbilityScore(player, ABILITY_CHARISMA); // Take player to level 5 in NWN levels so that we have access to more HP slots _.GiveXPToCreature(player, 10000); for (int level = 1; level <= 5; level++) { _.LevelUpHenchman(player, player.Class1); } // Set stats back to how they were on entry. NWNXCreature.SetRawAbilityScore(player, ABILITY_STRENGTH, str); NWNXCreature.SetRawAbilityScore(player, ABILITY_CONSTITUTION, con); NWNXCreature.SetRawAbilityScore(player, ABILITY_DEXTERITY, dex); NWNXCreature.SetRawAbilityScore(player, ABILITY_INTELLIGENCE, @int); NWNXCreature.SetRawAbilityScore(player, ABILITY_WISDOM, wis); NWNXCreature.SetRawAbilityScore(player, ABILITY_CHARISMA, cha); NWItem knife = (_.CreateItemOnObject("survival_knife", player)); knife.Name = player.Name + "'s Survival Knife"; knife.IsCursed = true; DurabilityService.SetMaxDurability(knife, 5); DurabilityService.SetDurability(knife, 5); NWItem book = (_.CreateItemOnObject("player_guide", player)); book.Name = player.Name + "'s Player Guide"; book.IsCursed = true; NWItem dyeKit = (_.CreateItemOnObject("tk_omnidye", player)); dyeKit.IsCursed = true; int numberOfFeats = NWNXCreature.GetFeatCount(player); for (int currentFeat = numberOfFeats; currentFeat >= 0; currentFeat--) { NWNXCreature.RemoveFeat(player, NWNXCreature.GetFeatByIndex(player, currentFeat - 1)); } NWNXCreature.AddFeatByLevel(player, FEAT_ARMOR_PROFICIENCY_LIGHT, 1); NWNXCreature.AddFeatByLevel(player, FEAT_ARMOR_PROFICIENCY_MEDIUM, 1); NWNXCreature.AddFeatByLevel(player, FEAT_ARMOR_PROFICIENCY_HEAVY, 1); NWNXCreature.AddFeatByLevel(player, FEAT_SHIELD_PROFICIENCY, 1); NWNXCreature.AddFeatByLevel(player, FEAT_WEAPON_PROFICIENCY_EXOTIC, 1); NWNXCreature.AddFeatByLevel(player, FEAT_WEAPON_PROFICIENCY_MARTIAL, 1); NWNXCreature.AddFeatByLevel(player, FEAT_WEAPON_PROFICIENCY_SIMPLE, 1); NWNXCreature.AddFeatByLevel(player, FEAT_UNCANNY_DODGE_1, 1); NWNXCreature.AddFeatByLevel(player, (int)CustomFeatType.StructureManagementTool, 1); NWNXCreature.AddFeatByLevel(player, (int)CustomFeatType.OpenRestMenu, 1); NWNXCreature.AddFeatByLevel(player, (int)CustomFeatType.RenameCraftedItem, 1); NWNXCreature.AddFeatByLevel(player, (int)CustomFeatType.ChatCommandTargeter, 1); for (int iCurSkill = 1; iCurSkill <= 27; iCurSkill++) { NWNXCreature.SetSkillRank(player, iCurSkill - 1, 0); } _.SetFortitudeSavingThrow(player, 0); _.SetReflexSavingThrow(player, 0); _.SetWillSavingThrow(player, 0); int classID = _.GetClassByPosition(1, player); for (int index = 0; index <= 255; index++) { NWNXCreature.RemoveKnownSpell(player, classID, 0, index); } Player entity = CreateDBPCEntity(player); DataService.SubmitDataChange(entity, DatabaseActionType.Insert); var skills = DataService.GetAll <Skill>(); foreach (var skill in skills) { var pcSkill = new PCSkill { IsLocked = false, SkillID = skill.ID, PlayerID = entity.ID, Rank = 0, XP = 0 }; DataService.SubmitDataChange(pcSkill, DatabaseActionType.Insert); } RaceService.ApplyDefaultAppearance(player); NWNXCreature.SetAlignmentLawChaos(player, 50); NWNXCreature.SetAlignmentGoodEvil(player, 50); BackgroundService.ApplyBackgroundBonuses(player); PlayerStatService.ApplyStatChanges(player, null, true); LanguageService.InitializePlayerLanguages(player); _.DelayCommand(1.0f, () => _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(999), player)); InitializeHotBar(player); } }