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); } } }
private bool ContextOnInterraction(InteractionContext context) { if (context.Method == InteractionMethod.Left) { if (context.SelectedItem is AxeItem) { if (context.HasBlock && context.Authed()) { var block = World.GetBlock(context.BlockPosition.Value); if (block.Is <TreeDebris>()) { foreach (Vector3i pos in WorldUtils.GetTopBlockPositionAroundPoint <TreeDebrisBlock>(context.Player.User, context.BlockPosition.Value, 1 + SkillsUtil.GetSkillLevel(context.Player.User, typeof(WoodPulpCleanerSkill)))) { if (context.Player.User.Inventory.TryAddItems <WoodPulpItem>(5)) { World.DeleteBlock(pos); } } } } if (context.HasTarget && context.Target is TreeEntity) { TreeEntity tree = context.Target as TreeEntity; if (context.Parameters != null && context.Parameters.ContainsKey("stump")) { if (SkillsUtil.HasSkillLevel(context.Player.User, typeof(StumpCleanerSkill), 1)) { tree.TryApplyDamage(context.Player, 500, context); } } if (context.Parameters != null && context.Parameters.ContainsKey("slice")) { if (SkillsUtil.HasSkillLevel(context.Player.User, typeof(ExpertLumbererSkill), 1)) { TreeBranch[] branches = typeof(Tree).GetField("branches", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tree) as TreeBranch[]; if (!branches.Where(branch => branch != null).Select(branch => branch.Health).Where(health => health != 0).Any()) { for (int i = 1; i < 20; i++) { typeof(TreeEntity).GetMethod("TrySliceTrunk", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(tree, new object[] { context.Player, 0.05f * (float)i }); } } } } } } } return(false); }
/// <summary> /// Get a list of position of top Block that match the type T. Usefull when wanted to destroy plants or tree debris /// </summary> public static List <Vector3i> GetTopBlockPositionAroundPoint <T>(User user, Vector3i position, int range) where T : Block { try { List <Vector3i> blockLists = new List <Vector3i>(); for (int i = -range; i < range; i++) { for (int j = -range; j < range; j++) { if (i == 0 && j == 0) { continue; } Vector3i positionAbove = World.GetTopPos(new Vector2i(position.x + i, position.z + j)) + Vector3i.Up; Block blockAbove = World.GetBlockProbablyTop(positionAbove); if (blockAbove is T) { if (positionAbove != position && Vector3i.Distance(positionAbove, position) < range) { InteractionInfo info = new InteractionInfo(); info.Method = InteractionMethod.Right; info.BlockPosition = positionAbove; InteractionContext context = info.MakeContext(user.Player); if (context.Authed()) { blockLists.Add(positionAbove); } } } } } return(blockLists); } catch (Exception) { return(null); } }