Example #1
0
        public void Update(float dt)
        {
            State wallRunState = this.CurrentState;

            if (wallRunState != State.None)
            {
                this.Vault.Execute();                      // Try to vault up
                if (this.CurrentState.Value == State.None) // We vaulted
                {
                    return;
                }

                if (!this.WallRunVoxel.Value.Active || this.IsSupported)
                {
                    this.Deactivate();
                    return;
                }

                Voxel voxel = this.WallRunVoxel.Value;
                if (voxel == null || !voxel.Active)
                {
                    this.Deactivate();
                    return;
                }

                Vector3 wallRunVector = voxel.GetAbsoluteVector(this.WallRunDirection.Value.GetVector());
                Vector3 baseVelocity  = voxel.LinearVelocity + Vector3.Cross(voxel.AngularVelocity, this.Position - voxel.Transform.Value.Translation);
                float   wallRunSpeed  = Vector3.Dot(this.LinearVelocity.Value - baseVelocity, wallRunVector);
                Vector3 pos           = this.Position + new Vector3(0, this.Height * -0.5f, 0);

                if (wallRunState == State.Straight)
                {
                    if (wallRunSpeed < 0.0f)
                    {
                        // Start sliding down
                        this.CurrentState.Value = wallRunState = State.Down;
                        AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_SLIDE_LOOP, this.Entity);
                    }
                }
                else if (wallRunState == State.Left || wallRunState == State.Right)
                {
                    if (this.IsSupported || wallRunSpeed < minWallRunSpeed)
                    {
                        // We landed on the ground or we're going too slow to continue wall-running
                        this.Deactivate();
                        return;
                    }
                    else
                    {
                        // Check if we should switch to another wall
                        Vector3 wallVector = voxel.GetAbsoluteVector(this.WallDirection.Value.GetVector());
                        Voxel.GlobalRaycastResult result = Voxel.GlobalRaycast(pos, wallRunVector + wallVector, 2.0f);
                        if (result.Voxel != null && result.Voxel != voxel)
                        {
                            float dot = Vector3.Dot(result.Voxel.GetAbsoluteVector(result.Normal.GetReverse().GetVector()), wallVector);
                            if (dot > 0.7f)
                            {
                                Matrix  matrix        = Matrix.CreateRotationY(this.Rotation);
                                Vector3 forwardVector = -matrix.Forward;
                                this.setup(result.Voxel, result.Normal.GetReverse(), wallRunState, forwardVector, false, true);
                            }
                        }
                    }
                }

                Voxel.Coord coord     = voxel.GetCoordinate(pos);
                Voxel.Coord wallCoord = coord.Move(this.WallDirection, 2);
                Voxel.State wallType  = voxel[wallCoord];

                if (!wallCoord.Equivalent(this.lastWallRunCoord))
                {
                    this.lastWallRunCoord = wallCoord;
                    this.WalkedOn.Execute(voxel, wallCoord, this.WallDirection);
                }

                if (this.EnableEnhancedWallRun &&
                    (wallRunState == State.Left || wallRunState == State.Right) &&
                    Zone.CanBuild(this.Position) &&
                    voxel.Entity.Type != "Bouncer")
                {
                    Direction up = voxel.GetRelativeDirection(Direction.PositiveY);
                    if (up.IsPerpendicular(this.WallDirection))
                    {
                        Direction right = this.WallDirection.Value.Cross(up);

                        List <EffectBlockFactory.BlockBuildOrder> buildCoords = new List <EffectBlockFactory.BlockBuildOrder>();

                        const int radius       = 5;
                        int       upwardRadius = wallRunState == State.Down ? 0 : radius;
                        for (Voxel.Coord x = wallCoord.Move(right, -radius); x.GetComponent(right) < wallCoord.GetComponent(right) + radius; x = x.Move(right))
                        {
                            int dx = x.GetComponent(right) - wallCoord.GetComponent(right);
                            for (Voxel.Coord y = x.Move(up, -radius); y.GetComponent(up) < wallCoord.GetComponent(up) + upwardRadius; y = y.Move(up))
                            {
                                int dy = y.GetComponent(up) - wallCoord.GetComponent(up);
                                if ((float)Math.Sqrt(dx * dx + dy * dy) < radius && voxel[y].ID == 0)
                                {
                                    buildCoords.Add(new EffectBlockFactory.BlockBuildOrder
                                    {
                                        Voxel      = voxel,
                                        Coordinate = y,
                                        State      = Voxel.States.Blue,
                                    });
                                }
                            }
                        }
                        Factory.Get <EffectBlockFactory>().Build(main, buildCoords, this.Position);
                    }
                    else
                    {
                        this.Deactivate();
                        return;
                    }
                }
                else if (wallType.ID == 0 && wallInstantiationTimer == 0.0f)                 // We ran out of wall to walk on
                {
                    this.Deactivate();
                    return;
                }

                wallInstantiationTimer = Math.Max(0.0f, wallInstantiationTimer - dt);

                Vector3 coordPos = voxel.GetAbsolutePosition(coord);

                Vector3 normal = voxel.GetAbsoluteVector(this.WallDirection.Value.GetVector());
                // Equation of a plane
                // normal (dot) point = d
                float d = Vector3.Dot(normal, coordPos) + (wallRunState == State.Down ? 0.3f : 0.4f);

                // Distance along the normal to keep the player glued to the wall
                float snapDistance = d - Vector3.Dot(pos, normal);

                this.Position.Value += normal * snapDistance;

                Vector3 velocity = this.LinearVelocity;

                // Also fix the velocity so we don't jitter away from the wall
                velocity -= Vector3.Dot(velocity, normal) * normal;

                // Slow our descent
                velocity += new Vector3(0, (wallRunState == State.Straight ? 3.0f : 10.0f) * dt, 0);

                this.LinearVelocity.Value = velocity;
            }
        }
Example #2
0
 private bool canBuild(Vector3 pos)
 {
     return(Zone.CanBuild(pos) && Water.Get(pos) == null);
 }
Example #3
0
        public void Update(float dt)
        {
            if (this.TargetVoxel.Target == null || !this.TargetVoxel.Target.Active)
            {
                this.Delete.Execute();
                return;
            }

            this.Lifetime += dt;

            if (this.Lifetime < this.Delay)
            {
                return;
            }

            float blend = (this.Lifetime - this.Delay) / this.TotalLifetime;

            Voxel m = this.TargetVoxel.Target.Get <Voxel>();

            Matrix finalOrientation = m.Transform;

            finalOrientation.Translation = Vector3.Zero;
            Quaternion finalQuat = Quaternion.CreateFromRotationMatrix(finalOrientation);

            Vector3 finalPosition = m.GetAbsolutePosition(this.Coord);

            if (blend > 1.0f)
            {
                if (this.StateId != Voxel.t.Empty)
                {
                    Voxel.Coord c = this.Coord;

                    bool blue = this.StateId == Voxel.t.Blue;
                    bool foundAdjacentCell = false;
                    bool foundConflict     = false;
                    if (this.CheckAdjacent)
                    {
                        foreach (Direction dir in DirectionExtensions.Directions)
                        {
                            Voxel.Coord adjacent   = c.Move(dir);
                            Voxel.t     adjacentID = m[adjacent].ID;
                            if (adjacentID != Voxel.t.Empty)
                            {
                                if (blue && (adjacentID == Voxel.t.Infected || adjacentID == Voxel.t.HardInfected || adjacentID == Voxel.t.Slider || adjacentID == Voxel.t.SliderPowered || adjacentID == Voxel.t.SocketWhite || adjacentID == Voxel.t.SocketBlue || adjacentID == Voxel.t.SocketYellow))
                                {
                                    foundConflict = true;
                                }
                                else
                                {
                                    foundAdjacentCell = true;
                                    if (blue)
                                    {
                                        if (adjacentID == Voxel.t.Reset)
                                        {
                                            this.StateId = Voxel.t.Neutral;
                                            break;
                                        }
                                        else if (adjacentID == Voxel.t.Powered || adjacentID == Voxel.t.PermanentPowered || adjacentID == Voxel.t.PoweredSwitch || adjacentID == Voxel.t.HardPowered)
                                        {
                                            this.StateId = Voxel.t.Powered;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        foundAdjacentCell = true;
                    }

                    if (foundAdjacentCell)
                    {
                        Vector3 absolutePos = m.GetAbsolutePosition(c);

                        if (blue && !Zone.CanBuild(absolutePos))
                        {
                            foundConflict = true;
                        }

                        if (!foundConflict)
                        {
                            bool isDynamic = m.GetType() == typeof(DynamicVoxel);
                            foreach (Voxel m2 in Voxel.ActivePhysicsVoxels)
                            {
                                bool atLeastOneDynamic = isDynamic || m2.GetType() == typeof(DynamicVoxel);
                                if (m2 != m && atLeastOneDynamic && m2[absolutePos].ID != 0)
                                {
                                    foundConflict = true;
                                    break;
                                }
                            }
                        }

                        if (!foundConflict)
                        {
                            Voxel.State state = m[this.Coord];
                            if (state.Permanent || state.Hard || state.ID == this.StateId || (blue && state == Voxel.States.Powered))
                            {
                                foundConflict = true;
                            }
                            else
                            {
                                if (state.ID != 0)
                                {
                                    m.Empty(this.Coord);
                                }
                                m.Fill(this.Coord, Voxel.States.All[this.StateId]);
                                m.Regenerate();
                                if (EffectBlock.random.Next(0, 4) == 0)
                                {
                                    AkSoundEngine.PostEvent(AK.EVENTS.PLAY_BLOCK_BUILD, this.Entity);
                                }
                                this.Entity.Delete.Execute();
                                return;
                            }
                        }
                    }

                    // For one reason or another, we can't fill the cell
                    // Animate nicely into oblivion
                    this.StateId = Voxel.t.Empty;
                }
                else
                {
                    // For one reason or another, we can't fill the cell
                    // Animate nicely into oblivion
                    if (blend > 2.0f)
                    {
                        this.Delete.Execute();
                    }
                    else
                    {
                        Matrix result = Matrix.CreateFromQuaternion(finalQuat);
                        float  scale  = 2.0f - blend;
                        result.Right        *= scale;
                        result.Up           *= scale;
                        result.Forward      *= scale;
                        result.Translation   = finalPosition;
                        this.Transform.Value = result;
                    }
                }
            }
            else
            {
                float scale;
                if (this.DoScale)
                {
                    scale = blend;
                }
                else
                {
                    scale = 1.0f;
                }

                float distance = (finalPosition - this.StartPosition).Length() * 0.1f * Math.Max(0.0f, 0.5f - Math.Abs(blend - 0.5f));

                Matrix result = Matrix.CreateFromQuaternion(Quaternion.Lerp(this.StartOrientation, finalQuat, blend));
                result.Right        *= scale;
                result.Up           *= scale;
                result.Forward      *= scale;
                result.Translation   = Vector3.Lerp(this.StartPosition, finalPosition, blend) + new Vector3((float)Math.Sin(blend * Math.PI) * distance);
                this.Transform.Value = result;
            }
        }
Example #4
0
 private bool canBuild(Vector3 pos)
 {
     return(Zone.CanBuild(pos) && !Water.IsSubmerged(pos));
 }