Fly no longer spawns a new thread

This commit is contained in:
UnknownShadow200 2017-05-31 23:19:28 +10:00
parent 5411ee4f97
commit 1e6cf8fe7b
4 changed files with 102 additions and 77 deletions

View File

@ -19,6 +19,7 @@ using System;
using System.Collections.Generic;
using System.Threading;
using MCGalaxy.Maths;
using MCGalaxy.Tasks;
namespace MCGalaxy.Commands.Misc {
public sealed class CmdFly : Command {
@ -36,61 +37,71 @@ namespace MCGalaxy.Commands.Misc {
p.isFlying = !p.isFlying;
if (!p.isFlying) return;
Player.Message(p, "You are now flying. &cJump!");
Thread flyThread = new Thread(() => FlyThread(p));
flyThread.Name = "MCG_Fly";
flyThread.Start();
}
void FlyThread(Player p) {
Position oldpos = default(Position);
List<Vec3U16> last = new List<Vec3U16>(), next = new List<Vec3U16>();
while (p.isFlying && !p.disconnected)
DoFly(p, ref oldpos, last, next);
foreach (Vec3U16 cP in last)
p.SendBlockchange(cP.X, cP.Y, cP.Z, ExtBlock.Air);
Player.Message(p, "Stopped flying");
}
void DoFly(Player p, ref Position old, List<Vec3U16> last, List<Vec3U16> next) {
Thread.Sleep(20);
if (p.Pos == old) return;
try {
int x = p.Pos.BlockX, z = p.Pos.BlockZ;
int y = (p.Pos.Y - 60) / 32;
ExtBlock glass = (ExtBlock)Block.glass;
Player.Message(p, "You are now flying. &cJump!");
FlyState state = new FlyState();
state.player = p;
SchedulerTask task = new SchedulerTask(FlyCallback, state, TimeSpan.Zero, true);
p.CriticalTasks.Add(task);
}
class FlyState {
public Player player;
public Position oldPos = default(Position);
public List<Vec3U16> last = new List<Vec3U16>();
public List<Vec3U16> next = new List<Vec3U16>();
}
static void FlyCallback(SchedulerTask task) {
FlyState state = (FlyState)task.State;
Player p = state.player;
if (state.player.isFlying) { DoFly(state); return; }
foreach (Vec3U16 cP in state.last) {
p.SendBlockchange(cP.X, cP.Y, cP.Z, ExtBlock.Air);
}
Player.Message(p, "Stopped flying");
task.Repeating = false;
}
for (int yy = y - 1; yy <= y; yy++)
for (int zz = z - 2; zz <= z + 2; zz++)
for (int xx = x - 2; xx <= x + 2; xx++)
{
ushort offX = (ushort)xx, offY = (ushort)yy, offZ = (ushort)zz;
if (p.level.GetTile(offX, offY, offZ) != Block.air) continue;
Vec3U16 pos;
pos.X = offX; pos.Y = offY; pos.Z = offZ;
next.Add(pos);
}
static void DoFly(FlyState state) {
Player p = state.player;
if (p.Pos == state.oldPos) return;
int x = p.Pos.BlockX, z = p.Pos.BlockZ;
int y = (p.Pos.Y - 60) / 32;
ExtBlock glass = (ExtBlock)Block.glass;
for (int yy = y - 1; yy <= y; yy++)
for (int zz = z - 2; zz <= z + 2; zz++)
for (int xx = x - 2; xx <= x + 2; xx++)
{
ushort offX = (ushort)xx, offY = (ushort)yy, offZ = (ushort)zz;
if (p.level.GetTile(offX, offY, offZ) != Block.air) continue;
foreach (Vec3U16 P in next) {
if (last.Contains(P)) continue;
last.Add(P);
p.SendBlockchange(P.X, P.Y, P.Z, glass);
}
Vec3U16 pos;
pos.X = offX; pos.Y = offY; pos.Z = offZ;
state.next.Add(pos);
}
foreach (Vec3U16 P in state.next) {
if (state.last.Contains(P)) continue;
state.last.Add(P);
p.SendBlockchange(P.X, P.Y, P.Z, glass);
}
for (int i = 0; i < state.last.Count; i++) {
Vec3U16 P = state.last[i];
if (state.next.Contains(P)) continue;
for (int i = 0; i < last.Count; i++) {
Vec3U16 P = last[i];
if (next.Contains(P)) continue;
p.SendBlockchange(P.X, P.Y, P.Z, ExtBlock.Air);
last.RemoveAt(i); i--;
}
next.Clear();
} catch (Exception ex) { Server.ErrorLog(ex); }
old = p.Pos;
p.SendBlockchange(P.X, P.Y, P.Z, ExtBlock.Air);
state.last.RemoveAt(i); i--;
}
state.next.Clear();
state.oldPos = p.Pos;
}
public override void Help(Player p) {

View File

@ -23,6 +23,7 @@ using MCGalaxy.Undo;
using MCGalaxy.Maths;
using MCGalaxy.Events;
using MCGalaxy.Network;
using MCGalaxy.Tasks;
namespace MCGalaxy {
@ -146,6 +147,7 @@ namespace MCGalaxy {
public bool staticCommands = false;
public DateTime ZoneSpam;
public VolatileArray<SchedulerTask> CriticalTasks = new VolatileArray<SchedulerTask>(false);
public bool aiming;
public bool isFlying = false;

View File

@ -276,6 +276,7 @@ namespace MCGalaxy {
leftServer = true;
if (chatMsg != null) chatMsg = Colors.EscapeColors(chatMsg);
discMsg = Colors.EscapeColors(discMsg);
CriticalTasks.Clear();
//Umm...fixed?
if (name == "") {

View File

@ -28,43 +28,54 @@ namespace MCGalaxy.Tasks {
internal static void LocationChecks(SchedulerTask task) {
Player[] players = PlayerInfo.Online.Items;
players = PlayerInfo.Online.Items;
players = PlayerInfo.Online.Items;
int delay = players.Length == 0 ? 100 : 20;
task.Delay = TimeSpan.FromMilliseconds(delay);
for (int i = 0; i < players.Length; i++) {
try {
Player p = players[i];
if (p.following != "") {
Player who = PlayerInfo.FindExact(p.following);
if (who == null || who.level != p.level) {
p.following = "";
if (!p.canBuild)
p.canBuild = true;
if (who != null && who.possess == p.name)
who.possess = "";
continue;
}
p.SendPos(Entities.SelfID, who.Pos, who.Rot);
} else if (p.possess != "") {
Player who = PlayerInfo.FindExact(p.possess);
if (who == null || who.level != p.level)
p.possess = "";
}
Vec3U16 P = (Vec3U16)p.Pos.BlockCoords;
if (p.level.Death)
p.CheckSurvival(P.X, P.Y, P.Z);
p.CheckBlock();
p.oldIndex = p.level.PosToInt(P.X, P.Y, P.Z);
TickPlayer(players[i]);
} catch (Exception e) {
Server.ErrorLog(e);
}
}
}
static void TickPlayer(Player p) {
if (p.following != "") {
Player who = PlayerInfo.FindExact(p.following);
if (who == null || who.level != p.level) {
p.following = "";
if (!p.canBuild)
p.canBuild = true;
if (who != null && who.possess == p.name)
who.possess = "";
return;
}
p.SendPos(Entities.SelfID, who.Pos, who.Rot);
} else if (p.possess != "") {
Player who = PlayerInfo.FindExact(p.possess);
if (who == null || who.level != p.level)
p.possess = "";
}
Vec3U16 P = (Vec3U16)p.Pos.BlockCoords;
if (p.level.Death)
p.CheckSurvival(P.X, P.Y, P.Z);
p.CheckBlock();
p.oldIndex = p.level.PosToInt(P.X, P.Y, P.Z);
SchedulerTask[] tasks = p.CriticalTasks.Items;
for (int i = 0; i < tasks.Length; i++) {
SchedulerTask task = tasks[i];
task.Callback(task);
if (task.Repeating) continue;
p.CriticalTasks.Remove(task);
}
}
internal static void UpdateEntityPositions(SchedulerTask task) {
Entities.GlobalUpdate();
PlayerBot.GlobalUpdatePosition();