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); } }
//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; } }
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); }
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); } } }
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); } }
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[] { }); } }
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); }
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. } } }
public RubbleSpawnEvent(ref RubbleObject obj) : base() { RubbleObject = obj; }