public override IEnumerable <Status> Run() { Vector3 oldPosition = Agent.Position; bool firstIter = true; Creature.Controller.Reset(); WanderTime.Reset(); TurnTime.Reset(); while (!WanderTime.HasTriggered) { Creature.OverrideCharacterMode = false; Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.CurrentCharacterMode = CharacterMode.Walking; WanderTime.Update(DwarfTime.LastTime); if (!Creature.IsOnGround) { yield return(Status.Success); yield break; } if (TurnTime.Update(DwarfTime.LastTime) || TurnTime.HasTriggered || firstIter) { int iters = 0; while (iters < 100) { iters++; Vector2 randTarget = MathFunctions.RandVector2Circle() * Radius; LocalTarget = new Vector3(randTarget.X, 0, randTarget.Y) + oldPosition; VoxelHandle voxel = new VoxelHandle(Agent.World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(LocalTarget)); bool foundLava = false; foreach (VoxelHandle neighbor in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate).Select(coord => new VoxelHandle(Agent.World.ChunkManager.ChunkData, coord))) { if (neighbor.IsValid && neighbor.Chunk != null) { if (neighbor.LiquidType == LiquidType.Lava) { foundLava = true; } } } if (!foundLava) { break; } } if (iters == 100) { yield return(Act.Status.Fail); yield break; } firstIter = false; TurnTime.Reset(TurnTime.TargetTimeSeconds + MathFunctions.Rand(-0.1f, 0.1f)); } float dist = (LocalTarget - Agent.Position).Length(); if (dist < 0.5f) { Creature.Physics.Velocity *= 0.0f; Creature.CurrentCharacterMode = CharacterMode.Idle; yield return(Status.Running); } else { Vector3 output = Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds, LocalTarget, Agent.Position); output.Y = 0.0f; Creature.Physics.ApplyForce(output * 0.5f, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds); Creature.CurrentCharacterMode = CharacterMode.Walking; } yield return(Status.Running); } Creature.CurrentCharacterMode = CharacterMode.Idle; yield return(Status.Success); }
public void GenerateCaves(VoxelChunk chunk, WorldManager world) { Vector3 origin = chunk.Origin; BiomeData biome = BiomeLibrary.GetBiome("Cave"); for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); for (int i = 0; i < CaveLevels.Count; i++) { int y = CaveLevels[i]; if (y <= 0 || y >= topVoxel.Coordinate.Y) { continue; } Vector3 vec = new Vector3(x, y, z) + chunk.Origin; double caveNoise = CaveNoise.GetValue((x + origin.X) * CaveNoiseScale * CaveFrequencies[i], (y + origin.Y) * CaveNoiseScale * 3.0f, (z + origin.Z) * CaveNoiseScale * CaveFrequencies[i]); double heightnoise = NoiseGenerator.Noise((x + origin.X) * NoiseScale * CaveFrequencies[i], (y + origin.Y) * NoiseScale * 3.0f, (z + origin.Z) * NoiseScale * CaveFrequencies[i]); int caveHeight = Math.Min(Math.Max((int)(heightnoise * 5), 1), 3); if (!(caveNoise > CaveSize)) { continue; } bool invalidCave = false; for (int dy = 0; dy < caveHeight; dy++) { if (y - dy <= 0) { continue; } var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - dy, z)); foreach (var coord in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate)) { VoxelHandle v = new VoxelHandle(Manager.ChunkData, coord); if (v.IsValid && (v.WaterCell.WaterLevel > 0 || v.SunColor > 0)) { invalidCave = true; break; } } if (!invalidCave) { voxel.RawSetType(VoxelLibrary.emptyType); } else { break; } } if (!invalidCave && caveNoise > CaveSize * 1.8f && y - caveHeight > 0) { GenerateCaveVegetation(chunk, x, y, z, caveHeight, biome, vec, world, NoiseGenerator); GenerateCaveFauna(chunk, world, biome, y - caveHeight, x, z); } } } } /* * // Second pass sets the caves to empty as needed * for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) * { * for (int y = 0; y < VoxelConstants.ChunkSizeY; y++) * { * for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) * { * VoxelHandle handle = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z)); * if (handle.Type == magicCube) * { * handle.RawSetType(VoxelLibrary.emptyType); * } * } * } * } */ }
public void WalkUpdate(DwarfTime time, ChunkManager chunks) { { var mouseState = Mouse.GetState(); if (!GameState.Game.GraphicsDevice.Viewport.Bounds.Contains(mouseState.X, mouseState.Y)) { return; } } // Don't attempt any camera control if the user is trying to type intoa focus item. if (World.UserInterface.Gui.FocusItem != null && !World.UserInterface.Gui.FocusItem.IsAnyParentTransparent() && !World.UserInterface.Gui.FocusItem.IsAnyParentHidden()) { return; } if (GameSettings.Default.FogofWar) { var currentCoordinate = GlobalVoxelCoordinate.FromVector3(Position); if (currentCoordinate != _prevVoxelCoord) { VoxelHelpers.RadiusReveal(chunks, new VoxelHandle(chunks, currentCoordinate), 10); _prevVoxelCoord = currentCoordinate; } } float diffPhi = 0; float diffTheta = 0; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); right.Normalize(); up.Normalize(); MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); var bounds = new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20); ZoomTargets.Clear(); Target = MathFunctions.Clamp(Target, bounds); float diffX, diffY = 0; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); bool switchState = false; bool isAnyRotationKeyActive = keys.IsKeyDown(ControlSettings.Mappings.CameraMode) || keys.IsKeyDown(Keys.RightShift) || Mouse.GetState().MiddleButton == ButtonState.Pressed; if (isAnyRotationKeyActive && !shiftPressed) { shiftPressed = true; mouseOnRotate = GameState.Game.GraphicsDevice.Viewport.Bounds.Center; mousePrerotate = new Point(mouse.X, mouse.Y); switchState = true; mouseActiveInWalk = !mouseActiveInWalk; } else if (!isAnyRotationKeyActive && shiftPressed) { shiftPressed = false; } if (shiftPressed) { Mouse.SetPosition(mousePrerotate.X, mousePrerotate.Y); KeyManager.TrueMousePos = new Point(mousePrerotate.X, mousePrerotate.Y); } else { KeyManager.TrueMousePos = new Point(mouse.X, mouse.Y); } if (KeyManager.RotationEnabled(this)) { World.UserInterface.Gui.MouseVisible = false; Mouse.SetPosition(mouseOnRotate.X, mouseOnRotate.Y); if (!switchState) { diffX = mouse.X - mouseOnRotate.X; diffY = mouse.Y - mouseOnRotate.Y; } else { diffX = 0; diffY = 0; } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } if (!isRightPressed) { float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); diffTheta = (filterDiffX); diffPhi = -(filterDiffY); } KeyManager.TrueMousePos = mousePrerotate; } else { World.UserInterface.Gui.MouseVisible = true; } Vector3 velocityToSet = Vector3.Zero; //if (EnableControl) { if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 mov = forward; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { Vector3 mov = forward; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 mov = right; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 mov = right; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed; } } if (keys.IsKeyDown(ControlSettings.Mappings.Fly)) { flyKeyPressed = true; } else { if (flyKeyPressed) { flying = !flying; } flyKeyPressed = false; } if (velocityToSet.LengthSquared() > 0) { if (!flying) { float y = Velocity.Y; Velocity = Velocity * 0.5f + 0.5f * velocityToSet; Velocity = new Vector3(Velocity.X, y, Velocity.Z); } else { Velocity = Velocity * 0.5f + 0.5f * velocityToSet; } } LastWheel = mouse.ScrollWheelValue; float ymult = flying ? 0.9f : 1.0f; Velocity = new Vector3(Velocity.X * 0.9f, Velocity.Y * ymult, Velocity.Z * 0.9f); float subSteps = 10.0f; float subStepLength = 1.0f / subSteps; crouched = false; for (int i = 0; i < subSteps; i++) { VoxelHandle currentVoxel = new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(Position)); var below = VoxelHelpers.GetNeighbor(currentVoxel, new GlobalVoxelOffset(0, -1, 0)); var above = VoxelHelpers.GetNeighbor(currentVoxel, new GlobalVoxelOffset(0, 1, 0)); if (above.IsValid && !above.IsEmpty) { crouched = true; } if (!flying) { if (!below.IsValid || below.IsEmpty) { Velocity += dt * Gravity * subStepLength; } else if (keys.IsKeyDown(ControlSettings.Mappings.Jump)) { Velocity += -dt * Gravity * subStepLength * 4; } if (currentVoxel.IsValid && currentVoxel.LiquidLevel > 0) { Velocity += -dt * Gravity * subStepLength * 0.999f; if (keys.IsKeyDown(ControlSettings.Mappings.Jump)) { Velocity += -dt * Gravity * subStepLength * 0.5f; } Velocity *= 0.99f; } } if (!CollidesWithChunks(World.ChunkManager, Position, true, true, 0.4f, 0.9f)) { MoveTarget(Velocity * dt * subStepLength); PushVelocity = Vector3.Zero; } else { MoveTarget(Velocity * dt * subStepLength); } } VoxelHandle voxelAfterMove = new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(Position)); if (voxelAfterMove.IsValid && !voxelAfterMove.IsEmpty) { float distCenter = (voxelAfterMove.GetBoundingBox().Center() - Position).Length(); if (distCenter < 0.5f) { float closest = float.MaxValue; VoxelHandle closestVoxel = VoxelHandle.InvalidHandle; foreach (var voxel in VoxelHelpers.EnumerateAllNeighbors(voxelAfterMove.Coordinate).Select(c => new VoxelHandle(World.ChunkManager, c)).Where(v => v.IsEmpty)) { float d = (voxel.GetBoundingBox().Center() - Position).Length(); if (d < closest) { closest = d; closestVoxel = voxel; } } if (closestVoxel.IsValid) { var newPosition = closestVoxel.GetBoundingBox().Center(); var diff = (newPosition - Position); MoveTarget(diff); } } } Target += right * diffTheta * 0.1f; var newTarget = up * diffPhi * 0.1f + Target; var newForward = (Target - Position); if (Math.Abs(Vector3.Dot(newForward, UpVector)) < 0.99f) { Target = newTarget; } var diffTarget = Target - Position; diffTarget.Normalize(); Target = Position + diffTarget * 1.0f; UpdateBasisVectors(); UpdateViewMatrix(); }
public override IEnumerable <Status> Run() { if (!Creature.Inventory.HasResource(Resource)) { yield return(Status.Fail); } foreach (var status in Creature.HitAndWait(1.0f, true, () => Location.Coordinate.ToVector3() + Vector3.One * 0.5f)) { if (status == Status.Running) { yield return(status); } } var grabbed = Creature.Inventory.RemoveAndCreate(Resource, Inventory.RestockType.Any).FirstOrDefault(); if (grabbed == null) { yield return(Status.Fail); yield break; } else { // If the creature intersects the box, find a voxel adjacent to it that is free, and jump there to avoid getting crushed. if (Creature.Physics.BoundingBox.Intersects(Location.GetBoundingBox())) { var neighbors = VoxelHelpers.EnumerateAllNeighbors(Location.Coordinate) .Select(c => new VoxelHandle(Agent.Chunks.ChunkData, c)); var closest = VoxelHandle.InvalidHandle; float closestDist = float.MaxValue; foreach (var voxel in neighbors) { if (!voxel.IsValid) { continue; } float dist = (voxel.WorldPosition - Creature.Physics.Position).LengthSquared(); if (dist < closestDist && voxel.IsEmpty) { closestDist = dist; closest = voxel; } } if (closest.IsValid) { TossMotion teleport = new TossMotion(0.5f, 1.0f, Creature.Physics.GlobalTransform, closest.WorldPosition + Vector3.One * 0.5f); Creature.Physics.AnimationQueue.Add(teleport); } } TossMotion motion = new TossMotion(1.0f, 2.0f, grabbed.LocalTransform, Location.Coordinate.ToVector3() + new Vector3(0.5f, 0.5f, 0.5f)); grabbed.UpdateRate = 1; grabbed.GetRoot().GetComponent <Physics>().CollideMode = Physics.CollisionMode.None; grabbed.AnimationQueue.Add(motion); var putType = VoxelLibrary.GetVoxelType(VoxelType); motion.OnComplete += () => { grabbed.Die(); PlaceVoxel(Location, putType, Creature.Manager.World); Creature.Stats.NumBlocksPlaced++; Creature.AI.AddXP(1); }; yield return(Status.Success); yield break; } }