Beispiel #1
0
        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());
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
 public override Body CreatePlant(Vector3 position)
 {
     return((Body)EntityFactory.CreateEntity <Body>("Mushroom", position));
 }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        /// <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;
            }
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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;
                        }
                    }
                }
            }
        }
Beispiel #9
0
        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;
                }
            }
        }
Beispiel #10
0
        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;
        }
Beispiel #11
0
        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;
        }
Beispiel #12
0
        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;
                            }
                        }
                    }
                }
            }
        }
Beispiel #13
0
        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;
            }
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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));
        }
Beispiel #16
0
        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);
                    }
                }
            }
        }
Beispiel #17
0
 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
        }