Ejemplo n.º 1
0
        public bool Activate(State state, bool checkPossibilities)
        {
            if (!this.EnableWallRun)
            {
                return(false);
            }

            Vector3 playerVelocity = this.LinearVelocity.Value;

            if (playerVelocity.Y < FallDamage.RollingDamageVelocity)
            {
                return(false);
            }

            if (this.IsSwimming)
            {
                if (state == State.Left || state == State.Right)
                {
                    return(false);
                }
            }

            wallInstantiationTimer = 0.0f;

            // Prevent the player from repeatedly wall-running and wall-jumping ad infinitum.
            bool wallRunDelayPassed     = main.TotalTime - this.lastWallRunEnded > wallRunDelay;
            bool wallRunJumpDelayPassed = main.TotalTime - this.LastWallJump > wallRunDelay;

            Matrix matrix = Matrix.CreateRotationY(this.Rotation);

            Vector3 forwardVector = -matrix.Forward;

            Vector3 wallVector;

            switch (state)
            {
            case State.Straight:
                wallVector = forwardVector;
                break;

            case State.Left:
                if (!this.EnableWallRunHorizontal)
                {
                    return(false);
                }
                wallVector = -matrix.Left;
                break;

            case State.Right:
                if (!this.EnableWallRunHorizontal)
                {
                    return(false);
                }
                wallVector = -matrix.Right;
                break;

            default:
                wallVector = Vector3.Zero;
                break;
            }

            Vector3 pos = this.Position + new Vector3(0, this.Height * -0.5f, 0);

            // Attempt to wall-run on an existing map
            bool  addInitialVelocity = false;
            Voxel closestVoxel       = null;

            Voxel.Coord closestCoord    = default(Voxel.Coord);
            const int   maxWallDistance = 4;
            int         closestDistance = maxWallDistance;
            Direction   closestDir      = Direction.None;

            foreach (Voxel voxel in Voxel.ActivePhysicsVoxels)
            {
                Vector3 baseVelocity = voxel.LinearVelocity + Vector3.Cross(voxel.AngularVelocity, this.Position - voxel.Transform.Value.Translation);
                Vector3 v            = Vector3.Normalize(playerVelocity - baseVelocity);
                v.Y = 0.0f;
                if (Vector3.Dot(forwardVector, v) < -0.3f)
                {
                    continue;
                }

                Voxel.Coord coord      = voxel.GetCoordinate(pos);
                Direction   dir        = voxel.GetRelativeDirection(wallVector);
                Direction   up         = voxel.GetRelativeDirection(Direction.PositiveY);
                Direction   forwardDir = voxel.GetRelativeDirection(forwardVector);
                for (int i = 1; i < maxWallDistance; i++)
                {
                    Voxel.Coord wallCoord = coord.Move(dir, i);
                    if (voxel[coord.Move(dir, i - 1)] != Voxel.States.Empty ||
                        voxel[coord.Move(dir, i - 1).Move(up, 1)] != Voxel.States.Empty ||
                        voxel[coord.Move(dir, i - 1).Move(up, 2)] != Voxel.States.Empty ||
                        ((state == State.Left || state == State.Right) &&
                         (voxel[coord.Move(forwardDir).Move(dir, i - 1)] != Voxel.States.Empty ||
                          voxel[coord.Move(forwardDir).Move(dir, i - 1).Move(up, 1)] != Voxel.States.Empty ||
                          voxel[coord.Move(forwardDir).Move(dir, i - 1).Move(up, 2)] != Voxel.States.Empty)))
                    {
                        // Blocked
                        break;
                    }

                    // Need at least two blocks to consider it a wall
                    if (voxel[wallCoord].ID != 0 && voxel[wallCoord.Move(up)].ID != 0)
                    {
                        bool differentWall = voxel != this.LastWallRunMap.Value || dir != this.LastWallDirection.Value;
                        if ((differentWall || wallRunJumpDelayPassed) && i < closestDistance)
                        {
                            closestVoxel       = voxel;
                            closestDistance    = i;
                            closestCoord       = coord;
                            closestDir         = dir;
                            addInitialVelocity = differentWall || wallRunDelayPassed;
                        }
                    }
                    else if (checkPossibilities)
                    {
                        // Check block possibilities
                        List <BlockPredictor.Possibility> mapBlockPossibilities = this.Predictor.GetPossibilities(voxel);
                        if (mapBlockPossibilities != null)
                        {
                            foreach (BlockPredictor.Possibility block in mapBlockPossibilities)
                            {
                                if (wallCoord.Between(block.StartCoord, block.EndCoord))
                                {
                                    this.Predictor.InstantiatePossibility(block);
                                    this.Predictor.ClearPossibilities();
                                    closestVoxel           = voxel;
                                    closestDistance        = i;
                                    closestCoord           = coord;
                                    closestDir             = dir;
                                    addInitialVelocity     = true;
                                    wallInstantiationTimer = 0.25f;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (closestVoxel != null)
            {
                if (!addInitialVelocity && Vector3.Dot(forwardVector, playerVelocity) < minWallRunSpeed)
                {
                    return(false);
                }
                this.Position.Value = closestVoxel.GetAbsolutePosition(closestCoord.Move(closestDir, closestDistance - 2)) + new Vector3(0, this.Height * 0.5f, 0);
                this.setup(closestVoxel, closestDir, state, forwardVector, addInitialVelocity);
                return(true);
            }
            return(false);
        }
Ejemplo n.º 2
0
        public static bool Go(Voxel voxel, Voxel.Coord center, int radius, Action <List <DynamicVoxel> > callback = null)
        {
            if (!voxel[center].Permanent)
            {
                // Break off a chunk of this voxel into a new DynamicMap.

                List <Voxel.Coord> edges = new List <Voxel.Coord>();

                Voxel.Coord ripStart = center.Move(-radius, -radius, -radius);
                Voxel.Coord ripEnd   = center.Move(radius, radius, radius);

                Dictionary <Voxel.Box, bool> permanentBoxes = new Dictionary <Voxel.Box, bool>();
                foreach (Voxel.Coord c in ripStart.CoordinatesBetween(ripEnd))
                {
                    Voxel.Box box = voxel.GetBox(c);
                    if (box != null && box.Type.Permanent)
                    {
                        permanentBoxes[box] = true;
                    }
                }

                foreach (Voxel.Box b in permanentBoxes.Keys)
                {
                    // Top and bottom
                    for (int x = b.X - 1; x <= b.X + b.Width; x++)
                    {
                        for (int z = b.Z - 1; z <= b.Z + b.Depth; z++)
                        {
                            Voxel.Coord coord = new Voxel.Coord {
                                X = x, Y = b.Y + b.Height, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }

                            coord = new Voxel.Coord {
                                X = x, Y = b.Y - 1, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }
                        }
                    }

                    // Outer shell
                    for (int y = b.Y; y < b.Y + b.Height; y++)
                    {
                        // Left and right
                        for (int z = b.Z - 1; z <= b.Z + b.Depth; z++)
                        {
                            Voxel.Coord coord = new Voxel.Coord {
                                X = b.X - 1, Y = y, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }

                            coord = new Voxel.Coord {
                                X = b.X + b.Width, Y = y, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }
                        }

                        // Backward and forward
                        for (int x = b.X; x < b.X + b.Width; x++)
                        {
                            Voxel.Coord coord = new Voxel.Coord {
                                X = x, Y = y, Z = b.Z - 1
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }

                            coord = new Voxel.Coord {
                                X = x, Y = y, Z = b.Z + b.Depth
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }
                        }
                    }
                }

                if (edges.Contains(center))
                {
                    return(false);
                }

                // Top and bottom
                for (int x = ripStart.X; x <= ripEnd.X; x++)
                {
                    for (int z = ripStart.Z; z <= ripEnd.Z; z++)
                    {
                        Voxel.Coord c = new Voxel.Coord {
                            X = x, Y = ripStart.Y, Z = z
                        };
                        Voxel.State s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                        c = new Voxel.Coord {
                            X = x, Y = ripEnd.Y, Z = z
                        };
                        s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                    }
                }

                // Sides
                for (int y = ripStart.Y + 1; y <= ripEnd.Y - 1; y++)
                {
                    // Left and right
                    for (int z = ripStart.Z; z <= ripEnd.Z; z++)
                    {
                        Voxel.Coord c = new Voxel.Coord {
                            X = ripStart.X, Y = y, Z = z
                        };
                        Voxel.State s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                        c = new Voxel.Coord {
                            X = ripEnd.X, Y = y, Z = z
                        };
                        s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                    }

                    // Backward and forward
                    for (int x = ripStart.X; x <= ripEnd.X; x++)
                    {
                        Voxel.Coord c = new Voxel.Coord {
                            X = x, Y = y, Z = ripStart.Z
                        };
                        Voxel.State s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                        c = new Voxel.Coord {
                            X = x, Y = y, Z = ripEnd.Z
                        };
                        s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                    }
                }

                Propagator p = WorldFactory.Instance.Get <Propagator>();
                foreach (Voxel.Coord c in edges)
                {
                    p.SparksLowPriority(voxel.GetAbsolutePosition(c), Propagator.Spark.Dangerous);
                }

                voxel.Empty(edges);

                voxel.Regenerate(callback);
                return(true);
            }
            return(false);
        }
Ejemplo n.º 3
0
        public bool Go(bool checkPossibilities)
        {
            if (this.main.TotalTime - this.LastVaultStarted < vaultCoolDown)
            {
                return(false);
            }

            Matrix rotationMatrix = Matrix.CreateRotationY(this.Rotation);

            foreach (Voxel map in Voxel.ActivePhysicsVoxels)
            {
                Direction   up          = map.GetRelativeDirection(Direction.PositiveY);
                Direction   backward    = map.GetRelativeDirection(rotationMatrix.Forward);
                Direction   right       = up.Cross(backward);
                Vector3     pos         = this.Position + rotationMatrix.Forward * -(this.Radius + 0.95f);
                Voxel.Coord resortCoord = default(Voxel.Coord);
                bool        resort      = false;
                for (int j = 0; j < searchForwardDistance; j++)
                {
                    Voxel.Coord baseCoord = map.GetCoordinate(pos + (rotationMatrix.Forward * -j)).Move(up, searchUpDistance);
                    foreach (int x in new[] { 0, -1, 1 })
                    {
                        Voxel.Coord coord = baseCoord.Move(right, x);
                        for (int i = 0; i < searchDownDistance; i++)
                        {
                            if (map[coord] != Voxel.States.Empty)
                            {
                                CandidateStatus status = checkAdjacent(map, coord, up, backward, right);
                                if (status == CandidateStatus.Bad)
                                {
                                    break;                                     // Conflict
                                }
                                bool conflict = false;
                                // Check other voxels for conflicts
                                foreach (Voxel v in Voxel.ActivePhysicsVoxels)
                                {
                                    if (v != map)
                                    {
                                        Direction up2       = v.GetRelativeDirection(Direction.PositiveY);
                                        Direction backward2 = v.GetRelativeDirection(rotationMatrix.Forward);
                                        Direction right2    = up2.Cross(backward2);

                                        Voxel.Coord coord2 = v.GetCoordinate(map.GetAbsolutePosition(coord));
                                        if (v[coord2] != Voxel.States.Empty ||
                                            checkAdjacent(v, coord2, up2, backward2, right2) != CandidateStatus.Good)
                                        {
                                            conflict = true;
                                            break;
                                        }
                                    }
                                }
                                if (conflict)
                                {
                                    break;
                                }

                                if (status == CandidateStatus.Uneven && !resort)
                                {
                                    resortCoord = coord;
                                    resort      = true;
                                    break;
                                }

                                // Vault
                                this.vault(map, coord.Move(up), false);
                                return(true);
                            }
                            coord = coord.Move(up.GetReverse());
                        }
                    }
                }
                if (resort)
                {
                    this.vault(map, resortCoord.Move(up), true);
                    return(true);
                }
            }

            if (checkPossibilities)
            {
                // Check block possibilities for vaulting
                foreach (BlockPredictor.Possibility possibility in this.Predictor.AllPossibilities)
                {
                    Direction   up        = possibility.Map.GetRelativeDirection(Direction.PositiveY);
                    Direction   right     = possibility.Map.GetRelativeDirection(Vector3.Cross(Vector3.Up, -rotationMatrix.Forward));
                    Vector3     pos       = this.Position + rotationMatrix.Forward * (this.WallRunState == WallRun.State.Straight ? -1.75f : -1.25f);
                    Voxel.Coord baseCoord = possibility.Map.GetCoordinate(pos).Move(up, searchUpDistance);
                    foreach (int x in new[] { 0, -1, 1 })
                    {
                        Voxel.Coord coord = baseCoord.Move(right, x);
                        for (int i = 0; i < searchDownDistance; i++)
                        {
                            Voxel.Coord downCoord = coord.Move(up.GetReverse());
                            if (!coord.Between(possibility.StartCoord, possibility.EndCoord) && downCoord.Between(possibility.StartCoord, possibility.EndCoord))
                            {
                                this.Predictor.InstantiatePossibility(possibility);
                                this.vault(possibility.Map, coord, false);
                                return(true);
                            }
                            coord = coord.Move(up.GetReverse());
                        }
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 4
0
        public bool Go()
        {
            if (this.main.TotalTime - this.LastJump < jumpCoolDown || this.Crouched)
            {
                return(false);
            }

            bool supported = this.IsSupported;

            WallRun.State wallRunState = this.WallRunState;

            Matrix  rotationMatrix = Matrix.CreateRotationY(this.Rotation);
            Vector3 forward        = -rotationMatrix.Forward;

            Vector2 jumpDirection = this.AbsoluteMovementDirection;

            Vector3 baseVelocity = Vector3.Zero;

            bool wallJumping = false;

            const float wallJumpHorizontalVelocityAmount = 0.75f;
            const float wallJumpDistance = 2.0f;

            Action <Voxel, Direction, Voxel.Coord> wallJump = delegate(Voxel wallJumpMap, Direction wallNormalDirection, Voxel.Coord wallCoordinate)
            {
                this.LastWallRunMap.Value    = wallJumpMap;
                this.LastWallDirection.Value = wallNormalDirection.GetReverse();
                this.LastWallJump.Value      = main.TotalTime;

                Voxel.State wallType = wallJumpMap[wallCoordinate];
                if (wallType == Voxel.States.Empty)                 // Empty. Must be a block possibility that hasn't been instantiated yet
                {
                    wallType = Voxel.States.Blue;
                }

                this.WalkedOn.Execute(wallJumpMap, wallCoordinate, wallNormalDirection.GetReverse());

                AkSoundEngine.PostEvent(AK.EVENTS.FOOTSTEP_PLAY, this.Entity);

                wallJumping = true;
                // Set up wall jump velocity
                Vector3 absoluteWallNormal = wallJumpMap.GetAbsoluteVector(wallNormalDirection.GetVector());
                Vector2 wallNormal2        = new Vector2(absoluteWallNormal.X, absoluteWallNormal.Z);
                wallNormal2.Normalize();

                bool wallRunningStraight = wallRunState == WallRun.State.Straight || wallRunState == WallRun.State.Down;
                if (wallRunningStraight)
                {
                    jumpDirection = new Vector2(main.Camera.Forward.Value.X, main.Camera.Forward.Value.Z);
                }
                else
                {
                    jumpDirection = new Vector2(forward.X, forward.Z);
                }

                jumpDirection.Normalize();

                float dot = Vector2.Dot(wallNormal2, jumpDirection);
                if (dot < 0)
                {
                    jumpDirection = jumpDirection - (2.0f * dot * wallNormal2);
                }
                jumpDirection *= wallJumpHorizontalVelocityAmount;

                if (!wallRunningStraight && Math.Abs(dot) < 0.5f)
                {
                    // If we're jumping perpendicular to the wall, add some velocity so we jump away from the wall a bit
                    jumpDirection += wallJumpHorizontalVelocityAmount * 0.75f * wallNormal2;
                }

                Vector3 supportLocation = this.FloorPosition;
                baseVelocity += wallJumpMap.LinearVelocity + Vector3.Cross(wallJumpMap.AngularVelocity, supportLocation - wallJumpMap.Transform.Value.Translation);
            };

            if (!supported && wallRunState == WallRun.State.None &&
                this.LinearVelocity.Value.Y > Lemma.Components.FallDamage.DamageVelocity * 1.5f)
            {
                // We're not doing our normal jump, and not wall-runnign
                // See if we can wall-jump
                Vector3 playerPos = this.Position;
                Voxel.GlobalRaycastResult?closestWallRaycastHit = null;
                Vector3 closestWallRaycastDirection             = Vector3.Zero;

                foreach (Vector3 dir in new[] { rotationMatrix.Left, rotationMatrix.Right, rotationMatrix.Backward, rotationMatrix.Forward })
                {
                    Voxel.GlobalRaycastResult hit = Voxel.GlobalRaycast(playerPos, dir, wallJumpDistance);
                    if (hit.Voxel != null && (!closestWallRaycastHit.HasValue || hit.Distance < closestWallRaycastHit.Value.Distance))
                    {
                        closestWallRaycastDirection = dir;
                        closestWallRaycastHit       = hit;
                    }
                }

                if (closestWallRaycastHit != null)
                {
                    Voxel m = closestWallRaycastHit.Value.Voxel;
                    wallJump(m, closestWallRaycastHit.Value.Normal, closestWallRaycastHit.Value.Coordinate.Value);
                }
            }

            // If we're wall-running, we can wall-jump
            // Add some velocity so we jump away from the wall a bit
            if (wallRunState != WallRun.State.None)
            {
                Vector3     pos       = this.FloorPosition + new Vector3(0, 0.5f, 0);
                Voxel.Coord wallCoord = this.WallRunMap.Value.GetCoordinate(pos).Move(this.WallDirection, 2);
                wallJump(this.WallRunMap, this.WallDirection.Value.GetReverse(), wallCoord);
            }

            bool go = supported || wallJumping;

            BlockPredictor.Possibility instantiatedBlockPossibility = null;
            Voxel.Coord instantiatedBlockPossibilityCoord           = default(Voxel.Coord);

            if (!go)
            {
                // Check block possibilities beneath us
                Vector3 jumpPos = this.FloorPosition + new Vector3(0, -1.0f, 0);
                foreach (BlockPredictor.Possibility possibility in this.Predictor.AllPossibilities)
                {
                    Voxel.Coord possibilityCoord = possibility.Map.GetCoordinate(jumpPos);
                    if (possibilityCoord.Between(possibility.StartCoord, possibility.EndCoord) &&
                        !possibility.Map.GetCoordinate(jumpPos + new Vector3(2.0f)).Between(possibility.StartCoord, possibility.EndCoord))
                    {
                        this.Predictor.InstantiatePossibility(possibility);
                        go = true;
                        instantiatedBlockPossibility      = possibility;
                        instantiatedBlockPossibilityCoord = possibilityCoord;
                        break;
                    }
                }
            }

            if (!go)
            {
                // Check block possibilities for wall jumping
                Vector3   playerPos          = this.Position;
                Vector3[] wallJumpDirections = new[] { rotationMatrix.Left, rotationMatrix.Right, rotationMatrix.Forward };
                foreach (BlockPredictor.Possibility possibility in this.Predictor.AllPossibilities)
                {
                    foreach (Vector3 dir in wallJumpDirections)
                    {
                        foreach (Voxel.Coord coord in possibility.Map.Rasterize(playerPos, playerPos + (dir * wallJumpDistance)))
                        {
                            if (coord.Between(possibility.StartCoord, possibility.EndCoord))
                            {
                                this.Predictor.InstantiatePossibility(possibility);
                                instantiatedBlockPossibility      = possibility;
                                instantiatedBlockPossibilityCoord = coord;
                                wallJump(possibility.Map, possibility.Map.GetRelativeDirection(dir).GetReverse(), coord);
                                wallJumping = true;
                                go          = true;
                                break;
                            }
                        }
                        if (wallJumping)
                        {
                            break;
                        }
                    }
                    if (wallJumping)
                    {
                        break;
                    }
                }
            }

            if (go)
            {
                float totalMultiplier = 1.0f;

                bool grunted = false;

                if (wallJumping)
                {
                    if (this.wallJumpCount == 0)
                    {
                        this.wallJumpChainStart = this.Position;
                    }
                    else
                    {
                        Vector3 chainDistance = this.Position - this.wallJumpChainStart;
                        chainDistance.Y = 0.0f;
                        if (chainDistance.Length() > 6.0f)
                        {
                            this.wallJumpCount      = 0;
                            this.wallJumpChainStart = this.Position;
                        }
                    }

                    if (this.wallJumpCount > 3)
                    {
                        return(false);
                    }
                    totalMultiplier = 1.0f - Math.Min(1.0f, this.wallJumpCount / 8.0f);
                    this.wallJumpCount++;
                }
                else
                {
                    // Regular jump
                    // Take base velocity into account
                    baseVelocity += this.SupportVelocity;

                    grunted = this.FallDamage.ApplyJump();
                    if (!this.Active)                     // We got killed by fall damage
                    {
                        return(false);
                    }
                    if (instantiatedBlockPossibility != null)
                    {
                        this.WalkedOn.Execute(instantiatedBlockPossibility.Map, instantiatedBlockPossibilityCoord, instantiatedBlockPossibility.Map.GetRelativeDirection(Direction.NegativeY));
                    }

                    // Also manually reset our ability to kick and wall-jump
                    this.CanKick.Value = true;
                    this.wallJumpCount = 0;
                }

                Vector3 velocity             = this.LinearVelocity - baseVelocity;
                float   currentVerticalSpeed = velocity.Y;
                velocity.Y = 0.0f;
                float jumpSpeed = jumpDirection.Length();
                if (jumpSpeed > 0)
                {
                    jumpDirection *= (wallJumping ? Math.Max(this.MaxSpeed, Vector3.Dot(forward, velocity)) : velocity.Length()) / jumpSpeed;
                }

                if (main.TotalTime - this.LastRollKickEnded < 0.3f)
                {
                    totalMultiplier *= 1.2f;
                }

                float verticalJumpSpeed = this.JumpSpeed;

                // If we're not instantiating a block possibility beneath us or we're not currently falling, incorporate some of our existing vertical velocity in our jump
                if (instantiatedBlockPossibility == null || wallJumping || currentVerticalSpeed > 0.0f)
                {
                    verticalJumpSpeed += currentVerticalSpeed * 0.5f;
                }

                this.LinearVelocity.Value = baseVelocity + new Vector3(jumpDirection.X, verticalJumpSpeed, jumpDirection.Y) * totalMultiplier;

                velocity   = this.LinearVelocity;
                velocity.Y = 0.0f;
                this.LastSupportedSpeed.Value = velocity.Length();

                if (supported && this.SupportEntity.Value != null)
                {
                    Vector3 impulsePosition = this.FloorPosition;
                    Vector3 impulse         = this.LinearVelocity.Value * this.Mass * -1.0f;
                    this.SupportEntity.Value.ApplyImpulse(ref impulsePosition, ref impulse);
                }

                Session.Recorder.Event(main, "Jump");

                this.IsSupported.Value   = false;
                this.SupportEntity.Value = null;
                this.HasTraction.Value   = false;

                AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_JUMP, this.Entity);
                if (!grunted && (float)this.random.NextDouble() < 0.15f)
                {
                    AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_LAND, this.Entity);                     // Grunt
                }
                this.model.Stop
                (
                    "Vault",
                    "Mantle",
                    "TopOut",
                    "Jump",
                    "Jump02",
                    "Jump03",
                    "JumpLeft",
                    "JumpRight",
                    "JumpBackward"
                );

                velocity   = -Vector3.TransformNormal(this.LinearVelocity, Matrix.CreateRotationY(-this.Rotation));
                velocity.Y = 0.0f;
                if (wallRunState == WallRun.State.Left || wallRunState == WallRun.State.Right)
                {
                    velocity.Z = 0.0f;
                }
                else if (wallJumping)
                {
                    velocity.Z *= 0.5f;
                }
                else
                {
                    velocity.X = 0.0f;
                }
                Direction direction = DirectionExtensions.GetDirectionFromVector(velocity);
                string    animation;
                switch (direction)
                {
                case Direction.NegativeX:
                    animation = "JumpLeft";
                    break;

                case Direction.PositiveX:
                    animation = "JumpRight";
                    break;

                case Direction.PositiveZ:
                    animation = wallJumping ? "JumpBackward" : this.randomJumpAnimation();
                    break;

                default:
                    animation = this.randomJumpAnimation();
                    break;
                }
                this.model.StartClip(animation, 4, false);
                this.model[animation].CurrentTime = TimeSpan.FromSeconds(0.2);

                // Deactivate any wall-running we're doing
                this.DeactivateWallRun.Execute();

                // Play a footstep sound since we're jumping off the ground
                AkSoundEngine.PostEvent(AK.EVENTS.FOOTSTEP_PLAY, this.Entity);

                this.LastJump.Value = this.main.TotalTime;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 5
0
		public static bool Go(Voxel voxel, Voxel.Coord center, int radius, Action<List<DynamicVoxel>> callback = null)
		{
			if (!voxel[center].Permanent)
			{
				// Break off a chunk of this voxel into a new DynamicMap.

				List<Voxel.Coord> edges = new List<Voxel.Coord>();

				Voxel.Coord ripStart = center.Move(-radius, -radius, -radius);
				Voxel.Coord ripEnd = center.Move(radius, radius, radius);

				Dictionary<Voxel.Box, bool> permanentBoxes = new Dictionary<Voxel.Box, bool>();
				foreach (Voxel.Coord c in ripStart.CoordinatesBetween(ripEnd))
				{
					Voxel.Box box = voxel.GetBox(c);
					if (box != null && box.Type.Permanent)
						permanentBoxes[box] = true;
				}

				foreach (Voxel.Box b in permanentBoxes.Keys)
				{
					// Top and bottom
					for (int x = b.X - 1; x <= b.X + b.Width; x++)
					{
						for (int z = b.Z - 1; z <= b.Z + b.Depth; z++)
						{
							Voxel.Coord coord = new Voxel.Coord { X = x, Y = b.Y + b.Height, Z = z };
							if (coord.Between(ripStart, ripEnd))
								edges.Add(coord);

							coord = new Voxel.Coord { X = x, Y = b.Y - 1, Z = z };
							if (coord.Between(ripStart, ripEnd))
								edges.Add(coord);
						}
					}

					// Outer shell
					for (int y = b.Y; y < b.Y + b.Height; y++)
					{
						// Left and right
						for (int z = b.Z - 1; z <= b.Z + b.Depth; z++)
						{
							Voxel.Coord coord = new Voxel.Coord { X = b.X - 1, Y = y, Z = z };
							if (coord.Between(ripStart, ripEnd))
								edges.Add(coord);

							coord = new Voxel.Coord { X = b.X + b.Width, Y = y, Z = z };
							if (coord.Between(ripStart, ripEnd))
								edges.Add(coord);
						}

						// Backward and forward
						for (int x = b.X; x < b.X + b.Width; x++)
						{
							Voxel.Coord coord = new Voxel.Coord { X = x, Y = y, Z = b.Z - 1 };
							if (coord.Between(ripStart, ripEnd))
								edges.Add(coord);

							coord = new Voxel.Coord { X = x, Y = y, Z = b.Z + b.Depth };
							if (coord.Between(ripStart, ripEnd))
								edges.Add(coord);
						}
					}
				}

				if (edges.Contains(center))
					return false;

				// Top and bottom
				for (int x = ripStart.X; x <= ripEnd.X; x++)
				{
					for (int z = ripStart.Z; z <= ripEnd.Z; z++)
					{
						Voxel.Coord c = new Voxel.Coord { X = x, Y = ripStart.Y, Z = z };
						Voxel.State s = voxel[c];
						if (s != Voxel.States.Empty && !s.Permanent)
							edges.Add(c);
						c = new Voxel.Coord { X = x, Y = ripEnd.Y, Z = z };
						s = voxel[c];
						if (s != Voxel.States.Empty && !s.Permanent)
							edges.Add(c);
					}
				}

				// Sides
				for (int y = ripStart.Y + 1; y <= ripEnd.Y - 1; y++)
				{
					// Left and right
					for (int z = ripStart.Z; z <= ripEnd.Z; z++)
					{
						Voxel.Coord c = new Voxel.Coord { X = ripStart.X, Y = y, Z = z };
						Voxel.State s = voxel[c];
						if (s != Voxel.States.Empty && !s.Permanent)
							edges.Add(c);
						c = new Voxel.Coord { X = ripEnd.X, Y = y, Z = z };
						s = voxel[c];
						if (s != Voxel.States.Empty && !s.Permanent)
							edges.Add(c);
					}

					// Backward and forward
					for (int x = ripStart.X; x <= ripEnd.X; x++)
					{
						Voxel.Coord c = new Voxel.Coord { X = x, Y = y, Z = ripStart.Z };
						Voxel.State s = voxel[c];
						if (s != Voxel.States.Empty && !s.Permanent)
							edges.Add(c);
						c = new Voxel.Coord { X = x, Y = y, Z = ripEnd.Z };
						s = voxel[c];
						if (s != Voxel.States.Empty && !s.Permanent)
							edges.Add(c);
					}
				}

				Propagator p = WorldFactory.Instance.Get<Propagator>();
				foreach (Voxel.Coord c in edges)
					p.SparksLowPriority(voxel.GetAbsolutePosition(c), Propagator.Spark.Dangerous);

				voxel.Empty(edges);

				voxel.Regenerate(callback);
				return true;
			}
			return false;
		}