public override void Draw() { var modifiers = Game.GetModifierKeys(); IEnumerable <Actor> rollover; if (IsValidDragbox) { var a = worldRenderer.Viewport.WorldToViewPx(dragStart); var b = worldRenderer.Viewport.WorldToViewPx(mousePos); var color = normalSelectionColor; if (modifiers.HasFlag(Modifiers.Alt) && !modifiers.HasFlag(Modifiers.Ctrl)) { color = altSelectionColor; } else if (modifiers.HasFlag(Modifiers.Ctrl) && !modifiers.HasFlag(Modifiers.Alt)) { color = ctrlSelectionColor; } Game.Renderer.RgbaColorRenderer.DrawRect(a, b, 1, color); // Render actors in the dragbox rollover = SelectionUtils.SelectActorsInBoxWithDeadzone(World, dragStart, mousePos, modifiers); } else { // Render actors under the mouse pointer rollover = SelectionUtils.SelectActorsInBoxWithDeadzone(World, mousePos, mousePos, modifiers); } worldRenderer.World.Selection.SetRollover(rollover); }
public override bool HandleMouseInput(MouseInput mi) { mousePos = worldRenderer.Viewport.ViewToWorldPx(mi.Location); var useClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle; var multiClick = mi.MultiTapCount >= 2; if (!(World.OrderGenerator is UnitOrderGenerator uog)) { ApplyOrders(World, mi); isDragging = false; YieldMouseFocus(mi); return(true); } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { if (!TakeMouseFocus(mi)) { return(false); } dragStart = mousePos; isDragging = true; } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { if (useClassicMouseStyle && HasMouseFocus) { if (!IsValidDragbox && World.Selection.Actors.Any() && !multiClick && uog.InputOverridesSelection(World, mousePos, mi)) { // Order units instead of selecting ApplyOrders(World, mi); isDragging = false; YieldMouseFocus(mi); return(true); } } if (multiClick) { var unit = World.ScreenMap.ActorsAtMouse(mousePos) .WithHighestSelectionPriority(mousePos, mi.Modifiers); var eligiblePlayers = SelectionUtils.GetPlayersToIncludeInSelection(World); if (unit != null && eligiblePlayers.Contains(unit.Owner)) { var s = unit.TraitOrDefault <ISelectable>(); if (s != null) { // Select actors on the screen that have the same selection class as the actor under the mouse cursor var newSelection = SelectionUtils.SelectActorsOnScreen(World, worldRenderer, new HashSet <string> { s.Class }, eligiblePlayers); 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 (isDragging && (uog.ClearSelectionOnLeftClick || IsValidDragbox)) { var newSelection = SelectionUtils.SelectActorsInBoxWithDeadzone(World, dragStart, mousePos, mi.Modifiers); World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == mousePos); } } World.CancelInputMode(); isDragging = false; YieldMouseFocus(mi); } if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Up) { // Don't do anything while selecting if (!IsValidDragbox) { if (useClassicMouseStyle) { World.Selection.Clear(); } ApplyOrders(World, mi); } } return(true); }