protected override void PlacedMark(Player p, ushort x, ushort y, ushort z, BlockID block) { p.RevertBlock(x, y, z); if (!p.level.Config.Guns) { p.ClearBlockchange(); return; } if (!CommandParser.IsBlockAllowed(p, "use", block)) { return; } WeaponArgs args = new WeaponArgs(); args.player = p; args.block = block; args.weaponType = (WeaponType)p.blockchangeObject; args.start = MakePos(p); args.dir = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX); args.pos = args.PosAt(3); args.iterations = 4; SchedulerTask task = new SchedulerTask(GunCallback, args, TimeSpan.Zero, true); p.CriticalTasks.Add(task); }
static Vec3U16 MissileTarget(WeaponArgs args) { Player p = args.player; args.start = MakePos(p); args.dir = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX); int i; for (i = 1; ; i++) { Vec3U16 target = args.PosAt(i); BlockID block = p.level.GetBlock(target.X, target.Y, target.Z); if (block == Block.Invalid) { break; } if (block != Block.Air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, block, args.weaponType, target, false)) { break; } Player hit = GetPlayer(p, target, true); if (hit != null) { return(MakePos(hit)); } } return(args.PosAt(i - 1)); }
void DoAim(Player p) { List <Vec3U16> lastSent = new List <Vec3U16>(), toSend = new List <Vec3U16>(); while (p.aiming) { Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]); try { ushort x = (ushort)Math.Round((ushort)(p.pos[0] / 32) + dir.X * 3); ushort y = (ushort)Math.Round((ushort)(p.pos[1] / 32) + dir.Y * 3); ushort z = (ushort)Math.Round((ushort)(p.pos[2] / 32) + dir.Z * 3); int signX = Math.Sign(dir.X) >= 0 ? 1 : -1, signZ = Math.Sign(dir.Z) >= 0 ? 1 : -1; CheckTile(p.level, toSend, x, y, z); CheckTile(p.level, toSend, x + signX, y, z); CheckTile(p.level, toSend, x, y, z + signZ); CheckTile(p.level, toSend, x + signX, y, z + signZ); // Revert all glass blocks now not in the ray from the player's direction for (int i = 0; i < lastSent.Count; i++) { Vec3U16 cP = lastSent[i]; if (toSend.Contains(cP)) { continue; } if (p.level.IsValidPos(cP)) { p.RevertBlock(cP.X, cP.Y, cP.Z); } lastSent.RemoveAt(i); i--; } // Place the new glass blocks that are in the ray from the player's direction foreach (Vec3U16 cP in toSend) { if (lastSent.Contains(cP)) { continue; } lastSent.Add(cP); p.SendBlockchange(cP.X, cP.Y, cP.Z, Block.glass); } toSend.Clear(); } catch { } Thread.Sleep(20); } foreach (Vec3U16 cP in lastSent) { if (p.level.IsValidPos(cP)) { p.RevertBlock(cP.X, cP.Y, cP.Z); } } }
static void DoAim(AimState state) { Player p = state.player; Vec3F32 dir = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX); ushort x = (ushort)Math.Round(p.Pos.BlockX + dir.X * 3); ushort y = (ushort)Math.Round(p.Pos.BlockY + dir.Y * 3); ushort z = (ushort)Math.Round(p.Pos.BlockZ + dir.Z * 3); int signX = Math.Sign(dir.X) >= 0 ? 1 : -1, signZ = Math.Sign(dir.Z) >= 0 ? 1 : -1; CheckTile(p.level, state.glassCoords, x, y, z); CheckTile(p.level, state.glassCoords, x + signX, y, z); CheckTile(p.level, state.glassCoords, x, y, z + signZ); CheckTile(p.level, state.glassCoords, x + signX, y, z + signZ); // Revert all glass blocks now not in the ray from the player's direction for (int i = 0; i < state.lastGlass.Count; i++) { Vec3U16 pos = state.lastGlass[i]; if (state.glassCoords.Contains(pos)) { continue; } if (p.level.IsValidPos(pos)) { p.RevertBlock(pos.X, pos.Y, pos.Z); } state.lastGlass.RemoveAt(i); i--; } // Place the new glass blocks that are in the ray from the player's direction foreach (Vec3U16 pos in state.glassCoords) { if (state.lastGlass.Contains(pos)) { continue; } state.lastGlass.Add(pos); p.SendBlockchange(pos.X, pos.Y, pos.Z, (ExtBlock)Block.Glass); } state.glassCoords.Clear(); }
void DoShoot(Player p, byte type, byte extType) { CatchPos bp = (CatchPos)p.blockchangeObject; List <Vec3U16> previous = new List <Vec3U16>(), allBlocks = new List <Vec3U16>(); Vec3U16 pos = MakePos(p); int total = 0; List <Vec3U16> buffer = new List <Vec3U16>(2); while (true) { Vec3U16 start = MakePos(p); total++; Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]); 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, type, extType); 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(Block.stone, 0, " was blown up by " + p.ColoredName, true); } else { hitP.HandleDeath(Block.stone, 0, " 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, Block.air, true); previous.RemoveAt(0); } Thread.Sleep(100); } } if (bp.ending == EndType.Teleport) { int index = previous.Count - 3; if (index >= 0 && index < previous.Count) { DoTeleport(p, previous[index]); } } foreach (Vec3U16 pos1 in previous) { p.level.Blockchange(pos1.X, pos1.Y, pos1.Z, Block.air, true); Thread.Sleep(100); } }
void DoShoot(Player p, byte type, byte extType) { CatchPos bp = (CatchPos)p.blockchangeObject; Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]); double bigDiag = Math.Sqrt(Math.Sqrt(p.level.Width * p.level.Width + p.level.Length * p.level.Length) + p.level.Height * p.level.Height + p.level.Width * p.level.Width); List <Vec3U16> previous = new List <Vec3U16>(); List <Vec3U16> allBlocks = new List <Vec3U16>(); Vec3U16 pos; ushort startX = (ushort)(p.pos[0] / 32); ushort startY = (ushort)(p.pos[1] / 32); ushort startZ = (ushort)(p.pos[2] / 32); pos.X = (ushort)Math.Round(startX + dir.X * 3); pos.Y = (ushort)Math.Round(startY + dir.Y * 3); pos.Z = (ushort)Math.Round(startZ + dir.Z * 3); for (double t = 4; bigDiag > t; t++) { pos.X = (ushort)Math.Round(startX + (double)(dir.X * t)); pos.Y = (ushort)Math.Round(startY + (double)(dir.Y * t)); pos.Z = (ushort)Math.Round(startZ + (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)) { break; } p.level.Blockchange(pos.X, pos.Y, pos.Z, type, extType); previous.Add(pos); allBlocks.Add(pos); if (HandlesPlayers(p, bp, pos)) { break; } if (t > 12 && bp.ending != EndType.Laser) { pos = previous[0]; p.level.Blockchange(pos.X, pos.Y, pos.Z, Block.air, true); previous.RemoveAt(0); } if (bp.ending != EndType.Laser) { Thread.Sleep(20); } } if (bp.ending == EndType.Teleport) { int index = previous.Count - 3; if (index >= 0 && index < previous.Count) { DoTeleport(p, previous[index]); } } if (bp.ending == EndType.Laser) { Thread.Sleep(400); } foreach (Vec3U16 pos1 in previous) { p.level.Blockchange(pos1.X, pos1.Y, pos1.Z, Block.air, true); if (bp.ending != EndType.Laser) { Thread.Sleep(20); } } }