From a6cd6423566f65a29a6556db72d46f421a2eb84a Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 6 Jun 2017 13:40:54 +1000 Subject: [PATCH] Modularise /missile --- GUI/PropertyWindow/PropertyWindow.Chat.cs | 1 + MCGalaxy/Chat/Colors.cs | 2 +- MCGalaxy/Commands/Fun/CmdGun.cs | 2 +- MCGalaxy/Commands/Fun/CmdMissile.cs | 168 ++++++++++++---------- MCGalaxy/Commands/Fun/WeaponCmd.cs | 9 +- 5 files changed, 102 insertions(+), 80 deletions(-) diff --git a/GUI/PropertyWindow/PropertyWindow.Chat.cs b/GUI/PropertyWindow/PropertyWindow.Chat.cs index 478b04dd3..ce529c67a 100644 --- a/GUI/PropertyWindow/PropertyWindow.Chat.cs +++ b/GUI/PropertyWindow/PropertyWindow.Chat.cs @@ -14,6 +14,7 @@ permissions and limitations under the Licenses. */ using System; using System.Windows.Forms; +using MCGalaxy.Gui.Popups; namespace MCGalaxy.Gui { diff --git a/MCGalaxy/Chat/Colors.cs b/MCGalaxy/Chat/Colors.cs index 05b7a14d6..1d17ac7d1 100644 --- a/MCGalaxy/Chat/Colors.cs +++ b/MCGalaxy/Chat/Colors.cs @@ -291,7 +291,7 @@ namespace MCGalaxy { return c; } - static int Hex(char value) { + public static int Hex(char value) { if (value >= '0' && value <= '9') return (int)(value - '0'); if (value >= 'a' && value <= 'f') diff --git a/MCGalaxy/Commands/Fun/CmdGun.cs b/MCGalaxy/Commands/Fun/CmdGun.cs index 1fe61ec4e..a784b93b6 100644 --- a/MCGalaxy/Commands/Fun/CmdGun.cs +++ b/MCGalaxy/Commands/Fun/CmdGun.cs @@ -56,7 +56,7 @@ namespace MCGalaxy.Commands.Fun { pos.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * t)); byte by = p.level.GetTile(pos.X, pos.Y, pos.Z); - if (by != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, by, bp, pos, true)) + if (by != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, by, bp.ending, pos, true)) break; p.level.Blockchange(pos.X, pos.Y, pos.Z, block); diff --git a/MCGalaxy/Commands/Fun/CmdMissile.cs b/MCGalaxy/Commands/Fun/CmdMissile.cs index ddb6a9fdf..c64cc2f6e 100644 --- a/MCGalaxy/Commands/Fun/CmdMissile.cs +++ b/MCGalaxy/Commands/Fun/CmdMissile.cs @@ -21,7 +21,7 @@ using System.Threading; using MCGalaxy.Drawing.Ops; using MCGalaxy.Maths; -namespace MCGalaxy.Commands.Fun { +namespace MCGalaxy.Commands.Fun { public sealed class CmdMissile : WeaponCmd { public override string name { get { return "missile"; } } @@ -34,93 +34,115 @@ namespace MCGalaxy.Commands.Fun { } p.RevertBlock(x, y, z); if (!CommandParser.IsBlockAllowed(p, "place ", block)) return; + + MissileArgs args = new MissileArgs(); + args.player = p; + args.block = block; + CatchPos bp = (CatchPos)p.blockchangeObject; + args.ending = bp.ending; + args.pos = MakePos(p); - Thread gunThread = new Thread(() => DoShoot(p, block)); + Thread gunThread = new Thread(() => DoShoot(args)); gunThread.Name = "MCG_Missile"; gunThread.Start(); } + + class MissileArgs { + public Player player; + public ExtBlock block; + public EndType ending; + public Vec3U16 pos; + + public List previous = new List(); + public List allBlocks = new List(); + public List buffer = new List(); + public int iterations; + } - void DoShoot(Player p, ExtBlock block) { - CatchPos bp = (CatchPos)p.blockchangeObject; - List previous = new List(), allBlocks = new List(); - Vec3U16 pos = MakePos(p); - - int total = 0; - List buffer = new List(2); + void DoShoot(MissileArgs args) { + Player p = args.player; + while (true) { - Vec3U16 start = MakePos(p); - total++; - Vec3F32 dir = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX); + args.iterations++; + Vec3U16 target = MissileTarget(args); + FindNext(target, ref args.pos, args.buffer); - Vec3U16 lookedAt; - int i; - for (i = 1; ; i++) { - lookedAt.X = (ushort)Math.Round(start.X + (double)(dir.X * i)); - lookedAt.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * i)); - lookedAt.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * i)); - - byte tile = p.level.GetTile(lookedAt.X, lookedAt.Y, lookedAt.Z); - if (tile == Block.Invalid) break; - - if (tile != Block.air && !allBlocks.Contains(lookedAt) && HandlesHitBlock(p, tile, bp, pos, false)) - break; - - Player hit = GetPlayer(p, lookedAt, true); - if (hit != null) { - lookedAt = MakePos(hit); break; - } - } - - lookedAt.X = (ushort)Math.Round(start.X + (double)(dir.X * (i - 1))); - lookedAt.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * (i - 1))); - lookedAt.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * (i - 1))); - FindNext(lookedAt, ref pos, buffer); - - byte by = p.level.GetTile(pos.X, pos.Y, pos.Z); - if (total > 3) { - if (by != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, by, bp, pos, true)) - break; - - p.level.Blockchange(pos.X, pos.Y, pos.Z, block); - previous.Add(pos); - allBlocks.Add(pos); - - Player hitP = GetPlayer(p, pos, true); - if (hitP != null) { - if (p.level.physics >= 3 && bp.ending >= EndType.Explode) { - hitP.HandleDeath((ExtBlock)Block.stone, " was blown up by " + p.ColoredName, true); - } else { - hitP.HandleDeath((ExtBlock)Block.stone, " was hit a missile from " + p.ColoredName); - } - break; - } - - if (pos.X == lookedAt.X && pos.Y == lookedAt.Y && pos.Z == lookedAt.Z) { - if (p.level.physics >= 3 && bp.ending >= EndType.Explode && p.allowTnt) { - p.level.MakeExplosion(lookedAt.X, lookedAt.Y, lookedAt.Z, 2); - break; - } - } - - if (previous.Count > 12) { - p.level.Blockchange(previous[0].X, previous[0].Y, previous[0].Z, ExtBlock.Air, true); - previous.RemoveAt(0); - } - Thread.Sleep(100); - } + if (args.iterations <= 3) continue; + if (!MoveMissile(args, args.pos, target)) break; + Thread.Sleep(100); } - if (bp.ending == EndType.Teleport) { - int index = previous.Count - 3; - if (index >= 0 && index < previous.Count) - DoTeleport(p, previous[index]); + if (args.ending == EndType.Teleport) { + int index = args.previous.Count - 3; + if (index >= 0 && index < args.previous.Count) + DoTeleport(p, args.previous[index]); } - foreach (Vec3U16 pos1 in previous) { + foreach (Vec3U16 pos1 in args.previous) { p.level.Blockchange(pos1.X, pos1.Y, pos1.Z, ExtBlock.Air, true); Thread.Sleep(100); } } + static Vec3U16 MissileTarget(MissileArgs args) { + Player p = args.player; + Vec3U16 start = MakePos(p); + Vec3F32 dir = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX); + Vec3U16 target; + int i; + + for (i = 1; ; i++) { + target.X = (ushort)Math.Round(start.X + (double)(dir.X * i)); + target.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * i)); + target.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * i)); + + byte tile = p.level.GetTile(target.X, target.Y, target.Z); + if (tile == Block.Invalid) break; + + if (tile != Block.air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, tile, args.ending, target, false)) + break; + + Player hit = GetPlayer(p, target, true); + if (hit != null) return MakePos(hit); + } + + target.X = (ushort)Math.Round(start.X + (double)(dir.X * (i - 1))); + target.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * (i - 1))); + target.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * (i - 1))); + return target; + } + + static bool MoveMissile(MissileArgs args, Vec3U16 pos, Vec3U16 target) { + Player p = args.player; + byte tile = p.level.GetTile(pos.X, pos.Y, pos.Z); + if (tile != Block.air && !args.allBlocks.Contains(pos) && HandlesHitBlock(p, tile, args.ending, pos, true)) + return false; + + p.level.Blockchange(pos.X, pos.Y, pos.Z, args.block); + args.previous.Add(pos); + args.allBlocks.Add(pos); + + Player hitP = GetPlayer(p, pos, true); + if (hitP != null) { + if (p.level.physics >= 3 && args.ending >= EndType.Explode) { + hitP.HandleDeath((ExtBlock)Block.stone, " was blown up by " + p.ColoredName, true); + } else { + hitP.HandleDeath((ExtBlock)Block.stone, " was hit a missile from " + p.ColoredName); + } + return false; + } + + if (pos == target && p.level.physics >= 3 && args.ending >= EndType.Explode) { + p.level.MakeExplosion(target.X, target.Y, target.Z, 2); + return false; + } + + if (args.previous.Count > 12) { + p.level.Blockchange(args.previous[0].X, args.previous[0].Y, args.previous[0].Z, ExtBlock.Air, true); + args.previous.RemoveAt(0); + } + return true; + } + static Vec3U16 MakePos(Player p) { return (Vec3U16)p.Pos.BlockCoords; } diff --git a/MCGalaxy/Commands/Fun/WeaponCmd.cs b/MCGalaxy/Commands/Fun/WeaponCmd.cs index 6be629a47..3cebe8cc2 100644 --- a/MCGalaxy/Commands/Fun/WeaponCmd.cs +++ b/MCGalaxy/Commands/Fun/WeaponCmd.cs @@ -137,7 +137,7 @@ namespace MCGalaxy.Commands.Fun { protected abstract void PlacedMark(Player p, ushort x, ushort y, ushort z, ExtBlock block); - protected Player GetPlayer(Player p, Vec3U16 pos, bool skipSelf) { + protected static Player GetPlayer(Player p, Vec3U16 pos, bool skipSelf) { Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (pl.level != p.level) continue; @@ -161,11 +161,10 @@ namespace MCGalaxy.Commands.Fun { } } - protected bool HandlesHitBlock(Player p, byte type, CatchPos bp, Vec3U16 pos, bool doExplode) { - if (p.level.physics < 2 || bp.ending == EndType.Teleport - || bp.ending == EndType.Normal) return true; + protected static bool HandlesHitBlock(Player p, byte type, EndType ending, Vec3U16 pos, bool doExplode) { + if (p.level.physics < 2 || ending == EndType.Teleport || ending == EndType.Normal) return true; - if (bp.ending == EndType.Destroy) { + if (ending == EndType.Destroy) { if ((!Block.FireKill(type) && !Block.NeedRestart(type)) && type != Block.glass) { return true; }