static void Player_PlacedBlock(object sender, Events.PlayerPlacedBlockEventArgs e) { try { if (e.Player.World.Portals != null && e.Player.World.Portals.Count > 0 && e.Context != BlockChangeContext.Portal) { lock (e.Player.World.Portals.SyncRoot) { foreach (Portal portal in e.Player.World.Portals) { if (portal.IsInRange(e.Coords)) { BlockUpdate update = new BlockUpdate(null, e.Coords, e.OldBlock); e.Player.World.Map.QueueUpdate(update); e.Player.Message("You can not place a block inside portal: " + portal.Name); } } } } } catch (Exception ex) { Logger.Log(LogType.Error, "PortalHandler.Player_PlacedBlock: " + ex); } }
IEnumerator MsgBox_ChangeLine(int value) { MessageBox.Show(LocaleManager.instance.GetLocaleText("creator_willdeleted"), LocaleManager.instance.GetLocaleText("creator_willdeleteddesc"), MessageBoxButton.YesNo); yield return(new WaitUntil(() => MessageBox.Instance.ResultExists == true)); if (MessageBox.Instance.Result.Equals(MessageBoxButtonType.Yes)) { while (Blocks.Count > 0) { Block target = Blocks[0]; UpdateBlockDivLine -= target.UpdateDivLine; UpdateBlockSize -= target.UpdateSize; UpdateSpecificView -= target.SpecificView; if (target.Checkbox.isOn) { UpdateBlockBPM -= target.UpdateBPM; UpdateBlockNoteSpeed -= target.UpdateNoteSpeed; UpdateBlockNoteColor -= target.UpdateNoteColor; } Blocks.Remove(target); Destroy(target.gameObject); } ChangeLine(value); } }
/// <summary> /// Updates a specific block for a given time /// </summary> private void updateBlock(Block blockType, Vector3I blockPosition, bool replaceWithAir, double time)//I left this class rather generic incase i used it for anything else { BlockUpdate update = new BlockUpdate(null, blockPosition, blockType); foreach (Player p in World.Players) { p.World.Map.QueueUpdate(update); } if (replaceWithAir) { Scheduler.NewTask(t => updateBlock(Block.Air, blockPosition, false, time)).RunManual(TimeSpan.FromSeconds(time));//place a block, replace it with air once 'time' is up } }
public override void BlockUpdateEvent(Vector3Int causingPos, Block causingBlock, BlockUpdate type, Vector3Int affectedPos, ChunkManager chunks) { if ((type == BlockUpdate.BlockBroke || type == BlockUpdate.BlockChanged) && causingPos.x == affectedPos.x && causingPos.z == affectedPos.z && causingPos.y + 1 == affectedPos.y) { for (int i = 0; i < _canGrowOn.Length; i++) { if (_canGrowOn[i] == causingBlock) { return; } } chunks.BreakBlock(affectedPos); } }
public void SelectBlock(int index) { Block block = Blocks[index]; if (block.Checkbox.isOn) { UpdateBlockBPM += block.UpdateBPM; UpdateBlockNoteSpeed += block.UpdateNoteSpeed; UpdateBlockNoteColor += block.UpdateNoteColor; } else { UpdateBlockBPM -= block.UpdateBPM; UpdateBlockNoteSpeed -= block.UpdateNoteSpeed; UpdateBlockNoteColor -= block.UpdateNoteColor; } }
static void Player_PlacedBlock(object sender, Events.PlayerPlacedBlockEventArgs e) { if (e.Player == Player.Console) return; try { if (e.Player.World.Portals != null && e.Player.World.Portals.Count > 0 && e.Context != BlockChangeContext.Portal) { lock (e.Player.World.Portals.SyncRoot) { foreach (Portal portal in e.Player.World.Portals) { if (portal.IsInRange(e.Coords)) { BlockUpdate update = new BlockUpdate(null, e.Coords, e.OldBlock); e.Player.World.Map.QueueUpdate(update); e.Player.Message("You can not place a block inside portal: " + portal.Name); } } } } } catch (Exception ex) { Logger.Log(LogType.Error, "PortalHandler.Player_PlacedBlock: " + ex); } }
public void ExitClean() { while (Blocks.Count > 0) { Block target = Blocks[0]; UpdateBlockDivLine -= target.UpdateDivLine; UpdateBlockSize -= target.UpdateSize; UpdateSpecificView -= target.SpecificView; if (target.Checkbox.isOn) { UpdateBlockBPM -= target.UpdateBPM; UpdateBlockNoteSpeed -= target.UpdateNoteSpeed; UpdateBlockNoteColor -= target.UpdateNoteColor; } Blocks.Remove(target); Destroy(target.gameObject); } }
public void Receive(PacketBuffer buffer) { chunkX = buffer.ReadInt(); chunkZ = buffer.ReadInt(); int arrLen = buffer.ReadVarInt(); updates = new BlockUpdate[arrLen]; for (int i = 0; i < arrLen; i++) { short temp = buffer.ReadShort(); int x = temp >> 12 & 15; int y = temp & 255; int z = temp >> 8 & 15; int newId = buffer.ReadVarInt() >> 4; updates[i] = new BlockUpdate(x, y, z, newId); } }
static void Player_PlacedBlock(object sender, Events.PlayerPlacedBlockEventArgs e) { if (e.Player == Player.Console || e.Context == BlockChangeContext.Portal) { return; } try { Portal portal = e.Player.World.Portals.Find(e.Coords); if (portal == null) { return; } BlockUpdate update = new BlockUpdate(null, e.Coords, e.OldBlock); e.Player.World.Map.QueueUpdate(update); e.Player.Message("You can not place a block inside portal: " + portal.Name); } catch (Exception ex) { Logger.Log(LogType.Error, "PortalHandler.Player_PlacedBlock: " + ex); } }
public override void Decode(MinecraftStream stream) { ChunkX = stream.ReadInt(); ChunkZ = stream.ReadInt(); int recordCount = stream.ReadVarInt(); Records = new BlockUpdate[recordCount]; for (int i = 0; i < Records.Length; i++) { byte horizontalPos = (byte)stream.ReadByte(); BlockUpdate update = new BlockUpdate(); update.X = (horizontalPos >> 4 & 15) + (ChunkX * 16); update.Z = (horizontalPos & 15) + (ChunkZ * 16); update.Y = (byte)stream.ReadByte(); update.BlockId = stream.ReadVarInt(); Records[i] = update; } }
internal static async Task <bool> HandleFallingBlock(BlockUpdate blockUpdate) { if (blockUpdate.Block is null) { return(false); } var world = blockUpdate.world; var location = blockUpdate.position; var material = blockUpdate.Block.Value.Material; if (await world.GetBlockAsync(location + Vector.Down) is Block below && (Block.Replaceable.Contains(below.Material) || below.IsFluid)) { await world.SetBlockAsync(location, Block.Air); world.SpawnFallingBlock(location, material); return(true); } return(false); }
public override void Decode(MinecraftStream stream) { var chunkSectionPos = stream.ReadLong(); ChunkX = (int)(chunkSectionPos >> 42); var sectionY = (int)(chunkSectionPos << 44 >> 44); ChunkZ = (int)(chunkSectionPos << 22 >> 42); var inverse = stream.ReadBool(); //ChunkX = stream.ReadInt(); // ChunkZ = stream.ReadInt(); int recordCount = stream.ReadVarInt(); Records = new BlockUpdate[recordCount]; for (int i = 0; i < Records.Length; i++) { var encoded = stream.ReadVarLong(); // long encoded = rawId << 12 | (blockLocalX << 8 | blockLocalZ << 4 | blockLocalY) var rawId = encoded >> 12; var x = (int)((encoded >> 8) & 0xF); var y = (int)(encoded & 0xF); var z = (int)((encoded >> 4) & 0xF); //byte horizontalPos = (byte)stream.ReadByte(); BlockUpdate update = new BlockUpdate(); update.X = (ChunkX << 4) + x; update.Z = (ChunkZ << 4) + z; update.Y = (sectionY << 4) + y; update.BlockId = (uint)rawId; Records[i] = update; } }
protected void UpdateMap(BlockUpdate upd) { _map.SetBlock(upd.X, upd.Y, upd.Z, upd.BlockType); _map.QueueUpdate(upd); }
protected override int PerformInternal() { //lock is done already if (Block.Undefined == _prevBlock) //created out of bounds, dont continue { return(0); } //fix for portal gun if (_owner.orangePortal.Count > 0) { if (_pos == _owner.orangePortal[0] || _pos == _owner.orangePortal[1]) { return(0); } } if (_owner.bluePortal.Count > 0) { if (_pos == _owner.bluePortal[0] || _pos == _owner.bluePortal[1]) { return(0); } } //delete at the previous position, restore water unconditionally, lava only when bullet is still there to prevent restoration of explosion lava if (_prevBlock != Block.Water) { _prevBlock = _map.GetBlock(_pos) == _block ? //is the bullet still here (_prevBlock == Block.Lava ? Block.Lava : Block.Air) //yes, then either restore lava or set air : Block.Undefined; //no, it was removed by some other process, do nothing then } if (Block.Undefined != _prevBlock) { UpdateMap(new BlockUpdate(null, _pos, _prevBlock)); } List <BlockUpdate> updates = new List <BlockUpdate>(); for (int i = 0; i < _behavior.MovesPerProcessingStep && _restDistance > 0; ++i) { _pos = Move(); _prevBlock = _map.GetBlock(_pos); if (Block.Undefined == _prevBlock) { _restDistance = 0; break; } _behavior.ModifyDirection(ref _direction, _prevBlock); //e.g. if you want it to be dependent on gravity or change direction depending on current block etc if (_behavior.VisitBlock(_world, _pos, _prevBlock, _owner, ref _restDistance, updates, _block) && _behavior.CanKillPlayer) { CheckHitPlayers(updates); } } bool cont = _restDistance > 0; if (cont) //check if the last update was for the current position and replace it with the particle { int idx = updates.Count - 1; if (idx >= 0 && updates[idx].X == _pos.X && updates[idx].Y == _pos.Y && updates[idx].Z == _pos.Z) { updates[idx] = new BlockUpdate(null, _pos, _block); } else { updates.Add(new BlockUpdate(null, _pos, _block)); } } for (int i = 0; i < updates.Count; ++i) { UpdateMap(updates[i]); } return(cont ? _stepDelay : 0); }
//hitted? jonty I thought you were better than that :( public void HitPlayer(World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList <BlockUpdate> updates) { //Capture the flag if (by.Info.isPlayingCTF) { //Friendly fire if ((hitted.Info.CTFBlueTeam && by.Info.CTFBlueTeam) || (hitted.Info.CTFRedTeam && by.Info.CTFRedTeam)) { by.Message("{0} is on your team!", hitted.Name); return; } if (hitted.Info.canDodge) { int dodgeChance = (new Random()).Next(0, 2); if (dodgeChance == 0) { by.Message("{0} dodged your attack!", hitted.Name); return; } } //Take the hit, one in ten chance of a critical hit which does 50 damage instead of 25 int critical = (new Random()).Next(0, 9); if (critical == 0) { if (by.Info.strengthened)//critical by a strengthened enemy instantly kills { hitted.Info.Health = 0; } else { hitted.Info.Health -= 50; } world.Players.Message("{0} landed a critical shot on {1}!", 0, by.Name, hitted.Name); } else { if (by.Info.strengthened) { hitted.Info.Health -= 50; } else { hitted.Info.Health -= 25; } } //Create epic ASCII Health Bar string healthBar = "&f[&a--------&f]"; if (hitted.Info.Health == 75) { healthBar = "&f[&a------&8--&f]"; } else if (hitted.Info.Health == 50) { healthBar = "&f[&e----&8----&f]"; } else if (hitted.Info.Health == 25) { healthBar = "&f[&c--&8------&f]"; } else if (hitted.Info.Health <= 0) { healthBar = "&f[&8--------&f]"; } if (hitted.usesCPE) { hitted.Send(PacketWriter.MakeSpecialMessage((byte)1, healthBar)); } else { hitted.Message("You have " + hitted.Info.Health.ToString() + " health."); } //If the hit player's health is 0 or less, they die if (hitted.Info.Health <= 0) { hitted.KillCTF(world, String.Format("&f{0}&S was shot by &f{1}", hitted.Name, by.Name)); CTF.PowerUp(by); hitted.Info.CTFKills++; if (hitted.Info.hasRedFlag) { world.Players.Message("The red flag has been returned."); hitted.Info.hasRedFlag = false; //Put flag back BlockUpdate blockUpdate = new BlockUpdate(null, world.redFlag, Block.Red); foreach (Player p in world.Players) { p.World.Map.QueueUpdate(blockUpdate); } world.redFlagTaken = false; } if (hitted.Info.hasBlueFlag) { world.Players.Message("The blue flag has been returned."); hitted.Info.hasBlueFlag = false; //Put flag back BlockUpdate blockUpdate = new BlockUpdate(null, world.blueFlag, Block.Blue); foreach (Player p in world.Players) { p.World.Map.QueueUpdate(blockUpdate); } world.blueFlagTaken = false; } //revive dead players with 100% health hitted.Info.Health = 100; if (hitted.usesCPE) { hitted.Send(PacketWriter.MakeSpecialMessage((byte)1, "&f[&a--------&f]")); } else { hitted.Message("You have 100 health."); } } return; } //TDM and FFA if ((hitted.Info.isOnBlueTeam && by.Info.isOnBlueTeam) || (hitted.Info.isOnRedTeam && by.Info.isOnRedTeam)) { by.Message("{0} is on your team!", hitted.ClassyName); } else { //Take the hit, one in ten chance of a critical hit which does 50 damage instead of 25 int critical = (new Random()).Next(0, 9); if (critical == 0) { hitted.Info.Health -= 50; world.Players.Message("{0} landed a critical shot on {1}!", 0, by.Name, hitted.Name); } else { hitted.Info.Health -= 25; } if (hitted.Info.Health < 0) { hitted.Info.Health = 0; } //Create epic ASCII Health Bar string healthBar = "&f[&a--------&f]"; if (hitted.Info.Health == 75) { healthBar = "&f[&a------&8--&f]"; } else if (hitted.Info.Health == 50) { healthBar = "&f[&e----&8----&f]"; } else if (hitted.Info.Health == 25) { healthBar = "&f[&c--&8------&f]"; } else { healthBar = "&f[&8--------&f]"; } hitted.Send(PacketWriter.MakeSpecialMessage((byte)1, healthBar)); if (hitted.usesCPE) { hitted.Send(PacketWriter.MakeSpecialMessage((byte)1, healthBar)); } else { hitted.Message("You have " + hitted.Info.Health.ToString() + " health."); } if (hitted.Info.Health == 0) { hitted.Kill(world, String.Format("{0}&S was shot by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName)); updates.Add(new BlockUpdate(null, pos, Block.Air)); restDistance = 0; //TDM if (TeamDeathMatch.isOn) { if (hitted.Info.isPlayingTD && hitted.Info.isOnBlueTeam && by.Info.isPlayingTD) //if the player is playing TD and on blue team, +1 for Red Team Score { TeamDeathMatch.redScore++; hitted.Info.gameDeaths++; hitted.Info.totalDeathsTDM++; by.Info.gameKills++; by.Info.totalKillsTDM++; } if (hitted.Info.isPlayingTD && hitted.Info.isOnRedTeam && by.Info.isPlayingTD) //if the player is playing TD and on blue team, +1 for Red Team Score { TeamDeathMatch.blueScore++; hitted.Info.gameDeaths++; //counts the individual players deaths hitted.Info.totalDeathsTDM++; //tallies total TDM deaths (never gets reset) by.Info.gameKills++; //counts the individual players amount of kills by.Info.totalKillsTDM++; //tallies total TDM kills } //update scoreboard for all players foreach (Player p in hitted.World.Players) { if (p.usesCPE) { p.Send(PacketWriter.MakeSpecialMessage((byte)2, "&cRed&f: " + TeamDeathMatch.redScore + ",&1 Blue&f: " + TeamDeathMatch.blueScore)); } else { p.Message("The score is now &cRed&f: " + TeamDeathMatch.redScore + ",&1 Blue&f: " + TeamDeathMatch.blueScore); } } } //FFA if (FFA.isOn()) { if (hitted.Info.isPlayingFFA && by.Info.isPlayingFFA) //if the player is playing FFA and the person they hit is also playing { hitted.Info.gameDeathsFFA++; hitted.Info.totalDeathsFFA++; by.Info.gameKillsFFA++; by.Info.totalKillsFFA++; } //find current kill leader Player leader = new Player("");//create a temp pseudo player int kills = 0; foreach (Player p in hitted.World.Players) { if (p.Info.gameKillsFFA > kills) { kills = p.Info.gameKillsFFA; leader = p; } } foreach (Player p in hitted.World.Players) { if (p.usesCPE) { p.Send(PacketWriter.MakeSpecialMessage((byte)2, "&eCurrent Leader&f: " + leader.Name + ", Kills: " + leader.Info.gameKillsFFA)); } } } //revive dead players with 100% health hitted.Info.Health = 100; if (hitted.usesCPE) { hitted.Send(PacketWriter.MakeSpecialMessage((byte)1, "&f[&a--------&f]")); } else { hitted.Message("You have " + hitted.Info.Health.ToString() + "health."); } } } }
private static void CheckGrassQueue(SchedulerTask task) { try { if (checkGrassQueue != null) { if (checkGrassQueue.ThreadState != ThreadState.Stopped) { return; } } checkGrassQueue = new Thread(new ThreadStart(delegate { lock (grassQueue.SyncRoot) { for (int i = 0; i < grassQueue.Count; i++) { GrassUpdate update = (GrassUpdate)grassQueue[i]; if (DateTime.Now > update.Scheduled) { try { if (CanPutGrassOn(update.Block, update.World)) { BlockUpdate grassUpdate = new BlockUpdate(null, update.Block, Block.Grass); update.World.Map.QueueUpdate(grassUpdate); } } catch (Exception ex) { Logger.Log(LogType.Error, "Physics.CheckGrassQueue: " + ex); } finally { grassQueue.Remove(update); } } } } })); checkGrassQueue.Start(); } catch (Exception ex) { Logger.Log(LogType.Error, "Physics.CheckGrassQueue: " + ex); } }
internal static async Task <bool> HandleLiquidPhysicsAsync(BlockUpdate blockUpdate) { if (blockUpdate.Block is null) { return(false); } var block = blockUpdate.Block.Value; var world = blockUpdate.world; var location = blockUpdate.position; int state = block.State; Vector belowPos = location + Vector.Down; // Handle the initial search for closet path downwards. // Just going to do a crappy pathfind for now. We can do // proper pathfinding some other time. if (state == 0) { var validPaths = new List <Vector>(); var paths = new List <Vector>() { { location + Vector.Forwards }, { location + Vector.Backwards }, { location + Vector.Left }, { location + Vector.Right } }; foreach (var pathLoc in paths) { if (await world.GetBlockAsync(pathLoc) is Block pathSide && (Block.Replaceable.Contains(pathSide.Material) || pathSide.IsFluid)) { var pathBelow = await world.GetBlockAsync(pathLoc + Vector.Down); if (pathBelow is Block pBelow && (Block.Replaceable.Contains(pBelow.Material) || pBelow.IsFluid)) { validPaths.Add(pathLoc); } } } // if all directions are valid, or none are, use normal liquid spread physics instead if (validPaths.Count != 4 && validPaths.Count != 0) { var path = validPaths[0]; var newBlock = new Block(block.BaseId, state + 1); await world.SetBlockAsync(path, newBlock); var neighborUpdate = new BlockUpdate(world, path, newBlock); await world.ScheduleBlockUpdateAsync(neighborUpdate); return(false); } } if (state >= 8) // Falling water { // If above me is no longer water, than I should disappear too if (await world.GetBlockAsync(location + Vector.Up) is Block up && !up.IsFluid) { await world.SetBlockAsync(location, Block.Air); await world.ScheduleBlockUpdateAsync(new BlockUpdate(world, belowPos)); return(false); } // Keep falling if (await world.GetBlockAsync(belowPos) is Block below && Block.Replaceable.Contains(below.Material)) { var newBlock = new Block(block.BaseId, state); await world.SetBlockAsync(belowPos, newBlock); await world.ScheduleBlockUpdateAsync(new BlockUpdate(world, belowPos, newBlock)); return(false); } else { // Falling water has hit something solid. Change state to spread. state = 1; await world.SetBlockUntrackedAsync(location, new Block(block.BaseId, state)); } }
public virtual void BlockUpdateEvent(Vector3Int causingPos, Block causingBlock, BlockUpdate type, Vector3Int affectedPos, ChunkManager chunks) { }
public static void PlayerMoving(object poo, Events.PlayerMovingEventArgs e) { if (!started) { return; } //If the player has the red flag (player is no the blue team) if (e.Player.Info.hasRedFlag) { Vector3I oldPos = e.OldPosition.ToBlockCoords(); //get positions as block coords Vector3I newPos = e.NewPosition.ToBlockCoords(); if (oldPos.X != newPos.X || oldPos.Y != newPos.Y || oldPos.Z != newPos.Z) //check if player has moved at least one block { //If the player is near enough to the blue spawn if (e.NewPosition.DistanceSquaredTo(world_.blueCTFSpawn.ToPlayerCoords()) <= 42 * 42) { blueScore++; world_.Players.Message("&f{0} has capped the &cred &fflag. The score is now &cRed&f: {1} and &1Blue&f: {2}.", 0, e.Player.Name, redScore, blueScore); e.Player.Info.hasRedFlag = false; redFlagHolder = null; e.Player.Info.CTFCaptures++; //Replace red block as flag BlockUpdate blockUpdate = new BlockUpdate(null, world_.redFlag, Block.Red); foreach (Player p in world_.Players) { p.World.Map.QueueUpdate(blockUpdate); //set game score if (p.usesCPE) { p.Send(PacketWriter.MakeSpecialMessage((byte)2, "&cRed&f: " + redScore + ",&1 Blue&f: " + blueScore)); p.Send(PacketWriter.MakeSpecialMessage((byte)100, e.Player.Name + " has successfully capped the &cred &fflag")); } } world_.redFlagTaken = false; announced = DateTime.Now; return; } } } //If the player has the blue flag (player must be on red team) else if (e.Player.Info.hasBlueFlag) { Vector3I oldPos = e.OldPosition.ToBlockCoords(); //get positions as block coords Vector3I newPos = e.NewPosition.ToBlockCoords(); if (oldPos.X != newPos.X || oldPos.Y != newPos.Y || oldPos.Z != newPos.Z) //check if player has moved at least one block { //If the player is near enough to the red spawn if (e.NewPosition.DistanceSquaredTo(world_.redCTFSpawn.ToPlayerCoords()) <= 42 * 42) { redScore++; world_.Players.Message("&f{0} has capped the &1blue &fflag. The score is now &cRed&f: {1} and &1Blue&f: {2}.", 0, e.Player.Name, redScore, blueScore); e.Player.Info.hasBlueFlag = false; blueFlagHolder = null; e.Player.Info.CTFCaptures++; //Replace blue block as flag BlockUpdate blockUpdate = new BlockUpdate(null, world_.blueFlag, Block.Blue); foreach (Player p in world_.Players) { p.World.Map.QueueUpdate(blockUpdate); //set game scorecboard if (p.usesCPE) { p.Send(PacketWriter.MakeSpecialMessage((byte)2, "&cRed&f: " + redScore + ",&1 Blue&f: " + blueScore)); p.Send(PacketWriter.MakeSpecialMessage((byte)100, e.Player.Name + " has successfully capped the &cred &fflag")); } } world_.blueFlagTaken = false; announced = DateTime.Now; return; } } } //backstabbing, player with a flag cannot backstab an enemy player else { if (e.Player.Info.stabDisarmed) { return; } Vector3I oldPos = e.OldPosition.ToBlockCoords(); //get positions as block coords Vector3I newPos = e.NewPosition.ToBlockCoords(); if (oldPos.X != newPos.X || oldPos.Y != newPos.Y || oldPos.Z != newPos.Z) //check if player has moved at least one block { //loop through each player, detect if current player is "touching" another player foreach (Player p in world_.Players) { Vector3I pos = p.Position.ToBlockCoords(); //convert to block coords //determine if player is "touching" another player if (e.NewPosition.DistanceSquaredTo(pos.ToPlayerCoords()) <= 42 * 42 && p != e.Player) { if ((p.Info.CTFBlueTeam && e.Player.Info.CTFBlueTeam) || (p.Info.CTFRedTeam && e.Player.Info.CTFRedTeam)) { //friendly fire, do not stab return; } //create just under a 180 degree semicircle in the direction the target player is facing (90 degrees = 64 pos.R bytes) short lowerLimit = (short)(p.Position.R - 63); short upperLimit = (short)(p.Position.R + 63); //if lower limit is -45 degrees for example, convert to 256 + (-32) = 201 bytes (-45 degrees translates to -32 bytes) if (lowerLimit < 0) { lowerLimit = (short)(256 + lowerLimit); } //if upper limit is 450 degrees for example, convert to 320 - 256 = 54 bytes (450 degrees translates to 320 bytes, 360 degrees translates to 256 bytes) if (upperLimit > 256) { upperLimit = (short)(upperLimit - 256); } //Logger.LogToConsole(upperLimit.ToString() + " " + lowerLimit.ToString() + " " + e.Player.Position.R.ToString() + " " + p.Position.R); bool kill = false; //if target's line of sight contains 0 if (p.Position.R > 192 && p.Position.R < 64) { if (Enumerable.Range(lowerLimit, 255).Contains(e.Player.Position.R) || Enumerable.Range(0, upperLimit).Contains(e.Player.Position.R)) { kill = true; } } else { if (Enumerable.Range(lowerLimit, upperLimit).Contains(e.Player.Position.R)) { kill = true; } } if (e.Player.Info.stabAnywhere) { kill = true; } if (kill) { p.KillCTF(world_, String.Format("&f{0}&S was backstabbed by &f{1}", p.Name, e.Player.Name)); e.Player.Info.CTFKills++; PowerUp(e.Player); if (p.Info.hasRedFlag) { world_.Players.Message("The red flag has been returned.", 0); p.Info.hasRedFlag = false; redFlagHolder = null; //Put flag back BlockUpdate blockUpdate = new BlockUpdate(null, world_.redFlag, Block.Red); foreach (Player pl in world_.Players) { pl.World.Map.QueueUpdate(blockUpdate); } world_.redFlagTaken = false; } if (p.Info.hasBlueFlag) { world_.Players.Message("The blue flag has been returned.", 0); p.Info.hasBlueFlag = false; blueFlagHolder = null; //Put flag back BlockUpdate blockUpdate = new BlockUpdate(null, world_.blueFlag, Block.Blue); foreach (Player pl in world_.Players) { pl.World.Map.QueueUpdate(blockUpdate); } world_.blueFlagTaken = false; } } //target player can see player, do not stab } } } } }
//I left this class rather generic incase i used it for anything else /// <summary> /// Updates a specific block for a given time /// </summary> private void updateBlock(Block blockType, Vector3I blockPosition, bool replaceWithAir, double time) { BlockUpdate update = new BlockUpdate(null, blockPosition, blockType); foreach (Player p in World.Players) { p.World.Map.QueueUpdate(update); } if (replaceWithAir) { Scheduler.NewTask(t => updateBlock(Block.Air, blockPosition, false, time)).RunManual(TimeSpan.FromSeconds(time));//place a block, replace it with air once 'time' is up } }