Пример #1
0
        public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button)
        {
            if (Command.Contains("Build/"))
            {
                string         type = Command.Substring(6);
                BuildRoomOrder des  = new BuildRoomOrder(RoomLibrary.CreateRoom(Player.Faction, type, refs, false, Player.World), Player.Faction, Player.World);
                des.ToBuild.Designations = refs;
                Player.Faction.RoomBuilder.BuildDesignations.Add(des);
                Player.Faction.RoomBuilder.DesignatedRooms.Add(des.ToBuild);
                des.Build();
            }
            if (Command.Contains("Spawn/"))
            {
                string type = Command.Substring(6);
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (vox.IsEmpty)
                    {
                        var craftItem = CraftLibrary.GetCraftable(type);
                        var offset    = Vector3.Zero;

                        if (craftItem != null)
                        {
                            offset = craftItem.SpawnOffset;
                        }

                        var body = EntityFactory.CreateEntity <Body>(type, vox.WorldPosition + new Vector3(0.5f, 0.0f, 0.5f) + offset);
                        if (body != null)
                        {
                            body.PropogateTransforms();

                            if (craftItem != null)
                            {
                                if (craftItem.AddToOwnedPool)
                                {
                                    Player.Faction.OwnedObjects.Add(body);
                                }

                                if (craftItem.Moveable)
                                {
                                    body.Tags.Add("Moveable");
                                }

                                if (craftItem.Deconstructable)
                                {
                                    body.Tags.Add("Deconstructable");
                                }
                            }
                        }
                    }
                }
            }
            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(Player.World.ComponentManager, vox, junction);
                        Player.World.ComponentManager.RootComponent.AddChild(entity);
                    }
                }
            }
            else if (Command.Contains("Grass/"))
            {
                var type = GrassLibrary.GetGrassType(Command.Substring(6));
                foreach (var vox in refs.Where(v => v.IsValid))
                {
                    var v = vox;
                    if (!vox.IsEmpty)
                    {
                        v.GrassType = type.ID;
                    }
                }
            }
            else if (Command.Contains("Decal/"))
            {
                var type = DecalLibrary.GetGrassType(Command.Substring(6));
                foreach (var vox in refs.Where(v => v.IsValid))
                {
                    var v = vox;
                    if (!vox.IsEmpty)
                    {
                        v.Decal = DecalType.EncodeDecal(DecalOrientation, type.ID);
                    }
                }
            }
            else
            {
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (Command.Contains("Place/"))
                    {
                        string type = Command.Substring(6);
                        var    v    = vox;
                        v.Type = VoxelLibrary.GetVoxelType(type);
                        v.QuickSetLiquid(LiquidType.None, 0);

                        if (type == "Magic")
                        {
                            Player.World.ComponentManager.RootComponent.AddChild(
                                new DestroyOnTimer(Player.World.ComponentManager, Player.World.ChunkManager, vox)
                            {
                                DestroyTimer = new Timer(5.0f + MathFunctions.Rand(-0.5f, 0.5f), true)
                            });
                        }
                    }
                    else
                    {
                        switch (Command)
                        {
                        case "Delete Block":
                        {
                            var v = vox;
                            Player.World.Master.Faction.OnVoxelDestroyed(vox);
                            v.Type = VoxelLibrary.emptyType;
                            v.QuickSetLiquid(LiquidType.None, 0);
                        }
                        break;

                        case "Kill Block":
                            foreach (var selected in refs)
                            {
                                if (!selected.IsEmpty)
                                {
                                    Player.World.ChunkManager.KillVoxel(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 Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Flammable>())
                            {
                                flam2.Heat = flam2.Flashpoint + 1;
                            }
                        }
                        break;

                        case "Kill Things":
                        {
                            foreach (var comp in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both))
                            {
                                comp.Die();
                            }
                        }
                        break;

                        case "Disease":
                        {
                            foreach (var creature in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Creature>())
                            {
                                var disease = Datastructures.SelectRandom(DiseaseLibrary.Diseases);
                                creature.AcquireDisease(disease.Name);
                            }
                            break;
                        }

                        default:
                            break;
                        }
                    }
                }
            }
        }
Пример #2
0
        private void LoadThreaded()
        {
            DwarfGame.ExitGame = false;
            // 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 !DEBUG
            try
            {
#endif
            bool fileExists = !string.IsNullOrEmpty(ExistingFile);

            SetLoadingMessage("Creating Sky...");

            Sky = new SkyRenderer();

            #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() +
                                                  Path.DirectorySeparatorChar + 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 <Body>(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();

                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.Stats != null)
                {
                    Stats = gameFile.PlayData.Stats;
                }
                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(new List <Goals.Goal>());// 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;


                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");

                foreach (var item in CraftLibrary.EnumerateCraftables())
                {
                    if (!String.IsNullOrEmpty(item.Tutorial))
                    {
                        TutorialManager.AddTutorial(item.Name, item.Tutorial, item.Icon);
                    }
                }
            }

            Camera.World = this;
            //Drawer3D.Camera = Camera;


            #endregion

            SetLoadingMessage("Creating Particles ...");
            ParticleManager = new ParticleManager(ComponentManager);

            SetLoadingMessage("Creating GameMaster ...");
            Master = new GameMaster(Factions.Factions["Player"], Game, ComponentManager, ChunkManager,
                                    Camera, GraphicsDevice);

            // If there's no file, we have to initialize the first chunk coordinate
            if (gameFile == null)
            {
                ChunkManager.GenerateInitialChunks(SpawnRect,
                                                   new GlobalChunkCoordinate(0, 0, 0),
                                                   SetLoadingMessage);
            }

            if (gameFile != null)
            {
                if (gameFile.PlayData.Tasks != null)
                {
                    Master.NewArrivals         = gameFile.PlayData.NewArrivals ?? new List <GameMaster.ApplicantArrival>();
                    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();
            }

            if (RevealSurface)
            {
                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);
            }

            SetLoadingMessage("Creating Geometry...");
            ChunkManager.GenerateAllGeometry();

            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;
            ProgramData.WriteExceptionLog(exception);
        }
#endif
        }
Пример #3
0
        public static void GenerateCaveVegetation(VoxelChunk chunk, int x, int y, int z, int caveHeight, BiomeData biome, Vector3 vec, WorldManager world, Perlin NoiseGenerator)
        {
            var vUnder   = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - 1, z));
            var wayUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - caveHeight, z));

            wayUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType));

            var grassType = GrassLibrary.GetGrassType(biome.GrassDecal);

            if (grassType != null)
            {
                wayUnder.RawSetGrass(grassType.ID);
            }

            foreach (VegetationData veg in biome.Vegetation)
            {
                if (!MathFunctions.RandEvent(veg.SpawnProbability))
                {
                    continue;
                }

                if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold)
                {
                    continue;
                }

                if (!vUnder.IsEmpty && vUnder.Type.Name == biome.SoilLayer.VoxelType)
                {
                    vUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType));
                    vUnder.RawSetGrass(0);
                    float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize;

                    WorldManager.DoLazy(() =>
                    {
                        if (!GameSettings.Default.FogofWar)
                        {
                            GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name,
                                                                                              vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                                                                                              Blackboard.Create("Scale", treeSize));
                        }
                        else
                        {
                            world.ComponentManager.RootComponent.AddChild(new ExploredListener(
                                                                              world.ComponentManager, vUnder)
                            {
                                EntityToSpawn  = veg.Name,
                                SpawnLocation  = vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                                BlackboardData = Blackboard.Create("Scale", treeSize)
                            });
                        }
                    });
                }
            }

            float spawnLikelihood = (world.InitialEmbark.Difficulty + 0.1f);

            foreach (FaunaData animal in biome.Fauna)
            {
                if (y <= 0 || !(MathFunctions.Random.NextDouble() < animal.SpawnProbability * spawnLikelihood))
                {
                    continue;
                }

                FaunaData animal1 = animal;
                WorldManager.DoLazy(() =>
                {
                    if (!GameSettings.Default.FogofWar)
                    {
                        var entity = EntityFactory.CreateEntity <GameComponent>(animal1.Name,
                                                                                wayUnder.WorldPosition + Vector3.Up * 1.5f);
                    }
                    else
                    {
                        world.ComponentManager.RootComponent.AddChild(new ExploredListener
                                                                          (world.ComponentManager, new VoxelHandle(chunk, wayUnder.Coordinate.GetLocalVoxelCoordinate()))
                        {
                            EntityToSpawn = animal1.Name,
                            SpawnLocation = wayUnder.WorldPosition + Vector3.Up * 1.5f
                        });
                    }
                });
                break;
            }
        }
Пример #4
0
        public VoxelChunk GenerateChunk(Vector3 origin, WorldManager World, float maxHeight)
        {
            float      waterHeight = NormalizeHeight(SeaLevel + 1.0f / VoxelConstants.ChunkSizeY, maxHeight);
            VoxelChunk c           = new VoxelChunk(Manager, origin, GlobalVoxelCoordinate.FromVector3(origin).GetGlobalChunkCoordinate());

            for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
            {
                for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                {
                    Vector2 v = Overworld.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), World.WorldScale, World.WorldOrigin);

                    var biome = Overworld.Map[(int)MathFunctions.Clamp(v.X, 0, Overworld.Map.GetLength(0) - 1), (int)MathFunctions.Clamp(v.Y, 0, Overworld.Map.GetLength(1) - 1)].Biome;

                    BiomeData biomeData = BiomeLibrary.Biomes[biome];

                    Vector2 pos         = Overworld.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), World.WorldScale, World.WorldOrigin);
                    float   hNorm       = NormalizeHeight(Overworld.LinearInterpolate(pos, Overworld.Map, Overworld.ScalarFieldType.Height), maxHeight);
                    float   h           = MathFunctions.Clamp(hNorm * VoxelConstants.ChunkSizeY, 0.0f, VoxelConstants.ChunkSizeY - 2);
                    int     stoneHeight = (int)(MathFunctions.Clamp((int)(h - (biomeData.SoilLayer.Depth + (Math.Sin(v.X) + Math.Cos(v.Y)))), 1, h));

                    int currentSubsurfaceLayer = 0;
                    int depthWithinSubsurface  = 0;
                    for (int y = VoxelConstants.ChunkSizeY - 1; y >= 0; y--)
                    {
                        var voxel = new VoxelHandle(c, new LocalVoxelCoordinate(x, y, z));

                        if (y == 0)
                        {
                            voxel.RawSetType(VoxelLibrary.GetVoxelType("Bedrock"));
                            continue;
                        }

                        if (y <= stoneHeight && stoneHeight > 1)
                        {
                            voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SubsurfaceLayers[currentSubsurfaceLayer].VoxelType));
                            depthWithinSubsurface++;
                            if (depthWithinSubsurface > biomeData.SubsurfaceLayers[currentSubsurfaceLayer].Depth)
                            {
                                depthWithinSubsurface = 0;
                                currentSubsurfaceLayer++;
                                if (currentSubsurfaceLayer > biomeData.SubsurfaceLayers.Count - 1)
                                {
                                    currentSubsurfaceLayer = biomeData.SubsurfaceLayers.Count - 1;
                                }
                            }
                        }

                        else if ((y == (int)h || y == stoneHeight) && hNorm > waterHeight)
                        {
                            if (biomeData.ClumpGrass &&
                                NoiseGenerator.Noise(pos.X / biomeData.ClumpSize, 0, pos.Y / biomeData.ClumpSize) >
                                biomeData.ClumpTreshold)
                            {
                                voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType));
                                if (!String.IsNullOrEmpty(biomeData.GrassDecal))
                                {
                                    var decal = GrassLibrary.GetGrassType(biomeData.GrassDecal);
                                    voxel.RawSetGrass(decal.ID);
                                }
                            }
                            else if (!biomeData.ClumpGrass)
                            {
                                voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType));
                                if (!String.IsNullOrEmpty(biomeData.GrassDecal))
                                {
                                    var decal = GrassLibrary.GetGrassType(biomeData.GrassDecal);
                                    voxel.RawSetGrass(decal.ID);
                                }
                            }
                            else
                            {
                                voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType));
                            }
                        }
                        else if (y > h && y > 0)
                        {
                            voxel.RawSetType(VoxelLibrary.emptyType);
                        }
                        else if (hNorm <= waterHeight)
                        {
                            voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.ShoreVoxel));
                        }
                        else
                        {
                            voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType));
                        }
                    }
                }
            }

            return(c);
        }
Пример #5
0
        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(
                TextureManager.GetTexture(ContentPaths.Sky.moon),
                TextureManager.GetTexture(ContentPaths.Sky.sun),
                Content.Load <TextureCube>(ContentPaths.Sky.day_sky),
                Content.Load <TextureCube>(ContentPaths.Sky.night_sky),
                TextureManager.GetTexture(ContentPaths.Gradients.skygradient),
                Content.Load <Model>(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(WorldOrigin.X, 0, WorldOrigin.Y);
                Vector3 extents = new Vector3(1500, 1500, 1500);
                CollisionManager = new CollisionManager(new BoundingBox(origin - extents, origin + extents));

                CraftLibrary = new CraftLibrary();

                new PrimitiveLibrary(GraphicsDevice, Content);
                NewInstanceManager = new NewInstanceManager(GraphicsDevice, new BoundingBox(origin - extents, origin + extents),
                                                            Content);

                Color[] white = new Color[1];
                white[0] = Color.White;
                pixel    = new Texture2D(GraphicsDevice, 1, 1);
                pixel.SetData(white);

                Tilesheet                  = TextureManager.GetTexture(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;
                VoxelLibrary.InitializeDefaultLibrary(GraphicsDevice, Tilesheet);
                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);

            LiquidAsset waterAsset = new LiquidAsset
            {
                Type        = LiquidType.Water,
                Opactiy     = 0.8f,
                Reflection  = 1.0f,
                WaveHeight  = 0.1f,
                WaveLength  = 0.05f,
                WindForce   = 0.001f,
                BumpTexture = TextureManager.GetTexture(ContentPaths.Terrain.water_normal),
                BaseTexture = TextureManager.GetTexture(ContentPaths.Terrain.cartoon_water),
                MinOpacity  = 0.4f,
                RippleColor = new Vector4(0.6f, 0.6f, 0.6f, 0.0f),
                FlatColor   = new Vector4(0.3f, 0.3f, 0.9f, 1.0f)
            };
            WaterRenderer.AddLiquidAsset(waterAsset);


            LiquidAsset lavaAsset = new LiquidAsset
            {
                Type        = LiquidType.Lava,
                Opactiy     = 0.95f,
                Reflection  = 0.0f,
                WaveHeight  = 0.1f,
                WaveLength  = 0.05f,
                WindForce   = 0.001f,
                MinOpacity  = 0.8f,
                BumpTexture = TextureManager.GetTexture(ContentPaths.Terrain.water_normal),
                BaseTexture = TextureManager.GetTexture(ContentPaths.Terrain.lava),
                RippleColor = new Vector4(0.5f, 0.4f, 0.04f, 0.0f),
                FlatColor   = new Vector4(0.9f, 0.7f, 0.2f, 1.0f)
            };

            WaterRenderer.AddLiquidAsset(lavaAsset);

            #endregion

            SetLoadingMessage("Generating Initial Terrain Chunks ...");

            if (!fileExists)
            {
                GameID = MathFunctions.Random.Next(0, 1024);
            }

            ChunkGenerator = new ChunkGenerator(VoxelLibrary, Seed, 0.02f, this.WorldScale)
            {
                SeaLevel = SeaLevel
            };


            #region Load Components

            if (fileExists)
            {
                ChunkManager = new ChunkManager(Content, this, Camera,
                                                GraphicsDevice,
                                                ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z);

                ChunkRenderer = new ChunkRenderer(this, Camera, GraphicsDevice, ChunkManager.ChunkData);

                SetLoadingMessage("Loading Terrain...");
                gameFile.ReadChunks(ExistingFile);
                ChunkManager.ChunkData.LoadFromFile(gameFile, SetLoadingMessage);

                ChunkManager.ChunkData.SetMaxViewingLevel(gameFile.Metadata.Slice > 0
                        ? gameFile.Metadata.Slice
                        : ChunkManager.ChunkData.MaxViewingLevel, ChunkManager.SliceMode.Y);

                SetLoadingMessage("Loading Entities...");
                gameFile.LoadPlayData(ExistingFile, this);
                Camera = gameFile.PlayData.Camera;
                ChunkManager.camera  = Camera;
                ChunkRenderer.camera = Camera;
                DesignationDrawer    = gameFile.PlayData.Designations;

                Vector3 origin  = new Vector3(WorldOrigin.X, 0, WorldOrigin.Y);
                Vector3 extents = new Vector3(1500, 1500, 1500);
                CollisionManager = new CollisionManager(new BoundingBox(origin - extents, origin + extents));

                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.");
                    }
                }

                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(Program.CreatePath("Content", "tutorial.txt"));
                TutorialManager.SetFromSaveData(gameFile.PlayData.TutorialSaveData);
            }
            else
            {
                Time = new WorldTime();
                // WorldOrigin is in "map" units. Convert to voxels
                var globalOffset = new Vector3(WorldOrigin.X, 0, WorldOrigin.Y) * WorldScale;

                Camera = new OrbitCamera(this,
                                         new Vector3(VoxelConstants.ChunkSizeX,
                                                     VoxelConstants.ChunkSizeY - 1.0f,
                                                     VoxelConstants.ChunkSizeZ) + new Vector3(WorldOrigin.X, 0, WorldOrigin.Y) * WorldScale,
                                         new Vector3(VoxelConstants.ChunkSizeY, VoxelConstants.ChunkSizeY - 1.0f,
                                                     VoxelConstants.ChunkSizeZ) + new Vector3(WorldOrigin.X, 0, WorldOrigin.Y) * WorldScale +
                                         Vector3.Up * 10.0f + Vector3.Backward * 10,
                                         MathHelper.PiOver4, AspectRatio, 0.1f,
                                         GameSettings.Default.VertexCullDistance);

                ChunkManager = new ChunkManager(Content, this, Camera,
                                                GraphicsDevice,
                                                ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z);

                ChunkRenderer = new ChunkRenderer(this, Camera, GraphicsDevice, ChunkManager.ChunkData);


                var chunkOffset = GlobalVoxelCoordinate.FromVector3(globalOffset).GetGlobalChunkCoordinate();
                //var chunkOffset = ChunkManager.ChunkData.RoundToChunkCoords(globalOffset);
                //globalOffset.X = chunkOffset.X * VoxelConstants.ChunkSizeX;
                //globalOffset.Y = chunkOffset.Y * VoxelConstants.ChunkSizeY;
                //globalOffset.Z = chunkOffset.Z * VoxelConstants.ChunkSizeZ;

                WorldOrigin     = new Vector2(globalOffset.X, globalOffset.Z);
                Camera.Position = new Vector3(0, 10, 0) + globalOffset;
                Camera.Target   = new Vector3(0, 10, 1) + globalOffset;

                // If there's no file, we have to initialize the first chunk coordinate
                if (gameFile == null)     // Todo: Always true?
                {
                    ChunkManager.GenerateInitialChunks(
                        GlobalVoxelCoordinate.FromVector3(globalOffset).GetGlobalChunkCoordinate(),
                        SetLoadingMessage);
                }

                ComponentManager = new ComponentManager(this);
                ComponentManager.SetRootComponent(new Body(ComponentManager, "root", Matrix.Identity,
                                                           Vector3.Zero, Vector3.Zero, false));

                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);
                    }

                    if (faction.CraftBuilder == null)
                    {
                        faction.CraftBuilder = new CraftBuilder(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(Program.CreatePath("Content", "tutorial.txt"));
                TutorialManager.TutorialEnabled = !GameSettings.Default.TutorialDisabledGlobally;
                Tutorial("new game start");
            }

            Camera.World = this;
            //Drawer3D.Camera = Camera;


            #endregion

            ChunkManager.camera = Camera;

            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;
                }
            }

            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.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
        }
Пример #6
0
        private static void UpdateChunk(VoxelChunk chunk)
        {
            var addGrassToThese = new List <Tuple <VoxelHandle, byte> >();

            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Skip empty slices.
                if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                {
                    continue;
                }

                for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
                {
                    for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                    {
                        var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                        // Allow grass to decay
                        if (voxel.GrassType != 0)
                        {
                            var decal = GrassLibrary.GetGrassType(voxel.GrassType);

                            if (decal.NeedsSunlight && !voxel.Sunlight)
                            {
                                voxel.GrassType = 0;
                            }
                            else if (decal.Decay)
                            {
                                voxel.GrassDecay -= 1;
                                if (voxel.GrassDecay == 0)
                                {
                                    var newDecal = GrassLibrary.GetGrassType(decal.BecomeWhenDecays);
                                    if (newDecal != null)
                                    {
                                        voxel.GrassType = newDecal.ID;
                                    }
                                    else
                                    {
                                        voxel.GrassType = 0;
                                    }
                                }
                            }
                        }
//#if false
                        else if (voxel.Type.GrassSpreadsHere)
                        {
                            // Spread grass onto this tile - but only from the same biome.

                            // Don't spread if there's an entity here.
                            var entityPresent = chunk.Manager.World.EnumerateIntersectingObjects(
                                new BoundingBox(voxel.WorldPosition + new Vector3(0.1f, 1.1f, 0.1f), voxel.WorldPosition + new Vector3(0.9f, 1.9f, 0.9f)),
                                CollisionType.Static).Any();
                            if (entityPresent)
                            {
                                continue;
                            }

                            var biome = Overworld.GetBiomeAt(voxel.Coordinate.ToVector3(), chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin);

                            var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate)
                                                  .Select(c => new VoxelHandle(voxel.Chunk.Manager.ChunkData, c))
                                                  .Where(v => v.IsValid && v.GrassType != 0)
                                                  .Where(v => biome == Overworld.GetBiomeAt(v.Coordinate.ToVector3(), chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin))
                                                  .ToList();

                            if (grassyNeighbors.Count > 0)
                            {
                                if (MathFunctions.RandEvent(0.1f))
                                {
                                    addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType));
                                }
                            }
                        }
//#endif
                    }
                }
            }

            foreach (var v in addGrassToThese)
            {
                var l         = v.Item1;
                var grassType = GrassLibrary.GetGrassType(v.Item2);
                if (grassType.NeedsSunlight && !l.Sunlight)
                {
                    continue;
                }
                l.GrassType = v.Item2;
            }
        }
Пример #7
0
        public void RebuildMoteLayer(int Y)
        {
            BoundingBox box = GetBoundingBox();

            box.Min.Y = Y;
            box.Max.Y = Y + 1;
            //Drawer3D.DrawBox(box, Color.Red, 0.1f, true);
            // Destroy old motes.
            if (MoteRecords[Y] != null)
            {
                foreach (var record in MoteRecords[Y])
                {
                    DestroyGrassMote(this.Manager.World, record.Type, record);
                }
                MoteRecords[Y].Clear();
            }
            else
            {
                MoteRecords[Y] = new List <NewInstanceData>();
            }

            // Enumerate voxels.
            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    // Don't generate motes if above is not empty
                    if (Y < VoxelConstants.ChunkSizeY - 1)
                    {
                        var voxelAbove = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y + 1, z));
                        if (!voxelAbove.IsEmpty || voxelAbove.WaterCell.WaterLevel != 0)
                        {
                            continue;
                        }
                    }

                    var v = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y, z));

                    // Don't generate in empty voxels.
                    if (v.IsEmpty)
                    {
                        continue;
                    }

                    if (!v.IsExplored)
                    {
                        continue;
                    }

                    // Find biome type.
                    var biome = Overworld.Map[
                        (int)MathFunctions.Clamp(v.WorldPosition.X / Manager.World.WorldScale, 0, Overworld.Map.GetLength(0) - 1),
                        (int)MathFunctions.Clamp(v.WorldPosition.Z / Manager.World.WorldScale, 0, Overworld.Map.GetLength(1) - 1)]
                                .Biome;

                    var biomeData = BiomeLibrary.Biomes[biome];

                    // Don't generate if not on grass type.
                    if (v.GrassType == 0 || GrassLibrary.GetGrassType(v.GrassType).Name != biomeData.GrassDecal)
                    {
                        continue;
                    }

                    // Biomes can contain multiple types of mote.
                    foreach (var moteDetail in biomeData.Motes)
                    {
                        // Lower mote if voxel is ramped.
                        float vOffset = 0.0f;
                        if (v.RampType != RampType.None)
                        {
                            vOffset = -0.5f;
                        }

                        var   vPos  = v.WorldPosition * moteDetail.RegionScale;
                        float value = MoteNoise.Noise(vPos.X, vPos.Y, vPos.Z);

                        if (!(Math.Abs(value) > moteDetail.SpawnThreshold))
                        {
                            continue;
                        }

                        float s = MoteScaleNoise.Noise(vPos.X, vPos.Y, vPos.Z) * moteDetail.MoteScale;

                        var smallNoise = ClampVector(VertexNoise.GetRandomNoiseVector(vPos * 20.0f) * 20.0f, 0.4f);
                        smallNoise.Y = 0.0f;

                        var mote = GenerateGrassMote(
                            Manager.World,
                            v.WorldPosition + new Vector3(0.5f, 1.0f + s * 0.5f + vOffset, 0.5f) + smallNoise,
                            new Color(v.SunColor, 128, 0),
                            s,
                            moteDetail.Name);

                        MoteRecords[Y].Add(mote);
                    }
                }
            }
        }
Пример #8
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;
                        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;
                    }
                }
            }

            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;
                    RainDrops[i].Particle = null;
                }
                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.ChunkData,
                                           GlobalVoxelCoordinate.FromVector3(RainDrops[i].Pos));
                if (!test.IsValid || test.IsEmpty || test.LiquidLevel > 0)
                {
                    continue;
                }

                RainDrops[i].IsAlive = false;
                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  = GrassLibrary.GetGrassType("snow").ID;
                        test.GrassDecay = GrassLibrary.GetGrassType("snow").InitialDecayValue;
                    }
                    else
                    {
                        var existingGrass = GrassLibrary.GetGrassType((byte)test.GrassType);
                        if (!String.IsNullOrEmpty(existingGrass.BecomeWhenSnowedOn))
                        {
                            var newGrass = GrassLibrary.GetGrassType(existingGrass.BecomeWhenSnowedOn);
                            test.GrassType  = newGrass.ID;
                            test.GrassDecay = newGrass.InitialDecayValue;
                        }
                    }
                }
            }

            Matrix tf = LocalTransform;

            tf.Translation += Velocity * DwarfTime.Dt;
            LocalTransform  = tf;
        }
Пример #9
0
 /// <summary>
 /// Set the decal of the voxel without triggering all the bookkeeping mechanisms.
 /// Should only be used by ChunkGenerator as it can break geometry building.
 /// </summary>
 /// <param name="Decal"></param>
 public void RawSetGrass(byte Type)
 {
     _cache_Chunk.Data.GrassType[_cache_Index]  = Type;
     _cache_Chunk.Data.GrassDecay[_cache_Index] = GrassLibrary.GetGrassType(Type).InitialDataValue;
 }
Пример #10
0
 /// <summary>
 /// Set the decal of the voxel without triggering all the bookkeeping mechanisms.
 /// Should only be used by ChunkGenerator as it can break geometry building.
 /// </summary>
 /// <param name="Type"></param>
 public void RawSetGrass(byte Type)
 {
     _cache_Chunk.Data.Grass[_cache_Index] = (byte)((Type << VoxelConstants.GrassTypeShift) + (GrassLibrary.GetGrassType(Type).InitialDecayValue & VoxelConstants.GrassDecayMask));
 }
Пример #11
0
        public void RebuildMoteLayer(int Y)
        {
            var moteList = new List <NewInstanceData>();

            // Enumerate voxels.
            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    // Don't generate motes if above is not empty
                    if (Y < VoxelConstants.ChunkSizeY - 1)
                    {
                        var voxelAbove = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y + 1, z));
                        if (!voxelAbove.IsEmpty || voxelAbove.LiquidLevel != 0)
                        {
                            continue;
                        }
                    }

                    var v = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y, z));

                    // Don't generate in empty voxels.
                    if (v.IsEmpty)
                    {
                        continue;
                    }

                    if (!v.IsExplored)
                    {
                        continue;
                    }

                    // Find biome type.
                    var biomeData = Overworld.GetBiomeAt(v.WorldPosition, Manager.World.WorldScale, Manager.World.WorldOrigin);

                    // Don't generate if not on grass type.
                    if (v.GrassType == 0 || GrassLibrary.GetGrassType(v.GrassType).Name != biomeData.GrassDecal)
                    {
                        continue;
                    }

                    // Biomes can contain multiple types of mote.
                    foreach (var moteDetail in biomeData.Motes)
                    {
                        // Lower mote if voxel is ramped.
                        float vOffset = 0.0f;
                        if (v.RampType != RampType.None)
                        {
                            vOffset = -0.5f;
                        }

                        var   vPos  = v.WorldPosition * moteDetail.RegionScale;
                        float value = MoteNoise.Noise(vPos.X, vPos.Y, vPos.Z);

                        if (!(Math.Abs(value) > moteDetail.SpawnThreshold))
                        {
                            continue;
                        }

                        float s = MoteScaleNoise.Noise(vPos.X, vPos.Y, vPos.Z) * moteDetail.MoteScale;

                        var smallNoise = ClampVector(VertexNoise.GetRandomNoiseVector(vPos * 20.0f) * 20.0f, 0.4f);
                        smallNoise.Y = 0.0f;

                        var mote = GenerateGrassMote(
                            Manager.World,
                            v.WorldPosition + new Vector3(0.5f, 1.0f + s * 0.5f + vOffset, 0.5f) + smallNoise,
                            new Color(v.Sunlight ? 255 : 0, 128, 0),
                            s,
                            moteDetail.Name);

                        moteList.Add(mote);
                    }
                }
            }

            MoteRecords[Y] = moteList;
        }
Пример #12
0
        private static void UpdateChunk(VoxelChunk chunk)
        {
            var addGrassToThese = new List <Tuple <VoxelHandle, byte> >();

            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Skip empty slices.
                if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                {
                    continue;
                }

                for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
                {
                    for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                    {
                        var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                        // Allow grass to decay
                        if (voxel.GrassType != 0)
                        {
                            var decal = GrassLibrary.GetGrassType(voxel.GrassType);

                            if (decal.NeedsSunlight && voxel.SunColor < 255)
                            {
                                voxel.GrassType = 0;
                            }
                            else if (decal.Decay)
                            {
                                voxel.GrassDecay -= 1;
                                if (voxel.GrassDecay == 0)
                                {
                                    var newDecal = GrassLibrary.GetGrassType(decal.BecomeWhenDecays);
                                    if (newDecal != null)
                                    {
                                        voxel.GrassType = newDecal.ID;
                                    }
                                    else
                                    {
                                        voxel.GrassType = 0;
                                    }
                                }
                            }
                        }
                        else if (voxel.Type.GrassSpreadsHere)
                        {
                            // Spread grass onto this tile - but only from the same biome.

                            var biome = Overworld.GetBiomeAt(voxel.Coordinate.ToVector3());

                            var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate)
                                                  .Select(c => new VoxelHandle(voxel.Chunk.Manager.ChunkData, c))
                                                  .Where(v => v.IsValid && v.GrassType != 0)
                                                  .Where(v => biome == Overworld.GetBiomeAt(v.Coordinate.ToVector3()))
                                                  .ToList();

                            if (grassyNeighbors.Count > 0)
                            {
                                if (MathFunctions.RandEvent(0.1f))
                                {
                                    addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType));
                                }
                            }
                        }
                    }
                }
            }

            foreach (var v in addGrassToThese)
            {
                var l         = v.Item1;
                var grassType = GrassLibrary.GetGrassType(v.Item2);
                if (grassType.NeedsSunlight && l.SunColor != 255)
                {
                    continue;
                }
                l.GrassType = v.Item2;
            }
        }
Пример #13
0
        private static void BuildGrassFringeGeometry(
            RawPrimitive Into,
            VoxelChunk Chunk,
            Cache Cache,
            BoxPrimitive Primitive,
            VoxelHandle V,
            VertexColorInfo[] VertexColors,
            Color[] VertexTint,
            Vector3[] VertexPositions,
            BoxPrimitive.FaceDescriptor Face,
            int ExploredVerts)
        {
            if (V.GrassType == 0)
            {
                return;
            }

            var decalType = GrassLibrary.GetGrassType(V.GrassType);

            AddGrassGeometry(Into, Cache.AmbientValues, Primitive, V, Face, ExploredVerts, VertexPositions, VertexColors, VertexTint, decalType);

            // Draw fringe
            if (decalType.FringeTransitionUVs == null)
            {
                return;
            }

            for (var s = 0; s < 4; ++s)
            {
                var neighborCoord = V.Coordinate + VoxelHelpers.ManhattanNeighbors2D[s];
                var neighbor      = new VoxelHandle(Chunk.Manager.ChunkData, neighborCoord);

                if (!neighbor.IsValid)
                {
                    continue;
                }

                var aboveNeighbor = new VoxelHandle(Chunk.Manager.ChunkData, neighborCoord + new GlobalVoxelOffset(0, 1, 0));

                if (!aboveNeighbor.IsValid || aboveNeighbor.IsEmpty)
                {
                    // Draw horizontal fringe.
                    if (!neighbor.IsEmpty)
                    {
                        if (neighbor.GrassType != 0 &&
                            GrassLibrary.GetGrassType(neighbor.GrassType).FringePrecedence >= decalType.FringePrecedence)
                        {
                            continue;
                        }
                    }

                    // Twizzle vertex positions.
                    var newPositions = new Vector3[4];
                    newPositions[FringeIndicies[s, 0]] = VertexPositions[FringeIndicies[s, 4]];
                    newPositions[FringeIndicies[s, 1]] = VertexPositions[FringeIndicies[s, 4]]
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * 0.5f);
                    newPositions[FringeIndicies[s, 2]] = VertexPositions[FringeIndicies[s, 5]]
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * 0.5f);
                    newPositions[FringeIndicies[s, 3]] = VertexPositions[FringeIndicies[s, 5]];

                    var newColors = new VertexColorInfo[4];
                    newColors[FringeIndicies[s, 0]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 1]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 2]] = VertexColors[FringeIndicies[s, 5]];
                    newColors[FringeIndicies[s, 3]] = VertexColors[FringeIndicies[s, 5]];

                    var slopeTweak = new Vector3(0.0f, 0.0f, 0.0f);
                    if (neighbor.IsEmpty)
                    {
                        slopeTweak.Y = -0.5f;
                    }
                    else
                    {
                        slopeTweak.Y = 0.125f;
                    }

                    newPositions[FringeIndicies[s, 1]] += slopeTweak;
                    newPositions[FringeIndicies[s, 2]] += slopeTweak;

                    var newTints = new Color[4];
                    newTints[FringeIndicies[s, 0]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 1]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 2]] = VertexTint[FringeIndicies[s, 5]];
                    newTints[FringeIndicies[s, 3]] = VertexTint[FringeIndicies[s, 5]];

                    AddTopFaceGeometry(Into,
                                       Cache.AmbientValues, Primitive,
                                       Face,
                                       newPositions,
                                       newColors,
                                       newTints,
                                       SideFringeUVScales[s],
                                       decalType.FringeTransitionUVs[s].UV,
                                       decalType.FringeTransitionUVs[s].Bounds);
                }
                else
                {
                    // Draw vertical fringe!

                    var newPositions = new Vector3[4];
                    newPositions[FringeIndicies[s, 0]] = VertexPositions[FringeIndicies[s, 4]];
                    newPositions[FringeIndicies[s, 1]] = VertexPositions[FringeIndicies[s, 4]]
                                                         + new Vector3(0.0f, 0.5f, 0.0f)
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * -0.05f);
                    newPositions[FringeIndicies[s, 2]] = VertexPositions[FringeIndicies[s, 5]]
                                                         + new Vector3(0.0f, 0.5f, 0.0f)
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * -0.05f);
                    newPositions[FringeIndicies[s, 3]] = VertexPositions[FringeIndicies[s, 5]];

                    var newColors = new VertexColorInfo[4];
                    newColors[FringeIndicies[s, 0]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 1]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 2]] = VertexColors[FringeIndicies[s, 5]];
                    newColors[FringeIndicies[s, 3]] = VertexColors[FringeIndicies[s, 5]];

                    var newTints = new Color[4];
                    newTints[FringeIndicies[s, 0]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 1]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 2]] = VertexTint[FringeIndicies[s, 5]];
                    newTints[FringeIndicies[s, 3]] = VertexTint[FringeIndicies[s, 5]];

                    AddTopFaceGeometry(Into,
                                       Cache.AmbientValues, Primitive,
                                       Face,
                                       newPositions,
                                       newColors,
                                       newTints,
                                       SideFringeUVScales[s],
                                       decalType.FringeTransitionUVs[s].UV,
                                       decalType.FringeTransitionUVs[s].Bounds);
                }
            }

            for (var s = 0; s < 4; ++s)
            {
                var neighborCoord = V.Coordinate + VoxelHelpers.DiagonalNeighbors2D[s];
                var handle        = new VoxelHandle(Chunk.Manager.ChunkData, neighborCoord);

                if (handle.IsValid)
                {
                    if (!handle.IsEmpty)
                    {
                        if (handle.GrassType != 0 &&
                            GrassLibrary.GetGrassType(handle.GrassType).FringePrecedence >= decalType.FringePrecedence)
                        {
                            continue;
                        }
                    }

                    var manhattanA = new VoxelHandle(Chunk.Manager.ChunkData,
                                                     V.Coordinate + VoxelHelpers.ManhattanNeighbors2D[s]);
                    if (!manhattanA.IsValid || (manhattanA.GrassType == V.GrassType))
                    {
                        continue;
                    }

                    manhattanA = new VoxelHandle(Chunk.Manager.ChunkData,
                                                 V.Coordinate + VoxelHelpers.ManhattanNeighbors2D[FringeIndicies[4 + s, 5]]);
                    if (!manhattanA.IsValid || (manhattanA.GrassType == V.GrassType))
                    {
                        continue;
                    }

                    // Twizzle vertex positions.
                    var newPositions = new Vector3[4];
                    var pivot        = VertexPositions[FringeIndicies[4 + s, 4]];
                    var nDelta       = VoxelHelpers.DiagonalNeighbors2D[s].AsVector3();

                    newPositions[FringeIndicies[4 + s, 0]] = pivot;
                    newPositions[FringeIndicies[4 + s, 1]] = pivot + new Vector3(nDelta.X * 0.5f, 0, 0);
                    newPositions[FringeIndicies[4 + s, 2]] = pivot + new Vector3(nDelta.X * 0.5f, 0, nDelta.Z * 0.5f);
                    newPositions[FringeIndicies[4 + s, 3]] = pivot + new Vector3(0, 0, nDelta.Z * 0.5f);

                    var slopeTweak = new Vector3(0.0f, 0.0f, 0.0f);
                    if (handle.IsEmpty)
                    {
                        slopeTweak.Y = -0.5f;
                    }
                    else
                    {
                        slopeTweak.Y = 0.125f;
                    }

                    newPositions[FringeIndicies[4 + s, 1]] += slopeTweak;
                    newPositions[FringeIndicies[4 + s, 2]] += slopeTweak;
                    newPositions[FringeIndicies[4 + s, 3]] += slopeTweak;

                    var newColors = new VertexColorInfo[4];
                    newColors[FringeIndicies[4 + s, 0]] = VertexColors[FringeIndicies[4 + s, 4]];
                    newColors[FringeIndicies[4 + s, 1]] = VertexColors[FringeIndicies[4 + s, 4]];
                    newColors[FringeIndicies[4 + s, 2]] = VertexColors[FringeIndicies[4 + s, 4]];
                    newColors[FringeIndicies[4 + s, 3]] = VertexColors[FringeIndicies[4 + s, 4]];

                    var newTints = new Color[4];
                    newTints[FringeIndicies[4 + s, 0]] = VertexTint[FringeIndicies[4 + s, 4]];
                    newTints[FringeIndicies[4 + s, 1]] = VertexTint[FringeIndicies[4 + s, 4]];
                    newTints[FringeIndicies[4 + s, 2]] = VertexTint[FringeIndicies[4 + s, 4]];
                    newTints[FringeIndicies[4 + s, 3]] = VertexTint[FringeIndicies[4 + s, 4]];

                    AddTopFaceGeometry(Into,
                                       Cache.AmbientValues, Primitive,
                                       Face,
                                       newPositions,
                                       newColors,
                                       newTints,
                                       new Vector2(0.5f, 0.5f),
                                       decalType.FringeTransitionUVs[4 + s].UV,
                                       decalType.FringeTransitionUVs[4 + s].Bounds);
                }
            }
        }