public override Task ActOnIdle() { if (DestroyPlayerObjectProbability > 0 && MathFunctions.RandEvent(DestroyPlayerObjectProbability)) { bool plantBomb = !String.IsNullOrEmpty(PlantBomb) && MathFunctions.RandEvent(0.5f); if (!plantBomb && World.PlayerFaction.OwnedObjects.Count > 0) { var thing = Datastructures.SelectRandom <Body>(World.PlayerFaction.OwnedObjects); AssignTask(new KillEntityTask(thing, KillEntityTask.KillType.Auto)); } else if (plantBomb) { var room = World.PlayerFaction.GetNearestRoom(Position); if (room != null) { AssignTask(new ActWrapperTask(new Sequence(new GoToZoneAct(this, room), new Do(() => { EntityFactory.CreateEntity <Body>(PlantBomb, Position); return(true); }))) { Priority = Task.PriorityType.High }); } else if (World.PlayerFaction.OwnedObjects.Count > 0) { var thing = Datastructures.SelectRandom <Body>(World.PlayerFaction.OwnedObjects); AssignTask(new ActWrapperTask(new Sequence(new GoToEntityAct(thing, this), new Do(() => { EntityFactory.CreateEntity <Body>(PlantBomb, Position); return(true); }))) { Priority = Task.PriorityType.High }); } } } LeaveWorldTimer.Update(DwarfTime.LastTime); if (LeaveWorldTimer.HasTriggered) { LeaveWorld(); LeaveWorldTimer.Reset(); } return(base.ActOnIdle()); }
public override void OnVoxelsSelected(List <Voxel> refs, InputManager.MouseButton button) { if (!IsActive) { return; } string command = SelectorBox.CurrentValue; if (command == "") { return; } HashSet <Point3> chunksToRebuild = new HashSet <Point3>(); if (command.Contains("Build/")) { string type = command.Substring(6); BuildRoomOrder des = new BuildRoomOrder(RoomLibrary.CreateRoom(Player.Faction, type, refs, false), Player.Faction); Player.Faction.RoomBuilder.BuildDesignations.Add(des); Player.Faction.RoomBuilder.DesignatedRooms.Add(des.ToBuild); des.Build(); } else if (command.Contains("Spawn/")) { string type = command.Substring(6); foreach (Voxel vox in refs.Where(vox => vox != null)) { if (vox.IsEmpty) { EntityFactory.CreateEntity <Body>(type, vox.Position + new Vector3(0.5f, 0.5f, 0.5f)); } } } else { foreach (Voxel vox in refs.Where(vox => vox != null)) { if (command.Contains("Place/")) { string type = command.Substring(6); vox.Type = VoxelLibrary.GetVoxelType(type); vox.Water = new WaterCell(); vox.Health = vox.Type.StartingHealth; if (type == "Magic") { new VoxelListener(PlayState.ComponentManager, PlayState.ComponentManager.RootComponent, PlayState.ChunkManager, vox) { DestroyOnTimer = true, DestroyTimer = new Timer(5.0f + MathFunctions.Rand(-0.5f, 0.5f), true) }; } chunksToRebuild.Add(vox.ChunkID); } else { switch (command) { case "Delete Block": { PlayState.Master.Faction.OnVoxelDestroyed(vox); vox.Chunk.NotifyDestroyed(new Point3(vox.GridPosition)); vox.Type = VoxelType.TypeList[0]; vox.Water = new WaterCell(); if (!chunksToRebuild.Contains(vox.ChunkID)) { Chunks.ChunkData.ChunkMap[vox.ChunkID].NotifyTotalRebuild(vox.IsEmpty && !vox.IsInterior); } chunksToRebuild.Add(vox.ChunkID); } break; case "Kill Block": foreach (Voxel selected in refs) { if (!selected.IsEmpty) { selected.Kill(); } } break; case "Fill Water": { if (vox.IsEmpty) { vox.WaterLevel = 255; vox.Chunk.Data.Water[vox.Index].Type = LiquidType.Water; chunksToRebuild.Add(vox.ChunkID); } } break; case "Fill Lava": { Vector3 gridPos = vox.GridPosition; if (vox.IsEmpty) { vox.WaterLevel = 255; vox.Chunk.Data.Water[vox.Index].Type = LiquidType.Lava; chunksToRebuild.Add(vox.ChunkID); } } break; case "Fire": { List <Body> components = new List <Body>(); Player.Faction.Components.GetBodiesIntersecting(vox.GetBoundingBox(), components, CollisionManager.CollisionType.Dynamic | CollisionManager.CollisionType.Static); foreach (Flammable flam2 in components.Select(comp => comp.GetChildrenOfTypeRecursive <Flammable>()).Where(flam => flam.Count > 0).SelectMany(flam => flam)) { flam2.Heat = flam2.Flashpoint + 1; } } break; case "Kill Things": { List <Body> components = new List <Body>(); Player.Faction.Components.GetBodiesIntersecting(vox.GetBoundingBox(), components, CollisionManager.CollisionType.Dynamic | CollisionManager.CollisionType.Static); foreach (Body comp in components) { comp.Die(); } } break; default: break; } } } } foreach (Point3 chunk in chunksToRebuild) { Chunks.ChunkData.ChunkMap[chunk].NotifyTotalRebuild(false); } }
public override Body CreatePlant(Vector3 position) { return((Body)EntityFactory.CreateEntity <Body>("Mushroom", position)); }
public IEnumerable <Status> FarmATile() { if (FarmToWork == null) { yield return(Status.Fail); yield break; } else if (FarmToWork.Finished) { yield return(Status.Success); } else { Creature.CurrentCharacterMode = Creature.Stats.CurrentClass.AttackMode; Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode); Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode); while (FarmToWork.Progress < FarmToWork.TargetProgress && !FarmToWork.Finished) { Creature.Physics.Velocity *= 0.1f; FarmToWork.Progress += 3 * Creature.Stats.BaseFarmSpeed * DwarfTime.Dt; Drawer2D.DrawLoadBar(Agent.Manager.World.Renderer.Camera, Agent.Position + Vector3.Up, Color.LightGreen, Color.Black, 64, 4, FarmToWork.Progress / FarmToWork.TargetProgress); if (FarmToWork.Progress >= (FarmToWork.TargetProgress * 0.5f) && FarmToWork.Voxel.Type.Name != "TilledSoil") { FarmToWork.Voxel.Type = Library.GetVoxelType("TilledSoil"); } if (FarmToWork.Progress >= FarmToWork.TargetProgress && !FarmToWork.Finished) { var plant = EntityFactory.CreateEntity <Plant>( Library.GetResourceType(FarmToWork.SeedString).PlantToGenerate, FarmToWork.Voxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f)); plant.Farm = FarmToWork; Matrix original = plant.LocalTransform; original.Translation += Vector3.Down; plant.AnimationQueue.Add(new EaseMotion(0.5f, original, plant.LocalTransform.Translation)); Creature.Manager.World.ParticleManager.Trigger("puff", original.Translation, Color.White, 20); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_env_plant_grow, FarmToWork.Voxel.WorldPosition, true); FarmToWork.Finished = true; DestroyResources(); } if (MathFunctions.RandEvent(0.01f)) { Creature.Manager.World.ParticleManager.Trigger("dirt_particle", Creature.AI.Position, Color.White, 1); } yield return(Status.Running); Creature.Sprite.ReloopAnimations(Creature.Stats.CurrentClass.AttackMode); } Creature.CurrentCharacterMode = CharacterMode.Idle; Creature.AddThought("I farmed something!", new TimeSpan(0, 4, 0, 0), 1.0f); Creature.AI.AddXP(1); Creature.Sprite.PauseAnimations(Creature.Stats.CurrentClass.AttackMode); yield return(Status.Success); } }
/// <summary> /// Called every frame /// </summary> /// <param name="gameTime">The current time</param> public void Update(DwarfTime gameTime) { EntityFactory.DoLazyActions(); if (FastForwardToDay) { if (Time.IsDay()) { FastForwardToDay = false; foreach (CreatureAI minion in Master.Faction.Minions) { minion.Status.Energy.CurrentValue = minion.Status.Energy.MaxValue; } //Master.ToolBar.SpeedButton.SetSpeed(1); Time.Speed = 100; } else { //Master.ToolBar.SpeedButton.SetSpecialSpeed(3); Time.Speed = 1000; } } //Drawer3D.DrawPlane(0, Camera.Position.X - 1500, Camera.Position.Z - 1500, Camera.Position.X + 1500, Camera.Position.Z + 1500, Color.Black); FillClosestLights(gameTime); IndicatorManager.Update(gameTime); AspectRatio = GraphicsDevice.Viewport.AspectRatio; Camera.AspectRatio = AspectRatio; Camera.Update(gameTime, ChunkManager); HandleAmbientSound(); Master.Update(Game, gameTime); GoalManager.Update(this); Time.Update(gameTime); if (Paused) { ComponentManager.UpdatePaused(); } // If not paused, we want to just update the rest of the game. else { TutorialManager.Update(Gui); GamePerformance.Instance.StartTrackPerformance("Diplomacy"); Diplomacy.Update(gameTime, Time.CurrentDate, this); GamePerformance.Instance.StopTrackPerformance("Diplomacy"); GamePerformance.Instance.StartTrackPerformance("Factions"); Factions.Update(gameTime); GamePerformance.Instance.StopTrackPerformance("Factions"); GamePerformance.Instance.StartTrackPerformance("Components"); ComponentManager.Update(gameTime, ChunkManager, Camera); GamePerformance.Instance.StopTrackPerformance("Components"); Sky.TimeOfDay = Time.GetSkyLightness(); Sky.CosTime = (float)(Time.GetTotalHours() * 2 * Math.PI / 24.0f); DefaultShader.TimeOfDay = Sky.TimeOfDay; GamePerformance.Instance.StartTrackPerformance("Monster Spawner"); MonsterSpawner.Update(gameTime); GamePerformance.Instance.StopTrackPerformance("Monster Spawner"); GamePerformance.Instance.StartTrackPerformance("All Asleep"); bool allAsleep = Master.AreAllEmployeesAsleep(); #if !UPTIME_TEST if (SleepPrompt == null && allAsleep && !FastForwardToDay && Time.IsNight()) { SleepPrompt = Gui.ConstructWidget(new Gui.Widgets.Confirm { Text = "All of your employees are asleep. Skip to daytime?", OkayText = "Skip to Daytime", CancelText = "Don't Skip", OnClose = (sender) => { if ((sender as Confirm).DialogResult == Confirm.Result.OKAY) { FastForwardToDay = true; } } }); Gui.ShowModalPopup(SleepPrompt); } else if (!allAsleep) { if (SleepPrompt != null) { SleepPrompt.Close(); } Time.Speed = 100; FastForwardToDay = false; SleepPrompt = null; } #endif GamePerformance.Instance.StopTrackPerformance("All Asleep"); } // These things are updated even when the game is paused GamePerformance.Instance.StartTrackPerformance("Chunk Manager"); ChunkManager.Update(gameTime, Camera, GraphicsDevice); ChunkRenderer.Update(gameTime, Camera, GraphicsDevice); GamePerformance.Instance.StopTrackPerformance("Chunk Manager"); GamePerformance.Instance.StartTrackPerformance("Sound Manager"); SoundManager.Update(gameTime, Camera, Time); GamePerformance.Instance.StopTrackPerformance("Sound Manager"); GamePerformance.Instance.StartTrackPerformance("Weather"); Weather.Update(this.Time.CurrentDate, this); GamePerformance.Instance.StopTrackPerformance("Weather"); if (gameFile != null) { // Cleanup game file. gameFile = null; } }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); Storm.InitializeStatics(); BoundingBox box = chunks.Bounds; box.Expand(10.0f); if (GlobalTransform.Translation.X < box.Min.X || GlobalTransform.Translation.X > box.Max.X || GlobalTransform.Translation.Z < box.Min.Z || GlobalTransform.Translation.Z > box.Max.Z) { Die(); } bool generateRainDrop = MathFunctions.RandEvent(Raininess * 0.75f); if (generateRainDrop) { for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { RainDrops[i].IsAlive = true; if (RainDrops[i].Particle != null) { RainDrops[i].Particle.LifeRemaining = 60.0f; RainDrops[i].Particle.TimeAlive = 0.0f; } RainDrops[i].Pos = MathFunctions.RandVector3Box(BoundingBox.Expand(5)); RainDrops[i].Pos = new Vector3(RainDrops[i].Pos.X, BoundingBox.Min.Y - 1, RainDrops[i].Pos.Z); RainDrops[i].Vel = Vector3.Down * Storm.Properties[TypeofStorm].RainSpeed + Velocity; break; } } } bool generateLightning = LightningChance > 0.0f && MathFunctions.RandEvent((float)(LightningChance * 0.001f)); if (generateLightning) { var below = VoxelHelpers.FindFirstVoxelBelowIncludingWater(new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(new Vector3(Position.X, Math.Min(World.WorldSizeInVoxels.Y - 1, Position.Y), Position.Z)))); if (below.IsValid && !below.IsEmpty) { var above = VoxelHelpers.GetVoxelAbove(below); if (above.IsValid) { EntityFactory.CreateEntity <Fire>("Fire", above.GetBoundingBox().Center()); List <Vector3> lightningStrikes = new List <Vector3>(); List <Color> colors = new List <Color>(); var c = above.GetBoundingBox().Center(); for (float t = 0; t < 1.0f; t += 0.25f) { var p = c * t + Position * (1.0f - t); lightningStrikes.Add(p + MathFunctions.RandVector3Box(-5, 5, 0, 0.1f, -5, 5)); colors.Add(Color.White); } lightningStrikes.Add(c); colors.Add(Color.White); Drawer3D.DrawLineList(lightningStrikes, colors, 0.3f); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_rain_storm_alert, MathFunctions.Rand(0.001f, 0.05f), MathFunctions.Rand(0.5f, 1.0f)); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_trap_destroyed, c, false, 1.0f, MathFunctions.Rand(-0.5f, 0.5f)); World.ParticleManager.Trigger("explode", c, Color.White, 10); } } } Storm.StormProperties stormProperties = Storm.Properties[TypeofStorm]; var rainEmitter = World.ParticleManager.Effects[stormProperties.RainEffect]; var hitEmitter = World.ParticleManager.Effects[stormProperties.HitEffect]; for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { continue; } RainDrops[i].Pos += RainDrops[i].Vel * DwarfTime.Dt; if (stormProperties.RainRandom > 0) { RainDrops[i].Vel.X += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; RainDrops[i].Vel.Z += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; } if (RainDrops[i].Pos.Y < 0) { RainDrops[i].IsAlive = false; } if (!RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.LifeRemaining = -1; } else if (RainDrops[i].IsAlive && RainDrops[i].Particle == null) { RainDrops[i].Particle = rainEmitter.Emitters[0].CreateParticle(RainDrops[i].Pos, RainDrops[i].Vel, Color.White); } else if (RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.Position = RainDrops[i].Pos; RainDrops[i].Particle.Velocity = RainDrops[i].Vel; } var test = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(RainDrops[i].Pos)); if (!test.IsValid || (test.IsEmpty && test.LiquidLevel == 0)) { continue; } RainDrops[i].IsAlive = false; var hitBodies = World.EnumerateIntersectingObjects(new BoundingBox(RainDrops[i].Pos - Vector3.One, RainDrops[i].Pos + Vector3.One)); foreach (var body in hitBodies) { if (body.Parent != Manager.RootComponent) { continue; } var flames = body.GetRoot().GetComponent <Flammable>(); if (flames != null) { flames.Heat *= 0.25f; } var seeds = body.GetRoot().GetComponent <Seedling>(); if (seeds != null) { if (TypeofStorm == StormType.RainStorm) { seeds.GrowthTime += MathFunctions.Rand(1.0f, 12.0f); } else if (MathFunctions.RandEvent(0.01f)) { seeds.GetRoot().Die(); } } } hitEmitter.Trigger(1, RainDrops[i].Pos + Vector3.UnitY * 0.5f, Color.White); //if (!MathFunctions.RandEvent(0.1f)) continue; var above = test.IsEmpty ? test : VoxelHelpers.GetVoxelAbove(test); if (!above.IsValid || !above.IsEmpty) { continue; } if (TypeofStorm == StormType.RainStorm && (above.LiquidLevel < WaterManager.maxWaterLevel && (above.LiquidType == LiquidType.Water))) { above.LiquidLevel = (byte)Math.Min(WaterManager.maxWaterLevel, above.LiquidLevel + WaterManager.rainFallAmount); above.LiquidType = stormProperties.LiquidToCreate; } else if (TypeofStorm == StormType.SnowStorm && above.IsEmpty && above.LiquidLevel == 0) { if (test.GrassType == 0) { test.GrassType = Library.GetGrassType("snow").ID; test.GrassDecay = Library.GetGrassType("snow").InitialDecayValue; } else { var existingGrass = Library.GetGrassType((byte)test.GrassType); if (!String.IsNullOrEmpty(existingGrass.BecomeWhenSnowedOn)) { var newGrass = Library.GetGrassType(existingGrass.BecomeWhenSnowedOn); test.GrassType = newGrass.ID; test.GrassDecay = newGrass.InitialDecayValue; } } } } Matrix tf = LocalTransform; tf.Translation += Velocity * DwarfTime.Dt; LocalTransform = tf; }
public bool RemoveResources(List <ResourceAmount> resources, Vector3 position, bool createItems = true) { Dictionary <ResourceLibrary.ResourceType, ResourceAmount> amounts = new Dictionary <ResourceLibrary.ResourceType, ResourceAmount>(); foreach (ResourceAmount resource in resources) { if (!amounts.ContainsKey(resource.ResourceType)) { amounts.Add(resource.ResourceType, new ResourceAmount(resource)); } else { amounts[resource.ResourceType].NumResources += resource.NumResources; } } if (!HasResources(amounts.Values)) { return(false); } List <Stockpile> stockpilesCopy = new List <Stockpile>(Stockpiles.Where(s => resources.All(r => s.IsAllowed(r.ResourceType)))); stockpilesCopy.Sort((a, b) => CompareZones(a, b, position)); foreach (ResourceAmount resource in resources) { int count = 0; List <Vector3> positions = new List <Vector3>(); foreach (Stockpile stock in stockpilesCopy) { int num = stock.Resources.RemoveMaxResources(resource, resource.NumResources - count); stock.HandleBoxes(); if (stock.Boxes.Count > 0) { for (int i = 0; i < num; i++) { positions.Add(stock.Boxes[stock.Boxes.Count - 1].LocalTransform.Translation); } } count += num; if (count >= resource.NumResources) { break; } } if (createItems) { foreach (Vector3 vec in positions) { Body newEntity = EntityFactory.CreateEntity <Body>(resource.ResourceType + " Resource", vec + MathFunctions.RandVector3Cube() * 0.5f); TossMotion toss = new TossMotion(1.0f + MathFunctions.Rand(0.1f, 0.2f), 2.5f + MathFunctions.Rand(-0.5f, 0.5f), newEntity.LocalTransform, position); newEntity.GetRoot().GetComponent <Physics>().CollideMode = Physics.CollisionMode.None; newEntity.AnimationQueue.Add(toss); toss.OnComplete += () => toss_OnComplete(newEntity); } } } return(true); }
public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button) { if (Command.Contains("Build/")) { if (Library.CreateZone(Command.Substring(6), World).HasValue(out var zone)) { World.AddZone(zone); zone.CompleteRoomImmediately(refs); } } if (Command.Contains("Spawn/")) { string type = Command.Substring(6); foreach (var vox in refs.Where(vox => vox.IsValid)) { if (vox.IsEmpty) { var offset = Vector3.Zero; if (Library.GetResourceType(type).HasValue(out var craftItem)) { offset = craftItem.Placement_SpawnOffset; } var body = EntityFactory.CreateEntity <GameComponent>(type, vox.WorldPosition + new Vector3(0.5f, 0.0f, 0.5f) + offset); if (body != null) { body.PropogateTransforms(); if (craftItem != null) { if (craftItem.Placement_AddToOwnedPool) { World.PlayerFaction.OwnedObjects.Add(body); } if (craftItem.Placement_MarkDestructable) { body.Tags.Add("Deconstructable"); // Todo: Should not need to set tag every time item is created. Inherint? } } } } } } else if (Command.Contains("Resource/")) { string type = Command.Substring("Resource/".Length); foreach (var vox in refs.Where(vox => vox.IsValid)) { var body = World.ComponentManager.RootComponent.AddChild(new ResourceEntity(World.ComponentManager, new Resource(type), vox.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f))); body.PropogateTransforms(); } } else if (Command.Contains("Rail/")) { string type = Command.Substring("Rail/".Length); var junction = new Rail.JunctionPiece { RailPiece = type, Orientation = Rail.PieceOrientation.North, Offset = Point.Zero }; foreach (var vox in refs.Where(vox => vox.IsValid)) { if (vox.IsEmpty) { var entity = new Rail.RailEntity(World.ComponentManager, vox, junction); World.ComponentManager.RootComponent.AddChild(entity); } } } else if (Command.Contains("Grass/")) { var type = Library.GetGrassType(Command.Substring(6)); if (type != null) { foreach (var vox in refs.Where(v => v.IsValid)) { var v = vox; if (!vox.IsEmpty) { v.GrassType = type.ID; v.GrassDecay = type.InitialDecayValue; } } } } else if (Command.Contains("Decal/")) { var type = Library.GetDecalType(Command.Substring(6)); if (type != null) { foreach (var vox in refs.Where(v => v.IsValid)) { var v = vox; if (!vox.IsEmpty) { v.DecalType = type.ID; } } } } else if (Command.Contains("Disease")) { foreach (var creature in World.EnumerateIntersectingObjects(VoxelHelpers.GetVoxelBoundingBox(refs), CollisionType.Both).OfType <Creature>()) { creature.Stats.AcquireDisease(DiseaseLibrary.GetRandomDisease()); } } else { foreach (var vox in refs.Where(vox => vox.IsValid)) { if (Command.Contains("Place/")) { string type = Command.Substring(6); var v = vox; if (Library.GetVoxelType(type).HasValue(out VoxelType vType)) { v.Type = vType; } v.QuickSetLiquid(LiquidType.None, 0); if (type == "Magic") { World.ComponentManager.RootComponent.AddChild( new DestroyOnTimer(World.ComponentManager, World.ChunkManager, vox) { DestroyTimer = new Timer(5.0f + MathFunctions.Rand(-0.5f, 0.5f), true) }); } } else { switch (Command) { case "Delete Block": { var v = vox; World.OnVoxelDestroyed(vox); v.Type = Library.EmptyVoxelType; v.QuickSetLiquid(LiquidType.None, 0); } break; case "Nuke Column": { for (var y = 1; y < World.WorldSizeInVoxels.Y; ++y) { var v = World.ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(vox.Coordinate.X, y, vox.Coordinate.Z)); v.Type = Library.EmptyVoxelType; v.QuickSetLiquid(LiquidType.None, 0); } } break; case "Kill Block": foreach (var selected in refs) { if (!selected.IsEmpty) { VoxelHelpers.KillVoxel(World, selected); } } break; case "Fill Water": { if (vox.IsEmpty) { var v = vox; v.QuickSetLiquid(LiquidType.Water, WaterManager.maxWaterLevel); } } break; case "Fill Lava": { if (vox.IsEmpty) { var v = vox; v.QuickSetLiquid(LiquidType.Lava, WaterManager.maxWaterLevel); } } break; case "Fire": { foreach (var flam2 in World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Flammable>()) { flam2.Heat = flam2.Flashpoint + 1; } } break; default: break; } } } } }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); if (Active) { DeathTimer.Update(gameTime); switch (_state) { case State.Initializing: if (PrepThread != null) { PrepThread.Abort(); } PrepThread = new Thread(PrepareForExplosion) { IsBackground = true }; _state = State.Prep; PrepThread.Start(); foreach (GameComponent body in Manager.World.EnumerateIntersectingObjects( new BoundingBox(LocalPosition - new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f), LocalPosition + new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f)), CollisionType.Both)) { var distance = (body.Position - LocalPosition).Length(); if (distance < (VoxelRadius * 2.0f)) { var creature = body.EnumerateAll().OfType <CreatureAI>().FirstOrDefault(); if (creature != null) { creature.ChangeTask(new FleeEntityTask(this, VoxelRadius * 2)); } } } break; case State.Prep: if (PrepThread == null) // Must have been saved mid-prep. { _state = State.Initializing; } break; case State.Ready: if (OrderedExplosionList == null) // Just a failsafe. { throw new InvalidOperationException(); } float timeLeft = (float)(DeathTimer.TargetTimeSeconds - DeathTimer.CurrentTimeSeconds); float pulseRate = 15 - 2 * timeLeft; float pulse = (float)Math.Sin(timeLeft * pulseRate); this.SetVertexColorRecursive(new Color(1.0f, 1.0f - pulse * pulse, 1.0f - pulse * pulse, 1.0f)); if (DeathTimer.HasTriggered) { _state = State.Exploding; Manager.World.ParticleManager.Effects["explode"].Trigger(10, Position, Color.White); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_trap_destroyed, 0.5f); foreach (GameComponent body in Manager.World.EnumerateIntersectingObjects( new BoundingBox(LocalPosition - new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f), LocalPosition + new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f)), CollisionType.Both)) { var distance = (body.Position - LocalPosition).Length(); if (distance <= (VoxelRadius * 2.0f)) { var health = body.EnumerateAll().OfType <Health>().FirstOrDefault(); if (health != null) { health.Damage(DamageAmount * (1.0f - (distance / (VoxelRadius * 2.0f)))); // Linear fall off on damage. } } } } break; case State.Exploding: SetFlagRecursive(Flag.Visible, false); if (OrderedExplosionList == null) { throw new InvalidOperationException(); } var voxelsExploded = 0; while (true) { if (voxelsExploded >= VoxelsPerTick) { break; } if (ExplosionProgress >= OrderedExplosionList.Count) { GetRoot().Delete(); _state = State.Done; foreach (var vox in OrderedExplosionList) { if (!vox.IsValid) { continue; } var under = VoxelHelpers.GetVoxelBelow(vox); if (under.IsValid && !under.IsEmpty && MathFunctions.RandEvent(0.5f)) { EntityFactory.CreateEntity <Fire>("Fire", vox.GetBoundingBox().Center()); } } break; } var nextVoxel = OrderedExplosionList[ExplosionProgress]; ExplosionProgress += 1; if (nextVoxel.IsValid) { if (!nextVoxel.Type.IsInvincible && !nextVoxel.IsEmpty) { voxelsExploded += 1; nextVoxel.Type = Library.EmptyVoxelType; Manager.World.ParticleManager.Effects["explode"].Trigger(1, nextVoxel.Coordinate.ToVector3() + new Vector3(0.5f, 0.5f, 0.5f), Color.White); Manager.World.ParticleManager.Effects["dirt_particle"].Trigger(3, nextVoxel.Coordinate.ToVector3() + new Vector3(0.5f, 0.5f, 0.5f), Color.White); Manager.World.OnVoxelDestroyed(nextVoxel); } } } break; case State.Done: default: if (PrepThread != null) { PrepThread.Abort(); } break; } } }
private void LoadFromFile() { SetLoadingMessage("Creating Sky..."); Renderer.Sky = new SkyRenderer(); #region Reading game file SetLoadingMessage("Loading " + Overworld.InstanceSettings.ExistingFile); var gameFile = SaveGame.LoadMetaFromDirectory(Overworld.InstanceSettings.ExistingFile); if (gameFile == null) { throw new InvalidOperationException("Game File does not exist."); } if (gameFile.Metadata.Version != Program.Version && !Program.CompatibleVersions.Contains(gameFile.Metadata.Version)) { throw new InvalidOperationException(String.Format("Game file is from version {0}. Compatible versions are {1}.", gameFile.Metadata.Version, TextGenerator.GetListString(Program.CompatibleVersions))); } Renderer.Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Renderer.PersistentSettings = gameFile.Metadata.RendererSettings; Time = gameFile.Metadata.Time; WorldSizeInChunks = new Point3(Overworld.InstanceSettings.Cell.Bounds.Width, Overworld.zLevels, Overworld.InstanceSettings.Cell.Bounds.Height); #endregion #region Initialize static data bool actionComplete = false; Game.DoLazyAction(new Action(() => { Renderer.InstanceRenderer = new InstanceRenderer(); Renderer.bloom = new BloomComponent(Game) { Settings = BloomSettings.PresetSettings[5] }; Renderer.bloom.Initialize(); SoundManager.Content = Content; if (PlanService != null) { PlanService.Restart(); } MonsterSpawner = new MonsterSpawner(this); EntityFactory.Initialize(this); }), () => { actionComplete = true; return(true); }); while (!actionComplete) { Thread.Sleep(10); } #endregion PlanService = new PlanService(); SetLoadingMessage("Creating Liquids ..."); #region liquids Renderer.WaterRenderer = new WaterRenderer(GraphicsDevice); #endregion #region Load Components // Create updateable systems. foreach (var updateSystemFactory in AssetManager.EnumerateModHooks(typeof(UpdateSystemFactoryAttribute), typeof(EngineModule), new Type[] { typeof(WorldManager) })) { UpdateSystems.Add(updateSystemFactory.Invoke(null, new Object[] { this }) as EngineModule); } ChunkManager = new ChunkManager(Content, this); Splasher = new Splasher(ChunkManager); Renderer.ChunkRenderer = new ChunkRenderer(ChunkManager); SetLoadingMessage("Loading Terrain..."); ChunkManager.LoadChunks(gameFile.LoadChunks(), ChunkManager); SetLoadingMessage("Loading Entities..."); gameFile.LoadPlayData(Overworld.InstanceSettings.ExistingFile, this); PersistentData = gameFile.PlayData.PersistentData; Renderer.Camera = gameFile.PlayData.Camera; if (gameFile.PlayData.Stats != null) { Stats = gameFile.PlayData.Stats; } ComponentManager = new ComponentManager(gameFile.PlayData.Components, this); foreach (var component in gameFile.PlayData.Components.SaveableComponents) { if (!ComponentManager.HasComponent(component.GlobalID) && ComponentManager.HasComponent(component.Parent.GlobalID)) { // Logically impossible. throw new InvalidOperationException("Component exists in save data but not in manager."); } } ConversationMemory = gameFile.PlayData.ConversationMemory; Factions = gameFile.PlayData.Factions; ComponentManager.World = this; Renderer.Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; PlayerFaction = Factions.Factions["Player"]; EventScheduler = new Events.Scheduler(); TutorialManager = new Tutorial.TutorialManager(); TutorialManager.SetFromSaveData(gameFile.PlayData.TutorialSaveData); Renderer.Camera.World = this; #endregion SetLoadingMessage("Creating Particles ..."); Game.DoLazyAction(new Action(() => ParticleManager = new ParticleManager(ComponentManager))); SetLoadingMessage("Creating GameMaster ..."); TaskManager = new TaskManager(); TaskManager.World = this; Time.NewDay += (time) => PayEmployees(); DwarfGame.LogSentryBreadcrumb("Loading", "Started new game with an existing file."); if (gameFile.PlayData.Tasks != null) { TaskManager = gameFile.PlayData.Tasks; TaskManager.World = this; } if (PlayerFaction.Economy.Information == null) { throw new InvalidProgramException(); } if (MathFunctions.RandEvent(0.01f)) { SetLoadingMessage("Reticulating Splines..."); } ChunkManager.StartThreads(); SetLoadingMessage("Presimulating ..."); ShowingWorld = false; OnLoadedEvent(); Thread.Sleep(1000); ShowingWorld = true; SetLoadingMessage("Complete."); // GameFile is no longer needed. gameFile = null; LoadStatus = LoadingStatus.Success; }
private void CreateNewWorld() { SetLoadingMessage("Creating Sky..."); Renderer.Sky = new SkyRenderer(); #region Initialize static data bool actionComplete = false; Game.DoLazyAction(new Action(() => { Renderer.InstanceRenderer = new InstanceRenderer(); Renderer.bloom = new BloomComponent(Game) { Settings = BloomSettings.PresetSettings[5] }; Renderer.bloom.Initialize(); SoundManager.Content = Content; if (PlanService != null) { PlanService.Restart(); } MonsterSpawner = new MonsterSpawner(this); EntityFactory.Initialize(this); }), () => { actionComplete = true; return(true); }); while (!actionComplete) { Thread.Sleep(10); } #endregion SetLoadingMessage("Creating Planner ..."); PlanService = new PlanService(); SetLoadingMessage("Creating Liquids ..."); #region liquids Renderer.WaterRenderer = new WaterRenderer(GraphicsDevice); #endregion #region Load Components // Create updateable systems. foreach (var updateSystemFactory in AssetManager.EnumerateModHooks(typeof(UpdateSystemFactoryAttribute), typeof(EngineModule), new Type[] { typeof(WorldManager) })) { UpdateSystems.Add(updateSystemFactory.Invoke(null, new Object[] { this }) as EngineModule); } Time = new WorldTime(); Renderer.Camera = new OrbitCamera(this, // Todo: Is setting the camera position and target redundant here? new Vector3(VoxelConstants.ChunkSizeX, WorldSizeInVoxels.Y - 1.0f, VoxelConstants.ChunkSizeZ), new Vector3(VoxelConstants.ChunkSizeX, WorldSizeInVoxels.Y - 1.0f, VoxelConstants.ChunkSizeZ) + Vector3.Up * 10.0f + Vector3.Backward * 10, MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.1f, GameSettings.Default.VertexCullDistance); PersistentData = new PersistentWorldData(); ChunkManager = new ChunkManager(Content, this); Splasher = new Splasher(ChunkManager); Renderer.ChunkRenderer = new ChunkRenderer(ChunkManager); Renderer.Camera.Position = new Vector3(0, 10, 0) + new Vector3(WorldSizeInChunks.X * VoxelConstants.ChunkSizeX, 0, WorldSizeInChunks.Z * VoxelConstants.ChunkSizeZ) * 0.5f; Renderer.Camera.Target = new Vector3(0, 10, 1) + new Vector3(WorldSizeInChunks.X * VoxelConstants.ChunkSizeX, 0, WorldSizeInChunks.Z * VoxelConstants.ChunkSizeZ) * 0.5f; ComponentManager = new ComponentManager(this); ComponentManager.SetRootComponent(new GameComponent(ComponentManager, "root", Matrix.Identity, Vector3.Zero, Vector3.Zero)); #region Prepare Factions Factions = new FactionSet(); //Factions.Initialize(this, Settings.Company); foreach (var faction in Overworld.Natives) { Factions.AddFaction(new Faction(this, faction)); } Point playerOrigin = new Point((int)(Overworld.InstanceSettings.Origin.X), (int)(Overworld.InstanceSettings.Origin.Y)); PlayerFaction = Factions.Factions["Player"]; PlayerFaction.Economy = new Company(PlayerFaction, 300.0m, Overworld.Company); #endregion EventScheduler = new Events.Scheduler(); TutorialManager = new Tutorial.TutorialManager(); TutorialManager.TutorialEnabled = !GameSettings.Default.TutorialDisabledGlobally; Tutorial("new game start"); foreach (var item in Library.EnumerateCraftables()) { if (!String.IsNullOrEmpty(item.Tutorial)) { TutorialManager.AddTutorial(item.Name, item.Tutorial, item.Icon); } } Renderer.Camera.World = this; //Drawer3D.Camera = Camera; #endregion SetLoadingMessage("Creating Particles ..."); Game.DoLazyAction(new Action(() => ParticleManager = new ParticleManager(ComponentManager))); SetLoadingMessage("Creating GameMaster ..."); TaskManager = new TaskManager(); TaskManager.World = this; Time.NewDay += (time) => PayEmployees(); var generatorSettings = new Generation.ChunkGeneratorSettings(MathFunctions.Random.Next(), 0.02f, Overworld) { WorldSizeInChunks = WorldSizeInChunks, SetLoadingMessage = SetLoadingMessage, World = this }; SetLoadingMessage("Generating Chunks..."); Generation.Generator.Generate(Overworld.InstanceSettings.Cell.Bounds, ChunkManager, this, generatorSettings, SetLoadingMessage); CreateInitialEmbarkment(generatorSettings); ChunkManager.NeedsMinimapUpdate = true; ChunkManager.RecalculateBounds(); if (PlayerFaction.Economy.Information == null) { throw new InvalidProgramException(); } if (MathFunctions.RandEvent(0.01f)) { SetLoadingMessage("Reticulating Splines..."); } ChunkManager.StartThreads(); SetLoadingMessage("Presimulating ..."); ShowingWorld = false; OnLoadedEvent(); Thread.Sleep(1000); ShowingWorld = true; SetLoadingMessage("Complete."); LoadStatus = LoadingStatus.Success; }
public void GenerateCaves(VoxelChunk chunk, WorldManager world) { 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 != null && 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.GrassLayer.VoxelType).ID; chunk.Data.Health[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassLayer.VoxelType).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.GrassLayer.VoxelType) { vUnder.Type = VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType); 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.GetEntityRootComponent().SetActiveRecursive(false); entity.GetEntityRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener( world.ComponentManager, entity, world.ChunkManager, vUnder); } } } } foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(MathFunctions.Random.NextDouble() < animal.SpawnProbability)) { continue; } var entity = EntityFactory.CreateEntity <GameComponent>(animal.Name, chunk.Origin + new Vector3(x, y, z) + Vector3.Up * 1.0f); if (GameSettings.Default.FogofWar) { entity.GetEntityRootComponent().SetActiveRecursive(false); entity.GetEntityRootComponent().SetVisibleRecursive(false); ExploredListener listener = new ExploredListener (world.ComponentManager, entity, world.ChunkManager, chunk.MakeVoxel(x, y, z)); } 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) / 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.GrassLayer.VoxelType) { vUnder.Type = VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType); 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 static List <Body> GenerateRoomComponentsTemplate(RoomData roomData, List <Voxel> voxels, ComponentManager componentManager, Microsoft.Xna.Framework.Content.ContentManager content, GraphicsDevice graphics) { List <Body> components = new List <Body>(); RoomTile[,] currentTiles = RoomTemplate.CreateFromRoom(voxels, componentManager.World.ChunkManager); float[,] rotations = new float[currentTiles.GetLength(0), currentTiles.GetLength(1)]; foreach (RoomTemplate myTemp in roomData.Templates) { RoomTemplate template = new RoomTemplate(myTemp) { Rotation = 0 }; for (int r = -2; r < currentTiles.GetLength(0) + 1; r++) { for (int c = -2; c < currentTiles.GetLength(1) + 1; c++) { for (int rotation = 0; rotation < 5; rotation++) { template.PlaceTemplate(ref currentTiles, ref rotations, r, c); template.RotateClockwise(1); } } } } BoundingBox box = MathFunctions.GetBoundingBox(voxels); int thingsMade = 0; for (int r = 0; r < currentTiles.GetLength(0); r++) { for (int c = 0; c < currentTiles.GetLength(1); c++) { RoomTile tile = currentTiles[r, c]; Body createdComponent = null; Vector3 noise = VertexNoise.GetNoiseVectorFromRepeatingTexture(box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1)); switch (tile) { case RoomTile.Barrel: createdComponent = EntityFactory.CreateEntity <Body>("Barrel", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Wheat: createdComponent = EntityFactory.CreateEntity <Body>("Wheat", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Mushroom: createdComponent = EntityFactory.CreateEntity <Body>("Mushroom", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Table: createdComponent = EntityFactory.CreateEntity <Body>("Table", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Stove: createdComponent = EntityFactory.CreateEntity <Body>("Stove", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.KitchenTable: createdComponent = EntityFactory.CreateEntity <Body>("Kitchen Table", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Lamp: createdComponent = EntityFactory.CreateEntity <Body>("Lamp", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Flag: createdComponent = EntityFactory.CreateEntity <Body>("Flag", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Chair: createdComponent = EntityFactory.CreateEntity <Body>("Chair", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Books: createdComponent = EntityFactory.CreateEntity <Body>(MathFunctions.RandEvent(0.5f) ? "Books" : "Potions", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Anvil: createdComponent = EntityFactory.CreateEntity <Body>("Anvil", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Forge: createdComponent = EntityFactory.CreateEntity <Body>("Forge", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Target: createdComponent = EntityFactory.CreateEntity <Body>("Target", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Strawman: createdComponent = EntityFactory.CreateEntity <Body>("Strawman", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.BookShelf: createdComponent = EntityFactory.CreateEntity <Body>("Bookshelf", box.Min + new Vector3(r - 1 + 0.5f, 1.5f, c - 1 + 0.5f) + noise); thingsMade++; break; case RoomTile.Pillow: for (int dx = -1; dx < 2; dx++) { for (int dy = -1; dy < 2; dy++) { if (Math.Abs(dx) + Math.Abs(dy) != 1 || r + dx < 0 || r + dx >= currentTiles.GetLength(0) || c + dy < 0 || c + dy >= currentTiles.GetLength(1)) { continue; } if (currentTiles[r + dx, c + dy] != RoomTile.Bed) { continue; } createdComponent = EntityFactory.CreateEntity <Body>("Bed", box.Min + new Vector3(r - 1 + 0.5f, 1.5f, c - 1 + 0.5f) + noise); break; } } thingsMade++; break; default: break; } if (createdComponent == null) { continue; } createdComponent.LocalTransform = Matrix.CreateRotationY(-(rotations[r, c] + (float)Math.PI * 0.5f)) * createdComponent.LocalTransform; components.Add(createdComponent); } } return(components); }
public static void Add(Resource resource) { Resources[resource.ResourceName] = resource; EntityFactory.RegisterEntity(resource.ResourceName + " Resource", (position, data) => new ResourceEntity(EntityFactory.World.ComponentManager, resource.Type, position)); }
public static void GenerateRoomComponentsTemplate(Room room, ComponentManager componentManager, Microsoft.Xna.Framework.Content.ContentManager content, GraphicsDevice graphics) { RoomTile[,] currentTiles = RoomTemplate.CreateFromRoom(room, room.Chunks); float[,] rotations = new float[currentTiles.GetLength(0), currentTiles.GetLength(1)]; foreach (RoomTemplate template in room.RoomData.Templates) { for (int r = -2; r < currentTiles.GetLength(0) + 1; r++) { for (int c = -2; c < currentTiles.GetLength(1) + 1; c++) { for (int rotation = 0; rotation < 5; rotation++) { if (MathFunctions.RandEvent(template.Probability)) { template.PlaceTemplate(ref currentTiles, ref rotations, r, c); template.RotateClockwise(1); } } } } } BoundingBox box = room.GetBoundingBox(); int thingsMade = 0; for (int r = 0; r < currentTiles.GetLength(0); r++) { for (int c = 0; c < currentTiles.GetLength(1); c++) { RoomTile tile = currentTiles[r, c]; Body createdComponent = null; Vector3 noise = VertexNoise.GetNoiseVectorFromRepeatingTexture(box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1)); switch (tile) { case RoomTile.Barrel: createdComponent = EntityFactory.CreateEntity <Body>("Barrel", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Wheat: createdComponent = EntityFactory.CreateEntity <Body>("Wheat", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Mushroom: createdComponent = EntityFactory.CreateEntity <Body>("Mushroom", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Table: createdComponent = EntityFactory.CreateEntity <Body>("Table", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Stove: createdComponent = EntityFactory.CreateEntity <Body>("Stove", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.KitchenTable: createdComponent = EntityFactory.CreateEntity <Body>("KitchenTable", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Lamp: createdComponent = EntityFactory.CreateEntity <Body>("Lamp", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Flag: createdComponent = EntityFactory.CreateEntity <Body>("Flag", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Chair: createdComponent = EntityFactory.CreateEntity <Body>("Chair", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.BookTable: createdComponent = EntityFactory.CreateEntity <Body>(MathFunctions.RandEvent(0.5f) ? "BookTable" : "PotionTable", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Anvil: createdComponent = EntityFactory.CreateEntity <Body>("Anvil", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Forge: createdComponent = EntityFactory.CreateEntity <Body>("Forge", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Target: createdComponent = EntityFactory.CreateEntity <Body>("Target", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.Strawman: createdComponent = EntityFactory.CreateEntity <Body>("Strawman", box.Min + new Vector3(r + 0.5f - 1, 1.5f, c + 0.5f - 1) + noise); thingsMade++; break; case RoomTile.BookShelf: createdComponent = EntityFactory.CreateEntity <Body>("Bookshelf", box.Min + new Vector3(r - 1 + 0.5f, 1.5f, c - 1 + 0.5f) + noise); thingsMade++; break; case RoomTile.Pillow: for (int dx = -1; dx < 2; dx++) { for (int dy = -1; dy < 2; dy++) { if (Math.Abs(dx) + Math.Abs(dy) != 1 || r + dx < 0 || r + dx >= currentTiles.GetLength(0) || c + dy < 0 || c + dy >= currentTiles.GetLength(1)) { continue; } if (currentTiles[r + dx, c + dy] != RoomTile.Bed) { continue; } createdComponent = EntityFactory.CreateEntity <Body>("Bed", box.Min + new Vector3(r - 1 + 0.5f, 1.5f, c - 1 + 0.5f) + noise); break; } } thingsMade++; break; default: break; } if (createdComponent != null) { createdComponent.LocalTransform = Matrix.CreateRotationY(-(rotations[r, c] + (float)Math.PI * 0.5f)) * createdComponent.LocalTransform; Vector3 endPos = createdComponent.LocalTransform.Translation; Matrix offsetTransform = createdComponent.LocalTransform; offsetTransform.Translation += new Vector3(0, -1, 0); createdComponent.LocalTransform = offsetTransform; createdComponent.AnimationQueue.Add(new EaseMotion(0.8f, offsetTransform, endPos)); room.AddBody(createdComponent); PlayState.ParticleManager.Trigger("puff", endPos + new Vector3(0.5f, 0.5f, 0.5f), Color.White, 10); } } } }
public override Body CreatePlant(Vector3 position) { return(EntityFactory.CreateEntity <Body>("Wheat", position)); }
private void LoadThreaded() { // Ensure we're using the invariant culture. Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; LoadStatus = LoadingStatus.Loading; SetLoadingMessage("Initializing ..."); while (GraphicsDevice == null) { Thread.Sleep(100); } Thread.Sleep(1000); #if CREATE_CRASH_LOGS try #endif #if !DEBUG try { #endif bool fileExists = !string.IsNullOrEmpty(ExistingFile); SetLoadingMessage("Creating Sky..."); Sky = new SkyRenderer( AssetManager.GetContentTexture(ContentPaths.Sky.moon), AssetManager.GetContentTexture(ContentPaths.Sky.sun), Content.Load <TextureCube>(AssetManager.ResolveContentPath(ContentPaths.Sky.day_sky)), Content.Load <TextureCube>(AssetManager.ResolveContentPath(ContentPaths.Sky.night_sky)), AssetManager.GetContentTexture(ContentPaths.Gradients.skygradient), Content.Load <Model>(AssetManager.ResolveContentPath(ContentPaths.Models.sphereLowPoly)), Content.Load <Effect>(ContentPaths.Shaders.SkySphere), Content.Load <Effect>(ContentPaths.Shaders.Background)); #region Reading game file if (fileExists) { SetLoadingMessage("Loading " + ExistingFile); gameFile = SaveGame.CreateFromDirectory(ExistingFile); if (gameFile == null) { throw new InvalidOperationException("Game File does not exist."); } // Todo: REMOVE THIS WHEN THE NEW SAVE SYSTEM IS COMPLETE. if (gameFile.Metadata.Version != Program.Version && !Program.CompatibleVersions.Contains(gameFile.Metadata.Version)) { throw new InvalidOperationException(String.Format("Game file is from version {0}. Compatible versions are {1}.", gameFile.Metadata.Version, TextGenerator.GetListString(Program.CompatibleVersions))); } Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; WorldOrigin = gameFile.Metadata.WorldOrigin; WorldScale = gameFile.Metadata.WorldScale; WorldSize = gameFile.Metadata.NumChunks; GameID = gameFile.Metadata.GameID; if (gameFile.Metadata.OverworldFile != null && gameFile.Metadata.OverworldFile != "flat") { SetLoadingMessage("Loading world " + gameFile.Metadata.OverworldFile); Overworld.Name = gameFile.Metadata.OverworldFile; DirectoryInfo worldDirectory = Directory.CreateDirectory(DwarfGame.GetWorldDirectory() + ProgramData.DirChar + Overworld.Name); var overWorldFile = new NewOverworldFile(worldDirectory.FullName); Overworld.Map = overWorldFile.Data.Data; Overworld.Name = overWorldFile.Data.Name; } else { SetLoadingMessage("Generating flat world.."); Overworld.CreateUniformLand(GraphicsDevice); } } #endregion #region Initialize static data { Vector3 origin = new Vector3(0, 0, 0); Vector3 extents = new Vector3(1500, 1500, 1500); OctTree = new OctTreeNode(origin - extents, origin + extents); PrimitiveLibrary.Initialize(GraphicsDevice, Content); InstanceRenderer = new InstanceRenderer(GraphicsDevice, Content); Color[] white = new Color[1]; white[0] = Color.White; pixel = new Texture2D(GraphicsDevice, 1, 1); pixel.SetData(white); Tilesheet = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_tiles); AspectRatio = GraphicsDevice.Viewport.AspectRatio; DefaultShader = new Shader(Content.Load <Effect>(ContentPaths.Shaders.TexturedShaders), true); DefaultShader.ScreenWidth = GraphicsDevice.Viewport.Width; DefaultShader.ScreenHeight = GraphicsDevice.Viewport.Height; CraftLibrary.InitializeDefaultLibrary(); PotionLibrary.Initialize(); VoxelLibrary.InitializeDefaultLibrary(GraphicsDevice); GrassLibrary.InitializeDefaultLibrary(); DecalLibrary.InitializeDefaultLibrary(); bloom = new BloomComponent(Game) { Settings = BloomSettings.PresetSettings[5] }; bloom.Initialize(); fxaa = new FXAA(); fxaa.Initialize(); SoundManager.Content = Content; if (PlanService != null) { PlanService.Restart(); } JobLibrary.Initialize(); MonsterSpawner = new MonsterSpawner(this); EntityFactory.Initialize(this); } #endregion SetLoadingMessage("Creating Planner ..."); PlanService = new PlanService(); SetLoadingMessage("Creating Shadows..."); Shadows = new ShadowRenderer(GraphicsDevice, 1024, 1024); SetLoadingMessage("Creating Liquids ..."); #region liquids WaterRenderer = new WaterRenderer(GraphicsDevice); #endregion SetLoadingMessage("Generating Initial Terrain Chunks ..."); if (!fileExists) { GameID = MathFunctions.Random.Next(0, 1024); } ChunkGenerator = new ChunkGenerator(VoxelLibrary, Seed, 0.02f) { SeaLevel = SeaLevel }; #region Load Components if (fileExists) { ChunkManager = new ChunkManager(Content, this, ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z); Splasher = new Splasher(ChunkManager); ChunkRenderer = new ChunkRenderer(ChunkManager.ChunkData); SetLoadingMessage("Loading Terrain..."); gameFile.ReadChunks(ExistingFile); ChunkManager.ChunkData.LoadFromFile(ChunkManager, gameFile, SetLoadingMessage); SetLoadingMessage("Loading Entities..."); gameFile.LoadPlayData(ExistingFile, this); Camera = gameFile.PlayData.Camera; DesignationDrawer = gameFile.PlayData.Designations; Vector3 origin = new Vector3(WorldOrigin.X, 0, WorldOrigin.Y); Vector3 extents = new Vector3(1500, 1500, 1500); if (gameFile.PlayData.Resources != null) { foreach (var resource in gameFile.PlayData.Resources) { if (!ResourceLibrary.Resources.ContainsKey(resource.Key)) { ResourceLibrary.Add(resource.Value); } } } ComponentManager = new ComponentManager(gameFile.PlayData.Components, this); foreach (var component in gameFile.PlayData.Components.SaveableComponents) { if (!ComponentManager.HasComponent(component.GlobalID) && ComponentManager.HasComponent(component.Parent.GlobalID)) { // Logically impossible. throw new InvalidOperationException("Component exists in save data but not in manager."); } } ConversationMemory = gameFile.PlayData.ConversationMemory; Factions = gameFile.PlayData.Factions; ComponentManager.World = this; Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; WorldOrigin = gameFile.Metadata.WorldOrigin; WorldScale = gameFile.Metadata.WorldScale; // Restore native factions from deserialized data. Natives = new List <Faction>(); foreach (Faction faction in Factions.Factions.Values) { if (faction.Race.IsNative && faction.Race.IsIntelligent && !faction.IsRaceFaction) { Natives.Add(faction); } } Diplomacy = gameFile.PlayData.Diplomacy; GoalManager = new Goals.GoalManager(); GoalManager.Initialize(gameFile.PlayData.Goals); TutorialManager = new Tutorial.TutorialManager(); TutorialManager.SetFromSaveData(gameFile.PlayData.TutorialSaveData); } else { Time = new WorldTime(); Camera = new OrbitCamera(this, new Vector3(VoxelConstants.ChunkSizeX, VoxelConstants.ChunkSizeY - 1.0f, VoxelConstants.ChunkSizeZ), new Vector3(VoxelConstants.ChunkSizeY, VoxelConstants.ChunkSizeY - 1.0f, VoxelConstants.ChunkSizeZ) + Vector3.Up * 10.0f + Vector3.Backward * 10, MathHelper.PiOver4, AspectRatio, 0.1f, GameSettings.Default.VertexCullDistance); ChunkManager = new ChunkManager(Content, this, ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z); Splasher = new Splasher(ChunkManager); ChunkRenderer = new ChunkRenderer(ChunkManager.ChunkData); Camera.Position = new Vector3(0, 10, 0) + new Vector3(WorldSize.X * VoxelConstants.ChunkSizeX, 0, WorldSize.Z * VoxelConstants.ChunkSizeZ) * 0.5f; Camera.Target = new Vector3(0, 10, 1) + new Vector3(WorldSize.X * VoxelConstants.ChunkSizeX, 0, WorldSize.Z * VoxelConstants.ChunkSizeZ) * 0.5f; // If there's no file, we have to initialize the first chunk coordinate if (gameFile == null) { ChunkManager.GenerateInitialChunks( new GlobalChunkCoordinate(0, 0, 0), SetLoadingMessage); } ComponentManager = new ComponentManager(this); ComponentManager.SetRootComponent(new Body(ComponentManager, "root", Matrix.Identity, Vector3.Zero, Vector3.Zero)); if (Natives == null) // Todo: Always true?? { FactionLibrary library = new FactionLibrary(); library.Initialize(this, CompanyMakerState.CompanyInformation); Natives = new List <Faction>(); for (int i = 0; i < 10; i++) { Natives.Add(library.GenerateFaction(this, i, 10)); } } #region Prepare Factions foreach (Faction faction in Natives) { faction.World = this; if (faction.RoomBuilder == null) { faction.RoomBuilder = new RoomBuilder(faction, this); } } Factions = new FactionLibrary(); if (Natives != null && Natives.Count > 0) { Factions.AddFactions(this, Natives); } Factions.Initialize(this, CompanyMakerState.CompanyInformation); Point playerOrigin = new Point((int)(WorldOrigin.X), (int)(WorldOrigin.Y)); Factions.Factions["Player"].Center = playerOrigin; Factions.Factions["The Motherland"].Center = new Point(playerOrigin.X + 50, playerOrigin.Y + 50); #endregion Diplomacy = new Diplomacy(this); Diplomacy.Initialize(Time.CurrentDate); // Initialize goal manager here. GoalManager = new Goals.GoalManager(); GoalManager.Initialize(new List <Goals.Goal>()); TutorialManager = new Tutorial.TutorialManager(); TutorialManager.TutorialEnabled = !GameSettings.Default.TutorialDisabledGlobally; Tutorial("new game start"); } Camera.World = this; //Drawer3D.Camera = Camera; #endregion SetLoadingMessage("Creating Particles ..."); ParticleManager = new ParticleManager(GraphicsDevice, ComponentManager); SetLoadingMessage("Creating GameMaster ..."); Master = new GameMaster(Factions.Factions["Player"], Game, ComponentManager, ChunkManager, Camera, GraphicsDevice); if (gameFile != null) { if (gameFile.PlayData.Spells != null) { Master.Spells = gameFile.PlayData.Spells; } if (gameFile.PlayData.Tasks != null) { Master.TaskManager = gameFile.PlayData.Tasks; Master.TaskManager.Faction = Master.Faction; } if (gameFile.PlayData.InitialEmbark != null) { InitialEmbark = gameFile.PlayData.InitialEmbark; } ChunkManager.World.Master.SetMaxViewingLevel(gameFile.Metadata.Slice > 0 ? gameFile.Metadata.Slice : ChunkManager.World.Master.MaxViewingLevel); } if (Master.Faction.Economy.Company.Information == null) { Master.Faction.Economy.Company.Information = new CompanyInformation(); } CreateInitialEmbarkment(); foreach (var chunk in ChunkManager.ChunkData.ChunkMap) { chunk.CalculateInitialSunlight(); } VoxelHelpers.InitialReveal(ChunkManager, ChunkManager.ChunkData, new VoxelHandle( ChunkManager.ChunkData.GetChunkEnumerator().FirstOrDefault(), new LocalVoxelCoordinate(0, VoxelConstants.ChunkSizeY - 1, 0))); foreach (var chunk in ChunkManager.ChunkData.ChunkMap) { ChunkManager.InvalidateChunk(chunk); } ChunkManager.StartThreads(); SetLoadingMessage("Presimulating ..."); ShowingWorld = false; OnLoadedEvent(); Thread.Sleep(1000); ShowingWorld = true; SetLoadingMessage("Complete."); // GameFile is no longer needed. gameFile = null; LoadStatus = LoadingStatus.Success; #if !DEBUG } catch (Exception exception) { Game.CaptureException(exception); LoadingException = exception; LoadStatus = LoadingStatus.Failure; } #endif }