From c334aa7c149eded259577dd4ea76150ecbb9344a Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 9 Sep 2016 19:47:03 +1000 Subject: [PATCH] Make kill instruction 200% more killer (does better dist check, instead of checking if block coords same) --- Bots/Instructions.cs | 48 --------------- Bots/Instructions/ComplexInstructions.cs | 76 +++++++++++++++++++++++- Bots/Instructions/Instruction.cs | 17 +++++- Bots/PlayerBot.cs | 17 ++++-- Bots/ScriptFile.cs | 2 +- 5 files changed, 103 insertions(+), 57 deletions(-) diff --git a/Bots/Instructions.cs b/Bots/Instructions.cs index 0ec1abd7c..b23532d10 100644 --- a/Bots/Instructions.cs +++ b/Bots/Instructions.cs @@ -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; - } - } } } diff --git a/Bots/Instructions/ComplexInstructions.cs b/Bots/Instructions/ComplexInstructions.cs index b33efcd1e..4f27d93d7 100644 --- a/Bots/Instructions/ComplexInstructions.cs +++ b/Bots/Instructions/ComplexInstructions.cs @@ -16,8 +16,80 @@ permissions and limitations under the Licenses. */ using System; -using System.Collections.Generic; -using System.IO; namespace MCGalaxy.Bots { + + /// Causes the bot to move towards the closest human, within a defined search radius. + 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); + } + } + + /// Causes the bot to kill nearby humans. + 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); + } + } } diff --git a/Bots/Instructions/Instruction.cs b/Bots/Instructions/Instruction.cs index cf2b8a0a9..66c0887c7 100644 --- a/Bots/Instructions/Instruction.cs +++ b/Bots/Instructions/Instruction.cs @@ -22,7 +22,7 @@ using System.IO; namespace MCGalaxy.Bots { /// Represents an action that a bot will perform - public abstract class Instruction { + public abstract class BotInstruction { /// Gets the identifying name for this instruction. public abstract string Name { get; } @@ -34,12 +34,25 @@ namespace MCGalaxy.Bots { /// Parses the given line which contains the metadata for this instruction. public abstract InstructionData Parse(string[] args); + + /// All instructions that bots can execute. + public static List Instructions = new List() { + new HuntInstruction(), new KillInstruction(), + }; + + /// Finds the instruction which has the given identifying name. + 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; } } diff --git a/Bots/PlayerBot.cs b/Bots/PlayerBot.cs index 6686bb86f..3c639cccf 100644 --- a/Bots/PlayerBot.cs +++ b/Bots/PlayerBot.cs @@ -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 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); } diff --git a/Bots/ScriptFile.cs b/Bots/ScriptFile.cs index da3b1e601..17cfd9be8 100644 --- a/Bots/ScriptFile.cs +++ b/Bots/ScriptFile.cs @@ -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;