Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #6
0
        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
            }
        }