public override bool HandleMouseInput(MouseInput mi)
        {
            var xy = worldRenderer.Viewport.ViewToWorldPx(mi.Location);

            var useClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle;

            var hasBox     = SelectionBox != null;
            var multiClick = mi.MultiTapCount >= 2;

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
            {
                if (!TakeMouseFocus(mi))
                {
                    return(false);
                }

                dragStart = xy;

                // Place buildings, use support powers, and other non-unit things
                if (!(World.OrderGenerator is UnitOrderGenerator))
                {
                    ApplyOrders(World, mi);
                    dragStart = dragEnd = null;
                    YieldMouseFocus(mi);
                    lastMousePosition = xy;
                    return(true);
                }
            }

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move && dragStart.HasValue)
            {
                dragEnd = xy;
            }

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
            {
                if (World.OrderGenerator is UnitOrderGenerator)
                {
                    if (useClassicMouseStyle && HasMouseFocus)
                    {
                        if (!hasBox && World.Selection.Actors.Any() && !multiClick)
                        {
                            if (!(World.ScreenMap.ActorsAt(xy).Any(x => x.Info.HasTraitInfo <SelectableInfo>() &&
                                                                   (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))) && !mi.Modifiers.HasModifier(Modifiers.Ctrl) &&
                                  !mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi)))
                            {
                                // Order units instead of selecting
                                ApplyOrders(World, mi);
                                dragStart = dragEnd = null;
                                YieldMouseFocus(mi);
                                lastMousePosition = xy;
                                return(true);
                            }
                        }
                    }

                    if (multiClick)
                    {
                        var unit = World.ScreenMap.ActorsAt(xy)
                                   .WithHighestSelectionPriority();

                        if (unit != null && unit.Owner == (World.RenderPlayer ?? World.LocalPlayer))
                        {
                            var s = unit.TraitOrDefault <Selectable>();
                            if (s != null)
                            {
                                // Select actors on the screen that have the same selection class as the actor under the mouse cursor
                                var newSelection = SelectActorsOnScreen(World, worldRenderer, new HashSet <string> {
                                    s.Class
                                }, unit.Owner);

                                World.Selection.Combine(World, newSelection, true, false);
                            }
                        }
                    }
                    else
                    {
                        /* The block below does three things:
                         * // 1. Allows actor selection using a selection box regardless of input mode.
                         * // 2. Allows actor deselection with a single click in the default input mode (UnitOrderGenerator).
                         * // 3. Prevents units from getting deselected when exiting input modes (eg. AttackMove or Guard).
                         * //
                         * // We cannot check for UnitOrderGenerator here since it's the default order generator that gets activated in
                         * // World.CancelInputMode. If we did check it, actor de-selection would not be possible by just clicking somewhere,
                         * // only by dragging an empty selection box.
                         */
                        if (dragStart.HasValue && (!(World.OrderGenerator is GenericSelectTarget) || hasBox))
                        {
                            // Select actors in the dragbox
                            var newSelection = SelectActorsInBoxWithDeadzone(World, dragStart.Value, xy);
                            World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
                        }
                    }

                    World.CancelInputMode();
                }

                dragStart = dragEnd = null;
                YieldMouseFocus(mi);
            }

            if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Up)
            {
                // Don't do anything while selecting
                if (!hasBox)
                {
                    if (useClassicMouseStyle)
                    {
                        World.Selection.Clear();
                    }

                    ApplyOrders(World, mi);
                }
            }

            lastMousePosition = xy;

            return(true);
        }
Esempio n. 2
0
        public override bool HandleMouseInput(MouseInput mi)
        {
            var xy = worldRenderer.Viewport.ViewToWorldPx(mi.Location);

            var useClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle;

            var hasBox     = SelectionBox != null;
            var multiClick = mi.MultiTapCount >= 2;

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
            {
                if (!TakeMouseFocus(mi))
                {
                    return(false);
                }

                dragStart = xy;

                // Place buildings, use support powers, and other non-unit things
                if (!(World.OrderGenerator is UnitOrderGenerator))
                {
                    ApplyOrders(World, mi);
                    dragStart = dragEnd = null;
                    YieldMouseFocus(mi);
                    lastMousePosition = xy;
                    return(true);
                }
            }

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move && dragStart.HasValue)
            {
                dragEnd = xy;
            }

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
            {
                if (World.OrderGenerator is UnitOrderGenerator)
                {
                    if (useClassicMouseStyle && HasMouseFocus)
                    {
                        if (!hasBox && World.Selection.Actors.Any() && !multiClick)
                        {
                            if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.HasTrait <Selectable>() &&
                                                                     (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))).Any() && !mi.Modifiers.HasModifier(Modifiers.Ctrl) &&
                                  !mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi)))
                            {
                                // Order units instead of selecting
                                ApplyOrders(World, mi);
                                dragStart = dragEnd = null;
                                YieldMouseFocus(mi);
                                lastMousePosition = xy;
                                return(true);
                            }
                        }
                    }

                    if (multiClick)
                    {
                        var unit = World.ScreenMap.ActorsAt(xy)
                                   .WithHighestSelectionPriority();

                        if (unit != null && unit.Owner == (World.RenderPlayer ?? World.LocalPlayer))
                        {
                            var s = unit.TraitOrDefault <Selectable>();
                            if (s != null)
                            {
                                // Select actors on the screen that have the same selection class as the actor under the mouse cursor
                                var newSelection = SelectActorsOnScreen(World, worldRenderer, new HashSet <string> {
                                    s.Class
                                }, unit.Owner);

                                World.Selection.Combine(World, newSelection, true, false);
                            }
                        }
                    }
                    else if (dragStart.HasValue)
                    {
                        // Select actors in the dragbox
                        var newSelection = SelectActorsInBoxWithDeadzone(World, dragStart.Value, xy);
                        World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
                    }
                }

                dragStart = dragEnd = null;
                YieldMouseFocus(mi);
            }

            if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down)
            {
                // Don't do anything while selecting
                if (!hasBox)
                {
                    if (useClassicMouseStyle)
                    {
                        World.Selection.Clear();
                    }

                    ApplyOrders(World, mi);
                }
            }

            lastMousePosition = xy;

            return(true);
        }