public bool Run(params object[] args) { NWPlaceable resource = NWPlaceable.Wrap(Object.OBJECT_SELF); NWPlayer oPC = NWPlayer.Wrap(_.GetLastDamager(resource.Object)); if (oPC.GetLocalInt("NOT_USING_CORRECT_WEAPON") == 1) { oPC.DeleteLocalInt("NOT_USING_CORRECT_WEAPON"); return(true); } PlayerCharacter pcEntity = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID); NWItem oWeapon = NWItem.Wrap(_.GetLastWeaponUsed(oPC.Object)); Location location = oPC.Location; string resourceItemResref = resource.GetLocalString("RESOURCE_RESREF"); int activityID = resource.GetLocalInt("RESOURCE_ACTIVITY"); string resourceName = resource.GetLocalString("RESOURCE_NAME"); int resourceCount = resource.GetLocalInt("RESOURCE_COUNT"); int difficultyRating = resource.GetLocalInt("RESOURCE_DIFFICULTY_RATING"); int weaponChanceBonus; SkillType skillType; int perkChanceBonus; int secondResourceChance; int durabilityChanceReduction = 0; int hasteChance; int lucky = _perk.GetPCPerkLevel(oPC, PerkType.Lucky); bool hasBaggerPerk; if (activityID == 1) // 1 = Logging { weaponChanceBonus = oWeapon.LoggingBonus; if (weaponChanceBonus > 0) { weaponChanceBonus += _perk.GetPCPerkLevel(oPC, PerkType.LoggingAxeExpert) * 5; durabilityChanceReduction = _perk.GetPCPerkLevel(oPC, PerkType.LoggingAxeExpert) * 10 + lucky; } skillType = SkillType.Logging; perkChanceBonus = _perk.GetPCPerkLevel(oPC, PerkType.Lumberjack) * 5 + lucky; secondResourceChance = _perk.GetPCPerkLevel(oPC, PerkType.PrecisionLogging) * 10; hasteChance = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyLogger) * 10 + lucky; if (pcEntity.BackgroundID == (int)BackgroundType.Lumberjack) { hasteChance += 10; } hasBaggerPerk = _perk.GetPCPerkLevel(oPC, PerkType.WoodBagger) > 0; } else if (activityID == 2) // Mining { weaponChanceBonus = oWeapon.MiningBonus; if (weaponChanceBonus > 0) { weaponChanceBonus += _perk.GetPCPerkLevel(oPC, PerkType.PickaxeExpert) * 5; durabilityChanceReduction = _perk.GetPCPerkLevel(oPC, PerkType.PickaxeExpert) * 10 + lucky; } skillType = SkillType.Mining; perkChanceBonus = _perk.GetPCPerkLevel(oPC, PerkType.Miner) * 5 + lucky; secondResourceChance = _perk.GetPCPerkLevel(oPC, PerkType.PrecisionMining) * 10; hasteChance = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyMiner) * 10 + lucky; if (pcEntity.BackgroundID == (int)BackgroundType.Miner) { hasteChance += 10; } hasBaggerPerk = _perk.GetPCPerkLevel(oPC, PerkType.OreBagger) > 0; } else { return(false); } PCSkill skill = _skill.GetPCSkillByID(oPC.GlobalID, (int)skillType); int durabilityLossChance = 100 - durabilityChanceReduction; if (_random.Random(100) <= durabilityLossChance) { _durability.RunItemDecay(oPC, oWeapon); } int baseChance = 10; int chance = baseChance + weaponChanceBonus; chance += CalculateSuccessChanceDeltaModifier(difficultyRating, skill.Rank); chance += perkChanceBonus; bool givePityItem = false; if (chance > 0) { if (_random.Random(100) + 1 <= hasteChance) { _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectHaste(), oPC.Object, 8.0f); } // Give an item if the player hasn't gotten anything after 6-8 attempts. int attemptFailureCount = oPC.GetLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT") + 1; NWObject failureResource = NWObject.Wrap(oPC.GetLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT")); if (!failureResource.IsValid || !Equals(failureResource, resource)) { failureResource = resource; attemptFailureCount = 1; } int pityItemChance = 0; if (attemptFailureCount == 6) { pityItemChance = 60; } else if (attemptFailureCount == 7) { pityItemChance = 80; } else if (attemptFailureCount >= 8) { pityItemChance = 100; } if (_random.Random(100) + 1 <= pityItemChance) { givePityItem = true; attemptFailureCount = 0; } oPC.SetLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT", attemptFailureCount); oPC.SetLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT", failureResource.Object); } if (chance <= 0) { oPC.FloatingText("You do not have enough skill to harvest this resource..."); } else if (_random.Random(100) <= chance || givePityItem) { if (hasBaggerPerk) { _.CreateItemOnObject(resourceItemResref, oPC.Object); } else { _.CreateObject(OBJECT_TYPE_ITEM, resourceItemResref, location); } oPC.FloatingText("You break off some " + resourceName + "."); resource.SetLocalInt("RESOURCE_COUNT", --resourceCount); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(10000), resource.Object); if (_random.Random(100) + 1 <= secondResourceChance) { oPC.FloatingText("You break off a second piece."); if (hasBaggerPerk) { _.CreateItemOnObject(resourceItemResref, oPC.Object); } else { _.CreateObject(OBJECT_TYPE_ITEM, resourceItemResref, location); } } float deltaModifier = CalculateXPDeltaModifier(difficultyRating, skill.Rank); float baseXP = (100 + _random.Random(20)) * deltaModifier; int xp = (int)_skill.CalculateSkillAdjustedXP(baseXP, oWeapon.RecommendedLevel, skill.Rank); _skill.GiveSkillXP(oPC, skillType, xp); oPC.DeleteLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT"); oPC.DeleteLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT"); } if (resourceCount <= 0) { SpawnSeed(resource, oPC); NWObject prop = NWObject.Wrap(resource.GetLocalObject("RESOURCE_PROP_OBJ")); if (prop.IsValid) { prop.Destroy(); } resource.Destroy(); } return(true); }
public void OnRemoved(NWPlayer oPC) { }
public bool CanCastSpell(NWPlayer oPC, NWObject oTarget) { return(false); }
public float CastingTime(NWPlayer oPC, float baseCastingTime) { return(baseCastingTime); }
public void OnImpact(NWPlayer oPC, NWObject oTarget) { }
public void OnImpact(NWPlayer player, NWObject target, int perkLevel) { }
public string Description(NWPlayer player, NWItem target, params string[] args) { int value = Convert.ToInt32(args[0]); return("Harvesting +" + value); }
public static void CalculateEffectiveStats(NWPlayer player, NWItem item) { if (item == null || !item.IsValid || !player.IsPlayer || player.IsDMPossessed || player.IsDM || !player.IsInitializedAsPlayer) { return; } // Calculating effective stats can be expensive, so we cache it on the item. SkillType skill; if (item.BaseItemType == BaseItem.Amulet || item.BaseItemType == BaseItem.Ring) { var forceArmor = SkillService.GetPCSkill(player, (int)SkillType.ForceArmor); var lightArmor = SkillService.GetPCSkill(player, (int)SkillType.LightArmor); var heavyArmor = SkillService.GetPCSkill(player, (int)SkillType.HeavyArmor); var highest = forceArmor.Rank; skill = SkillType.ForceArmor; if (lightArmor.Rank > highest) { highest = lightArmor.Rank; skill = SkillType.LightArmor; } if (heavyArmor.Rank > highest) { skill = SkillType.HeavyArmor; } } else { skill = ItemService.GetSkillTypeForItem(item); } var rank = DataService.PCSkill.GetByPlayerIDAndSkillID(player.GlobalID, (int)skill).Rank; using (new Profiler("PlayerStatService::ApplyStatChanges::GetPlayerItemEffectiveStats::ItemLoop::CalculateEffectiveStats")) { // Only scale cooldown recovery if it's a bonus. Penalties remain regardless of skill level difference. item.SetLocalInt("STAT_EFFECTIVE_LEVEL_COOLDOWN_RECOVERY", item.CooldownRecovery > 0 ? CalculateAdjustedValue(item.CooldownRecovery, item.RecommendedLevel, rank, 1) : item.CooldownRecovery); item.SetLocalFloat("STAT_EFFECTIVE_LEVEL_ENMITY_RATE", CalculateAdjustedValue(0.01f * item.EnmityRate, item.RecommendedLevel, rank, 0.00f)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_LUCK_BONUS", CalculateAdjustedValue(item.LuckBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_MEDITATE_BONUS", CalculateAdjustedValue(item.MeditateBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_REST_BONUS", CalculateAdjustedValue(item.RestBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_MEDICINE_BONUS", CalculateAdjustedValue(item.MedicineBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_HP_REGEN_BONUS", CalculateAdjustedValue(item.HPRegenBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_FP_REGEN_BONUS", CalculateAdjustedValue(item.FPRegenBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_WEAPONSMITH_BONUS", CalculateAdjustedValue(item.CraftBonusWeaponsmith, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_COOKING_BONUS", CalculateAdjustedValue(item.CraftBonusCooking, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_ENGINEERING_BONUS", CalculateAdjustedValue(item.CraftBonusEngineering, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_FABRICATION_BONUS", CalculateAdjustedValue(item.CraftBonusFabrication, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_ARMORSMITH_BONUS", CalculateAdjustedValue(item.CraftBonusArmorsmith, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_HARVESTING_BONUS", CalculateAdjustedValue(item.HarvestingBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_PILOTING_BONUS", CalculateAdjustedValue(item.PilotingBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_SCAVENGING_BONUS", CalculateAdjustedValue(item.ScavengingBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_SNEAK_ATTACK_BONUS", CalculateAdjustedValue(item.SneakAttackBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_STRENGTH_BONUS", CalculateAdjustedValue(item.StrengthBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_DEXTERITY_BONUS", CalculateAdjustedValue(item.DexterityBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_CONSTITUTION_BONUS", CalculateAdjustedValue(item.ConstitutionBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_WISDOM_BONUS", CalculateAdjustedValue(item.WisdomBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_INTELLIGENCE_BONUS", CalculateAdjustedValue(item.IntelligenceBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_CHARISMA_BONUS", CalculateAdjustedValue(item.CharismaBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_HP_BONUS", CalculateAdjustedValue(item.HPBonus, item.RecommendedLevel, rank, 0)); item.SetLocalInt("STAT_EFFECTIVE_LEVEL_FP_BONUS", CalculateAdjustedValue(item.FPBonus, item.RecommendedLevel, rank, 0)); } }
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) || ItemService.ShieldBaseItemTypes.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 if (item.CustomItemType == CustomItemType.MartialArtWeapon) { skillRankToUse = martialRank; } else { continue; } int itemAC = item.CustomAC; itemAC = CalculateAdjustedValue(itemAC, item.RecommendedLevel, skillRankToUse, 0); 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); }
public void OnItemUnequipped(NWPlayer oPC, NWItem oItem) { ApplyFeatChanges(oPC, oItem); }
public bool Run(params object[] args) { int nodeType = (int)args[0]; int nodeID = (int)args[1]; NWPlayer player = NWPlayer.Wrap(_.GetPCSpeaker()); PlayerDialog dialog = _dialog.LoadPlayerDialog(player.GlobalID); DialogPage page = dialog.CurrentPage; int currentSelectionNumber = nodeID + 1; bool displayNode = false; string newNodeText = string.Empty; int dialogOffset = (_dialog.NumberOfResponsesPerPage + 1) * (dialog.DialogNumber - 1); if (currentSelectionNumber == _dialog.NumberOfResponsesPerPage + 1) // Next page { int displayCount = page.NumberOfResponses - (_dialog.NumberOfResponsesPerPage * dialog.PageOffset); if (displayCount > _dialog.NumberOfResponsesPerPage) { displayNode = true; } } else if (currentSelectionNumber == _dialog.NumberOfResponsesPerPage + 2) // Previous Page { if (dialog.PageOffset > 0) { displayNode = true; } } else if (nodeType == 2) { int responseID = (dialog.PageOffset * _dialog.NumberOfResponsesPerPage) + nodeID; if (responseID + 1 <= page.NumberOfResponses) { DialogResponse response = page.Responses[responseID]; if (response != null) { newNodeText = response.Text; displayNode = response.IsActive; } } } else if (nodeType == 1) { IConversation convo = App.ResolveByInterface <IConversation>("Conversation." + dialog.ActiveDialogName); if (player.GetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN") != 1) { convo.Initialize(); player.SetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN", 1); } if (dialog.IsEnding) { convo.EndDialog(); _dialog.RemovePlayerDialog(player.GlobalID); player.DeleteLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN"); return(false); } page = dialog.CurrentPage; newNodeText = page.Header; _.SetCustomToken(90000 + dialogOffset, newNodeText); return(true); } _.SetCustomToken(90001 + nodeID + dialogOffset, newNodeText); return(displayNode); }
public void OnItemEquipped(NWPlayer oPC, NWItem oItem) { ApplyFeatChanges(oPC, null); }
public void OnRemoved(NWPlayer oPC) { _nwnxCreature.RemoveFeat(oPC, FEAT_DODGE); }
public void OnPurchased(NWPlayer oPC, int newLevel) { ApplyFeatChanges(oPC, null); }
public static void InitializePlayerLanguages(NWPlayer player) { RacialType race = (RacialType)player.RacialType; BackgroundType background = (BackgroundType)player.Class1; var languages = new List <SkillType>(new[] { SkillType.Basic }); switch (race) { case RacialType.Bothan: languages.Add(SkillType.Bothese); break; case RacialType.Chiss: languages.Add(SkillType.Cheunh); break; case RacialType.Zabrak: languages.Add(SkillType.Zabraki); break; case RacialType.Wookiee: languages.Add(SkillType.Shyriiwook); break; case RacialType.Twilek: languages.Add(SkillType.Twileki); break; case RacialType.Cathar: languages.Add(SkillType.Catharese); break; case RacialType.Trandoshan: languages.Add(SkillType.Dosh); break; case RacialType.Cyborg: languages.Add(SkillType.Droidspeak); break; case RacialType.Mirialan: languages.Add(SkillType.Mirialan); break; case RacialType.MonCalamari: languages.Add(SkillType.MonCalamarian); break; case RacialType.Ugnaught: languages.Add(SkillType.Ugnaught); break; case RacialType.Togruta: languages.Add(SkillType.Togruti); break; case RacialType.Rodian: languages.Add(SkillType.Rodese); break; case RacialType.KelDor: languages.Add(SkillType.KelDor); break; } switch (background) { case BackgroundType.Mandalorian: languages.Add(SkillType.Mandoa); break; } // Fair warning: We're short-circuiting the skill system here. // Languages don't level up like normal skills (no stat increases, SP, etc.) // So it's safe to simply set the player's rank in the skill to max. List <int> languageSkillIDs = languages.ConvertAll(x => (int)x); var pcSkills = DataService.PCSkill.GetAllByPlayerIDAndSkillIDs(player.GlobalID, languageSkillIDs).ToList(); foreach (var pcSkill in pcSkills) { var skill = DataService.Skill.GetByID(pcSkill.SkillID); int maxRank = skill.MaxRank; int maxRankXP = SkillService.SkillXPRequirements[maxRank]; pcSkill.Rank = maxRank; pcSkill.XP = maxRankXP - 1; DataService.SubmitDataChange(pcSkill, 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 int FPCost(NWPlayer oPC, int baseFPCost) { return(baseFPCost); }
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 void OnCustomEnmityRule(NWPlayer oPC, int amount) { }
public override void Back(NWPlayer player, string beforeMovePage, string afterMovePage) { }
public int ManaCost(NWPlayer oPC, int baseManaCost) { return(baseManaCost); }
public bool Run(params object[] args) { NWPlaceable container = Object.OBJECT_SELF; NWObject owner = container.GetLocalObject("QUEST_OWNER"); NWPlayer player = _.GetLastDisturbed(); NWItem item = _.GetInventoryDisturbItem(); int disturbType = _.GetInventoryDisturbType(); string crafterPlayerID = item.GetLocalString("CRAFTER_PLAYER_ID"); Guid? crafterPlayerGUID = null; if (!string.IsNullOrWhiteSpace(crafterPlayerID)) { crafterPlayerGUID = new Guid(crafterPlayerID); } if (disturbType == INVENTORY_DISTURB_TYPE_ADDED) { int questID = container.GetLocalInt("QUEST_ID"); PCQuestStatus status = DataService.Single <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID); PCQuestItemProgress progress = DataService.SingleOrDefault <PCQuestItemProgress>(x => x.PCQuestStatusID == status.ID && x.Resref == item.Resref); DatabaseActionType action = DatabaseActionType.Update; if (progress == null) { _.CopyItem(item, player, TRUE); player.SendMessage(ColorTokenService.Red("That item is not required for this quest.")); } else if (progress.MustBeCraftedByPlayer && crafterPlayerGUID != player.GlobalID) { _.CopyItem(item, player, TRUE); player.SendMessage(ColorTokenService.Red("You may only submit items which you have personally created for this quest.")); } else { progress.Remaining--; if (progress.Remaining <= 0) { var progressCopy = progress; progress = DataService.Single <PCQuestItemProgress>(x => x.ID == progressCopy.ID); action = DatabaseActionType.Delete; } DataService.SubmitDataChange(progress, action); // Recalc the remaining items needed. int remainingCount = DataService.GetAll <PCQuestItemProgress>().Count(x => x.PCQuestStatusID == status.ID); if (remainingCount <= 0) { QuestService.AdvanceQuestState(player, owner, questID); } player.SendMessage("You need " + progress.Remaining + " " + item.Name + " for this quest."); } item.Destroy(); var questItemProgresses = DataService.Where <PCQuestItemProgress>(x => x.PCQuestStatusID == status.ID); if (!questItemProgresses.Any()) { string conversation = _.GetLocalString(owner, "CONVERSATION"); if (!string.IsNullOrWhiteSpace(conversation)) { DialogService.StartConversation(player, owner, conversation); } else { player.AssignCommand(() => { _.ActionStartConversation(owner, "", TRUE, FALSE); }); } } } return(true); }
public float CooldownTime(NWPlayer oPC, float baseCooldownTime) { return(baseCooldownTime); }
public string ValidateArguments(NWPlayer user, params string[] args) { return(string.Empty); }
public void OnPurchased(NWPlayer oPC, int newLevel) { }
public static void ApplyDefaultAppearance(NWPlayer player) { CustomRaceType race = (CustomRaceType)player.RacialType; int maleHead; int femaleHead; int skinColor; int hairColor; int gender = player.Gender; int appearance = APPEARANCE_TYPE_HUMAN; int maleNeck = 1; int maleTorso = 1; int malePelvis = 1; int maleRightBicep = 1; int maleRightForearm = 1; int maleRightHand = 1; int maleRightThigh = 1; int maleRightShin = 1; int maleRightFoot = 1; int maleLeftBicep = 1; int maleLeftForearm = 1; int maleLeftHand = 1; int maleLeftThigh = 1; int maleLeftShin = 1; int maleLeftFoot = 1; int femaleNeck = 1; int femaleTorso = 1; int femalePelvis = 1; int femaleRightBicep = 1; int femaleRightForearm = 1; int femaleRightHand = 1; int femaleRightThigh = 1; int femaleRightShin = 1; int femaleRightFoot = 1; int femaleLeftBicep = 1; int femaleLeftForearm = 1; int femaleLeftHand = 1; int femaleLeftThigh = 1; int femaleLeftShin = 1; int femaleLeftFoot = 1; switch (race) { case CustomRaceType.Human: skinColor = 2; hairColor = 0; maleHead = 1; femaleHead = 1; break; case CustomRaceType.Bothan: skinColor = 6; hairColor = 1; appearance = APPEARANCE_TYPE_ELF; maleHead = 40; femaleHead = 109; break; case CustomRaceType.Chiss: skinColor = 137; hairColor = 134; maleHead = 33; femaleHead = 191; break; case CustomRaceType.Zabrak: skinColor = 88; hairColor = 0; maleHead = 103; femaleHead = 120; break; case CustomRaceType.Twilek: skinColor = 52; hairColor = 0; maleHead = 115; femaleHead = 145; break; case CustomRaceType.Cyborg: skinColor = 2; hairColor = 0; maleHead = 168; femaleHead = 41; break; case CustomRaceType.Mirialan: skinColor = 38; hairColor = 3; maleHead = 20; femaleHead = 1; break; case CustomRaceType.Echani: skinColor = 164; hairColor = 16; maleHead = 182; femaleHead = 45; break; case CustomRaceType.Cathar: skinColor = 54; hairColor = 0; appearance = APPEARANCE_TYPE_HALF_ORC; maleHead = 27; femaleHead = 18; break; case CustomRaceType.Trandoshan: skinColor = 39; hairColor = 4; maleHead = 162; femaleHead = 135; maleNeck = 201; maleTorso = 201; malePelvis = 201; maleRightBicep = 201; maleRightForearm = 201; maleRightHand = 201; maleRightThigh = 201; maleRightShin = 201; maleRightFoot = 201; maleLeftBicep = 201; maleLeftForearm = 201; maleLeftHand = 201; maleLeftThigh = 201; maleLeftShin = 201; maleLeftFoot = 201; femaleNeck = 201; femaleTorso = 201; femalePelvis = 201; femaleRightBicep = 201; femaleRightForearm = 201; femaleRightHand = 201; femaleRightThigh = 201; femaleRightShin = 201; femaleRightFoot = 201; femaleLeftBicep = 201; femaleLeftForearm = 201; femaleLeftHand = 201; femaleLeftThigh = 201; femaleLeftShin = 201; femaleLeftFoot = 201; break; case CustomRaceType.Wookiee: appearance = APPEARANCE_TYPE_ELF; skinColor = 0; hairColor = 0; maleHead = 192; femaleHead = 110; maleNeck = 1; maleTorso = 208; malePelvis = 208; maleRightBicep = 208; maleRightForearm = 208; maleRightHand = 208; maleRightThigh = 208; maleRightShin = 208; maleRightFoot = 208; maleLeftBicep = 208; maleLeftForearm = 208; maleLeftHand = 208; maleLeftThigh = 208; maleLeftShin = 208; maleLeftFoot = 208; femaleNeck = 1; femaleTorso = 208; femalePelvis = 208; femaleRightBicep = 208; femaleRightForearm = 208; femaleRightHand = 208; femaleRightThigh = 208; femaleRightShin = 208; femaleRightFoot = 208; femaleLeftBicep = 208; femaleLeftForearm = 208; femaleLeftHand = 208; femaleLeftThigh = 208; femaleLeftShin = 208; femaleLeftFoot = 208; break; case CustomRaceType.MonCalamari: skinColor = 6; hairColor = 7; maleHead = 6; femaleHead = 6; maleNeck = 1; maleTorso = 204; malePelvis = 204; maleRightBicep = 204; maleRightForearm = 204; maleRightHand = 204; maleRightThigh = 204; maleRightShin = 204; maleRightFoot = 204; maleLeftBicep = 204; maleLeftForearm = 204; maleLeftHand = 204; maleLeftThigh = 204; maleLeftShin = 204; maleLeftFoot = 204; femaleNeck = 1; femaleTorso = 204; femalePelvis = 204; femaleRightBicep = 204; femaleRightForearm = 204; femaleRightHand = 204; femaleRightThigh = 204; femaleRightShin = 204; femaleRightFoot = 204; femaleLeftBicep = 204; femaleLeftForearm = 204; femaleLeftHand = 204; femaleLeftThigh = 204; femaleLeftShin = 204; femaleLeftFoot = 204; break; default: { _.BootPC(player, "You have selected an invalid race. This could be due to files in your override folder. Ensure these are removed from the folder and then try creating a new character. If you have any problems, visit our website at http://starwarsnwn.com"); return; } } _.SetCreatureAppearanceType(player, appearance); _.SetColor(player, COLOR_CHANNEL_SKIN, skinColor); _.SetColor(player, COLOR_CHANNEL_HAIR, hairColor); if (gender == GENDER_MALE) { _.SetCreatureBodyPart(CREATURE_PART_HEAD, maleHead, player); _.SetCreatureBodyPart(CREATURE_PART_NECK, maleNeck, player); _.SetCreatureBodyPart(CREATURE_PART_TORSO, maleTorso, player); _.SetCreatureBodyPart(CREATURE_PART_PELVIS, malePelvis, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_BICEP, maleRightBicep, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_FOREARM, maleRightForearm, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_HAND, maleRightHand, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_THIGH, maleRightThigh, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_SHIN, maleRightShin, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_FOOT, maleRightFoot, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_BICEP, maleLeftBicep, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_FOREARM, maleLeftForearm, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_HAND, maleLeftHand, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_THIGH, maleLeftThigh, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_SHIN, maleLeftShin, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_FOOT, maleLeftFoot, player); } else if (gender == GENDER_FEMALE) { _.SetCreatureBodyPart(CREATURE_PART_HEAD, femaleHead, player); _.SetCreatureBodyPart(CREATURE_PART_NECK, femaleNeck, player); _.SetCreatureBodyPart(CREATURE_PART_TORSO, femaleTorso, player); _.SetCreatureBodyPart(CREATURE_PART_PELVIS, femalePelvis, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_BICEP, femaleRightBicep, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_FOREARM, femaleRightForearm, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_HAND, femaleRightHand, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_THIGH, femaleRightThigh, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_SHIN, femaleRightShin, player); _.SetCreatureBodyPart(CREATURE_PART_RIGHT_FOOT, femaleRightFoot, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_BICEP, femaleLeftBicep, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_FOREARM, femaleLeftForearm, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_HAND, femaleLeftHand, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_THIGH, femaleLeftThigh, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_SHIN, femaleLeftShin, player); _.SetCreatureBodyPart(CREATURE_PART_LEFT_FOOT, femaleLeftFoot, player); } }
public void OnItemUnequipped(NWPlayer oPC, NWItem oItem) { }
public static string TranslateSnippetForListener(NWObject speaker, NWObject listener, SkillType language, string snippet) { Dictionary <SkillType, Type> map = new Dictionary <SkillType, Type> { { SkillType.Bothese, typeof(TranslatorBothese) }, { SkillType.Catharese, typeof(TranslatorCatharese) }, { SkillType.Cheunh, typeof(TranslatorCheunh) }, { SkillType.Dosh, typeof(TranslatorDosh) }, { SkillType.Droidspeak, typeof(TranslatorDroidspeak) }, { SkillType.Huttese, typeof(TranslatorHuttese) }, { SkillType.Mandoa, typeof(TranslatorMandoa) }, { SkillType.Shyriiwook, typeof(TranslatorShyriiwook) }, { SkillType.Twileki, typeof(TranslatorTwileki) }, { SkillType.Zabraki, typeof(TranslatorZabraki) }, { SkillType.Mirialan, typeof(TranslatorMirialan) }, { SkillType.MonCalamarian, typeof(TranslatorMonCalamarian) }, { SkillType.Ugnaught, typeof(TranslatorUgnaught) }, { SkillType.Togruti, typeof(TranslatorTogruti) }, { SkillType.Rodese, typeof(TranslatorRodese) }, { SkillType.KelDor, typeof(TranslatorKelDor) } }; Type type = typeof(TranslatorGeneric); map.TryGetValue(language, out type); ITranslator translator = (ITranslator)Activator.CreateInstance(type); if (speaker.IsPC && !speaker.IsDM) { // Get the rank and max rank for the speaker, and garble their English text based on it. NWPlayer speakerAsPlayer = speaker.Object; int speakerSkillRank = SkillService.GetPCSkillRank(speakerAsPlayer, language); int speakerSkillMaxRank = SkillService.GetSkill(language).MaxRank; if (speakerSkillRank != speakerSkillMaxRank) { int garbledChance = 100 - (int)(((float)speakerSkillRank / (float)speakerSkillMaxRank) * 100); string[] split = snippet.Split(' '); for (int i = 0; i < split.Length; ++i) { if (RandomService.Random(100) <= garbledChance) { split[i] = new string(split[i].ToCharArray().OrderBy(s => (RandomService.Random(2) % 2) == 0).ToArray()); } } snippet = split.Aggregate((a, b) => a + " " + b); } } if (!listener.IsPC || listener.IsDM) { // Short circuit for a DM or NPC - they will always understand the text. return(snippet); } // Let's grab the max rank for the listener skill, and then we roll for a successful translate based on that. NWPlayer listenerAsPlayer = listener.Object; int rank = SkillService.GetPCSkillRank(listenerAsPlayer, language); int maxRank = SkillService.GetSkill(language).MaxRank; // Check for the Comprehend Speech concentration ability. Player dbPlayer = DataService.Player.GetByID(listenerAsPlayer.GlobalID); bool grantSenseXP = false; if (dbPlayer.ActiveConcentrationPerkID == (int)PerkType.ComprehendSpeech) { int bonus = 5 * dbPlayer.ActiveConcentrationTier; rank += bonus; grantSenseXP = true; } // Ensure we don't go over the maximum. if (rank > maxRank) { rank = maxRank; } if (rank == maxRank || speaker == listener) { // Guaranteed success - return original. return(snippet); } string textAsForeignLanguage = translator.Translate(snippet); if (rank != 0) { int englishChance = (int)(((float)rank / (float)maxRank) * 100); string[] originalSplit = snippet.Split(' '); string[] foreignSplit = textAsForeignLanguage.Split(' '); StringBuilder endResult = new StringBuilder(); // WARNING: We're making the assumption that originalSplit.Length == foreignSplit.Length. // If this assumption changes, the below logic needs to change too. for (int i = 0; i < originalSplit.Length; ++i) { if (RandomService.Random(100) <= englishChance) { endResult.Append(originalSplit[i]); } else { endResult.Append(foreignSplit[i]); } endResult.Append(" "); } textAsForeignLanguage = endResult.ToString(); } long now = DateTime.Now.Ticks; int lastSkillUpLow = listenerAsPlayer.GetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_LOW"); int lastSkillUpHigh = listenerAsPlayer.GetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_HIGH"); long lastSkillUp = lastSkillUpHigh; lastSkillUp = (lastSkillUp << 32) | (uint)lastSkillUpLow; long differenceInSeconds = (now - lastSkillUp) / 10000000; if (differenceInSeconds / 60 >= 2) { int amount = Math.Max(10, Math.Min(150, snippet.Length) / 3); // Reward exp towards the language - we scale this with character count, maxing at 50 exp for 150 characters. SkillService.GiveSkillXP(listenerAsPlayer, language, amount); // Grant Sense XP if player is concentrating Comprehend Speech. if (grantSenseXP) { SkillService.GiveSkillXP(listenerAsPlayer, SkillType.ForceSense, amount * 10); } listenerAsPlayer.SetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_LOW", (int)(now & 0xFFFFFFFF)); listenerAsPlayer.SetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_HIGH", (int)((now >> 32) & 0xFFFFFFFF)); } return(textAsForeignLanguage); }
public string CannotCastSpellMessage(NWPlayer oPC, NWObject oTarget) { return(null); }
public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID) { }