Beispiel #1
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);
    }
Beispiel #2
0
        public override InteractResult OnActLeft(InteractionContext context)
        {
            // Try delete tree debris with reduced XP multiplier.
            if (context.HasBlock && context.Block.Get <TreeDebris>() is TreeDebris treeDebris)
            {
                // Create game action pack, compose and try to perform.
                using (var pack = new GameActionPack())
                {
                    // Add debris items to inventory.
                    foreach (var x in ((TreeSpecies)EcoSim.GetSpecies(treeDebris.Species)).DebrisResources)
                    {
                        pack.AddToInventory(context.Player?.User.Inventory, Item.Get(x.Key), x.Value.RandInt, context.Player?.User);
                    }

                    // Create multiblock context with reduced XP multiplier for cleaning debris.
                    var multiblockContext = this.CreateMultiblockContext(context);
                    multiblockContext.ActionDescription    = Localizer.DoStr("clean up tree debris");
                    multiblockContext.ExperiencePerAction *= 0.1f;

                    // Add block deletion to the pack and try to perform it.
                    pack.DeleteBlock(multiblockContext);
                    return((InteractResult)pack.TryPerform());
                }
            }

            // Try interact with a world object.
            if (context.Target is WorldObject)
            {
                return(this.BasicToolOnWorldObjectCheck(context));
            }

            // Fallback (try to damage target).
            return(base.OnActLeft(context));
        }
Beispiel #3
0
    private InteractResult PlaceBlockFill(InteractionContext context, Vector3i blockPosition)
    {
        int rotation = 0;
        BlueprintInstance blueprintInstance = null;

        if (context.Parameters != null)
        {
            BSONValue val;
            if (context.Parameters.TryGetValue("formRotation", out val))
            {
                rotation = val.Int32Value;
            }

            if (context.Parameters.TryGetValue("blueprint", out val))
            {
                blueprintInstance = new BlueprintInstance(new Blueprint(), Vector3i.Zero);
                blueprintInstance.FromBson(val.ObjectValue);
            }
        }

        var creatingItem = context.CarriedItem as BlockItem;

        if (creatingItem == null)
        {
            return(InteractResult.NoOp);
        }

        // TODO SJS: Verify all the blocks are created from the same type

        var form      = context.Player?.User.Inventory.Carried.SelectedForm?.FormType.Name;
        var blockType = BlockFormManager.GetBlockTypeToCreate(context.Player, context.SelectedItem, context.CarriedItem, form, rotation);

        // Let's give up! (Let the carried type handle it)
        if (form == null || blockType == null || blueprintInstance == null)
        {
            return(InteractResult.NoOp);
        }

        // Create game action pack, fill it and try to perform.
        using (var pack = new GameActionPack())
        {
            // Fill the pack.
            foreach (var blockPos in blueprintInstance)
            {
                pack.PlaceBlock(
                    context:              this.CreateMultiblockContext(context.Player, blockPos.Offset.SingleItemAsEnumerable()),
                    blockType:            BlockManager.FromId(blockPos.BlockId),
                    createBlockAction:    true,
                    removeFromInv:        context.Player?.User.Inventory,
                    itemToRemove:         creatingItem.GetType());
            }

            // Try to perform created actions.
            return((InteractResult)pack.TryPerform(false));
        }
    }
Beispiel #4
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));
        }
Beispiel #5
0
 void ApplyAction(User user, INetObject target, INetObject tool, GameActionPack pack)
 {
     // only apply talent when object picked up by hands, not with tool like excavator or skid steer
     if (tool != null)
     {
         return;
     }
     if (target is RubbleObject rubble)
     {
         this.ApplyTalent(user, rubble, pack);
     }
 }
Beispiel #6
0
        public override void OnAreaValid(GameActionPack pack, Player player, Vector3i position, Quaternion rotation)
        {
            var deed = PropertyManager.FindConnectedDeedOrCreate(player.User, position.XZ);

            foreach (var plotPosition in PlotUtil.GetAllPropertyPos(position, virtualOccupancy))
            {
                if (!this.IsPlotAuthorized(plotPosition, player.User, out var canClaimPlot))
                {
                    return;
                }

                if (canClaimPlot)
                {
                    pack.ClaimProperty(deed, player.User, player.User.Inventory, plotPosition, requirePapers: false);
                }
            }

            if (!pack.EarlyResult)
            {
                return;
            }

            pack.AddPostEffect(() =>
            {
                var camp      = WorldObjectManager.ForceAdd(typeof(CampsiteObject), player.User, position, rotation, false);
                var stockpile = WorldObjectManager.ForceAdd(typeof(TinyStockpileObject), player.User, position + rotation.RotateVector(Vector3i.Right * 3), rotation, false);
                player.User.OnWorldObjectPlaced.Invoke(camp);
                player.User.Markers.Add(camp.Position3i + Vector3i.Up, camp.UILinkContent(), false);
                var storage   = camp.GetComponent <PublicStorageComponent>();
                var changeSet = new InventoryChangeSet(storage.Inventory);
                PlayerDefaults.GetDefaultCampsiteInventory().ForEach(x => changeSet.AddItems(x.Key, x.Value, storage.Inventory));

                //If we're running a settlement system, create the homestead item now and fill it with homestead-specific claim papers.
                if (SettlementPluginConfig.Obj.SettlementSystemEnabled)
                {
                    var marker     = WorldObjectManager.ForceAdd(typeof(HomesteadMarkerObject), player.User, position + rotation.RotateVector(new Vector3i(3, 0, 3)), rotation, false);
                    var markerComp = marker.GetComponent <SettlementMarkerComponent>();
                    markerComp.Settlement.Citizenship.AddSpawnedClaims(this.bonusPapers);
                    markerComp.UpdateSpawnedClaims();
                }
                else
                {
                    //For the old system, add the papers to the tent.
                    if (this.bonusPapers > 0)
                    {
                        changeSet.AddItems(typeof(PropertyClaimItem), this.bonusPapers);
                    }
                }
                changeSet.Apply();
            });
        }
        // TODO: create atomic actions covering the case and utilize them.
        public override void BlockInteraction(Vector3i pos, Quaternion rot, VehicleComponent vehicle, Inventory inv = null)
        {
            if (inv == null)
            {
                return;
            }

            if (!this.enabled)
            {
                return;
            }

            foreach (var offset in area)
            {
                var stack = inv.GroupedStacks.Where(x => x.Item is SeedItem).FirstOrDefault();
                if (stack == null)
                {
                    return;
                }
                SeedItem seed       = stack.Item as SeedItem;
                var      targetPos  = (rot.RotateVector(offset) + pos).XYZi;
                Result   authResult = ServiceHolder <IAuthManager> .Obj.IsAuthorized(targetPos, vehicle.Driver.User, AccessType.ConsumerAccess, null);

                if (authResult.Success)
                {
                    if (World.GetBlock(targetPos + Vector3i.Down).Is <Tilled>() && World.GetBlock(targetPos).Is <Empty>())
                    {
                        var pack = new GameActionPack();
                        pack.AddGameAction(new PlantSeeds()
                        {
                            Species        = seed.Species.GetType(),
                            ActionLocation = targetPos,
                            Citizen        = vehicle.Driver.User,
                            ToolUsed       = this
                        });

                        var changes = new InventoryChangeSet(inv, vehicle.Driver.User);
                        changes.RemoveItem(seed.Type);
                        pack.AddChangeSet(changes);

                        if (pack.TryPerform())
                        {
                            var plant = EcoSim.PlantSim.SpawnPlant(seed.Species, targetPos);
                            plant.Tended = true;
                        }
                    }
                }
            }
        }
Beispiel #8
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.
                }
            }
        }