Exemplo n.º 1
0
        private async void processWalkInstruction(WalkInstruction previousWalk, WalkInstruction currentWalk)
        {
            if (previousWalk != null)
            {
                await previousWalk.OnCompletion.Task;
            }
            var debugRenderers = DebugDrawWalkPath ? new List <IObject>() : null;

            _debugPath = debugRenderers;
            OnPropertyChanged(nameof(IsWalking));
            float xSource       = _translate.X;
            float ySource       = _translate.Y;
            bool  completedWalk = false;

            try
            {
                completedWalk = await walkAsync(currentWalk, currentWalk.Destination, currentWalk.StraightLine, debugRenderers);
            }
            finally
            {
                _faceDirection.CurrentDirectionalAnimation = _outfit.Outfit[AGSOutfit.Idle];
                await _faceDirection.FaceDirectionAsync(_faceDirection.Direction);

                currentWalk.OnCompletion.TrySetResult(completedWalk);
                OnPropertyChanged(nameof(IsWalking));
            }
        }
Exemplo n.º 2
0
        private async Task <bool> addNewInstructionAsync(Position destination, bool walkAnywhere, bool straightLine, bool stopOnly)
        {
            WalkInstruction newWalk = new WalkInstruction(_room?.Room, destination, walkAnywhere, straightLine, stopOnly);

            _incomingInstructions.Enqueue(newWalk);
            return(await newWalk.OnCompletion.Task);
        }
Exemplo n.º 3
0
        private WalkInstruction getWalkInstruction()
        {
            WalkInstruction instruction = _currentWalk;

            while (_incomingInstructions.TryDequeue(out var nextInstruction))
            {
                if (instruction != null)
                {
                    onWalkLineCompleted(instruction, instruction.CurrentLine, false);
                }
                if (nextInstruction != null)
                {
                    instruction = nextInstruction;
                }
            }
            if (_currentWalk != instruction)
            {
                if (instruction.StopOnly)
                {
                    instruction.OnCompletion.TrySetResult(false);
                    _currentWalk = null;
                    return(null);
                }
                var previousInstruction = _currentWalk;
                _currentWalk = instruction;
                processWalkInstruction(previousInstruction, instruction);
            }
            return(instruction);
        }
Exemplo n.º 4
0
 private void onWalkLineCompleted(WalkInstruction currentWalk, WalkLineInstruction currentLine, bool success)
 {
     currentWalk.CurrentLine = null;
     if (currentLine == null)
     {
         return;
     }
     currentLine.LastFrame = null;
     currentLine.OnCompletion.TrySetResult(success);
 }
Exemplo n.º 5
0
        private async Task <bool> walkAsync(WalkInstruction currentWalk, Position location, bool straightLine, List <IObject> debugRenderers)
        {
            Position[] walkPoints = straightLine ? new [] { location } : getWalkPoints(location);

            if (walkPoints.Length == 0)
            {
                return(false);
            }
            foreach (var point in walkPoints)
            {
                if (MathUtils.FloatEquals(point.X, _translate.X) && MathUtils.FloatEquals(point.Y, _translate.Y))
                {
                    continue;
                }
                if (!await walkStraightLine(currentWalk, point, debugRenderers))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 6
0
        private async Task <bool> walkAsync(WalkInstruction currentWalk, Position location, bool straightLine, List <IObject> debugRenderers)
        {
            IEnumerable <Position> walkPoints = straightLine ? new List <Position> {
                location
            } : getWalkPoints(location);

            if (!walkPoints.Any())
            {
                return(false);
            }
            foreach (var point in walkPoints)
            {
                if (point.X == _translate.X && point.Y == _translate.Y)
                {
                    continue;
                }
                if (!await walkStraightLine(currentWalk, point, debugRenderers))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 7
0
        private async Task <bool> walkStraightLine(WalkInstruction currentWalk, Position destination, List <IObject> debugRenderers)
        {
            if (_room?.Room != currentWalk.Room)
            {
                return(false);
            }

            if (debugRenderers != null)
            {
                IObject renderer = _objFactory.GetObject("Debug Line");
                var     line     = renderer.AddComponent <GLLineRenderer>();
                if (line != null)
                {
                    line.X1 = _translate.X;
                    line.Y1 = _translate.Y;
                    line.X2 = destination.X;
                    line.Y2 = destination.Y;
                }
                await renderer.ChangeRoomAsync(currentWalk.Room);

                debugRenderers.Add(renderer);
            }

            if (_cutscene.IsSkipping)
            {
                _translate.Position = destination;
                return(true);
            }

            if (!isDistanceVeryShort(destination))
            {
                var  lastDirection  = _faceDirection.Direction;
                var  walkAnimation  = _outfit.Outfit[AGSOutfit.Walk];
                bool alreadyWalking = _faceDirection.CurrentDirectionalAnimation == walkAnimation;
                _faceDirection.CurrentDirectionalAnimation = walkAnimation;
                await _faceDirection.FaceDirectionAsync(_translate.X, _translate.Y, destination.X, destination.Y);

                if (lastDirection != _faceDirection.Direction && alreadyWalking)
                {
                    await Task.Delay(200);
                }
            }

            float xSteps = Math.Abs(destination.X - _translate.X);
            float ySteps = Math.Abs(destination.Y - _translate.Y);

            float numSteps    = Math.Max(xSteps, ySteps);
            bool  isBaseStepX = xSteps >= ySteps;

            float xStep = xSteps / numSteps;

            if (_translate.X > destination.X)
            {
                xStep = -xStep;
            }

            float yStep = ySteps / numSteps;

            if (_translate.Y > destination.Y)
            {
                yStep = -yStep;
            }

            WalkLineInstruction instruction = new WalkLineInstruction(numSteps, xStep, yStep,
                                                                      isBaseStepX, destination);

            currentWalk.CurrentLine = instruction;
            if (_currentWalk != currentWalk)
            {
                onWalkLineCompleted(currentWalk, instruction, false);
                currentWalk.CancelToken.Cancel();
                return(false);
            }
            Task timeout       = Task.Delay(WalkLineTimeoutInMilliseconds);
            Task completedTask = await Task.WhenAny(instruction.OnCompletion.Task, currentWalk.OnCompletion.Task, timeout);

            if (completedTask == timeout)
            {
                currentWalk.CancelToken.Cancel();
                return(false);
            }

            if (completedTask == currentWalk.OnCompletion.Task)
            {
                return(false);
            }

            if (!instruction.OnCompletion.Task.Result || currentWalk.CancelToken.IsCancellationRequested ||
                _room?.Room != currentWalk.Room || (!currentWalk.WalkAnywhere && !isWalkable(_translate.Position)))
            {
                return(false);
            }

            if (currentWalk.WalkAnywhere || isWalkable(destination))
            {
                _translate.Position = destination;
                return(true);
            }

            return(false);
        }
Exemplo n.º 8
0
        private void onRepeatedlyExecute()
        {
            WalkInstruction     currentWalk = getWalkInstruction();
            WalkLineInstruction currentLine = currentWalk?.CurrentLine;

            if (currentLine == null)
            {
                return;
            }

            if (currentWalk.CancelToken.IsCancellationRequested ||
                (!currentWalk.WalkAnywhere && !isWalkable(_translate.Position)) || _room?.Room != currentWalk.Room)
            {
                onWalkLineCompleted(currentWalk, currentLine, false);
                return;
            }
            if (currentLine.NumSteps <= 1f)
            {
                onWalkLineCompleted(currentWalk, currentLine, true);
                return;
            }
            if (_cutscene.IsSkipping)
            {
                _translate.Position = currentLine.Destination;
                onWalkLineCompleted(currentWalk, currentLine, true);
                return;
            }
            PointF walkSpeed = adjustWalkSpeed(WalkStep);
            float  xStep     = currentLine.XStep * walkSpeed.X;
            float  yStep     = currentLine.YStep * walkSpeed.Y;

            if (MovementLinkedToAnimation && _animation != null && _animation.Animation.Frames.Count > 1 &&
                _animation.Animation.Sprite == currentLine.LastFrame)
            {
                //If the movement is linked to the animation and the animation speed is slower the the viewport movement, it can lead to flickering
                //so we do a smooth movement for this scenario.
                (var compensateX, var compensateY)     = currentLine.Compensate;
                (var lastViewportX, var lastViewportY) = currentLine.Viewport;
                var candidateX = _translate.X + compensateForViewScrollIfNeeded(_state.Viewport.X, xStep, ref compensateX, ref lastViewportX);
                var candidateY = _translate.Y + compensateForViewScrollIfNeeded(_state.Viewport.Y, yStep, ref compensateY, ref lastViewportY);
                if (currentWalk.WalkAnywhere || isWalkable(new Position(candidateX, candidateY)))
                {
                    currentLine.Compensate = (compensateX, compensateY);
                    _translate.Position    = (candidateX, candidateY);
                    return;
                }
            }
            currentLine.LastFrame = _animation?.Animation.Sprite;
            currentLine.Viewport  = (_state.Viewport.X, _state.Viewport.Y);

            currentLine.NumSteps -= Math.Abs(currentLine.IsBaseStepX ? xStep : yStep);
            if (currentLine.NumSteps >= 0f)
            {
                var candidateX = _translate.X + (xStep - currentLine.Compensate.x);
                var candidateY = _translate.Y + (yStep - currentLine.Compensate.y);
                if (currentWalk.WalkAnywhere || isWalkable(new Position(candidateX, candidateY)))
                {
                    _translate.Position = (candidateX, candidateY);
                }
                else
                {
                    onWalkLineCompleted(currentWalk, currentLine, false);
                    return;
                }
            }
            currentLine.Compensate = (0f, 0f);
        }