public override void Die() { if (World == null) { return; // WUT } if (Stats == null) { return; // SERIOUSLY WTF?? } World.RemoveFromSpeciesTracking(Stats.Species); NoiseMaker.MakeNoise("Die", Physics.Position, true); if (AI.Stats.Money > 0) { EntityFactory.CreateEntity <CoinPile>("Coins Resource", AI.Position, Blackboard.Create("Money", AI.Stats.Money)); } if (Stats.Species.HasMeat) { String type = Stats.CurrentClass.Name + " " + "Meat"; if (!Library.DoesResourceTypeExist(type)) { var r = Library.CreateResourceType(Library.GetResourceType(Stats.Species.BaseMeatResource)); r.Name = type; r.ShortName = type; Library.AddResourceType(r); } Inventory.AddResource(new ResourceAmount(type, 1)); } if (Stats.Species.HasBones) { String type = Stats.CurrentClass.Name + " Bone"; if (!Library.DoesResourceTypeExist(type)) { var r = Library.CreateResourceType(Library.GetResourceType("Bone")); r.Name = type; r.ShortName = type; Library.AddResourceType(r); } Inventory.AddResource(new ResourceAmount(type, 1)); } base.Die(); }
/// <summary> /// Kills the creature and releases its resources. /// </summary> public override void Die() { // This is just a silly hack to make sure that creatures // carrying resources to a trade depot release their resources // when they die. CreateMeatAndBones(); NoiseMaker.MakeNoise("Die", Physics.Position, true); if (AI.Status.Money > 0) { EntityFactory.CreateEntity <CoinPile>("Coins Resource", AI.Position, Blackboard.Create("Money", AI.Status.Money)); } base.Die(); }
public static IEnumerable <Body> CreateResourcePiles(IEnumerable <ResourceAmount> resources, BoundingBox box) { const int maxPileSize = 64; foreach (ResourceAmount resource in resources) { for (int numRemaining = resource.NumResources; numRemaining > 0; numRemaining -= maxPileSize) { const int maxIters = 10; for (int i = 0; i < maxIters; i++) { Vector3 pos = MathFunctions.RandVector3Box(box); var voxel = new VoxelHandle(World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(pos)); if ((!voxel.IsValid) || !voxel.IsEmpty) { continue; } Physics body = EntityFactory.CreateEntity <Physics>(resource.ResourceType + " Resource", pos, Blackboard.Create <int>("num", Math.Min(numRemaining, maxPileSize))) as Physics; if (body != null) { body.Velocity = MathFunctions.RandVector3Cube(); body.Velocity.Normalize(); body.Velocity *= 5.0f; body.IsSleeping = false; yield return(body); } break; } } } }
public static void GenerateCaveVegetation(VoxelChunk chunk, int x, int y, int z, int caveHeight, BiomeData biome, Vector3 vec, WorldManager world, Perlin NoiseGenerator) { var vUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - 1, z)); var wayUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - caveHeight, z)); wayUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType)); var grassType = GrassLibrary.GetGrassType(biome.GrassDecal); if (grassType != null) { wayUnder.RawSetGrass(grassType.ID); } foreach (VegetationData veg in biome.Vegetation) { if (!MathFunctions.RandEvent(veg.SpawnProbability)) { continue; } if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold) { continue; } if (!vUnder.IsEmpty && vUnder.Type.Name == biome.SoilLayer.VoxelType) { vUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType)); vUnder.RawSetGrass(0); float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; WorldManager.DoLazy(() => { if (!GameSettings.Default.FogofWar) { GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name, vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", treeSize)); } else { world.ComponentManager.RootComponent.AddChild(new ExploredListener( world.ComponentManager, vUnder) { EntityToSpawn = veg.Name, SpawnLocation = vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), BlackboardData = Blackboard.Create("Scale", treeSize) }); } }); } } float spawnLikelihood = (world.InitialEmbark.Difficulty + 0.1f); foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(MathFunctions.Random.NextDouble() < animal.SpawnProbability * spawnLikelihood)) { continue; } FaunaData animal1 = animal; WorldManager.DoLazy(() => { if (!GameSettings.Default.FogofWar) { var entity = EntityFactory.CreateEntity <GameComponent>(animal1.Name, wayUnder.WorldPosition + Vector3.Up * 1.5f); } else { world.ComponentManager.RootComponent.AddChild(new ExploredListener (world.ComponentManager, new VoxelHandle(chunk, wayUnder.Coordinate.GetLocalVoxelCoordinate())) { EntityToSpawn = animal1.Name, SpawnLocation = wayUnder.WorldPosition + Vector3.Up * 1.5f }); } }); break; } }
public void GenerateSurfaceLife(Dictionary <string, Dictionary <string, int> > creatureCounts, VoxelChunk Chunk, float maxHeight) { //int waterHeight = (int)(VoxelConstants.ChunkSizeY * NormalizeHeight(SeaLevel + 1.0f / VoxelConstants.ChunkSizeY, maxHeight)); for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { var biomeData = Overworld.GetBiomeAt(new Vector3(x + Chunk.Origin.X, 0, z + Chunk.Origin.Z), Chunk.Manager.World.WorldScale, Chunk.Manager.World.WorldOrigin); var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( Chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); if (!topVoxel.IsValid || topVoxel.Coordinate.Y == 0 || topVoxel.Coordinate.Y >= 60) // Lift to some kind of generator settings? { continue; } var above = VoxelHelpers.GetVoxelAbove(topVoxel); if (above.IsValid && above.LiquidLevel != 0) { continue; } foreach (var animal in biomeData.Fauna) { if (MathFunctions.RandEvent(animal.SpawnProbability)) { if (!creatureCounts.ContainsKey(biomeData.Name)) { creatureCounts[biomeData.Name] = new Dictionary <string, int>(); } var dict = creatureCounts[biomeData.Name]; if (!dict.ContainsKey(animal.Name)) { dict[animal.Name] = 0; } if (dict[animal.Name] < animal.MaxPopulation) { EntityFactory.CreateEntity <Body>(animal.Name, topVoxel.WorldPosition + Vector3.Up * 1.5f); } break; } } if (topVoxel.Type.Name != biomeData.SoilLayer.VoxelType) { continue; } foreach (VegetationData veg in biomeData.Vegetation) { if (topVoxel.GrassType == 0) { continue; } if (MathFunctions.RandEvent(veg.SpawnProbability) && NoiseGenerator.Noise(topVoxel.Coordinate.X / veg.ClumpSize, veg.NoiseOffset, topVoxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold) { topVoxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType)); var treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; var tree = EntityFactory.CreateEntity <Plant>(veg.Name, topVoxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", treeSize)); break; } } } } }
public void GenerateVegetation(VoxelChunk chunk, ComponentManager components, ContentManager content, GraphicsDevice graphics) { int waterHeight = (int)(SeaLevel * chunk.SizeY); bool updated = false; Voxel v = chunk.MakeVoxel(0, 0, 0); Voxel vUnder = chunk.MakeVoxel(0, 0, 0); for (int x = 0; x < chunk.SizeX; x++) { for (int z = 0; z < chunk.SizeZ; z++) { Vector2 vec = new Vector2(x + chunk.Origin.X, z + chunk.Origin.Z) / PlayState.WorldScale; Overworld.Biome biome = Overworld.Map[(int)MathFunctions.Clamp(vec.X, 0, Overworld.Map.GetLength(0) - 1), (int)MathFunctions.Clamp(vec.Y, 0, Overworld.Map.GetLength(1) - 1)].Biome; BiomeData biomeData = BiomeLibrary.Biomes[biome]; int y = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); if (!chunk.IsCellValid(x, (int)(y - chunk.Origin.Y), z)) { continue; } v.GridPosition = new Vector3(x, y, z); if (!v.IsEmpty || chunk.Data.Water[v.Index].WaterLevel != 0 || y <= waterHeight) { continue; } foreach (VegetationData veg in biomeData.Vegetation) { if (y <= 0) { continue; } if (!MathFunctions.RandEvent(veg.SpawnProbability)) { continue; } if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold) { continue; } int yh = chunk.GetFilledVoxelGridHeightAt(x, y, z); if (yh > 0) { vUnder.GridPosition = new Vector3(x, yh - 1, z); if (!vUnder.IsEmpty && vUnder.TypeName == biomeData.GrassVoxel) { vUnder.Type = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel); updated = true; float offset = veg.VerticalOffset; if (vUnder.RampType != RampType.None) { offset -= 0.25f; } float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; EntityFactory.CreateEntity <Body>(veg.Name, chunk.Origin + new Vector3(x, y, z) + new Vector3(0, treeSize * offset, 0), Blackboard.Create("Scale", treeSize)); } } break; } } } if (updated) { chunk.ShouldRebuild = true; } }
public void VoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button) { if (!IsEnabled) { return; } switch (button) { case (InputManager.MouseButton.Left): { List <Task> assignments = new List <Task>(); // Creating multiples doesn't work anyway - kill it. foreach (var r in refs) { if (IsDesignation(r) || !r.IsValid || !r.IsEmpty) { continue; } else { Vector3 pos = r.WorldPosition + new Vector3(0.5f, 0.0f, 0.5f) + CurrentCraftType.SpawnOffset; Vector3 startPos = pos + new Vector3(0.0f, -0.1f, 0.0f); Vector3 endPos = pos; // TODO: Why are we creating a new designation? CraftDesignation newDesignation = new CraftDesignation() { ItemType = CurrentCraftType, Location = r, Orientation = CurrentDesignation.Orientation, OverrideOrientation = CurrentDesignation.OverrideOrientation, Valid = true, Entity = CurrentCraftBody, SelectedResources = SelectedResources }; if (IsValid(newDesignation)) { AddDesignation(newDesignation, CurrentCraftType.SpawnOffset); assignments.Add(new CraftItemTask(newDesignation)); // Todo: Maybe don't support create huge numbers of entities at once? CurrentCraftBody = EntityFactory.CreateEntity <Body>(CurrentCraftType.Name, r.WorldPosition, Blackboard.Create <List <ResourceAmount> >("Resources", SelectedResources)); EntityFactory.GhostEntity(CurrentCraftBody, Color.White); newDesignation.WorkPile = new WorkPile(World.ComponentManager, startPos); World.ComponentManager.RootComponent.AddChild(newDesignation.WorkPile); newDesignation.WorkPile.AnimationQueue.Add(new EaseMotion(1.1f, Matrix.CreateTranslation(startPos), endPos)); World.ParticleManager.Trigger("puff", pos, Color.White, 10); } } } if (assignments.Count > 0) { World.Master.TaskManager.AddTasks(assignments); } break; } case (InputManager.MouseButton.Right): { foreach (var r in refs) { if (!IsDesignation(r)) { continue; } RemoveDesignation(r); } break; } } }
public void Update(DwarfTime gameTime, GameMaster player) { if (!IsEnabled) { if (CurrentCraftBody != null) { CurrentCraftBody.Delete(); CurrentCraftBody = null; } return; } if (Faction == null) { Faction = player.Faction; } if (CurrentCraftType != null && CurrentCraftBody == null) { CurrentCraftBody = EntityFactory.CreateEntity <Body>(CurrentCraftType.Name, player.VoxSelector.VoxelUnderMouse.WorldPosition, Blackboard.Create <List <ResourceAmount> >("Resources", SelectedResources)); EntityFactory.GhostEntity(CurrentCraftBody, Color.White); CurrentDesignation = new CraftDesignation() { ItemType = CurrentCraftType, Location = VoxelHandle.InvalidHandle, Valid = true }; OverrideOrientation = false; CurrentCraftBody.SetTintRecursive(Color.Green); } if (CurrentCraftBody == null || !player.VoxSelector.VoxelUnderMouse.IsValid) { return; } CurrentCraftBody.LocalPosition = player.VoxSelector.VoxelUnderMouse.WorldPosition + new Vector3(0.5f, 0.0f, 0.5f) + CurrentCraftType.SpawnOffset; CurrentCraftBody.GlobalTransform = CurrentCraftBody.LocalTransform; CurrentCraftBody.UpdateTransform(); CurrentCraftBody.PropogateTransforms(); if (OverrideOrientation) { CurrentCraftBody.Orient(CurrentOrientation); } else { CurrentCraftBody.OrientToWalls(); } HandleOrientation(); if (CurrentDesignation != null) { if (CurrentDesignation.Location.Equals(player.VoxSelector.VoxelUnderMouse)) { return; } CurrentDesignation.Location = player.VoxSelector.VoxelUnderMouse; World.ShowTooltip("Click to build. Press R/T to rotate."); CurrentCraftBody.SetTintRecursive(IsValid(CurrentDesignation) ? Color.Green : Color.Red); } }
public void GenerateCaves(VoxelChunk chunk) { Vector3 origin = chunk.Origin; int chunkSizeX = chunk.SizeX; int chunkSizeY = chunk.SizeY; int chunkSizeZ = chunk.SizeZ; BiomeData biome = BiomeLibrary.Biomes[Overworld.Biome.Cave]; List <Voxel> neighbors = new List <Voxel>(); Voxel vUnder = chunk.MakeVoxel(0, 0, 0); for (int x = 0; x < chunkSizeX; x++) { for (int z = 0; z < chunkSizeZ; z++) { int h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); for (int i = 0; i < CaveLevels.Count; i++) { int y = CaveLevels[i]; if (y <= 0 || y >= h - 1) { 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) { bool waterFound = false; for (int dy = 0; dy < caveHeight; dy++) { int index = chunk.Data.IndexAt(x, y - dy, z); chunk.GetNeighborsManhattan(x, y - dy, z, neighbors); if (neighbors.Any(v => v.WaterLevel > 0)) { waterFound = true; } if (waterFound) { break; } chunk.Data.Types[index] = 0; } if (!waterFound && caveNoise > CaveSize * 1.8f && y - caveHeight > 0) { int indexunder = chunk.Data.IndexAt(x, y - caveHeight, z); chunk.Data.Types[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassVoxel).ID; chunk.Data.Health[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassVoxel).StartingHealth; chunk.Data.IsExplored[indexunder] = false; foreach (VegetationData veg in biome.Vegetation) { if (!MathFunctions.RandEvent(veg.SpawnProbability)) { continue; } if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold) { continue; } vUnder.GridPosition = new Vector3(x, y - 1, z); if (!vUnder.IsEmpty && vUnder.TypeName == biome.GrassVoxel) { vUnder.Type = VoxelLibrary.GetVoxelType(biome.SoilVoxel); float offset = veg.VerticalOffset; if (vUnder.RampType != RampType.None) { offset -= 0.25f; } float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name, chunk.Origin + new Vector3(x, y, z) + new Vector3(0, treeSize * offset, 0), Blackboard.Create("Scale", treeSize)); entity.GetRootComponent().SetActiveRecursive(false); entity.GetRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener( PlayState.ComponentManager, entity, PlayState.ChunkManager, vUnder); } } } } foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(PlayState.Random.NextDouble() < animal.SpawnProbability)) { continue; } var entity = EntityFactory.CreateEntity <GameComponent>(animal.Name, chunk.Origin + new Vector3(x, y, z) + Vector3.Up * 1.0f); entity.GetRootComponent().SetActiveRecursive(false); entity.GetRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener(PlayState.ComponentManager, entity, PlayState.ChunkManager, chunk.MakeVoxel(x, y, z)); } break; } } } } } }
public override void Destroy() { BoundingBox box = GetBoundingBox(); const int maxPileSize = 64; foreach (ResourceAmount resource in Resources) { for (int numRemaining = resource.NumResources; numRemaining > 0; numRemaining -= maxPileSize) { Physics body = EntityFactory.CreateEntity <Physics>(resource.ResourceType + " Resource", Vector3.Up + MathFunctions.RandVector3Box(box), Blackboard.Create <int>("num", Math.Min(numRemaining, maxPileSize))) as Physics; if (body != null) { body.Velocity = MathFunctions.RandVector3Cube(); } } } if (Faction != null) { Faction.Stockpiles.Remove(this); } base.Destroy(); }
public void GenerateSurfaceLife(VoxelChunk Chunk) { var waterHeight = (int)(SeaLevel * VoxelConstants.ChunkSizeY); for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { var biomeData = GetBiomeAt(new Vector2(x + Chunk.Origin.X, z + Chunk.Origin.Z)); var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( Chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); if (!topVoxel.IsValid || topVoxel.Coordinate.Y == 0 || topVoxel.Coordinate.Y >= 60) // Lift to some kind of generator settings? { continue; } var above = VoxelHelpers.GetVoxelAbove(topVoxel); if (above.IsValid && above.WaterCell.WaterLevel != 0) { continue; } foreach (var animal in biomeData.Fauna) { if (MathFunctions.RandEvent(animal.SpawnProbability)) { EntityFactory.CreateEntity <Body>(animal.Name, topVoxel.WorldPosition + Vector3.Up * 1.5f); break; } } if (topVoxel.Type.Name != biomeData.SoilLayer.VoxelType) { continue; } foreach (VegetationData veg in biomeData.Vegetation) { if (topVoxel.GrassType == 0) { continue; } if (MathFunctions.RandEvent(veg.SpawnProbability) && NoiseGenerator.Noise(topVoxel.Coordinate.X / veg.ClumpSize, veg.NoiseOffset, topVoxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold) { topVoxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType)); var treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; var tree = EntityFactory.CreateEntity <Plant>(veg.Name, topVoxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", treeSize)); break; } } } } }