Make kill instruction 200% more killer (does better dist check, instead of checking if block coords same)

This commit is contained in:
UnknownShadow200 2016-09-09 19:47:03 +10:00
parent f2eef89460
commit c334aa7c14
5 changed files with 103 additions and 57 deletions

View File

@ -143,53 +143,5 @@ namespace MCGalaxy.Bots {
}
bot.NextInstruction(); return true;
}
internal static void DoKill(PlayerBot bot) {
ushort x = (ushort)Math.Round((decimal)bot.pos[0] / 32);
ushort y = (ushort)((bot.pos[1] - 33) / 32);
ushort z = (ushort)Math.Round((decimal)bot.pos[2] / 32);
Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) {
if ((ushort)(p.pos[0] / 32) == x
&& Math.Abs((ushort)(p.pos[1] / 32) - y) < 2
&& (ushort)(p.pos[2] / 32) == z) {
p.HandleDeath(Block.Zero);
}
}
}
internal static void DoHunt(PlayerBot bot) {
int dist = 75 * 32;
Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) {
if (p.level != bot.level || p.invincible) continue;
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;
dist = curDist;
bot.foundPos = p.pos;
bot.movement = true;
Vec3F32 dir = new Vec3F32(dx, dy, dz);
dir = Vec3F32.Normalise(dir);
byte yaw, pitch;
DirUtils.GetYawPitch(dir, out yaw, out pitch);
// 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;
}
}
}
}

View File

@ -16,8 +16,80 @@
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using System.IO;
namespace MCGalaxy.Bots {
/// <summary> Causes the bot to move towards the closest human, within a defined search radius. </summary>
public sealed class HuntInstruction : BotInstruction {
public override string Name { get { return "Hunt"; } }
const int searchRadius = 75;
public override bool Execute(PlayerBot bot, InstructionData data) {
int dist = searchRadius * 32;
Player[] players = PlayerInfo.Online.Items;
Player closest = null;
foreach (Player p in players) {
if (p.level != bot.level || p.invincible) continue;
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;
closest = p;
}
if (closest == null) return true;
MoveTowards(bot, closest);
return false;
}
static void MoveTowards(PlayerBot bot, Player p) {
int dx = p.pos[0] - bot.pos[0], dy = p.pos[1] - bot.pos[1], dz = p.pos[2] - bot.pos[2];
bot.foundPos = p.pos;
bot.movement = true;
Vec3F32 dir = new Vec3F32(dx, dy, dz);
dir = Vec3F32.Normalise(dir);
byte yaw, pitch;
DirUtils.GetYawPitch(dir, out yaw, out pitch);
// 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;
}
public override InstructionData Parse(string[] args) {
return default(InstructionData);
}
}
/// <summary> Causes the bot to kill nearby humans. </summary>
public sealed class KillInstruction : BotInstruction {
public override string Name { get { return "Kill"; } }
public override bool Execute(PlayerBot bot, InstructionData data) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) {
int dx = Math.Abs(bot.pos[0] - p.pos[0]);
int dy = Math.Abs(bot.pos[1] - p.pos[1]);
int dz = Math.Abs(bot.pos[2] - p.pos[2]);
if (dx <= 8 && dy <= 16 && dz <= 8) {
p.HandleDeath(Block.Zero);
}
}
return true;
}
public override InstructionData Parse(string[] args) {
return default(InstructionData);
}
}
}

View File

@ -22,7 +22,7 @@ using System.IO;
namespace MCGalaxy.Bots {
/// <summary> Represents an action that a bot will perform </summary>
public abstract class Instruction {
public abstract class BotInstruction {
/// <summary> Gets the identifying name for this instruction. </summary>
public abstract string Name { get; }
@ -34,12 +34,25 @@ namespace MCGalaxy.Bots {
/// <summary> Parses the given line which contains the metadata for this instruction. </summary>
public abstract InstructionData Parse(string[] args);
/// <summary> All instructions that bots can execute. </summary>
public static List<BotInstruction> Instructions = new List<BotInstruction>() {
new HuntInstruction(), new KillInstruction(),
};
/// <summary> Finds the instruction which has the given identifying name. </summary>
public static BotInstruction Find(string name) {
foreach (BotInstruction ins in Instructions) {
if (ins.Name.CaselessEq(name)) return ins;
}
return null;
}
}
public struct InstructionData {
public string type, newscript;
public int seconds, rotspeed;
public ushort x, y, z;
public byte rotx, roty;
public byte rotx, roty;
}
}

View File

@ -206,11 +206,17 @@ namespace MCGalaxy {
// Script handling
void BotTimerFunc(object sender, ElapsedEventArgs e) {
if (kill) Instructions.DoKill(this);
if (kill) {
InstructionData data = default(InstructionData);
BotInstruction.Find("kill").Execute(this, data);
}
movement = false;
if (Waypoints.Count == 0) {
if (hunt) Instructions.DoHunt(this);
if (hunt) {
InstructionData data = default(InstructionData);
BotInstruction.Find("hunt").Execute(this, data);
}
} else {
bool doNextInstruction = !DoInstruction();
if (cur == Waypoints.Count) cur = 0;
@ -225,8 +231,11 @@ namespace MCGalaxy {
bool DoInstruction() {
Func<PlayerBot, bool> instruction;
if (!Instructions.Defined.TryGetValue(Waypoints[cur].type, out instruction))
return false;
if (!Instructions.Defined.TryGetValue(Waypoints[cur].type, out instruction)) {
BotInstruction botIns = BotInstruction.Find(Waypoints[cur].type);
if (botIns == null) return false;
return botIns.Execute(this, Waypoints[cur]);
}
return instruction(this);
}

View File

@ -27,7 +27,7 @@ namespace MCGalaxy.Bots {
string[] codes = File.ReadAllLines(file);
if (codes[0] != "#Version 2") { Player.Message(p, "Invalid file version. Remake"); return false; }
PlayerBot.InstructionData newPos = new PlayerBot.InstructionData();
InstructionData newPos = new InstructionData();
try { bot.Waypoints.Clear(); } catch { }
bot.cur = 0; bot.countdown = 0; bot.movementSpeed = 3;