コード例 #1
0
        public void AddPlayer(Player player)
        {
            if (!_players.ContainsKey(player.NetworkId))
            {
                _players.Add(player.NetworkId, player);
            }

            var unit = RandomUnit();

            if (unit == null)
            {
                Logger.Log("GAME error - no more units", true);
                return;
            }
            unit.Rise(player);
            unit.Position = FindSpawnPoint();
            if (player.DoubleUnits)
            {
                for (int i = 0; i < _config.AdditionalUnitCount; i++)
                {
                    NearUnit(unit)?.Rise(player);
                }

                for (int i = 0; i < player.Units.Count; i++)
                {
                    player.Units[i].Position = unit.Position;
                }
            }

            _unitsTree = new OcTree(_worldZone, _units, true);
        }
コード例 #2
0
        private PhysicalObject[] GenerateObstacles(int count)
        {
            var objs = new List <PhysicalObject>();

            for (int i = 0; i < count; i++)
            {
                OcTree         tree = null;
                PhysicalObject obj  = null;
                for (int n = 0; n < MaxTryCount; n++)
                {
                    obj = ObstacleFactory.MakeObstacle();

                    obj.Position = GetPointInCircle(WorldScale * _config.ObstacleRange);
                    if (GameMath.MathF.Abs(obj.Position.X) > WorldScale - 2f)
                    {
                        continue;
                    }
                    if (GameMath.MathF.Abs(obj.Position.Y) > WorldScale - 2f)
                    {
                        continue;
                    }

                    tree = new OcTree(_worldZone, objs, false);

                    if (tree != null && !tree.Intersect(obj.Position, obj.Radius + ObstacleFactory.SpaceBetween))
                    {
                        break;
                    }
                }
                objs.Add(obj);
            }
            return(objs.ToArray());
        }
コード例 #3
0
        public World(Config config, GameMode gameMode)
        {
            _config   = config;
            _gameMode = gameMode;

            Logger.Log("WORLD creating world");
            _mapType          = GameMath.MathF.RandomInt(int.MinValue, int.MaxValue);
            WorldScale        = GameMath.MathF.RandomInt(config.MinWorldScale, config.MaxWorldScale);
            ZoneRadius        = WorldScale;
            _targetZoneRadius = 0.3f * ZoneRadius;
            _worldZone        = new BoundingBox(-WorldScale, -WorldScale, WorldScale * 2, WorldScale * 2);

            Logger.Log("WORLD creating obstacles");
            _obstacles = GenerateObstacles(config.ObstacleCount);
            Logger.Log("WORLD creating obstacle tree");
            _obstaclesTree = new OcTree(_worldZone, _obstacles, true);

            Logger.Log("WORLD creating units");
            _units = GenerateUnits(config.UnitCount);
            Logger.Log("WORLD creating unit tree");
            _unitsTree = new OcTree(_worldZone, _units, true);

            Logger.Log("WORLD creating runes");
            _runes = GenerateRunes(config.RuneCount);
            Logger.Log("WORLD creating rune tree");
            _runesTree = new OcTree(_worldZone, _runes, true);

            Logger.Log("WORLD warming chaches");
            UnitPosition.Warmup();

            Logger.Log("WORLD created");
        }
コード例 #4
0
        private List <Rune> GenerateRunes(int count)
        {
            var objs = new List <Rune>();

            for (int i = 0; i < count; i++)
            {
                var tree = new OcTree(_worldZone, objs, false);
                var obj  = RuneFactory.MakeRune();

                Vector2 pos;
                for (int n = 0; n < MaxTryCount; n++)
                {
                    pos        = GetPointInCircle(ZoneRadius * _config.RuneRange);
                    obj.Radius = ZoneRadius / 3f;
                    if (!obj.TryMove(pos, tree))
                    {
                        continue;
                    }
                    obj.Radius = Rune.RuneRadius;

                    if (obj.TryMove(pos, tree, _obstaclesTree, _unitsTree))
                    {
                        break;
                    }
                }
                objs.Add(obj);
            }
            return(objs);
        }
コード例 #5
0
ファイル: WorldPhysics.cs プロジェクト: Norne9/NecroServer
        public Rune TakeRune(Unit unit)
        {
            var rune = _runesTree.Overlap <Rune>(unit.Position, unit.Radius).SingleOrDefault();

            if (rune == null)
            {
                return(null);
            }
            Logger.Log($"GAME user '{unit.Owner?.Name ?? "null"}' take rune");
            _runes.Remove(rune);
            _runesTree = new OcTree(_worldZone, _runes, true);
            return(rune);
        }
コード例 #6
0
        private Unit[] GenerateUnits(int count)
        {
            var objs    = new List <Unit>();
            var factory = new UnitFactory(_config);

            for (int i = 0; i < count; i++)
            {
                var     tree = new OcTree(_worldZone, objs, false);
                var     obj  = factory.MakeUnit();
                Vector2 pos;
                for (int n = 0; n < MaxTryCount; n++)
                {
                    pos = GetPointInCircle(WorldScale * _config.UnitRange);
                    if (obj.TryMove(pos, tree, _obstaclesTree))
                    {
                        break;
                    }
                }
                objs.Add(obj);
            }
            return(objs.ToArray());
        }
コード例 #7
0
        public void Update(float deltaTime)
        {
            DeltaTime = deltaTime;

            //Rebuild unit tree
            _unitsTree = new OcTree(_worldZone, _units, true);

            //Get alive players count
            if (_gameMode == GameMode.Royale)
            {
                _alivePlayers = _players.Values.Where((p) => p.IsAlive && !p.IsNeutrall).Count();
                //Kill all units if we have winner
                if (_alivePlayers == 1)
                {
                    foreach (var unit in _units)
                    {
                        unit.TakeDamage(null, float.MaxValue);
                    }
                }
            }
            else
            {
                _alivePlayers = _players.Values.Where((p) => p.IsAlive && !p.IsAI).Count();
            }

            //Update players
            foreach (var player in _players.Values)
            {
                player.Update(this);
                if (!player.IsAlive && player.PlayerStatus.Place == 0)
                {
                    player.PlayerStatus.Place = _alivePlayers > 0 ? _alivePlayers : 1;
                    if (!player.IsAI)
                    {
                        OnPlayerDead?.Invoke(player.UserId, player.PlayerStatus);
                    }
                    Logger.Log($"GAME player dead {player.PlayerStatus.Place}/{_config.MaxPlayers}");
                }
            }

            //No more players - end game
            if (_alivePlayers == 0)
            {
                OnGameEnd?.Invoke();
            }

            //Mode processing
            switch (_gameMode)
            {
            case GameMode.Royale:     //Royale mode - process zone
                float elapsedTime = (float)(DateTime.Now - _startTime).TotalSeconds;
                switch (_worldState)
                {
                case WorldState.Static:
                    if (elapsedTime > _config.StaticTime)
                    {
                        _startTime       = DateTime.Now;
                        _worldState      = WorldState.Resize;
                        _beginZoneRadius = ZoneRadius;
                        Logger.Log($"GAME zone begin");
                    }
                    _timeToEnd = _config.StaticTime - elapsedTime;
                    break;

                case WorldState.Resize:
                    float percent = (_config.ResizeTime - elapsedTime) / _config.ResizeTime;
                    if (percent < 0f)
                    {
                        percent    = 0; _targetZoneRadius = 0f;
                        _startTime = DateTime.Now; _worldState = WorldState.Static;
                    }
                    else
                    {
                        ZoneRadius = Lerp(_beginZoneRadius, _targetZoneRadius, 1f - percent);
                        _timeToEnd = _config.ResizeTime - elapsedTime;
                    }
                    break;
                }
                if (_timeToEnd < 0)
                {
                    _timeToEnd = 0;
                }
                break;

            case GameMode.Free:     //Free mode - no zone
                _timeToEnd = 0;
                //Add runes if empty
                if (_runes.Count == 0)
                {
                    Logger.Log("WORLD creating runes");
                    _runes.AddRange(GenerateRunes(_config.RuneCount));
                    Logger.Log("WORLD creating rune tree");
                    _runesTree = new OcTree(_worldZone, _runes, true);
                }
                break;
            }
        }