World.doesAreaContainFireSource needs patch to support modded fire
rikka0w0 opened this issue ยท 4 comments
Here is the code segment from vanilla:
public boolean doesAreaContainFireSource(Box box) {
...
Block block = this.getBlockState(pooledMutable.set(o, p, q)).getBlock();
if (block == Blocks.FIRE || block == Blocks.LAVA) {
As we can see, the logic is hard coded. Can we make a callback to support detecting modded fire? I have one solution:
@Mixin(World.class)
public abstract class MixinWorld {
@Redirect(method = "doesAreaContainFireSource", at = @At(value = "INVOKE", target = "net/minecraft/world/World.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", ordinal = 0))
private BlockState patchwork_doesAreaContainFireSource_getBlockState(World world, BlockPos blockPos) {
BlockState blockState = world.getBlockState(blockPos);
boolean isBurning = Our_Call_Back_isBurning(world, blockPos);
return isBurning ? Blocks.FIRE.getDefaultState() : Blocks.WATER.getDefaultState();
}
}
Hmm, is this 1.15? In 1.16 I think vanilla should support custom fires given now there are 2 types of fire.
In 1.16, World:doesAreaContainFireSource is removed and the logic is now handled in Entity.tick():
if (this.world.method_29556(this.getBoundingBox().contract(0.001D)).noneMatch((blockStatex) -> {
return blockStatex.isIn(BlockTags.FIRE) || blockStatex.isOf(Blocks.LAVA);
}) && this.fireTicks <= 0) {
this.setFireTicks(-this.getBurningDuration());
}
But it might be a good idea to have a blockstate and blockpos sensitive version of this. E.g. can be used in a toggleable heater
hmm, nowadays mojang prefer modifying the block state. Back in like 1.12 there were extensive client-specific rendering state; nowadays such states are gone. Moreover, Mojang intend to reflect behavioral changes of block entities in block state changes, such as furnace burning or not, etc. You should just create a few more states that have the toggle property.
I see, after the big flattening there's no limit on the maximum block id and blockstates.
I have another look at the 1.16 source code, now more things are done in the AbstractFireBlock class, so the custom fire can decide if it should deliver the damage. The check I mentioned earlier is now purely used for entity's path finding.
The only case we need blockstate-sensitive callback is we want mods to walk through our custom fire block when it is not burning.