Exemple #1
0
 public virtual void UpdateSyncMobileToServer()
 {
     SyncMobile.MobileMetadata   = MobileMetadata;
     SyncMobile.Position         = Topography.GetRelativePosition(SyncPosition);
     SyncMobile.SelectedShotType = SelectedShotType;
     SyncMobile.CrosshairAngle   = Crosshair.ShootingAngle;
     SyncMobile.Facing           = Facing;
 }
Exemple #2
0
        /// <summary>
        ///Update mobile standing angle based on the projections defined by ParameterCalculationOffsetX/Y
        /// </summary>
        public void UpdateAngle()
        {
            Vector2 leftNotCollidablePosition, rightNotCollidablePosition;
            Vector2 leftCollidablePosition, rightCollidablePosition;
            Vector2 selectedLeft, selectedRight;

            leftNotCollidablePosition           =
                leftCollidablePosition          =
                    rightNotCollidablePosition  =
                        rightCollidablePosition = default;

            int[] relPos = Topography.GetRelativePosition(Mobile.Position);

            int xAxis = Parameter.TankMovementRotationCalculationOffsetX;
            int yAxis = Parameter.TankMovementRotationCalculationOffsetY;

            int minXCoord = MathHelper.Clamp(relPos[0] - xAxis, 0, Topography.CollidableForegroundMatrix[0].Length - 1);
            int maxXCoord = MathHelper.Clamp(relPos[0] + xAxis, 0, Topography.CollidableForegroundMatrix[0].Length - 1);

            //Project possible left spot
            for (int h = -yAxis; h < yAxis; h++)
            {
                if (relPos[1] + h >= Topography.CollidableForegroundMatrix.Length)
                {
                    break;
                }

                if (!Topography.CollidableForegroundMatrix[relPos[1] + h][minXCoord])
                {
                    leftNotCollidablePosition = new Vector2(minXCoord, relPos[1] + h);
                }
                else
                {
                    if (leftNotCollidablePosition != default)
                    {
                        break;
                    }
                }
            }

            //Project possible right spot
            for (int h = -yAxis; h < yAxis; h++)
            {
                if (relPos[1] + h >= Topography.CollidableForegroundMatrix.Length)
                {
                    break;
                }

                if (!Topography.CollidableForegroundMatrix[relPos[1] + h][maxXCoord])
                {
                    rightNotCollidablePosition = new Vector2(maxXCoord, relPos[1] + h);
                }
                else
                {
                    if (rightNotCollidablePosition != default)
                    {
                        break;
                    }
                }
            }

            //TODO maybe fix it or maybe not

            // In case of left/right projection is located on a hole
            for (int h = -yAxis; h < yAxis; h++)
            {
                if (relPos[1] - h >= Topography.CollidableForegroundMatrix.Length)
                {
                    break;
                }

                if (Topography.CollidableForegroundMatrix[relPos[1] - h][minXCoord])
                {
                    leftCollidablePosition = new Vector2(
                        minXCoord,
                        relPos[1] - h);
                }

                if (Topography.CollidableForegroundMatrix[relPos[1] - h][maxXCoord])
                {
                    rightCollidablePosition = new Vector2(
                        maxXCoord,
                        relPos[1] - h);
                }
            }

            //Select best projection
            if (leftNotCollidablePosition == default)
            {
                selectedLeft = leftCollidablePosition;
            }
            else
            {
                selectedLeft = leftNotCollidablePosition;
            }

            if (rightNotCollidablePosition == default)
            {
                selectedRight = rightCollidablePosition;
            }
            else
            {
                selectedRight = rightNotCollidablePosition;
            }

            Vector2 tmp = selectedRight - selectedLeft;

            BufferRotationInDegrees = MathHelper.ToDegrees((float)Math.Atan2(tmp.Y, tmp.X));

            float newRot = MathHelper.ToRadians(BufferRotationInDegrees);

            if (IsFalling)
            {
                newRot = 0;
            }

            //Crosshair Angle
            if (Mobile.Crosshair != null)
            {
                Mobile.Crosshair.UpdateCrosshairPointerAngle(Mobile.MobileFlipbook.Rotation - newRot);
            }

            //Tank Rotation
            Mobile.MobileFlipbook.Rotation = newRot;
        }
Exemple #3
0
        public void MoveSideways(Facing Facing)
        {
            //Sound Effect
            Mobile.PlayMovementSE();

            //Copy parameter tank speed
            float TankSpeed = Parameter.TankMovementSpeed;

            if (Facing == Facing.Right)
            {
                TankSpeed *= -1;
            }

            //Start calculating the next possible position
            int[] relPos = Topography.GetRelativePosition(Mobile.Position);
            int   i      = (int)Parameter.TankMovementMaxYStepping;

            //Flag to determine if the movement is possible
            bool isValid = false;

            //Get the possible adjacent block coordinate and save it on newX & newY
            for (; i > -Parameter.TankMovementMinYStepping; i--)
            {
                //If the collision flag of the adjacent block is 0

                //Save as a possible adjacent solution

                if (relPos[0] - TankSpeed < 0 || relPos[0] - TankSpeed >= Topography.MapHeight)
                {
                    //Keep the height
                    i       = 0;
                    isValid = true;
                    break;
                }

                isValid = isValid || !Topography.CollidableForegroundMatrix[relPos[1] - i][(int)(relPos[0] - TankSpeed)];

                //if has already a valid movement and a wall is detected
                if (isValid && Topography.CollidableForegroundMatrix[relPos[1] - i][(int)(relPos[0] - TankSpeed)])
                {
                    break;
                }
            }

            if (isValid)
            {
                if (!IsMoving)
                {
                    IsMoving           = true;
                    sidewaysDelayTimer = 0;
                }

                sidewaysDelayTimer += Parameter.ProjectileMovementFixedElapedTime;

                if (sidewaysDelayTimer > Parameter.TankMovementSidewaysDelay)
                {
                    // Add new movement based on tank speed
                    RemainingStepsThisTurn--;
                    Mobile.Position += new Vector2(-(int)TankSpeed, -i);
                    Mobile.ChangeFlipbookState(ActorFlipbookState.Moving, true);
                    if (Mobile.IsPlayable)
                    {
                        LevelScene.HUD.MovementBar.PerformStep();
                    }
                }
            }
            else
            {
                InvalidateMovementAttempt();
            }

            IsAbleToMove = RemainingStepsThisTurn > 0;
        }
Exemple #4
0
        public void ApplyGravity()
        {
            if (Topography.IsNotInsideMapYBoundaries(Mobile.Position - new Vector2(0, Mobile.MobileFlipbook.SpriteHeight)))
            {
                if (Mobile.IsAlive)
                {
                    Mobile.RequestDeath(CausaMortis.Bungee);
                }
                return;
            }

            int[] relPos = Topography.GetRelativePosition(Mobile.Position);

            //Compute the where is the next collidable block bellow the pawn
            int yPosition = 0;

            for (; yPosition < Math.Max(Parameter.TankMovementMinYStepping, GravitySpeed); yPosition++)
            {
                if (relPos[1] + yPosition >= Topography.CollidableForegroundMatrix.Length)
                {
                    continue;
                }

                if (relPos[0] > 0 && relPos[0] < Topography.MapHeight && Topography.CollidableForegroundMatrix[relPos[1] + yPosition][relPos[0]])
                {
                    break;
                }
            }

            //If the unit isn't on the ground
            if (yPosition > 0)
            {
                //Update gravity values on the pawn
                if (IsFalling)
                {
                    gravityDelayTimer += Parameter.ProjectileMovementFixedElapedTime;
                    if (gravityDelayTimer > Parameter.TankMovementGravityDelay)
                    {
                        //Wind-changing accumulated offset
                        Vector2 wForce = (LevelScene.MatchMetadata != null) ? LevelScene.MatchMetadata.WindForceComponents().ToVector2() : Vector2.Zero;

                        windForceAccumulator = MathHelper.Clamp(windForceAccumulator + wForce.X / 45, -1, 1);

                        //Add interpolated movement
                        Vector2 newPosition = Mobile.Position + new Vector2((int)windForceAccumulator, Math.Min((int)GravitySpeed, yPosition));

                        //In case the mobile collides in walls the X axis stop updating in order to prevent wall clipping
                        if (Topography.IsInsideMapBoundaries(newPosition) && !Topography.CheckCollision(newPosition))
                        {
                            windForceAccumulator = 0;
                        }

                        Mobile.Position += new Vector2((int)windForceAccumulator, Math.Min((int)GravitySpeed, yPosition));

                        GravitySpeed += Parameter.TankMovementGravityFactor;

                        //Reseting the accumulator
                        if (Math.Abs(windForceAccumulator) >= 1)
                        {
                            windForceAccumulator = 0;
                        }
                    }
                }
                else
                {
                    gravityDelayTimer = 0;
                    GravitySpeed      = Parameter.TankMovementInitialGravity;
                }

                //Reset the rotation
                BufferRotationInDegrees = 0;

                //Set the state to falling
                if (!IsFalling)
                {
                    Mobile.ForceSynchronize = true;
                    IsFalling = true;
                }

                IsMoving = false;
                //desiredPosition.Y = Mobile.Position.Y;

                Mobile.ChangeFlipbookState(ActorFlipbookState.Falling, true);
            }
            else
            {
                //Set the the falling state to false
                if (IsFalling == true)
                {
                    IsFalling            = false;
                    windForceAccumulator = 0;
                    Mobile.ChangeFlipbookState(ActorFlipbookState.Stand, true);
                }
            }
        }