mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 12:05:51 -04:00
fix some issues with /gun
This commit is contained in:
parent
70593dde6c
commit
4bf0b21023
@ -58,10 +58,7 @@ namespace MCGalaxy.Core {
|
|||||||
foreach (Zone zn in zones) { zn.Show(p); }
|
foreach (Zone zn in zones) { zn.Show(p); }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.aiming && !level.Config.Guns) {
|
if (p.weapon != null && !level.Config.Guns) p.weapon.Disable();
|
||||||
p.aiming = false;
|
|
||||||
p.ClearBlockchange();
|
|
||||||
}
|
|
||||||
if (!level.Config.UseBlockDB) {
|
if (!level.Config.UseBlockDB) {
|
||||||
p.Message("BlockDB is disabled here, %Wyou will not be able to /undo or /redo");
|
p.Message("BlockDB is disabled here, %Wyou will not be able to /undo or /redo");
|
||||||
}
|
}
|
||||||
|
@ -175,10 +175,10 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
if (old == b.Block || !p.group.Blocks[old] || !p.group.Blocks[b.Block]) return;
|
if (old == b.Block || !p.group.Blocks[old] || !p.group.Blocks[b.Block]) return;
|
||||||
|
|
||||||
// Check if player can affect block at coords in world
|
// Check if player can affect block at coords in world
|
||||||
AccessController denied = lvl.CanAffect(p, b.X, b.Y, b.Z);
|
AccessController denier = lvl.CanAffect(p, b.X, b.Y, b.Z);
|
||||||
if (denied != null) {
|
if (denier != null) {
|
||||||
if (p.lastAccessStatus < DateTime.UtcNow) {
|
if (p.lastAccessStatus < DateTime.UtcNow) {
|
||||||
denied.CheckDetailed(p);
|
denier.CheckDetailed(p);
|
||||||
p.lastAccessStatus = DateTime.UtcNow.AddSeconds(2);
|
p.lastAccessStatus = DateTime.UtcNow.AddSeconds(2);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -75,12 +75,9 @@ namespace MCGalaxy.Games {
|
|||||||
void ResetPlayerFlag(Player p, CtfData data) {
|
void ResetPlayerFlag(Player p, CtfData data) {
|
||||||
Vec3S32 last = data.LastHeadPos;
|
Vec3S32 last = data.LastHeadPos;
|
||||||
ushort x = (ushort)last.X, y = (ushort)last.Y, z = (ushort)last.Z;
|
ushort x = (ushort)last.X, y = (ushort)last.Y, z = (ushort)last.Z;
|
||||||
data.LastHeadPos = default(Vec3S32);
|
|
||||||
|
|
||||||
BlockID origBlock = Map.GetBlock(x, y, z);
|
data.LastHeadPos = default(Vec3S32);
|
||||||
if (origBlock != Block.Invalid) {
|
Map.BroadcastRevert(x, y, z);
|
||||||
Map.BroadcastChange(x, y, z, origBlock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawPlayerFlag(Player p, CtfData data) {
|
void DrawPlayerFlag(Player p, CtfData data) {
|
||||||
|
@ -52,7 +52,7 @@ namespace MCGalaxy.Games {
|
|||||||
if (args.iterations > 12) {
|
if (args.iterations > 12) {
|
||||||
Vec3U16 pos = args.visible[0];
|
Vec3U16 pos = args.visible[0];
|
||||||
args.visible.RemoveAt(0);
|
args.visible.RemoveAt(0);
|
||||||
p.level.Blockchange(pos.X, pos.Y, pos.Z, Block.Air, true);
|
p.level.BroadcastRevert(pos.X, pos.Y, pos.Z);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ namespace MCGalaxy.Games {
|
|||||||
if (args.visible.Count > 0) {
|
if (args.visible.Count > 0) {
|
||||||
Vec3U16 pos = args.visible[0];
|
Vec3U16 pos = args.visible[0];
|
||||||
args.visible.RemoveAt(0);
|
args.visible.RemoveAt(0);
|
||||||
p.level.Blockchange(pos.X, pos.Y, pos.Z, Block.Air, true);
|
p.level.BroadcastRevert(pos.X, pos.Y, pos.Z);
|
||||||
}
|
}
|
||||||
return args.visible.Count > 0;
|
return args.visible.Count > 0;
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ namespace MCGalaxy.Games {
|
|||||||
if (cur != Block.Air && !args.all.Contains(pos) && OnHitBlock(args, pos, cur))
|
if (cur != Block.Air && !args.all.Contains(pos) && OnHitBlock(args, pos, cur))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
p.level.Blockchange(pos.X, pos.Y, pos.Z, args.block);
|
p.level.BroadcastChange(pos.X, pos.Y, pos.Z, args.block);
|
||||||
args.visible.Add(pos);
|
args.visible.Add(pos);
|
||||||
args.all.Add(pos);
|
args.all.Add(pos);
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ namespace MCGalaxy.Games {
|
|||||||
args.all.Clear();
|
args.all.Clear();
|
||||||
} else {
|
} else {
|
||||||
foreach (Vec3U16 pos in args.visible) {
|
foreach (Vec3U16 pos in args.visible) {
|
||||||
p.level.Blockchange(pos.X, pos.Y, pos.Z, Block.Air, true);
|
p.level.BroadcastRevert(pos.X, pos.Y, pos.Z);
|
||||||
}
|
}
|
||||||
args.visible.Clear();
|
args.visible.Clear();
|
||||||
}
|
}
|
||||||
|
@ -25,171 +25,172 @@ using BlockID = System.UInt16;
|
|||||||
|
|
||||||
namespace MCGalaxy.Games {
|
namespace MCGalaxy.Games {
|
||||||
|
|
||||||
/// <summary> Represents a weapon which can interact with blocks or players until it dies. </summary>
|
/// <summary> Represents a weapon which can interact with blocks or players until it dies. </summary>
|
||||||
/// <remarks> Activated by clicking through either PlayerClick or a glass box around the player. </remarks>
|
/// <remarks> Activated by clicking through either PlayerClick or a glass box around the player. </remarks>
|
||||||
public abstract class Weapon {
|
public abstract class Weapon {
|
||||||
|
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
static bool hookedEvents;
|
static bool hookedEvents;
|
||||||
|
|
||||||
protected Player p;
|
protected Player p;
|
||||||
AimBox aimer;
|
AimBox aimer;
|
||||||
|
|
||||||
public void Enable(Player p) {
|
public void Enable(Player p) {
|
||||||
if (!hookedEvents) {
|
if (!hookedEvents) {
|
||||||
OnPlayerClickEvent.Register(PlayerClickCallback, Priority.Low);
|
OnPlayerClickEvent.Register(PlayerClickCallback, Priority.Low);
|
||||||
hookedEvents = true;
|
hookedEvents = true;
|
||||||
}
|
}
|
||||||
this.p = p;
|
this.p = p;
|
||||||
p.ClearBlockchange();
|
p.ClearBlockchange();
|
||||||
|
|
||||||
if (p.Supports(CpeExt.PlayerClick)) {
|
if (p.Supports(CpeExt.PlayerClick)) {
|
||||||
p.Message(Name + " engaged, click to fire at will");
|
p.Message(Name + " engaged, click to fire at will");
|
||||||
} else {
|
} else {
|
||||||
p.Blockchange += BlockClickCallback;
|
p.Blockchange += BlockClickCallback;
|
||||||
p.Message(Name + " engaged, fire at will");
|
p.Message(Name + " engaged, fire at will");
|
||||||
aimer = new AimBox();
|
aimer = new AimBox();
|
||||||
aimer.Hook(p);
|
aimer.Hook(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disable() {
|
public void Disable() {
|
||||||
p.aiming = false;
|
p.aiming = false;
|
||||||
p.ClearBlockchange();
|
p.ClearBlockchange();
|
||||||
p.Message(Name + " disabled");
|
p.Message(Name + " disabled");
|
||||||
}
|
p.weapon = null;
|
||||||
|
}
|
||||||
protected abstract void OnActivated(byte yaw, byte pitch, BlockID block);
|
|
||||||
|
protected abstract void OnActivated(byte yaw, byte pitch, BlockID block);
|
||||||
|
|
||||||
|
|
||||||
static void BlockClickCallback(Player p, ushort x, ushort y, ushort z, BlockID block) {
|
static void BlockClickCallback(Player p, ushort x, ushort y, ushort z, BlockID block) {
|
||||||
Weapon weapon = p.weapon;
|
Weapon weapon = p.weapon;
|
||||||
if (weapon == null) return;
|
if (weapon == null) return;
|
||||||
|
|
||||||
p.RevertBlock(x, y, z);
|
p.RevertBlock(x, y, z);
|
||||||
// defer to player click handler
|
// defer to player click handler
|
||||||
if (weapon.aimer == null) return;
|
if (weapon.aimer == null) return;
|
||||||
|
|
||||||
if (!p.level.Config.Guns) { weapon.Disable(); return; }
|
if (!p.level.Config.Guns) { weapon.Disable(); return; }
|
||||||
if (!CommandParser.IsBlockAllowed(p, "use", block)) return;
|
if (!CommandParser.IsBlockAllowed(p, "use", block)) return;
|
||||||
|
|
||||||
weapon.OnActivated(p.Rot.RotY, p.Rot.HeadX, block);
|
weapon.OnActivated(p.Rot.RotY, p.Rot.HeadX, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PlayerClickCallback(Player p, MouseButton btn, MouseAction action,
|
static void PlayerClickCallback(Player p, MouseButton btn, MouseAction action,
|
||||||
ushort yaw, ushort pitch, byte entity,
|
ushort yaw, ushort pitch, byte entity,
|
||||||
ushort x, ushort y, ushort z, TargetBlockFace face) {
|
ushort x, ushort y, ushort z, TargetBlockFace face) {
|
||||||
Weapon weapon = p.weapon;
|
Weapon weapon = p.weapon;
|
||||||
if (weapon == null || action != MouseAction.Pressed) return;
|
if (weapon == null || action != MouseAction.Pressed) return;
|
||||||
|
|
||||||
if (!(btn == MouseButton.Left || btn == MouseButton.Right)) return;
|
if (!(btn == MouseButton.Left || btn == MouseButton.Right)) return;
|
||||||
if (!p.level.Config.Guns) { weapon.Disable(); return; }
|
if (!p.level.Config.Guns) { weapon.Disable(); return; }
|
||||||
|
|
||||||
BlockID held = p.RawHeldBlock;
|
BlockID held = p.RawHeldBlock;
|
||||||
if (!CommandParser.IsBlockAllowed(p, "use", held)) return;
|
if (!CommandParser.IsBlockAllowed(p, "use", held)) return;
|
||||||
weapon.OnActivated((byte)(yaw >> 8), (byte)(pitch >> 8), held);
|
weapon.OnActivated((byte)(yaw >> 8), (byte)(pitch >> 8), held);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Player PlayerAt(Player p, Vec3U16 pos, bool skipSelf) {
|
protected static Player PlayerAt(Player p, Vec3U16 pos, bool skipSelf) {
|
||||||
Player[] players = PlayerInfo.Online.Items;
|
Player[] players = PlayerInfo.Online.Items;
|
||||||
foreach (Player pl in players) {
|
foreach (Player pl in players) {
|
||||||
if (pl.level != p.level) continue;
|
if (pl.level != p.level) continue;
|
||||||
if (p == pl && skipSelf) continue;
|
if (p == pl && skipSelf) continue;
|
||||||
|
|
||||||
if (Math.Abs(pl.Pos.BlockX - pos.X) <= 1
|
if (Math.Abs(pl.Pos.BlockX - pos.X) <= 1
|
||||||
&& Math.Abs(pl.Pos.BlockY - pos.Y) <= 1
|
&& Math.Abs(pl.Pos.BlockY - pos.Y) <= 1
|
||||||
&& Math.Abs(pl.Pos.BlockZ - pos.Z) <= 1)
|
&& Math.Abs(pl.Pos.BlockZ - pos.Z) <= 1)
|
||||||
{
|
{
|
||||||
return pl;
|
return pl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AmmunitionData {
|
public class AmmunitionData {
|
||||||
public BlockID block;
|
public BlockID block;
|
||||||
public Vec3U16 pos, start;
|
public Vec3U16 pos, start;
|
||||||
public Vec3F32 dir;
|
public Vec3F32 dir;
|
||||||
public bool moving = true;
|
public bool moving = true;
|
||||||
|
|
||||||
// positions of all currently visible "trailing" blocks
|
// positions of all currently visible "trailing" blocks
|
||||||
public List<Vec3U16> visible = new List<Vec3U16>();
|
public List<Vec3U16> visible = new List<Vec3U16>();
|
||||||
// position of all blocks this ammunition has touched/gone through
|
// position of all blocks this ammunition has touched/gone through
|
||||||
public List<Vec3U16> all = new List<Vec3U16>();
|
public List<Vec3U16> all = new List<Vec3U16>();
|
||||||
public int iterations;
|
public int iterations;
|
||||||
|
|
||||||
public Vec3U16 PosAt(int i) {
|
public Vec3U16 PosAt(int i) {
|
||||||
Vec3U16 target;
|
Vec3U16 target;
|
||||||
target.X = (ushort)Math.Round(start.X + (double)(dir.X * i));
|
target.X = (ushort)Math.Round(start.X + (double)(dir.X * i));
|
||||||
target.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * i));
|
target.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * i));
|
||||||
target.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * i));
|
target.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * i));
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Manages the glass box around the player. Adjusts based on where player is looking. </summary>
|
/// <summary> Manages the glass box around the player. Adjusts based on where player is looking. </summary>
|
||||||
internal sealed class AimBox {
|
internal sealed class AimBox {
|
||||||
|
|
||||||
Player player;
|
Player player;
|
||||||
List<Vec3U16> lastGlass = new List<Vec3U16>();
|
List<Vec3U16> lastGlass = new List<Vec3U16>();
|
||||||
List<Vec3U16> curGlass = new List<Vec3U16>();
|
List<Vec3U16> curGlass = new List<Vec3U16>();
|
||||||
|
|
||||||
public void Hook(Player p) {
|
public void Hook(Player p) {
|
||||||
player = p;
|
player = p;
|
||||||
SchedulerTask task = new SchedulerTask(AimCallback, null, TimeSpan.Zero, true);
|
SchedulerTask task = new SchedulerTask(AimCallback, null, TimeSpan.Zero, true);
|
||||||
p.CriticalTasks.Add(task);
|
p.CriticalTasks.Add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AimCallback(SchedulerTask task) {
|
void AimCallback(SchedulerTask task) {
|
||||||
Player p = player;
|
Player p = player;
|
||||||
if (p.aiming) { Update(); return; }
|
if (p.aiming) { Update(); return; }
|
||||||
|
|
||||||
foreach (Vec3U16 pos in lastGlass) {
|
foreach (Vec3U16 pos in lastGlass) {
|
||||||
if (!p.level.IsValidPos(pos)) continue;
|
if (!p.level.IsValidPos(pos)) continue;
|
||||||
p.RevertBlock(pos.X, pos.Y, pos.Z);
|
p.RevertBlock(pos.X, pos.Y, pos.Z);
|
||||||
}
|
}
|
||||||
task.Repeating = false;
|
task.Repeating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update() {
|
void Update() {
|
||||||
Player p = player;
|
Player p = player;
|
||||||
Vec3F32 dir = DirUtils.GetDirVector(p.Rot.RotY, p.Rot.HeadX);
|
Vec3F32 dir = DirUtils.GetDirVector(p.Rot.RotY, p.Rot.HeadX);
|
||||||
ushort x = (ushort)Math.Round(p.Pos.BlockX + dir.X * 3);
|
ushort x = (ushort)Math.Round(p.Pos.BlockX + dir.X * 3);
|
||||||
ushort y = (ushort)Math.Round(p.Pos.BlockY + dir.Y * 3);
|
ushort y = (ushort)Math.Round(p.Pos.BlockY + dir.Y * 3);
|
||||||
ushort z = (ushort)Math.Round(p.Pos.BlockZ + dir.Z * 3);
|
ushort z = (ushort)Math.Round(p.Pos.BlockZ + dir.Z * 3);
|
||||||
|
|
||||||
int dx = Math.Sign(dir.X) >= 0 ? 1 : -1, dz = Math.Sign(dir.Z) >= 0 ? 1 : -1;
|
int dx = Math.Sign(dir.X) >= 0 ? 1 : -1, dz = Math.Sign(dir.Z) >= 0 ? 1 : -1;
|
||||||
Check(p.level, x, y, z );
|
Check(p.level, x, y, z );
|
||||||
Check(p.level, x + dx, y, z );
|
Check(p.level, x + dx, y, z );
|
||||||
Check(p.level, x, y, z + dz);
|
Check(p.level, x, y, z + dz);
|
||||||
Check(p.level, x + dx, y, z + dz);
|
Check(p.level, x + dx, y, z + dz);
|
||||||
|
|
||||||
// Revert all glass blocks now not in the ray from the player's direction
|
// Revert all glass blocks now not in the ray from the player's direction
|
||||||
for (int i = 0; i < lastGlass.Count; i++) {
|
for (int i = 0; i < lastGlass.Count; i++) {
|
||||||
Vec3U16 pos = lastGlass[i];
|
Vec3U16 pos = lastGlass[i];
|
||||||
if (curGlass.Contains(pos)) continue;
|
if (curGlass.Contains(pos)) continue;
|
||||||
|
|
||||||
if (p.level.IsValidPos(pos))
|
if (p.level.IsValidPos(pos))
|
||||||
p.RevertBlock(pos.X, pos.Y, pos.Z);
|
p.RevertBlock(pos.X, pos.Y, pos.Z);
|
||||||
lastGlass.RemoveAt(i); i--;
|
lastGlass.RemoveAt(i); i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place the new glass blocks that are in the ray from the player's direction
|
// Place the new glass blocks that are in the ray from the player's direction
|
||||||
foreach (Vec3U16 pos in curGlass) {
|
foreach (Vec3U16 pos in curGlass) {
|
||||||
if (lastGlass.Contains(pos)) continue;
|
if (lastGlass.Contains(pos)) continue;
|
||||||
lastGlass.Add(pos);
|
lastGlass.Add(pos);
|
||||||
p.SendBlockchange(pos.X, pos.Y, pos.Z, Block.Glass);
|
p.SendBlockchange(pos.X, pos.Y, pos.Z, Block.Glass);
|
||||||
}
|
}
|
||||||
curGlass.Clear();
|
curGlass.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Check(Level lvl, int x, int y, int z) {
|
void Check(Level lvl, int x, int y, int z) {
|
||||||
Vec3U16 pos = new Vec3U16((ushort)x, (ushort)(y - 1), (ushort)z);
|
Vec3U16 pos = new Vec3U16((ushort)x, (ushort)(y - 1), (ushort)z);
|
||||||
if (lvl.IsAirAt(pos.X, pos.Y, pos.Z)) curGlass.Add(pos);
|
if (lvl.IsAirAt(pos.X, pos.Y, pos.Z)) curGlass.Add(pos);
|
||||||
|
|
||||||
pos.Y++;
|
pos.Y++;
|
||||||
if (lvl.IsAirAt(pos.X, pos.Y, pos.Z)) curGlass.Add(pos);
|
if (lvl.IsAirAt(pos.X, pos.Y, pos.Z)) curGlass.Add(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ namespace MCGalaxy.Generator.Foliage {
|
|||||||
public virtual int MinSize { get { return 3; } }
|
public virtual int MinSize { get { return 3; } }
|
||||||
|
|
||||||
/// <summary> Maximum allowed size (usually means height) for this tree. </summary>
|
/// <summary> Maximum allowed size (usually means height) for this tree. </summary>
|
||||||
public virtual int MaxSize { get { return 100; } }
|
public virtual int MaxSize { get { return 4096; } }
|
||||||
|
|
||||||
/// <summary> Estimated the maximum number of blocks affected by this tree. </summary>
|
/// <summary> Estimated the maximum number of blocks affected by this tree. </summary>
|
||||||
public abstract int EstimateBlocksAffected();
|
public abstract int EstimateBlocksAffected();
|
||||||
|
@ -180,6 +180,8 @@ namespace MCGalaxy {
|
|||||||
return block >= Block.Water && block <= Block.StillLava;
|
return block >= Block.Water && block <= Block.StillLava;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Returns the AccessController denying the player from changing blocks at the given coordinates. </summary>
|
||||||
|
/// <remarks> If no AccessController denies the player, returns null. </remarks>
|
||||||
public AccessController CanAffect(Player p, ushort x, ushort y, ushort z) {
|
public AccessController CanAffect(Player p, ushort x, ushort y, ushort z) {
|
||||||
Zone[] zones = Zones.Items;
|
Zone[] zones = Zones.Items;
|
||||||
if (zones.Length == 0) goto checkRank; // TODO: avoid this
|
if (zones.Length == 0) goto checkRank; // TODO: avoid this
|
||||||
@ -216,11 +218,11 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
public bool CheckAffect(Player p, ushort x, ushort y, ushort z, BlockID old, BlockID block) {
|
public bool CheckAffect(Player p, ushort x, ushort y, ushort z, BlockID old, BlockID block) {
|
||||||
if (!p.group.Blocks[old] || !p.group.Blocks[block]) return false;
|
if (!p.group.Blocks[old] || !p.group.Blocks[block]) return false;
|
||||||
AccessController denied = CanAffect(p, x, y, z);
|
AccessController denier = CanAffect(p, x, y, z);
|
||||||
if (denied == null) return true;
|
if (denier == null) return true;
|
||||||
|
|
||||||
if (p.lastAccessStatus < DateTime.UtcNow) {
|
if (p.lastAccessStatus < DateTime.UtcNow) {
|
||||||
denied.CheckDetailed(p);
|
denier.CheckDetailed(p);
|
||||||
p.lastAccessStatus = DateTime.UtcNow.AddSeconds(2);
|
p.lastAccessStatus = DateTime.UtcNow.AddSeconds(2);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -234,6 +236,13 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Sends a block update packet to all players in this level. </summary>
|
||||||
|
/// <remarks> The block sent is the current block at the given coordinates. </remarks>
|
||||||
|
public void BroadcastRevert(ushort x, ushort y, ushort z) {
|
||||||
|
BlockID block = GetBlock(x, y, z);
|
||||||
|
if (block != Block.Invalid) BroadcastChange(x, y, z, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Blockchange(Player p, ushort x, ushort y, ushort z, BlockID block) {
|
public void Blockchange(Player p, ushort x, ushort y, ushort z, BlockID block) {
|
||||||
if (DoBlockchange(p, x, y, z, block) == 2) BroadcastChange(x, y, z, block);
|
if (DoBlockchange(p, x, y, z, block) == 2) BroadcastChange(x, y, z, block);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user