public CraftItemAct(CreatureAI creature, Voxel voxel, string type) : base(creature) { ItemType = type; Voxel = voxel; Name = "Build craft item"; }
public BuildVoxelTask(Voxel voxel, VoxelType type) { Name = "Put voxel of type: " + type.Name + " on voxel " + voxel.Position; Voxel = voxel; VoxType = type; Priority = PriorityType.Low; }
public CraftItemTask(Voxel voxel, string type) { Name = "Craft item " + voxel.GridPosition + " " + voxel.ChunkID.X + " " + voxel.ChunkID.Y + " " + voxel.ChunkID.Z; Voxel = voxel; CraftType = type; Priority = PriorityType.Low; }
public Flag(Vector3 position) : base("Flag", PlayState.ComponentManager.RootComponent, Matrix.CreateTranslation(position), new Vector3(1.0f, 1.0f, 1.0f), Vector3.Zero) { SpriteSheet spriteSheet = new SpriteSheet(ContentPaths.Entities.Furniture.interior_furniture); List<Point> frames = new List<Point> { new Point(0, 2), new Point(1, 2), new Point(2, 2) }; Animation lampAnimation = new Animation(GameState.Game.GraphicsDevice, new SpriteSheet(ContentPaths.Entities.Furniture.interior_furniture), "Flag", 32, 32, frames, true, Color.White, 5.0f + MathFunctions.Rand(), 1f, 1.0f, false); Sprite sprite = new Sprite(PlayState.ComponentManager, "sprite", this, Matrix.Identity, spriteSheet, false) { OrientationType = Sprite.OrientMode.YAxis }; sprite.AddAnimation(lampAnimation); Voxel voxelUnder = new Voxel(); if (PlayState.ChunkManager.ChunkData.GetFirstVoxelUnder(position, ref voxelUnder)) { VoxelListener listener = new VoxelListener(PlayState.ComponentManager, this, PlayState.ChunkManager, voxelUnder); } lampAnimation.Play(); Tags.Add("Flag"); CollisionType = CollisionManager.CollisionType.Static; }
public PlaceVoxelAct(Voxel voxel, CreatureAI agent, ResourceAmount resource) : base(agent) { Agent = agent; Voxel = voxel; Name = "Build Voxel " + voxel.ToString(); Resource = resource; }
public CreateCraftItemAct(Voxel voxel, CreatureAI agent, string itemType) : base(agent) { Agent = agent; Voxel = voxel; Name = "Create craft item"; ItemType = itemType; }
public VoxelListener(ComponentManager manager, GameComponent parent, ChunkManager chunkManager, Voxel vref) : base("VoxelListener", parent) { Chunk = vref.Chunk; VoxelID = new Point3(vref.GridPosition); Chunk.OnVoxelDestroyed += VoxelListener_OnVoxelDestroyed; ChunkID = Chunk.ID; }
public Tinter(string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos, bool collisionManager) : base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos, collisionManager) { LightsWithVoxels = true; Tint = new Color(255, 255, 0); LightingTimer = new Timer(0.2f, true); StartTimer = new Timer(0.5f, true); TargetTint = Tint; TintChangeRate = 1.0f; LightsWithVoxels = true; VoxelUnder = new Voxel(); }
public static float GetDistance(Voxel a, Voxel b, Creature.MoveType action, ChunkManager chunks) { if(!b.IsEmpty) { return 100000; } else { float score = (a.Position - b.Position).LengthSquared() * ActionCost(action); return score; } }
public GoToVoxelAct(Voxel voxel, PlanAct.PlanType planType, CreatureAI creature, float radius = 0.0f) : base(creature) { Voxel = voxel; Name = "Go to Voxel"; if(Voxel != null) { Tree = new Sequence( new SetBlackboardData<Voxel>(Agent, "TargetVoxel", Voxel), new PlanAct(Agent, "PathToVoxel", "TargetVoxel", planType) { Radius = radius}, new FollowPathAnimationAct(Agent, "PathToVoxel"), new StopAct(Agent)); } }
public GuardVoxelAct(CreatureAI agent, Voxel voxel) : base(agent) { Voxel = voxel; Name = "Guard Voxel " + voxel; Tree = new Sequence ( new GoToVoxelAct(voxel, PlanAct.PlanType.Adjacent, agent), new StopAct(Agent), new WhileLoop(new WanderAct(Agent, 1.0f, 0.5f, 0.1f), new Condition(LoopCondition)), new Condition(ExitCondition) ); }
public static List<Creature.MoveAction> FindPath(CreatureMovement mover, Voxel start, GoalRegion goal, ChunkManager chunks, int maxExpansions) { List<Creature.MoveAction> p = new List<Creature.MoveAction>(); bool success = Path(mover, start, goal, chunks, maxExpansions, ref p, false); if(success) { return p; } else { return null; } }
public Tree(Vector3 position, string asset, float treeSize) : base("Tree", PlayState.ComponentManager.RootComponent, Matrix.Identity, new Vector3(treeSize * 2, treeSize * 3, treeSize * 2), new Vector3(treeSize * 0.5f, treeSize * 0.25f, treeSize * 0.5f)) { HurtTimer = new Timer(1.0f, false); ComponentManager componentManager = PlayState.ComponentManager; Matrix matrix = Matrix.Identity; matrix.Translation = position; LocalTransform = matrix; new Mesh(componentManager, "Model", this, Matrix.CreateRotationY((float)(PlayState.Random.NextDouble() * Math.PI)) * Matrix.CreateScale(treeSize, treeSize, treeSize) * Matrix.CreateTranslation(new Vector3(0.7f, 0.0f, 0.7f)), asset, false); Health health = new Health(componentManager, "HP", this, 100.0f * treeSize, 0.0f, 100.0f * treeSize); new Flammable(componentManager, "Flames", this, health); Tags.Add("Vegetation"); Tags.Add("EmitsWood"); new MinimapIcon(this, new ImageFrame(TextureManager.GetTexture(ContentPaths.GUI.map_icons), 16, 1, 0)); Voxel voxelUnder = new Voxel(); if (PlayState.ChunkManager.ChunkData.GetFirstVoxelUnder(position, ref voxelUnder)) { new VoxelListener(componentManager, this, PlayState.ChunkManager, voxelUnder); } Inventory inventory = new Inventory("Inventory", this) { Resources = new ResourceContainer { MaxResources = (int)(treeSize * 10) } }; inventory.Resources.AddResource(new ResourceAmount() { NumResources = (int)(treeSize * 10), ResourceType = ResourceLibrary.Resources[ResourceLibrary.ResourceType.Wood] }); Particles = new ParticleTrigger("Leaves", componentManager, "LeafEmitter", this, Matrix.Identity, new Vector3(treeSize * 2, treeSize * 3, treeSize * 2), new Vector3(treeSize * 0.5f, treeSize * 0.25f, treeSize * 0.5f)) { SoundToPlay = ContentPaths.Audio.vegetation_break }; AddToCollisionManager = true; CollisionType = CollisionManager.CollisionType.Static; }
public Bed(Vector3 position) : base("Bed", PlayState.ComponentManager.RootComponent, Matrix.CreateTranslation(position), new Vector3(1.5f, 0.5f, 0.75f), new Vector3(-0.5f + 1.5f * 0.5f, -0.5f + 0.25f, -0.5f + 0.75f * 0.5f)) { Texture2D spriteSheet = TextureManager.GetTexture(ContentPaths.Entities.Furniture.bedtex); bedModel = new Box(PlayState.ComponentManager, "bedbox", this, Matrix.CreateTranslation(-0.5f, -0.5f, -0.5f) * Matrix.CreateRotationY((float)Math.PI * 0.5f), new Vector3(1.0f, 1.0f, 2.0f), new Vector3(0.5f, 0.5f, 1.0f), PrimitiveLibrary.BoxPrimitives["bed"], spriteSheet); Voxel voxelUnder = new Voxel(); if (PlayState.ChunkManager.ChunkData.GetFirstVoxelUnder(position, ref voxelUnder)) { VoxelListener listener = new VoxelListener(PlayState.ComponentManager, this, PlayState.ChunkManager, voxelUnder); } Tags.Add("Bed"); CollisionType = CollisionManager.CollisionType.Static; }
public KillVoxelAct(Voxel voxel, CreatureAI creature) : base(creature) { Voxel = voxel; Name = "Kill Voxel " + voxel.Position; Tree = new Sequence( new SetBlackboardData<Voxel>(creature, "DigVoxel", voxel), new Sequence( new Wrap(() => IncrementAssignment(creature, "DigVoxel", 1)), new GoToVoxelAct(voxel, PlanAct.PlanType.Adjacent, creature), new Wrap(() => CheckIsDigDesignation(creature, "DigVoxel")), new DigAct(Agent, "DigVoxel"), new ClearBlackboardData(creature, "DigVoxel") ) | new Wrap(() => IncrementAssignment(creature, "DigVoxel", -1)) & false); }
public override IEnumerable<Status> Run() { Body target = Creature.AI.Blackboard.GetData<Body>(EntityName); if (target == null) { yield return Status.Fail; } else { Voxel voxel = new Voxel(); if(!Creature.Chunks.ChunkData.GetFirstVoxelUnder(target.BoundingBox.Center(), ref voxel, true)) { yield return Status.Fail; } else { Agent.Blackboard.SetData(VoxelOutName, voxel); yield return Status.Success; } } }
public Forge(Vector3 position) : base("Forge", PlayState.ComponentManager.RootComponent, Matrix.CreateTranslation(position), new Vector3(1.0f, 1.0f, 1.0f), Vector3.Zero) { SpriteSheet spriteSheet = new SpriteSheet(ContentPaths.Entities.Furniture.interior_furniture); List<Point> frames = new List<Point> { new Point(1, 3), new Point(3, 3), new Point(2, 3), new Point(3, 3) }; Animation lampAnimation = new Animation(GameState.Game.GraphicsDevice, new SpriteSheet(ContentPaths.Entities.Furniture.interior_furniture), "Forge", 32, 32, frames, true, Color.White, 3.0f, 1f, 1.0f, false); Sprite sprite = new Sprite(PlayState.ComponentManager, "sprite", this, Matrix.Identity, spriteSheet, false) { LightsWithVoxels = false }; sprite.AddAnimation(lampAnimation); lampAnimation.Play(); Tags.Add("Forge"); Voxel voxelUnder = new Voxel(); if (PlayState.ChunkManager.ChunkData.GetFirstVoxelUnder(position, ref voxelUnder)) { new VoxelListener(PlayState.ComponentManager, this, PlayState.ChunkManager, voxelUnder); } new LightEmitter("light", this, Matrix.Identity, new Vector3(0.1f, 0.1f, 0.1f), Vector3.Zero, 50, 4) { HasMoved = true }; CollisionType = CollisionManager.CollisionType.Static; }
public static void UpdateCornerRamps(VoxelChunk chunk) { Voxel v = chunk.MakeVoxel(0, 0, 0); Voxel vAbove = chunk.MakeVoxel(0, 0, 0); List <Voxel> diagNeighbors = chunk.AllocateVoxels(3); List <VoxelVertex> top = new List <VoxelVertex>() { VoxelVertex.FrontTopLeft, VoxelVertex.FrontTopRight, VoxelVertex.BackTopLeft, VoxelVertex.BackTopRight }; for (int x = 0; x < chunk.SizeX; x++) { for (int y = 0; y < chunk.SizeY; y++) { for (int z = 0; z < chunk.SizeZ; z++) { v.GridPosition = new Vector3(x, y, z); bool isTop = false; if (y < chunk.SizeY - 1) { vAbove.GridPosition = new Vector3(x, y + 1, z); isTop = vAbove.IsEmpty; } if (v.IsEmpty || !v.IsVisible || !isTop || !v.Type.CanRamp) { v.RampType = RampType.None; continue; } v.RampType = RampType.None; foreach (VoxelVertex bestKey in top) { List <Vector3> neighbors = VertexNeighbors2D[(int)bestKey]; chunk.GetNeighborsSuccessors(neighbors, (int)v.GridPosition.X, (int)v.GridPosition.Y, (int)v.GridPosition.Z, diagNeighbors); bool emptyFound = diagNeighbors.Any(vox => vox.IsEmpty); if (!emptyFound) { continue; } switch (bestKey) { case VoxelVertex.FrontTopLeft: v.RampType |= RampType.TopBackLeft; break; case VoxelVertex.FrontTopRight: v.RampType |= RampType.TopBackRight; break; case VoxelVertex.BackTopLeft: v.RampType |= RampType.TopFrontLeft; break; case VoxelVertex.BackTopRight: v.RampType |= RampType.TopFrontRight; break; } } } } } }
public void GetNeighborsManhattan(Voxel v, List<Voxel> toReturn) { GetNeighborsManhattan((int) v.GridPosition.X, (int) v.GridPosition.Y, (int) v.GridPosition.Z, toReturn); }
public BearTrap(Vector3 pos) : base("BearTrap", PlayState.ComponentManager.RootComponent, Matrix.CreateTranslation(pos), new Vector3(1.0f, 1.0f, 1.0f), Vector3.Zero, true) { Allies = PlayState.PlayerFaction; Sensor = new Sensor("Sensor", this, Matrix.Identity, new Vector3(0.5f, 0.5f, 0.5f), Vector3.Zero) { FireTimer = new Timer(0.5f, false) }; Sensor.OnSensed += Sensor_OnSensed; DeathTimer = new Timer(0.6f, true); DeathParticles = new ParticleTrigger("puff", PlayState.ComponentManager, "DeathParticles", this, Matrix.Identity, new Vector3(0.5f, 0.5f, 0.5f), Vector3.Zero) { SoundToPlay = "" }; DamageAmount = 200; Voxel voxUnder = new Voxel(); PlayState.ChunkManager.ChunkData.GetFirstVoxelUnder(pos, ref voxUnder); VoxListener = new VoxelListener(PlayState.ComponentManager, this, PlayState.ChunkManager, voxUnder); Sprite = new Sprite(PlayState.ComponentManager, "Sprite", this, Matrix.Identity, new SpriteSheet(ContentPaths.Entities.DwarfObjects.beartrap), false); Sprite.AddAnimation(new Animation(0, ContentPaths.Entities.DwarfObjects.beartrap, 32, 32, 0) {Name = IdleAnimation}); Sprite.AddAnimation(new Animation(1, ContentPaths.Entities.DwarfObjects.beartrap, 32, 32, 0, 1, 2, 3) {Name = TriggerAnimation, Speeds = new List<float>() {6.6f}, Loops = true}); }
public void HandleTransfers(DwarfTime time) { Voxel atPos = new Voxel(); while(Transfers.Count > 0) { Transfer transfer; if(!Transfers.TryDequeue(out transfer)) { break; } if(transfer.cellFrom.Type == LiquidType.Lava && transfer.cellTo.Type == LiquidType.Water || (transfer.cellFrom.Type == LiquidType.Water && transfer.cellTo.Type == LiquidType.Lava)) { bool success = Chunks.ChunkData.GetVoxel(transfer.worldLocation, ref atPos); if(success) { Voxel v = atPos; VoxelLibrary.PlaceType(VoxelLibrary.GetVoxelType("Stone"), v); VoxelChunk chunk = Chunks.ChunkData.ChunkMap[v.ChunkID]; chunk.Data.Water[v.Index].Type = LiquidType.None; chunk.Data.Water[v.Index].WaterLevel = 0; chunk.ShouldRebuild = true; chunk.ShouldRecalculateLighting = true; } } } }
public Room GetMostLikelyRoom(Voxel v) { Voxel vRef = v; foreach(Room r in DesignatedRooms.Where(r => r.ContainsVoxel(vRef))) { return r; } BoundingBox larger = new BoundingBox(v.GetBoundingBox().Min - new Vector3(0.5f, 0.5f, 0.5f), v.GetBoundingBox().Max + new Vector3(0.5f, 0.5f, 0.5f)); return (from room in BuildDesignations from buildDesignation in room.VoxelOrders where larger.Intersects(buildDesignation.Voxel.GetBoundingBox()) select buildDesignation.ToBuild).FirstOrDefault(); }
public bool IsInRoom(Voxel v) { Voxel vRef = v; return DesignatedRooms.Any(r => r.ContainsVoxel(vRef)) || Faction.IsInStockpile(v); }
public bool IsInRoom(Voxel v) { Voxel vRef = v; return(DesignatedRooms.Any(r => r.ContainsVoxel(vRef)) || Faction.IsInStockpile(v)); }
public BuildVoxelOrder GetBuildDesignation(Voxel v) { return BuildDesignations.SelectMany(room => room.VoxelOrders).FirstOrDefault(buildDesignation => (buildDesignation.Voxel.Position - v.Position).LengthSquared() < 0.1f); }
public void Reveal(IEnumerable <Voxel> voxels) { if (!GameSettings.Default.FogofWar) { return; } List <Point3> affectedChunks = new List <Point3>(); Queue <Voxel> q = new Queue <Voxel>(128); foreach (Voxel voxel in voxels) { if (voxel != null) { q.Enqueue(voxel); } } List <Voxel> neighbors = new List <Voxel>(); while (q.Count > 0) { Voxel v = q.Dequeue(); if (v == null) { continue; } if (!affectedChunks.Contains(v.ChunkID)) { affectedChunks.Add(v.ChunkID); } v.Chunk.GetNeighborsManhattan(v, neighbors); foreach (Voxel nextVoxel in neighbors) { if (nextVoxel == null) { continue; } if (nextVoxel.IsExplored) { continue; } nextVoxel.Chunk.NotifyExplored(new Point3(nextVoxel.GridPosition)); if (!nextVoxel.IsEmpty) { if (!nextVoxel.IsExplored) { nextVoxel.IsExplored = true; if (!affectedChunks.Contains(nextVoxel.ChunkID)) { affectedChunks.Add(nextVoxel.ChunkID); } } continue; } if (!v.IsExplored) { q.Enqueue(new Voxel(new Point3(nextVoxel.GridPosition), nextVoxel.Chunk)); } } v.IsExplored = true; } foreach (Point3 chunkID in affectedChunks) { VoxelChunk chunk = ChunkMap[chunkID]; if (!chunk.ShouldRebuild) { chunk.ShouldRecalculateLighting = true; chunk.ShouldRebuildWater = true; chunk.ShouldRebuild = true; } } }
public bool IsBuildDesignation(Voxel v) { return(BuildDesignations.SelectMany(room => room.VoxelOrders).Any(buildDesignation => buildDesignation.Voxel.Equals(v))); }
public bool HasTile(Voxel vox) { return(FarmTiles.Any(f => f.Vox.Equals(vox))); }
public bool HasPlant(Voxel vox) { return(HasTile(vox) && FarmTiles.Any(f => f.Vox.Equals(vox) && f.PlantExists())); }
public static bool RampIsDegenerate(RampType rampType) { return(rampType == RampType.All || (Voxel.HasFlag(rampType, RampType.Left) && Voxel.HasFlag(rampType, RampType.Right)) || (Voxel.HasFlag(rampType, RampType.Front) && Voxel.HasFlag(rampType, RampType.Back))); }
public bool GetVoxel(Vector3 worldLocation, ref Voxel voxel) { return(GetVoxel(null, worldLocation, ref voxel)); }
public BuildVoxelOrder GetBuildDesignation(Voxel v) { return(BuildDesignations.SelectMany(room => room.VoxelOrders).FirstOrDefault(buildDesignation => (buildDesignation.Voxel.Position - v.Position).LengthSquared() < 0.1f)); }
public Voxel GetFirstVisibleBlockHitByMouse(MouseState mouse, Camera camera, Viewport viewPort, bool selectEmpty = false) { Voxel vox = GetFirstVisibleBlockHitByScreenCoord(mouse.X, mouse.Y, camera, viewPort, 150.0f, false, selectEmpty); return(vox); }
/// <summary> /// TODO: Get rid of the recursion /// Recursive function which gets all the voxels at a position in the world, assuming the voxel is in a given chunk /// </summary> /// <param Name="checkFirst">The voxel chunk to check first</param> /// <param Name="worldLocation">The point in the world to check</param> /// <param Name="toReturn">A list of voxels to get</param> /// <param Name="depth">The depth of the recursion</param> public bool GetNonNullVoxelAtWorldLocationCheckFirst(VoxelChunk checkFirst, Vector3 worldLocation, ref Voxel toReturn) { if (checkFirst != null) { if (!checkFirst.IsWorldLocationValid(worldLocation)) { return(GetNonNullVoxelAtWorldLocation(worldLocation, ref toReturn)); } bool success = checkFirst.GetVoxelAtWorldLocation(worldLocation, ref toReturn); if (success && !toReturn.IsEmpty) { return(true); } return(GetNonNullVoxelAtWorldLocation(worldLocation, ref toReturn)); } VoxelChunk chunk = GetVoxelChunkAtWorldLocation(worldLocation); if (chunk == null) { return(false); } if (!chunk.IsWorldLocationValid(worldLocation)) { return(false); } if (chunk.GetVoxelAtWorldLocation(worldLocation, ref toReturn) && !toReturn.IsEmpty) { return(true); } else { return(false); } }
public BuildRoomOrder GetMostLikelyDesignation(Voxel v) { BoundingBox larger = new BoundingBox(v.GetBoundingBox().Min - new Vector3(0.5f, 0.5f, 0.5f), v.GetBoundingBox().Max + new Vector3(0.5f, 0.5f, 0.5f)); return (from room in BuildDesignations from buildDesignation in room.VoxelOrders where larger.Intersects(buildDesignation.Voxel.GetBoundingBox()) select room).FirstOrDefault(); }
/// <summary> /// Given a world location, returns the voxel at that location if it exists /// Otherwise returns null. /// </summary> /// <param Name="worldLocation">A floating point vector location in the world space</param> /// <param Name="depth">unused</param> /// <returns>The voxel at that location (as a list)</returns> public bool GetNonNullVoxelAtWorldLocation(Vector3 worldLocation, ref Voxel voxel) { return(GetNonNullVoxelAtWorldLocationCheckFirst(null, worldLocation, ref voxel)); }
public bool IsBuildDesignation(Voxel v) { return BuildDesignations.SelectMany(room => room.VoxelOrders).Any(buildDesignation => buildDesignation.Voxel.Equals(v)); }
public byte GetIntensity(DynamicLight light, byte lightIntensity, Voxel voxel) { Vector3 vertexPos = voxel.Position; Vector3 diff = vertexPos - (light.Position + new Vector3(0.5f, 0.5f, 0.5f)); float dist = diff.LengthSquared() * 2; return (byte) (int) ((Math.Min(1.0f / (dist + 0.0001f), 1.0f)) * (float) light.Intensity); }
public void OnVoxelDestroyed(Voxel voxDestroyed) { List<Room> toDestroy = new List<Room>(); Voxel vRef = voxDestroyed; lock (DesignatedRooms) { List<Room> toCheck = new List<Room>(); toCheck.AddRange(DesignatedRooms); foreach (Room r in toCheck) { r.RemoveVoxel(vRef); if (r.Voxels.Count == 0) { toDestroy.Add(r); } } foreach (Room r in toDestroy) { DesignatedRooms.Remove(r); r.Destroy(); } } }
public List<Voxel> GetNeighborsEuclidean(Voxel v) { Vector3 gridCoord = v.GridPosition; return GetNeighborsEuclidean((int) gridCoord.X, (int) gridCoord.Y, (int) gridCoord.Z); }
public bool DiscreteUpdate(VoxelChunk chunk) { Vector3 gridCoord = new Vector3(0, 0, 0); bool updateOccurred = false; List<int> updateList = new List<int>(); WaterCell cellBelow = new WaterCell(); int maxSize = chunk.SizeX*chunk.SizeY*chunk.SizeZ; for (int i = 0; i < maxSize; i++) { WaterCell cell = chunk.Data.Water[i]; // Don't check empty cells or cells we've already modified. if (cell.WaterLevel < 1 || chunk.Data.Types[i] != 0) { continue; } updateList.Add(i); } if(updateList.Count == 0) { return false; } Voxel voxBelow = chunk.MakeVoxel(0, 0, 0); List<int> indices = Datastructures.RandomIndices(updateList.Count); // Loop through each cell. foreach(int t in indices) { int idx = updateList[indices[t]]; // Don't check empty cells or cells we've already modified. if (chunk.Data.Water[idx].WaterLevel < 1 || chunk.Data.Types[idx] != 0) { continue; } gridCoord = chunk.Data.CoordsAt(idx); int x = (int) gridCoord.X; int y = (int) gridCoord.Y; int z = (int) gridCoord.Z; Vector3 worldPos = gridCoord + chunk.Origin; if (chunk.Data.Water[idx].WaterLevel < EvaporationLevel && PlayState.Random.Next(0, 10) < 5) { if (chunk.Data.Water[idx].WaterLevel > 1) { chunk.Data.Water[idx].WaterLevel--; } else { chunk.Data.Water[idx].WaterLevel = 0; chunk.Data.Water[idx].Type = LiquidType.None; CreateSplash(worldPos, chunk.Data.Water[idx].Type); } updateOccurred = true; } bool shouldFall = false; // Now check the cell immediately below this one. // There are two cases, either we are at the bottom of the chunk, // in which case we must find the water from the chunk manager. // Otherwise, we just get the cell immediately beneath us. if(y > 0) { voxBelow.GridPosition = new Vector3(x, y - 1, z); if(voxBelow.IsEmpty) { cellBelow = voxBelow.Water; shouldFall = true; } } /* else { if(chunk.Manager.ChunkData.DoesWaterCellExist(worldPos)) { Voxel voxelsBelow = chunk.Manager.ChunkData.GetVoxel(chunk, worldPos + new Vector3(0, -1, 0)); if(voxelsBelow != null && voxelsBelow.IsEmpty) { cellBelow = chunk.Manager.ChunkData.GetWaterCellAtLocation(worldPos + new Vector3(0, -1, 0)); shouldFall = true; cellBelow.IsFalling = true; } } } */ // Cases where the fluid can fall down. if(shouldFall) { // If the cell immediately below us is empty, // swap the contents and move on. if(cellBelow.WaterLevel < 1) { cellBelow.WaterLevel = chunk.Data.Water[idx].WaterLevel; if(cellBelow.Type == LiquidType.None) { cellBelow.Type = chunk.Data.Water[idx].Type; } chunk.Data.Water[idx].WaterLevel = 0; chunk.Data.Water[idx].Type = LiquidType.None; chunk.Data.Water[idx].IsFalling = true; chunk.Data.Water[idx].HasChanged = true; cellBelow.HasChanged = true; voxBelow.Water = cellBelow; CreateSplash(worldPos, chunk.Data.Water[idx].Type); CreateTransfer(worldPos, chunk.Data.Water[idx], cellBelow, cellBelow.WaterLevel); updateOccurred = true; continue; } // Otherwise, fill as much of the space as we can. else { byte spaceLeft = (byte) (255 - cellBelow.WaterLevel); if(spaceLeft > 5) { CreateSplash(gridCoord + chunk.Origin, chunk.Data.Water[idx].Type); } // Special case where we can flow completely into the next cell. if (spaceLeft >= chunk.Data.Water[idx].WaterLevel) { byte transfer = chunk.Data.Water[idx].WaterLevel; cellBelow.WaterLevel += transfer; cellBelow.HasChanged = true; if(cellBelow.Type == LiquidType.None) { cellBelow.Type = chunk.Data.Water[idx].Type; } chunk.Data.Water[idx].WaterLevel = 0; chunk.Data.Water[idx].Type = LiquidType.None; chunk.Data.Water[idx].HasChanged = true; CreateTransfer(worldPos - Vector3.UnitY, chunk.Data.Water[idx], cellBelow, transfer); voxBelow.Water = cellBelow; updateOccurred = true; continue; } // Otherwise, only flow a little bit, and spread later. else { chunk.Data.Water[idx].WaterLevel -= spaceLeft; cellBelow.WaterLevel += spaceLeft; chunk.Data.Water[idx].HasChanged = true; cellBelow.HasChanged = true; if(cellBelow.Type == LiquidType.None) { cellBelow.Type = chunk.Data.Water[idx].Type; } CreateTransfer(worldPos - Vector3.UnitY, chunk.Data.Water[idx], cellBelow, spaceLeft); voxBelow.Water = cellBelow; } } } // Now the only fluid left can spread. // We spread to the manhattan neighbors //Array.Sort(m_spreadNeighbors, (a, b) => CompareFlowVectors(a, b, chunk.Data.Water[idx].FluidFlow)); Voxel neighbor = new Voxel(); foreach(Vector3 spread in m_spreadNeighbors) { bool success = chunk.Manager.ChunkData.GetVoxel(chunk, worldPos + spread, ref neighbor); if(!success) { continue; } if(!neighbor.IsEmpty) { continue; } WaterCell neighborWater = neighbor.Water; byte amountToMove = (byte)(Math.Min(255.0f - (float)neighborWater.WaterLevel, chunk.Data.Water[idx].WaterLevel) * GetSpreadRate(chunk.Data.Water[idx].Type)); if(amountToMove == 0) { continue; } if(neighborWater.WaterLevel < 2) { CreateSplash(worldPos + spread, chunk.Data.Water[idx].Type); updateOccurred = true; } CreateTransfer(worldPos + spread, chunk.Data.Water[idx], neighborWater, amountToMove); chunk.Data.Water[idx].WaterLevel -= amountToMove; neighborWater.WaterLevel += amountToMove; if(neighborWater.Type == LiquidType.None) { neighborWater.Type = chunk.Data.Water[idx].Type; } chunk.Data.Water[idx].HasChanged = true; neighborWater.HasChanged = true; neighbor.Water = neighborWater; if (chunk.Data.Water[idx].WaterLevel >= 1) { continue; } chunk.Data.Water[idx].WaterLevel = 0; chunk.Data.Water[idx].Type = LiquidType.None; break; } } return updateOccurred; }
public List<Voxel> GetNeighborsEuclidean(int x, int y, int z) { List<Voxel> toReturn = new List<Voxel>(); bool isInterior = (x > 0 && y > 0 && z > 0 && x < SizeX - 1 && y < SizeY - 1 && z < SizeZ - 1); for(int dx = -1; dx < 2; dx++) { for(int dy = -1; dy < 2; dy++) { for(int dz = -1; dz < 2; dz++) { if(dx == 0 && dy == 0 && dz == 0) { continue; } int nx = (int) dx + x; int ny = (int) dy + y; int nz = (int) dz + z; if(isInterior || IsCellValid(nx, ny, nz)) { toReturn.Add(MakeVoxel(nx, ny, nz)); } else { Voxel otherVox = new Voxel(); if (Manager.ChunkData.GetVoxel(this, new Vector3(nx, ny, nz) + Origin, ref otherVox)) { toReturn.Add(otherVox); } } } } } return toReturn; }
public Wheat(ComponentManager componentManager, Vector3 position) : base("Wheat", componentManager.RootComponent, Matrix.Identity, new Vector3(1.0f, 1.0f, 1.0f), Vector3.Zero) { Seedlingsheet = new SpriteSheet(ContentPaths.Entities.Plants.gnarled, 32, 32); SeedlingFrame = new Point(0, 0); Matrix matrix = Matrix.CreateRotationY(MathFunctions.Rand(-0.1f, 0.1f)); matrix.Translation = position + new Vector3(0.5f, -0.25f, 0.5f); LocalTransform = matrix; SpriteSheet spriteSheet = new SpriteSheet(ContentPaths.Entities.Plants.wheat); List <Point> frames = new List <Point> { new Point(0, 0) }; Animation tableAnimation = new Animation(GameState.Game.GraphicsDevice, new SpriteSheet(ContentPaths.Entities.Plants.wheat), "Wheat", 32, 32, frames, false, Color.White, 0.01f, 1.0f, 1.0f, false); Sprite sprite = new Sprite(componentManager, "sprite", this, Matrix.Identity, spriteSheet, false) { OrientationType = Sprite.OrientMode.Fixed }; sprite.AddAnimation(tableAnimation); Sprite sprite2 = new Sprite(componentManager, "sprite2", this, Matrix.CreateRotationY((float)Math.PI * 0.5f), spriteSheet, false) { OrientationType = Sprite.OrientMode.Fixed }; sprite2.AddAnimation(tableAnimation); Voxel voxelUnder = new Voxel(); bool success = componentManager.World.ChunkManager.ChunkData.GetFirstVoxelUnder(position, ref voxelUnder); if (success) { VoxelListener listener = new VoxelListener(componentManager, this, componentManager.World.ChunkManager, voxelUnder); } Inventory inventory = new Inventory("Inventory", this) { Resources = new ResourceContainer() { MaxResources = 4, Resources = new Dictionary <ResourceLibrary.ResourceType, ResourceAmount>() { { ResourceLibrary.ResourceType.Grain, new ResourceAmount(ResourceLibrary.ResourceType.Grain, MathFunctions.RandInt(1, 5)) } } } }; Health health = new Health(componentManager, "HP", this, 30, 0.0f, 30); new Flammable(componentManager, "Flames", this, health); tableAnimation.Play(); Tags.Add("Wheat"); Tags.Add("Vegetation"); CollisionType = CollisionManager.CollisionType.Static; }
public static void UpdateRamps(VoxelChunk chunk) { Dictionary <BoxFace, bool> faceExists = new Dictionary <BoxFace, bool>(); Dictionary <BoxFace, bool> faceVisible = new Dictionary <BoxFace, bool>(); Voxel v = chunk.MakeVoxel(0, 0, 0); Voxel vAbove = chunk.MakeVoxel(0, 0, 0); Voxel voxelOnFace = chunk.MakeVoxel(0, 0, 0); Voxel worldVoxel = new Voxel(); for (int x = 0; x < chunk.SizeX; x++) { for (int y = 0; y < Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY); y++) { for (int z = 0; z < chunk.SizeZ; z++) { v.GridPosition = new Vector3(x, y, z); bool isTop = false; if (y < chunk.SizeY - 1) { vAbove.GridPosition = new Vector3(x, y + 1, z); isTop = vAbove.IsEmpty; } if (isTop && !v.IsEmpty && v.IsVisible && v.Type.CanRamp) { for (int i = 0; i < 6; i++) { BoxFace face = (BoxFace)i; if (!IsSideFace(face)) { continue; } Vector3 delta = FaceDeltas[(int)face]; faceExists[face] = chunk.IsCellValid(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z); faceVisible[face] = true; if (faceExists[face]) { voxelOnFace.GridPosition = new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z); if (voxelOnFace.IsEmpty || !voxelOnFace.IsVisible) { faceVisible[face] = true; } else { faceVisible[face] = false; } } else { if (!chunk.Manager.ChunkData.GetNonNullVoxelAtWorldLocation(new Vector3(x + (int)delta.X + 0.5f, y + (int)delta.Y + 0.5f, z + (int)delta.Z + 0.5f) + chunk.Origin, ref worldVoxel) || !worldVoxel.IsVisible) { faceVisible[face] = true; } else { faceVisible[face] = false; } } if (faceVisible[face]) { v.RampType = v.RampType | UpdateRampType(face); } } if (RampIsDegenerate(v.RampType)) { v.RampType = RampType.None; } } else if (!v.IsEmpty && v.IsVisible && v.Type.CanRamp) { v.RampType = RampType.None; } } } } }