Exemplo n.º 1
0
 public void Setup(Entity map, Voxel.Coord c, Voxel.t s)
 {
     this.TargetVoxel = map;
     this.Coord       = c;
     this.StateId     = s;
     this.addEntry();
 }
Exemplo n.º 2
0
 public float Sample(Voxel voxel, Voxel.Coord coord, float octave)
 {
     coord.X -= voxel.MinX;
     coord.Y -= voxel.MinY;
     coord.Z -= voxel.MinZ;
     return(this.noise3d(new Vector3(coord.X / octave, coord.Y / octave, coord.Z / octave)));
 }
Exemplo n.º 3
0
 private static CandidateStatus checkAdjacent(Voxel v, Voxel.Coord coord, Direction up, Direction backward, Direction right)
 {
     if (v[coord.Move(backward)] != Voxel.States.Empty ||
         v[coord.Move(up).Move(backward)] != Voxel.States.Empty ||
         v[coord.Move(up, 2).Move(backward)] != Voxel.States.Empty ||
         v[coord.Move(up, 3).Move(backward)] != Voxel.States.Empty ||
         v[coord.Move(up)] != Voxel.States.Empty ||
         v[coord.Move(up, 2)] != Voxel.States.Empty ||
         v[coord.Move(up, 3)] != Voxel.States.Empty)
     {
         return(CandidateStatus.Bad);
     }
     else if (v[coord.Move(right, -1).Move(up)] != Voxel.States.Empty ||
              v[coord.Move(right, -1).Move(up, 2)] != Voxel.States.Empty ||
              v[coord.Move(right, -1).Move(up, 3)] != Voxel.States.Empty ||
              v[coord.Move(right).Move(up)] != Voxel.States.Empty ||
              v[coord.Move(right).Move(up, 2)] != Voxel.States.Empty ||
              v[coord.Move(right).Move(up, 3)] != Voxel.States.Empty)
     {
         return(CandidateStatus.Uneven);
     }
     else
     {
         return(CandidateStatus.Good);
     }
 }
Exemplo n.º 4
0
 private void populateCoords()
 {
     if (this.Coords.Length == 0)
     {
         Voxel  map          = this.Entity.Get <Voxel>();
         Entity targetEntity = this.Target.Value.Target;
         if (targetEntity != null && targetEntity.Active)
         {
             Voxel m = targetEntity.Get <Voxel>();
             lock (map.MutationLock)
             {
                 foreach (CoordinateEntry e in map.Chunks.SelectMany(c => c.Boxes.SelectMany(x => x.GetCoords())).Select(delegate(Voxel.Coord y)
                 {
                     Voxel.Coord z = m.GetCoordinate(map.GetAbsolutePosition(y));
                     z.Data = y.Data;
                     return(new CoordinateEntry {
                         Coord = z,
                     });
                 }))
                 {
                     this.Coords.Add(e);
                 }
             }
         }
     }
 }
Exemplo n.º 5
0
        public static void Consolidate(Main main, DynamicVoxel voxel, float interval = 1.0f)
        {
            int   maxDistance  = 12;
            Voxel closestVoxel = null;

            Voxel.Coord closestCoord = new Voxel.Coord();
            foreach (Voxel m in Voxel.ActivePhysicsVoxels)
            {
                if (m == voxel)
                {
                    continue;
                }

                Voxel.Coord relativeCoord = m.GetCoordinate(voxel.Transform.Value.Translation);
                Voxel.Coord?closestFilled = m.FindClosestFilledCell(relativeCoord, maxDistance);
                if (closestFilled != null)
                {
                    maxDistance  = Math.Min(Math.Abs(relativeCoord.X - closestFilled.Value.X), Math.Min(Math.Abs(relativeCoord.Y - closestFilled.Value.Y), Math.Abs(relativeCoord.Z - closestFilled.Value.Z)));
                    closestVoxel = m;
                    closestCoord = closestFilled.Value;
                }
            }

            if (closestVoxel != null)
            {
                VoxelRip.Consolidate(main, voxel, closestVoxel, closestCoord, interval);
            }
        }
Exemplo n.º 6
0
        public override void Start()
        {
            if (this.Enabled && !this.main.EditorEnabled)
            {
                if (this.AttachedVoxel.Value.Target == null)
                {
                    Vector3 target = Vector3.Transform(new Vector3(0, 0, this.Offset), this.Transform);

                    Entity closestMap           = null;
                    float  closestFloatDistance = 3.0f;

                    foreach (SceneryBlock block in SceneryBlock.All)
                    {
                        Vector3 pos      = block.Entity.Get <Transform>().Position;
                        float   distance = (pos - target).Length();
                        if (distance < closestFloatDistance)
                        {
                            closestFloatDistance = distance;
                            closestMap           = block.Entity;
                        }
                    }

                    int closestDistance = (int)Math.Floor(closestFloatDistance);
                    foreach (Voxel m in Voxel.Voxels)
                    {
                        SliderCommon s = m.Entity.Get <SliderCommon>();
                        Vector3      relativeTarget = Vector3.Transform(target, Matrix.Invert(s != null ? s.OriginalTransform : m.Transform)) + m.Offset;
                        Voxel.Coord  targetCoord    = m.GetCoordinateFromRelative(relativeTarget);
                        Voxel.Coord? c = m.FindClosestFilledCell(targetCoord, closestDistance);
                        if (c.HasValue)
                        {
                            float distance = (m.GetRelativePosition(c.Value) - m.GetRelativePosition(targetCoord)).Length();
                            if (distance < closestFloatDistance)
                            {
                                closestFloatDistance = distance;
                                closestDistance      = (int)Math.Floor(distance);
                                closestMap           = m.Entity;
                            }
                        }
                    }
                    if (closestMap == null)
                    {
                        this.Detach.Execute();
                    }
                    else
                    {
                        this.AttachedVoxel.Value = closestMap;
                    }
                }
                else
                {
                    this.AttachedVoxel.Reset();
                }
            }
        }
Exemplo n.º 7
0
 private IEnumerable <Voxel.Coord> spreadFromCenter(Voxel.Coord center, Direction dir)
 {
     for (Voxel.Coord z = center.Move(dir, -1); z.GetComponent(dir) > center.GetComponent(dir) - 3; z = z.Move(dir.GetReverse()))
     {
         yield return(z);
     }
     for (Voxel.Coord z = center.Clone(); z.GetComponent(dir) < center.GetComponent(dir) + 3; z = z.Move(dir))
     {
         yield return(z);
     }
 }
Exemplo n.º 8
0
 public void MoveTo(Voxel.Coord coord, Voxel map = null)
 {
     this.LastCoord.Value = this.Coord;
     this.LastVoxel.Value = this.Voxel;
     if (map != null)
     {
         this.Voxel.Value = map.Entity;
     }
     this.Coord.Value = coord;
     this.Blend.Value = 0.0f;
 }
Exemplo n.º 9
0
 private bool isInQueue(Entity m, Voxel.Coord c, bool removing)
 {
     for (int i = 0; i < this.BlockQueue.Count; i++)
     {
         ScheduledBlock b = this.BlockQueue[i];
         if (b.Removing == removing && m == b.Voxel.Target && b.Coordinate.Equivalent(c))
         {
             return(true);
         }
     }
     return(false);
 }
Exemplo n.º 10
0
        // Search for nearby boxes that meet a filter criteria within a vaguely defined radius
        public static Voxel.Box BroadphaseSearch(Voxel v, Voxel.Coord coord, int radius, Func <Voxel.Box, bool> filter)
        {
            Queue <Voxel.Box>           queue   = new Queue <Voxel.Box>();
            Dictionary <Voxel.Box, int> visited = new Dictionary <Voxel.Box, int>();

            Voxel.Box startBox = v.GetBox(coord);
            if (startBox == null)
            {
                return(null);
            }
            queue.Enqueue(startBox);
            visited[startBox] = 0;
            int maxSearch   = radius * radius * radius;
            int searchIndex = 0;

            while (queue.Count > 0 && searchIndex < maxSearch)
            {
                searchIndex++;
                Voxel.Box b = queue.Dequeue();
                lock (b.Adjacent)
                {
                    int parentGScore = visited[b];
                    for (int i = 0; i < b.Adjacent.Count; i++)
                    {
                        Voxel.Box adjacent        = b.Adjacent[i];
                        int       tentativeGScore = parentGScore + adjacent.Width * adjacent.Height * adjacent.Depth;
                        int       previousGScore;
                        if (!visited.TryGetValue(adjacent, out previousGScore) || tentativeGScore < previousGScore)
                        {
                            visited[adjacent] = tentativeGScore;

                            if (parentGScore < radius * radius &&
                                coord.X >= adjacent.X - radius && coord.X < adjacent.X + adjacent.Width + radius &&
                                coord.Y >= adjacent.Y - radius && coord.Y < adjacent.Y + adjacent.Height + radius &&
                                coord.Z >= adjacent.Z - radius && coord.Z < adjacent.Z + adjacent.Depth + radius)
                            {
                                if (filter(adjacent))
                                {
                                    return(adjacent);
                                }
                                else
                                {
                                    queue.Enqueue(adjacent);
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }
Exemplo n.º 11
0
        // =========================
        // Procedural generation of a voxel environment based on the above noise functions.
        // =========================

        // This is the density function that builds the environment.
        // We sample the noise function at different octaves and combine them together.
        // If its value sampled at a certain voxel cell is above a certain threshold,
        // we fill in that voxel cell.
        private float density(Voxel.Coord sample)
        {
            Vector3 sampleVector = new Vector3(sample.X, sample.Y, sample.Z);

            // First octave
            float value = this.noise3d(sampleVector / this.PrimaryOctave1);

            // Second octave
            value += this.noise3d(sampleVector / this.PrimaryOctave2) * 0.8f;

            // Third octave
            value += this.noise3d(sampleVector / this.PrimaryOctave3) * 0.4f;

            return(value);
        }
Exemplo n.º 12
0
 public override void Awake()
 {
     base.Awake();
     AkGameObjectTracker.Attach(this.Entity, this.Position);
     this.particles         = ParticleSystem.Get(this.main, "Rift");
     this.EnabledInEditMode = false;
     this.EnabledWhenPaused = false;
     this.Add(new CommandBinding(this.Enable, delegate()
     {
         if (this.Coords.Length == 0)
         {
             AkSoundEngine.PostEvent(AK.EVENTS.PLAY_RIFT_OPEN, this.Entity);
             if (PlayerFactory.Instance != null)
             {
                 PlayerFactory.Instance.Get <CameraController>().Shake.Execute(this.Position, 30.0f);
             }
             Entity voxelEntity = this.Voxel.Value.Target;
             if (voxelEntity != null && voxelEntity.Active)
             {
                 Voxel v            = voxelEntity.Get <Voxel>();
                 Voxel.Coord center = this.Coordinate;
                 Vector3 pos        = v.GetRelativePosition(center);
                 int radius         = this.Radius;
                 List <VoxelFill.CoordinateEntry> coords = Rift.coordSortCache;
                 for (Voxel.Coord x = center.Move(Direction.NegativeX, radius); x.X < center.X + radius; x.X++)
                 {
                     for (Voxel.Coord y = x.Move(Direction.NegativeY, radius); y.Y < center.Y + radius; y.Y++)
                     {
                         for (Voxel.Coord z = y.Move(Direction.NegativeZ, radius); z.Z < center.Z + radius; z.Z++)
                         {
                             float distance = (pos - v.GetRelativePosition(z)).Length();
                             if (distance <= radius && v[z] != Components.Voxel.States.Empty)
                             {
                                 coords.Add(new VoxelFill.CoordinateEntry {
                                     Coord = z.Clone(), Distance = distance
                                 });
                             }
                         }
                     }
                 }
                 coords.Sort(new LambdaComparer <VoxelFill.CoordinateEntry>((x, y) => x.Distance.CompareTo(y.Distance)));
                 this.Coords.AddAll(coords.Select(x => x.Coord));
                 coords.Clear();
             }
         }
     }));
     rifts.Add(this);
 }
Exemplo n.º 13
0
        public void Implode(Main main, Voxel v, Voxel.Coord coord, Voxel.State state, Vector3 target)
        {
            Entity       block        = this.CreateAndBind(main);
            ImplodeBlock implodeBlock = block.Get <ImplodeBlock>();

            state.ApplyToEffectBlock(block.Get <ModelInstance>());
            implodeBlock.Offset.Value = v.GetRelativePosition(coord);

            implodeBlock.StateId          = state.ID;
            implodeBlock.StartPosition    = v.GetAbsolutePosition(coord);
            implodeBlock.Type             = Rift.Style.In;
            implodeBlock.StartOrientation = Quaternion.CreateFromRotationMatrix(v.Transform);
            implodeBlock.EndOrientation   = Quaternion.CreateFromYawPitchRoll((float)this.random.NextDouble() * (float)Math.PI * 2.0f, (float)this.random.NextDouble() * (float)Math.PI * 2.0f, 0.0f);
            implodeBlock.EndPosition      = target;
            main.Add(block);
        }
Exemplo n.º 14
0
 private void go()
 {
     if (this.Coords.Length == 0)
     {
         AkSoundEngine.PostEvent(AK.EVENTS.PLAY_RIFT_OPEN, this.Entity);
         if (PlayerFactory.Instance != null)
         {
             PlayerFactory.Instance.Get <CameraController>().Shake.Execute(this.Position, 30.0f);
         }
         Entity voxelEntity = this.Voxel.Value.Target;
         if (voxelEntity != null && voxelEntity.Active)
         {
             Voxel       v      = voxelEntity.Get <Voxel>();
             Voxel.Coord center = this.Coordinate;
             Vector3     pos    = v.GetRelativePosition(center);
             int         radius = this.Radius;
             List <VoxelFill.CoordinateEntry> coords = Rift.coordSortCache;
             for (Voxel.Coord x = center.Move(Direction.NegativeX, radius); x.X < center.X + radius; x.X++)
             {
                 for (Voxel.Coord y = x.Move(Direction.NegativeY, radius); y.Y < center.Y + radius; y.Y++)
                 {
                     for (Voxel.Coord z = y.Move(Direction.NegativeZ, radius); z.Z < center.Z + radius; z.Z++)
                     {
                         float distance = (pos - v.GetRelativePosition(z)).Length();
                         if (distance <= radius && v[z] != Components.Voxel.States.Empty)
                         {
                             coords.Add(new VoxelFill.CoordinateEntry {
                                 Coord = z.Clone(), Distance = distance
                             });
                         }
                     }
                 }
             }
             if (coords.Count == 0)
             {
                 this.Entity.Delete.Execute();
             }
             else
             {
                 coords.Sort(new LambdaComparer <VoxelFill.CoordinateEntry>((x, y) => x.Distance.CompareTo(y.Distance)));
                 this.Coords.AddAll(coords.Select(x => x.Coord));
                 coords.Clear();
             }
         }
     }
 }
Exemplo n.º 15
0
 public void Update(float dt)
 {
     if (this.mover != null)
     {
         Entity parentEntity = this.Parent.Value.Target;
         if (parentEntity != null && parentEntity.Active)
         {
             Voxel       parentMap = parentEntity.Get <Voxel>();
             Voxel.Coord coord     = this.Coord;
             this.mover.TargetPosition = parentMap.GetAbsolutePosition(new Vector3(coord.X + 1.0f, coord.Y + 1.0f, coord.Z + 1.0f));
         }
         else
         {
             if (this.mover != null && this.mover.Space != null)
             {
                 this.main.Space.Remove(this.mover);
             }
             this.mover = null;
         }
     }
 }
Exemplo n.º 16
0
        private void updatePower()
        {
            Entity v       = this.AttachedVoxel.Value.Target;
            bool   powered = false;

            if (v != null)
            {
                Voxel       voxel = v.Get <Voxel>();
                Voxel.Coord coord = this.Coord;
                for (int i = 0; i < 6; i++)
                {
                    Direction dir = DirectionExtensions.Directions[i];
                    if (voxel[coord.Move(dir)].ID == this.Type)
                    {
                        powered = true;
                        break;
                    }
                }
            }
            this.Powered.Value = powered;
        }
Exemplo n.º 17
0
 private void checkShouldBuildFloor()
 {
     if (this.EnableEnhancedRollSlide)
     {
         Voxel.GlobalRaycastResult floorRaycast = this.raycastFloor();
         if (floorRaycast.Voxel != null && floorRaycast.Voxel.Entity.Type != "Bouncer")
         {
             Voxel.t t = floorRaycast.Voxel[floorRaycast.Coordinate.Value].ID;
             if (t != Voxel.t.Blue && t != Voxel.t.Powered && t != Voxel.t.Slider && t != Voxel.t.SliderPowered)
             {
                 this.floorCoordinate  = floorRaycast.Coordinate.Value;
                 this.shouldBuildFloor = true;
                 if (this.Kicking)
                 {
                     this.sliding = true;
                     AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_SLIDE_LOOP, this.Entity);
                 }
             }
         }
     }
 }
Exemplo n.º 18
0
        public void BuildFloor(Voxel floorMap, Voxel.Coord floorCoordinate, Direction forwardDir, Direction rightDir)
        {
            List <EffectBlockFactory.BlockBuildOrder> buildCoords = new List <EffectBlockFactory.BlockBuildOrder>();

            Voxel.Coord newFloorCoordinate = floorMap.GetCoordinate(this.Position);
            floorCoordinate.SetComponent(rightDir, newFloorCoordinate.GetComponent(rightDir));
            floorCoordinate.SetComponent(forwardDir, newFloorCoordinate.GetComponent(forwardDir));
            Direction upDir = floorMap.GetRelativeDirection(Direction.PositiveY);

            const int radius = 3;

            foreach (Voxel.Coord x in this.spreadFromCenter(floorCoordinate, rightDir))
            {
                if (floorMap[x.Move(upDir)].Hard)
                {
                    break;
                }
                int dx = x.GetComponent(rightDir) - floorCoordinate.GetComponent(rightDir);
                for (Voxel.Coord y = x.Move(forwardDir, -radius); y.GetComponent(forwardDir) < floorCoordinate.GetComponent(forwardDir) + radius; y = y.Move(forwardDir))
                {
                    if (floorMap[y.Move(upDir)].Hard)
                    {
                        break;
                    }
                    int dy = y.GetComponent(forwardDir) - floorCoordinate.GetComponent(forwardDir);
                    if ((float)Math.Sqrt(dx * dx + dy * dy) < radius && floorMap[y].ID == 0)
                    {
                        buildCoords.Add(new EffectBlockFactory.BlockBuildOrder
                        {
                            Voxel      = floorMap,
                            Coordinate = y,
                            State      = Voxel.States.Blue,
                        });
                    }
                }
            }
            Factory.Get <EffectBlockFactory>().Build(this.main, buildCoords, this.Position);
        }
Exemplo n.º 19
0
        // Classic 3D perlin noise
        float noise3d(Vector3 pos)
        {
            Voxel.Coord cell = new Voxel.Coord {
                X = (int)Math.Floor(pos.X) & 255, Y = (int)Math.Floor(pos.Y) & 255, Z = (int)Math.Floor(pos.Z) & 255
            };

            pos.X = pos.X % 256;
            pos.Y = pos.Y % 256;
            pos.Z = pos.Z % 256;
            Vector3 withinCell = pos - new Vector3(cell.X, cell.Y, cell.Z);

            // Calculate contribution of gradients from each cell
            float contribution000 = Vector3.Dot(this.gradientAtCell3d(cell), withinCell);
            float contribution001 = Vector3.Dot(this.gradientAtCell3d(cell.Move(0, 0, 1)), withinCell - new Vector3(0, 0, 1));
            float contribution010 = Vector3.Dot(this.gradientAtCell3d(cell.Move(0, 1, 0)), withinCell - new Vector3(0, 1, 0));
            float contribution011 = Vector3.Dot(this.gradientAtCell3d(cell.Move(0, 1, 1)), withinCell - new Vector3(0, 1, 1));
            float contribution100 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 0, 0)), withinCell - new Vector3(1, 0, 0));
            float contribution101 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 0, 1)), withinCell - new Vector3(1, 0, 1));
            float contribution110 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 1, 0)), withinCell - new Vector3(1, 1, 0));
            float contribution111 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 1, 1)), withinCell - new Vector3(1, 1, 1));

            Vector3 blend = new Vector3(blendCurve(withinCell.X), blendCurve(withinCell.Y), blendCurve(withinCell.Z));

            // Interpolate along X
            float contribution00 = lerp(contribution000, contribution100, blend.X);
            float contribution01 = lerp(contribution001, contribution101, blend.X);
            float contribution10 = lerp(contribution010, contribution110, blend.X);
            float contribution11 = lerp(contribution011, contribution111, blend.X);

            // Interpolate along Y
            float contribution0 = lerp(contribution00, contribution10, blend.Y);
            float contribution1 = lerp(contribution01, contribution11, blend.Y);

            // Interpolate along Z
            return(lerp(contribution0, contribution1, blend.Z));
        }
Exemplo n.º 20
0
		public static void Consolidate(Main main, DynamicVoxel voxel, float interval = 1.0f)
		{
			int maxDistance = 12;
			Voxel closestVoxel = null;
			Voxel.Coord closestCoord = new Voxel.Coord();
			foreach (Voxel m in Voxel.ActivePhysicsVoxels)
			{
				if (m == voxel)
					continue;

				Voxel.Coord relativeCoord = m.GetCoordinate(voxel.Transform.Value.Translation);
				Voxel.Coord? closestFilled = m.FindClosestFilledCell(relativeCoord, maxDistance);
				if (closestFilled != null)
				{
					maxDistance = Math.Min(Math.Abs(relativeCoord.X - closestFilled.Value.X), Math.Min(Math.Abs(relativeCoord.Y - closestFilled.Value.Y), Math.Abs(relativeCoord.Z - closestFilled.Value.Z)));
					closestVoxel = m;
					closestCoord = closestFilled.Value;
				}
			}

			if (closestVoxel != null)
				VoxelRip.Consolidate(main, voxel, closestVoxel, closestCoord, interval);
		}
Exemplo n.º 21
0
        public void Go(bool overrideCooldown = false)
        {
            if (this.Rolling || this.Kicking || (main.TotalTime - this.LastRollKickEnded < coolDown && !overrideCooldown))
            {
                return;
            }

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

            this.forward          = -rotationMatrix.Forward;
            this.right            = rotationMatrix.Right;
            this.shouldBuildFloor = false;

            bool instantiatedBlockPossibility = false;

            if (this.EnableCrouch && this.EnableRoll && !this.IsSwimming &&
                (!this.EnableKick || !this.IsSupported || (this.LinearVelocity.Value - this.SupportVelocity.Value).Length() < 4.0f))
            {
                // Try to roll
                Vector3 playerPos = this.FloorPosition + new Vector3(0, 0.5f, 0);

                Voxel.GlobalRaycastResult floorRaycast = this.raycastFloor();

                bool nearGround = this.LinearVelocity.Value.Y < this.SupportVelocity.Value.Y + 0.1f && floorRaycast.Voxel != null;

                this.floorCoordinate = new Voxel.Coord();
                this.floorMap        = null;

                if (nearGround)
                {
                    this.floorMap        = floorRaycast.Voxel;
                    this.floorCoordinate = floorRaycast.Coordinate.Value;
                }
                else
                {
                    // Check for block possibilities
                    foreach (BlockPredictor.Possibility block in this.Predictor.AllPossibilities)
                    {
                        bool first = true;
                        foreach (Voxel.Coord coord in block.Map.Rasterize(playerPos + Vector3.Up * 2.0f, playerPos + (Vector3.Down * (this.Height + 3.0f))))
                        {
                            if (coord.Between(block.StartCoord, block.EndCoord))
                            {
                                if (first)
                                {
                                    break;                                     // If the top coord is intersecting the possible block, we're too far down into the block. Need to be at the top.
                                }
                                this.Predictor.InstantiatePossibility(block);
                                instantiatedBlockPossibility = true;
                                this.floorMap         = block.Map;
                                this.floorCoordinate  = coord;
                                this.Position.Value  += new Vector3(0, this.floorMap.GetAbsolutePosition(coord).Y + 2 - this.FloorPosition.Value.Y, 0);
                                this.shouldBuildFloor = true;
                                nearGround            = true;
                                break;
                            }
                            first = false;
                        }
                        if (nearGround)
                        {
                            break;
                        }
                    }
                }

                if (nearGround)
                {
                    // We're rolling.
                    this.Rolling.Value = true;

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

                    this.DeactivateWallRun.Execute();

                    this.EnableWalking.Value = false;
                    this.LockRotation.Execute();

                    this.Footstep.Execute();                     // We just landed; play a footstep sound
                    AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_ROLL, this.Entity);

                    this.model.StartClip("Roll", 5, false, AnimatedModel.DefaultBlendTime);

                    Voxel.State floorState = floorRaycast.Voxel == null ? Voxel.States.Empty : floorRaycast.Coordinate.Value.Data;
                    if (this.EnableEnhancedRollSlide && (instantiatedBlockPossibility || (this.IsSupported && floorState != Voxel.States.Slider && floorState != Voxel.States.SliderPowered)))
                    {
                        this.shouldBuildFloor |= this.determineShouldBuildFloor(floorRaycast.Voxel, floorState);
                    }

                    // If the player is not yet supported, that means they're just about to land.
                    // So give them a little speed boost for having such good timing.
                    this.velocity             = this.SupportVelocity + this.forward * this.MaxSpeed * (this.IsSupported ? 0.75f : 1.25f);
                    this.LinearVelocity.Value = new Vector3(this.velocity.X, instantiatedBlockPossibility ? 0.0f : this.LinearVelocity.Value.Y, this.velocity.Z);

                    // Crouch
                    this.Crouched.Value      = true;
                    this.AllowUncrouch.Value = false;

                    this.rightDir   = this.floorMap.GetRelativeDirection(this.right);
                    this.forwardDir = this.floorMap.GetRelativeDirection(this.forward);

                    this.rollKickTime          = 0.0f;
                    this.firstTimeBreak        = true;
                    this.LastRollStarted.Value = this.main.TotalTime;
                }
            }

            if (!this.Rolling && this.EnableCrouch && this.EnableKick && this.CanKick && !this.Kicking && !this.IsSwimming && Vector3.Dot(this.LinearVelocity.Value - this.SupportVelocity, this.forward) > 0.05f)
            {
                // Kick
                this.Kicking.Value = true;
                this.CanKick.Value = false;

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

                this.DeactivateWallRun.Execute();

                this.EnableWalking.Value = false;
                this.LockRotation.Execute();

                this.Crouched.Value      = true;
                this.AllowUncrouch.Value = false;

                Vector3 playerPos = this.FloorPosition + new Vector3(0, 0.5f, 0);

                this.sliding = false;

                Voxel.GlobalRaycastResult floorRaycast = this.raycastFloor();
                this.floorMap = floorRaycast.Voxel;

                if (instantiatedBlockPossibility)
                {
                    this.sliding          = true;
                    this.shouldBuildFloor = true;
                }
                else if (this.floorMap == null)
                {
                    this.shouldBuildFloor = false;
                    this.sliding          = false;
                    this.floorCoordinate  = new Voxel.Coord();
                }
                else if (this.LinearVelocity.Value.Y - this.SupportVelocity.Value.Y < 1.0f)
                {
                    this.floorCoordinate = floorRaycast.Coordinate.Value;
                    if (this.EnableEnhancedRollSlide)
                    {
                        this.shouldBuildFloor |= this.determineShouldBuildFloor(floorRaycast.Voxel, floorRaycast.Coordinate.Value.Data);
                    }
                    this.sliding = true;
                }

                float forwardSpeed = Vector3.Dot(this.forward, this.LinearVelocity.Value - this.SupportVelocity);
                if (forwardSpeed < this.MaxSpeed * 1.1f)
                {
                    if (this.sliding)
                    {
                        this.velocity = this.LinearVelocity.Value + this.forward * (this.MaxSpeed - forwardSpeed);
                    }
                    else
                    {
                        this.velocity = this.LinearVelocity.Value + this.forward * Math.Max(4.0f, forwardSpeed * 0.4f) + new Vector3(0, this.JumpSpeed * 0.2f, 0);
                    }
                }
                else
                {
                    this.velocity = this.LinearVelocity;
                }

                if (this.sliding)
                {
                    this.velocity.Y = 0.0f;
                }

                this.LinearVelocity.Value = this.velocity;

                this.model.StartClip(this.sliding ? "Slide" : "Kick", 5, false, AnimatedModel.DefaultBlendTime);
                AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_SLIDE, this.Entity);
                if (this.sliding)                 // We're sliding on the floor
                {
                    AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_SLIDE_LOOP, this.Entity);
                }

                this.forwardDir = Direction.None;
                this.rightDir   = Direction.None;

                if (this.floorMap != null)
                {
                    this.forwardDir = this.floorMap.GetRelativeDirection(this.forward);
                    this.rightDir   = this.floorMap.GetRelativeDirection(this.right);
                }

                this.rollKickTime   = 0.0f;
                this.firstTimeBreak = true;
            }
        }
Exemplo n.º 22
0
        public override void Bind(Entity entity, Main main, bool creating = false)
        {
            Transform transform = entity.GetOrCreate <Transform>("Transform");

            this.SetMain(entity, main);

            VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main, true, false);

            attachable.Offset.Value  = 1;
            attachable.Enabled.Value = true;

            PowerBlockSocket socket = entity.GetOrCreate <PowerBlockSocket>("PowerBlockSocket");

            socket.Add(new Binding <Voxel.Coord>(socket.Coord, attachable.Coord));
            socket.Add(new Binding <Entity.Handle>(socket.AttachedVoxel, attachable.AttachedVoxel));

            const float maxLightAttenuation = 15.0f;
            PointLight  light = entity.Create <PointLight>();

            light.Attenuation.Value = maxLightAttenuation;
            light.Add(new Binding <Vector3>(light.Position, transform.Position));
            light.Add(new Binding <Vector3, Voxel.t>(light.Color, delegate(Voxel.t t)
            {
                switch (t)
                {
                case Voxel.t.GlowBlue:
                    return(new Vector3(0.8f, 0.9f, 1.2f));

                case Voxel.t.GlowYellow:
                    return(new Vector3(1.2f, 1.2f, 0.8f));

                default:
                    return(Vector3.One);
                }
            }, socket.Type));
            light.Add(new Binding <bool>(light.Enabled, socket.Powered));

            PointLight animationLight = entity.Create <PointLight>();

            animationLight.Add(new Binding <Vector3>(animationLight.Position, light.Position));
            animationLight.Add(new Binding <Vector3>(animationLight.Color, light.Color));
            animationLight.Enabled.Value = false;

            PlayerTrigger trigger = entity.GetOrCreate <PlayerTrigger>("PlayerTrigger");

            trigger.Radius.Value = 7;
            trigger.Add(new Binding <Vector3>(trigger.Position, transform.Position));
            const float minimumChangeTime = 1.5f;
            float       lastChange        = -minimumChangeTime;

            trigger.Add(new CommandBinding(trigger.PlayerEntered, delegate()
            {
                if (main.TotalTime - lastChange > minimumChangeTime)
                {
                    BlockCloud cloud = PlayerFactory.Instance.Get <BlockCloud>();

                    bool changed    = false;
                    Voxel sockVoxel = attachable.AttachedVoxel.Value.Target.Get <Voxel>();
                    if (!socket.Powered && cloud.Type.Value == socket.Type.Value)
                    {
                        // Plug in to the socket
                        List <Voxel.Coord> coords = new List <Voxel.Coord>();
                        Queue <Voxel.Coord> queue = new Queue <Voxel.Coord>();
                        queue.Enqueue(sockVoxel.GetCoordinate(transform.Position));
                        while (queue.Count > 0)
                        {
                            Voxel.Coord c = queue.Dequeue();
                            coords.Add(c);
                            if (coords.Count >= cloud.Blocks.Length)
                            {
                                break;
                            }

                            Voxel.CoordDictionaryCache[c] = true;
                            foreach (Direction adjacentDirection in DirectionExtensions.Directions)
                            {
                                Voxel.Coord adjacentCoord = c.Move(adjacentDirection);
                                if (!Voxel.CoordDictionaryCache.ContainsKey(adjacentCoord))
                                {
                                    Voxel.t adjacentID = sockVoxel[adjacentCoord].ID;
                                    if (adjacentID == Voxel.t.Empty)
                                    {
                                        queue.Enqueue(adjacentCoord);
                                    }
                                }
                            }
                        }
                        Voxel.CoordDictionaryCache.Clear();

                        EffectBlockFactory factory = Factory.Get <EffectBlockFactory>();
                        int i = 0;
                        foreach (Entity block in cloud.Blocks)
                        {
                            Entity effectBlockEntity = factory.CreateAndBind(main);
                            Voxel.States.All[cloud.Type].ApplyToEffectBlock(effectBlockEntity.Get <ModelInstance>());
                            EffectBlock effectBlock      = effectBlockEntity.Get <EffectBlock>();
                            effectBlock.DoScale          = false;
                            Transform blockTransform     = block.Get <Transform>();
                            effectBlock.StartPosition    = blockTransform.Position;
                            effectBlock.StartOrientation = blockTransform.Quaternion;
                            effectBlock.TotalLifetime    = (i + 1) * 0.04f;
                            effectBlock.Setup(sockVoxel.Entity, coords[i], cloud.Type);
                            main.Add(effectBlockEntity);
                            block.Delete.Execute();
                            i++;
                        }
                        cloud.Blocks.Clear();
                        cloud.Type.Value     = Voxel.t.Empty;
                        socket.Powered.Value = true;
                        changed = true;
                    }
                    else if (socket.Powered && cloud.Type.Value == Voxel.t.Empty && !socket.PowerOnOnly)
                    {
                        // Pull blocks out of the socket
                        SceneryBlockFactory factory = Factory.Get <SceneryBlockFactory>();
                        Quaternion quat             = Quaternion.CreateFromRotationMatrix(sockVoxel.Transform);
                        cloud.Type.Value            = socket.Type;
                        List <Voxel.Coord> coords   = sockVoxel.GetContiguousByType(new[] { sockVoxel.GetBox(transform.Position) }).SelectMany(x => x.GetCoords()).ToList();
                        sockVoxel.Empty(coords, true);
                        sockVoxel.Regenerate();
                        ParticleSystem particles = ParticleSystem.Get(main, "WhiteShatter");
                        foreach (Voxel.Coord c in coords)
                        {
                            Vector3 pos = sockVoxel.GetAbsolutePosition(c);
                            for (int j = 0; j < 20; j++)
                            {
                                Vector3 offset = new Vector3((float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f);
                                particles.AddParticle(pos + offset, offset);
                            }
                            Entity block                    = factory.CreateAndBind(main);
                            Transform blockTransform        = block.Get <Transform>();
                            blockTransform.Position.Value   = pos;
                            blockTransform.Quaternion.Value = quat;
                            SceneryBlock sceneryBlock       = block.Get <SceneryBlock>();
                            sceneryBlock.Type.Value         = socket.Type;
                            sceneryBlock.Scale.Value        = 0.5f;
                            cloud.Blocks.Add(block);
                            main.Add(block);
                        }
                        socket.Powered.Value = false;
                        changed = true;
                    }

                    if (changed)
                    {
                        lastChange = main.TotalTime;
                        animationLight.Enabled.Value     = true;
                        animationLight.Attenuation.Value = 0.0f;
                        entity.Add(new Animation
                                   (
                                       new Animation.FloatMoveTo(animationLight.Attenuation, maxLightAttenuation, 0.25f),
                                       new Animation.FloatMoveTo(animationLight.Attenuation, 0.0f, 2.0f),
                                       new Animation.Set <bool>(animationLight.Enabled, false)
                                   ));
                    }
                }
            }));

            entity.Add("Type", socket.Type);
            entity.Add("Powered", socket.Powered, new PropertyEntry.EditorData {
                Readonly = true
            });
            entity.Add("PowerOnOnly", socket.PowerOnOnly);
            entity.Add("OnPowerOn", socket.OnPowerOn);
            entity.Add("OnPowerOff", socket.OnPowerOff);
        }
Exemplo n.º 23
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);
        }
Exemplo n.º 24
0
		// Classic 3D perlin noise
		float noise3d(Vector3 pos)
		{
			Voxel.Coord cell = new Voxel.Coord { X = (int)Math.Floor(pos.X) & 255, Y = (int)Math.Floor(pos.Y) & 255, Z = (int)Math.Floor(pos.Z) & 255 };
			
			pos.X = pos.X % 256;
			pos.Y = pos.Y % 256;
			pos.Z = pos.Z % 256;
			Vector3 withinCell = pos - new Vector3(cell.X, cell.Y, cell.Z);
			
			// Calculate contribution of gradients from each cell
			float contribution000 = Vector3.Dot(this.gradientAtCell3d(cell), withinCell);
			float contribution001 = Vector3.Dot(this.gradientAtCell3d(cell.Move(0, 0, 1)), withinCell - new Vector3(0, 0, 1));
			float contribution010 = Vector3.Dot(this.gradientAtCell3d(cell.Move(0, 1, 0)), withinCell - new Vector3(0, 1, 0));
			float contribution011 = Vector3.Dot(this.gradientAtCell3d(cell.Move(0, 1, 1)), withinCell - new Vector3(0, 1, 1));
			float contribution100 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 0, 0)), withinCell - new Vector3(1, 0, 0));
			float contribution101 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 0, 1)), withinCell - new Vector3(1, 0, 1));
			float contribution110 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 1, 0)), withinCell - new Vector3(1, 1, 0));
			float contribution111 = Vector3.Dot(this.gradientAtCell3d(cell.Move(1, 1, 1)), withinCell - new Vector3(1, 1, 1));
			
			Vector3 blend = new Vector3(blendCurve(withinCell.X), blendCurve(withinCell.Y), blendCurve(withinCell.Z));
			
			// Interpolate along X
			float contribution00 = lerp(contribution000, contribution100, blend.X);
			float contribution01 = lerp(contribution001, contribution101, blend.X);
			float contribution10 = lerp(contribution010, contribution110, blend.X);
			float contribution11 = lerp(contribution011, contribution111, blend.X);
			
			// Interpolate along Y
			float contribution0 = lerp(contribution00, contribution10, blend.Y);
			float contribution1 = lerp(contribution01, contribution11, blend.Y);
			
			// Interpolate along Z
			return lerp(contribution0, contribution1, blend.Z);
		}
Exemplo n.º 25
0
        private void setup(Voxel voxel, Direction dir, State state, Vector3 forwardVector, bool addInitialVelocity, bool rotationAlreadyLocked = false)
        {
            this.StopKick.Execute();
            this.AllowUncrouch.Value = true;

            this.WallRunVoxel.Value  = this.LastWallRunMap.Value = voxel;
            this.WallDirection.Value = this.LastWallDirection.Value = dir;
            this.lastWallRunCoord    = new Voxel.Coord {
                X = int.MinValue, Y = int.MinValue, Z = int.MinValue
            };

            Vector3 baseVelocity = voxel.LinearVelocity + Vector3.Cross(voxel.AngularVelocity, this.Position - voxel.Transform.Value.Translation);

            if (state == State.Straight)
            {
                // Determine if we're actually going down
                if (!this.IsSupported && this.LinearVelocity.Value.Y - baseVelocity.Y < -0.5f)
                {
                    state = State.Down;
                }
            }

            this.CurrentState.Value = state;

            Session.Recorder.Event(main, "WallRun", this.CurrentState.Value.ToString());

            this.WallRunDirection.Value = state == State.Straight ? voxel.GetRelativeDirection(Vector3.Up) : (state == State.Down ? voxel.GetRelativeDirection(Vector3.Down) : dir.Cross(voxel.GetRelativeDirection(Vector3.Up)));

            if (state == State.Straight || state == State.Down)
            {
                if (state == State.Straight)
                {
                    Vector3 velocity = this.LinearVelocity.Value;
                    velocity.X = baseVelocity.X;
                    velocity.Z = baseVelocity.Z;
                    if (addInitialVelocity)
                    {
                        velocity.Y = Math.Max(this.JumpSpeed * 1.3f, (this.LinearVelocity.Value.Y * 1.4f) + this.JumpSpeed * 0.5f);
                    }
                    else
                    {
                        velocity.Y = this.LinearVelocity.Value.Y;
                    }

                    this.LinearVelocity.Value = velocity;
                    this.IsSupported.Value    = false;
                    this.HasTraction.Value    = false;
                }
                Vector3 wallVector = this.WallRunVoxel.Value.GetAbsoluteVector(this.WallDirection.Value.GetVector());

                // Make sure we lock in the correct rotation value
                float rotation = (float)Math.Atan2(wallVector.X, wallVector.Z);
                if (rotationAlreadyLocked)
                {
                    this.UpdateLockedRotation.Execute(rotation);
                }
                else
                {
                    this.Rotation.Value = rotation;
                    this.LockRotation.Execute();
                }
            }
            else
            {
                this.IsSupported.Value = false;
                this.HasTraction.Value = false;
                Vector3 velocity = voxel.GetAbsoluteVector(this.WallRunDirection.Value.GetVector());
                if (Vector3.Dot(velocity, forwardVector) < 0.0f)
                {
                    velocity = -velocity;
                    this.WallRunDirection.Value = this.WallRunDirection.Value.GetReverse();
                }

                float rotation = (float)Math.Atan2(velocity.X, velocity.Z);
                if (rotationAlreadyLocked)
                {
                    this.UpdateLockedRotation.Execute(rotation);
                }
                else
                {
                    this.Rotation.Value = rotation;
                    this.LockRotation.Execute();
                }

                if (addInitialVelocity)
                {
                    velocity.Y = 0;
                    float length = velocity.Length();
                    if (length > 0)
                    {
                        velocity /= length;

                        Vector3 currentHorizontalVelocity = this.LinearVelocity - baseVelocity;
                        float   currentVerticalSpeed      = currentHorizontalVelocity.Y;
                        currentHorizontalVelocity.Y = 0.0f;
                        float horizontalSpeed = currentHorizontalVelocity.Length();
                        velocity *= Math.Min(this.MaxSpeed * 1.4f, Math.Max(horizontalSpeed * 1.1f, 6.0f));

                        if (Vector3.Dot(velocity - baseVelocity, forwardVector) < minWallRunSpeed + 1.0f)
                        {
                            velocity += forwardVector * ((minWallRunSpeed + 2.0f) - Vector3.Dot(velocity - baseVelocity, forwardVector));
                        }

                        velocity += baseVelocity;

                        velocity.Y = (currentVerticalSpeed > -10.0f ? Math.Max(currentVerticalSpeed * 0.5f, 0.0f) + velocity.Length() * 0.6f : currentVerticalSpeed * 0.5f + 3.0f);

                        this.LinearVelocity.Value     = velocity;
                        this.LastSupportedSpeed.Value = Vector3.Dot(velocity, forwardVector);
                    }
                }
            }
            if (this.CurrentState != State.Straight)
            {
                AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_SLIDE_LOOP, this.Entity);
            }
        }
Exemplo n.º 26
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;
		}
Exemplo n.º 27
0
		public static void Consolidate(Main main, DynamicVoxel voxel, Voxel targetVoxel, Voxel.Coord targetCoord, float interval = 1.0f)
		{
			if (targetVoxel != null)
			{
				// Combine this map with the other one

				Direction x = targetVoxel.GetRelativeDirection(voxel.GetAbsoluteVector(Vector3.Right));
				Direction y = targetVoxel.GetRelativeDirection(voxel.GetAbsoluteVector(Vector3.Up));
				Direction z = targetVoxel.GetRelativeDirection(voxel.GetAbsoluteVector(Vector3.Backward));

				if (x.IsParallel(y))
					x = y.Cross(z);
				else if (y.IsParallel(z))
					y = x.Cross(z);

				Voxel.Coord offset = new Voxel.Coord();
				float closestCoordDistance = float.MaxValue;
				Vector3 closestCoordPosition = targetVoxel.GetAbsolutePosition(targetCoord);
				lock (voxel.MutationLock)
				{
					foreach (Voxel.Coord c in voxel.Chunks.SelectMany(c => c.Boxes).SelectMany(b => b.GetCoords()))
					{
						float distance = (voxel.GetAbsolutePosition(c) - closestCoordPosition).LengthSquared();
						if (distance < closestCoordDistance)
						{
							closestCoordDistance = distance;
							offset = c;
						}
					}
				}
				Vector3 toLevitatingMap = voxel.Transform.Value.Translation - targetVoxel.GetAbsolutePosition(targetCoord);
				offset = offset.Move(voxel.GetRelativeDirection(-toLevitatingMap));

				Quaternion orientation = Quaternion.CreateFromRotationMatrix(voxel.Transform.Value);

				EffectBlockFactory blockFactory = Factory.Get<EffectBlockFactory>();

				int index = 0;
				List<Voxel.Coord> coords;
				lock (voxel.MutationLock)
					coords = voxel.Chunks.SelectMany(c => c.Boxes).SelectMany(b => b.GetCoords()).ToList();
				Voxel.Coord camera = voxel.GetCoordinate(main.Camera.Position);
				foreach (Voxel.Coord c in coords.OrderBy(c2 => new Vector3(c2.X - camera.X, c2.Y - camera.Y, c2.Z - camera.Z).LengthSquared()))
				{
					Voxel.Coord offsetFromCenter = c.Move(-offset.X, -offset.Y, -offset.Z);
					Voxel.Coord targetCoord2 = new Voxel.Coord();
					targetCoord2.SetComponent(x, offsetFromCenter.GetComponent(Direction.PositiveX));
					targetCoord2.SetComponent(y, offsetFromCenter.GetComponent(Direction.PositiveY));
					targetCoord2.SetComponent(z, offsetFromCenter.GetComponent(Direction.PositiveZ));
					targetCoord2 = targetCoord2.Move(targetCoord.X, targetCoord.Y, targetCoord.Z);
					if (targetVoxel[targetCoord2].ID == 0)
					{
						Entity blockEntity = blockFactory.CreateAndBind(main);
						c.Data.ApplyToEffectBlock(blockEntity.Get<ModelInstance>());
						EffectBlock effectBlock = blockEntity.Get<EffectBlock>();
						effectBlock.Offset.Value = targetVoxel.GetRelativePosition(targetCoord2);
						effectBlock.DoScale = false;
						effectBlock.StartPosition = voxel.GetAbsolutePosition(c);
						effectBlock.StartOrientation = orientation;
						effectBlock.TotalLifetime = (0.05f + (index * 0.0075f)) * interval;
						effectBlock.Setup(targetVoxel.Entity, targetCoord2, c.Data.ID);
						main.Add(blockEntity);
						index++;
					}
				}

				// Delete the map
				voxel.Entity.Delete.Execute();
			}
		}
Exemplo n.º 28
0
        public void Update(float dt)
        {
            if (this.Coords.Length == 0)
            {
                this.go();
            }
            else if (this.CurrentIndex < this.Coords.Length)
            {
                if (this.voxel == null)
                {
                    Entity v = this.Voxel.Value.Target;
                    if (v != null && v.Active)
                    {
                        this.voxel = v.Get <Voxel>();
                    }
                }
                else if (this.voxel.Active)
                {
                    this.intervalTimer += dt;

                    if (this.Type == Style.In)
                    {
                        this.particleIntervalTimer += dt;
                        while (this.particleIntervalTimer > particleInterval)
                        {
                            this.particleIntervalTimer -= particleInterval;
                            this.particles.AddParticle(this.Position, Vector3.Zero, -1.0f, this.CurrentRadius * 2.0f);
                        }

                        this.soundIntervalTimer += dt;
                        while (this.soundIntervalTimer > soundInterval)
                        {
                            this.soundIntervalTimer -= soundInterval;
                            AkSoundEngine.PostEvent(AK.EVENTS.PLAY_RIFT, this.Entity);
                        }
                    }

                    bool regenerate = false;
                    if (this.intervalTimer > batchInterval)
                    {
                        for (int i = 0; i < batch && this.CurrentIndex < this.Coords.Length; i++)
                        {
                            Voxel.Coord c = this.Coords[this.CurrentIndex];
                            if ((c.Data = this.voxel[c]) != Components.Voxel.States.Empty)
                            {
                                regenerate = true;
                                this.removals.Add(c);
                            }
                            this.CurrentIndex.Value++;
                        }
                    }

                    if (regenerate)
                    {
                        this.intervalTimer -= batchInterval;
                        this.voxel.Empty(this.removals, true, true);
                        foreach (Voxel.Coord c in this.removals)
                        {
                            if (this.Type == Style.In)
                            {
                                this.blockFactory.Implode(main, this.voxel, c, c.Data, this.Position);
                            }
                            else
                            {
                                this.blockFactory.BlowAway(main, this.voxel, c, c.Data);
                            }
                        }
                        this.removals.Clear();
                        this.voxel.Regenerate();
                    }

                    this.CurrentRadius.Value = (this.voxel.GetRelativePosition(this.Coords[Math.Max(0, this.CurrentIndex - 1)]) - this.voxel.GetRelativePosition(this.Coordinate)).Length();
                }
                else
                {
                    this.Entity.Delete.Execute();
                }
            }
            else
            {
                this.Entity.Delete.Execute();
            }

            if (this.Type.Value == Style.In)
            {
                Entity player = PlayerFactory.Instance;
                if (player != null && (player.Get <Transform>().Position.Value - this.Position.Value).Length() < this.CurrentRadius)
                {
                    player.Get <Agent>().Damage.Execute(dt * damageTime);
                }
            }
        }
Exemplo n.º 29
0
        public static bool Broadphase(Voxel m, Voxel.Box start, Voxel.Coord target, Func <Voxel.State, bool> filter, Stack <Voxel.Box> result, int maxIterations = 50)
        {
            BroadphaseEntry closestEntry = null;
            bool            found        = false;

            lock (m.MutationLock)
            {
                Vector3         targetPos  = m.GetRelativePosition(target);
                BroadphaseEntry startEntry = new BroadphaseEntry
                {
                    Parent  = null,
                    Box     = start,
                    G       = 0,
                    F       = (targetPos - start.GetCenter()).Length(),
                    BoxSize = Math.Max(start.Width, Math.Max(start.Height, start.Depth)),
                };
                broadphaseQueue.Push(startEntry);
                broadphaseQueueLookup[start] = startEntry;

                float closestHeuristic = float.MaxValue;

                int iterations = 0;
                while (broadphaseQueue.Count > 0 && iterations < maxIterations)
                {
                    iterations++;

                    BroadphaseEntry entry = broadphaseQueue.Pop();

                    if (entry.Box.Contains(target))
                    {
                        closestEntry = entry;
                        found        = true;
                        break;
                    }

                    broadphaseQueueLookup.Remove(entry.Box);

                    broadphaseClosed[entry.Box] = entry.G;
                    lock (entry.Box.Adjacent)
                    {
                        for (int i = 0; i < entry.Box.Adjacent.Count; i++)
                        {
                            Voxel.Box adjacent = entry.Box.Adjacent[i];
                            if (adjacent == null || !filter(adjacent.Type))
                            {
                                continue;
                            }

                            int boxSize = (int)((adjacent.Width + adjacent.Height + adjacent.Depth) / 3.0f);

                            int tentativeGScore = entry.G + boxSize;

                            int  previousGScore;
                            bool hasPreviousGScore = broadphaseClosed.TryGetValue(adjacent, out previousGScore);

                            if (hasPreviousGScore && tentativeGScore > previousGScore)
                            {
                                continue;
                            }

                            BroadphaseEntry alreadyInQueue;
                            broadphaseQueueLookup.TryGetValue(adjacent, out alreadyInQueue);

                            if (alreadyInQueue == null || tentativeGScore < previousGScore)
                            {
                                BroadphaseEntry newEntry = alreadyInQueue != null ? alreadyInQueue : new BroadphaseEntry();

                                newEntry.Parent = entry;
                                newEntry.G      = tentativeGScore;
                                float heuristic = (targetPos - adjacent.GetCenter()).Length();
                                newEntry.F = tentativeGScore + heuristic;

                                if (heuristic < closestHeuristic)
                                {
                                    closestEntry     = newEntry;
                                    closestHeuristic = heuristic;
                                }

                                if (alreadyInQueue == null)
                                {
                                    newEntry.Box     = adjacent;
                                    newEntry.BoxSize = boxSize;
                                    broadphaseQueue.Push(newEntry);
                                    broadphaseQueueLookup[adjacent] = newEntry;
                                }
                            }
                        }
                    }
                }
            }
            broadphaseClosed.Clear();
            broadphaseQueue.Clear();
            broadphaseQueueLookup.Clear();
            if (closestEntry != null)
            {
                VoxelAStar.reconstructBroadphasePath(closestEntry, result);
            }
            return(found);
        }
Exemplo n.º 30
0
        public static void Narrowphase(Voxel m, Voxel.Coord start, Voxel.Box target, Stack <Voxel.Coord> result)
        {
            Voxel.Box        currentBox = m.GetBox(start);
            Vector3          targetPos  = target.GetCenter();
            NarrowphaseEntry startEntry = new NarrowphaseEntry
            {
                Parent = null,
                Coord  = start,
                G      = 0,
                F      = (targetPos - m.GetRelativePosition(start)).Length(),
            };

            narrowphaseQueue.Push(startEntry);
            narrowphaseQueueLookup[start] = startEntry;

            NarrowphaseEntry closestEntry     = null;
            float            closestHeuristic = float.MaxValue;

            int iterations = 0;

            while (narrowphaseQueue.Count > 0 && iterations < 80)
            {
                iterations++;

                NarrowphaseEntry entry = narrowphaseQueue.Pop();

                if (m.GetBox(entry.Coord) == target)
                {
                    closestEntry = entry;
                    break;
                }

                narrowphaseQueueLookup.Remove(entry.Coord);

                narrowphaseClosed[entry.Coord] = entry.G;
                for (int i = 0; i < 6; i++)
                {
                    Voxel.Coord adjacent = entry.Coord.Move(DirectionExtensions.Directions[i]);
                    if (!currentBox.Contains(adjacent) && !target.Contains(adjacent))
                    {
                        continue;
                    }

                    int tentativeGScore = entry.G + 1;

                    int  previousGScore;
                    bool hasPreviousGScore = narrowphaseClosed.TryGetValue(adjacent, out previousGScore);

                    if (hasPreviousGScore && tentativeGScore > previousGScore)
                    {
                        continue;
                    }

                    NarrowphaseEntry alreadyInQueue;
                    narrowphaseQueueLookup.TryGetValue(adjacent, out alreadyInQueue);

                    if (alreadyInQueue == null || tentativeGScore < previousGScore)
                    {
                        NarrowphaseEntry newEntry = alreadyInQueue != null ? alreadyInQueue : new NarrowphaseEntry();

                        newEntry.Parent = entry;
                        newEntry.G      = tentativeGScore;
                        float heuristic = (targetPos - m.GetRelativePosition(adjacent)).Length();
                        newEntry.F = tentativeGScore + heuristic;

                        if (heuristic < closestHeuristic)
                        {
                            closestEntry     = newEntry;
                            closestHeuristic = heuristic;
                        }

                        if (alreadyInQueue == null)
                        {
                            newEntry.Coord = adjacent;
                            narrowphaseQueue.Push(newEntry);
                            narrowphaseQueueLookup[adjacent] = newEntry;
                        }
                    }
                }
            }
            narrowphaseClosed.Clear();
            narrowphaseQueue.Clear();
            narrowphaseQueueLookup.Clear();
            if (closestEntry != null)
            {
                VoxelAStar.reconstructNarrowphasePath(closestEntry, result);
            }
        }
Exemplo n.º 31
0
        public static void Consolidate(Main main, DynamicVoxel voxel, Voxel targetVoxel, Voxel.Coord targetCoord, float interval = 1.0f)
        {
            if (targetVoxel != null)
            {
                // Combine this map with the other one

                Direction x = targetVoxel.GetRelativeDirection(voxel.GetAbsoluteVector(Vector3.Right));
                Direction y = targetVoxel.GetRelativeDirection(voxel.GetAbsoluteVector(Vector3.Up));
                Direction z = targetVoxel.GetRelativeDirection(voxel.GetAbsoluteVector(Vector3.Backward));

                if (x.IsParallel(y))
                {
                    x = y.Cross(z);
                }
                else if (y.IsParallel(z))
                {
                    y = x.Cross(z);
                }

                Voxel.Coord offset = new Voxel.Coord();
                float       closestCoordDistance = float.MaxValue;
                Vector3     closestCoordPosition = targetVoxel.GetAbsolutePosition(targetCoord);
                foreach (Voxel.Coord c in voxel.Chunks.SelectMany(c => c.Boxes).SelectMany(b => b.GetCoords()))
                {
                    float distance = (voxel.GetAbsolutePosition(c) - closestCoordPosition).LengthSquared();
                    if (distance < closestCoordDistance)
                    {
                        closestCoordDistance = distance;
                        offset = c;
                    }
                }
                Vector3 toLevitatingMap = voxel.Transform.Value.Translation - targetVoxel.GetAbsolutePosition(targetCoord);
                offset = offset.Move(voxel.GetRelativeDirection(-toLevitatingMap));

                Quaternion orientation = Quaternion.CreateFromRotationMatrix(voxel.Transform.Value);

                EffectBlockFactory blockFactory = Factory.Get <EffectBlockFactory>();

                int index = 0;
                List <Voxel.Coord> coords = voxel.Chunks.SelectMany(c => c.Boxes).SelectMany(b => b.GetCoords()).ToList();
                Voxel.Coord        camera = voxel.GetCoordinate(main.Camera.Position);
                foreach (Voxel.Coord c in coords.OrderBy(c2 => new Vector3(c2.X - camera.X, c2.Y - camera.Y, c2.Z - camera.Z).LengthSquared()))
                {
                    Voxel.Coord offsetFromCenter = c.Move(-offset.X, -offset.Y, -offset.Z);
                    Voxel.Coord targetCoord2     = new Voxel.Coord();
                    targetCoord2.SetComponent(x, offsetFromCenter.GetComponent(Direction.PositiveX));
                    targetCoord2.SetComponent(y, offsetFromCenter.GetComponent(Direction.PositiveY));
                    targetCoord2.SetComponent(z, offsetFromCenter.GetComponent(Direction.PositiveZ));
                    targetCoord2 = targetCoord2.Move(targetCoord.X, targetCoord.Y, targetCoord.Z);
                    if (targetVoxel[targetCoord2].ID == 0)
                    {
                        Entity blockEntity = blockFactory.CreateAndBind(main);
                        c.Data.ApplyToEffectBlock(blockEntity.Get <ModelInstance>());
                        EffectBlock effectBlock = blockEntity.Get <EffectBlock>();
                        effectBlock.Offset.Value     = targetVoxel.GetRelativePosition(targetCoord2);
                        effectBlock.DoScale          = false;
                        effectBlock.StartPosition    = voxel.GetAbsolutePosition(c);
                        effectBlock.StartOrientation = orientation;
                        effectBlock.TotalLifetime    = (0.05f + (index * 0.0075f)) * interval;
                        effectBlock.Setup(targetVoxel.Entity, targetCoord2, c.Data.ID);
                        main.Add(blockEntity);
                        index++;
                    }
                }

                // Delete the map
                voxel.Entity.Delete.Execute();
            }
        }
Exemplo n.º 32
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;
            }
        }
Exemplo n.º 33
0
 // Get a psuedo-random gradient for the given 3D cell
 private Vector3 gradientAtCell3d(Voxel.Coord coord)
 {
     return(gradients[this.permutations[coord.X + this.permutations[coord.Y + this.permutations[coord.Z]]] % gradients.Length]);
 }
Exemplo n.º 34
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);
        }