Move bots to be per-level, remove obsolete bot functions and minorly optimise bots

This commit is contained in:
UnknownShadow200 2017-08-01 22:26:05 +10:00
parent f843237188
commit 16e87c8c3a
19 changed files with 60 additions and 109 deletions

View File

@ -93,15 +93,12 @@ namespace MCGalaxy.Bots {
public static void UnloadBots(Level lvl) {
lock (locker) {
PlayerBot[] bots = PlayerBot.Bots.Items;
bool hasBots = false;
PlayerBot[] bots = lvl.Bots.Items;
foreach (PlayerBot bot in bots) {
if (bot.level != lvl) continue;
DoUpdateBot(bot, false);
hasBots = true;
}
if (hasBots) Save();
if (bots.Length > 0) Save();
}
}

View File

@ -37,11 +37,12 @@ namespace MCGalaxy {
}
static void BotsTick(SchedulerTask task) {
PlayerBot[] bots = PlayerBot.Bots.Items;
for (int i = 0; i < bots.Length; i++) {
BotTick(bots[i]);
Level[] levels = LevelInfo.Loaded.Items;
for (int i = 0; i < levels.Length; i++) {
PlayerBot[] bots = levels[i].Bots.Items;
for (int j = 0; j < bots.Length; j++) { BotTick(bots[j]); }
}
}
}
static void BotTick(PlayerBot bot) {
if (bot.kill) {
@ -72,17 +73,17 @@ namespace MCGalaxy {
BotInstruction ins = BotInstruction.Find(bot.Instructions[bot.cur].Name);
if (ins == null) return false;
return ins.Execute(bot, bot.Instructions[bot.cur]);
}
}
static void DoJump(PlayerBot bot) {
bot.currentjump++;
Position pos = bot.Pos;
switch (bot.currentjump) {
case 1: pos.Y += 24; break;
case 2: pos.Y += 12; break;
case 3: break;
case 4: pos.Y -= 12; break;
case 5: pos.Y -= 24; bot.jumping = false; bot.currentjump = 0; break;
case 1: pos.Y += 24; break;
case 2: pos.Y += 12; break;
case 3: break;
case 4: pos.Y -= 12; break;
case 5: pos.Y -= 24; bot.jumping = false; bot.currentjump = 0; break;
}
bot.Pos = pos;
}

View File

@ -22,7 +22,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to nod spin around for a certain interval. </summary>
public class SpinInstruction : BotInstruction {
public override string Name { get { return "spin"; } }
public SpinInstruction() { Name = "spin"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
Metadata meta = (Metadata)data.Metadata;
@ -65,7 +65,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to nod down up and down for a certain interval. </summary>
public sealed class NodInstruction : SpinInstruction {
public override string Name { get { return "nod"; } }
public NodInstruction() { Name = "nod"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
Metadata meta = (Metadata)data.Metadata;

View File

@ -23,7 +23,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to move towards the closest player, within a defined search radius. </summary>
public sealed class HuntInstruction : BotInstruction {
public override string Name { get { return "hunt"; } }
public HuntInstruction() { Name = "hunt"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
int search = 75;
@ -99,7 +99,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to kill nearby players. </summary>
public sealed class KillInstruction : BotInstruction {
public override string Name { get { return "kill"; } }
public KillInstruction() { Name = "kill"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
Player[] players = PlayerInfo.Online.Items;
@ -123,7 +123,7 @@ namespace MCGalaxy.Bots {
}
public sealed class StareInstruction : BotInstruction {
public override string Name { get { return "stare"; } }
public StareInstruction() { Name = "stare"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
int search = 20000;

View File

@ -25,7 +25,7 @@ namespace MCGalaxy.Bots {
public abstract class BotInstruction {
/// <summary> Gets the identifying name for this instruction. </summary>
public abstract string Name { get; }
public string Name;
/// <summary> Performs a tick for this instruction. </summary>
/// <returns> false if the bot should proceed to execute the

View File

@ -22,7 +22,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to instantly teleport to a position. </summary>
public class TeleportInstruction : BotInstruction {
public override string Name { get { return "teleport"; } }
public TeleportInstruction() { Name = "teleport"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
Coords coords = (Coords)data.Metadata;
@ -65,7 +65,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to gradually move to to a position. </summary>
public sealed class WalkInstruction : TeleportInstruction {
public override string Name { get { return "walk"; } }
public WalkInstruction() { Name = "walk"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
Coords target = (Coords)data.Metadata;
@ -91,7 +91,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to begin jumping. </summary>
public sealed class JumpInstruction : BotInstruction {
public override string Name { get { return "jump"; } }
public JumpInstruction() { Name = "jump"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
bot.jumping = true;
@ -109,7 +109,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to change how fast it moves. </summary>
public sealed class SpeedInstruction : BotInstruction {
public override string Name { get { return "speed"; } }
public SpeedInstruction() { Name = "speed"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
bot.movementSpeed = (int)Math.Round(3m * (short)data.Metadata / 100m);

View File

@ -22,7 +22,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to reset to the and execute first instruction. </summary>
public sealed class ResetInstruction : BotInstruction {
public override string Name { get { return "reset"; } }
public ResetInstruction() { Name = "reset"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
bot.cur = 0; return false;
@ -37,7 +37,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to be removed from the world. </summary>
public sealed class RemoveInstruction : BotInstruction {
public override string Name { get { return "remove"; } }
public RemoveInstruction() { Name = "remove"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
PlayerBot.Remove(bot); return true;
@ -52,7 +52,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to switch to a different AI. </summary>
public sealed class LinkScriptInstruction : BotInstruction {
public override string Name { get { return "linkscript"; } }
public LinkScriptInstruction() { Name = "linkscript"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
string script = (string)data.Metadata;
@ -87,7 +87,7 @@ namespace MCGalaxy.Bots {
/// <summary> Causes the bot to wait/do nothing for a certain interval. </summary>
public sealed class WaitInstruction : BotInstruction {
public override string Name { get { return "wait"; } }
public WaitInstruction() { Name = "wait"; }
public override bool Execute(PlayerBot bot, InstructionData data) {
if (bot.countdown == 0) {

View File

@ -23,10 +23,6 @@ using MCGalaxy.Maths;
namespace MCGalaxy {
public sealed class PlayerBot : Entity {
[Obsolete("Use PlayerBot.Bots.Items instead")]
public static List<PlayerBot> playerbots;
public static VolatileArray<PlayerBot> Bots = new VolatileArray<PlayerBot>(true);
public bool hunt = false, kill = false;
@ -42,8 +38,6 @@ namespace MCGalaxy {
public List<InstructionData> Instructions = new List<InstructionData>();
public Position TargetPos;
public ushort[] pos = new ushort[3];
public byte[] rot = new byte[2];
public bool movement = false;
public int movementSpeed = 3;
internal bool jumping = false;
@ -72,26 +66,14 @@ namespace MCGalaxy {
public override byte EntityID { get { return id; } }
public override Level Level { get { return level; } }
protected override void OnSetPos() {
Position p = Pos;
pos[0] = (ushort)p.X; pos[1] = (ushort)p.Y; pos[2] = (ushort)p.Z;
}
protected override void OnSetRot() {
Orientation r = Rot;
rot[0] = r.RotY; rot[1] = r.HeadX;
}
public static void Add(PlayerBot bot, bool save = true) {
Bots.Add(bot);
bot.GlobalSpawn();
if (save)
BotsFile.UpdateBot(bot);
bot.level.Bots.Add(bot);
bot.GlobalSpawn();
if (save) BotsFile.UpdateBot(bot);
}
public static void Remove(PlayerBot bot, bool save = true) {
Bots.Remove(bot);
bot.level.Bots.Remove(bot);
bot.GlobalDespawn();
bot.jumping = false;
if (save) BotsFile.RemoveBot(bot);
@ -108,10 +90,9 @@ namespace MCGalaxy {
}
static void RemoveLoadedBots(Level lvl, bool save) {
PlayerBot[] bots = Bots.Items;
PlayerBot[] bots = lvl.Bots.Items;
for (int i = 0; i < bots.Length; i++) {
PlayerBot bot = bots[i];
if (bots[i].level == lvl) Remove(bot, save);
Remove(bots[i], save);
}
}
@ -131,22 +112,11 @@ namespace MCGalaxy {
}
public static void GlobalUpdatePosition() {
PlayerBot[] bots = Bots.Items;
foreach (PlayerBot b in bots) b.UpdatePosition();
}
public static PlayerBot Find(string name) {
PlayerBot match = null; int matches = 0;
PlayerBot[] bots = Bots.Items;
foreach (PlayerBot bot in bots) {
if (bot.name.CaselessEq(name)) return bot;
if (bot.name.CaselessContains(name)) {
match = bot; matches++;
}
Level[] levels = LevelInfo.Loaded.Items;
for (int i = 0; i < levels.Length; i++) {
PlayerBot[] bots = levels[i].Bots.Items;
for (int j = 0; j < bots.Length; j++) { bots[j].UpdatePosition(); }
}
return matches == 1 ? match : null;
}
void UpdatePosition() {
@ -179,10 +149,9 @@ namespace MCGalaxy {
used[i] = 0;
// Lock to ensure that no two bots can end up with the same playerid
lock (Bots.locker) {
PlayerBot[] bots = Bots.Items;
lock (bot.level.Bots.locker) {
PlayerBot[] bots = bot.level.Bots.Items;
for (int i = 0; i < bots.Length; i++) {
if (bots[i].level != bot.level) continue;
byte id = bots[i].id;
used[id] = 1;
}

View File

@ -34,7 +34,7 @@ namespace MCGalaxy.Commands.Bots {
if (message.CaselessEq("all")) {
PlayerBot.RemoveAllFromLevel(p.level); return;
} else {
PlayerBot bot = Matcher.FindBotsInLevel(p, message);
PlayerBot bot = Matcher.FindBots(p, message);
if (bot == null) return;
PlayerBot.Remove(bot);

View File

@ -25,6 +25,7 @@ namespace MCGalaxy.Commands.Bots {
public override string type { get { return CommandTypes.Other; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
public override bool SuperUseable { get { return false; } }
public override CommandPerm[] ExtraPerms {
get { return new[] { new CommandPerm(LevelPermission.Operator, "+ can set bots to be killer") }; }
}
@ -32,7 +33,7 @@ namespace MCGalaxy.Commands.Bots {
public override void Use(Player p, string message) {
if (message.Length == 0) { Help(p); return; }
string[] args = message.SplitSpaces();
PlayerBot bot = Matcher.FindBotsInLevel(p, args[0]);
PlayerBot bot = Matcher.FindBots(p, args[0]);
if (bot == null) return;
if (p != null && !bot.level.BuildAccess.CheckDetailed(p)) {

View File

@ -32,7 +32,7 @@ namespace MCGalaxy.Commands.Bots {
return;
}
PlayerBot bot = Matcher.FindBotsInLevel(p, message);
PlayerBot bot = Matcher.FindBots(p, message);
if (bot == null) return;
bot.Pos = p.Pos; bot.SetYawPitch(p.Rot.RotY, p.Rot.HeadX);

View File

@ -36,19 +36,12 @@ namespace MCGalaxy.Commands.Bots {
if (lvl == null) return;
}
PlayerBot[] bots = PlayerBot.Bots.Items;
List<PlayerBot> inScope = new List<PlayerBot>();
foreach (PlayerBot bot in bots) {
if (lvl != null && bot.level != lvl) continue;
inScope.Add(bot);
}
string cmd = (lvl == null || lvl == p.level) ? "bots" : "bots " + lvl.name;
PlayerBot[] bots = lvl.Bots.Items;
string cmd = (lvl == p.level) ? "bots" : "bots " + lvl.name;
string modifier = args.Length > offset ? args[offset] : "";
string group = lvl == null ? "All bots:" : "Bots in " + lvl.ColoredName + ":";
Player.Message(p, group);
MultiPageOutput.Output(p, inScope, FormatBot, cmd, "Bots", modifier, false);
Player.Message(p, "Bots in " + lvl.ColoredName + ":");
MultiPageOutput.Output(p, bots, FormatBot, cmd, "Bots", modifier, false);
}
static string FormatBot(PlayerBot bot) {

View File

@ -28,7 +28,7 @@ namespace MCGalaxy.Commands {
Player who = null;
PlayerBot bot = null;
if (isBot) bot = Matcher.FindBotsInLevel(p, args[1]);
if (isBot) bot = Matcher.FindBots(p, args[1]);
else who = PlayerInfo.FindMatches(p, args[0]);
if (bot == null && who == null) return;

View File

@ -41,7 +41,7 @@ namespace MCGalaxy.Commands.Misc {
if (target == null) return;
if (!CheckPlayer(p, target)) return;
} else if (args[0].CaselessEq("bot")) {
bot = Matcher.FindBotsInLevel(p, args[1]);
bot = Matcher.FindBots(p, args[1]);
if (bot == null) return;
} else {
Help(p); return;

View File

@ -113,9 +113,8 @@ namespace MCGalaxy {
GlobalSpawn(p, pos, rot, true);
if (!bots) return;
PlayerBot[] botsList = PlayerBot.Bots.Items;
foreach (PlayerBot b in botsList)
if (b.level == p.level) Spawn(p, b);
PlayerBot[] botsList = p.level.Bots.Items;
foreach (PlayerBot b in botsList) { Spawn(p, b); }
}
/// <summary> Despawns this player to all other players, and despawns all others players to this player. </summary>
@ -127,10 +126,8 @@ namespace MCGalaxy {
GlobalDespawn(p, true, true);
if (!bots) return;
PlayerBot[] botsList = PlayerBot.Bots.Items;
foreach (PlayerBot b in botsList) {
if (p.level == b.level) Despawn(p, b);
}
PlayerBot[] botsList = p.level.Bots.Items;
foreach (PlayerBot b in botsList) { Despawn(p, b); }
}
internal static void Spawn(Player dst, PlayerBot b) {

View File

@ -42,6 +42,7 @@ namespace MCGalaxy {
public BlockDefinition[] CustomBlockDefs = new BlockDefinition[Block.Count];
public BlockProps[] BlockProps = new BlockProps[Block.Count * 2];
public ExtrasCollection Extras = new ExtrasCollection();
public VolatileArray<PlayerBot> Bots = new VolatileArray<PlayerBot>(false);
internal HandleDelete[] deleteHandlers = new HandleDelete[Block.Count * 2];
internal HandlePlace[] placeHandlers = new HandlePlace[Block.Count * 2];

View File

@ -339,7 +339,7 @@ namespace MCGalaxy {
lvl.Config.jailroty = lvl.roty;
LoadMetadata(lvl);
Bots.BotsFile.LoadBots(lvl);
MCGalaxy.Bots.BotsFile.LoadBots(lvl);
object locker = ThreadSafeCache.DBCache.GetLocker(name);
lock (locker) {

View File

@ -78,7 +78,6 @@ namespace MCGalaxy {
Player.players = PlayerInfo.Online.list;
PlayerInfo.players = PlayerInfo.Online.list;
Server.levels = LevelInfo.Loaded.list;
PlayerBot.playerbots = PlayerBot.Bots.list;
#pragma warning restore 0618
StartTime = DateTime.UtcNow;

View File

@ -36,18 +36,11 @@ namespace MCGalaxy {
return award == null ? null : award.Name;
}
/// <summary> Finds partial matches of 'name' against the list of all bots. </summary>
/// <summary> Finds partial matches of 'name' against the list of bots in same level as player. </summary>
public static PlayerBot FindBots(Player p, string name) {
int matches = 0;
return Find<PlayerBot>(p, name, out matches, PlayerBot.Bots.Items,
null, b => b.name, "bots");
}
/// <summary> Finds partial matches of 'name' against the list of bots in same level as player. </summary>
public static PlayerBot FindBotsInLevel(Player p, string name) {
int matches = 0;
return Find<PlayerBot>(p, name, out matches, PlayerBot.Bots.Items,
b => b.level == p.level, b => b.name, "bots in this level");
return Find<PlayerBot>(p, name, out matches, p.level.Bots.Items,
b => b.level == p.level, b => b.name, "bots");
}
/// <summary> Find partial matches of 'name' against the list of loaded maps/levels. </summary>