Esempio n. 1
0
 public static IEnumerable<Zone> GetConnectedZones(Zone zone)
 {
     IEnumerable<Zone> result = new Zone[] { zone };
     foreach (Entity e in zone.ConnectedEntities)
     {
         Zone z;
         if (e != null && (z = e.Get<Zone>()) != null)
             result = result.Concat(Zone.GetConnectedZones(z));
     }
     return result;
 }
Esempio n. 2
0
        private static void processEntity(Entity entity, Zone currentZone, IEnumerable<NonAxisAlignedBoundingBox> boxes, Vector3 cameraPosition, float suspendDistance)
        {
            Map map = entity.Get<Map>();
            if (map != null && !typeof(DynamicMap).IsAssignableFrom(map.GetType()))
                processMap(map, boxes);
            else
            {
                Transform transform = entity.Get<Transform>();
                bool hasPosition = transform != null;

                Vector3 pos = Vector3.Zero;

                if (hasPosition)
                    pos = transform.Position;

                if (map != null && typeof(DynamicMap).IsAssignableFrom(map.GetType()))
                {
                    hasPosition = true;
                    pos = Vector3.Transform(Vector3.Zero, map.Transform);
                }

                bool suspended;
                if (currentZone != null && currentZone.Exclusive) // Suspend everything outside the current zone, unless it's connected
                    suspended = !currentZone.ConnectedEntities.Contains(entity) && hasPosition && !boxesContain(boxes, pos);
                else
                {
                    // Only suspend things that are in a different (exclusive) zone, or that are just too far away
                    suspended = false;
                    if (hasPosition)
                    {
                        if (!entity.CannotSuspendByDistance && !boxesContain(boxes, pos) && (pos - cameraPosition).Length() > suspendDistance)
                            suspended = true;
                        else
                        {
                            foreach (Zone z in Zone.Zones)
                            {
                                if (z != currentZone && z.Exclusive && z.BoundingBox.Value.Contains(Vector3.Transform(pos, Matrix.Invert(z.Transform))) != ContainmentType.Disjoint)
                                {
                                    suspended = true;
                                    break;
                                }
                            }
                        }
                    }

                    // Allow the editor to reverse the decision
                    if (currentZone != null && currentZone.ConnectedEntities.Contains(entity))
                        suspended = !suspended;
                }

                entity.SetSuspended(suspended);
            }
        }
Esempio n. 3
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;
                }

                Vector3 wallRunVector = this.WallRunVoxel.Value.GetAbsoluteVector(this.WallRunDirection.Value.GetVector());
                float   wallRunSpeed  = Vector3.Dot(this.LinearVelocity.Value, 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 = this.WallRunVoxel.Value.GetAbsoluteVector(this.WallDirection.Value.GetVector());
                        Voxel.GlobalRaycastResult result = Voxel.GlobalRaycast(pos, wallRunVector + wallVector, 2.0f);
                        if (result.Voxel != null && result.Voxel != this.WallRunVoxel.Value)
                        {
                            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     = this.WallRunVoxel.Value.GetCoordinate(pos);
                Voxel.Coord wallCoord = coord.Move(this.WallDirection, 2);
                Voxel.State wallType  = this.WallRunVoxel.Value[wallCoord];
                this.WalkedOn.Execute(this.WallRunVoxel, wallCoord, this.WallDirection);

                if (this.EnableEnhancedWallRun && (wallRunState == State.Left || wallRunState == State.Right) && Zone.CanBuild(this.Position))
                {
                    Direction up    = this.WallRunVoxel.Value.GetRelativeDirection(Direction.PositiveY);
                    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 && this.WallRunVoxel.Value[y].ID == 0)
                            {
                                buildCoords.Add(new EffectBlockFactory.BlockBuildOrder
                                {
                                    Voxel      = this.WallRunVoxel,
                                    Coordinate = y,
                                    State      = Voxel.States.Blue,
                                });
                            }
                        }
                    }
                    Factory.Get <EffectBlockFactory>().Build(main, buildCoords, this.Position);
                }
                else if (wallType.ID == 0 && wallInstantiationTimer == 0.0f)                 // We ran out of wall to walk on
                {
                    this.Deactivate();
                    return;
                }

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

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

                Vector3 coordPos = this.WallRunVoxel.Value.GetAbsolutePosition(coord);

                Vector3 normal = this.WallRunVoxel.Value.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;
            }
        }
Esempio n. 4
0
 private static IEnumerable<NonAxisAlignedBoundingBox> getActiveBoundingBoxes(Camera camera, Zone currentZone)
 {
     if (currentZone == null)
     {
         Vector3 pos = camera.Position;
         float radius = camera.FarPlaneDistance;
         return new[] { new NonAxisAlignedBoundingBox { BoundingBox = new BoundingBox(pos - new Vector3(radius), pos + new Vector3(radius)), Transform = Matrix.Identity } };
     }
     else
         return Zone.GetConnectedZones(currentZone).Select(x => new NonAxisAlignedBoundingBox { BoundingBox = x.BoundingBox, Transform = Matrix.Invert(x.Transform) }).ToList();
 }
Esempio n. 5
0
        public static bool CanSpawnAt(Vector3 x)
        {
            Zone z = Zone.Get(x);

            return(z == null || z.CanSpawn.Value);
        }