예제 #1
0
        public static void TransferLeadership()
        {
            var player  = Object.StringToObject(Events.GetEventData("NEW_LEADER"));
            var partyId = _playerToParty[player];

            _partyLeaders[partyId] = player;
        }
예제 #2
0
        public static void JoinParty()
        {
            var player    = OBJECT_SELF;
            var requester = Object.StringToObject(Events.GetEventData("INVITED_BY"));

            // This is a brand new party.
            // Add both the requester and the player to the cache.
            // Mark the requester as the party leader.
            if (!_playerToParty.ContainsKey(requester))
            {
                var partyId = Guid.NewGuid();
                _parties[partyId] = new List <uint>
                {
                    requester,
                    player
                };
                _partyLeaders[partyId]    = requester;
                _playerToParty[player]    = partyId;
                _playerToParty[requester] = partyId;
            }
            // This is an existing party.
            // Add the player to the party cache.
            else
            {
                var partyId = _playerToParty[requester];
                _parties[partyId].Add(player);
                _playerToParty[player] = partyId;
            }
        }
예제 #3
0
        public static void UseOpenRestMenuFeat()
        {
            var player = OBJECT_SELF;
            var feat   = (Feat)Convert.ToInt32(Events.GetEventData("FEAT_ID"));

            if (feat != Feat.ChatCommandTargeter)
            {
                return;
            }

            var target  = Object.StringToObject(Events.GetEventData("TARGET_OBJECT_ID"));
            var area    = Object.StringToObject(Events.GetEventData("AREA_OBJECT_ID"));
            var targetX = (float)Convert.ToDouble(Events.GetEventData("TARGET_POSITION_X"));
            var targetY = (float)Convert.ToDouble(Events.GetEventData("TARGET_POSITION_Y"));
            var targetZ = (float)Convert.ToDouble(Events.GetEventData("TARGET_POSITION_Z"));

            var targetLocation = Location(area, new Vector(targetX, targetY, targetZ), 0.0f);
            var command        = GetLocalString(player, "CHAT_COMMAND");
            var args           = GetLocalString(player, "CHAT_COMMAND_ARGS");

            if (string.IsNullOrWhiteSpace(command))
            {
                SendMessageToPC(player, "Please enter a chat command and then use this feat. Type /help to learn more about the available chat commands.");
                return;
            }

            ProcessChatCommand(command, player, target, targetLocation, args);

            DeleteLocalString(player, "CHAT_COMMAND");
            DeleteLocalString(player, "CHAT_COMMAND_ARGS");
        }
예제 #4
0
        public static void UseFeat()
        {
            var activator = OBJECT_SELF;
            var target    = Object.StringToObject(Events.GetEventData("TARGET_OBJECT_ID"));
            var feat      = (Feat)Convert.ToInt32(Events.GetEventData("FEAT_ID"));

            if (!Ability.IsFeatRegistered(feat))
            {
                return;
            }
            var ability = Ability.GetAbilityDetail(feat);

            // Creature cannot use the feat.
            var effectivePerkLevel = Perk.GetEffectivePerkLevel(activator, ability.EffectiveLevelPerkType);

            if (!CanUseAbility(activator, target, ability, effectivePerkLevel))
            {
                return;
            }

            Messaging.SendMessageNearbyToPlayers(activator, $"{GetName(activator)} readies {ability.Name}.");

            // Weapon abilties are queued for the next time the activator's attack lands on an enemy.
            if (ability.ActivationType == AbilityActivationType.Weapon)
            {
                QueueWeaponAbility(activator, ability, feat, effectivePerkLevel);
            }
            // All other abilities are funneled through the same process.
            else
            {
                ActivateAbility(activator, target, ability, effectivePerkLevel);
            }
        }
예제 #5
0
        /// <summary>
        /// When an item is equipped, if any of a player's perks has an Equipped Trigger, run those actions now.
        /// </summary>
        private static void ApplyEquipTriggers()
        {
            var player = OBJECT_SELF;

            if (!GetIsPC(player) || GetIsDM(player))
            {
                return;
            }

            var playerId = GetObjectUUID(player);
            var dbPlayer = DB.Get <Player>(playerId);
            var item     = Object.StringToObject(Events.GetEventData("ITEM"));
            var slot     = (InventorySlot)Convert.ToInt32(Events.GetEventData("SLOT"));

            foreach (var(perkType, actionList) in Perk.GetAllEquipTriggers())
            {
                var playerPerkLevel = Perk.GetEffectivePerkLevel(player, perkType);
                if (playerPerkLevel <= 0)
                {
                    continue;
                }

                foreach (var action in actionList)
                {
                    action(player, item, slot, perkType, playerPerkLevel);
                }
            }
        }
예제 #6
0
        public static void RemoveBarteringFlag()
        {
            var player1 = OBJECT_SELF;
            var player2 = Object.StringToObject(Events.GetEventData("BARTER_TARGET"));

            DeleteLocalBool(player1, "IS_BARTERING");
            DeleteLocalBool(player2, "IS_BARTERING");
        }
예제 #7
0
        public static void SetBarteringFlag()
        {
            var player1 = OBJECT_SELF;
            var player2 = Object.StringToObject(Events.GetEventData("BARTER_TARGET"));

            SetLocalBool(player1, "IS_BARTERING", true);
            SetLocalBool(player2, "IS_BARTERING", true);
        }
예제 #8
0
        public static void ValidateItemUse()
        {
            var creature = OBJECT_SELF;
            var item     = Object.StringToObject(Events.GetEventData("ITEM_OBJECT_ID"));

            Events.SetEventResult(string.IsNullOrWhiteSpace(CanItemBeUsed(creature, item)) ? "1" : "0");
            Events.SkipEvent();
        }
예제 #9
0
        public static void ValidateDualWield()
        {
            var creature = OBJECT_SELF;
            var item     = Object.StringToObject(Events.GetEventData("ITEM"));
            var slot     = (InventorySlot)Convert.ToInt32(Events.GetEventData("SLOT"));

            // Not equipping to the left hand, or there's nothing equipped in the right hand.
            if (slot != InventorySlot.LeftHand)
            {
                return;
            }
            if (!GetIsObjectValid(GetItemInSlot(InventorySlot.RightHand, creature)))
            {
                return;
            }

            var baseItem         = GetBaseItemType(item);
            var dualWieldWeapons = new[]
            {
                BaseItem.ShortSword,
                BaseItem.Longsword,
                BaseItem.BattleAxe,
                BaseItem.BastardSword,
                BaseItem.LightFlail,
                BaseItem.LightMace,
                BaseItem.Dagger,
                BaseItem.Club,
                BaseItem.HandAxe,
                BaseItem.Kama,
                BaseItem.Katana,
                BaseItem.Kukri,
                BaseItem.Rapier,
                BaseItem.Scimitar,
                BaseItem.Sickle
            };

            if (!dualWieldWeapons.Contains(baseItem))
            {
                return;
            }

            var dualWieldLevel = Perk.GetEffectivePerkLevel(creature, PerkType.DualWield);

            if (dualWieldLevel <= 0)
            {
                SendMessageToPC(creature, ColorToken.Red("Equipping two weapons requires the Dual Wield perk."));
                Events.SkipEvent();
            }
        }
예제 #10
0
        public static void OnUseItem()
        {
            var creature = OBJECT_SELF;
            var item     = Object.StringToObject(Events.GetEventData("ITEM_OBJECT_ID"));
            var script   = GetLocalString(item, "SCRIPT");

            // No script associated. Let it run the normal execution process.
            if (string.IsNullOrWhiteSpace(script))
            {
                return;
            }

            Events.SkipEvent();
            Events.SetEventResult("0"); // Prevents the "You cannot use that item" error message from being sent.
            ExecuteScript(script, creature);
        }
예제 #11
0
        public static void ValidateItemEquip()
        {
            var creature = OBJECT_SELF;
            var item     = Object.StringToObject(Events.GetEventData("ITEM"));

            var error = CanItemBeUsed(creature, item);

            if (string.IsNullOrWhiteSpace(error))
            {
                ApplyEquipTriggers();
                return;
            }

            SendMessageToPC(creature, ColorToken.Red(error));
            Events.SkipEvent();
        }
예제 #12
0
        public static void AddItemToBankStorage()
        {
            var container = OBJECT_SELF;

            if (GetResRef(container) != "bank_chest" || GetLocalBool(container, "IS_DESERIALIZING"))
            {
                return;
            }

            var item      = Object.StringToObject(Events.GetEventData("ITEM"));
            var player    = GetItemPossessor(item);
            var playerId  = GetObjectUUID(player);
            var storageId = GetStorageID();
            var key       = $"{storageId}:{playerId}";

            AddItem(key, "Bank");
        }
예제 #13
0
        public static void UsePerkRefundTome()
        {
            var player = OBJECT_SELF;

            if (!GetIsPC(player) || GetIsDM(player))
            {
                return;
            }
            var item = Object.StringToObject(Events.GetEventData("ITEM_OBJECT_ID"));

            if (GetResRef(item) != "refund_tome")
            {
                return;
            }

            SetLocalObject(player, "PERK_REFUND_OBJECT", item);
            AssignCommand(player, () => ClearAllActions());
            Dialog.StartConversation(player, player, "PerkRefundDialog");

            // Don't display the "You cannot use this item" message. Skip the event.
            Events.SetEventResult("1");
            Events.SkipEvent();
        }
예제 #14
0
        public static void LearnRecipes()
        {
            var user = OBJECT_SELF;

            if (!GetIsPC(user) || GetIsDM(user))
            {
                SendMessageToPC(user, "Only players may use this item.");
                return;
            }

            var item           = Object.StringToObject(Events.GetEventData("ITEM_OBJECT_ID"));
            var playerId       = GetObjectUUID(user);
            var dbPlayer       = DB.Get <Player>(playerId);
            var recipeList     = GetLocalString(item, "RECIPES");
            var recipeIds      = recipeList.Split(',');
            var recipesLearned = 0;

            foreach (var recipeId in recipeIds)
            {
                // If it fails to parse, exit early.
                if (!int.TryParse(recipeId, out var convertedId))
                {
                    SendMessageToPC(user, "This recipe book has a configuration problem. Please inform a DM.");
                    return;
                }

                // Id number is zero or negative. Skip as those aren't valid.
                if (convertedId <= 0)
                {
                    SendMessageToPC(user, "This recipe book has a configuration problem. Please inform a DM.");
                    return;
                }

                var recipeType = (RecipeType)convertedId;

                // Ensure this type of recipe has been registered.
                if (!Craft.RecipeExists(recipeType))
                {
                    SendMessageToPC(user, "This recipe has not been registered. Please inform a DM.");
                    return;
                }

                // Player already knows this recipe. Move to the next one.
                if (dbPlayer.UnlockedRecipes.ContainsKey(recipeType))
                {
                    continue;
                }

                recipesLearned++;
                dbPlayer.UnlockedRecipes[recipeType] = DateTime.UtcNow;

                var recipeDetail = Craft.GetRecipe(recipeType);
                var skillDetail  = Skill.GetSkillDetails(recipeDetail.Skill);
                SendMessageToPC(user, $"You learn the {skillDetail.Name} recipe: {recipeDetail.Name}.");
            }

            // Player didn't learn any recipes. Let them know but don't destroy the item.
            if (recipesLearned <= 0)
            {
                SendMessageToPC(user, "You have already learned all of the recipes contained in this book.");
                return;
            }

            DestroyObject(item);
        }
예제 #15
0
        public static void LeaveParty()
        {
            var player = Object.StringToObject(Events.GetEventData("LEAVING"));

            RemovePlayerFromParty(player);
        }