Пример #1
0
 public void EnqueueBroadcastUpdateObject()
 {
     if (CurrentLandblock != null)
     {
         GameMessage msg = new GameMessageUpdateObject(this);
         CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, msg);
     }
 }
Пример #2
0
        public static void UseObjectOnTarget(Player player, WorldObject source, WorldObject target)
        {
            if (player.IsBusy)
            {
                player.SendUseDoneEvent(WeenieError.YoureTooBusy);
                return;
            }

            if (source == target)
            {
                var message = new GameMessageSystemChat($"The {source.Name} cannot be combined with itself.", ChatMessageType.Craft);
                player.Session.Network.EnqueueSend(message);
                player.SendUseDoneEvent();
                return;
            }

            var recipe = DatabaseManager.World.GetCachedCookbook(source.WeenieClassId, target.WeenieClassId);

            if (recipe == null)
            {
                var message = new GameMessageSystemChat($"The {source.Name} cannot be used on the {target.Name}.", ChatMessageType.Craft);
                player.Session.Network.EnqueueSend(message);
                player.SendUseDoneEvent();
                return;
            }

            // verify requirements
            if (!VerifyRequirements(recipe.Recipe, player, source, target))
            {
                player.SendUseDoneEvent(WeenieError.YouDoNotPassCraftingRequirements);
                return;
            }

            if (source.ItemType == ItemType.TinkeringMaterial)
            {
                HandleTinkering(player, source, target);
                return;
            }

            ActionChain   craftChain     = new ActionChain();
            CreatureSkill skill          = null;
            bool          success        = true; // assume success, unless there's a skill check
            double        percentSuccess = 1;

            player.IsBusy = true;

            if (player.CombatMode != CombatMode.NonCombat)
            {
                var stanceTime = player.SetCombatMode(CombatMode.NonCombat);
                craftChain.AddDelaySeconds(stanceTime);
            }

            var motion = new Motion(MotionStance.NonCombat, MotionCommand.ClapHands);

            craftChain.AddAction(player, () => player.EnqueueBroadcastMotion(motion));
            var motionTable          = DatManager.PortalDat.ReadFromDat <MotionTable>(player.MotionTableId);
            var craftAnimationLength = motionTable.GetAnimationLength(MotionCommand.ClapHands);

            craftChain.AddDelaySeconds(craftAnimationLength);

            craftChain.AddAction(player, () =>
            {
                if (recipe.Recipe.Skill > 0 && recipe.Recipe.Difficulty > 0)
                {
                    // there's a skill associated with this
                    Skill skillId = (Skill)recipe.Recipe.Skill;

                    // this shouldn't happen, but sanity check for unexpected nulls
                    skill = player.GetCreatureSkill(skillId);

                    if (skill == null)
                    {
                        log.Warn("Unexpectedly missing skill in Recipe usage");
                        player.SendUseDoneEvent();
                        player.IsBusy = false;
                        return;
                    }

                    //Console.WriteLine("Skill difficulty: " + recipe.Recipe.Difficulty);

                    percentSuccess = skill.GetPercentSuccess(recipe.Recipe.Difficulty); //FIXME: Pretty certain this is broken
                }

                if (skill != null)
                {
                    // check for pre-MoA skill
                    // convert into appropriate post-MoA skill
                    // pre-MoA melee weapons: get highest melee weapons skill
                    var newSkill = player.ConvertToMoASkill(skill.Skill);
                    skill        = player.GetCreatureSkill(newSkill);

                    //Console.WriteLine("Required skill: " + skill.Skill);

                    if (skill.AdvancementClass <= SkillAdvancementClass.Untrained)
                    {
                        var message = new GameEventWeenieError(player.Session, WeenieError.YouAreNotTrainedInThatTradeSkill);
                        player.Session.Network.EnqueueSend(message);
                        player.SendUseDoneEvent(WeenieError.YouAreNotTrainedInThatTradeSkill);
                        player.IsBusy = false;
                        return;
                    }
                }

                // perform skill check, if applicable
                if (skill != null)
                {
                    success = ThreadSafeRandom.Next(0.0f, 1.0f) <= percentSuccess;
                }

                CreateDestroyItems(player, recipe.Recipe, source, target, success);

                // this code was intended for dyes, but UpdateObj seems to remove crafting components
                // from shortcut bar, if they are hotkeyed
                // more specifity for this, only if relevant properties are modified?
                var shortcuts = player.GetShortcuts();
                if (!shortcuts.Select(i => i.ObjectId).Contains(target.Guid.Full))
                {
                    var updateObj  = new GameMessageUpdateObject(target);
                    var updateDesc = new GameMessageObjDescEvent(player);

                    if (target.CurrentWieldedLocation != null)
                    {
                        player.EnqueueBroadcast(updateObj, updateDesc);
                    }
                    else
                    {
                        player.Session.Network.EnqueueSend(updateObj);
                    }
                }

                player.SendUseDoneEvent();
                player.IsBusy = false;
            });

            craftChain.EnqueueChain();
        }