public static string OnModuleExamine(string existingDescription, NWObject examinedObject) { if (examinedObject.ObjectType != ObjectType.Item) { return(existingDescription); } NWItem examinedItem = (examinedObject.Object); if (examinedItem.GetLocalFloat("DURABILITY_MAX") <= 0f) { return(existingDescription); } string description = ColorTokenService.Orange("Durability: "); float durability = GetDurability(examinedItem); if (durability <= 0.0f) { description += ColorTokenService.Red(Convert.ToString(durability)); } else { description += ColorTokenService.White(FormatDurability(durability)); } description += ColorTokenService.White(" / " + FormatDurability(GetMaxDurability(examinedItem))); return(existingDescription + "\n\n" + description); }
public static string OnModuleExamine(string existingDescription, NWPlayer examiner, NWObject examinedObject) { if (examinedObject.ObjectType != _.OBJECT_TYPE_ITEM) { return(existingDescription); } NWItem examinedItem = (examinedObject.Object); string description = string.Empty; ModSlots slot = GetModSlots(examinedItem); for (int red = 1; red <= slot.FilledRedSlots; red++) { description += ColorTokenService.Red("Red Slot #" + red + ": ") + examinedItem.GetLocalString("MOD_SLOT_RED_DESC_" + red) + "\n"; } for (int blue = 1; blue <= slot.FilledBlueSlots; blue++) { description += ColorTokenService.Red("Blue Slot #" + blue + ": ") + examinedItem.GetLocalString("MOD_SLOT_BLUE_DESC_" + blue) + "\n"; } for (int green = 1; green <= slot.FilledGreenSlots; green++) { description += ColorTokenService.Red("Green Slot #" + green + ": ") + examinedItem.GetLocalString("MOD_SLOT_GREEN_DESC_" + green) + "\n"; } for (int yellow = 1; yellow <= slot.FilledYellowSlots; yellow++) { description += ColorTokenService.Red("Yellow Slot #" + yellow + ": ") + examinedItem.GetLocalString("MOD_SLOT_YELLOW_DESC_" + yellow) + "\n"; } for (int prismatic = 1; prismatic <= slot.FilledPrismaticSlots; prismatic++) { description += PrismaticString() + " Slot #" + prismatic + ": " + examinedItem.GetLocalString("MOD_SLOT_PRISMATIC_DESC_" + prismatic) + "\n"; } return(existingDescription + "\n" + description); }
public static void RunItemDecay(NWPlayer player, NWItem item, float reduceAmount) { if (reduceAmount <= 0) { return; } if (player.IsPlot || item.IsPlot || item.GetLocalInt("UNBREAKABLE") == 1 || !item.IsValid || item.BaseItemType == BaseItem.CreatureItem || // Creature skin item.BaseItemType == BaseItem.CreatureBludgeWeapon || // Creature bludgeoning weapon item.BaseItemType == BaseItem.CreaturePierceWeapon || // Creature piercing weapon item.BaseItemType == BaseItem.CreatureSlashWeapon || // Creature slashing weapon item.BaseItemType == BaseItem.CreatureSlashPierceWeapon) // Creature slashing/piercing weapon { return; } float durability = GetDurability(item); string sItemName = item.Name; int apr = NWNXCreature.GetAttacksPerRound(player, true); // Reduce by 0.001 each time it's run. Player only receives notifications when it drops a full point. // I.E: Dropping from 29.001 to 29. // Note that players only see two decimal places in-game on purpose. durability -= reduceAmount / apr; bool displayMessage = Math.Abs(durability % 1) < 0.05f; if (displayMessage) { player.SendMessage(ColorTokenService.Red("Your " + sItemName + " has been damaged. (" + FormatDurability(durability) + " / " + GetMaxDurability(item))); } if (durability <= 0.00f) { item.Destroy(); player.SendMessage(ColorTokenService.Red("Your " + sItemName + " has broken!")); } else { SetDurability(item, durability); } }
public static bool IsPVPAttackAllowed(NWPlayer attacker, NWPlayer target) { // Check for sanctuary if this attack is PC versus PC if (target.IsPlayer && attacker.IsPlayer) { // Either the attacker or target has sanctuary - prevent combat from happening if (PlayerHasPVPSanctuary(attacker)) { attacker.FloatingText(ColorTokenService.Red("You are under the effects of PVP sanctuary and cannot engage in PVP. To disable this feature permanently refer to the 'Disable PVP Sanctuary' option in your rest menu.")); attacker.DelayAssignCommand(() => attacker.ClearAllActions(), 0.0f); return(false); } else if (PlayerHasPVPSanctuary(target)) { attacker.FloatingText(ColorTokenService.Red("Your target is under the effects of PVP sanctuary and cannot engage in PVP combat.")); attacker.DelayAssignCommand(() => attacker.ClearAllActions(), 0.0f); return(false); } } return(true); }
private static void ProcessChatCommand(IChatCommand command, NWPlayer sender, NWObject target, NWLocation targetLocation, string args) { if (target == null) { target = _.OBJECT_INVALID; } if (targetLocation == null) { targetLocation = sender.Location; } CommandDetailsAttribute attribute = command.GetType().GetCustomAttribute <CommandDetailsAttribute>(); var authorization = AuthorizationService.GetDMAuthorizationType(sender); if (attribute != null && (attribute.Permissions.HasFlag(CommandPermissionType.Player) && authorization == DMAuthorizationType.None || attribute.Permissions.HasFlag(CommandPermissionType.DM) && authorization == DMAuthorizationType.DM || attribute.Permissions.HasFlag(CommandPermissionType.Admin) && authorization == DMAuthorizationType.Admin)) { string[] argsArr = string.IsNullOrWhiteSpace(args) ? new string[0] : args.Split(' ').ToArray(); string error = command.ValidateArguments(sender, argsArr); if (!string.IsNullOrWhiteSpace(error)) { sender.SendMessage(error); } else { command.DoAction(sender, target, targetLocation, argsArr); } } else { sender.SendMessage(ColorTokenService.Red("Invalid chat command. Use '/help' to get a list of available commands.")); } }
private static void OnModuleEquipItem() { NWPlayer oPC = (GetPCItemLastEquippedBy()); // Don't run heavy code when customizing equipment. if (GetLocalBool(oPC, "IS_CUSTOMIZING_ITEM")) { return; } NWItem oItem = (GetPCItemLastEquipped()); float durability = GetDurability(oItem); if (durability <= 0 && durability != -1 && oItem.IsValid) { oPC.AssignCommand(() => { ClearAllActions(); ActionUnequipItem(oItem.Object); }); oPC.FloatingText(ColorTokenService.Red("That item is broken and must be repaired before you can use it.")); } }
private static void ProcessChatCommand(IChatCommand command, NWPlayer sender, NWObject target, NWLocation targetLocation, string args) { if (target == null) { target = new NWGameObject(); } if (targetLocation == null) { targetLocation = new Location(); } CommandDetailsAttribute attribute = command.GetType().GetCustomAttribute <CommandDetailsAttribute>(); bool isDM = sender.IsDM || AuthorizationService.IsPCRegisteredAsDM(sender); if (attribute != null && (attribute.Permissions.HasFlag(CommandPermissionType.Player) && sender.IsPlayer || attribute.Permissions.HasFlag(CommandPermissionType.DM) && isDM)) { string[] argsArr = string.IsNullOrWhiteSpace(args) ? new string[0] : args.Split(' ').ToArray(); string error = command.ValidateArguments(sender, argsArr); if (!string.IsNullOrWhiteSpace(error)) { sender.SendMessage(error); } else { command.DoAction(sender, target, targetLocation, argsArr); } } else { sender.SendMessage(ColorTokenService.Red("Invalid chat command. Use '/help' to get a list of available commands.")); } }
public static string BuildBlueprintHeader(NWPlayer player, bool showAddedComponentList) { var model = GetPlayerCraftingData(player); var bp = model.Blueprint; int playerEL = CalculatePCEffectiveLevel(player, model.PlayerSkillRank, (SkillType)bp.SkillID); var baseStructure = bp.BaseStructureID == null ? null : DataService.BaseStructure.GetByID(Convert.ToInt32(bp.BaseStructureID)); var mainComponent = DataService.ComponentType.GetByID(bp.MainComponentTypeID); var secondaryComponent = DataService.ComponentType.GetByID(bp.SecondaryComponentTypeID); var tertiaryComponent = DataService.ComponentType.GetByID(bp.TertiaryComponentTypeID); string header = ColorTokenService.Green("Blueprint: ") + bp.Quantity + "x " + bp.ItemName + "\n"; header += ColorTokenService.Green("Level: ") + (model.AdjustedLevel < 0 ? 0 : model.AdjustedLevel) + " (Base: " + (bp.BaseLevel < 0 ? 0 : bp.BaseLevel) + ")\n"; header += ColorTokenService.Green("Difficulty: ") + CalculateDifficultyDescription(playerEL, model.AdjustedLevel) + "\n"; if (baseStructure != null) { header += ColorTokenService.Green("Raises Atmosphere: "); if (baseStructure.HasAtmosphere) { header += ColorTokenService.Green("Yes"); } else { header += ColorTokenService.Red("No"); } header += "\n"; } header += ColorTokenService.Green("Required Components (Required/Maximum): ") + "\n\n"; string mainCounts = " (" + (model.MainMinimum > 0 ? Convert.ToString(model.MainMinimum) : "Optional") + "/" + model.MainMaximum + ")"; header += ColorTokenService.Green("Main: ") + mainComponent.Name + mainCounts + "\n"; if (bp.SecondaryMinimum > 0 && bp.SecondaryComponentTypeID > 0) { string secondaryCounts = " (" + (model.SecondaryMinimum > 0 ? Convert.ToString(model.SecondaryMinimum) : "Optional") + "/" + model.SecondaryMaximum + ")"; header += ColorTokenService.Green("Secondary: ") + secondaryComponent.Name + secondaryCounts + "\n"; } if (bp.TertiaryMinimum > 0 && bp.TertiaryComponentTypeID > 0) { string tertiaryCounts = " (" + (model.TertiaryMinimum > 0 ? Convert.ToString(model.TertiaryMinimum) : "Optional") + "/" + model.TertiaryMaximum + ")"; header += ColorTokenService.Green("Tertiary: ") + tertiaryComponent.Name + tertiaryCounts + "\n"; } if (bp.EnhancementSlots > 0) { int nSlots = bp.EnhancementSlots; if (model.IsInitialized) { // We have the player's stats, so tell them how many they can actually add. if (model.PlayerPerkLevel / 2 < nSlots) { nSlots = model.PlayerPerkLevel / 2; } } string enhancementSlots = " (0/" + Convert.ToString(nSlots) + ")"; header += ColorTokenService.Green("Enhancement slots: ") + enhancementSlots + "\n"; } if (showAddedComponentList) { header += "\n" + ColorTokenService.Green("Your components:") + "\n\n"; if (!model.HasPlayerComponents) { header += "No components selected yet!"; } else { foreach (var item in model.MainComponents) { header += item.Name + "\n"; } foreach (var item in model.SecondaryComponents) { header += item.Name + "\n"; } foreach (var item in model.TertiaryComponents) { header += item.Name + "\n"; } foreach (var item in model.EnhancementComponents) { header += item.Name + "\n"; } } } return(header); }
public static string PrismaticString() { return(ColorTokenService.Red("p") + ColorTokenService.Orange("r") + ColorTokenService.Yellow("i") + ColorTokenService.Green("s") + ColorTokenService.Blue("m") + ColorTokenService.LightPurple("a") + ColorTokenService.Purple("t") + ColorTokenService.White("i") + ColorTokenService.Black("c")); }
private static void OnModuleNWNXChat() { NWPlayer sender = Object.OBJECT_SELF; string originalMessage = NWNXChat.GetMessage().Trim(); if (!CanHandleChat(sender, originalMessage)) { return; } var split = originalMessage.Split(' ').ToList(); // Commands with no arguments won't be split, so if we didn't split anything then add the command to the split list manually. if (split.Count <= 0) { split.Add(originalMessage); } split[0] = split[0].ToLower(); string command = split[0].Substring(1, split[0].Length - 1); split.RemoveAt(0); NWNXChat.SkipMessage(); if (!IsChatCommandRegistered(command)) { sender.SendMessage(ColorTokenService.Red("Invalid chat command. Use '/help' to get a list of available commands.")); return; } IChatCommand chatCommand = GetChatCommandHandler(command); string args = string.Join(" ", split); if (!chatCommand.RequiresTarget) { ProcessChatCommand(chatCommand, sender, null, null, args); } else { string error = chatCommand.ValidateArguments(sender, split.ToArray()); if (!string.IsNullOrWhiteSpace(error)) { sender.SendMessage(error); return; } sender.SetLocalString("CHAT_COMMAND", command); sender.SetLocalString("CHAT_COMMAND_ARGS", args); sender.SendMessage("Please use your 'Chat Command Targeter' feat to select the target of this chat command."); if (_.GetHasFeat((int)CustomFeatType.ChatCommandTargeter, sender) == FALSE || sender.IsDM) { NWNXCreature.AddFeatByLevel(sender, (int)CustomFeatType.ChatCommandTargeter, 1); if (sender.IsDM) { var qbs = NWNXPlayer.GetQuickBarSlot(sender, 11); if (qbs.ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(sender, 11, NWNXPlayerQuickBarSlot.UseFeat((int)CustomFeatType.ChatCommandTargeter)); } } } } }
public static string OnModuleExamine(string existingDescription, NWObject examinedObject) { if (examinedObject.ObjectType != OBJECT_TYPE_ITEM) { return(existingDescription); } NWItem examinedItem = (examinedObject.Object); string description = ""; if (examinedItem.RecommendedLevel > 0) { description += ColorTokenService.Orange("Recommended Level: ") + examinedItem.RecommendedLevel + "\n"; } if (examinedItem.LevelIncrease > 0) { description += ColorTokenService.Orange("Level Increase: ") + examinedItem.LevelIncrease + "\n"; } if (examinedItem.AssociatedSkillType > 0) { Skill skill = DataService.Skill.GetByID((int)examinedItem.AssociatedSkillType); description += ColorTokenService.Orange("Associated Skill: ") + skill.Name + "\n"; } if (examinedItem.CustomAC > 0) { if (ShieldBaseItemTypes.Contains(examinedItem.BaseItemType)) { description += ColorTokenService.Orange("Damage Immunity: ") + (10 + examinedItem.CustomAC / 3) + "\n"; } else if (ArmorBaseItemTypes.Contains(examinedItem.BaseItemType)) { description += ColorTokenService.Orange("AC: ") + examinedItem.CustomAC + "\n"; } else { description += ColorTokenService.Red("AC (ignored due to item type): ") + examinedItem.CustomAC + "\n"; } } if (examinedItem.HPBonus > 0) { description += ColorTokenService.Orange("HP Bonus: ") + examinedItem.HPBonus + "\n"; } if (examinedItem.FPBonus > 0) { description += ColorTokenService.Orange("FP Bonus: ") + examinedItem.FPBonus + "\n"; } if (examinedItem.StructureBonus > 0) { description += ColorTokenService.Orange("Structure Bonus: ") + examinedItem.StructureBonus + "\n"; } if (examinedItem.StrengthBonus > 0) { description += ColorTokenService.Orange("Strength Bonus: ") + examinedItem.StrengthBonus + "\n"; } if (examinedItem.DexterityBonus > 0) { description += ColorTokenService.Orange("Dexterity Bonus: ") + examinedItem.DexterityBonus + "\n"; } if (examinedItem.ConstitutionBonus > 0) { description += ColorTokenService.Orange("Constitution Bonus: ") + examinedItem.ConstitutionBonus + "\n"; } if (examinedItem.WisdomBonus > 0) { description += ColorTokenService.Orange("Wisdom Bonus: ") + examinedItem.WisdomBonus + "\n"; } if (examinedItem.IntelligenceBonus > 0) { description += ColorTokenService.Orange("Intelligence Bonus: ") + examinedItem.IntelligenceBonus + "\n"; } if (examinedItem.CharismaBonus > 0) { description += ColorTokenService.Orange("Charisma Bonus: ") + examinedItem.CharismaBonus + "\n"; } if (examinedItem.CooldownRecovery > 0) { description += ColorTokenService.Orange("Cooldown Recovery: +") + examinedItem.CooldownRecovery + "%\n"; } else if (examinedItem.CooldownRecovery < 0) { description += ColorTokenService.Orange("Cooldown Recovery: -") + examinedItem.CooldownRecovery + "%\n"; } if (examinedItem.HarvestingBonus > 0) { description += ColorTokenService.Orange("Harvesting Bonus: ") + examinedItem.HarvestingBonus + "\n"; } if (examinedItem.CraftBonusArmorsmith > 0) { description += ColorTokenService.Orange("Armorsmith Bonus: ") + examinedItem.CraftBonusArmorsmith + "\n"; } if (examinedItem.CraftBonusEngineering > 0) { description += ColorTokenService.Orange("Engineering Bonus: ") + examinedItem.CraftBonusEngineering + "\n"; } if (examinedItem.CraftBonusFabrication > 0) { description += ColorTokenService.Orange("Fabrication Bonus: ") + examinedItem.CraftBonusFabrication + "\n"; } if (examinedItem.CraftBonusWeaponsmith > 0) { description += ColorTokenService.Orange("Weaponsmith Bonus: ") + examinedItem.CraftBonusWeaponsmith + "\n"; } if (examinedItem.CraftBonusCooking > 0) { description += ColorTokenService.Orange("Cooking Bonus: ") + examinedItem.CraftBonusCooking + "\n"; } if (examinedItem.CraftTierLevel > 0) { description += ColorTokenService.Orange("Tool Level: ") + examinedItem.CraftTierLevel + "\n"; } if (examinedItem.EnmityRate != 0) { description += ColorTokenService.Orange("Enmity: ") + examinedItem.EnmityRate + "%\n"; } if (examinedItem.LuckBonus > 0) { description += ColorTokenService.Orange("Luck Bonus: ") + examinedItem.LuckBonus + "\n"; } if (examinedItem.MeditateBonus > 0) { description += ColorTokenService.Orange("Meditate Bonus: ") + examinedItem.MeditateBonus + "\n"; } if (examinedItem.RestBonus > 0) { description += ColorTokenService.Orange("Rest Bonus: ") + examinedItem.RestBonus + "\n"; } if (examinedItem.ScanningBonus > 0) { description += ColorTokenService.Orange("Scanning Bonus: ") + examinedItem.ScanningBonus + "\n"; } if (examinedItem.ScavengingBonus > 0) { description += ColorTokenService.Orange("Scavenging Bonus: ") + examinedItem.ScavengingBonus + "\n"; } if (examinedItem.MedicineBonus > 0) { description += ColorTokenService.Orange("Medicine Bonus: ") + examinedItem.MedicineBonus + "\n"; } if (examinedItem.HPRegenBonus > 0) { description += ColorTokenService.Orange("HP Regen Bonus: ") + examinedItem.HPRegenBonus + "\n"; } if (examinedItem.FPRegenBonus > 0) { description += ColorTokenService.Orange("FP Regen Bonus: ") + examinedItem.FPRegenBonus + "\n"; } if (examinedItem.PilotingBonus > 0) { description += ColorTokenService.Orange("Piloting Bonus: ") + examinedItem.PilotingBonus + "\n"; } if (examinedItem.BaseAttackBonus > 0) { if (WeaponBaseItemTypes.Contains(examinedItem.BaseItemType)) { description += ColorTokenService.Orange("Base Attack Bonus: ") + examinedItem.BaseAttackBonus + "\n"; } else { description += ColorTokenService.Red("Base Attack Bonus (ignored due to item type): ") + examinedItem.BaseAttackBonus + "\n"; } } if (examinedItem.SneakAttackBonus > 0) { description += ColorTokenService.Orange("Sneak Attack Bonus: ") + examinedItem.SneakAttackBonus + "\n"; } if (examinedItem.DamageBonus > 0) { if (WeaponBaseItemTypes.Contains(examinedItem.BaseItemType)) { description += ColorTokenService.Orange("Damage Bonus: ") + examinedItem.DamageBonus + "\n"; } else { description += ColorTokenService.Red("Damage Bonus (ignored due to item type): ") + examinedItem.DamageBonus + "\n"; } } if (examinedItem.CustomItemType != CustomItemType.None) { string itemTypeProper = string.Concat(examinedItem.CustomItemType.ToString().Select(x => char.IsUpper(x) ? " " + x : x.ToString())).TrimStart(' '); description += ColorTokenService.Orange("Item Type: ") + itemTypeProper + "\n"; } // Check for properties that can only be applied to limited things, and flag them here. // Attack bonus, damage, base attack bonus: weapons only // AC - armor items only. ItemProperty ip = _.GetFirstItemProperty(examinedItem); while (_.GetIsItemPropertyValid(ip) == TRUE) { if (_.GetItemPropertyType(ip) == (int)CustomItemPropertyType.ComponentBonus) { switch (_.GetItemPropertySubType(ip)) { case (int)ComponentBonusType.ACUp: { description += ColorTokenService.Cyan("AC can only be applied to Shields, Armor and Helmets. On other items, it will be ignored.\n"); break; } case (int)ComponentBonusType.DamageUp: case (int)ComponentBonusType.AttackBonusUp: case (int)ComponentBonusType.BaseAttackBonusUp: { description += ColorTokenService.Cyan("Damage Up, Attack Bonus Up and Base Attack Bonus Up can only be applied to weapons (including gloves). On other items, it will be ignored.\n"); break; } } } ip = _.GetNextItemProperty(examinedItem); } return(existingDescription + "\n" + description); }
/// <summary> /// Calculates ability resistance for an ability. /// The attacker and defender's skills, ability modifiers, and balance affinity will be /// used to make this determination. /// </summary> /// <param name="attacker">The creature using the ability.</param> /// <param name="defender">The creature being targeted by the ability.</param> /// <param name="skill">The skill used for this ability.</param> /// <param name="balanceType">The force balance type to use for this ability.</param> /// <param name="sendRollMessage">If true, the roll message will be sent. Otherwise it won't be.</param> /// <returns>Data regarding the ability resistance roll</returns> public static AbilityResistanceResult CalculateAbilityResistance(NWCreature attacker, NWCreature defender, SkillType skill, ForceBalanceType balanceType, bool sendRollMessage = true) { int abilityScoreType; switch (skill) { case SkillType.ForceAlter: abilityScoreType = ABILITY_INTELLIGENCE; break; case SkillType.ForceControl: abilityScoreType = ABILITY_WISDOM; break; case SkillType.ForceSense: abilityScoreType = ABILITY_CHARISMA; break; default: throw new ArgumentException("Invalid skill type called for " + nameof(CalculateAbilityResistance) + ", value '" + skill + "' not supported."); } AbilityResistanceResult result = new AbilityResistanceResult(); int attackerSkill = SkillService.GetPCSkillRank(attacker.Object, skill); int attackerAbility = _.GetAbilityModifier(abilityScoreType, attacker); int defenderSkill = SkillService.GetPCSkillRank(defender.Object, skill); int defenderAbility = _.GetAbilityModifier(abilityScoreType, defender); // If the defender is equipped with a lightsaber, we check their lightsaber skill if (defender.RightHand.CustomItemType == CustomItemType.Lightsaber || defender.LeftHand.CustomItemType == CustomItemType.Lightsaber) { int lightsaberSkill = SkillService.GetPCSkillRank(defender.Object, SkillType.Lightsaber); if (lightsaberSkill > defenderSkill) { defenderSkill = lightsaberSkill; } } // If the defender's martial arts skill is greater than the current skill they're using, we'll use that instead. int defenderMASkill = SkillService.GetPCSkillRank(defender.Object, SkillType.MartialArts); if (defenderMASkill > defenderSkill) { defenderSkill = defenderMASkill; } int attackerAffinity = 0; int defenderAffinity = 0; // Only check affinity if ability has a force balance type. if (balanceType == ForceBalanceType.Dark || balanceType == ForceBalanceType.Light) { attackerAffinity = GetBalanceAffinity(attacker.Object, balanceType); defenderAffinity = GetBalanceAffinity(defender.Object, balanceType); } float attackerCR = attacker.IsPlayer ? 0f : attacker.ChallengeRating * 5f; float defenderCR = defender.IsPlayer ? 0f : defender.ChallengeRating * 5f; float attackerTotal = attackerSkill + attackerAbility + attackerAffinity + attackerCR; float defenderTotal = defenderSkill + defenderAbility + defenderAffinity + defenderCR; float divisor = attackerTotal + defenderTotal + 1; // +1 to prevent division by zero. //Console.WriteLine("attackerCR = " + attackerCR); //Console.WriteLine("defenderCR = " + defenderCR); //Console.WriteLine("attackerSkill = " + attackerSkill); //Console.WriteLine("attackerAbility = " + attackerAbility); //Console.WriteLine("attackerAffinity = " + attackerAffinity); //Console.WriteLine("defenderSkill = " + defenderSkill); //Console.WriteLine("defenderAbility = " + defenderAbility); //Console.WriteLine("defenderAffinity = " + defenderAffinity); //Console.WriteLine("attackerTotal = " + attackerTotal); //Console.WriteLine("defenderTotal = " + defenderTotal); //Console.WriteLine("divisor = " + divisor); result.DC = (int)(attackerTotal / divisor * 100); result.Roll = RandomService.D100(1); if (sendRollMessage) { string resisted = result.IsResisted ? ColorTokenService.Red(" [RESISTED " + Math.Abs(result.Delta) + "%]") : string.Empty; string message = ColorTokenService.SavingThrow("Roll: " + result.Roll + " VS " + result.DC + " DC") + resisted; attacker.SendMessage(message); defender.SendMessage(message); } return(result); }
public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = DataService.Single <Data.Entity.Perk>(x => x.ID == perkID); var perkLevels = DataService.Where <PerkLevel>(x => x.PerkID == perkID); var pcPerk = DataService.SingleOrDefault <PCPerk>(x => x.PlayerID == oPC.GlobalID && x.PerkID == perkID); var player = DataService.Single <Player>(x => x.ID == oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; DataService.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; DataService.SubmitDataChange(player, DatabaseActionType.Update); } // Look for any perk levels to grant. var perkFeatsToGrant = DataService.Where <PerkFeat>(x => x.PerkID == perkID && x.PerkLevelUnlocked == pcPerk.PerkLevel); // If at least one feat ID is assigned, add the feat(s) to the player if it doesn't exist yet. if (perkFeatsToGrant.Count > 0) { foreach (var perkFeat in perkFeatsToGrant) { if (_.GetHasFeat(perkFeat.FeatID, oPC.Object) == TRUE) { continue; } NWNXCreature.AddFeatByLevel(oPC, perkFeat.FeatID, 1); var qbs = NWNXPlayerQuickBarSlot.UseFeat(perkFeat.FeatID); // Try to add the new feat to the player's hotbar. if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs); } } } oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); var handler = GetPerkHandler(perkID); handler.OnPurchased(oPC, pcPerk.PerkLevel); MessageHub.Instance.Publish(new PerkUpgradedMessage(oPC, perkID)); } else { oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time.")); } }
/// <summary> /// Performs a perk purchase for a player. This handles deducting SP, inserting perk records, /// and adjusting hotbar slots as necessary. /// </summary> /// <param name="oPC">The player receiving the perk upgrade.</param> /// <param name="perkID">The ID number of the perk.</param> /// <param name="freeUpgrade">If true, no SP will be deducted. Otherwise, SP will be deducted from player.</param> public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = DataService.Perk.GetByID(perkID); var perkLevels = DataService.PerkLevel.GetAllByPerkID(perkID); var pcPerk = DataService.PCPerk.GetByPlayerAndPerkIDOrDefault(oPC.GlobalID, perkID); var player = DataService.Player.GetByID(oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; DataService.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; DataService.SubmitDataChange(player, DatabaseActionType.Update); } // Look for a perk feat to grant. var perkFeatToGrant = DataService.PerkFeat.GetByPerkIDAndLevelUnlockedOrDefault(perkID, pcPerk.PerkLevel); // Add the feat(s) to the player if it doesn't exist yet. if (perkFeatToGrant != null && _.GetHasFeat((Feat)perkFeatToGrant.FeatID, oPC.Object) == false) { NWNXCreature.AddFeatByLevel(oPC, (Feat)perkFeatToGrant.FeatID, 1); var qbs = NWNXPlayerQuickBarSlot.UseFeat((Feat)perkFeatToGrant.FeatID); // Try to add the new feat to the player's hotbar. if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs); } } oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); MessageHub.Instance.Publish(new OnPerkUpgraded(oPC, perkID)); var handler = GetPerkHandler(perkID); handler.OnPurchased(oPC, pcPerk.PerkLevel); } else { oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time.")); } }