コード例 #1
0
        // update dynamic entities
        private void UpdateDynamic(object o)
        {
            if (Monitor.TryEnter(_areaManagerSyncRoot))
            {
                try
                {
                    var state = new DynamicUpdateState
                    {
                        ElapsedTime = _lastUpdate == new UtopiaTime() ? UtopiaTimeSpan.Zero : _server.Clock.Now - _lastUpdate,
                        CurrentTime = _server.Clock.Now
                    };

                    state.RealTime = _server.Clock.GameToReal(state.ElapsedTime);

                    _lastUpdate = _server.Clock.Now;

                    Update(state);
                }
                finally
                {
                    Monitor.Exit(_areaManagerSyncRoot);
                }
            }
            else
            {
                logger.Warn("Warning! Server is overloaded. Try to decrease dynamic entities count");
            }
        }
コード例 #2
0
        public void CheckGrowing()
        {
            var entityGrowingManager = new EntityGrowingManager(null);

            var random = new Random(1);

            var entity = new PlantGrowingEntity();

            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromHours(1)
            });
            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromHours(1)
            });
            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromHours(1)
            });
            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromHours(1)
            });
            entity.LastGrowUpdate = new UtopiaTime() + UtopiaTimeSpan.FromMinutes(1);

            var now = new UtopiaTime() + UtopiaTimeSpan.FromHours(2.5);

            entityGrowingManager.EntityGrowCheck(now, entity, null, random);
            Assert.AreEqual(2, entity.CurrentGrowLevelIndex);

            entity = new PlantGrowingEntity();
            entity.GrowingSeasons.Add(UtopiaTime.TimeConfiguration.Seasons[0].Name);
            entity.GrowingSeasons.Add(UtopiaTime.TimeConfiguration.Seasons[2].Name);
            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromDays(10)
            });
            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromDays(10)
            });
            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromDays(10)
            });
            entity.GrowLevels.Add(new GrowLevel {
                GrowTime = UtopiaTimeSpan.FromDays(10)
            });
            entity.LastGrowUpdate = new UtopiaTime() + UtopiaTimeSpan.FromMinutes(1);

            now = new UtopiaTime() + UtopiaTimeSpan.FromMinutes(50);
            entityGrowingManager.EntityGrowCheck(now, entity, null, random);
            entity.LastGrowUpdate = now;
            Assert.AreEqual(0, entity.CurrentGrowLevelIndex);

            now = new UtopiaTime() + UtopiaTimeSpan.FromYears(1);
            entityGrowingManager.EntityGrowCheck(now, entity, null, random);
            entity.LastGrowUpdate = now;
            Assert.AreEqual(1, entity.CurrentGrowLevelIndex);

            now = new UtopiaTime() + UtopiaTimeSpan.FromYears(1) + UtopiaTimeSpan.FromMinutes(1);
            entityGrowingManager.EntityGrowCheck(now, entity, null, random);
            entity.LastGrowUpdate = now;
            Assert.AreEqual(2, entity.CurrentGrowLevelIndex);
        }
コード例 #3
0
ファイル: WeatherService.cs プロジェクト: ErtyHackward/utopia
        private WeatherMessage UpdateWeather()
        {
            UtopiaTime now = _server.Clock.Now;

            if (TimeConfiguration.Seasons.Count == 0)
            {
                return(new WeatherMessage());
            }

            var growing = now.Day / ((float)TimeConfiguration.DaysPerSeason / 2) <= 1;

            Season s1, s2;
            float  power;

            var seasonIndex = now.SeasonIndex;

            if (growing)
            {
                var s1Index = seasonIndex - 1 < 0 ? TimeConfiguration.Seasons.Count - 1 : seasonIndex - 1;
                s1 = TimeConfiguration.Seasons[s1Index];
                s2 = TimeConfiguration.Seasons[seasonIndex];

                power = now.Day / ((float)TimeConfiguration.DaysPerSeason) + 0.5f;
            }
            else
            {
                var s2Index = seasonIndex + 1 >= TimeConfiguration.Seasons.Count ? 0 : seasonIndex + 1;
                s1 = TimeConfiguration.Seasons[seasonIndex];
                s2 = TimeConfiguration.Seasons[s2Index];

                power = now.Day / ((float)TimeConfiguration.DaysPerSeason) - 0.5f;
            }

            var temperature = Lerp(s1.Temperature, s2.Temperature, power);
            var moisture    = Lerp(s1.Moisture, s2.Moisture, power);

            var msg = new WeatherMessage
            {
                MoistureOffset    = moisture,
                TemperatureOffset = temperature
            };

            return(msg);
        }
コード例 #4
0
        private void AssignTimeAndFactor(double timeFactor, UtopiaTime worldDatetime)
        {
            TimeFactor = (float)timeFactor;

            _baseUtopiaTime           = worldDatetime;
            _utopiaLastRealTimeUpdate = DateTime.Now;

            _clockTime = -1;
            var prevFrozen = FrozenTime;

            FrozenTime = false;
            FTSUpdate(new GameTime());
            FrozenTime = prevFrozen;

            float y = (float)Math.Cos(ClockTime.ClockTimeNormalized * MathHelper.TwoPi);
            float x = (float)Math.Sin(ClockTime.ClockTimeNormalized * MathHelper.TwoPi);

            logger.Info("SunLight Vector is {0}", new SharpDX.Vector3(x, y, 0));
        }
コード例 #5
0
        private void GrowingLookup(UtopiaTime gametime)
        {
            var random = new Random();

            foreach (var chunk in _server.LandscapeManager.GetBufferedChunks())
            {
                var growingEntities = chunk.Entities.OfType <GrowingEntity>().ToList();

                foreach (var entity in growingEntities)
                {
                    var now = _server.Clock.Now;

                    // fix time cheat
                    if (now > entity.LastGrowUpdate)
                    {
                        EntityGrowCheck(_server.Clock.Now, entity, chunk, random);
                    }

                    entity.LastGrowUpdate = now;
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Method responsible to do chunk spawn logic
        /// </summary>
        private void UtopiaSpawningLookup(UtopiaTime gametime)
        {
            //Logic to "Randomize" and limit the number of chunk to update per cycle ======================================================

            //Get the chunks that are under server management and are candidate for a refresh !
            var serverChunksToUpdate = _landscapeManager.GetBufferedChunks().Where(x => (gametime - x.LastSpawningRefresh) > _chunkUpdateCycle).ToList();

            //Get the chunk not in the processing list => New chunk to process
            var newChunks = serverChunksToUpdate.Where(x => _chunks4Processing.Contains(x) == false).ToList();

            if (newChunks.Count > 0)
            {
                _chunks4Processing.AddRange(newChunks);
                _chunks4Processing.Shuffle(); //Shuffle all chunks that must be updated.
            }

            //Get the chunk not handled anymore by the server and remove them from the processing list
            _chunks4Processing.RemoveAll(c => serverChunksToUpdate.Contains(c) == false);

            //Process _maxChunkRefreshPerCycle at maximum
            foreach (var chunk in _chunks4Processing.Take(_maxChunkRefreshPerCycle))
            {
                SpawnBiomeEntities(gametime, chunk);
                TreeSoulUpdate(chunk);
                chunk.LastSpawningRefresh = gametime;
            }

            if (_chunks4Processing.Count < _maxChunkRefreshPerCycle)
            {
                _chunks4Processing.Clear();
            }
            else
            {
                _chunks4Processing.RemoveRange(0, _maxChunkRefreshPerCycle);
            }
        }
コード例 #7
0
        public void EntityGrowCheck(UtopiaTime now, GrowingEntity entity, ServerChunk chunk, Random random)
        {
            if (entity.LastGrowUpdate.IsZero)
            {
                return;
            }

            var checkTimeSpan = now - entity.LastGrowUpdate;

            bool updated;
            bool rotten;

            // grow time left at the current season
            var tillTheEndOfSeason = UtopiaTimeSpan.FromSeasons(1d - entity.LastGrowUpdate.TotalSeasons % 1d);

            if (checkTimeSpan <= tillTheEndOfSeason)
            {
                // small grow update
                updated = GrowSeasonLogic(entity, now.Season, checkTimeSpan, random, chunk, out rotten);

                if (rotten)
                {
                    return;
                }
            }
            else
            {
                // grow at the end of the first season
                updated = GrowSeasonLogic(entity, now.Season, tillTheEndOfSeason, random, chunk, out rotten);

                if (rotten)
                {
                    return;
                }

                // align time to the beginning of next season
                checkTimeSpan -= tillTheEndOfSeason;

                while (checkTimeSpan.TotalSeconds > 0)
                {
                    var seasonCheckSpan = checkTimeSpan.TotalSeasons > 0 ? UtopiaTimeSpan.FromSeasons(1) : checkTimeSpan;

                    updated = GrowSeasonLogic(entity, (now - checkTimeSpan).Season, seasonCheckSpan, random, chunk, out rotten) || updated;

                    if (rotten)
                    {
                        return;
                    }

                    checkTimeSpan -= seasonCheckSpan;
                }
            }

            if (updated)
            {
                if (entity is PlantGrowingEntity)
                {
                    if (chunk != null)
                    {
                        chunk.Entities.RemoveById(entity.StaticId);
                        chunk.Entities.Add(entity);
                    }
                }
                var tree = entity as TreeGrowingEntity;
                if (tree != null)
                {
                    var treeBlueprint = _server.EntityFactory.Config.TreeBluePrintsDico[tree.TreeTypeId];

                    if (tree.CurrentGrowTime > treeBlueprint.GrowTime)
                    {
                        // the tree is ready

                        var model = VoxelModel.GenerateTreeModel(tree.TreeRndSeed, treeBlueprint);

                        // create tree blocks
                        var rootOffset = model.States[0].PartsStates[0].Translation;
                        var cursor     = _server.LandscapeManager.GetCursor(tree.Position);
                        var frame      = model.Frames[0];
                        var range      = new Range3I(new Vector3I(), frame.BlockData.ChunkSize);

                        using (cursor.TransactionScope())
                        {
                            foreach (var position in range)
                            {
                                var value = frame.BlockData.GetBlock(position);
                                if (value == 0)
                                {
                                    continue;
                                }
                                var blockType = value == 1 ? treeBlueprint.TrunkBlock : treeBlueprint.FoliageBlock;
                                var worldPos  = (Vector3I)(tree.Position + rootOffset) + position;
                                cursor.GlobalPosition = worldPos;
                                if (cursor.Read() == WorldConfiguration.CubeId.Air)
                                {
                                    cursor.Write(blockType);
                                }
                            }
                        }

                        // create tree soul
                        var soul = _server.EntityFactory.CreateEntity <TreeSoul>();
                        soul.Position    = tree.Position;
                        soul.TreeRndSeed = tree.TreeRndSeed;
                        soul.TreeTypeId  = tree.TreeTypeId;

                        chunk.Entities.Add(soul);

                        // remove the growing tree
                        chunk.Entities.RemoveById(tree.StaticId);
                    }
                    else
                    {
                        // just make the model bigger
                        tree.Scale = (float)tree.CurrentGrowTime.TotalSeconds / treeBlueprint.GrowTime.TotalSeconds;
                        chunk.Entities.RemoveById(tree.StaticId);
                        chunk.Entities.Add(tree);
                    }
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Create new instance of the Server class
        /// </summary>
        public ServerCore(
            XmlSettingsManager <ServerSettings> settingsManager,
            WorldGenerator worldGenerator,
            IUsersStorage usersStorage,
            IChunksStorage chunksStorage,
            IEntityStorage entityStorage,
            ICustomStorage customStorage,
            EntityFactory entityFactory,
            WorldParameters wp
            )
        {
            // dependency injection
            SettingsManager = settingsManager;
            UsersStorage    = usersStorage;
            EntityStorage   = entityStorage;
            CustomStorage   = customStorage;
            EntityFactory   = entityFactory;
            WorldParameters = wp;

            if (SettingsManager.Settings == null)
            {
                SettingsManager.Load();
            }

            var settings = SettingsManager.Settings;

            ConnectionManager = new ConnectionManager(SettingsManager.Settings.ServerPort);

            Scheduler = new ScheduleManager();

            UtopiaTime startTime = CustomStorage.GetVariable <UtopiaTime>("GameTimeElapsed");

            Clock = new Clock(this, startTime, TimeSpan.FromMinutes(20));

            LandscapeManager = new ServerLandscapeManager(
                this,
                chunksStorage,
                worldGenerator,
                EntityFactory,
                settings.ChunkLiveTimeMinutes,
                settings.CleanUpInterval,
                settings.SaveInterval,
                settings.ChunksCountLimit,
                wp);

            EntityManager = new EntityManager(this);

            AreaManager = new AreaManager(this);

            DynamicIdHelper.SetMaxExistsId(EntityStorage.GetMaximumId());

            Services = new ServiceManager(this);

            PerformanceManager = new PerformanceManager(AreaManager);

            CommandsManager = new CommandsManager(this);

            ChatManager = new ChatManager(this);

            GlobalStateManager = new GlobalStateManager(this);

            LoginManager = new LoginManager(this, EntityFactory);

            EntitySpawningManager = new EntitySpawningManager(this, worldGenerator.EntitySpawningControler);

            EntityGrowingManager = new Managers.EntityGrowingManager(this);
        }
コード例 #9
0
ファイル: WeatherService.cs プロジェクト: ErtyHackward/utopia
 private void PerDayTrigger(UtopiaTime gametime)
 {
     // each day we will recalculate temperature and humidity values
     _lastMessage = UpdateWeather();
     _server.ConnectionManager.Broadcast(_lastMessage);
 }
コード例 #10
0
        private void SpawnBiomeEntities(UtopiaTime gametime, ServerChunk chunk)
        {
            var chunkBiome = _configuration.ProcessorParam.Biomes[chunk.BlockData.ChunkMetaData.ChunkMasterBiomeType];

            foreach (var spawnableEntity in chunkBiome.SpawnableEntities)
            {
                bool isStaticEntity = _configuration.BluePrints[spawnableEntity.BluePrintId] is IStaticEntity;

                //Remark : isChunkGenerationSpawning is set to true for static entities, and false for dynamic entities, maybe worth renaming the properties
                //The aim of it is to avoid dynamic entity creation at chunk generation time (Pure chunk).
                //Apply creation constaint :
                //1) if static entity with is isWildChunkNeeded and chunk is not wild => Do nothing
                if (spawnableEntity.IsWildChunkNeeded && chunk.BlockData.ChunkMetaData.IsWild == false)
                {
                    continue;
                }

                if (chunk.PureGenerated && isStaticEntity)
                {
                    continue;
                }

                var isDayTime = gametime.TimeOfDay > UtopiaTimeSpan.FromHours(8) &&
                                gametime.TimeOfDay < UtopiaTimeSpan.FromHours(20);
                // check daytime constraints
                if (!spawnableEntity.SpawningDayTime.HasFlag(ChunkSpawningDayTime.Day) &&
                    isDayTime)
                {
                    continue;
                }

                if (!spawnableEntity.SpawningDayTime.HasFlag(ChunkSpawningDayTime.Night) &&
                    !isDayTime)
                {
                    continue;
                }

                // check season constraint
                var weatherService = _server.Services.GetService <WeatherService>();

                if (weatherService != null && weatherService.CurrentSeason != null &&
                    spawnableEntity.SpawningSeasons.Count > 0 &&
                    !spawnableEntity.SpawningSeasons.Contains(weatherService.CurrentSeason.Name))
                {
                    continue;
                }

                ByteChunkCursor chunkCursor = new ByteChunkCursor(chunk.BlockData.GetBlocksBytes(), chunk.BlockData.ColumnsInfo);
                // ==> Maybe worth to automaticaly create this specialize cursor at server chunk creation ? Multithreading problem ?
                //It is only use for reading chunk block data in fast way
                Vector3D entityLocation;
                if (_entitySpawningControler.TryGetSpawnLocation(spawnableEntity, chunk, chunkCursor, _fastRandom,
                                                                 out entityLocation))
                {
                    var entity       = _server.EntityFactory.CreateFromBluePrint(spawnableEntity.BluePrintId);
                    var staticEntity = entity as IStaticEntity;

                    if (staticEntity != null)
                    {
                        //Check the maximum amount of static entities;
                        int maxEntityAmount;
                        chunk.BlockData.ChunkMetaData.InitialSpawnableEntitiesAmount.TryGetValue(spawnableEntity.BluePrintId,
                                                                                                 out maxEntityAmount);
                        if (maxEntityAmount == 0)
                        {
                            continue;
                        }
                        if (chunk.Entities.Where(e => e.BluePrintId == spawnableEntity.BluePrintId)
                            .CountAtLeast(maxEntityAmount))
                        {
                            continue;
                        }

                        staticEntity.Position = entityLocation;

                        var cursor = _server.LandscapeManager.GetCursor(entityLocation);
                        logger.Debug("Spawning new static entity : {0} at location {1}", staticEntity.Name, entityLocation);

                        var blockLinkedItem = staticEntity as IBlockLinkedEntity;
                        if (blockLinkedItem != null)
                        {
                            blockLinkedItem.LinkedCube = (Vector3I)entityLocation + Vector3I.Down;
                        }

                        cursor.AddEntity(staticEntity);
                    }

                    var charEntity = entity as CharacterEntity;
                    if (charEntity != null)
                    {
                        if (DisableNPCSpawn)
                        {
                            continue;
                        }

                        var radius = Math.Max(8, spawnableEntity.DynamicEntitySpawnRadius);
                        if (
                            _server.AreaManager.EnumerateAround(entityLocation, radius)
                            .CountAtLeast(spawnableEntity.MaxEntityAmount))
                        {
                            continue;
                        }

                        charEntity.Position = entityLocation;
                        logger.Debug("Spawning new dynamic entity : {0} at location {1}", charEntity.Name, entityLocation);
                        _server.EntityManager.AddNpc(charEntity);
                    }
                }
            }
        }