feat: Add auto dodge
This commit is contained in:
1 parent
afb8235c08
commit
6701dd0305
8 files changed
+150
-2
No files matched your search
@@ -57,6 +57,7 @@ public static class Hotkeys
|
|||||||
Toggle("Combat", "WeakenEnemies", "Weaken Enemies", () => Settings.WeakenEnemies, v => Settings.WeakenEnemies = v),
|
Toggle("Combat", "WeakenEnemies", "Weaken Enemies", () => Settings.WeakenEnemies, v => Settings.WeakenEnemies = v),
|
||||||
Toggle("Combat", "RapidAttack", "Rapid Attack", () => Settings.RapidAttack, v => Settings.RapidAttack = v),
|
Toggle("Combat", "RapidAttack", "Rapid Attack", () => Settings.RapidAttack, v => Settings.RapidAttack = v),
|
||||||
Toggle("Combat", "MagicBullets", "Magic Bullets", () => Settings.MagicBullets, v => Settings.MagicBullets = v),
|
Toggle("Combat", "MagicBullets", "Magic Bullets", () => Settings.MagicBullets, v => Settings.MagicBullets = v),
|
||||||
|
Toggle("Combat", "AutoDodge", "Auto Dodge", () => Settings.AutoDodge, v => Settings.AutoDodge = v),
|
||||||
new("Combat", "GatherAll", "Gather All Enemies", CombatFeatures.GatherAll),
|
new("Combat", "GatherAll", "Gather All Enemies", CombatFeatures.GatherAll),
|
||||||
new("Combat", "KillAll", "Kill All Enemies", CombatFeatures.KillAll),
|
new("Combat", "KillAll", "Kill All Enemies", CombatFeatures.KillAll),
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public static partial class Settings
|
|||||||
[nameof(AimFov)] = "Combat.Aim.CursorRadius",
|
[nameof(AimFov)] = "Combat.Aim.CursorRadius",
|
||||||
[nameof(AimRange)] = "Combat.Aim.Range",
|
[nameof(AimRange)] = "Combat.Aim.Range",
|
||||||
[nameof(MagicBullets)] = "Combat.MagicBullets",
|
[nameof(MagicBullets)] = "Combat.MagicBullets",
|
||||||
|
[nameof(AutoDodge)] = "Combat.AutoDodge",
|
||||||
|
|
||||||
[nameof(InstantBreak)] = "Items.InstantBreak",
|
[nameof(InstantBreak)] = "Items.InstantBreak",
|
||||||
[nameof(InfItems)] = "Items.InfiniteItems",
|
[nameof(InfItems)] = "Items.InfiniteItems",
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public static partial class Settings
|
|||||||
public static bool KillAura, HitMagnet, FreezeEnemies, WeakenEnemies;
|
public static bool KillAura, HitMagnet, FreezeEnemies, WeakenEnemies;
|
||||||
public static float KillAuraRange = 20f, HitMagnetRange = 30f;
|
public static float KillAuraRange = 20f, HitMagnetRange = 30f;
|
||||||
public static int KillAuraInterval = 10;
|
public static int KillAuraInterval = 10;
|
||||||
public static bool Aimbot, AimPrediction = true, AimDrawTarget = true, AutoAttack, AimExact = true, ShotPreview, MagicBullets;
|
public static bool Aimbot, AimPrediction = true, AimDrawTarget = true, AutoAttack, AimExact = true, ShotPreview, MagicBullets, AutoDodge;
|
||||||
public static float AimFov = 250f, AimRange = 60f;
|
public static float AimFov = 250f, AimRange = 60f;
|
||||||
|
|
||||||
public static bool InstantBreak, InfItems, ItemVacuum, AutoSell, BankButtons = true;
|
public static bool InstantBreak, InfItems, ItemVacuum, AutoSell, BankButtons = true;
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Terraria;
|
||||||
|
using TerraSharp.Core;
|
||||||
|
using TerraSharp.Simulation;
|
||||||
|
|
||||||
|
namespace TerraSharp.Features.Combat;
|
||||||
|
|
||||||
|
// Steers the local player out of predicted projectile and contact hits.
|
||||||
|
public static class AutoDodge
|
||||||
|
{
|
||||||
|
const int Horizon = 24;
|
||||||
|
const int MaxThreats = 48;
|
||||||
|
const float ScanRange = 60f * 16f;
|
||||||
|
const float Margin = 6f;
|
||||||
|
const int WallCheckTicks = 6;
|
||||||
|
|
||||||
|
sealed class Threat
|
||||||
|
{
|
||||||
|
public readonly Vector2[] Path = new Vector2[Horizon + 1];
|
||||||
|
public int Count, Width, Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly record struct Move(int Horizontal, int Vertical);
|
||||||
|
|
||||||
|
static readonly Move[] Moves = [new(0, 0), new(-1, 0), new(1, 0), new(0, -1), new(-1, -1), new(1, -1), new(0, 1), new(-1, 1), new(1, 1)];
|
||||||
|
static readonly Threat[] Pool = new Threat[MaxThreats];
|
||||||
|
static readonly List<Threat> Threats = [];
|
||||||
|
|
||||||
|
static AutoDodge()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Pool.Length; i++)
|
||||||
|
Pool[i] = new Threat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Player.HorizontalMovement prefix: controls and velocity set here drive this tick's movement.
|
||||||
|
public static void Steer(Player player)
|
||||||
|
{
|
||||||
|
if (!Settings.AutoDodge || player.dead)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CollectThreats(player);
|
||||||
|
if (Threats.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float speed = Settings.Fly ? Settings.FlySpeed : Math.Max(Math.Max(player.maxRunSpeed, player.accRunSpeed), 3f);
|
||||||
|
float jump = Player.jumpSpeed * 1.5f;
|
||||||
|
int baseline = FirstHit(player, player.velocity, false);
|
||||||
|
if (baseline > Horizon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Move best = Moves[0];
|
||||||
|
int bestHit = baseline;
|
||||||
|
foreach (Move move in Moves)
|
||||||
|
{
|
||||||
|
if (move == Moves[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var velocity = new Vector2(move.Horizontal * speed, move.Vertical == 0 ? player.velocity.Y : move.Vertical * jump * player.gravDir);
|
||||||
|
int hit = FirstHit(player, velocity, true);
|
||||||
|
if (hit > bestHit)
|
||||||
|
(best, bestHit) = (move, hit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best == Moves[0])
|
||||||
|
return;
|
||||||
|
|
||||||
|
Apply(player, best, speed, jump);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Apply(Player player, Move move, float speed, float jump)
|
||||||
|
{
|
||||||
|
player.controlLeft = move.Horizontal < 0;
|
||||||
|
player.controlRight = move.Horizontal > 0;
|
||||||
|
if (move.Horizontal != 0)
|
||||||
|
player.velocity.X = move.Horizontal * speed;
|
||||||
|
|
||||||
|
player.controlUp = move.Vertical < 0;
|
||||||
|
player.controlDown = move.Vertical > 0;
|
||||||
|
if (move.Vertical != 0)
|
||||||
|
player.velocity.Y = move.Vertical * jump * player.gravDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First tick a threat overlaps the player moving at this velocity, or Horizon + 1 when none do.
|
||||||
|
static int FirstHit(Player player, Vector2 velocity, bool checkWalls)
|
||||||
|
{
|
||||||
|
Vector2 size = new(player.width, player.height);
|
||||||
|
if (checkWalls && TileCollision.Sweep(player.Center, player.Center + velocity * WallCheckTicks, player.width, player.height))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (int t = 1; t <= Horizon; t++)
|
||||||
|
{
|
||||||
|
Vector2 position = player.position + velocity * t;
|
||||||
|
var bounds = new Rectangle((int)(position.X - Margin), (int)(position.Y - Margin), (int)(size.X + Margin * 2), (int)(size.Y + Margin * 2));
|
||||||
|
foreach (Threat threat in Threats)
|
||||||
|
{
|
||||||
|
if (t >= threat.Count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector2 center = threat.Path[t];
|
||||||
|
if (bounds.Intersects(new Rectangle((int)(center.X - threat.Width / 2f), (int)(center.Y - threat.Height / 2f), threat.Width, threat.Height)))
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Horizon + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CollectThreats(Player player)
|
||||||
|
{
|
||||||
|
Threats.Clear();
|
||||||
|
float rangeSq = ScanRange * ScanRange;
|
||||||
|
for (int i = 0; i < Main.maxProjectiles && Threats.Count < MaxThreats; i++)
|
||||||
|
{
|
||||||
|
Projectile projectile = Main.projectile[i];
|
||||||
|
if (!projectile.active || !projectile.hostile || projectile.damage <= 0 || Vector2.DistanceSquared(projectile.Center, player.Center) > rangeSq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!Ballistics.Current(i, out Vector2 velocity, out int age))
|
||||||
|
(velocity, age) = (projectile.velocity * (1 + projectile.extraUpdates), 0);
|
||||||
|
|
||||||
|
Threat threat = Pool[Threats.Count];
|
||||||
|
threat.Count = Ballistics.Path(Ballistics.Get(projectile.type), projectile.Center, velocity, age, Horizon, threat.Path);
|
||||||
|
(threat.Width, threat.Height) = (Math.Max(4, projectile.width), Math.Max(4, projectile.height));
|
||||||
|
Threats.Add(threat);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Main.maxNPCs && Threats.Count < MaxThreats; i++)
|
||||||
|
{
|
||||||
|
NPC npc = Main.npc[i];
|
||||||
|
if (!Hostility.IsHostile(npc) || npc.damage <= 0 || Vector2.DistanceSquared(npc.Center, player.Center) > rangeSq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Threat threat = Pool[Threats.Count];
|
||||||
|
for (int t = 0; t <= Horizon; t++)
|
||||||
|
threat.Path[t] = npc.Center + NpcMotion.Offset(npc, t);
|
||||||
|
(threat.Count, threat.Width, threat.Height) = (Horizon + 1, npc.width, npc.height);
|
||||||
|
Threats.Add(threat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Terraria;
|
using Terraria;
|
||||||
using TerraSharp.Core;
|
using TerraSharp.Core;
|
||||||
|
using TerraSharp.Features.Combat;
|
||||||
using TerraSharp.UI;
|
using TerraSharp.UI;
|
||||||
|
|
||||||
namespace TerraSharp.Features;
|
namespace TerraSharp.Features;
|
||||||
@@ -102,6 +103,7 @@ public static class PlayerFeatures
|
|||||||
ApplyGhost(player);
|
ApplyGhost(player);
|
||||||
|
|
||||||
ApplyVision(player);
|
ApplyVision(player);
|
||||||
|
AutoDodge.Steer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetEffects clears both every tick; NPC.TargetClosest and SetTargetTrackingValues read them.
|
// ResetEffects clears both every tick; NPC.TargetClosest and SetTargetTrackingValues read them.
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ public sealed partial class MainWindow
|
|||||||
Slider("Max range", ref Settings.AimRange, 5f, 150f, 60f, "{0:0} tiles");
|
Slider("Max range", ref Settings.AimRange, 5f, 150f, 60f, "{0:0} tiles");
|
||||||
Toggle("Show target", ref Settings.AimDrawTarget);
|
Toggle("Show target", ref Settings.AimDrawTarget);
|
||||||
});
|
});
|
||||||
|
Toggle("Auto Dodge", ref Settings.AutoDodge);
|
||||||
Toggle("Magic Bullets", ref Settings.MagicBullets);
|
Toggle("Magic Bullets", ref Settings.MagicBullets);
|
||||||
Toggle("Shot Preview", ref Settings.ShotPreview);
|
Toggle("Shot Preview", ref Settings.ShotPreview);
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public sealed partial class MainWindow
|
|||||||
["Exact check"] = "Checks and corrects aim before firing. Auto Attack skips known misses. Orange brackets mean an unconfirmed shot.",
|
["Exact check"] = "Checks and corrects aim before firing. Auto Attack skips known misses. Orange brackets mean an unconfirmed shot.",
|
||||||
["Shot Preview"] = "Shows your next shot's path, including spread and homing.",
|
["Shot Preview"] = "Shows your next shot's path, including spread and homing.",
|
||||||
["Magic Bullets"] = "Your projectiles home in on the aimbot target or the nearest enemy, through blocks.",
|
["Magic Bullets"] = "Your projectiles home in on the aimbot target or the nearest enemy, through blocks.",
|
||||||
|
["Auto Dodge"] = "Moves you out of the way of incoming projectiles and enemies.",
|
||||||
["Auto Attack"] = "Swings at enemies in reach and shoots at enemies your weapon can hit.",
|
["Auto Attack"] = "Swings at enemies in reach and shoots at enemies your weapon can hit.",
|
||||||
["Show target"] = "Shows the cursor radius, target brackets and aim point.",
|
["Show target"] = "Shows the cursor radius, target brackets and aim point.",
|
||||||
["Kill Aura"] = "Kills enemies in range and drops their loot.",
|
["Kill Aura"] = "Kills enemies in range and drops their loot.",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public sealed partial class MainWindow : Window
|
|||||||
[
|
[
|
||||||
new Page("Player", PlayerPage, () => Count(Settings.GodMode, Settings.InfHealth, Settings.InfMana, Settings.InfBreath, Settings.InfFlight, Settings.InstantRespawn, Settings.AutoHeal, Settings.AutoMana, Settings.GhostMode, Settings.DefenseBoost)),
|
new Page("Player", PlayerPage, () => Count(Settings.GodMode, Settings.InfHealth, Settings.InfMana, Settings.InfBreath, Settings.InfFlight, Settings.InstantRespawn, Settings.AutoHeal, Settings.AutoMana, Settings.GhostMode, Settings.DefenseBoost)),
|
||||||
new Page("Movement", MovementPage, () => Count(Settings.Fly, Settings.SuperSpeed, Settings.HighJump, Settings.GravityFlip, Settings.NoFallDamage, Settings.LavaImmune, Settings.WaterWalk, Settings.NoKnockback, Settings.ExtendedReach)),
|
new Page("Movement", MovementPage, () => Count(Settings.Fly, Settings.SuperSpeed, Settings.HighJump, Settings.GravityFlip, Settings.NoFallDamage, Settings.LavaImmune, Settings.WaterWalk, Settings.NoKnockback, Settings.ExtendedReach)),
|
||||||
new Page("Combat", CombatPage, () => Count(Settings.RapidAttack, Settings.AutoSwing, Settings.DamageBoost, Settings.NoManaCost, Settings.NoSpread, Settings.Aimbot, Settings.AutoAttack, Settings.KillAura, Settings.HitMagnet, Settings.FreezeEnemies, Settings.WeakenEnemies, Settings.MagicBullets)),
|
new Page("Combat", CombatPage, () => Count(Settings.RapidAttack, Settings.AutoSwing, Settings.DamageBoost, Settings.NoManaCost, Settings.NoSpread, Settings.Aimbot, Settings.AutoAttack, Settings.KillAura, Settings.HitMagnet, Settings.FreezeEnemies, Settings.WeakenEnemies, Settings.MagicBullets, Settings.AutoDodge)),
|
||||||
new Page("Items", ItemsPage, () => Count(Settings.InstantBreak, Settings.InfItems, Settings.ItemVacuum, Settings.AutoSell, Settings.AutoFish, Settings.Sonar)),
|
new Page("Items", ItemsPage, () => Count(Settings.InstantBreak, Settings.InfItems, Settings.ItemVacuum, Settings.AutoSell, Settings.AutoFish, Settings.Sonar)),
|
||||||
new Page("Visuals", VisualsPage, () => Count(Settings.Esp, Settings.Spelunker, Settings.Hunter, Settings.Shine, Settings.NightOwl, Settings.DangerSense, Settings.BiomeSight, Settings.FullBright, Settings.ExtendedZoom)),
|
new Page("Visuals", VisualsPage, () => Count(Settings.Esp, Settings.Spelunker, Settings.Hunter, Settings.Shine, Settings.NightOwl, Settings.DangerSense, Settings.BiomeSight, Settings.FullBright, Settings.ExtendedZoom)),
|
||||||
new Page("World", WorldPage, () => Count(Settings.FreezeTime, Settings.SpawnRateBoost, Settings.MapTeleport)),
|
new Page("World", WorldPage, () => Count(Settings.FreezeTime, Settings.SpawnRateBoost, Settings.MapTeleport)),
|
||||||
|
|||||||
Reference in new issue
Block a user