public override Character ClosestCharacter(Vector2 pos, float radius, Character notThis) { var closestRange = radius * 2f; Character closest = null; foreach (var character in GetEntities <Character>()) { if (character == notThis) { continue; } var len = Math.Distance(pos, character.Position); if (len < character.ProximityRadius + radius) { if (len < closestRange) { closestRange = len; closest = character; } } } return(closest); }
public override Character IntersectCharacter(Vector2 pos1, Vector2 pos2, float radius, ref Vector2 newPos, Character notThis) { var closestLength = Math.Distance(pos1, pos2) * 100f; Character closest = null; foreach (var character in GetEntities <Character>()) { if (character == notThis) { continue; } var intersectPos = Math.ClosestPointOnLine(pos1, pos2, character.Position); var length = Math.Distance(character.Position, intersectPos); if (length < character.ProximityRadius + radius) { length = Math.Distance(pos1, intersectPos); if (length < closestLength) { newPos = intersectPos; closestLength = length; closest = character; } } } return(closest); }
public override IEnumerable <T> FindEntities <T>(Vector2 pos, float radius) { var current = Entity <T> .FirstTypeEntity; while (current != null) { if (Math.Distance(current.Position, pos) < radius + current.ProximityRadius) { yield return((T)current); } current = current.NextTypeEntity; } }
protected virtual void EvaluateSpawnType(SpawnEval eval, IList <Vector2> spawnPos) { for (var i = 0; i < spawnPos.Count; i++) { var positions = new[] { new Vector2(0.0f, 0.0f), new Vector2(-32.0f, 0.0f), new Vector2(0.0f, -32.0f), new Vector2(32.0f, 0.0f), new Vector2(0.0f, 32.0f) }; // start, left, up, right, down var result = -1; var characters = GameContext.World .FindEntities <Character>(spawnPos[i], 64f) .ToArray(); for (var index = 0; index < 5 && result == -1; ++index) { result = index; for (var c = 0; c < characters.Length; c++) { if (GameContext.Collision.IsTileSolid(spawnPos[i] + positions[index]) || Math.Distance(characters[c].Position, spawnPos[i] + positions[index]) <= characters[c].ProximityRadius) { result = -1; break; } } if (result == -1) { continue; } var p = spawnPos[i] + positions[index]; var s = EvaluateSpawnPos(eval, p); if (!eval.Got || eval.Score > s) { eval.Got = true; eval.Score = s; eval.Pos = p; } } } }
protected virtual float EvaluateSpawnPos(SpawnEval eval, Vector2 pos) { var score = 0f; foreach (var character in GameContext.World.GetEntities <Character>()) { var scoremod = 1f; if (eval.FriendlyTeam != Team.SPECTATORS && character.Player.Team == eval.FriendlyTeam) { scoremod = 0.5f; } var d = Math.Distance(pos, character.Position); score += scoremod * (System.Math.Abs(d) < 0.00001 ? 1000000000.0f : 1.0f / d); } return(score); }
protected virtual void UpdatePlayerMaps() { if (Server.Tick % Config["SvMapUpdateRate"] != 0) { return; } for (var i = 0; i < PlayersDistances.Count; i++) { PlayersDistances[i].First = 0; PlayersDistances[i].Second = 0; } for (var i = 0; i < PlayersDistances.Count; i++) { if (!Server.ClientInGame(i)) { continue; } var idMap = BaseServer.GetIdMap(i); // compute distances for (var j = 0; j < PlayersDistances.Count; j++) { PlayersDistances[j].Second = j; if (!Server.ClientInGame(j) || GameContext.Players[j] == null) { PlayersDistances[j].First = (float)1e10; continue; } var character = GameContext.Players[j].GetCharacter(); if (character == null) { PlayersDistances[j].First = (float)1e9; continue; } // copypasted chunk from character.cpp Snap() follows if (GameContext.Players[i].GetCharacter() != null && GameContext.Players[i].Team != Team.SPECTATORS && GameContext.Players[i].ClientVersion == ClientVersion.VANILLA) { PlayersDistances[j].First = (float)1e8; } else { PlayersDistances[j].First = 0; } PlayersDistances[j].First += Math.Distance( GameContext.Players[i].ViewPos, GameContext.Players[j].GetCharacter().Position ); } // always send the player himself PlayersDistances[i].First = 0; // compute reverse map var rMap = new int[PlayersDistances.Count]; for (var j = 0; j < PlayersDistances.Count; j++) { rMap[j] = -1; } for (var j = 0; j < BaseServer.VANILLA_MAX_CLIENTS; j++) { if (Server.IdMap[idMap + j] == -1) { continue; } if (PlayersDistances[Server.IdMap[idMap + j]].First > 1e9) { Server.IdMap[idMap + j] = -1; } else { rMap[Server.IdMap[idMap + j]] = j; } } PlayersDistances.Sort(DistancesComparer); var mapc = 0; var demand = 0; for (var j = 0; j < BaseServer.VANILLA_MAX_CLIENTS - 1; j++) { var k = PlayersDistances[j].Second; if (rMap[k] != -1 || PlayersDistances[j].First > 5e9) { continue; } while (mapc < BaseServer.VANILLA_MAX_CLIENTS && Server.IdMap[idMap + mapc] != -1) { mapc++; } if (mapc < BaseServer.VANILLA_MAX_CLIENTS - 1) { Server.IdMap[idMap + mapc] = k; } else { demand++; } } for (var j = PlayersDistances.Count - 1; j > BaseServer.VANILLA_MAX_CLIENTS - 2; j--) { var k = PlayersDistances[j].Second; if (rMap[k] != -1 && demand-- > 0) { Server.IdMap[idMap + rMap[k]] = -1; } } Server.IdMap[idMap + BaseServer.VANILLA_MAX_CLIENTS - 1] = -1; // player with empty name to say chat msgs } }