Example #1
0
        private void OnNewTick(Client client, Packet p)
        {
            NewTickPacket packet = p as NewTickPacket;

            tickCount++;

            // Health changed event.
            float healthPercentage = (float)client.PlayerData.Health / (float)client.PlayerData.MaxHealth * 100f;

            healthChanged?.Invoke(this, new HealthChangedEventArgs(healthPercentage));

            // Autonexus.
            if (healthPercentage < config.AutonexusThreshold && !(currentMapName?.Equals("Nexus") ?? false) && enabled)
            {
                Escape(client);
            }

            // Fame event.
            fameUpdate?.Invoke(this, new FameUpdateEventArgs(client.PlayerData?.CharacterFame ?? -1, client.PlayerData?.CharacterFameGoal ?? -1));

            if (tickCount % config.TickCountThreshold == 0)
            {
                if (followTarget && playerPositions.Count > 0 && !gotoRealm)
                {
                    List <Target> newTargets = D36n4.Invoke(playerPositions.Values.ToList(), config.Epsilon, config.MinPoints, config.FindClustersNearCenter);
                    if (newTargets == null)
                    {
                        if (targets.Count != 0 && config.EscapeIfNoTargets)
                        {
                            Escape(client);
                        }
                        targets.Clear();
                        Log("No valid clusters found.");
                    }
                    else
                    {
                        if (targets.Count != newTargets.Count)
                        {
                            Log(string.Format("Now targeting {0} players.", newTargets.Count));
                        }
                        targets = newTargets;
                    }
                }
                tickCount = 0;
            }

            // Updates.
            foreach (Status status in packet.Statuses)
            {
                // Update player positions.
                if (playerPositions.ContainsKey(status.ObjectId))
                {
                    playerPositions[status.ObjectId].UpdatePosition(status.Position);
                }

                // Update enemy positions.
                if (enemies.Exists(en => en.ObjectId == status.ObjectId))
                {
                    enemies.Find(en => en.ObjectId == status.ObjectId).Location = status.Position;
                }

                // Update portal player counts when in nexus.
                if (portals.Exists(ptl => ptl.ObjectId == status.ObjectId) && (isInNexus))
                {
                    foreach (var data in status.Data)
                    {
                        if (data.StringValue != null)
                        {
                            var strCount = data.StringValue.Split(' ')[1].Split('/')[0].Remove(0, 1);
                            portals[portals.FindIndex(ptl => ptl.ObjectId == status.ObjectId)].PlayerCount = int.Parse(strCount);
                        }
                    }
                }

                // Change the speed if in Nexus.
                if (isInNexus && status.ObjectId == client.ObjectId)
                {
                    foreach (var data in status.Data)
                    {
                        if (data.Id == StatsType.Speed)
                        {
                            if (data.IntValue > 45)
                            {
                                List <StatData> list = new List <StatData>(status.Data)
                                {
                                    new StatData {
                                        Id = StatsType.Speed, IntValue = 45
                                    }
                                };
                                status.Data = list.ToArray();
                            }
                        }
                    }
                }
            }

            // Reset keys if the bot is not active.
            if (!followTarget && !gotoRealm)
            {
                W_PRESSED = false;
                A_PRESSED = false;
                S_PRESSED = false;
                D_PRESSED = false;
            }

            if (followTarget && targets.Count > 0)
            {
                // Get the target position: the average of all current targets.
                var targetPosition = new Location(targets.Average(t => t.Position.X), targets.Average(t => t.Position.Y));

                if (client.PlayerData.Pos.DistanceTo(targetPosition) > config.TeleportDistanceThreshold)
                {
                    // If the distance exceeds the teleport threshold, send a text packet to teleport.
                    var name = targets.OrderBy(t => t.Position.DistanceTo(targetPosition)).First().Name;
                    if (name != client.PlayerData.Name)
                    {
                        var tpPacket = (PlayerTextPacket)Packet.Create(PacketType.PLAYERTEXT);
                        tpPacket.Text = "/teleport " + name;
                        client.SendToServer(tpPacket);
                    }
                }

                if (enemies.Exists(en => en.Location.DistanceSquaredTo(client.PlayerData.Pos) <= 49))
                {
                    // If there is an enemy within 7 tiles, actively attempt to avoid it.
                    Location closestEnemy = enemies.OrderBy(en => en.Location.DistanceSquaredTo(client.PlayerData.Pos)).First().Location;

                    // Get the angle between the enemy and the player.
                    double angle = Math.Atan2(client.PlayerData.Pos.Y - closestEnemy.Y, client.PlayerData.Pos.X - closestEnemy.X);

                    // Calculate a point on a 'circle' around the enemy with a radius 8 at the angle specified.
                    float newX = closestEnemy.X + 8f * (float)Math.Cos(angle);
                    float newY = closestEnemy.Y + 8f * (float)Math.Sin(angle);

                    var avoidPos = new Location(newX, newY);
                    CalculateMovement(client, avoidPos, config.FollowDistanceThreshold);
                    return;
                }

                if (rocks.Exists(rock => rock.Location.DistanceSquaredTo(client.PlayerData.Pos) <= 4))
                {
                    // If there is a rock within 2 tiles, actively attempt to move around it.
                    Location closestRock     = rocks.OrderBy(rock => rock.Location.DistanceSquaredTo(client.PlayerData.Pos)).First().Location;
                    double   angleDifference = client.PlayerData.Pos.GetAngleDifferenceDegrees(targetPosition, closestRock);

                    if (Math.Abs(angleDifference) < 70.0)
                    {
                        double angle = Math.Atan2(client.PlayerData.Pos.Y - closestRock.Y, client.PlayerData.Pos.X - closestRock.X);
                        if (angleDifference <= 0)
                        {
                            angle += (Math.PI / 2); // add 90 degrees to the angle to go clockwise around the rock.
                        }
                        if (angleDifference > 0)
                        {
                            angle -= (Math.PI / 2); // remove 90 degrees from the angle to go anti-clockwise around the rock.
                        }
                        float newX = closestRock.X + 2f * (float)Math.Cos(angle);
                        float newY = closestRock.Y + 2f * (float)Math.Sin(angle);

                        var avoidRockPos = new Location(newX, newY);
                        CalculateMovement(client, avoidRockPos, 0.5f);
                        return;
                    }
                }

                CalculateMovement(client, targetPosition, config.FollowDistanceThreshold);
            }
        }
Example #2
0
        private void OnNewTick(Client client, Packet p)
        {
            NewTickPacket packet = p as NewTickPacket;

            tickCount++;

            float healthPercentage = (float)client.PlayerData.Health / (float)client.PlayerData.MaxHealth * 100f;

            healthChanged?.Invoke(this, new HealthChangedEventArgs(healthPercentage));

            if (healthPercentage < config.AutonexusThreshold && !(currentMapName?.Equals("Nexus") ?? false) && enabled)
            {
                Escape(client);
            }

            fameUpdate?.Invoke(this, new FameUpdateEventArgs(client.PlayerData?.CharacterFame ?? -1, client.PlayerData?.CharacterFameGoal ?? -1));

            if (tickCount % config.TickCountThreshold == 0)
            {
                if (followTarget && playerPositions.Count > 0 && !gotoRealm)
                {
                    List <Target> newTargets = D36n4.Invoke(playerPositions.Values.ToList(), config.Epsilon, config.MinPoints, config.FindClustersNearCenter);
                    if (newTargets == null)
                    {
                        if (targets.Count != 0 && config.EscapeIfNoTargets)
                        {
                            Escape(client);
                        }
                        targets.Clear();
                        Log("No valid clusters found.");
                    }
                    else
                    {
                        if (targets.Count != newTargets.Count)
                        {
                            Log(string.Format("Now targeting {0} players.", newTargets.Count));
                        }
                        targets = newTargets;
                    }
                }
                tickCount = 0;
            }

            foreach (Status status in packet.Statuses)
            {
                if (playerPositions.ContainsKey(status.ObjectId))
                {
                    playerPositions[status.ObjectId].UpdatePosition(status.Position);
                }

                if (enemies.Exists(en => en.ObjectId == status.ObjectId))
                {
                    enemies.Find(en => en.ObjectId == status.ObjectId).Location = status.Position;
                }

                if (portals.Exists(ptl => ptl.ObjectId == status.ObjectId) && (isInNexus))
                {
                    foreach (var data in status.Data)
                    {
                        if (data.StringValue != null)
                        {
                            var strCount = data.StringValue.Split(' ') [1].Split('/') [0].Remove(0, 1);
                            portals[portals.FindIndex(ptl => ptl.ObjectId == status.ObjectId)].PlayerCount = int.Parse(strCount);
                        }
                    }
                }

                if (isInNexus && status.ObjectId == client.ObjectId)
                {
                    foreach (var data in status.Data)
                    {
                        if (data.Id == StatsType.Speed)
                        {
                            if (data.IntValue > 45)
                            {
                                List <StatData> list = new List <StatData> (status.Data)
                                {
                                    new StatData {
                                        Id = StatsType.Speed, IntValue = 45
                                    }
                                };
                                status.Data = list.ToArray();
                            }
                        }
                    }
                }
            }

            if (enabled)
            {
                if (lastLocation != null)
                {
                    if (client.PlayerData.Pos.X == lastLocation.X && client.PlayerData.Pos.Y == lastLocation.Y)
                    {
                        ResetAllKeys();
                    }
                }
                lastLocation = client.PlayerData.Pos;
            }

            if (!followTarget && !gotoRealm)
            {
                ResetAllKeys();
            }

            if (followTarget && targets.Count > 0)
            {
                var targetPosition = new Location(targets.Average(t => t.Position.X), targets.Average(t => t.Position.Y));
                if (lastAverage != null)
                {
                    var           dir            = targetPosition.Subtract(lastAverage);
                    var           faraway        = targetPosition.Add(dir.Scale(20));
                    var           desiredTargets = (int)(targets.Count * (config.TrainTargetPercentage / 100f));
                    List <Target> newTargets     = new List <Target> ();
                    for (int i = 0; i < desiredTargets; i++)
                    {
                        var closest = targets.OrderBy((t) => t.Position.DistanceSquaredTo(faraway)).First();
                        newTargets.Add(closest);
                        targets.RemoveAll((t) => t.Name == closest.Name);
                    }
                    targets.AddRange(newTargets);
                    lastAverage    = targetPosition;
                    targetPosition = new Location(newTargets.Average(t => t.Position.X), newTargets.Average(t => t.Position.Y));
                }
                else
                {
                    lastAverage = targetPosition;
                }

                if (client.PlayerData.Pos.DistanceTo(targetPosition) > config.TeleportDistanceThreshold)
                {
                    var name = targets.OrderBy(t => t.Position.DistanceTo(targetPosition)).First().Name;
                    if (name != client.PlayerData.Name)
                    {
                        var tpPacket = (PlayerTextPacket)Packet.Create(PacketType.PLAYERTEXT);
                        tpPacket.Text = "/teleport " + name;
                        client.SendToServer(tpPacket);
                    }
                }

                if (config.EnableEnemyAvoidance && enemies.Exists(en => en.Location.DistanceSquaredTo(client.PlayerData.Pos) <= (config.EnemyAvoidanceDistance * config.EnemyAvoidanceDistance)))
                {
                    Location closestEnemy    = enemies.OrderBy(en => en.Location.DistanceSquaredTo(client.PlayerData.Pos)).First().Location;
                    double   angleDifference = client.PlayerData.Pos.GetAngleDifferenceDegrees(targetPosition, closestEnemy);

                    if (Math.Abs(angleDifference) < 70.0)
                    {
                        double angle = Math.Atan2(client.PlayerData.Pos.Y - closestEnemy.Y, client.PlayerData.Pos.X - closestEnemy.X);
                        if (angleDifference <= 0)
                        {
                            angle += (Math.PI / 2);
                        }
                        if (angleDifference > 0)
                        {
                            angle -= (Math.PI / 2);
                        }

                        float newX = closestEnemy.X + config.EnemyAvoidanceDistance * (float)Math.Cos(angle);
                        float newY = closestEnemy.Y + config.EnemyAvoidanceDistance * (float)Math.Sin(angle);

                        var avoidPos = new Location(newX, newY);
                        CalculateMovement(client, avoidPos, config.FollowDistanceThreshold);
                        return;
                    }
                }

                if (obstacles.Exists(obstacle => obstacle.Location.DistanceSquaredTo(client.PlayerData.Pos) <= 4))
                {
                    Location closestObstacle = obstacles.OrderBy(obstacle => obstacle.Location.DistanceSquaredTo(client.PlayerData.Pos)).First().Location;
                    double   angleDifference = client.PlayerData.Pos.GetAngleDifferenceDegrees(targetPosition, closestObstacle);

                    if (Math.Abs(angleDifference) < 70.0)
                    {
                        double angle = Math.Atan2(client.PlayerData.Pos.Y - closestObstacle.Y, client.PlayerData.Pos.X - closestObstacle.X);
                        if (angleDifference <= 0)
                        {
                            angle += (Math.PI / 2);
                        }
                        if (angleDifference > 0)
                        {
                            angle -= (Math.PI / 2);
                        }

                        float newX = closestObstacle.X + 2f * (float)Math.Cos(angle);
                        float newY = closestObstacle.Y + 2f * (float)Math.Sin(angle);

                        var avoidObstaclePos = new Location(newX, newY);
                        CalculateMovement(client, avoidObstaclePos, 0.75f);
                        return;
                    }
                }

                CalculateMovement(client, targetPosition, config.FollowDistanceThreshold);
            }
        }