Skip to content

Commit

Permalink
Close #236
Browse files Browse the repository at this point in the history
  • Loading branch information
shedaniel committed Apr 11, 2022
1 parent 8d142d6 commit 0de9a64
Show file tree
Hide file tree
Showing 6 changed files with 446 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package dev.architectury.registry.level.block;

import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;

public final class BlockFlammabilityRegistry {
/**
* Gets the burn odds for the given block.
*
* @param level the level
* @param state the block state
* @param pos the position of the block
* @param direction the direction of where the fire is coming from
* @return the burn odds
*/
@ExpectPlatform
public static int getBurnOdds(BlockGetter level, BlockState state, BlockPos pos, Direction direction) {
throw new AssertionError();
}

/**
* Gets the flame odds for the given block.
*
* @param level the level
* @param state the block state
* @param pos the position of the block
* @param direction the direction of where the fire is spreading from
* @return the flame odds
*/
@ExpectPlatform
public static int getFlameOdds(BlockGetter level, BlockState state, BlockPos pos, Direction direction) {
throw new AssertionError();
}

/**
* Registers the flammability for the given blocks for all fire blocks.
*
* @param burnOdds the burn odds
* @param flameOdds the flame odds
* @param flammableBlocks the flammable blocks
*/
@ExpectPlatform
public static void registerAll(int burnOdds, int flameOdds, Block... flammableBlocks) {
throw new AssertionError();
}

/**
* Registers the flammability for a given block tag for all fire blocks.
*
* @param burnOdds the burn odds
* @param flameOdds the flame odds
* @param flammableBlocks the flammable block tag
*/
@ExpectPlatform
public static void registerAll(int burnOdds, int flameOdds, TagKey<Block> flammableBlocks) {
throw new AssertionError();
}

/**
* Registers the flammability for the given blocks for a given fire block.
*
* @param fireBlock the specific fire block
* @param burnOdds the burn odds
* @param flameOdds the flame odds
* @param flammableBlocks the flammable blocks
*/
@ExpectPlatform
public static void register(Block fireBlock, int burnOdds, int flameOdds, Block... flammableBlocks) {
throw new AssertionError();
}

/**
* Registers the flammability for a given block tag for a given fire block.
*
* @param fireBlock the specific fire block
* @param burnOdds the burn odds
* @param flameOdds the flame odds
* @param flammableBlocks the flammable block tag
*/
@ExpectPlatform
public static void register(Block fireBlock, int burnOdds, int flameOdds, TagKey<Block> flammableBlocks) {
throw new AssertionError();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package dev.architectury.registry.level.block.fabric;

import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.FireBlock;
import net.minecraft.world.level.block.state.BlockState;

public class BlockFlammabilityRegistryImpl {
public static int getBurnOdds(BlockGetter level, BlockState state, BlockPos pos, Direction direction) {
BlockState fireState = level.getBlockState(pos.relative(direction));

if (fireState.getBlock() instanceof FireBlock fireBlock) {
FlammableBlockRegistry.Entry entry = FlammableBlockRegistry.getInstance(fireBlock).get(state.getBlock());
return entry.getBurnChance();
} else {
FlammableBlockRegistry.Entry entry = FlammableBlockRegistry.getDefaultInstance().get(state.getBlock());
return entry.getBurnChance();
}
}

public static int getFlameOdds(BlockGetter level, BlockState state, BlockPos pos, Direction direction) {
BlockState fireState = level.getBlockState(pos.relative(direction));

if (fireState.getBlock() instanceof FireBlock fireBlock) {
FlammableBlockRegistry.Entry entry = FlammableBlockRegistry.getInstance(fireBlock).get(state.getBlock());
return entry.getSpreadChance();
} else {
FlammableBlockRegistry.Entry entry = FlammableBlockRegistry.getDefaultInstance().get(state.getBlock());
return entry.getSpreadChance();
}
}

public static void registerAll(int burnOdds, int flameOdds, Block... flammableBlocks) {
FlammableBlockRegistry registry = FlammableBlockRegistry.getDefaultInstance();
for (Block block : flammableBlocks) {
registry.add(block, burnOdds, flameOdds);
}
}

public static void registerAll(int burnOdds, int flameOdds, TagKey<Block> flammableBlocks) {
FlammableBlockRegistry registry = FlammableBlockRegistry.getDefaultInstance();
registry.add(flammableBlocks, burnOdds, flameOdds);
}

public static void register(Block fireBlock, int burnOdds, int flameOdds, Block... flammableBlocks) {
FlammableBlockRegistry registry = FlammableBlockRegistry.getInstance(fireBlock);
for (Block block : flammableBlocks) {
registry.add(block, burnOdds, flameOdds);
}
}

public static void register(Block fireBlock, int burnOdds, int flameOdds, TagKey<Block> flammableBlocks) {
FlammableBlockRegistry registry = FlammableBlockRegistry.getInstance(fireBlock);
registry.add(flammableBlocks, burnOdds, flameOdds);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package dev.architectury.mixin.forge;

import net.minecraftforge.common.extensions.IForgeBlock;
import org.spongepowered.asm.mixin.Mixin;

@Mixin(IForgeBlock.class)
public interface MixinIForgeBlock {
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@

package dev.architectury.plugin.forge;

import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;

import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

public class ArchitecturyMixinPlugin implements IMixinConfigPlugin {
@Override
Expand Down Expand Up @@ -59,6 +62,46 @@ public void preApply(String targetClassName, ClassNode targetClass, String mixin

@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {

if ("dev.architectury.mixin.forge.MixinIForgeBlock".equals(mixinClassName)) {
for (MethodNode method : targetClass.methods) {
if ("getFlammability".equals(method.name) && method.desc.endsWith(")I")) {
AbstractInsnNode last = method.instructions.getLast();
// iterate backwards to find the last IRETURN
while (last != null && !(last instanceof InsnNode && last.getOpcode() == Opcodes.IRETURN)) {
last = last.getPrevious();
}

if (last != null) {
// insert a call to BlockFlammabilityRegistryImpl.handleFlammabilityHook
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 1)); // BlockState
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 2)); // BlockGetter
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 3)); // BlockPos
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 4)); // Direction
Type type = Type.getMethodType(method.desc);
Type[] types = type.getArgumentTypes();
String newDesc = Type.getMethodDescriptor(type.getReturnType(), Stream.concat(Stream.of(Type.INT_TYPE), Stream.of(types)).toArray(Type[]::new));
method.instructions.insertBefore(last, new MethodInsnNode(Opcodes.INVOKESTATIC, "dev/architectury/mixin/forge/BlockFlammabilityRegistryImpl", "handleBurnOddsHook", newDesc, false));
}
} else if ("getFireSpreadSpeed".equals(method.name) && method.desc.endsWith(")I")) {
AbstractInsnNode last = method.instructions.getLast();
// iterate backwards to find the last IRETURN
while (last != null && !(last instanceof InsnNode && last.getOpcode() == Opcodes.IRETURN)) {
last = last.getPrevious();
}

if (last != null) {
// insert a call to BlockFlammabilityRegistryImpl.handleFlammabilityHook
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 1)); // BlockState
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 2)); // BlockGetter
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 3)); // BlockPos
method.instructions.insertBefore(last, new VarInsnNode(Opcodes.ALOAD, 4)); // Direction
Type type = Type.getMethodType(method.desc);
Type[] types = type.getArgumentTypes();
String newDesc = Type.getMethodDescriptor(type.getReturnType(), Stream.concat(Stream.of(Type.INT_TYPE), Stream.of(types)).toArray(Type[]::new));
method.instructions.insertBefore(last, new MethodInsnNode(Opcodes.INVOKESTATIC, "dev/architectury/mixin/forge/BlockFlammabilityRegistryImpl", "handleSpreadOddsHook", newDesc, false));
}
}
}
}
}
}
Loading

0 comments on commit 0de9a64

Please sign in to comment.