Add clickable text in bots.

This commit is contained in:
UnknownShadow200 2017-08-25 20:51:41 +10:00
parent 5458a34f58
commit 2c05d65247
10 changed files with 221 additions and 148 deletions

View File

@ -38,17 +38,7 @@ namespace MCGalaxy.Blocks.Extended {
message = message.Replace("@p", p.name);
if (message != p.prevMsg || (alwaysRepeat || ServerConfig.RepeatMBs)) {
string text;
List<string> cmds = GetParts(message, out text);
if (text != null) Player.Message(p, text);
if (cmds.Count == 1) {
string[] parts = cmds[0].SplitSpaces(2);
p.HandleCommand(parts[0], parts.Length > 1 ? parts[1] : "");
} else if (cmds.Count > 0) {
p.HandleCommands(cmds);
}
p.prevMsg = message;
Execute(p, message);
}
return true;
} catch {
@ -56,10 +46,56 @@ namespace MCGalaxy.Blocks.Extended {
}
}
public static void Execute(Player p, string message) {
string text;
List<string> cmds = GetParts(message, out text);
if (text != null) Player.Message(p, text);
if (cmds.Count == 1) {
string[] parts = cmds[0].SplitSpaces(2);
p.HandleCommand(parts[0], parts.Length > 1 ? parts[1] : "");
} else if (cmds.Count > 0) {
p.HandleCommands(cmds);
}
p.prevMsg = message;
}
public static bool Validate(Player p, string message, bool allCmds) {
string text;
List<string> cmds = MessageBlock.GetParts(message, out text);
foreach (string cmd in cmds) {
if (!CheckCommand(p, cmd, allCmds)) return false;
}
return true;
}
static bool CheckCommand(Player p, string message, bool allCmds) {
string[] parts = message.SplitSpaces(2);
string alias = parts[0], cmdArgs = "";
Command.Search(ref alias, ref cmdArgs);
foreach (Command cmd in Command.all.commands) {
if (p.group.CanExecute(cmd) && (allCmds || !cmd.type.Contains("mod"))) continue;
if (IsCommand(message, cmd.name) || IsCommand(alias, cmd.name)) {
Player.Message(p, "You cannot use %T/{0} %Sin a messageblock.", cmd.name); return false;
}
if (cmd.shortcut.Length > 0 && IsCommand(message, cmd.shortcut)) {
Player.Message(p, "You cannot use %T/{0} %Sin a messageblock.", cmd.name); return false;
}
}
return true;
}
static bool IsCommand(string message, string cmd) {
return message.CaselessEq(cmd) || message.CaselessStarts(cmd + " ");
}
static string[] sep = new string[] { " |/" };
const StringSplitOptions opts = StringSplitOptions.RemoveEmptyEntries;
static List<string> empty = new List<string>();
internal static List<string> GetParts(string message, out string text) {
static List<string> GetParts(string message, out string text) {
if (message.IndexOf('|') == -1) return ParseSingle(message, out text);
string[] parts = message.Split(sep, opts);

View File

@ -60,16 +60,7 @@ namespace MCGalaxy.Bots {
foreach (BotProperties props in SavedBots) {
if (lvl.name != props.Level) continue;
PlayerBot bot = new PlayerBot(props.Name, lvl);
bot.Pos = new Position(props.X, props.Y, props.Z);
bot.SetYawPitch(props.RotX, props.RotY);
Orientation rot = bot.Rot;
rot.RotX = props.BodyX; rot.RotZ = props.BodyZ;
bot.Rot = rot;
bot.SkinName = props.Skin; bot.Model = props.Model; bot.color = props.Color;
bot.AIName = props.AI; bot.hunt = props.Hunt; bot.kill = props.Kill;
bot.DisplayName = props.DisplayName;
props.ApplyTo(bot);
bot.ModelBB = AABB.ModelAABB(bot.Model, lvl);
LoadAi(props, bot);
@ -124,7 +115,7 @@ namespace MCGalaxy.Bots {
SavedBots.RemoveAt(i);
removed++; i--;
}
}
if (removed > 0) Save();
}
}
@ -137,7 +128,7 @@ namespace MCGalaxy.Bots {
BotProperties props = SavedBots[i];
if (!props.Level.CaselessEq(srcLevel)) continue;
props.Level = dstLevel;
props.Level = dstLevel;
moved++;
}
if (moved > 0) Save();
@ -187,6 +178,7 @@ namespace MCGalaxy.Bots {
public string Skin { get; set; }
public string Model { get; set; }
public string Color { get; set; }
public string ClickedOnText { get; set; }
public string AI { get; set; }
public bool Kill { get; set; }
@ -208,20 +200,37 @@ namespace MCGalaxy.Bots {
Kill = bot.kill; Hunt = bot.hunt;
DisplayName = bot.DisplayName;
CurInstruction = bot.cur;
ClickedOnText = bot.ClickedOnText;
X = bot.Pos.X; Y = bot.Pos.Y; Z = bot.Pos.Z;
RotX = bot.Rot.RotY; RotY = bot.Rot.HeadX;
BodyX = bot.Rot.RotX; BodyZ = bot.Rot.RotZ;
}
public void ApplyTo(PlayerBot bot) {
bot.Pos = new Position(X, Y, Z);
bot.SetYawPitch(RotX, RotY);
Orientation rot = bot.Rot;
rot.RotX = BodyX; rot.RotZ = BodyZ;
bot.Rot = rot;
bot.SkinName = Skin; bot.Model = Model; bot.color = Color;
bot.AIName = AI; bot.hunt = Hunt; bot.kill = Kill;
bot.DisplayName = DisplayName;
bot.cur = CurInstruction;
bot.ClickedOnText = ClickedOnText;
}
public BotProperties Copy() {
BotProperties copy = new BotProperties();
copy.DisplayName = DisplayName; copy.Name = Name;
copy.Level = Level; copy.Skin = Skin;
copy.Model = Model; copy.Color = Color;
copy.AI = AI; copy.Kill = Kill;
copy.Hunt = Hunt; copy.CurInstruction = CurInstruction;
copy.AI = AI; copy.Kill = Kill; copy.Hunt = Hunt;
copy.CurInstruction = CurInstruction;
copy.ClickedOnText = ClickedOnText;
copy.X = X; copy.Y = Y; copy.Z = Z;
copy.RotX = RotX; copy.RotY = RotY;

View File

@ -29,6 +29,7 @@ namespace MCGalaxy {
public string AIName = "", color;
public string name, DisplayName;
public string ClickedOnText;
public string ColoredName { get { return color + DisplayName; } }
public byte id;

View File

@ -0,0 +1,119 @@
/*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using MCGalaxy.Blocks.Extended;
using MCGalaxy.Bots;
namespace MCGalaxy.Commands.Bots {
public sealed class CmdBot : Command {
public override string name { get { return "Bot"; } }
public override string type { get { return CommandTypes.Moderation; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
public override bool SuperUseable { get { return false; } }
public override CommandAlias[] Aliases {
get { return new[] { new CommandAlias("BotAdd", "add"), new CommandAlias("BotRemove", "remove") }; }
}
public override void Use(Player p, string message) {
if (message.Length == 0) { Help(p); return; }
string[] args = message.SplitSpaces(3);
if (args.Length < 2) { Help(p); return; }
if (!Formatter.ValidName(p, args[1], "bot")) return;
if (args[0].CaselessEq("add")) {
AddBot(p, args[1]);
} else if (args[0].CaselessEq("remove")) {
RemoveBot(p, args[1]);
} else if (args[0].CaselessEq("text")) {
string text = args.Length > 2 ? args[2] : null;
SetBotText(p, args[1], text);
} else {
Help(p);
}
}
void AddBot(Player p, string botName) {
if (!p.level.BuildAccess.CheckDetailed(p)) {
Player.Message(p, "Hence, you cannot add bots to this map.");
return;
}
if (BotExists(p.level, botName)) {
Player.Message(p, "A bot with that name already exists."); return;
}
PlayerBot bot = new PlayerBot(botName, p.level);
bot.Pos = p.Pos;
bot.SetYawPitch(p.Rot.RotY, 0);
Player.Message(p, "You added the bot " + bot.ColoredName );
PlayerBot.Add(bot);
}
static bool BotExists(Level lvl, string name) {
PlayerBot[] bots = lvl.Bots.Items;
foreach (PlayerBot bot in bots) {
if (bot.name.CaselessEq(name)) return true;
}
return false;
}
void RemoveBot(Player p, string botName) {
if (!p.level.BuildAccess.CheckDetailed(p)) {
Player.Message(p, "Hence, you cannot remove bots from this map.");
return;
}
if (botName.CaselessEq("all")) {
PlayerBot.RemoveAllFromLevel(p.level); return;
} else {
PlayerBot bot = Matcher.FindBots(p, botName);
if (bot == null) return;
PlayerBot.Remove(bot);
Player.Message(p, "Removed bot {0}", bot.ColoredName);
}
}
void SetBotText(Player p, string botName, string text) {
PlayerBot bot = Matcher.FindBots(p, botName);
if (bot == null) return;
if (text == null) {
Player.Message(p, "Removed text shown when bot {0} %Sclicked on", bot.ColoredName);
bot.ClickedOnText = null;
} else {
if (!MessageBlock.Validate(p, text, false)) return;
Player.Message(p, "Set text shown when bot {0} %Sis clicked on to {1}", bot.ColoredName, text);
bot.ClickedOnText = text;
}
BotsFile.UpdateBot(bot);
}
public override void Help(Player p) {
Player.Message(p, "%T/Bot add [name]");
Player.Message(p, "%HAdds a new bot at your position.");
Player.Message(p, "%T/Bot remove [name]");
Player.Message(p, "%HRemove a bot on the same level as you");
Player.Message(p, "%HIf [name] is \"all\", all bots on your map are removed");
Player.Message(p, "%T/Bot text [name] <text>");
Player.Message(p, "%HSets the text shown when a player clicks on this bot");
Player.Message(p, "%HSee %T/help mb %Hfor more details on <text>");
}
}
}

View File

@ -1,60 +0,0 @@
/*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
namespace MCGalaxy.Commands.Bots {
public sealed class CmdBotAdd : Command {
public override string name { get { return "BotAdd"; } }
public override string type { get { return CommandTypes.Moderation; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
public override bool SuperUseable { get { return false; } }
public override void Use(Player p, string message) {
if (message.Length == 0) { Help(p); return; }
if (!p.level.BuildAccess.CheckDetailed(p)) {
Player.Message(p, "Hence, you cannot add bots to this map.");
return;
}
if (!Formatter.ValidName(p, message, "bot")) return;
if (BotExists(p.level, message)) {
Player.Message(p, "A bot with that name already exists."); return;
}
PlayerBot bot = new PlayerBot(message, p.level);
bot.Pos = p.Pos;
bot.SetYawPitch(p.Rot.RotY, 0);
Player.Message(p, "You added the bot " + bot.ColoredName + "%S.");
PlayerBot.Add(bot);
}
static bool BotExists(Level lvl, string name) {
PlayerBot[] bots = lvl.Bots.Items;
foreach (PlayerBot bot in bots) {
if (bot.name.CaselessEq(name)) return true;
}
return false;
}
public override void Help(Player p) {
Player.Message(p, "%T/BotAdd [name]");
Player.Message(p, "%HAdds a new bot at your position.");
}
}
}

View File

@ -1,51 +0,0 @@
/*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
namespace MCGalaxy.Commands.Bots {
public sealed class CmdBotRemove : Command {
public override string name { get { return "BotRemove"; } }
public override string type { get { return CommandTypes.Moderation; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
public override bool SuperUseable { get { return false; } }
public override void Use(Player p, string message) {
if (message.Length == 0) { Help(p); return; }
if (!p.level.BuildAccess.CheckDetailed(p)) {
Player.Message(p, "Hence, you cannot change remove bots from this map.");
return;
}
if (message.CaselessEq("all")) {
PlayerBot.RemoveAllFromLevel(p.level); return;
} else {
PlayerBot bot = Matcher.FindBots(p, message);
if (bot == null) return;
PlayerBot.Remove(bot);
Player.Message(p, "Removed bot {0}%S", bot.ColoredName);
}
}
public override void Help(Player p) {
Player.Message(p, "%T/BotRemove [name]");
Player.Message(p, "%HRemove a bot on the same level as you");
Player.Message(p, "%HIf [name] is \"all\", all bots on your map are removed");
}
}
}

View File

@ -55,11 +55,8 @@ namespace MCGalaxy.Commands.Building {
data.Message = args[1];
}
string text;
List<string> cmds = MessageBlock.GetParts(data.Message, out text);
foreach (string cmd in cmds) {
if (!CheckCommand(p, cmd)) return;
}
bool allCmds = HasExtraPerm(p, 1);
if (!MessageBlock.Validate(p, data.Message, allCmds)) return;
Player.Message(p, "Place where you wish the message block to go.");
p.MakeSelection(1, data, PlacedMark);

View File

@ -84,8 +84,12 @@ namespace MCGalaxy.Core {
internal static void HandlePlayerClick(Player p, MouseButton button, MouseAction action, ushort yaw, ushort pitch,
byte entity, ushort x, ushort y, ushort z, TargetBlockFace face) {
if (p.level.Config.Deletable || action != MouseAction.Pressed || !p.level.IsValidPos(x, y, z)) return;
if (action != MouseAction.Pressed) return;
bool validPos = p.level.IsValidPos(x, y, z);
if (entity != Entities.SelfID && !validPos && ClickOnBot(p, entity)) return;
if (p.level.Config.Deletable || !validPos) return;
ExtBlock block = p.level.GetBlock(x, y, z);
bool isMB = p.level.BlockProps[block.Index].IsMessageBlock;
bool isPortal = p.level.BlockProps[block.Index].IsPortal;
@ -94,19 +98,36 @@ namespace MCGalaxy.Core {
if (isPortal) { Portal.Handle(p, x, y, z); }
}
static bool ClickOnBot(Player p, byte entity) {
PlayerBot[] bots = p.level.Bots.Items;
for (int i = 0; i < bots.Length; i++) {
if (bots[i].EntityID != entity) continue;
if (bots[i].ClickedOnText == null) return false;
Vec3F32 delta = p.Pos.ToVec3F32() - bots[i].Pos.ToVec3F32();
float reachSq = p.ReachDistance * p.ReachDistance;
if (delta.LengthSquared > (reachSq + 1)) return false;
string message = bots[i].ClickedOnText;
MessageBlock.Execute(p, message);
return true;
}
return false;
}
// Update rank colors and rank prefixes for online players
internal static void HandleGroupLoad() {
Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) {
p.group = Group.Find(p.group.Permission);
if (p.group == null) p.group = Group.standard;
if (p.group == null) p.group = Group.standard;
p.SetPrefix();
string dbCol = PlayerData.FindDBColor(p);
if (dbCol.Length == 0 && p.color != p.group.Color) {
p.color = p.group.Color;
Entities.GlobalRespawn(p);
}
}
}
}
}

View File

@ -32,6 +32,8 @@ namespace MCGalaxy {
/// <summary> Z fixed-point location in the world. </summary>
public int Z;
public Vec3F32 ToVec3F32() { return new Vec3F32(X / 32.0f, Y / 32.0f, Z / 32.0f); }
public Position(int x, int y, int z) { X = x; Y = y; Z = z; }
@ -50,7 +52,7 @@ namespace MCGalaxy {
public int BlockY { get { return Y >> 5; } }
/// <summary> Z block coordinate of this position. </summary>
public int BlockZ { get { return Z >> 5; } }
public int BlockZ { get { return Z >> 5; } }
public override bool Equals(object obj) { return (obj is Position) && Equals((Position)obj); }

View File

@ -118,9 +118,8 @@
<Compile Include="Chat\LineWrapper.cs" />
<Compile Include="Chat\ProfanityFilter.cs" />
<Compile Include="Commands\Alias.cs" />
<Compile Include="Commands\Bots\CmdBotAdd.cs" />
<Compile Include="Commands\Bots\CmdBot.cs" />
<Compile Include="Commands\Bots\CmdBotAI.cs" />
<Compile Include="Commands\Bots\CmdBotRemove.cs" />
<Compile Include="Commands\Bots\CmdBots.cs" />
<Compile Include="Commands\Bots\CmdBotSet.cs" />
<Compile Include="Commands\Bots\CmdBotSummon.cs" />