/Commands/CmdGun.cs

https://github.com/cazzar/MCaznowl-Build · C# · 294 lines · 249 code · 41 blank · 4 comment · 108 complexity · 45c346b52aa31d7c7643d68a9cd36ac4 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using MCForge;
  7. namespace MCForge.Commands
  8. {
  9. /// <summary>
  10. /// This is the command /gun
  11. /// use /help gun in-game for more info
  12. /// </summary>
  13. public class CmdGun : Command
  14. {
  15. public override string name { get { return "gun"; } }
  16. public override string shortcut { get { return ""; } }
  17. public override string type { get { return "other"; } }
  18. public override bool museumUsable { get { return false; } }
  19. public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
  20. public CmdGun() { }
  21. public override void Use(Player p, string message)
  22. {
  23. Level foundLevel;
  24. foundLevel = p.level;
  25. if (foundLevel.guns == false)
  26. {
  27. Player.SendMessage(p, "Guns and missiles cannot be used on this map!");
  28. return;
  29. }
  30. if (p.hasflag != null) { Player.SendMessage(p, "You can't use a gun while you have the flag!"); return; }
  31. Pos cpos;
  32. if (p.aiming)
  33. {
  34. if (message == "")
  35. {
  36. p.aiming = false;
  37. p.ClearBlockchange();
  38. Player.SendMessage(p, "Disabled gun");
  39. return;
  40. }
  41. }
  42. cpos.ending = 0;
  43. if (message.ToLower() == "destroy") cpos.ending = 1;
  44. else if (p.allowTnt == false)
  45. {
  46. if (message.ToLower() == "explode")
  47. {
  48. Player.SendMessage(p, Server.DefaultColor + "Since tnt usage is disallowed at the moment, switching to normal gun!"); cpos.ending = 1;
  49. }
  50. else if (message.ToLower() == "laser")
  51. {
  52. Player.SendMessage(p, Server.DefaultColor + "Since tnt usage is disallowed at the moment, switching to normal gun!"); cpos.ending = 1;
  53. }
  54. else if (message.ToLower() == "teleport" || message.ToLower() == "tp") cpos.ending = -1;
  55. else if (message != "") { Help(p); return; }
  56. }
  57. else if (message.ToLower() == "explode") cpos.ending = 2;
  58. else if (message.ToLower() == "laser") cpos.ending = 3;
  59. else if (message.ToLower() == "teleport" || message.ToLower() == "tp") cpos.ending = -1;
  60. else if (message != "") { Help(p); return; }
  61. cpos.x = 0; cpos.y = 0; cpos.z = 0; p.blockchangeObject = cpos;
  62. p.ClearBlockchange();
  63. p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1);
  64. p.SendMessage("Gun mode engaged, fire at will");
  65. if (p.aiming)
  66. {
  67. return;
  68. }
  69. p.aiming = true;
  70. Thread aimThread = new Thread(new ThreadStart(delegate
  71. {
  72. CatchPos pos;
  73. List<CatchPos> buffer = new List<CatchPos>();
  74. while (p.aiming)
  75. {
  76. List<CatchPos> tempBuffer = new List<CatchPos>();
  77. double a = Math.Sin(((double)(128 - p.rot[0]) / 256) * 2 * Math.PI);
  78. double b = Math.Cos(((double)(128 - p.rot[0]) / 256) * 2 * Math.PI);
  79. double c = Math.Cos(((double)(p.rot[1] + 64) / 256) * 2 * Math.PI);
  80. try
  81. {
  82. ushort x = (ushort)(p.pos[0] / 32);
  83. x = (ushort)Math.Round(x + (double)(a * 3));
  84. ushort y = (ushort)(p.pos[1] / 32 + 1);
  85. y = (ushort)Math.Round(y + (double)(c * 3));
  86. ushort z = (ushort)(p.pos[2] / 32);
  87. z = (ushort)Math.Round(z + (double)(b * 3));
  88. if (x > p.level.width || y > p.level.depth || z > p.level.height) throw new Exception();
  89. if (x < 0 || y < 0 || z < 0) throw new Exception();
  90. for (ushort xx = x; xx <= x + 1; xx++)
  91. {
  92. for (ushort yy = (ushort)(y - 1); yy <= y; yy++)
  93. {
  94. for (ushort zz = z; zz <= z + 1; zz++)
  95. {
  96. if (p.level.GetTile(xx, yy, zz) == Block.air)
  97. {
  98. pos.x = xx; pos.y = yy; pos.z = zz;
  99. tempBuffer.Add(pos);
  100. }
  101. }
  102. }
  103. }
  104. List<CatchPos> toRemove = new List<CatchPos>();
  105. foreach (CatchPos cP in buffer)
  106. {
  107. if (!tempBuffer.Contains(cP))
  108. {
  109. p.SendBlockchange(cP.x, cP.y, cP.z, Block.air);
  110. toRemove.Add(cP);
  111. }
  112. }
  113. foreach (CatchPos cP in toRemove)
  114. {
  115. buffer.Remove(cP);
  116. }
  117. foreach (CatchPos cP in tempBuffer)
  118. {
  119. if (!buffer.Contains(cP))
  120. {
  121. buffer.Add(cP);
  122. p.SendBlockchange(cP.x, cP.y, cP.z, Block.glass);
  123. }
  124. }
  125. tempBuffer.Clear();
  126. toRemove.Clear();
  127. }
  128. catch { }
  129. Thread.Sleep(20);
  130. }
  131. foreach (CatchPos cP in buffer)
  132. {
  133. p.SendBlockchange(cP.x, cP.y, cP.z, Block.air);
  134. }
  135. }));
  136. aimThread.Start();
  137. }
  138. public void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type)
  139. {
  140. byte by = p.level.GetTile(x, y, z);
  141. p.SendBlockchange(x, y, z, by);
  142. Pos bp = (Pos)p.blockchangeObject;
  143. double a = Math.Sin(((double)(128 - p.rot[0]) / 256) * 2 * Math.PI);
  144. double b = Math.Cos(((double)(128 - p.rot[0]) / 256) * 2 * Math.PI);
  145. double c = Math.Cos(((double)(p.rot[1] + 64) / 256) * 2 * Math.PI);
  146. double bigDiag = Math.Sqrt(Math.Sqrt(p.level.width * p.level.width + p.level.height * p.level.height) + p.level.depth * p.level.depth + p.level.width * p.level.width);
  147. List<CatchPos> previous = new List<CatchPos>();
  148. List<CatchPos> allBlocks = new List<CatchPos>();
  149. CatchPos pos;
  150. if (p.modeType != Block.air)
  151. type = p.modeType;
  152. Thread gunThread = new Thread(new ThreadStart(delegate
  153. {
  154. ushort startX = (ushort)(p.pos[0] / 32);
  155. ushort startY = (ushort)(p.pos[1] / 32);
  156. ushort startZ = (ushort)(p.pos[2] / 32);
  157. pos.x = (ushort)Math.Round(startX + (double)(a * 3));
  158. pos.y = (ushort)Math.Round(startY + (double)(c * 3));
  159. pos.z = (ushort)Math.Round(startZ + (double)(b * 3));
  160. for (double t = 4; bigDiag > t; t++)
  161. {
  162. pos.x = (ushort)Math.Round(startX + (double)(a * t));
  163. pos.y = (ushort)Math.Round(startY + (double)(c * t));
  164. pos.z = (ushort)Math.Round(startZ + (double)(b * t));
  165. by = p.level.GetTile(pos.x, pos.y, pos.z);
  166. if (by != Block.air && !allBlocks.Contains(pos))
  167. {
  168. if (p.level.physics < 2 || bp.ending <= 0)
  169. {
  170. break;
  171. }
  172. else
  173. {
  174. if (bp.ending == 1)
  175. {
  176. if ((!Block.LavaKill(by) && !Block.NeedRestart(by)) && by != Block.glass)
  177. {
  178. break;
  179. }
  180. }
  181. else if (p.level.physics >= 3)
  182. {
  183. if (by != Block.glass)
  184. {
  185. if (p.allowTnt == true)
  186. {
  187. p.level.MakeExplosion(pos.x, pos.y, pos.z, 1);
  188. break;
  189. }
  190. }
  191. }
  192. else
  193. {
  194. break;
  195. }
  196. }
  197. }
  198. p.level.Blockchange(pos.x, pos.y, pos.z, type);
  199. previous.Add(pos);
  200. allBlocks.Add(pos);
  201. bool comeOut = false;
  202. foreach (Player pl in Player.players)
  203. {
  204. if (pl.level == p.level)
  205. {
  206. if ((ushort)(pl.pos[0] / 32) == pos.x || (ushort)(pl.pos[0] / 32 + 1) == pos.x || (ushort)(pl.pos[0] / 32 - 1) == pos.x)
  207. {
  208. if ((ushort)(pl.pos[1] / 32) == pos.y || (ushort)(pl.pos[1] / 32 + 1) == pos.y || (ushort)(pl.pos[1] / 32 - 1) == pos.y)
  209. {
  210. if ((ushort)(pl.pos[2] / 32) == pos.z || (ushort)(pl.pos[2] / 32 + 1) == pos.z || (ushort)(pl.pos[2] / 32 - 1) == pos.z)
  211. {
  212. if (p.level.physics >= 3 && bp.ending >= 2)
  213. pl.HandleDeath(Block.stone, " was blown up by " + p.color + p.name, true);
  214. else
  215. pl.HandleDeath(Block.stone, " was shot by " + p.color + p.name);
  216. comeOut = true;
  217. }
  218. }
  219. }
  220. }
  221. }
  222. if (comeOut) break;
  223. if (t > 12 && bp.ending != 3)
  224. {
  225. pos = previous[0];
  226. p.level.Blockchange(pos.x, pos.y, pos.z, Block.air);
  227. previous.Remove(pos);
  228. }
  229. if (bp.ending != 3) Thread.Sleep(20);
  230. }
  231. if (bp.ending == -1)
  232. try
  233. {
  234. unchecked { p.SendPos((byte)-1, (ushort)(previous[previous.Count - 3].x * 32), (ushort)(previous[previous.Count - 3].y * 32 + 32), (ushort)(previous[previous.Count - 3].z * 32), p.rot[0], p.rot[1]); }
  235. } catch { }
  236. if (bp.ending == 3) Thread.Sleep(400);
  237. foreach (CatchPos pos1 in previous)
  238. {
  239. p.level.Blockchange(pos1.x, pos1.y, pos1.z, Block.air);
  240. if (bp.ending != 3) Thread.Sleep(20);
  241. }
  242. }));
  243. gunThread.Start();
  244. }
  245. public override void Help(Player p)
  246. {
  247. Player.SendMessage(p, "/gun [at end] - Allows you to fire bullets at people");
  248. Player.SendMessage(p, "Available [at end] values: &cexplode, destroy, laser, tp");
  249. }
  250. public struct CatchPos { public ushort x, y, z; }
  251. public struct Pos { public ushort x, y, z; public int ending; }
  252. }
  253. }