示例#1
0
 public override InteractResult OnActLeft(InteractionContext context)
 {
     if (context.HasBlock && context.Block.Is <Minable>())
     {
         Result result = this.PlayerDeleteBlock(context.BlockPosition.Value, context.Player, false, 1);
         if (result.Success)
         {
             if (RubbleObject.TrySpawnFromBlock(context.Block.GetType(), context.BlockPosition.Value))
             {
                 RubbleUtils.BreakBigRubble(context.BlockPosition.Value, 20 * SkillsUtil.GetSkillLevel(context.Player.User, typeof(StrongMiningSkill)));
                 context.Player.User.UserUI.OnCreateRubble.Invoke();
             }
         }
         return((InteractResult)result);
     }
     else if (context.Target is RubbleObject)
     {
         var rubble = (RubbleObject)context.Target;
         if (rubble.IsBreakable)
         {
             rubble.Breakup();
             BurnCalories(context.Player);
             return(InteractResult.Success);
         }
         else
         {
             return(InteractResult.NoOp);
         }
     }
     else
     {
         return(InteractResult.NoOp);
     }
 }
示例#2
0
        //Blasting
        public void BlockBreaker(Vector3i Pos, Vector3 Dir) // consider making this a bool to facilitate feedback?
        {
            //get collar position and facing direction
            Vector3i rung   = Pos;
            Vector3i facing = StyleSet(this.style, Dir);



            //determine blast radius and depth
            if (this.Explosive.Fuel < 5)
            {
                //ChatManager.ServerMessageToAll("Column Mode", false);
                //step to next block until reach bottom - may want to invert this so that it blasts from the bottom up
                for (int a = 0; a < this.blastingDepth; a = a + 1)
                {
                    rung = rung + facing;
                    //break if mineable and replace with rubble
                    Block block = World.GetBlock(rung);
                    if (block.Is <Minable>())
                    {
                        World.DeleteBlock(rung);
                        RubbleObject.TrySpawnFromBlock(block.GetType(), rung);
                    }
                }
            }
            else if (this.Explosive.Fuel > 5)
            {
                //ChatManager.ServerMessageToAll("cylinder Mode", false);
                DirectionAxis dir = LookupDirectionAxis(facing);


                for (int a = 0; a < this.blastingDepth; a = a + 1)
                {
                    rung = rung + facing;
                    Vector3i[] ring = DirectionExtensions.Get8Edges(dir);
                    //break if mineable and replace with rubble
                    Block block = World.GetBlock(rung);
                    if (block.Is <Minable>())
                    {
                        World.DeleteBlock(rung);
                        RubbleObject.TrySpawnFromBlock(block.GetType(), rung);
                    }
                    foreach (Vector3i neighbour in ring)
                    {
                        // ChatManager.ServerMessageToAll("neighbour mode", false);
                        Vector3i tar = rung + neighbour;
                        block = World.GetBlock(tar);
                        if (block.Is <Minable>())
                        {
                            World.DeleteBlock(tar);
                            RubbleObject.TrySpawnFromBlock(block.GetType(), tar);
                        }
                    }
                }
            }
            else
            {
                return;
            }
        }
示例#3
0
    private InteractResult Blast(InteractionContext context, Vector3i blockPosition)
    {
        //todo: make it use the hammer's calories and durability if it's selected
        Vector3i minTop = blockPosition + new Vector3i(-2, -1, -2);
        Vector3i maxTop = blockPosition + new Vector3i(2, -1, 2);

        Vector3i minBottom = minTop + new Vector3i(0, -5, 0);
        Vector3i maxBottom = maxTop + new Vector3i(0, -5, 0);

        var pack = new GameActionPack();

        var range = new WorldRange(minBottom, maxTop);

        foreach (var blockPos in range.XYZIterInc())
        {
            var blockType = World.GetBlock(blockPos).GetType();
            if (RubbleObject.BecomesRubble(blockType))
            {
                AtomicActions.DeleteBlockNow(this.CreateMultiblockContext(context));
                RubbleObject.TrySpawnFromBlock(context.Player, blockType, blockPos, 4);
            }
        }

        return(InteractResult.Success);
    }
示例#4
0
        public static void Explosion(Player player, Vector3i centerPosition, int radius, int percentBlockDrop)
        {
            Random rng = new Random();
            List <DynamiteObject> tnts = new List <DynamiteObject>();

            foreach (WorldObject obj in WorldObjectManager.All)
            {
                if (obj is DynamiteObject)
                {
                    tnts.Add(obj as DynamiteObject);
                }
            }
            foreach (Vector3i pos in GetSphereBlock(centerPosition, radius))
            {
                Block           block = World.GetBlock(pos);
                InteractionInfo info  = new InteractionInfo();
                info.Method        = InteractionMethod.None;
                info.BlockPosition = pos;
                InteractionContext context = info.MakeContext(player);
                if (context.Authed())
                {
                    foreach (DynamiteObject tnt in tnts)
                    {
                        if (centerPosition != pos && tnt.Position3i == pos)
                        {
                            tnt.Ignite(1, player);
                        }
                    }
                    if (block is ImpenetrableStoneBlock || block is EmptyBlock)
                    {
                        continue;
                    }
                    if (block is TreeBlock)
                    {
                        foreach (TreeEntity tree in NetObjectManager.GetObjectsOfType <TreeEntity>())
                        {
                            if (tree.Position.Ceiling == pos)
                            {
                                tree.Destroy();
                            }
                        }
                    }
                    if (block is WorldObjectBlock)
                    {
                        (block as WorldObjectBlock).WorldObjectHandle.Object.Destroy();
                    }
                    if (rng.Next(100) < percentBlockDrop)
                    {
                        if (block.Is <Minable>())
                        {
                            RubbleObject.TrySpawnFromBlock(block.GetType(), pos);
                        }
                    }
                    World.DeleteBlock(pos);
                }
            }
        }
示例#5
0
        public override InteractResult OnActLeft(InteractionContext context)
        {
            if (context.HasBlock && context.Block.Is <Minable>())
            {
                var user = context.Player.User;
                var item = context.Block is IRepresentsItem?Item.Get((IRepresentsItem)context.Block) : null;

                var totalDamageToTarget = user.BlockHitCache.MemorizeHit(context.Block.GetType(), context.BlockPosition.Value, this.Tier.GetCurrentValue(context.Player.User) * this.Damage);
                if (context.Block.Get <Minable>().Hardness <= totalDamageToTarget)
                {
                    var result = AtomicActions.DeleteBlockNow(this.CreateMultiblockContext(context), spawnRubble: false);

                    //Spawn the rubble if needed
                    if (result.Success)
                    {
                        var forced = context.Player.User.Talentset.HasTalent(typeof(MiningLuckyBreakTalent)) ? 4 : -1;
                        if (RubbleObject.TrySpawnFromBlock(context.Player, context.Block.GetType(), context.BlockPosition.Value, forced))
                        {
                            var addition = item != null ? " " + item.UILink() : string.Empty;
                            this.AddExperience(user, 1f, new LocString(Localizer.Format("mining") + addition));
                            user.UserUI.OnCreateRubble.Invoke(item.DisplayName.NotTranslated);
                            user.BlockHitCache.ForgetHit(context.BlockPosition.Value);
                        }
                    }

                    return((InteractResult)result);
                }
                else
                {
                    return((InteractResult)AtomicActions.UseToolNow(this.CreateMultiblockContext(context)));
                }
            }
            else if (context.Target is RubbleObject)
            {
                var rubble = (RubbleObject)context.Target;
                if (rubble.IsBreakable)
                {
                    using var pack = new GameActionPack();
                    pack.UseTool(this.CreateMultiblockContext(context));
                    pack.AddPostEffect(() => rubble.Breakup(context.Player));
                    return((InteractResult)pack.TryPerform(false));
                }

                return(InteractResult.NoOp);
            }

            if (context.Target is WorldObject)
            {
                return(this.BasicToolOnWorldObjectCheck(context));
            }

            return(base.OnActLeft(context));
        }
        public override InteractResult OnActLeft(InteractionContext context)
        {
            if (context.HasBlock && context.Block.Is <Minable>())
            {
                Result result;
                if (context.Block is IRepresentsItem)
                {
                    Item          item      = Item.Get((IRepresentsItem)context.Block);
                    IAtomicAction lawAction = PlayerActions.PickUp.CreateAtomicAction(context.Player, item, context.BlockPosition.Value);
                    result = this.PlayerDeleteBlock(context.BlockPosition.Value, context.Player, false, 1, null, lawAction);
                }
                else
                {
                    result = this.PlayerDeleteBlock(context.BlockPosition.Value, context.Player, false, 1);
                }

                if (result.Success)
                {
                    if (RubbleObject.TrySpawnFromBlock(context.Block.GetType(), context.BlockPosition.Value))
                    {
                        context.Player.User.UserUI.OnCreateRubble.Invoke();
                    }
                }

                return((InteractResult)result);
            }
            else if (context.Target is RubbleObject)
            {
                var rubble = (RubbleObject)context.Target;
                if (rubble.IsBreakable)
                {
                    rubble.Breakup();
                    BurnCalories(context.Player);
                    return(InteractResult.Success);
                }
                else
                {
                    return(InteractResult.NoOp);
                }
            }
            else
            {
                return(InteractResult.NoOp);
            }
        }
示例#7
0
        public static void Postfix(ref IEcoObject ecoObject)
        {
            if (!(ecoObject is RubbleObject))
            {
                return;
            }

            RubbleObject rubble = (RubbleObject)ecoObject;

            RubbleSpawnEvent sre      = new RubbleSpawnEvent(ref rubble);
            IEvent           sreEvent = sre;

            EventManager.CallEvent(ref sreEvent);

            if (sre.IsCancelled())
            {
                typeof(RubbleObject).GetMethod("Destroy", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(rubble, new object[] { });
            }
        }
示例#8
0
        public override InteractResult OnActLeft(InteractionContext context)
        {
            if (context.HasBlock && context.Block.Is <Minable>())
            {
                var user = context.Player.User;
                var item = context.Block is IRepresentsItem?Item.Get((IRepresentsItem)context.Block) : null;

                var totalDamageToTarget = user.BlockHitCache.MemorizeHit(context.Block.GetType(), context.BlockPosition.Value, this.Tier.GetCurrentValue(context.Player.User));
                if (context.Block.Get <Minable>().Hardness <= totalDamageToTarget)
                {
                    Result result;
                    if (item != null)
                    {
                        IAtomicAction lawAction = PlayerActions.PickUp.CreateAtomicAction(context.Player.User, item, context.BlockPosition.Value);
                        result = this.PlayerDeleteBlock(context.BlockPosition.Value, context.Player, false, 1, null, lawAction);
                    }
                    else
                    {
                        result = this.PlayerDeleteBlock(context.BlockPosition.Value, context.Player, false, 1);
                    }

                    if (result.Success)
                    {
                        var forced = context.Player.User.Talentset.HasTalent(typeof(MiningLuckyBreakTalent)) ? 4 : -1;
                        if (RubbleObject.TrySpawnFromBlock(context.Player, context.Block.GetType(), context.BlockPosition.Value, forced))
                        {
                            var addition = item != null ? " " + (item.UILink()) : string.Empty;
                            this.AddExperience(user, 1f, new LocString(Localizer.Format("mining") + addition));
                            user.UserUI.OnCreateRubble.Invoke(item.DisplayName.NotTranslated);
                            user.BlockHitCache.ForgetHit(context.BlockPosition.Value);
                        }
                    }

                    return((InteractResult)result);
                }
                else
                {
                    this.BurnCalories(context.Player);
                }
            }
            else if (context.Target is RubbleObject)
            {
                var rubble = (RubbleObject)context.Target;
                if (rubble.IsBreakable)
                {
                    rubble.Breakup(context.Player);
                    this.BurnCalories(context.Player);
                    return(InteractResult.Success);
                }
                else
                {
                    return(InteractResult.NoOp);
                }
            }

            if (context.Target is WorldObject)
            {
                return(this.BasicToolOnWorldObjectCheck(context));
            }

            return(InteractResult.NoOp);
        }
        private void ApplyTalent(User user, RubbleObject target, List <IAtomicAction> actions)
        {
            var representsItem = target as IRepresentsItem;

            if (representsItem == null)
            {
                return;
            }

            var itemType = representsItem.RepresentedItemType;
            // max stack size minus currently picking item
            var numToTake = Item.GetMaxStackSize(itemType) - 1;

            if (numToTake <= 0)
            {
                return;
            }

            var carrying = user.Carrying;

            if (!carrying.Empty)
            {
                if (carrying.Item.Type != itemType || carrying.Quantity >= numToTake)
                {
                    return;
                }
                // adjust to currently carrying item count
                numToTake -= carrying.Quantity;
            }

            var inventoryChangeSet = (InventoryChangeSet)actions.FirstOrDefault(a => a is InventoryChangeSet);

            DebugUtils.Assert(inventoryChangeSet != null, "No inventory change set for PickUp Rubble event");
            if (inventoryChangeSet == null)
            {
                return;
            }

            var item     = Item.Get(itemType);
            var numTaken = 0;

            foreach (var rubble in NetObjectManager.GetObjectsWithin(target.Position, this.PickUpRange).OfType <RubbleObject>())
            {
                if (rubble == target || rubble.IsBreakable)
                {
                    continue;
                }
                var rubbleRepresentsItem = rubble as IRepresentsItem;
                if (rubbleRepresentsItem == null || rubbleRepresentsItem.RepresentedItemType != itemType)
                {
                    continue;
                }
                actions.Add(PlayerActions.PickUp.CreateAtomicAction(user, item, rubble.Position.Round));
                actions.Add(new DestroyRubbleAction(rubble));
                if (++numTaken == numToTake)
                {
                    break;
                }
            }
            inventoryChangeSet.AddItems(itemType, numTaken);
        }
示例#10
0
        private void ApplyTalent(User user, RubbleObject target, GameActionPack pack)
        {
            if (!(target is IRepresentsItem representsItem))
            {
                return;
            }

            var itemType = representsItem.RepresentedItemType;
            // max stack size minus currently picking item
            var numToTake = Item.GetMaxStackSize(itemType) - 1;

            if (numToTake <= 0)
            {
                return;
            }

            var carrying = user.Carrying;

            if (!carrying.Empty())
            {
                // ReSharper disable once PossibleNullReferenceException because Empty checked
                if (carrying.Item.Type != itemType || carrying.Quantity >= numToTake)
                {
                    return;
                }
                // adjust to currently carrying item count
                numToTake -= carrying.Quantity;
            }

            //Get the changeset already in the action pack
            var numTaken      = 0;
            var player        = user.Player;
            var userInventory = user.Inventory;
            var checkedPlots  = new Dictionary <Vector2i, bool>(); // A dictionary to cache auth checks for objects within the same plots.

            foreach (var rubble in NetObjectManager.GetObjectsWithin(target.Position, this.PickUpRange).OfType <RubbleObject>())
            {
                var plotPosition  = rubble.Position.XZi.ToPlotPosition();
                var positionIsNew = !checkedPlots.ContainsKey(plotPosition);

                if (!positionIsNew && !checkedPlots[plotPosition])
                {
                    continue;                                                // If we already failed to pickup something on this plot position, there's no need to proceed (we'll fail auth again).
                }
                if (rubble == target || rubble.IsBreakable)
                {
                    continue;
                }
                if (!(rubble is IRepresentsItem rubbleRepresentsItem) || rubbleRepresentsItem.RepresentedItemType != itemType)
                {
                    continue;
                }

                var addedToPack = pack.PickupRubbles(player, userInventory, rubble.SingleItemAsEnumerable(), itemType, checkAuthFirst: positionIsNew, notificate: false); // Check auth before adding to the pack if the position is new.
                if (addedToPack && ++numTaken == numToTake)
                {
                    break;
                }

                if (positionIsNew)
                {
                    checkedPlots.Add(plotPosition, addedToPack);                // Add auth check for this plot to the dictionary.
                }
            }
        }
示例#11
0
 public RubbleSpawnEvent(ref RubbleObject obj) : base()
 {
     RubbleObject = obj;
 }