public bool BeginMove(Vector2Int target)
        {
            if (Mathf.Approximately(MoveSpeed, 0))
            {
                return(false); //can't move
            }
            var start = walkProvider.GetTilePositionForPoint(transform.position);

            if (MovePath.Count >= 1)
            {
                start = MovePath[0];
            }

            var end = target;

            if (MovePath.Count == 0 || MovePath.Last() != end)
            {
                if (tempPath == null)
                {
                    tempPath = new Vector2Int[17];
                }

                //Debug.Log(TempPath.Length);

                var steps = Pathfinder.GetPath(walkProvider.WalkData, start, end, tempPath);

                if (steps > 0)
                {
                    if (MovePath.Count > 1)
                    {
                        //Debug.Log($"{MovePath[0]} {tempPath[0]} {MovePath[1]} {tempPath[1]}");

                        if (!IsNeighbor(MovePath[1], tempPath[1]))
                        {
                            MoveProgress = 1f;
                        }
                        else
                        {
                            if (MovePath[1] != tempPath[1])
                            {
                                MoveProgress = Mathf.Min(1f, MoveProgress + 0.3f);
                            }
                        }
                    }
                    else
                    {
                        MoveProgress = 1f;
                    }

                    MovePath.Clear();

                    for (var i = 0; i < steps; i++)
                    {
                        MovePath.Add(tempPath[i]);
                    }
                    //MovePath = path;
                    //var str = string.Join(", ", path);

                    var offset = MovePath[1] - MovePath[0];
                    //if (IsDiagonal(GetDirectionForOffset(offset)))
                    //    MoveProgress += 0.3f;
                    StartPos = transform.position - new Vector3(0.5f, 0f, 0.5f);

                    return(true);
                }
            }

            return(false);
        }
Exemple #2
0
        private void DoScreenCast()
        {
            var ray = Camera.ScreenPointToRay(Input.mousePosition);

            var hasHitCharacter = false;

            var characterHits = Physics.RaycastAll(ray, MaxClickDistance, (1 << LayerMask.NameToLayer("Characters")));
            var hasHitMap     = Physics.Raycast(ray, out var groundHit, MaxClickDistance, (1 << LayerMask.NameToLayer("WalkMap")));

            if (characterHits.Length > 0)
            {
                hasHitCharacter = true;
            }

            if (isHolding)
            {
                hasHitCharacter = false;
            }

            if (hasHitCharacter)
            {
                //var anim = charHit.transform.gameObject.GetComponent<RoSpriteAnimator>();
                var anim = GetClosestOrEnemy(characterHits);
                if (anim == null)
                {
                    hasHitCharacter = false;                     //back out if our hit is a false positive (the object is dead or dying for example)
                }
                if (hasHitCharacter)
                {
                    var screenPos = Camera.main.WorldToScreenPoint(anim.Controllable.gameObject.transform.position);
                    var color     = "";
                    if (!anim.Controllable.IsAlly)
                    {
                        ChangeCursor(AttackCursorTexture);
                        color     = "<color=#FFAAAA>";
                        hasHitMap = false;
                    }
                    else
                    {
                        ChangeCursor(NormalCursorTexture);
                    }

                    var reverseScale = 1f / CanvasScaler.scaleFactor;

                    TargetUi.rectTransform.anchoredPosition = new Vector2(screenPos.x * reverseScale,
                                                                          ((screenPos.y - UiCanvas.pixelRect.height) - 30) * reverseScale);
                    TargetUi.text = color + anim.Controllable.gameObject.name;

                    if (anim.Controllable.CharacterType == CharacterType.Monster)
                    {
                        if (Input.GetMouseButtonDown(0))
                        {
                            NetworkManager.Instance.SendAttack(anim.Controllable.Id);
                            isHolding = false;
                            noHold    = true;
                        }
                    }
                }
            }
            else
            {
                ChangeCursor(NormalCursorTexture);
            }

            ClickDelay -= Time.deltaTime;

            if (Input.GetMouseButtonUp(0))
            {
                ClickDelay = 0;
            }

            if (!Input.GetMouseButton(0))
            {
                isHolding = false;
                noHold    = false;
            }

            if (!hasHitMap)
            {
                WalkProvider.DisableRenderer();
                return;
            }

            //we hit the map! Do map things

            var hasGroundPos = WalkProvider.GetMapPositionForWorldPosition(groundHit.point, out var mapPosition);
            var hasSrcPos    = WalkProvider.GetMapPositionForWorldPosition(Target.transform.position, out var srcPosition);
            var okPath       = true;

            if (hasGroundPos && hasSrcPos)
            {
                if (mapPosition != lastTile)
                {
                    if (tempPath == null)
                    {
                        tempPath = new Vector2Int[SharedConfig.MaxPathLength + 2];
                    }

                    if (!WalkProvider.IsCellWalkable(mapPosition))
                    {
                        okPath = false;
                    }

                    if ((mapPosition - srcPosition).SquareDistance() > SharedConfig.MaxPathLength)
                    {
                        okPath = false;
                    }

                    if (okPath)
                    {
                        //Debug.Log("Performing path check");

                        var steps = Pathfinder.GetPath(WalkProvider.WalkData, mapPosition, srcPosition, tempPath);
                        if (steps == 0)
                        {
                            okPath = false;
                        }
                    }
                }
                else
                {
                    okPath = lastPathValid;
                }

                WalkProvider.UpdateCursorPosition(Target.transform.position, groundHit.point, okPath);

                lastPathValid = okPath;
                lastTile      = mapPosition;
            }

            if (!hasHitCharacter)
            {
                TargetUi.text = "";
            }


            if (noHold)
            {
                return;
            }

            if (Input.GetMouseButton(0) && ClickDelay <= 0)
            {
                var srcPos  = controllable.Position;
                var hasDest = WalkProvider.GetClosestTileTopToPoint(groundHit.point, out var destPos);

                if (hasDest)
                {
                    if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) ||
                        controllable.SpriteAnimator.State == SpriteState.Sit)
                    {
                        if (Input.GetMouseButtonDown(0))                         //only do this when mouse is down the first time. Yeah the second check is dumb...
                        {
                            ClickDelay = 0.1f;
                            ChangeFacing(WalkProvider.GetWorldPositionForTile(destPos));
                        }
                    }
                    else
                    {
                        var dist = (srcPos - destPos).SquareDistance();
                        if (WalkProvider.IsCellWalkable(destPos) && dist < SharedConfig.MaxPathLength)
                        {
                            NetworkManager.Instance.MovePlayer(destPos);
                            ClickDelay = 0.5f;
                            isHolding  = true;
                        }
                        else
                        {
                            if (WalkProvider.GetNextWalkableTileForClick(srcPos, destPos, out var dest2))
                            {
                                NetworkManager.Instance.MovePlayer(dest2);
                                ClickDelay = 0.5f;
                                isHolding  = true;
                            }
                        }
                    }
                }
            }
        }