internal override bool MouseMoved(IGameViewport viewport, MessageMouseArgs args)
    {
        var sourceLocation = Picker.caster.GetLocationFull();
        var radius         = Picker.caster.GetRadius();
        var targetLocation = GameViews.Primary.ScreenToTile(args.X, args.Y);

        PickerStatusFlags &= ~(PickerStatusFlags.Invalid | PickerStatusFlags.OutOfRange);

        if (Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.Range))
        {
            var distance = sourceLocation.DistanceTo(targetLocation) - radius;
            if (distance > Picker.range)
            {
                PickerStatusFlags |= PickerStatusFlags.OutOfRange;
            }
        }

        if (Picker.modeTarget.HasFlag(UiPickerType.LocIsClear))
        {
            if (!IsTargetLocationClear(targetLocation))
            {
                PickerStatusFlags |= PickerStatusFlags.Invalid;
            }
        }

        return(true);
    }
    internal override bool LeftMouseButtonReleased(IGameViewport viewport, MessageMouseArgs args)
    {
        ClearResults();

        var targetLocation = GameViews.Primary.ScreenToTile(args.X, args.Y);

        var distance = Picker.caster.GetLocationFull().DistanceTo(targetLocation);

        // TODO: This seems like a bug, since range seems to be in feet, but the distance is in inches
        // TODO: Second bug: Radius of caster is ignored (see MouseMove)
        if (distance >= Picker.range)
        {
            return(true);
        }


        if (Picker.modeTarget.HasFlag(UiPickerType.LocIsClear))
        {
            if (!IsTargetLocationClear(targetLocation))
            {
                return(true);
            }
        }

        SetResultLocation(targetLocation);
        return(FinalizePicker());
    }
    private void ResizeViewport(IGameViewport viewport)
    {
        _viewportSize = viewport.Size;
        _viewportZoom = viewport.Zoom;

        // Calculate the tile locations in each corner of the screen
        var topLeftLoc     = viewport.ScreenToTile(0, 0);
        var topRightLoc    = viewport.ScreenToTile(_viewportSize.Width, 0);
        var bottomLeftLoc  = viewport.ScreenToTile(0, _viewportSize.Height);
        var bottomRightLoc = viewport.ScreenToTile(_viewportSize.Width, _viewportSize.Height);

        _fogScreenBufferOrigin.locx = topRightLoc.location.locx;
        _fogScreenBufferOrigin.locy = topLeftLoc.location.locy;

        // Whatever the point of this may be ...
        if (topLeftLoc.off_y < topLeftLoc.off_x || topLeftLoc.off_y < -topLeftLoc.off_x)
        {
            _fogScreenBufferOrigin.locy--;
        }

        _fogScreenBufferWidthSubtiles  = (bottomLeftLoc.location.locx - _fogScreenBufferOrigin.locx + 3) * 3;
        _fogScreenBufferHeightSubtiles = (bottomRightLoc.location.locy - _fogScreenBufferOrigin.locy + 3) * 3;

        if (_fogScreenBuffer == null || _fogScreenBuffer.Length !=
            _fogScreenBufferWidthSubtiles * _fogScreenBufferHeightSubtiles)
        {
            _fogScreenBuffer = new byte[_fogScreenBufferWidthSubtiles * _fogScreenBufferHeightSubtiles];
            // TODO: Changing this should not invalidate the line of sight info per party member
            _lineOfSightInvalidated = true;
        }
    }
    public void Render(IGameViewport viewport)
    {
        if (AtEnd)
        {
            return;
        }

        var elapsed = (int)(TimePoint.Now - _start).TotalMilliseconds;

        for (var i = 0; i < _targets.Count; i++)
        {
            // The elapsed time relative to the time-window where the arc for this target should be shown
            // Target arcs are staggered 256ms from the effect start
            var targetElapsed = elapsed - i * ChainLightningRenderer.ChainDelay;
            if (targetElapsed is >= 0 and < ChainLightningRenderer.Duration)
            {
                var target = _targets[i];
                // Trigger the effect as soon as the arc to the target becomes visible
                target.TriggerEffect();

                var from = i > 0 ? _targets[i - 1].Location : _source;
                _renderer.Render(viewport.Camera, i, targetElapsed, from, target.Location);
            }
        }

        // The effect ends after the delay for every target past the first and then the arc duration has elapsed.
        var totalDuration = (_targets.Count - 1) * ChainLightningRenderer.ChainDelay
                            + ChainLightningRenderer.Duration;

        if (elapsed > totalDuration)
        {
            AtEnd = true;
        }
    }
 public void Render(IGameViewport viewport)
 {
     if (RenderFor >= 0 && RenderFor < GameSystems.Party.PartySize)
     {
         RenderLineOfSight(viewport, RenderFor);
     }
 }
    internal override bool MouseMoved(IGameViewport viewport, MessageMouseArgs args)
    {
        ClearResults();
        PickerStatusFlags |= PickerStatusFlags.Invalid;

        var raycastFlags = PickerState.GetFlagsFromExclusions();

        GameSystems.Raycast.PickObjectOnScreen(viewport, args.X, args.Y, out var target, raycastFlags);

        PickerState.Target = target;
        if (target != Picker.caster)
        {
            return(false);
        }

        PickerStatusFlags &= ~PickerStatusFlags.Invalid;

        if (!Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.Radius))
        {
            Picker.SetSingleTgt(target);
        }
        else
        {
            Picker.SetAreaTargets(target.GetLocationFull());
        }

        return(false);
    }
예제 #7
0
 public Camera(IGameViewport gameCanvas)
 {
     this.gameCanvas = gameCanvas;
     ZoomTarget      = () => Vector2.Zero;
     Zoom            = 1.0f;
     ZoomTarget      = () => { return(ViewportCenter); };
 }
예제 #8
0
    public void ScrollBy(IGameViewport viewport, int x, int y)
    {
        var translationX = GameSystems.Location.LocationTranslationX;
        var translationY = GameSystems.Location.LocationTranslationY;

        var screenWidth  = (int)viewport.Camera.GetViewportWidth();
        var screenHeight = (int)viewport.Camera.GetViewportHeight();

        // Perform clamping to the scroll-limit on the x/y values
        if (!IsEditor)
        {
            if (x + translationX >= _currentLimits.Right + screenWidth)
            {
                if (x + translationX > _currentLimits.Left)
                {
                    x = _currentLimits.Left - translationX;
                }
            }
            else
            {
                x = _currentLimits.Right + screenWidth - translationX;
            }

            if (y + translationY < _currentLimits.Bottom + screenHeight)
            {
                y = _currentLimits.Bottom + screenHeight - translationY;
            }
            else if (y + translationY > _currentLimits.Top)
            {
                y = _currentLimits.Top - translationY;
            }
        }

        GameSystems.Location.AddTranslation(x, y);
    }
예제 #9
0
    private void HandleNormalModeMessage(IGameViewport viewport, Message msg)
    {
        if (msg.type == MessageType.MOUSE)
        {
            if (UiSystems.CharSheet.HasCurrentCritter)
            {
                return;
            }

            var args  = msg.MouseArgs;
            var flags = args.flags;
            if (flags.HasFlag(MouseEventFlag.LeftReleased))
            {
                HandleNormalLeftMouseReleased(viewport, args);
            }
            else if (flags.HasFlag(MouseEventFlag.LeftClick) ||
                     (flags & (MouseEventFlag.PosChange | MouseEventFlag.LeftHeld)) != default)
            {
                HandleNormalLeftMouseDragHandler(viewport, args);
            }
            else if (flags.HasFlag(MouseEventFlag.RightClick))
            {
                HandleNormalRightMouseButton(viewport, args);
            }
            else if (flags.HasFlag(MouseEventFlag.PosChange) || flags.HasFlag(MouseEventFlag.PosChangeSlow))
            {
                HandleMouseMove(viewport, args);
            }
        }
        else if (msg.type == MessageType.KEYSTATECHANGE)
        {
            HandleNormalKeyStateChange(viewport, msg.KeyStateChangeArgs);
        }
    }
예제 #10
0
 public void Render(IGameViewport viewport)
 {
     UiSystems.InGameSelect.RenderMovementTargets(viewport);
     UiSystems.InGameSelect.RenderMouseoverOrSth(viewport);
     UiSystems.RadialMenu.Render(); // TODO: Radial Menu should not become a "game" render aspect, but rather a UI render aspect
     UiSystems.InGameSelect.RenderPickers(viewport);
 }
예제 #11
0
    private void ProcessMainMenuScrolling(IGameViewport viewport)
    {
        var elapsedSeconds = (TimePoint.Now - _scrollMainMenuRefPoint).TotalSeconds;

        if (elapsedSeconds < 1.0f)
        {
            _mainMenuScrollState += (float)elapsedSeconds;
        }

        var amountToScroll = _mainMenuScrollState;

        if (amountToScroll < 0.0f)
        {
            amountToScroll       = 0.0f;
            _mainMenuScrollState = amountToScroll;
        }
        else
        {
            while (amountToScroll > 100.0f)
            {
                amountToScroll -= 100.0f;
            }
        }

        var screenHeight       = (int)viewport.Camera.GetViewportHeight();
        var targetTranslationX = 1400 - (int)(amountToScroll * 53.599998);
        var targetTranslationY = screenHeight / 2 - 13726;

        GameSystems.Location.AddTranslation(
            targetTranslationX - GameSystems.Location.LocationTranslationX,
            targetTranslationY - GameSystems.Location.LocationTranslationY
            );
        _scrollMainMenuRefPoint = TimePoint.Now;
    }
예제 #12
0
 public void radialmenu_ignore_close_till_move(IGameViewport viewport, int x, int y)
 {
     UiSystems.RadialMenu.Spawn(viewport, x, y);
     UiSystems.RadialMenu.HandleRightMouseClick(x, y);
     Logger.Info("intgame_radialmenu_ignore_close_till_move()");
     UiSystems.RadialMenu.dword_10BE6D70 = true;
 }
    internal override bool MouseMoved(IGameViewport viewport, MessageMouseArgs args)
    {
        var location = GameViews.Primary.ScreenToTile(args.X, args.Y);

        Picker.SetConeTargets(location);
        return(false);
    }
예제 #14
0
    /*
     *  occludedOnly means that the circle will only draw
     *  in already occluded areas (based on depth buffer)
     */
    public void DrawFilledCircle(IGameViewport viewport,
                                 Vector3 center,
                                 float radius,
                                 PackedLinearColorA borderColor,
                                 PackedLinearColorA fillColor,
                                 bool occludedOnly = false)
    {
        // The positions array contains the following:
        // 0 . The center of the circle
        // 1 - (sCircleSegments + 1) . Positions on the diameter of the circle
        // sCircleSegments + 2 . The first position again to close the circle
        Span <Vector3> positions = stackalloc Vector3[CircleSegments + 3];

        // A full rotation divided by the number of segments
        var rotPerSegment = 2 * MathF.PI / CircleSegments;

        positions[0] = center;
        for (var i = 1; i < CircleSegments + 3; ++i)
        {
            var rot = (CircleSegments - i) * rotPerSegment;
            positions[i].X = center.X + MathF.Cos(rot) * radius - MathF.Sin(rot) * 0.0f;
            positions[i].Y = center.Y;
            positions[i].Z = center.Z + MathF.Cos(rot) * 0.0f + MathF.Sin(rot) * radius;
        }

        positions[^ 1] = positions[1];
    public void WorldToScreen(IGameViewport viewport, Vector3 worldPos, out Vector2 screenPos)
    {
        screenPos = viewport.Camera.WorldToScreen(worldPos);
        var offset2d = viewport.Camera.Get2dTranslation();

        screenPos.X += offset2d.X;
        screenPos.Y += offset2d.Y;
    }
예제 #16
0
    public void HandleMessage(IGameViewport viewport, Message msg)
    {
        if (UiSystems.RadialMenu.HandleMessage(viewport, msg))
        {
            return;
        }

        if (UiSystems.InGameSelect.HandleMessage(viewport, msg))
        {
            return;
        }

        if (GameSystems.D20.RadialMenu.GetCurrentNode() == -1)
        {
            if (UiSystems.Dialog.IsVisible)
            {
                if (msg.type == MessageType.KEYSTATECHANGE)
                {
                    UiSystems.KeyManager.InputState = 0;
                    UiSystems.KeyManager.HandleKeyEvent(msg.KeyStateChangeArgs);
                }
            }
            else
            {
                if (UiSystems.CharSheet.Inventory.DraggedObject != null)
                {
                    Stub.TODO();
                    // TODO: Check if this is actually needed!!!

                    /*if (msg.type == MessageType.MOUSE)
                     * {
                     *  var flags = msg.MouseArgs.flags;
                     *  if (flags.HasFlag(MouseEventFlag.LeftReleased) ||
                     *      flags.HasFlag(MouseEventFlag.RightReleased))
                     *  {
                     *      UiSystems.CharSheet.Inventory.DraggedObject = null;
                     *      Tig.Mouse.ClearDraggedIcon();
                     *  }
                     * }*/
                }

                if (GameSystems.Combat.IsCombatActive())
                {
                    if (!isCombatModeMessage)
                    {
                        partyMembersMoving = false;
                    }
                    isCombatModeMessage = true;
                    HandleCombatModeMessage(viewport, msg);
                }
                else
                {
                    isCombatModeMessage = false;
                    HandleNormalModeMessage(viewport, msg);
                }
            }
        }
    }
예제 #17
0
    public static void Add(IGameViewport gameView)
    {
        var oldPrimary = Primary;

        Primary = gameView;
        OnPrimaryChange?.Invoke(oldPrimary, Primary);

        VisibleGameViews.Add(gameView);
    }
예제 #18
0
    public static void Remove(IGameViewport gameView)
    {
        if (Primary == gameView)
        {
            Primary = null;
            OnPrimaryChange?.Invoke(gameView, null);
        }

        VisibleGameViews.Remove(gameView);
    }
예제 #19
0
    private void HandleNormalKeyStateChange(IGameViewport viewport, MessageKeyStateChangeArgs args)
    {
        if (args.down)
        {
            return;
        }

        var leader = GameSystems.Party.GetConsciousLeader();

        if (leader != null)
        {
            if (GameSystems.D20.Hotkeys.IsReservedHotkey(args.key))
            {
                if (Tig.Keyboard.IsKeyPressed(VirtualKey.VK_LCONTROL) ||
                    Tig.Keyboard.IsKeyPressed(VirtualKey.VK_RCONTROL))
                {
                    // trying to assign hotkey to reserved hotkey
                    GameSystems.D20.Hotkeys.HotkeyReservedPopup(args.key);
                    return;
                }
            }
            else if (GameSystems.D20.Hotkeys.IsNormalNonreservedHotkey(args.key))
            {
                if (Tig.Keyboard.IsKeyPressed(VirtualKey.VK_LCONTROL) ||
                    Tig.Keyboard.IsKeyPressed(VirtualKey.VK_RCONTROL))
                {
                    // assign hotkey
                    var leaderLoc = leader.GetLocationFull();
                    var screenPos = viewport.WorldToScreen(leaderLoc.ToInches3D());

                    UiSystems.RadialMenu.Spawn(viewport, (int)screenPos.X, (int)screenPos.Y);
                    UiSystems.RadialMenu.HandleKeyMessage(args);
                    return;
                }

                GameSystems.D20.Actions.TurnBasedStatusInit(leader);
                leader = GameSystems.Party.GetConsciousLeader(); // in case the leader changes somehow...
                Logger.Info("Intgame: Resetting sequence.");
                GameSystems.D20.Actions.CurSeqReset(leader);

                GameSystems.D20.Actions.GlobD20ActnInit();
                if (GameSystems.D20.Hotkeys.RadmenuHotkeySthg(GameSystems.Party.GetConsciousLeader(), args.key))
                {
                    GameSystems.D20.Actions.ActionAddToSeq();
                    GameSystems.D20.Actions.sequencePerform();
                    PlayVoiceConfirmationSound(leader);
                    GameSystems.D20.RadialMenu.ClearActiveRadialMenu();
                    return;
                }
            }
        }

        UiSystems.KeyManager.InputState = 0;
        UiSystems.KeyManager.HandleKeyEvent(args);
    }
        private void Awake()
        {
            m_rt         = GetComponent <RectTransform>();
            m_gameView   = Dependencies.GameView;
            m_selectable = GetComponent <Selectable>();

            m_viewport     = GetComponentInParent <GameViewport>();
            m_virtualMouse = m_gameView.GetVirtualMouse(m_viewport.LocalPlayerIndex);

            m_isKeyboardAndMouse = Dependencies.InputManager.IsKeyboardAndMouse(m_viewport.LocalPlayerIndex);
        }
예제 #21
0
    public static void Render(IGameViewport viewport)
    {
        if (ImGui.Begin("Debug Overlay", ref isActive))
        {
            var mousePt = TigSubsystems.Tig.Mouse.GetPos();

            var worldCoord = viewport.ScreenToTile(mousePt.X, mousePt.Y);
            ImGui.Text($"{worldCoord}");
            ImGui.End();
        }
    }
예제 #22
0
 public bool IsOnScreen(IGameViewport viewport)
 {
     if (_attachedTo != null && !_external.GetObjLocation(_attachedTo, out var worldPos))
     {
         return(_external.IsBoxVisible(viewport, worldPos, _screenBounds));
     }
     else
     {
         return(_external.IsBoxVisible(viewport, _fixedWorldPos, _screenBounds));
     }
 }
    /// <summary>
    /// Renders the Line Of Sight buffer for a given party member.
    /// </summary>
    public void RenderLineOfSight(IGameViewport viewport, int partyIndex)
    {
        var buffer = _system.GetLineOfSightBuffer(partyIndex, out var size, out var originTile);

        if (!_texture.IsValid || _texture.Resource.GetSize() != size)
        {
            _colorBuffer = new PackedLinearColorA[size.Width * size.Height];

            _texture.Dispose();
            _texture = _device.CreateDynamicTexture(BufferFormat.A8R8G8B8, size.Width, size.Height);
        }

        // Update color buffer
        for (int i = 0; i < buffer.Length; i++)
        {
            _colorBuffer[i] = GetColorFromLosFlags(buffer[i]);
        }

        var rawColorBuffer = MemoryMarshal.Cast <PackedLinearColorA, byte>(_colorBuffer);

        _texture.Resource.UpdateRaw(rawColorBuffer, size.Width * 4);

        var origin = new Vector4(originTile.ToInches3D(), 1);

        var widthVec  = new Vector4(size.Width * locXY.INCH_PER_SUBTILE, 0, 0, 0);
        var heightVec = new Vector4(0, 0, size.Height * locXY.INCH_PER_SUBTILE, 0);

        Span <ShapeVertex3d> corners = stackalloc ShapeVertex3d[4]
        {
            new ShapeVertex3d
            {
                pos = origin,
                uv  = new Vector2(0, 0)
            },
            new ShapeVertex3d
            {
                pos = origin + widthVec,
                uv  = new Vector2(1, 0)
            },
            new ShapeVertex3d
            {
                pos = origin + widthVec + heightVec,
                uv  = new Vector2(1, 1)
            },
            new ShapeVertex3d
            {
                pos = origin + heightVec,
                uv  = new Vector2(0, 1)
            }
        };

        Tig.ShapeRenderer3d.DrawQuad(viewport, corners, new PackedLinearColorA(255, 255, 255, 127), _texture.Resource);
    }
    public override void Render(IGameViewport viewport, PartSysEmitter emitter)
    {
        if (!GetEmitterWorldMatrix(viewport, emitter, out var worldMatrix))
        {
            return;
        }

        _device.SetVertexShaderConstants(0, ref worldMatrix);
        _device.SetIndexBuffer(_indexBuffer);

        RenderParticles(emitter);
    }
예제 #25
0
    public void DrawCylinder(IGameViewport viewport, Vector3 pos, float radius, float height)
    {
        float x = pos.X;
        float y = pos.Y;
        float z = pos.Z;

        var     scaledRadius = radius * cos45;
        Vector3 from, to;

        from.X = x + scaledRadius;
        from.Y = y;
        from.Z = z - scaledRadius;
        to.X   = from.X;
        to.Y   = y + height;
        to.Z   = from.Z;

        DrawLine(viewport, from, to, CylinderDiffuse);

        from.X = x - scaledRadius;
        from.Z = z + scaledRadius;
        to.X   = from.X;
        to.Z   = from.Z;
        DrawLine(viewport, from, to, CylinderDiffuse);

        /*
         * Draw the circle on top and on the bottom
         * of the cylinder.
         */
        for (var i = 0; i < 24; ++i)
        {
            // We rotate 360° in 24 steps of 15° each
            var rot     = i * Angles.ToRadians(15);
            var nextRot = rot + Angles.ToRadians(15);

            // This is the bottom cap
            from.X = x + MathF.Cos(rot) * radius;
            from.Y = y;
            from.Z = z - MathF.Sin(rot) * radius;
            to.X   = x + MathF.Cos(nextRot) * radius;
            to.Y   = y;
            to.Z   = z - MathF.Sin(nextRot) * radius;
            DrawLine(viewport, from, to, CylinderDiffuse);

            // This is the top cap
            from.X = x + MathF.Cos(rot) * radius;
            from.Y = y + height;
            from.Z = z - MathF.Sin(rot) * radius;
            to.X   = x + MathF.Cos(nextRot) * radius;
            to.Y   = y + height;
            to.Z   = z - MathF.Sin(nextRot) * radius;
            DrawLine(viewport, from, to, CylinderDiffuse);
        }
    }
예제 #26
0
    public void RenderMapObjects(IGameViewport viewport, int tileX1, int tileX2, int tileY1, int tileY2)
    {
        using var perfGroup = mDevice.CreatePerfGroup("Map Objects");

        mTotalLastFrame    = 0;
        mRenderedLastFrame = 0;

        using var iterator = new SectorIterator(tileX1, tileX2, tileY1, tileY2);
        foreach (var obj in iterator.EnumerateObjects())
        {
            RenderObject(viewport, obj, true);
        }
    }
    public bool IsBoxVisible(IGameViewport viewport, Vector3 worldPos, Box2d box)
    {
        WorldToScreen(viewport, worldPos, out var screenPos);

        if (viewport.Camera.IsBoxOnScreen(screenPos,
                                          box.left, box.top,
                                          box.right, box.bottom))
        {
            return(true);
        }

        return(false);
    }
예제 #28
0
    private void BindQuadMaterial(IGameViewport viewport, PackedLinearColorA color, ITexture texture)
    {
        _device.SetMaterial(_quadMaterial);

        Shape3dGlobals globals;

        globals.viewProj = viewport.Camera.GetViewProj();
        globals.colors   = color.ToRGBA();

        _device.SetVertexShaderConstants(0, ref globals);

        _device.SetTexture(0, texture);
    }
예제 #29
0
    public void DrawQuad(IGameViewport viewport,
                         ReadOnlySpan <ShapeVertex3d> corners,
                         PackedLinearColorA color,
                         ITexture texture)
    {
        _discVertexBuffer.Resource.Update(corners);
        _discBufferBinding.Resource.Bind();

        BindQuadMaterial(viewport, color, texture);

        _device.SetIndexBuffer(_discIndexBuffer);
        _device.DrawIndexed(PrimitiveType.TriangleList, 4, 2 * 3);
    }
    public void Render(IGameViewport viewport)
    {
        using var perfGroup = _renderingDevice.CreatePerfGroup("Particles");

        _totalLastFrame    = 0;
        _renderedLastFrame = 0;

        var sw = Stopwatch.StartNew();

        foreach (var partSys in _particleSysSystem.ActiveSystems)
        {
            _totalLastFrame++;

            if (!partSys.IsOnScreen(viewport))
            {
                continue;
            }

            _renderedLastFrame++;

            using var sysPerfGroup = _renderingDevice.CreatePerfGroup("PartSys '{0}'", partSys.GetSpec().GetName());

            // each emitter is rendered individually
            foreach (var emitter in partSys.GetEmitters())
            {
                if (emitter.GetActiveCount() == 0)
                {
                    continue; // Skip emitters with no particles
                }

                using var emitterPerfGroup =
                          _renderingDevice.CreatePerfGroup("Emitter '{0}'", emitter.GetSpec().GetName());

                var type     = emitter.GetSpec().GetParticleType();
                var renderer = _rendererManager.GetRenderer(type);
                renderer.Render(viewport, emitter);
            }

            if (Globals.Config.DebugPartSys)
            {
                RenderDebugInfo(viewport, partSys);
            }
        }

        _renderTimes[_renderTimesPos++] = (int)sw.ElapsedMilliseconds;
        if (_renderTimesPos >= _renderTimes.Length)
        {
            _renderTimesPos = 0;
        }
    }