示例#1
0
        public override void MouseDown(MouseButtonEventArgs eventargs)
        {
            if (playerManager.LocalPlayer == null || placementManager.MouseDown(eventargs))
            {
                return;
            }

            var     map           = playerManager.LocalPlayer.ControlledEntity.GetComponent <ITransformComponent>().MapID;
            var     mousePosWorld = eyeManager.ScreenToWorld(new ScreenCoordinates(eventargs.Position, map));
            IEntity entityToClick = GetEntityUnderPosition(mousePosWorld);

            //First possible exit point for click, acceptable due to being clientside
            if (entityToClick != null && placementManager.Eraser && placementManager.IsActive)
            {
                placementManager.HandleDeletion(entityToClick);
                return;
            }

            ClickType clicktype = eventargs.ClickType;

            //Dispatches clicks to relevant clickable components, another single exit point for UI
            if (entityToClick != null)
            {
                var clickable = entityToClick.GetComponent <IClientClickableComponent>();
                switch (eventargs.ClickType)
                {
                case ClickType.Left:
                    clickable.DispatchClick(playerManager.LocalPlayer.ControlledEntity, ClickType.Left);
                    break;

                case ClickType.Right:
                    clickable.DispatchClick(playerManager.LocalPlayer.ControlledEntity, ClickType.Right);
                    break;

                    /*
                     * //Acceptable click exit due to being a UI behavior
                     * case Mouse.Button.Middle:
                     * OpenEntityEditWindow(entToClick);
                     * return;
                     */
                }
            }

            //Assemble information to send to server about click
            if (clicktype != ClickType.None)
            {
                var UID = EntityUid.Invalid;
                if (entityToClick != null)
                {
                    UID = entityToClick.Uid;
                }

                ClickEventMessage message = new ClickEventMessage(UID, clicktype, mousePosWorld);
                IoCManager.Resolve <IEntityNetworkManager>().SendSystemNetworkMessage(message);
            }
        }
        public void Examine(ClickEventMessage msg, IEntity player)
        {
            //Get entity clicked upon from UID if valid UID, if not assume no entity clicked upon and null
            IEntity examined = null;

            if (msg.Uid.IsValid())
            {
                examined = EntityManager.GetEntity(msg.Uid);
            }

            if (examined == null)
            {
                return;
            }

            //Verify player has a transform component
            if (!player.TryGetComponent <IServerTransformComponent>(out var playerTransform))
            {
                return;
            }
            //Verify player is on the same map as the entity he clicked on
            else if (msg.Coordinates.MapID != playerTransform.MapID)
            {
                Logger.Warning(string.Format("Player named {0} clicked on a map he isn't located on", player.Name));
                return;
            }

            //Start a stringbuilder since we have no idea how many times this could be appended to
            StringBuilder fullexaminetext = new StringBuilder("This is " + examined.Name);

            //Add an entity description if one is declared
            if (!string.IsNullOrEmpty(examined.Description))
            {
                fullexaminetext.Append(Environment.NewLine + examined.Description);
            }

            //Add component statuses from components that report one
            foreach (var examinecomponents in examined.GetAllComponents <IExamine>())
            {
                string componentdescription = examinecomponents.Examine();
                if (!string.IsNullOrEmpty(componentdescription))
                {
                    fullexaminetext.Append(Environment.NewLine + componentdescription);
                }
            }

            //Send to client chat channel
            //TODO: Fix fact you can only send to all clients because you cant resolve clients from player entities
            IoCManager.Resolve <IChatManager>().DispatchMessage(SS14.Shared.Console.ChatChannel.Visual, fullexaminetext.ToString());
        }
示例#3
0
        /// <summary>
        /// Parse click to the relevant entity system
        /// </summary>
        /// <param name="message"></param>
        /// <param name="player"></param>
        private void ParseClickMessage(ClickEventMessage message, IEntity player)
        {
            switch (message.Click)
            {
            case ClickType.Left:
                EntitySystemManager.GetEntitySystem <InteractionSystem>().UserInteraction(message, player);
                break;

            case (ClickType.Left | ClickType.Shift):
                EntitySystemManager.GetEntitySystem <ExamineSystem>().Examine(message, player);
                break;

            case ClickType.Right:
                //Verb System
                break;
            }
        }
示例#4
0
        private void UserInteraction(ClickEventMessage msg, IEntity player)
        {
            //Verify click type
            if (msg.Click != ClickType.Left)
            {
                return;
            }

            //Get entity clicked upon from UID if valid UID, if not assume no entity clicked upon and null
            IEntity attacked = null;

            if (msg.Uid.IsValid())
            {
                attacked = EntityManager.GetEntity(msg.Uid);
            }

            //Verify player has a transform component
            if (!player.TryGetComponent <IServerTransformComponent>(out var playerTransform))
            {
                return;
            }
            //Verify player is on the same map as the entity he clicked on
            else if (msg.Coordinates.MapID != playerTransform.MapID)
            {
                Logger.Warning(string.Format("Player named {0} clicked on a map he isn't located on", player.Name));
                return;
            }

            //Verify player has a hand, and find what object he is currently holding in his active hand
            if (!player.TryGetComponent <IHandsComponent>(out var hands))
            {
                return;
            }
            var item = hands.GetHand(hands.ActiveIndex)?.Owner;


            //TODO: Mob status code that allows or rejects interactions based on current mob status
            //Check if client should be able to see that object to click on it in the first place, prevent using locaters by firing a laser or something

            //Off entity click handling
            if (attacked == null)
            {
                if (item != null)
                {
                    //AFTERATTACK: Check if we clicked on an empty location, if so the only interaction we can do is afterattack
                    InteractAfterattack(player, item, msg.Coordinates);
                    return;
                }
                return;
            }
            //USE: Check if we clicked on the item we are holding in our active hand to use it
            else if (attacked == item && item != null)
            {
                UseInteraction(player, item);
                return;
            }

            //Check if ClickLocation is in object bounds here, if not lets log as warning and see why
            if (attacked != null && attacked.TryGetComponent(out BoundingBoxComponent boundingbox))
            {
                if (!boundingbox.WorldAABB.Contains(msg.Coordinates.Position))
                {
                    Logger.Warning(string.Format("Player {0} clicked {1} outside of its bounding box component somehow", player.Name, attacked.Name));
                    return;
                }
            }

            //RANGEDATTACK/AFTERATTACK: Check distance between user and clicked item, if too large parse it in the ranged function
            //TODO: have range based upon the item being used? or base it upon some variables of the player himself?
            var distance = (playerTransform.WorldPosition - attacked.GetComponent <IServerTransformComponent>().WorldPosition).LengthSquared;

            if (distance > INTERACTION_RANGE_SQUARED)
            {
                if (item != null)
                {
                    RangedInteraction(player, item, attacked, msg.Coordinates);
                    return;
                }
                return; //Add some form of ranged attackhand here if you need it someday, or perhaps just ways to modify the range of attackhand
            }

            //We are close to the nearby object and the object isn't contained in our active hand
            //ATTACKBY/AFTERATTACK: We will either use the item on the nearby object
            if (item != null)
            {
                Interaction(player, item, attacked, msg.Coordinates);
            }
            //ATTACKHAND: Since our hand is empty we will use attackhand
            else
            {
                Interaction(player, attacked);
            }
        }
示例#5
0
        public override void MouseDown(MouseButtonEventArgs eventargs)
        {
            if (playerManager.LocalPlayer == null || placementManager.MouseDown(eventargs))
            {
                return;
            }

            var map           = playerManager.LocalPlayer.ControlledEntity.GetComponent <ITransformComponent>().MapID;
            var mousePosWorld = eyeManager.ScreenToWorld(new ScreenCoordinates(eventargs.Position, map));

            // Find all the entities intersecting our click
            var entities =
                _entityManager.GetEntitiesIntersecting(mousePosWorld.MapID, mousePosWorld.Position);

            // Check the entities against whether or not we can click them
            var clickedEntities = new List <(IEntity clicked, int drawDepth)>();

            foreach (IEntity entity in entities)
            {
                if (entity.TryGetComponent <IClientClickableComponent>(out var component) &&
                    entity.GetComponent <ITransformComponent>().IsMapTransform &&
                    component.CheckClick(mousePosWorld, out int drawdepthofclicked))
                {
                    clickedEntities.Add((entity, drawdepthofclicked));
                }
            }

            IEntity entityToClick;

            if (clickedEntities.Any())
            {
                entityToClick = (from cd in clickedEntities
                                 orderby cd.drawDepth ascending,
                                 cd.clicked.GetComponent <ITransformComponent>().LocalPosition
                                 .Y ascending
                                 select cd.clicked).Last();
            }
            else
            {
                entityToClick = null;
            }

            //First possible exit point for click, acceptable due to being clientside
            if (entityToClick != null && placementManager.Eraser && placementManager.IsActive)
            {
                placementManager.HandleDeletion(entityToClick);
                return;
            }

            ClickType clicktype = eventargs.ClickType;

            //Dispatches clicks to relevant clickable components, another single exit point for UI
            if (entityToClick != null)
            {
                var clickable = entityToClick.GetComponent <IClientClickableComponent>();
                switch (eventargs.ClickType)
                {
                case ClickType.Left:
                    clickable.DispatchClick(playerManager.LocalPlayer.ControlledEntity, ClickType.Left);
                    break;

                case ClickType.Right:
                    clickable.DispatchClick(playerManager.LocalPlayer.ControlledEntity, ClickType.Right);
                    break;

                    /*
                     * //Acceptable click exit due to being a UI behavior
                     * case Mouse.Button.Middle:
                     * OpenEntityEditWindow(entToClick);
                     * return;
                     */
                }
            }

            //Assemble information to send to server about click
            if (clicktype != ClickType.None)
            {
                var UID = EntityUid.Invalid;
                if (entityToClick != null)
                {
                    UID = entityToClick.Uid;
                }

                ClickEventMessage message = new ClickEventMessage(UID, clicktype, mousePosWorld);
                IoCManager.Resolve <IEntityNetworkManager>().SendSystemNetworkMessage(message);
            }
        }
示例#6
0
        /// <summary>
        /// 返回具体事件类型
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected RequestMessage ToMessage(XmlNode node)
        {
            RequestMessage message = null;

            switch (this.Event)
            {
            case EventType.Click:
                ClickEventMessage cm = this.Copy <ClickEventMessage>();
                cm.EventKey = GetValue(node, "EventKey");
                message     = cm;
                break;

            case EventType.Scan:
                //是二维码扫描事件
                QCodeEventMessage m = this.Copy <QCodeEventMessage>();
                m.Ticket   = GetValue(node, "Ticket");
                m.EventKey = GetValue(node, "EventKey");
                message    = m;
                break;

            case EventType.Location:
                //是地理位置事件
                LocationEventMessage lm = this.Copy <LocationEventMessage>();
                lm.Latitude  = Convert.ToDouble(GetValue(node, "Latitude"));
                lm.Longitude = Convert.ToDouble(GetValue(node, "Longitude"));
                lm.Precision = Convert.ToDouble(GetValue(node, "Precision"));
                message      = lm;
                break;

            case EventType.View:
                ViewEventMessage vm = this.Copy <ViewEventMessage>();
                vm.EventKey = GetValue(node, "EventKey");
                message     = vm;
                break;

            case EventType.Subscribe:
                //分2种  用户未关注时,进行关注后的事件推送 / 关注事件
                string ticekt = GetValue(node, "Ticket");
                if (ticekt == null)
                {
                    //是关注事件
                    message = this.Copy <SubscribeEventMessage>();
                }
                else
                {
                    QCodeEventMessage mm = this.Copy <QCodeEventMessage>();
                    mm.Ticket   = GetValue(node, "Ticket");
                    mm.EventKey = GetValue(node, "EventKey");
                    message     = mm;
                }
                break;

            case EventType.UnSubscribe:
                //是取消关注事件
                message = this.Copy <SubscribeEventMessage>();
                break;

            default:
                message = this;
                break;
            }


            return(message);
        }
示例#7
0
 public virtual void RaiseClick(ClickEventMessage message)
 {
     //TODO: Check modifiers here and modify the click type of the message?
     RaiseNetworkEvent(message);
 }