Frepo Posted February 7, 2023 Report Share Posted February 7, 2023 (edited) I'm trying to lower the drop rate from explosions (from using the oreblastingbomb). Sadly I can't add a new value to EnumBlastType. So I though I'd just override the OnBlockExploded method and hardcode in a lower value there. Problem is that my behavior seems to not get called at all. I can't see why. ModCore Spoiler public override void Start(ICoreAPI api) { base.Start(api); ft_api = api; // Register new block behaviors api.RegisterBlockBehaviorClass("ExplosionDropNerf", typeof(ExplosionDropNerf)); } ExplosionDropNerf behavior class Spoiler public class ExplosionDropNerf : BlockBehavior { // empty constructor public ExplosionDropNerf(Block block) : base(block) { } // the override method public override void OnBlockExploded(IWorldAccessor world, BlockPos pos, BlockPos explosionCenter, EnumBlastType blastType, ref EnumHandling handling) { //if (world.Api.Side.IsClient()) {return;} //BlockOre oreBlock = world.BlockAccessor.GetBlock(pos) as BlockOre; if (world.BlockAccessor.GetBlock(pos) is BlockOre oreBlock) { world.BulkBlockAccessor.SetBlock(0, pos); double dropChance; if (blastType == EnumBlastType.OreBlast) // type 0 (used by the ore blasting bomb) { dropChance = 0.25; // the nerf handling = EnumHandling.PreventSubsequent; } else { handling = EnumHandling.PassThrough; return; } if (world.Rand.NextDouble() < dropChance) { ItemStack[] drops = oreBlock.GetDrops(world, pos, null, 1f); if (drops == null) { return; } for (int i = 0; i < drops.Length; i++) { if (oreBlock.SplitDropStacks) { for (int j = 0; j < drops[i].StackSize; j++) { ItemStack stack = drops[i].Clone(); if (!stack.Collectible.Code.Path.Contains("crystal")) { stack.StackSize = 1; world.SpawnItemEntity(stack, new Vec3d((double)pos.X + 0.5, (double)pos.Y + 0.5, (double)pos.Z + 0.5), null); } } } } } if (oreBlock.EntityClass != null) { BlockEntity entity = world.BlockAccessor.GetBlockEntity(pos); if (entity != null) { entity.OnBlockBroken(null); } } } } } Vanilla OnBlockExploded (BlockOre.cs) Spoiler public override void OnBlockExploded(IWorldAccessor world, BlockPos pos, BlockPos explosionCenter, EnumBlastType blastType) { EnumHandling handled = EnumHandling.PassThrough; BlockBehavior[] blockBehaviors = this.BlockBehaviors; for (int k = 0; k < blockBehaviors.Length; k++) { blockBehaviors[k].OnBlockExploded(world, pos, explosionCenter, blastType, ref handled); if (handled == EnumHandling.PreventSubsequent) { break; } } if (handled == EnumHandling.PreventDefault) { return; } world.BulkBlockAccessor.SetBlock(0, pos); double dropChancce = this.ExplosionDropChance(world, pos, blastType); if (world.Rand.NextDouble() < dropChancce) { ItemStack[] drops = this.GetDrops(world, pos, null, 1f); if (drops == null) { return; } for (int i = 0; i < drops.Length; i++) { if (this.SplitDropStacks) { for (int j = 0; j < drops[i].StackSize; j++) { ItemStack stack = drops[i].Clone(); if (!stack.Collectible.Code.Path.Contains("crystal")) { stack.StackSize = 1; world.SpawnItemEntity(stack, new Vec3d((double)pos.X + 0.5, (double)pos.Y + 0.5, (double)pos.Z + 0.5), null); } } } } } if (this.EntityClass != null) { BlockEntity entity = world.BlockAccessor.GetBlockEntity(pos); if (entity != null) { entity.OnBlockBroken(null); } } } Edited March 4, 2023 by Frepo Link to comment Share on other sites More sharing options...
Frepo Posted February 7, 2023 Author Report Share Posted February 7, 2023 (edited) I just noticed that OnBlockExploded in BlockBehavior takes in an ref EnumHandling, but OnBlockExploded in the BlockOre class doesn't. The behavior is pretty much empty. Spoiler public virtual void OnBlockExploded(IWorldAccessor world, BlockPos pos, BlockPos explosionCenter, EnumBlastType blastType, ref EnumHandling handling) { handling = EnumHandling.PassThrough; } This must be the method I'm actually overriding. So I guess I can only add additional stuff, not really override the OnBlockExploded in BlockOre, that code is gonna run no matter what (thinking out loud here) Am I supposed to register my own myBlockOreBlastingBomb and disable the vanilla? Replacing the item entierly? Well, I guess it's the BlockOre I should replace really, but I don't think that would be a good thing to do (worldGen and all...). Or can the method (in BlockOre) be overridden in some other way? I just want to find the "cleanest" way to go about all this. Edited February 7, 2023 by Frepo Link to comment Share on other sites More sharing options...
Spear and Fang Posted February 7, 2023 Report Share Posted February 7, 2023 (edited) A Harmony prefix patch (or similar) to override BlockOre's onBlockExploded is probably the cleanest imo. I'd say transpiler patch but they're a little harder to implement.https://harmony.pardeike.net/articles/patching-prefix.html Edited February 7, 2023 by Spear and Fang Link to comment Share on other sites More sharing options...
Frepo Posted February 8, 2023 Author Report Share Posted February 8, 2023 Yeah I started reading a little bit about harmony, the name came up when I was searching for a solution. Gonna look into that! Seems to be a very handy tool for modders. Thanks for the link. Man, modding is FUN! Link to comment Share on other sites More sharing options...
Frepo Posted February 14, 2023 Author Report Share Posted February 14, 2023 Oh, forgot to mention that this problem was solved (forgot to add the block behavior to the ore blocks... ooops) Link to comment Share on other sites More sharing options...
DArkHekRoMaNT Posted February 18, 2023 Report Share Posted February 18, 2023 (edited) On 2/7/2023 at 5:10 PM, Frepo said: Sadly I can't add a new value to EnumBlastType You can do it. Enum is just an int. For example: EnumBlastType value = (EnumBlastType)124; if(value == (EnumBlastType)124) { // do smth } To make it more convenient, you can use it as const or static readonly property public static EnumBlastType CustomBlastType { get; } = (EnumBlastType)124; Edited February 18, 2023 by DArkHekRoMaNT Link to comment Share on other sites More sharing options...
Frepo Posted February 28, 2023 Author Report Share Posted February 28, 2023 This is driving me crazy! I thought it was solved, but apparently not... it's a simple behavior, from what I can see it SHOULD work, but it's not... BlockBehaviorExplosionDropNerf : BlockBehavior I've removed checks for type of block (which should be quite redundant anyway since the behavior is only patched into ore-gem, ore-graded and ore-ungraded), I've set dropChance to 0. Tried removing the BlastType check. Hell, I even tried removing all code and just having handling = EnumHandling.PreventDefault; return; PreventDefault should stop the drops, right??? But they still drop their loot! It's like the behavior is not even added at all. PatchExplosionDropNerf Vanilla ore-graded The already present behavior, 'BreakIfFloating' can't have anything to with it, right? Vanilla BlockOre Again, if I set handled = EnumHandling.PreventDefault in my behavior, it should stop the drops? Link to comment Share on other sites More sharing options...
Frepo Posted February 28, 2023 Author Report Share Posted February 28, 2023 So, the other behavior could potentially interfere here. Since the base class 'BlockBehavior' sets handling to PassThrough. But that shouldn't matter here, since I add my behavior at the end of the array. Link to comment Share on other sites More sharing options...
Frepo Posted March 4, 2023 Author Report Share Posted March 4, 2023 Well... couldn't get it to work with a behavior. Still have no idea why. Solved it with a harmony-patch instead. Link to comment Share on other sites More sharing options...
Recommended Posts