예제 #1
0
        protected override void OnActivated(Vec3F32 dir, BlockID block)
        {
            AmmunitionData args = MakeArgs(dir, block);
            SchedulerTask  task = new SchedulerTask(GunCallback, args, TimeSpan.Zero, true);

            p.CriticalTasks.Add(task);
        }
예제 #2
0
        bool TickGun(AmmunitionData args)
        {
            while (true)
            {
                Vec3U16 pos = args.PosAt(args.iterations);
                args.iterations++;

                BlockID cur = p.level.GetBlock(pos.X, pos.Y, pos.Z);
                if (cur == Block.Invalid)
                {
                    return(false);
                }
                if (cur != Block.Air && !args.all.Contains(pos) && OnHitBlock(args, pos, cur))
                {
                    return(false);
                }

                p.level.BroadcastChange(pos.X, pos.Y, pos.Z, args.block);
                args.visible.Add(pos);
                args.all.Add(pos);

                Player pl = PlayerAt(p, pos, true);
                if (pl != null)
                {
                    OnHitPlayer(args, pl); return(false);
                }
                if (TickMove(args))
                {
                    return(true);
                }
            }
        }
예제 #3
0
 protected override bool OnHitBlock(AmmunitionData args, Vec3U16 pos, BlockID block)
 {
     if (p.level.physics >= 3)
     {
         p.level.MakeExplosion(pos.X, pos.Y, pos.Z, 1);
     }
     return(true);
 }
예제 #4
0
 protected virtual bool TickMove(AmmunitionData args)
 {
     if (args.iterations > 12)
     {
         Vec3U16 pos = args.visible[0];
         args.visible.RemoveAt(0);
         p.level.BroadcastRevert(pos.X, pos.Y, pos.Z);
     }
     return(true);
 }
예제 #5
0
        protected AmmunitionData MakeArgs(Vec3F32 dir, BlockID block)
        {
            AmmunitionData args = new AmmunitionData();

            args.block = block;

            args.start      = (Vec3U16)p.Pos.BlockCoords;
            args.dir        = dir;
            args.iterations = 4;
            return(args);
        }
예제 #6
0
 protected override void OnHitPlayer(AmmunitionData args, Player pl)
 {
     if (pl.level.physics >= 3)
     {
         pl.HandleDeath(Block.Cobblestone, "@p %Swas blown up by " + p.ColoredName, true);
     }
     else
     {
         base.OnHitPlayer(args, pl);
     }
 }
예제 #7
0
        void DoTeleport(AmmunitionData args)
        {
            int i = args.visible.Count - 3;

            if (i >= 0 && i < args.visible.Count)
            {
                Vec3U16  coords = args.visible[i];
                Position pos    = new Position(coords.X * 32, coords.Y * 32 + 32, coords.Z * 32);
                p.SendPos(Entities.SelfID, pos, p.Rot);
            }
        }
예제 #8
0
        protected virtual bool TickRevert(SchedulerTask task)
        {
            AmmunitionData args = (AmmunitionData)task.State;

            if (args.visible.Count > 0)
            {
                Vec3U16 pos = args.visible[0];
                args.visible.RemoveAt(0);
                p.level.BroadcastRevert(pos.X, pos.Y, pos.Z);
            }
            return(args.visible.Count > 0);
        }
예제 #9
0
        protected void GunCallback(SchedulerTask task)
        {
            AmmunitionData args = (AmmunitionData)task.State;

            if (args.moving)
            {
                args.moving = TickGun(args);
            }
            else
            {
                task.Repeating = TickRevert(task);
            }
        }
예제 #10
0
        protected override bool OnHitBlock(AmmunitionData args, Vec3U16 pos, BlockID block)
        {
            if (p.level.physics < 2)
            {
                return(true);
            }

            if (!p.level.Props[block].LavaKills)
            {
                return(true);
            }
            // Penetrative gun goes through blocks lava can go through
            p.level.Blockchange(pos.X, pos.Y, pos.Z, Block.Air);
            return(false);
        }
예제 #11
0
        protected override bool TickRevert(SchedulerTask task)
        {
            AmmunitionData args = (AmmunitionData)task.State;

            if (args.all.Count > 0)
            {
                // laser persists for a short while
                task.Delay = TimeSpan.FromMilliseconds(400);
                args.all.Clear();
            }
            else
            {
                foreach (Vec3U16 pos in args.visible)
                {
                    p.level.BroadcastRevert(pos.X, pos.Y, pos.Z);
                }
                args.visible.Clear();
            }
            return(args.visible.Count > 0);
        }
예제 #12
0
 /// <summary> Called when a bullet has collided with a player. </summary>
 protected virtual void OnHitPlayer(AmmunitionData args, Player pl)
 {
     pl.HandleDeath(Block.Cobblestone, "@p %Swas shot by " + p.ColoredName);
 }
예제 #13
0
 /// <summary> Called when a bullet has collided with a block. </summary>
 /// <returns> true if this block stops the bullet, false if it should continue moving. </returns>
 protected virtual bool OnHitBlock(AmmunitionData args, Vec3U16 pos, BlockID block)
 {
     return(true);
 }
예제 #14
0
 protected override bool OnHitBlock(AmmunitionData args, Vec3U16 pos, BlockID block)
 {
     args.DoTeleport(p);
     return(true);
 }
예제 #15
0
 protected override void OnHitPlayer(AmmunitionData args, Player pl)
 {
     args.DoTeleport(p);
 }
예제 #16
0
 protected override bool TickMove(AmmunitionData args)
 {
     // laser immediately strikes target
     return(false);
 }