Initial support for per axis entity models.

This commit is contained in:
UnknownShadow200 2017-11-12 23:00:14 +11:00
parent 3bc2064378
commit 6644e21425
14 changed files with 67 additions and 103 deletions

View File

@ -44,7 +44,7 @@ namespace MCGalaxy.Bots {
PlayerBot bot = new PlayerBot(props.Name, lvl);
props.ApplyTo(bot);
bot.ModelBB = AABB.ModelAABB(bot.Model, lvl);
bot.ModelBB = AABB.ModelAABB(bot, lvl);
LoadAi(props, bot);
PlayerBot.Add(bot, false);
}

View File

@ -49,7 +49,7 @@ namespace MCGalaxy {
public PlayerBot(string n, Level lvl) {
name = n; DisplayName = n; SkinName = n;
color = "&1";
ModelBB = AABB.ModelAABB(Model, lvl);
ModelBB = AABB.ModelAABB(this, lvl);
level = lvl;
hasExtPositions = true;
BotsScheduler.Activate();

View File

@ -55,13 +55,10 @@ namespace MCGalaxy {
/// <remarks> NOTE: This returns false for A to F, be warned! </remarks>
public static bool IsDefined(char c) { return c <= '\xff' && List[c].Fallback != '\0'; }
/// <summary> Returns whether c is a color code in 0-9, a-f, or A-F. </summary>
public static bool IsStandard(char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
/// <summary> Gets the default color description for the given color code. </summary>
public static ColorDesc DefaultCol(char code) {
switch (code) {
case '0': return new ColorDesc('0', "Black");
@ -86,8 +83,7 @@ namespace MCGalaxy {
col.Code = code;
return col;
}
/// <summary> Updates the colors list array, sends change to all players, then saves color list. </summary>
public static void Update(ColorDesc col) {
List[col.Code] = col;
Player[] players = PlayerInfo.Online.Items;
@ -98,7 +94,6 @@ namespace MCGalaxy {
SaveList();
}
/// <summary> Finds the color code which has the given name, or empty string if not found. </summary>
public static string Parse(string name) {
for (int i = 0; i < List.Length; i++) {
if (List[i].Undefined) continue;
@ -107,14 +102,12 @@ namespace MCGalaxy {
}
return "";
}
/// <summary> Gets the name of the given color code. </summary>
public static string Name(string color) {
if (color.Length != 2 || color[0] != '&') return "";
return Name(color[1]);
}
/// <summary> Gets the name of the given color code. </summary>
public static string Name(char code) {
if (code >= 'A' && code <= 'F') code += ' ';
return IsDefined(code) ? List[code].Name : "";
@ -136,7 +129,6 @@ namespace MCGalaxy {
};
static readonly Regex IrcTwoColorCode = new Regex("(\x03\\d{1,2}),\\d{1,2}");
/// <summary> Converts IRC color codes into normal color codes. </summary>
public static string ConvertIRCToMC(string input) {
if (input == null) throw new ArgumentNullException("input");
// get rid of background color component of some IRC color codes.
@ -155,7 +147,6 @@ namespace MCGalaxy {
return sb.ToString();
}
/// <summary> Escapes then converts color codes into IRC color codes. </summary>
public static string ConvertMCToIRC(string input) {
if (input == null) throw new ArgumentNullException("input");
input = Escape(input);
@ -235,7 +226,6 @@ namespace MCGalaxy {
}
}
/// <summary> Removes all percentage and actual color codes from the given string. </summary>
public static string Strip(string value) {
if (value.IndexOf('%') == -1 && value.IndexOf('&') == -1) return value;
char[] output = new char[value.Length];
@ -279,9 +269,8 @@ namespace MCGalaxy {
}
}
}
/// <summary> Saves the list of all colors. </summary>
internal static void SaveList() {
using (StreamWriter w = new StreamWriter(Paths.CustomColorsFile)) {
foreach (ColorDesc col in List) {
@ -293,7 +282,6 @@ namespace MCGalaxy {
}
}
/// <summary> Loads the list of all colors. </summary>
internal static void LoadList() {
if (!File.Exists(Paths.CustomColorsFile)) return;
string[] lines = File.ReadAllLines(Paths.CustomColorsFile);

View File

@ -21,15 +21,6 @@ using System.IO;
using System.Text;
using MCGalaxy.Commands;
namespace MCGalaxy {
public class GrpCommands {
[Obsolete("Use CommandPerms.Load()")]
public static void fillRanks() { CommandPerms.Load(); }
}
}
namespace MCGalaxy.Commands {
/// <summary> Represents which ranks are allowed (and which are disallowed) to use a command. </summary>

View File

@ -43,7 +43,7 @@ namespace MCGalaxy.Core {
p.prevMsg = "";
p.showMBs = false;
p.showPortals = false;
p.ModelBB = AABB.ModelAABB(p.Model, level); // in case had been using a level-only custom block for their model
p.ModelBB = AABB.ModelAABB(p, level); // in case had been using a level-only custom block for their model
if (!Hacks.CanUseHacks(p, level) && p.isFlying) {
Player.Message(p, "You cannot use /fly on this map.");

View File

@ -89,7 +89,7 @@ namespace MCGalaxy {
string skin = p.SkinName, model = p.Model;
OnEntitySpawnedEvent.Call(p, ref name, ref skin, ref model, dst);
SpawnRaw(dst, id, skin, name, model, p.Pos, p.Rot);
SpawnRaw(dst, id, p, skin, name, model);
if (!ServerConfig.TablistGlobal) TabList.Add(dst, p, id);
}
@ -130,15 +130,16 @@ namespace MCGalaxy {
string model = Chat.Format(b.Model, dst, true, false);
OnEntitySpawnedEvent.Call(b, ref name, ref skin, ref model, dst);
SpawnRaw(dst, b.id, skin, name, model, b.Pos, b.Rot);
SpawnRaw(dst, b.id, b, skin, name, model);
if (ServerConfig.TablistBots) TabList.Add(dst, b);
}
static void SpawnRaw(Player dst, byte id, string skin, string name,
string model, Position pos, Orientation rot) {
static void SpawnRaw(Player dst, byte id, Entity entity,
string skin, string name, string model) {
Position pos = entity.Pos; Orientation rot = entity.Rot;
// NOTE: Fix for standard clients
if (id == Entities.SelfID) pos.Y -= 22;
name = Colors.Cleanup(name, dst.hasTextColors);
name = Colors.Cleanup(name, dst.hasTextColors);
if (dst.Supports(CpeExt.ExtPlayerList, 2)) {
dst.Send(Packet.ExtAddEntity2(id, skin, name, pos, rot, dst.hasCP437, dst.hasExtPositions));
@ -153,6 +154,7 @@ namespace MCGalaxy {
if (dst.Supports(CpeExt.EntityProperty)) {
dst.Send(Packet.EntityProperty(id, EntityProp.RotX, Orientation.PackedToDegrees(rot.RotX)));
dst.Send(Packet.EntityProperty(id, EntityProp.RotZ, Orientation.PackedToDegrees(rot.RotZ)));
SendModelScales(dst, id, entity);
}
}
@ -183,7 +185,7 @@ namespace MCGalaxy {
Player[] players = PlayerInfo.Online.Items;
entity.Model = model;
Level lvl = entity.Level;
entity.ModelBB = AABB.ModelAABB(model, lvl);
entity.ModelBB = AABB.ModelAABB(entity, lvl);
foreach (Player pl in players) {
if (pl.level != lvl || !pl.Supports(CpeExt.ChangeModel)) continue;
@ -192,9 +194,22 @@ namespace MCGalaxy {
byte id = (pl == entity) ? Entities.SelfID : entity.EntityID;
string modelSend = Chat.Format(model, pl, true, false);
SendModel(pl, id, modelSend);
SendModelScales(pl, id, entity);
}
}
static void SendModelScales(Player pl, byte id, Entity entity) {
if (!pl.Supports(CpeExt.EntityProperty)) return;
SendModelScale(pl, id, EntityProp.ScaleX, entity.ScaleX);
SendModelScale(pl, id, EntityProp.ScaleY, entity.ScaleY);
SendModelScale(pl, id, EntityProp.ScaleZ, entity.ScaleZ);
}
static void SendModelScale(Player pl, byte id, EntityProp axis, float value) {
if (value == 0) return;
pl.Send(Packet.EntityProperty(id, axis, (int)(value * 1000)));
}
static void SendModel(Player pl, byte id, string model) {
byte block;
// Fallback block models for clients that don't support block definitions

View File

@ -33,7 +33,8 @@ namespace MCGalaxy {
public string Model = "humanoid";
public AABB ModelBB;
public string SkinName;
public string SkinName;
public float ScaleX, ScaleY, ScaleZ;
public Orientation Rot {
get { return Orientation.Unpack(_rot); }

View File

@ -54,12 +54,6 @@ namespace MCGalaxy {
internal AABB[] blockAABBs = new AABB[Block.Count * 2];
public ushort Width, Height, Length;
// NOTE: These are for legacy code only, you should use upper case Width/Height/Length
// as these correctly map Y to being Height
[Obsolete] public ushort width;
[Obsolete] public ushort height;
[Obsolete] public ushort depth;
[Obsolete] public ushort length;
public bool IsMuseum;
public int ReloadThreshold {

View File

@ -45,12 +45,6 @@ namespace MCGalaxy {
if (Width < 16) Width = 16;
if (Height < 16) Height = 16;
if (Length < 16) Length = 16;
#pragma warning disable 0612
width = Width;
length = Height;
height = Length; depth = Length;
#pragma warning restore 0612
for (int i = 0; i < CustomBlockDefs.Length; i++)
CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i];

View File

@ -193,21 +193,28 @@ namespace MCGalaxy {
void LoadCpeData() {
string skin = Server.skins.FindData(name);
if (skin != null) SkinName = skin;
if (skin != null) SkinName = skin;
string model = Server.models.FindData(name);
if (model != null) Model = model;
ModelBB = AABB.ModelAABB(Model, level);
string modelScales = Server.modelScales.FindData(name);
if (modelScales != null) {
string[] bits = modelScales.SplitSpaces(3);
Utils.TryParseDecimal(bits[0], out ScaleX);
Utils.TryParseDecimal(bits[1], out ScaleY);
Utils.TryParseDecimal(bits[2], out ScaleZ);
}
string rotations = Server.rotations.FindData(name);
if (rotations == null) return;
string[] rotParts = rotations.SplitSpaces(2);
if (rotParts.Length != 2) return;
if (rotations != null) {
string[] bits = rotations.SplitSpaces(2);
Orientation rot = Rot;
byte.TryParse(bits[0], out rot.RotX);
byte.TryParse(bits[1], out rot.RotZ);
Rot = rot;
}
Orientation rot = Rot;
byte.TryParse(rotParts[0], out rot.RotX);
byte.TryParse(rotParts[1], out rot.RotZ);
Rot = rot;
ModelBB = AABB.ModelAABB(this, level);
}
void GetPlayerStats() {

View File

@ -60,7 +60,7 @@ namespace MCGalaxy {
public static PlayerList bannedIP, whiteList, ircControllers, invalidIds;
public static PlayerList ignored, hidden, agreed, vip, noEmotes, lockdown;
public static PlayerExtList models, skins, reach, rotations;
public static PlayerExtList models, skins, reach, rotations, modelScales;
public static PlayerExtList frozen, muted, jailed, tempBans, tempRanks;
public static readonly List<string> Devs = new List<string>(), Mods = new List<string>();

View File

@ -69,6 +69,7 @@ namespace MCGalaxy {
reach = PlayerExtList.Load("extra/reach.txt");
invalidIds = PlayerList.Load("extra/invalidids.txt");
rotations = PlayerExtList.Load("extra/rotations.txt");
modelScales = PlayerExtList.Load("extra/modelscales.txt");
muted = PlayerExtList.Load("ranks/muted.txt");
frozen = PlayerExtList.Load("ranks/frozen.txt");

View File

@ -38,31 +38,6 @@ namespace MCGalaxy.Util {
Count = 0;
}
public bool Exists(Predicate<T> condition) {
for (int i = 0; i < Count; i++) {
if (condition(Items[i])) return true;
}
return false;
}
public int IndexOf(Predicate<T> condition) {
for (int i = 0; i < Count; i++) {
if (condition(Items[i])) return i;
}
return -1;
}
public bool Remove(T item) {
int index = Array.IndexOf<T>(Items, item, 0, Count);
if (index < 0) return false;
Count--;
if (index < Count)
Array.Copy(Items, index + 1, Items, index, Count - index);
Items[Count] = default(T);
return true;
}
public void RemoveAt(int index) {
Count--;
if (index < Count)
@ -70,15 +45,6 @@ namespace MCGalaxy.Util {
Items[Count] = default(T);
}
public void RemoveAll(Predicate<T> condition) {
int j = 0;
for (int i = 0; i < Count; i++) {
if (condition(Items[i])) continue;
Items[j] = Items[i]; j++;
}
Count = j;
}
void EnsureCapacity(int threshold) {
if (Items.Length >= threshold) return;
int newSize = Items.Length * 2;

View File

@ -88,34 +88,41 @@ namespace MCGalaxy.Maths {
return false;
}
public override string ToString() {
return Min + " : " + Max;
}
public override string ToString() { return Min + " : " + Max; }
public static AABB ModelAABB(string model, Level lvl) {
public static AABB ModelAABB(Entity entity, Level lvl) {
string model = entity.Model;
int sep = model.IndexOf('|');
string scaleStr = sep == -1 ? null : model.Substring(sep + 1);
model = sep == -1 ? model : model.Substring(0, sep);
AABB baseBB;
AABB bb;
byte raw;
if (byte.TryParse(model, out raw)) {
ExtBlock block = ExtBlock.FromRaw(raw);
baseBB = Block.BlockAABB(block, lvl);
baseBB = baseBB.Offset(-16, 0, -16); // centre around [-16, 16] instead of [0, 32]
bb = Block.BlockAABB(block, lvl);
bb = bb.Offset(-16, 0, -16); // centre around [-16, 16] instead of [0, 32]
} else {
baseBB = AABB.Make(new Vec3S32(0, 0, 0), BaseSize(model));
bb = AABB.Make(new Vec3S32(0, 0, 0), BaseSize(model));
}
baseBB = baseBB.Expand(-1); // adjust the model AABB inwards slightly
bb = bb.Expand(-1); // adjust the model AABB inwards slightly
float scale;
if (!Utils.TryParseDecimal(scaleStr, out scale)) return baseBB;
if (!Utils.TryParseDecimal(scaleStr, out scale)) return bb;
if (scale < 0.25f) scale = 0.25f;
float maxScale = model.CaselessEq("chibi") ? 3 : 2;
if (scale > maxScale) scale = maxScale;
return new AABB(baseBB.Min * scale, baseBB.Max * scale);
float scaleX = scale, scaleY = scale, scaleZ = scale;
if (entity.ScaleX != 0) scaleX = entity.ScaleX;
if (entity.ScaleY != 0) scaleY = entity.ScaleY;
if (entity.ScaleZ != 0) scaleZ = entity.ScaleZ;
bb.Min.X = (int)(bb.Min.X * scaleX); bb.Max.X = (int)(bb.Max.X * scaleX);
bb.Min.Y = (int)(bb.Min.Y * scaleY); bb.Max.Y = (int)(bb.Max.Y * scaleY);
bb.Min.Z = (int)(bb.Min.Z * scaleZ); bb.Max.Z = (int)(bb.Max.Z * scaleZ);
return bb;
}
static Vec3S32 BaseSize(string model) {