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