mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 12:05:51 -04:00
Bots should rotate when hunting to face the target player.
This commit is contained in:
parent
d501219f4f
commit
c25602b429
@ -165,19 +165,30 @@ namespace MCGalaxy.Bots {
|
|||||||
Player[] players = PlayerInfo.Online.Items;
|
Player[] players = PlayerInfo.Online.Items;
|
||||||
foreach (Player p in players) {
|
foreach (Player p in players) {
|
||||||
if (p.level != bot.level || p.invincible) continue;
|
if (p.level != bot.level || p.invincible) continue;
|
||||||
int curDist = Math.Abs(p.pos[0] - bot.pos[0]) + Math.Abs(p.pos[1] - bot.pos[1]) + Math.Abs(p.pos[2] - bot.pos[2]);
|
|
||||||
|
int dx = p.pos[0] - bot.pos[0], dy = p.pos[1] - bot.pos[1], dz = p.pos[2] - bot.pos[2];
|
||||||
|
int curDist = Math.Abs(dx) + Math.Abs(dy) + Math.Abs(dz);
|
||||||
if (curDist >= dist) continue;
|
if (curDist >= dist) continue;
|
||||||
|
|
||||||
dist = curDist;
|
dist = curDist;
|
||||||
bot.foundPos = p.pos;
|
bot.foundPos = p.pos;
|
||||||
bot.foundRot = p.rot;
|
|
||||||
bot.movement = true;
|
bot.movement = true;
|
||||||
|
|
||||||
bot.rot[1] = (byte)(255 - bot.foundRot[1]);
|
Vec3F32 dir = new Vec3F32(dx, dy, dz);
|
||||||
if (bot.foundRot[0] < 128)
|
dir = Vec3F32.Normalise(dir);
|
||||||
bot.rot[0] = (byte)(bot.foundRot[0] + 128);
|
byte yaw, pitch;
|
||||||
else
|
DirUtils.GetYawPitch(dir, out yaw, out pitch);
|
||||||
bot.rot[0] = (byte)(bot.foundRot[0] - 128);
|
|
||||||
|
// If we are very close to a player, switch from trying to look
|
||||||
|
// at them to just facing the opposite direction to them
|
||||||
|
if (Math.Abs(dx) >= 4 || Math.Abs(dz) >= 4) {
|
||||||
|
bot.rot[0] = yaw;
|
||||||
|
} else if (p.rot[0] < 128) {
|
||||||
|
bot.rot[0] = (byte)(p.rot[0] + 128);
|
||||||
|
} else {
|
||||||
|
bot.rot[0] = (byte)(p.rot[0] - 128);
|
||||||
|
}
|
||||||
|
bot.rot[1] = pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ namespace MCGalaxy {
|
|||||||
public struct Pos { public string type, newscript; public int seconds, rotspeed; public ushort x, y, z; public byte rotx, roty; }
|
public struct Pos { public string type, newscript; public int seconds, rotspeed; public ushort x, y, z; public byte rotx, roty; }
|
||||||
|
|
||||||
public ushort[] pos = new ushort[3], oldpos = new ushort[3], foundPos = new ushort[3];
|
public ushort[] pos = new ushort[3], oldpos = new ushort[3], foundPos = new ushort[3];
|
||||||
public byte[] rot = new byte[2], oldrot = new byte[2], foundRot = new byte[2];
|
public byte[] rot = new byte[2], oldrot = new byte[2];
|
||||||
public bool movement = false;
|
public bool movement = false;
|
||||||
public int movementSpeed = 3;
|
public int movementSpeed = 3;
|
||||||
internal bool jumping = false;
|
internal bool jumping = false;
|
||||||
|
@ -38,7 +38,7 @@ namespace MCGalaxy.Commands {
|
|||||||
|
|
||||||
void DoShoot(Player p, byte type, byte extType) {
|
void DoShoot(Player p, byte type, byte extType) {
|
||||||
CatchPos bp = (CatchPos)p.blockchangeObject;
|
CatchPos bp = (CatchPos)p.blockchangeObject;
|
||||||
Vec3F32 dir = DirUtils.GetDirVector(p.rot[0], p.rot[1]);
|
Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]);
|
||||||
|
|
||||||
double bigDiag = Math.Sqrt(Math.Sqrt(p.level.Width * p.level.Width + p.level.Length * p.level.Length)
|
double bigDiag = Math.Sqrt(Math.Sqrt(p.level.Width * p.level.Width + p.level.Length * p.level.Length)
|
||||||
+ p.level.Height * p.level.Height + p.level.Width * p.level.Width);
|
+ p.level.Height * p.level.Height + p.level.Width * p.level.Width);
|
||||||
|
@ -51,7 +51,7 @@ namespace MCGalaxy.Commands {
|
|||||||
while (true) {
|
while (true) {
|
||||||
Vec3U16 start = MakePos(p);
|
Vec3U16 start = MakePos(p);
|
||||||
total++;
|
total++;
|
||||||
Vec3F32 dir = DirUtils.GetDirVector(p.rot[0], p.rot[1]);
|
Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]);
|
||||||
|
|
||||||
Vec3U16 lookedAt;
|
Vec3U16 lookedAt;
|
||||||
int i;
|
int i;
|
||||||
|
@ -79,7 +79,7 @@ namespace MCGalaxy.Commands {
|
|||||||
void DoAim(Player p) {
|
void DoAim(Player p) {
|
||||||
List<Vec3U16> lastSent = new List<Vec3U16>(), toSend = new List<Vec3U16>();
|
List<Vec3U16> lastSent = new List<Vec3U16>(), toSend = new List<Vec3U16>();
|
||||||
while (p.aiming) {
|
while (p.aiming) {
|
||||||
Vec3F32 dir = DirUtils.GetDirVector(p.rot[0], p.rot[1]);
|
Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]);
|
||||||
try {
|
try {
|
||||||
ushort x = (ushort)Math.Round((ushort)(p.pos[0] / 32) + dir.X * 3);
|
ushort x = (ushort)Math.Round((ushort)(p.pos[0] / 32) + dir.X * 3);
|
||||||
ushort y = (ushort)Math.Round((ushort)(p.pos[1] / 32) + dir.Y * 3);
|
ushort y = (ushort)Math.Round((ushort)(p.pos[1] / 32) + dir.Y * 3);
|
||||||
|
@ -75,7 +75,7 @@ namespace MCGalaxy {
|
|||||||
dirY = -1;
|
dirY = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3F32 GetDirVector(byte yaw, byte pitch) {
|
public static Vec3F32 GetFlatDirVector(byte yaw, byte pitch) {
|
||||||
const double packed2Rad = (2 * Math.PI) / 256.0;
|
const double packed2Rad = (2 * Math.PI) / 256.0;
|
||||||
double x = Math.Sin(yaw * packed2Rad);
|
double x = Math.Sin(yaw * packed2Rad);
|
||||||
double y = -Math.Sin(pitch * packed2Rad); // e.g. 64 -> PI/2, result should be -1
|
double y = -Math.Sin(pitch * packed2Rad); // e.g. 64 -> PI/2, result should be -1
|
||||||
@ -83,7 +83,7 @@ namespace MCGalaxy {
|
|||||||
return new Vec3F32((float)x, (float)y, (float)z);
|
return new Vec3F32((float)x, (float)y, (float)z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3F32 GetAdjDirVector(byte yaw, byte pitch) {
|
public static Vec3F32 GetDirVector(byte yaw, byte pitch) {
|
||||||
const double packed2Rad = (2 * Math.PI) / 256.0;
|
const double packed2Rad = (2 * Math.PI) / 256.0;
|
||||||
double x = Math.Sin(yaw * packed2Rad) * Math.Cos(pitch * packed2Rad);
|
double x = Math.Sin(yaw * packed2Rad) * Math.Cos(pitch * packed2Rad);
|
||||||
double y = -Math.Sin(pitch * packed2Rad);
|
double y = -Math.Sin(pitch * packed2Rad);
|
||||||
@ -92,35 +92,22 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void GetYawPitch(Vec3F32 dir, out byte yaw, out byte pitch) {
|
public static void GetYawPitch(Vec3F32 dir, out byte yaw, out byte pitch) {
|
||||||
// y = -sin(pitch) -> pitch = arcsin(-y)
|
// y = -sin(pitch) -> pitch = arcsin(-y)
|
||||||
// x = sin(yaw) * cos(pitch) -> yaw = arcsin(x/cos(pitch))
|
// x = sin(yaw) -> yaw = arcsin(x)
|
||||||
// z = -cos(yaw) * cos(pitch) -> yaw = arccos(-z/cos(pitch))
|
// z = -cos(yaw) -> yaw = arccos(-z)
|
||||||
|
|
||||||
|
// We ignore the cos(pitch) multiplication by the x/z components, since
|
||||||
|
// this does not affect the resulting yaw
|
||||||
const double rad2Packed = 256.0 / (2 * Math.PI);
|
const double rad2Packed = 256.0 / (2 * Math.PI);
|
||||||
|
|
||||||
// NOTE: This conversion method **does** lose information
|
// NOTE: This conversion method **does** lose information
|
||||||
// a) If pitch is 0, yaw cannot be properly recalculated
|
// a) If x and z are 0, yaw cannot be properly recalculated
|
||||||
// b) Pitch will always be from 0-64 or 192-256, therefore flipped heads lost
|
// b) Pitch will always be from 0-64 or 192-256, therefore flipped heads lost
|
||||||
// However since we have X/Z, this problem does not occur for yaw,
|
// However since we have X/Z, this problem does not occur for yaw,
|
||||||
// as we can use both values to determine which side of unit circle yaw is in
|
// as we can use both values to determine which side of unit circle yaw is in
|
||||||
// c) Resulting yaw/pitch may be 1 or 2 values off due to rounding
|
// c) Resulting yaw/pitch may be 1 or 2 values off due to rounding
|
||||||
|
yaw = (byte)(Math.Atan2(dir.X, -dir.Z) * rad2Packed);
|
||||||
double pitchRad = Math.Asin(-dir.Y);
|
pitch = (byte)(Math.Asin(-dir.Y) * rad2Packed);
|
||||||
double cosPitch = Math.Cos(pitchRad);
|
|
||||||
double yawRad = Math.Asin(dir.X / cosPitch);
|
|
||||||
yaw = (byte)(yawRad * rad2Packed);
|
|
||||||
pitch = (byte)(pitchRad * rad2Packed);
|
|
||||||
yaw = AdjustYaw(dir, yaw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte AdjustYaw(Vec3F32 dir, byte yaw) {
|
|
||||||
// Other side of unit circle
|
|
||||||
if (dir.Z > 0) return (byte)(128 - yaw);
|
|
||||||
const double epsilon = 0.0000001;
|
|
||||||
|
|
||||||
if (dir.Z >= 0 && dir.Z < +epsilon) return 192; // exactly +X
|
|
||||||
if (dir.Z <= 0 && dir.Z > -epsilon) return 64; // exactly -X
|
|
||||||
if (dir.X >= 0 && dir.X < +epsilon) return 0; // exactly -Z
|
|
||||||
if (dir.X <= 0 && dir.X > -epsilon) return 128; // exactly +Z
|
|
||||||
return yaw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user