Jump to content

[Solved] Can't override OnBlockExploded


Frepo

Recommended Posts

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 by Frepo
Link to comment
Share on other sites

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 by Frepo
Link to comment
Share on other sites

  • Frepo changed the title to [Solved] Can't override OnBlockExploded
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 by DArkHekRoMaNT
Link to comment
Share on other sites

  • Frepo changed the title to Can't override OnBlockExploded

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

image.thumb.png.1396e94c839ea82706b00bc2460fc72c.png

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
image.png.2ffb9f5e3580eb10e120a09f74576d5e.png

Vanilla ore-graded
image.png.4a6f1da9370dd4e5adf33886cd6d6c30.png

The already present behavior, 'BreakIfFloating' can't have anything to with it, right?

Vanilla BlockOre
image.png.2531283eee68fed97fb94ff8f2c6fb77.png

Again, if I set handled = EnumHandling.PreventDefault in my behavior, it should stop the drops?

Link to comment
Share on other sites

  • Frepo changed the title to [Solved] Can't override OnBlockExploded
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.