Ejemplo n.º 1
0
        private static void OnModuleEquipItem()
        {
            NWPlayer oPC = (_.GetPCItemLastEquippedBy());

            // Don't run heavy code when customizing equipment.
            if (oPC.GetLocalInt("IS_CUSTOMIZING_ITEM") == _.TRUE)
            {
                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."));
            }
        }
Ejemplo n.º 2
0
        private static void ProcessChatCommand(IChatCommand command, NWPlayer sender, NWObject target, NWLocation targetLocation, string args)
        {
            if (target == null)
            {
                target = new Object();
            }

            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."));
            }
        }
Ejemplo n.º 3
0
        private static void OnCreatureDeath()
        {
            NWCreature creature = Object.OBJECT_SELF;

            int npcGroupID = creature.GetLocalInt("NPC_GROUP");

            if (npcGroupID <= 0)
            {
                return;
            }

            NWObject oKiller = _.GetLastKiller();

            if (!oKiller.IsPlayer)
            {
                return;
            }

            string areaResref = creature.Area.Resref;

            List <KeyValuePair <NWPlayer, int> > playersToAdvance = new List <KeyValuePair <NWPlayer, int> >();
            NWPlayer oPC = _.GetFirstFactionMember(oKiller);

            while (oPC.IsValid)
            {
                if (areaResref != oPC.Area.Resref)
                {
                    oPC = _.GetNextFactionMember(oKiller);
                    continue;
                }

                if (_.GetDistanceBetween(creature, oPC) <= 0.0f || _.GetDistanceBetween(creature, oPC) > 20.0f)
                {
                    oPC = _.GetNextFactionMember(oKiller);
                    continue;
                }

                var playerID    = oPC.GlobalID;
                var killTargets = DataService.Where <PCQuestKillTargetProgress>(x => x.PlayerID == playerID && x.NPCGroupID == npcGroupID).ToList();

                foreach (var kt in killTargets)
                {
                    var questStatus = DataService.Get <PCQuestStatus>(kt.PCQuestStatusID);
                    var quest       = DataService.Get <Quest>(questStatus.QuestID);
                    var npcGroup    = DataService.Get <NPCGroup>(kt.NPCGroupID);

                    kt.RemainingToKill--;
                    string             targetGroupName = npcGroup.Name;
                    string             updateMessage   = "[" + quest.Name + "] " + targetGroupName + " remaining: " + kt.RemainingToKill;
                    DatabaseActionType action          = DatabaseActionType.Update;

                    if (kt.RemainingToKill <= 0)
                    {
                        updateMessage += " " + ColorTokenService.Green(" {COMPLETE}");
                        playersToAdvance.Add(new KeyValuePair <NWPlayer, int>(oPC, quest.ID));
                        action = DatabaseActionType.Delete;
                    }

                    DataService.SubmitDataChange(kt, action);

                    var pc = oPC;
                    _.DelayCommand(1.0f, () =>
                    {
                        pc.SendMessage(updateMessage);
                    });

                    string ruleName = quest.OnKillTargetRule;
                    if (!string.IsNullOrWhiteSpace(ruleName))
                    {
                        var pcCopy = oPC;
                        var rule   = GetQuestRule(ruleName);

                        string[] args = null;
                        if (!string.IsNullOrWhiteSpace(quest.OnKillTargetArgs))
                        {
                            args = quest.OnKillTargetArgs.Split(',');
                        }
                        rule.Run(pcCopy, creature, quest.ID, args);
                    }
                }

                oPC = _.GetNextFactionMember(oKiller);
            }

            foreach (var player in playersToAdvance)
            {
                AdvanceQuestState(player.Key, null, player.Value);
            }
        }
Ejemplo n.º 4
0
        private static void OnModuleNWNXChat()
        {
            ChatChannelType channel = (ChatChannelType)NWNXChat.GetChannel();

            // So we're going to play with a couple of channels here.

            // - PlayerTalk, PlayerWhisper, PlayerParty, and PlayerShout are all IC channels. These channels
            //   are subject to emote colouring and language translation. (see below for more info).
            // - PlayerParty is an IC channel with special behaviour. Those outside of the party but within
            //   range may listen in to the party chat. (see below for more information).
            // - PlayerShout sends a holocom message server-wide through the DMTell channel.
            // - PlayerDM echoes back the message received to the sender.

            bool inCharacterChat =
                channel == ChatChannelType.PlayerTalk ||
                channel == ChatChannelType.PlayerWhisper ||
                channel == ChatChannelType.PlayerParty ||
                channel == ChatChannelType.PlayerShout;

            bool messageToDm = channel == ChatChannelType.PlayerDM;

            if (!inCharacterChat && !messageToDm)
            {
                // We don't much care about traffic on the other channels.
                return;
            }

            NWObject sender  = NWNXChat.GetSender();
            string   message = NWNXChat.GetMessage().Trim();

            if (string.IsNullOrWhiteSpace(message))
            {
                // We can't handle empty messages, so skip it.
                return;
            }

            if (ChatCommandService.CanHandleChat(sender, message) ||
                BaseService.CanHandleChat(sender) ||
                CraftService.CanHandleChat(sender) ||
                MarketService.CanHandleChat(sender.Object) ||
                MessageBoardService.CanHandleChat(sender) ||
                ItemService.CanHandleChat(sender))
            {
                // This will be handled by other services, so just bail.
                return;
            }

            if (channel == ChatChannelType.PlayerDM)
            {
                // Simply echo the message back to the player.
                NWNXChat.SendMessage((int)ChatChannelType.ServerMessage, "(Sent to DM) " + message, sender, sender);
                return;
            }

            // At this point, every channel left is one we want to manually handle.
            NWNXChat.SkipMessage();

            // If this is a shout message, and the holonet is disabled, we disallow it.
            if (channel == ChatChannelType.PlayerShout && sender.IsPC &&
                sender.GetLocalInt("DISPLAY_HOLONET") == FALSE)
            {
                NWPlayer player = sender.Object;
                player.SendMessage("You have disabled the holonet and cannot send this message.");
                return;
            }

            List <ChatComponent> chatComponents;

            // Quick early out - if we start with "//" or "((", this is an OOC message.
            bool isOOC = false;

            if (message.Length >= 2 && (message.Substring(0, 2) == "//" || message.Substring(0, 2) == "(("))
            {
                ChatComponent component = new ChatComponent
                {
                    m_Text         = message,
                    m_CustomColour = true,
                    m_ColourRed    = 64,
                    m_ColourGreen  = 64,
                    m_ColourBlue   = 64,
                    m_Translatable = false
                };

                chatComponents = new List <ChatComponent> {
                    component
                };

                if (channel == ChatChannelType.PlayerShout)
                {
                    _.SendMessageToPC(sender, "Out-of-character messages cannot be sent on the Holonet.");
                    return;
                }

                isOOC = true;
            }
            else
            {
                if (EmoteStyleService.GetEmoteStyle(sender) == EmoteStyle.Regular)
                {
                    chatComponents = SplitMessageIntoComponents_Regular(message);
                }
                else
                {
                    chatComponents = SplitMessageIntoComponents_Novel(message);
                }

                // For any components with colour, set the emote colour.
                foreach (ChatComponent component in chatComponents)
                {
                    if (component.m_CustomColour)
                    {
                        component.m_ColourRed   = 0;
                        component.m_ColourGreen = 255;
                        component.m_ColourBlue  = 0;
                    }
                }
            }

            // Now, depending on the chat channel, we need to build a list of recipients.
            bool  needsAreaCheck = false;
            float distanceCheck  = 0.0f;

            // The sender always wants to see their own message.
            List <NWObject> recipients = new List <NWObject> {
                sender
            };

            // This is a server-wide holonet message (that receivers can toggle on or off).
            if (channel == ChatChannelType.PlayerShout)
            {
                recipients.AddRange(NWModule.Get().Players.Where(player => player.GetLocalInt("DISPLAY_HOLONET") == TRUE));
                recipients.AddRange(AppCache.ConnectedDMs);
            }
            // This is the normal party chat, plus everyone within 20 units of the sender.
            else if (channel == ChatChannelType.PlayerParty)
            {
                // Can an NPC use the playerparty channel? I feel this is safe ...
                NWPlayer player = sender.Object;
                recipients.AddRange(player.PartyMembers.Cast <NWObject>().Where(x => x != sender));
                recipients.AddRange(AppCache.ConnectedDMs);

                needsAreaCheck = true;
                distanceCheck  = 20.0f;
            }
            // Normal talk - 20 units.
            else if (channel == ChatChannelType.PlayerTalk)
            {
                needsAreaCheck = true;
                distanceCheck  = 20.0f;
            }
            // Whisper - 4 units.
            else if (channel == ChatChannelType.PlayerWhisper)
            {
                needsAreaCheck = true;
                distanceCheck  = 4.0f;
            }

            if (needsAreaCheck)
            {
                recipients.AddRange(sender.Area.Objects.Where(obj => obj.IsPC && _.GetDistanceBetween(sender, obj) <= distanceCheck));
                recipients.AddRange(AppCache.ConnectedDMs.Where(dm => dm.Area == sender.Area && _.GetDistanceBetween(sender, dm) <= distanceCheck));
            }

            // Now we have a list of who is going to actually receive a message, we need to modify
            // the message for each recipient then dispatch them.

            foreach (NWObject obj in recipients.Distinct())
            {
                // Generate the final message as perceived by obj.

                StringBuilder finalMessage = new StringBuilder();

                if (channel == ChatChannelType.PlayerShout)
                {
                    finalMessage.Append("[Holonet] ");
                }
                else if (channel == ChatChannelType.PlayerParty)
                {
                    finalMessage.Append("[Comms] ");

                    if (obj.IsDM)
                    {
                        // Convenience for DMs - append the party members.
                        finalMessage.Append("{ ");

                        int               count        = 0;
                        NWPlayer          player       = sender.Object;
                        List <NWCreature> partyMembers = player.PartyMembers.ToList();

                        foreach (NWCreature otherPlayer in partyMembers)
                        {
                            string name = otherPlayer.Name;
                            finalMessage.Append(name.Substring(0, Math.Min(name.Length, 10)));

                            ++count;

                            if (count >= 3)
                            {
                                finalMessage.Append(", ...");
                                break;
                            }
                            else if (count != partyMembers.Count)
                            {
                                finalMessage.Append(",");
                            }
                        }

                        finalMessage.Append(" } ");
                    }
                }

                SkillType language = LanguageService.GetActiveLanguage(sender);

                // Wookiees cannot speak any other language (but they can understand them).
                // Swap their language if they attempt to speak in any other language.
                CustomRaceType race = (CustomRaceType)_.GetRacialType(sender);
                if (race == CustomRaceType.Wookiee && language != SkillType.Shyriiwook)
                {
                    LanguageService.SetActiveLanguage(sender, SkillType.Shyriiwook);
                    language = SkillType.Shyriiwook;
                }

                int  colour = LanguageService.GetColour(language);
                byte r      = (byte)(colour >> 24 & 0xFF);
                byte g      = (byte)(colour >> 16 & 0xFF);
                byte b      = (byte)(colour >> 8 & 0xFF);

                if (language != SkillType.Basic)
                {
                    string languageName = LanguageService.GetName(language);
                    finalMessage.Append(ColorTokenService.Custom($"[{languageName}] ", r, g, b));
                }

                foreach (ChatComponent component in chatComponents)
                {
                    string text = component.m_Text;

                    if (component.m_Translatable && language != SkillType.Basic)
                    {
                        text = LanguageService.TranslateSnippetForListener(sender, obj.Object, language, component.m_Text);

                        if (colour != 0)
                        {
                            text = ColorTokenService.Custom(text, r, g, b);
                        }
                    }

                    if (component.m_CustomColour)
                    {
                        text = ColorTokenService.Custom(text, component.m_ColourRed, component.m_ColourGreen, component.m_ColourBlue);
                    }

                    finalMessage.Append(text);
                }

                // Dispatch the final message - method depends on the original chat channel.
                // - Shout and party is sent as DMTalk. We do this to get around the restriction that
                //   the PC needs to be in the same area for the normal talk channel.
                //   We could use the native channels for these but the [shout] or [party chat] labels look silly.
                // - Talk and whisper are sent as-is.

                ChatChannelType finalChannel = channel;

                if (channel == ChatChannelType.PlayerShout || channel == ChatChannelType.PlayerParty)
                {
                    finalChannel = ChatChannelType.DMTalk;
                }

                // There are a couple of colour overrides we want to use here.
                // - One for holonet (shout).
                // - One for comms (party chat).

                string finalMessageColoured = finalMessage.ToString();

                if (channel == ChatChannelType.PlayerShout)
                {
                    finalMessageColoured = ColorTokenService.Custom(finalMessageColoured, 0, 180, 255);
                }
                else if (channel == ChatChannelType.PlayerParty)
                {
                    finalMessageColoured = ColorTokenService.Orange(finalMessageColoured);
                }

                NWNXChat.SendMessage((int)finalChannel, finalMessageColoured, sender, obj);
            }

            MessageHub.Instance.Publish(new OnChatProcessed(sender, channel, isOOC));
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Updates a player's quest status if the creature is part of an ongoing quest.
        /// Progresses the player to the next state if all requirements are met.
        /// </summary>
        private static void OnCreatureDeath()
        {
            NWCreature creature = _.OBJECT_SELF;

            int npcGroupID = creature.GetLocalInt("NPC_GROUP");

            if (npcGroupID <= 0)
            {
                return;
            }

            NWObject oKiller = GetLastKiller();

            if (!oKiller.IsPlayer)
            {
                return;
            }

            string areaResref = creature.Area.Resref;

            List <KeyValuePair <NWPlayer, int> > playersToAdvance = new List <KeyValuePair <NWPlayer, int> >();
            NWPlayer oPC = GetFirstFactionMember(oKiller);

            while (oPC.IsValid)
            {
                if (areaResref != oPC.Area.Resref)
                {
                    oPC = GetNextFactionMember(oKiller);
                    continue;
                }

                if (GetDistanceBetween(creature, oPC) <= 0.0f || GetDistanceBetween(creature, oPC) > 40.0f)
                {
                    oPC = GetNextFactionMember(oKiller);
                    continue;
                }

                var playerID    = oPC.GlobalID;
                var killTargets = DataService.PCQuestKillTargetProgress.GetAllByPlayerIDAndNPCGroupID(playerID, npcGroupID).ToList();

                foreach (var kt in killTargets)
                {
                    var questStatus = DataService.PCQuestStatus.GetByID(kt.PCQuestStatusID);
                    var quest       = GetQuestByID(questStatus.QuestID);
                    var npcGroup    = DataService.NPCGroup.GetByID(kt.NPCGroupID);

                    kt.RemainingToKill--;
                    string             targetGroupName = npcGroup.Name;
                    string             updateMessage   = "[" + quest.Name + "] " + targetGroupName + " remaining: " + kt.RemainingToKill;
                    DatabaseActionType action          = DatabaseActionType.Update;

                    if (kt.RemainingToKill <= 0)
                    {
                        updateMessage += " " + ColorTokenService.Green(" {COMPLETE}");
                        playersToAdvance.Add(new KeyValuePair <NWPlayer, int>(oPC, quest.QuestID));
                        action = DatabaseActionType.Delete;
                    }

                    DataService.SubmitDataChange(kt, action);

                    var pc = oPC;
                    DelayCommand(1.0f, () =>
                    {
                        pc.SendMessage(updateMessage);
                    });
                }

                oPC = GetNextFactionMember(oKiller);
            }

            foreach (var player in playersToAdvance)
            {
                var quest = GetQuestByID(player.Value);
                quest.Advance(player.Key, creature);
            }
        }
Ejemplo n.º 7
0
 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"));
 }
Ejemplo n.º 8
0
        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));
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        private static void ProcessConcentrationEffects()
        {
            // Loop through each creature. If they have a concentration ability active,
            // process it using that perk's OnConcentrationTick() method.
            for (int index = ConcentratingCreatures.Count - 1; index >= 0; index--)
            {
                var  creature      = ConcentratingCreatures.ElementAt(index);
                var  activeAbility = GetActiveConcentrationEffect(creature);
                int  perkID        = (int)activeAbility.Type;
                int  tier          = activeAbility.Tier;
                bool ended         = false;

                // If we have an invalid creature for any reason, remove it and move to the next one.
                if (!creature.IsValid || creature.CurrentHP <= 0 || activeAbility.Type == PerkType.Unknown)
                {
                    ConcentratingCreatures.RemoveAt(index);
                    continue;
                }

                // Track the current tick.
                int tick = creature.GetLocalInt("ACTIVE_CONCENTRATION_ABILITY_TICK") + 1;
                creature.SetLocalInt("ACTIVE_CONCENTRATION_ABILITY_TICK", tick);

                PerkFeat perkFeat = DataService.PerkFeat.GetByPerkIDAndLevelUnlocked(perkID, tier);

                // Are we ready to continue processing this concentration effect?
                if (tick % perkFeat.ConcentrationTickInterval != 0)
                {
                    continue;
                }

                // Get the perk handler, FP cost, and the target.
                var      handler   = PerkService.GetPerkHandler(perkID);
                int      fpCost    = handler.FPCost(creature, perkFeat.ConcentrationFPCost, tier);
                NWObject target    = creature.GetLocalObject("CONCENTRATION_TARGET");
                int      currentFP = GetCurrentFP(creature);
                int      maxFP     = GetMaxFP(creature);

                // Is the target still valid?
                if (!target.IsValid || target.CurrentHP <= 0)
                {
                    creature.SendMessage("Concentration effect has ended because your target is no longer valid.");
                    EndConcentrationEffect(creature);
                    ended = true;
                }
                // Does player have enough FP to maintain this concentration?
                else if (currentFP < fpCost)
                {
                    creature.SendMessage("Concentration effect has ended because you ran out of FP.");
                    EndConcentrationEffect(creature);
                    ended = true;
                }
                // Is the target still within range and in the same area?
                else if (creature.Area.Object != target.Area.Object ||
                         _.GetDistanceBetween(creature, target) > 50.0f)
                {
                    creature.SendMessage("Concentration effect has ended because your target has gone out of range.");
                    EndConcentrationEffect(creature);
                    ended = true;
                }
                // Otherwise deduct the required FP.
                else
                {
                    currentFP -= fpCost;
                }

                SetCurrentFP(creature, currentFP);

                // Send a FP status message if the effect ended or it's been six seconds since the last one.
                if (ended || tick % 6 == 0)
                {
                    creature.SendMessage(ColorTokenService.Custom("FP: " + currentFP + " / " + maxFP, 32, 223, 219));
                }

                // Run this individual perk's concentration tick method if it didn't end this tick.
                if (!ended && target.IsValid)
                {
                    handler.OnConcentrationTick(creature, target, tier, tick);
                }
            }
        }
Ejemplo n.º 11
0
        private static void HandleEvadeOrDeflectBlasterFire()
        {
            DamageEventData data = NWNXDamage.GetDamageEventData();

            if (data.Total <= 0)
            {
                return;
            }
            NWCreature damager = data.Damager.Object;
            NWCreature target  = NWGameObject.OBJECT_SELF;

            NWItem damagerWeapon = _.GetLastWeaponUsed(damager);
            NWItem targetWeapon  = target.RightHand;

            int perkLevel;

            // Attacker isn't using a pistol or rifle. Return.
            if (damagerWeapon.CustomItemType != CustomItemType.BlasterPistol &&
                damagerWeapon.CustomItemType != CustomItemType.BlasterRifle)
            {
                return;
            }

            int    modifier;
            string action;

            // Check target's equipped weapon, armor and perk.
            if (target.Chest.CustomItemType == CustomItemType.LightArmor &&
                (targetWeapon.CustomItemType == CustomItemType.MartialArtWeapon ||
                 !target.RightHand.IsValid && !target.LeftHand.IsValid))
            {
                // Martial Arts (weapon or unarmed) uses the Evade Blaster Fire perk which is primarily DEX based.
                perkLevel = PerkService.GetCreaturePerkLevel(target.Object, PerkType.EvadeBlasterFire);
                modifier  = target.DexterityModifier;
                action    = "evade";
            }
            else if (target.Chest.CustomItemType == CustomItemType.ForceArmor &&
                     (targetWeapon.CustomItemType == CustomItemType.Lightsaber ||
                      targetWeapon.CustomItemType == CustomItemType.Saberstaff ||
                      targetWeapon.GetLocalInt("LIGHTSABER") == TRUE))
            {
                // Lightsabers (lightsaber or saberstaff) uses the Deflect Blaster Fire perk which is primarily CHA based.
                perkLevel = PerkService.GetCreaturePerkLevel(target.Object, PerkType.DeflectBlasterFire);
                modifier  = target.CharismaModifier;
                action    = "deflect";
            }
            else
            {
                return;
            }

            // Don't have the perk. Return.
            if (perkLevel <= 0)
            {
                return;
            }

            // Check attacker's DEX against the primary stat of the perk.
            int delta = modifier - damager.DexterityModifier;

            if (delta <= 0)
            {
                return;
            }

            // Has the delay between block/evade attempts past?
            DateTime cooldown       = DateTime.UtcNow;
            string   lastAttemptVar = target.GetLocalString("EVADE_OR_DEFLECT_BLASTER_FIRE_COOLDOWN");

            if (!string.IsNullOrWhiteSpace(lastAttemptVar))
            {
                cooldown = DateTime.Parse(lastAttemptVar);
            }

            // Cooldown hasn't expired yet. Not ready to attempt a deflect.
            if (cooldown >= DateTime.UtcNow)
            {
                return;
            }

            // Ready to attempt a deflect. Adjust chance based on the delta of attacker DEX versus primary stat of defender.
            int chanceToDeflect = 5 * delta;

            if (chanceToDeflect > 80)
            {
                chanceToDeflect = 80;
            }

            int delay; // Seconds delay between deflect attempts.

            switch (perkLevel)
            {
            case 1:
                delay = 18;
                break;

            case 2:
                delay = 12;
                break;

            case 3:
                delay = 6;
                break;

            default: throw new Exception("HandleEvadeOrDeflectBlasterFire -> Perk Level " + perkLevel + " unsupported.");
            }

            cooldown = DateTime.UtcNow.AddSeconds(delay);
            target.SetLocalString("EVADE_OR_DEFLECT_BLASTER_FIRE_COOLDOWN", cooldown.ToString(CultureInfo.InvariantCulture));

            int roll = RandomService.D100(1);

            if (roll <= chanceToDeflect)
            {
                target.SendMessage(ColorTokenService.Gray("You " + action + " a blaster shot."));
                data.AdjustAllByPercent(-1);
                NWNXDamage.SetDamageEventData(data);
            }
            else
            {
                target.SendMessage(ColorTokenService.Gray("You fail to " + action + " a blaster shot. (" + roll + " vs " + chanceToDeflect + ")"));
            }
        }
Ejemplo n.º 12
0
        /// <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);
        }
Ejemplo n.º 13
0
        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."));
            }
        }
Ejemplo n.º 14
0
        private static void ShowMOTD()
        {
            NWPlayer            player = GetEnteringObject();
            ServerConfiguration config = DataService.ServerConfiguration.Get();
            string message             = ColorTokenService.Green("Welcome to " + config.ServerName + "!\n\nMOTD: ") + ColorTokenService.White(config.MessageOfTheDay);

            DelayCommand(6.5f, () =>
            {
                player.SendMessage(message);
            });
        }
Ejemplo n.º 15
0
        /// <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."));
            }
        }
Ejemplo n.º 16
0
        public static string OnModuleExamine(string existingDescription, NWPlayer examiner, 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.Get <Skill>((int)examinedItem.AssociatedSkillType);
                description += ColorTokenService.Orange("Associated Skill: ") + skill.Name + "\n";
            }
            if (examinedItem.CustomAC > 0)
            {
                description += ColorTokenService.Orange("AC: ") + 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.CastingSpeed > 0)
            {
                description += ColorTokenService.Orange("Activation Speed: +") + examinedItem.CastingSpeed + "%\n";
            }
            else if (examinedItem.CastingSpeed < 0)
            {
                description += ColorTokenService.Orange("Activation Penalty: -") + examinedItem.CastingSpeed + "%\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.ForcePotencyBonus > 0)
            {
                description += ColorTokenService.Orange("Force Potency Bonus: ") + examinedItem.ForcePotencyBonus + "\n";
            }
            if (examinedItem.ForceAccuracyBonus > 0)
            {
                description += ColorTokenService.Orange("Force Accuracy Bonus: ") + examinedItem.ForceAccuracyBonus + "\n";
            }
            if (examinedItem.ForceDefenseBonus > 0)
            {
                description += ColorTokenService.Orange("Force Defense Bonus: ") + examinedItem.ForceDefenseBonus + "\n";
            }
            if (examinedItem.ElectricalPotencyBonus > 0)
            {
                description += ColorTokenService.Orange("Electrical Potency Bonus: ") + examinedItem.ElectricalPotencyBonus + "\n";
            }
            if (examinedItem.MindPotencyBonus > 0)
            {
                description += ColorTokenService.Orange("Mind Potency Bonus: ") + examinedItem.MindPotencyBonus + "\n";
            }
            if (examinedItem.LightPotencyBonus > 0)
            {
                description += ColorTokenService.Orange("Light Potency Bonus: ") + examinedItem.LightPotencyBonus + "\n";
            }
            if (examinedItem.DarkPotencyBonus > 0)
            {
                description += ColorTokenService.Orange("Dark Potency Bonus: ") + examinedItem.DarkPotencyBonus + "\n";
            }
            if (examinedItem.ElectricalDefenseBonus > 0)
            {
                description += ColorTokenService.Orange("Electrical Defense Bonus: ") + examinedItem.ElectricalDefenseBonus + "\n";
            }
            if (examinedItem.MindDefenseBonus > 0)
            {
                description += ColorTokenService.Orange("Mind Defense Bonus: ") + examinedItem.MindDefenseBonus + "\n";
            }
            if (examinedItem.LightDefenseBonus > 0)
            {
                description += ColorTokenService.Orange("Light Defense Bonus: ") + examinedItem.LightDefenseBonus + "\n";
            }
            if (examinedItem.DarkDefenseBonus > 0)
            {
                description += ColorTokenService.Orange("Dark Defense Bonus: ") + examinedItem.DarkDefenseBonus + "\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.BaseAttackBonus > 0)
            {
                description += ColorTokenService.Orange("Base Attack Bonus: ") + examinedItem.BaseAttackBonus + "\n";
            }
            if (examinedItem.SneakAttackBonus > 0)
            {
                description += ColorTokenService.Orange("Sneak Attack Bonus: ") + examinedItem.SneakAttackBonus + "\n";
            }
            if (examinedItem.DamageBonus > 0)
            {
                description += ColorTokenService.Orange("Damage Bonus: ") + 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";
            }

            return(existingDescription + "\n" + description);
        }