Exemple #1
0
 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);
     }
 }
Exemple #2
0
        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
            }
        }
Exemple #4
0
    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);
        }
    }
Exemple #5
0
        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;
            }
        }
Exemple #6
0
 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);
     }
 }
Exemple #7
0
 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);
            }
        }
Exemple #9
0
        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);
            }
        }
Exemple #10
0
        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;
            }
        }
Exemple #11
0
    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);
    }
Exemple #12
0
        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;
            }
        }
Exemple #13
0
 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.");
                    }
                }
            }
        }
Exemple #16
0
        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);
            }
        }
Exemple #17
0
    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));
            }
        }
Exemple #18
0
 public virtual void BlockUpdateEvent(Vector3Int causingPos, Block causingBlock, BlockUpdate type, Vector3Int affectedPos, ChunkManager chunks)
 {
 }
Exemple #19
0
        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
                        }
                    }
                }
            }
        }
Exemple #20
0
        //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
            }
        }