mirror of
https://github.com/XevianLight/Aphelion.git
synced 2026-05-10 17:40:56 +01:00
Multiblock testing, JEI support, Alloying Recipe type
This commit is contained in:
16
build.gradle
16
build.gradle
@@ -19,6 +19,17 @@ group = mod_group_id
|
||||
|
||||
repositories {
|
||||
// Add here additional repositories if required by some of the dependencies below.
|
||||
mavenLocal()
|
||||
maven {
|
||||
// location of the maven that hosts JEI files since January 2023
|
||||
name = "Jared's maven"
|
||||
url = "https://maven.blamejared.com/"
|
||||
}
|
||||
maven {
|
||||
// location of a maven mirror for JEI files, as a fallback
|
||||
name = "ModMaven"
|
||||
url = "https://modmaven.dev"
|
||||
}
|
||||
}
|
||||
|
||||
base {
|
||||
@@ -119,6 +130,11 @@ dependencies {
|
||||
// We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it
|
||||
// localRuntime "mezz.jei:jei-${mc_version}-neoforge:${jei_version}"
|
||||
|
||||
// compile against the JEI API but do not include it at runtime
|
||||
compileOnly("mezz.jei:jei-${minecraft_version}-neoforge-api:${jei_version}")
|
||||
// at runtime, use the full JEI jar for NeoForge
|
||||
runtimeOnly("mezz.jei:jei-${minecraft_version}-neoforge:${jei_version}")
|
||||
|
||||
// Example mod dependency using a mod jar from ./libs with a flat dir repository
|
||||
// This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar
|
||||
// The group id is ignored when searching -- in this case, it is "blank"
|
||||
|
||||
@@ -22,6 +22,8 @@ neo_version=21.1.217
|
||||
# The loader version range can only use the major version of FML as bounds
|
||||
loader_version_range=[1,)
|
||||
|
||||
jei_version=19.25.0.322
|
||||
|
||||
## Mod Properties
|
||||
|
||||
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// 1.21.1 2026-01-11T16:25:14.5769018 Loot Tables
|
||||
// 1.21.1 2026-01-17T20:45:45.6230298 Loot Tables
|
||||
69d8318ddba171526d1fabb87d9d93548ed8598e data/aphelion/loot_table/blocks/arc_furnace_casing.json
|
||||
05f08985e601d30116f67e2f07b48b03b40cdca6 data/aphelion/loot_table/blocks/block_steel.json
|
||||
ff43a9c3741faf10b1e156a7a74d5cfb035cc118 data/aphelion/loot_table/blocks/dimension_changer.json
|
||||
b63130d9c10485676303d729807b6fcaac080294 data/aphelion/loot_table/blocks/electric_arc_furnace.json
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 1.21.1 2026-01-11T16:22:45.6439549 Tags for minecraft:block mod id aphelion
|
||||
// 1.21.1 2026-01-17T21:22:18.4350515 Tags for minecraft:block mod id aphelion
|
||||
058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks.json
|
||||
058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks/steel.json
|
||||
74a1db8ab013dc51b65440e5b6521b340b37af7c data/minecraft/tags/block/mineable/pickaxe.json
|
||||
74a1db8ab013dc51b65440e5b6521b340b37af7c data/minecraft/tags/block/needs_stone_tool.json
|
||||
51e9ab2ffa3ba81700cbaab7f39985bb2ab673fa data/minecraft/tags/block/mineable/pickaxe.json
|
||||
51e9ab2ffa3ba81700cbaab7f39985bb2ab673fa data/minecraft/tags/block/needs_stone_tool.json
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// 1.21.1 2026-01-14T23:38:35.7389032 Block States: aphelion
|
||||
// 1.21.1 2026-01-17T21:22:18.4335623 Block States: aphelion
|
||||
851ff42f7b21dec86107c8e0cefb3934ae4ebc08 assets/aphelion/blockstates/block_steel.json
|
||||
30b9c0efd7aaadb5412d98e4568f98b3632adbb9 assets/aphelion/blockstates/dimension_changer.json
|
||||
29dfcf9c4933ebf2020c57a83c60e7e7d3bd2bb5 assets/aphelion/blockstates/electric_arc_furnace.json
|
||||
b86c50fddcf6c8c6c19cb748529239d5962a3ede assets/aphelion/blockstates/test_block.json
|
||||
a810b97f4dace35d026f28d96cb9c47c93600d75 assets/aphelion/models/block/block_steel.json
|
||||
2d3592b7ab7132908709243e97540151e0fb762e assets/aphelion/models/block/dimension_changer.json
|
||||
5f7e8674070f31a63875b5d6147153bfa0eef61a assets/aphelion/models/block/electric_arc_furnace.json
|
||||
e0971228b4a1c4bc9dbab58a7dacdc3ae6037e02 assets/aphelion/models/block/test_block.json
|
||||
cdc831b0f1c462be64825fd34bd446e5b95afac6 assets/aphelion/models/item/arc_furnace_casing.json
|
||||
3599f9037eb2f66de1765318b97ab564c3eae92f assets/aphelion/models/item/block_steel.json
|
||||
db0ec473a016ce05c258cde18a217d47a9ea8324 assets/aphelion/models/item/dimension_changer.json
|
||||
279080c06ada87f54fd0a7b885b256dbe25a946a assets/aphelion/models/item/electric_arc_furnace.json
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace"
|
||||
},
|
||||
"facing=north,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace"
|
||||
},
|
||||
"facing=south,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
"values": [
|
||||
"aphelion:test_block",
|
||||
"aphelion:electric_arc_furnace",
|
||||
"aphelion:block_steel"
|
||||
"aphelion:block_steel",
|
||||
"aphelion:arc_furnace_casing"
|
||||
]
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
"values": [
|
||||
"aphelion:test_block",
|
||||
"aphelion:electric_arc_furnace",
|
||||
"aphelion:block_steel"
|
||||
"aphelion:block_steel",
|
||||
"aphelion:arc_furnace_casing"
|
||||
]
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import net.xevianlight.aphelion.core.init.*;
|
||||
import net.xevianlight.aphelion.fluid.BaseFluidType;
|
||||
import net.xevianlight.aphelion.fluid.ModFluidTypes;
|
||||
import net.xevianlight.aphelion.fluid.ModFluids;
|
||||
import net.xevianlight.aphelion.recipe.ModRecipes;
|
||||
import net.xevianlight.aphelion.screen.ElectricArcFurnaceScreen;
|
||||
import net.xevianlight.aphelion.screen.ModMenuTypes;
|
||||
import net.xevianlight.aphelion.screen.TestBlockScreen;
|
||||
@@ -55,6 +56,7 @@ public class Aphelion {
|
||||
ModFluidTypes.FLUID_TYPES.register(MOD_BUS);
|
||||
ModFluids.register(MOD_BUS);
|
||||
ModSounds.register(MOD_BUS);
|
||||
ModRecipes.register(MOD_BUS);
|
||||
|
||||
// Register ourselves for server and other game events we are interested in.
|
||||
// Note that this is necessary if and only if we want *this* class (ExtremeRocketry) to respond directly to events.
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package net.xevianlight.aphelion.block.custom;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.xevianlight.aphelion.block.entity.custom.EAFPartEntity;
|
||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ArcFurnaceCasingBlock extends BaseEntityBlock {
|
||||
|
||||
public static final BooleanProperty FORMED = BooleanProperty.create("formed");
|
||||
|
||||
public ArcFurnaceCasingBlock(Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.getStateDefinition().any()
|
||||
.setValue(FORMED, false));
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return Properties
|
||||
.of()
|
||||
.sound(SoundType.ANVIL)
|
||||
.destroyTime(2f)
|
||||
.explosionResistance(10f)
|
||||
.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
public static Item.Properties getItemProperties() {
|
||||
return new Item.Properties();
|
||||
}
|
||||
|
||||
public static final MapCodec<ArcFurnaceCasingBlock> CODEC = simpleCodec(ArcFurnaceCasingBlock::new);
|
||||
|
||||
@Override
|
||||
protected MapCodec<? extends BaseEntityBlock> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new EAFPartEntity(blockPos, blockState);
|
||||
}
|
||||
|
||||
private void pingNearbyController(Level level, BlockPos pos) {
|
||||
int r = 3;
|
||||
BlockPos.MutableBlockPos mp = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (int dx=-r; dx<=r; dx++)
|
||||
for (int dy=-r; dy<=r; dy++)
|
||||
for (int dz=-r; dz<=r; dz++) {
|
||||
mp.set(pos.getX()+dx, pos.getY()+dy, pos.getZ()+dz);
|
||||
BlockEntity be = level.getBlockEntity(mp);
|
||||
if (be instanceof ElectricArcFurnaceEntity eaf) {
|
||||
if (level.getBlockState(eaf.getBlockPos()).getBlock() instanceof ElectricArcFurnace) {
|
||||
eaf.tryForm();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
|
||||
super.onPlace(state, level, pos, oldState, movedByPiston);
|
||||
if (!level.isClientSide()) pingNearbyController(level, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
if (!level.isClientSide() && state.getBlock() != newState.getBlock()) {
|
||||
pingNearbyController(level, pos);
|
||||
}
|
||||
super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState pState) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
return this.defaultBlockState().setValue(FORMED, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(FORMED);
|
||||
}
|
||||
}
|
||||
@@ -36,13 +36,21 @@ public class ElectricArcFurnace extends BaseEntityBlock {
|
||||
|
||||
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
public static final BooleanProperty LIT = BlockStateProperties.LIT;
|
||||
public static final BooleanProperty FORMED = BooleanProperty.create("formed");
|
||||
|
||||
public ElectricArcFurnace(Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.getStateDefinition().any()
|
||||
.setValue(FORMED, false));
|
||||
}
|
||||
|
||||
public static final MapCodec<ElectricArcFurnace> CODEC = simpleCodec(ElectricArcFurnace::new);
|
||||
|
||||
private final int INPUT_SLOT = 0;
|
||||
private final int SECONDARY_INPUT_SLOT = 1;
|
||||
private final int OUTPUT_SLOT = 2;
|
||||
private final int ENERGY_SLOT = 3;
|
||||
|
||||
@Override
|
||||
protected MapCodec<? extends BaseEntityBlock> codec() {
|
||||
return CODEC;
|
||||
@@ -64,7 +72,7 @@ public class ElectricArcFurnace extends BaseEntityBlock {
|
||||
@Override
|
||||
public InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult result) {
|
||||
|
||||
if (!level.isClientSide && player instanceof ServerPlayer serverPlayer && level.getBlockEntity(pos) instanceof ElectricArcFurnaceEntity electricArcFurnaceEntity) {
|
||||
if (!level.isClientSide && player instanceof ServerPlayer serverPlayer && level.getBlockEntity(pos) instanceof ElectricArcFurnaceEntity electricArcFurnaceEntity && state.getValue(FORMED)) {
|
||||
serverPlayer.openMenu(new SimpleMenuProvider(electricArcFurnaceEntity, Component.literal("Electric Arc Furnace")), pos);
|
||||
}
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
@@ -84,15 +92,27 @@ public class ElectricArcFurnace extends BaseEntityBlock {
|
||||
|
||||
@Override
|
||||
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
if (state.getBlock() != newState.getBlock()) {
|
||||
if (!level.isClientSide && state.getBlock() != newState.getBlock()) {
|
||||
BlockEntity blockEntity= level.getBlockEntity(pos);
|
||||
if (blockEntity instanceof ElectricArcFurnaceEntity electricArcFurnaceEntity) {
|
||||
if(state.getValue(FORMED)) electricArcFurnaceEntity.unformForRemoval();
|
||||
electricArcFurnaceEntity.drops();
|
||||
}
|
||||
}
|
||||
super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
|
||||
super.onPlace(state, level, pos, oldState, movedByPiston);
|
||||
if (!level.isClientSide() && oldState.getBlock() != state.getBlock()) {
|
||||
BlockEntity blockEntity= level.getBlockEntity(pos);
|
||||
if (blockEntity instanceof ElectricArcFurnaceEntity electricArcFurnaceEntity) {
|
||||
electricArcFurnaceEntity.tryForm();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getRedstoneSignalFromItemHandler(@javax.annotation.Nullable ItemStackHandler itemStackHandler, List<Integer> slots) {
|
||||
if (itemStackHandler == null) {
|
||||
return 0;
|
||||
@@ -131,12 +151,15 @@ public class ElectricArcFurnace extends BaseEntityBlock {
|
||||
@Override
|
||||
protected int getAnalogOutputSignal(BlockState blockState, Level level, BlockPos pos) {
|
||||
List<Integer> slots = new ArrayList<>();
|
||||
slots.add(0);
|
||||
slots.add(1);
|
||||
slots.add(2);
|
||||
slots.add(3);
|
||||
slots.add(ElectricArcFurnaceEntity.INPUT_SLOT);
|
||||
slots.add(ElectricArcFurnaceEntity.SECONDARY_INPUT_SLOT);
|
||||
slots.add(ElectricArcFurnaceEntity.OUTPUT_SLOT);
|
||||
ElectricArcFurnaceEntity electricArcFurnaceEntity = ((ElectricArcFurnaceEntity) level.getBlockEntity(pos));
|
||||
return getRedstoneSignalFromItemHandler(electricArcFurnaceEntity.inventory, slots);
|
||||
|
||||
if (electricArcFurnaceEntity != null)
|
||||
return getRedstoneSignalFromItemHandler(electricArcFurnaceEntity.inventory, slots);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,11 +183,11 @@ public class ElectricArcFurnace extends BaseEntityBlock {
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()).setValue(LIT, false);
|
||||
return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()).setValue(LIT, false).setValue(FORMED, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(FACING, LIT);
|
||||
builder.add(FACING, LIT, FORMED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.xevianlight.aphelion.block.entity.custom;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EAFPartEntity extends BlockEntity {
|
||||
@Nullable private BlockPos controllerPos;
|
||||
|
||||
public EAFPartEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.EAF_PART_ENTITY.get(), pos, blockState);
|
||||
}
|
||||
|
||||
public void setControllerPos(@Nullable BlockPos pos) {
|
||||
controllerPos = pos;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public @Nullable BlockPos getControllerPos() {
|
||||
return controllerPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
|
||||
super.saveAdditional(tag, registries);
|
||||
if (controllerPos != null) tag.putLong("controller", controllerPos.asLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
|
||||
super.loadAdditional(tag, registries);
|
||||
controllerPos = tag.contains("controller") ? BlockPos.of(tag.getLong("controller")) : null;
|
||||
}
|
||||
}
|
||||
@@ -3,41 +3,45 @@ package net.xevianlight.aphelion.block.entity.custom;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.*;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.energy.EnergyStorage;
|
||||
import net.neoforged.neoforge.energy.IEnergyStorage;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.block.custom.ArcFurnaceCasingBlock;
|
||||
import net.xevianlight.aphelion.block.custom.ElectricArcFurnace;
|
||||
import net.xevianlight.aphelion.block.entity.energy.ModEnergyStorage;
|
||||
import net.xevianlight.aphelion.block.entity.energy.ModEnergyUtil;
|
||||
import net.xevianlight.aphelion.client.dimension.DimensionRendererCache;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
import net.xevianlight.aphelion.recipe.ElectricArcFurnaceRecipe;
|
||||
import net.xevianlight.aphelion.recipe.ElectricArcFurnaceRecipeInput;
|
||||
import net.xevianlight.aphelion.recipe.ModRecipes;
|
||||
import net.xevianlight.aphelion.screen.ElectricArcFurnaceMenu;
|
||||
import net.xevianlight.aphelion.util.SidedSlotHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvider {
|
||||
@@ -49,12 +53,12 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
private int maxProgress = 100;
|
||||
private final int DEFAULT_MAX_PROGRESS = 100;
|
||||
private final ContainerData data;
|
||||
private int Blasting_ENERGY_COST = 20;
|
||||
private int MACHINE_ENERGY_COST = 20;
|
||||
|
||||
private final int INPUT_SLOT = 0;
|
||||
private final int SECONDARY_INPUT_SLOT = 1;
|
||||
private final int OUTPUT_SLOT = 2;
|
||||
private final int ENERGY_SLOT = 3;
|
||||
public static final int INPUT_SLOT = 0;
|
||||
public static final int SECONDARY_INPUT_SLOT = 1;
|
||||
public static final int OUTPUT_SLOT = 2;
|
||||
public static final int ENERGY_SLOT = 3;
|
||||
|
||||
public ElectricArcFurnaceEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.ELECTRIC_ARC_FURNACE_ENTITY.get(), pos, blockState);
|
||||
@@ -104,10 +108,17 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
|
||||
public void tick(Level level, BlockPos pos, BlockState blockState) {
|
||||
|
||||
if (!blockState.getValue(ElectricArcFurnace.FORMED))
|
||||
return;
|
||||
|
||||
chargeFromItem();
|
||||
|
||||
if (inventory.getStackInSlot(SECONDARY_INPUT_SLOT).isEmpty()) {
|
||||
if (hasFurnaceRecipe(INPUT_SLOT) && hasEnoughEnergyToCraft(Blasting_ENERGY_COST)) {
|
||||
// Secondary slot is empty, try furnace recipes
|
||||
if (hasFurnaceRecipe(INPUT_SLOT) && hasEnoughEnergyToCraft(MACHINE_ENERGY_COST)) {
|
||||
// Recipe detected! We have enough energy to process
|
||||
progress++;
|
||||
useEnergyForBlasting();
|
||||
useEnergy();
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, true));
|
||||
setChanged(level, pos, blockState);
|
||||
|
||||
@@ -115,22 +126,46 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
outputBlastingResult(INPUT_SLOT, OUTPUT_SLOT);
|
||||
resetProgress();
|
||||
}
|
||||
} else if (hasFurnaceRecipe(INPUT_SLOT) && !hasEnoughEnergyToCraft(Blasting_ENERGY_COST)) {
|
||||
} else if (hasFurnaceRecipe(INPUT_SLOT) && !hasEnoughEnergyToCraft(MACHINE_ENERGY_COST)) {
|
||||
// Recipe detected but we ran out of power
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, false));
|
||||
setChanged(level, pos, blockState);
|
||||
progress = progress > 0 ? progress - 1 : 0;
|
||||
} else {
|
||||
// Invalid recipe
|
||||
resetProgress();
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, false));
|
||||
setChanged(level, pos, blockState);
|
||||
}
|
||||
} else {
|
||||
resetProgress();
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, false));
|
||||
setChanged(level, pos, blockState);
|
||||
// Secondary slot is NOT empty, try alloying recipes
|
||||
if (hasAlloyingRecipe(INPUT_SLOT, SECONDARY_INPUT_SLOT)) {
|
||||
if (hasEnoughEnergyToCraft(MACHINE_ENERGY_COST)) {
|
||||
// Alloy recipe detected! We have enough energy to process
|
||||
progress++;
|
||||
useEnergy();
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, true));
|
||||
setChanged(level, pos, blockState);
|
||||
|
||||
if (hasCraftingFinished()) {
|
||||
outputAlloyingResult(INPUT_SLOT, SECONDARY_INPUT_SLOT, OUTPUT_SLOT);
|
||||
resetProgress();
|
||||
}
|
||||
} else {
|
||||
// Recipe detected but we ran out of power
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, false));
|
||||
setChanged(level, pos, blockState);
|
||||
progress = progress > 0 ? progress - 1 : 0;
|
||||
}
|
||||
} else {
|
||||
// Invalid recipe
|
||||
resetProgress();
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, false));
|
||||
setChanged(level, pos, blockState);
|
||||
}
|
||||
}
|
||||
|
||||
chargeFromItem();
|
||||
|
||||
}
|
||||
|
||||
private void chargeFromItem() {
|
||||
@@ -177,13 +212,22 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
inventory.getStackInSlot(resultSlot).getCount() + (output.getCount() * 2)));
|
||||
}
|
||||
|
||||
private void outputAlloyingResult(int inputSlot, int secondaryInputSlot, int outputSlot) {
|
||||
Optional<RecipeHolder<ElectricArcFurnaceRecipe>> recipe = getAlloyingRecipe(inventory.getStackInSlot(inputSlot), inventory.getStackInSlot(secondaryInputSlot));
|
||||
ItemStack output = recipe.get().value().getResultItem(null);
|
||||
|
||||
inventory.extractItem(inputSlot, recipe.get().value().baseCount(), false);
|
||||
inventory.extractItem(secondaryInputSlot, recipe.get().value().alloyCount(), false);
|
||||
inventory.setStackInSlot(outputSlot, new ItemStack(output.getItem(), inventory.getStackInSlot(outputSlot).getCount() + (output.getCount())));
|
||||
}
|
||||
|
||||
private void resetProgress() {
|
||||
this.progress = 0;
|
||||
this.maxProgress = DEFAULT_MAX_PROGRESS;
|
||||
}
|
||||
|
||||
private void useEnergyForBlasting() {
|
||||
this.ENERGY_STORAGE.extractEnergy(Blasting_ENERGY_COST, false);
|
||||
private void useEnergy() {
|
||||
this.ENERGY_STORAGE.extractEnergy(MACHINE_ENERGY_COST, false);
|
||||
}
|
||||
|
||||
private boolean hasEnoughEnergyToCraft(int energyCost) {
|
||||
@@ -208,9 +252,47 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
}
|
||||
|
||||
private boolean hasCraftingFinished() {
|
||||
maxProgress = DEFAULT_MAX_PROGRESS;
|
||||
return this.progress >= this.maxProgress;
|
||||
}
|
||||
|
||||
|
||||
private boolean hasAlloyingRecipe(int slotBase, int slotAlloy) {
|
||||
ItemStack baseStack = inventory.getStackInSlot(slotBase);
|
||||
ItemStack alloyStack = inventory.getStackInSlot(slotAlloy);
|
||||
|
||||
Optional<RecipeHolder<ElectricArcFurnaceRecipe>> opt =
|
||||
getAlloyingRecipe(baseStack, alloyStack);
|
||||
|
||||
if (opt.isEmpty()) return false;
|
||||
|
||||
ElectricArcFurnaceRecipe recipe = opt.get().value();
|
||||
|
||||
// 1) Check required input counts
|
||||
if (baseStack.getCount() < recipe.baseCount()) return false;
|
||||
if (alloyStack.getCount() < recipe.alloyCount()) return false;
|
||||
|
||||
// 2) Check output slot compatibility + space
|
||||
ItemStack output = recipe.getResultItem(null);
|
||||
|
||||
maxProgress = recipe.cookTime();
|
||||
|
||||
return canInsertItemIntoOutputSlot(output, OUTPUT_SLOT)
|
||||
&& canInsertAmountIntoOutputSlot(output.getCount(), OUTPUT_SLOT);
|
||||
}
|
||||
|
||||
private Optional<RecipeHolder<ElectricArcFurnaceRecipe>> getAlloyingRecipe(ItemStack base, ItemStack alloy) {
|
||||
if (base.isEmpty()) return Optional.empty();
|
||||
if (alloy.isEmpty()) return Optional.empty();
|
||||
|
||||
return this.level.getRecipeManager()
|
||||
.getRecipeFor(
|
||||
ModRecipes.ELECTRIC_ARC_FURNACE_RECIPE_TYPE.get(),
|
||||
new ElectricArcFurnaceRecipeInput(base, alloy),
|
||||
level
|
||||
);
|
||||
}
|
||||
|
||||
private boolean hasFurnaceRecipe(int slot) {
|
||||
Optional<RecipeHolder<BlastingRecipe>> recipe = getFurnaceRecipe(new ItemStack(inventory.getStackInSlot(slot).getItem().asItem(), 1));
|
||||
if (recipe.isEmpty())
|
||||
@@ -233,7 +315,7 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
|
||||
private final IItemHandler fullHandler = new SidedSlotHandler(inventory, new int[]{0,1}, true, true);
|
||||
private final IItemHandler fullHandler = new SidedSlotHandler(inventory, new int[]{INPUT_SLOT, SECONDARY_INPUT_SLOT, OUTPUT_SLOT, ENERGY_SLOT}, true, true);
|
||||
private final IItemHandler inputHandler = new SidedSlotHandler(inventory, new int[]{0,1}, true, true);
|
||||
private final IItemHandler outputHandler = new SidedSlotHandler(inventory, new int[]{2,3}, false, true);
|
||||
private final IItemHandler jadeHandler = new SidedSlotHandler(inventory, new int[]{0}, false, false);
|
||||
@@ -247,6 +329,7 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
}
|
||||
|
||||
private final ModEnergyStorage ENERGY_STORAGE = createEnergyStorage();
|
||||
|
||||
private ModEnergyStorage createEnergyStorage() {
|
||||
return new ModEnergyStorage(ENERGY_CAPACITY, MAX_TRANSFER) {
|
||||
@Override
|
||||
@@ -308,4 +391,144 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider pRegistries) {
|
||||
return saveWithoutMetadata(pRegistries);
|
||||
}
|
||||
|
||||
private static BlockPos rotateY(BlockPos off, Direction facing) {
|
||||
// Assumes "default" shape faces NORTH.
|
||||
return switch (facing) {
|
||||
case NORTH -> off;
|
||||
case EAST -> new BlockPos(-off.getZ(), off.getY(), off.getX());
|
||||
case SOUTH -> new BlockPos(-off.getX(), off.getY(), -off.getZ());
|
||||
case WEST -> new BlockPos(off.getZ(), off.getY(), -off.getX());
|
||||
default -> off;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// MULTIBLOCK
|
||||
/// LOGIC
|
||||
/// BELOW
|
||||
|
||||
|
||||
|
||||
private boolean formed = false; // cached runtime state
|
||||
|
||||
private static final BlockPos[] SHAPE = new BlockPos[] {
|
||||
new BlockPos(1, 0, 0),
|
||||
new BlockPos(0, 0, 1),
|
||||
new BlockPos(1, 0, 1),
|
||||
|
||||
new BlockPos(0, 1, 0),
|
||||
new BlockPos(1, 1, 0),
|
||||
new BlockPos(0, 1, 1),
|
||||
new BlockPos(1, 1, 1),
|
||||
};
|
||||
|
||||
private List<BlockPos> getPartPositions() {
|
||||
Direction facing = getBlockState().getValue(BlockStateProperties.HORIZONTAL_FACING);
|
||||
BlockPos origin = getBlockPos();
|
||||
|
||||
List<BlockPos> out = new ArrayList<>(SHAPE.length);
|
||||
for (BlockPos off : SHAPE) {
|
||||
BlockPos ro = rotateY(off, facing);
|
||||
out.add(origin.offset(ro));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private boolean structureMatches() {
|
||||
if (level == null) return false;
|
||||
|
||||
for (BlockPos p : getPartPositions()) {
|
||||
BlockState st = level.getBlockState(p);
|
||||
|
||||
// Accept only your casing/part blocks
|
||||
if (!(st.getBlock() instanceof ArcFurnaceCasingBlock)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isFormed() {
|
||||
return formed;
|
||||
}
|
||||
|
||||
public void tryForm() {
|
||||
if (level == null || level.isClientSide()) return;
|
||||
if (!(getBlockState().getBlock() instanceof ElectricArcFurnace)) return; // don't form if not actually present
|
||||
|
||||
boolean valid = structureMatches();
|
||||
|
||||
if (valid && !formed) {
|
||||
formed = true;
|
||||
setFormedState(true);
|
||||
linkParts();
|
||||
} else if (!valid && formed) {
|
||||
unform();
|
||||
}
|
||||
}
|
||||
|
||||
public void unform() {
|
||||
if (level == null || level.isClientSide()) return;
|
||||
|
||||
formed = false;
|
||||
setFormedState(false);
|
||||
unlinkParts();
|
||||
}
|
||||
|
||||
public void unformForRemoval() {
|
||||
if (level == null || level.isClientSide()) return;
|
||||
|
||||
formed = false;
|
||||
unlinkParts();
|
||||
}
|
||||
|
||||
private void setFormedState(boolean value) {
|
||||
BlockState state = getBlockState();
|
||||
if (state.hasProperty(ElectricArcFurnace.FORMED) && state.getValue(ElectricArcFurnace.FORMED) != value) {
|
||||
level.setBlock(worldPosition, state.setValue(ElectricArcFurnace.FORMED, value), 3);
|
||||
}
|
||||
}
|
||||
|
||||
private void linkParts() {
|
||||
if (level == null || level.isClientSide()) return;
|
||||
|
||||
for (BlockPos p : getPartPositions()) {
|
||||
BlockState st = level.getBlockState(p);
|
||||
|
||||
if (st.getBlock() instanceof ArcFurnaceCasingBlock && st.hasProperty(ArcFurnaceCasingBlock.FORMED)) {
|
||||
if (!st.getValue(ArcFurnaceCasingBlock.FORMED)) {
|
||||
level.setBlock(p, st.setValue(ArcFurnaceCasingBlock.FORMED, true), 3);
|
||||
}
|
||||
}
|
||||
|
||||
BlockEntity be = level.getBlockEntity(p);
|
||||
if (be instanceof EAFPartEntity part) {
|
||||
part.setControllerPos(worldPosition);
|
||||
part.setChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unlinkParts() {
|
||||
if (level == null || level.isClientSide()) return;
|
||||
|
||||
for (BlockPos p : getPartPositions()) {
|
||||
BlockState st = level.getBlockState(p);
|
||||
|
||||
if (st.getBlock() instanceof ArcFurnaceCasingBlock && st.hasProperty(ArcFurnaceCasingBlock.FORMED)) {
|
||||
if (st.getValue(ArcFurnaceCasingBlock.FORMED)) {
|
||||
level.setBlock(p, st.setValue(ArcFurnaceCasingBlock.FORMED, false), 3);
|
||||
}
|
||||
}
|
||||
|
||||
BlockEntity be = level.getBlockEntity(p);
|
||||
if (be instanceof EAFPartEntity part && worldPosition.equals(part.getControllerPos())) {
|
||||
part.setControllerPos(null);
|
||||
part.setChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class AphelionCommand {
|
||||
SpacePartitionSavedData.get(level).setOrbitForPartition(x, z, orbit);
|
||||
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.set", x, z, orbit.toString()),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.set", x, z, orbit.toString()),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -62,7 +62,7 @@ public class AphelionCommand {
|
||||
SpacePartitionSavedData.get(level).overwriteAllExistingOrbits(orbit);
|
||||
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.overwriteall", orbit.toString()),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.overwriteall", orbit.toString()),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -82,12 +82,12 @@ public class AphelionCommand {
|
||||
|
||||
if (orbit != null) {
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.get", x, z, orbit.toString()),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.get", x, z, orbit.toString()),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.get.unassigned", x, z),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.get.unassigned", x, z),
|
||||
true
|
||||
);
|
||||
}
|
||||
@@ -108,7 +108,7 @@ public class AphelionCommand {
|
||||
|
||||
if (success) {
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.cleared", x, z),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.cleared", x, z),
|
||||
true
|
||||
);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public class AphelionCommand {
|
||||
SpacePartitionSavedData.get(level).clearAllOrbits();
|
||||
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.clearall"),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.clearall"),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -153,7 +153,7 @@ public class AphelionCommand {
|
||||
);
|
||||
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.debug.posToKey", x, z, clickableOutput),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.debug.posToKey", x, z, clickableOutput),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -185,7 +185,7 @@ public class AphelionCommand {
|
||||
);
|
||||
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.debug.keyToPos", key, clickableOutput),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.debug.keyToPos", key, clickableOutput),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -213,7 +213,7 @@ public class AphelionCommand {
|
||||
);
|
||||
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.orbit.debug.getPartition", x, z, clickableOutput),
|
||||
() -> Component.translatable("command.aphelion.station.orbit.debug.getPartition", x, z, clickableOutput),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -263,7 +263,7 @@ public class AphelionCommand {
|
||||
player.teleportTo(space, destX, player.position().y, destZ, EnumSet.noneOf(RelativeMovement.class), player.getYRot(), player.getXRot());
|
||||
|
||||
context.getSource().sendSuccess(
|
||||
() -> Component.translatable("aphelion.command.station.teleport.success", player.getDisplayName(), clickablePos, clickableId),
|
||||
() -> Component.translatable("command.aphelion.station.teleport.success", player.getDisplayName(), clickablePos, clickableId),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -271,7 +271,7 @@ public class AphelionCommand {
|
||||
}
|
||||
|
||||
context.getSource().sendFailure(
|
||||
Component.translatable("aphelion.command.station.teleport.failure")
|
||||
Component.translatable("command.aphelion.station.teleport.failure")
|
||||
);
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.xevianlight.aphelion.compat;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.BlastingRecipe;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.xevianlight.aphelion.recipe.ElectricArcFurnaceRecipe;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record ElectricArcFurnaceJeiRecipe (
|
||||
Ingredient base,
|
||||
int baseCount,
|
||||
@Nullable Ingredient alloy,
|
||||
int secondaryCount,
|
||||
ItemStack result,
|
||||
int cookTime
|
||||
){
|
||||
public boolean isAlloying() {
|
||||
return alloy != null;
|
||||
}
|
||||
|
||||
public static ElectricArcFurnaceJeiRecipe fromAlloying(ElectricArcFurnaceRecipe r) {
|
||||
return new ElectricArcFurnaceJeiRecipe(
|
||||
r.base(),
|
||||
r.baseCount(),
|
||||
r.alloy(),
|
||||
r.alloyCount(),
|
||||
r.getResultItem(null),
|
||||
r.cookTime()
|
||||
);
|
||||
}
|
||||
|
||||
public static ElectricArcFurnaceJeiRecipe fromBlasting(BlastingRecipe r) {
|
||||
Ingredient in = r.getIngredients().get(0);
|
||||
return new ElectricArcFurnaceJeiRecipe(
|
||||
in,
|
||||
1,
|
||||
null,
|
||||
1,
|
||||
r.getResultItem(null),
|
||||
r.getCookingTime()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package net.xevianlight.aphelion.compat;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import mezz.jei.api.constants.VanillaTypes;
|
||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
||||
import mezz.jei.api.gui.drawable.IDrawable;
|
||||
import mezz.jei.api.gui.drawable.IDrawableAnimated;
|
||||
import mezz.jei.api.gui.drawable.IDrawableStatic;
|
||||
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
|
||||
import mezz.jei.api.helpers.IGuiHelper;
|
||||
import mezz.jei.api.recipe.IFocusGroup;
|
||||
import mezz.jei.api.recipe.RecipeIngredientRole;
|
||||
import mezz.jei.api.recipe.RecipeType;
|
||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||
import net.xevianlight.aphelion.recipe.ElectricArcFurnaceRecipe;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ElectricArcFurnaceRecipeCategory implements IRecipeCategory<ElectricArcFurnaceJeiRecipe> {
|
||||
|
||||
private final Int2ObjectMap<IDrawableAnimated> arrows = new Int2ObjectOpenHashMap<>();
|
||||
private final Int2ObjectMap<IDrawableAnimated> energyBars = new Int2ObjectOpenHashMap<>();
|
||||
private final IGuiHelper helper;
|
||||
|
||||
public static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "alloying");
|
||||
public static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID,
|
||||
"textures/gui/electric_arc_furnace/jei.png");
|
||||
|
||||
public static final RecipeType<ElectricArcFurnaceJeiRecipe> ELECTRIC_ARC_FURNACE_RECIPE_TYPE =
|
||||
new RecipeType<>(UID, ElectricArcFurnaceJeiRecipe.class);
|
||||
|
||||
private final IDrawable background;
|
||||
private final IDrawable icon;
|
||||
|
||||
public ElectricArcFurnaceRecipeCategory(IGuiHelper helper) {
|
||||
this.helper = helper;
|
||||
this.background = helper.createDrawable(TEXTURE, 0, 0, 176, 82);
|
||||
this.icon = helper.createDrawableIngredient(VanillaTypes.ITEM_STACK, new ItemStack(ModBlocks.ELECTRIC_ARC_FURNACE.get()));
|
||||
}
|
||||
|
||||
private IDrawableAnimated getArrow(int cookTime) {
|
||||
return arrows.computeIfAbsent(cookTime, t -> {
|
||||
IDrawableStatic arrowStatic = helper.createDrawable(TEXTURE, 176, 0, 24, 15);
|
||||
return helper.createAnimatedDrawable(arrowStatic, t, IDrawableAnimated.StartDirection.LEFT, false);
|
||||
});
|
||||
}
|
||||
|
||||
private IDrawableAnimated getEnergyBar() {
|
||||
return arrows.computeIfAbsent(200, t -> {
|
||||
IDrawableStatic arrowStatic = helper.createDrawable(TEXTURE, 176, 15, 14, 42);
|
||||
return helper.createAnimatedDrawable(arrowStatic, t, IDrawableAnimated.StartDirection.TOP, true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(ElectricArcFurnaceJeiRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics guiGraphics, double mouseX, double mouseY) {
|
||||
getArrow(recipe.cookTime()).draw(guiGraphics, 89, 35);
|
||||
getEnergyBar().draw(guiGraphics, 9, 9);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<ElectricArcFurnaceJeiRecipe> getRecipeType() {
|
||||
return ELECTRIC_ARC_FURNACE_RECIPE_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTitle() {
|
||||
return Component.translatable("block.aphelion.electric_arc_furnace");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IDrawable getBackground() {
|
||||
return background;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable IDrawable getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecipe(IRecipeLayoutBuilder builder, ElectricArcFurnaceJeiRecipe recipe, IFocusGroup focuses) {
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 63, 35).addIngredients(recipe.base());
|
||||
if(recipe.alloy() != null) {
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 40, 35).addIngredients(recipe.alloy());
|
||||
}
|
||||
builder.addSlot(RecipeIngredientRole.OUTPUT, 125, 35).addItemStack(recipe.result());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package net.xevianlight.aphelion.compat;
|
||||
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
import mezz.jei.api.constants.RecipeTypes;
|
||||
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCategoryRegistration;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||
import net.xevianlight.aphelion.recipe.ElectricArcFurnaceRecipe;
|
||||
import net.xevianlight.aphelion.recipe.ModRecipes;
|
||||
import net.xevianlight.aphelion.screen.ElectricArcFurnaceScreen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@JeiPlugin
|
||||
public class JEIAphelionPlugin implements IModPlugin {
|
||||
@Override
|
||||
public ResourceLocation getPluginUid() {
|
||||
return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "jei_plugin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
registration.addRecipeCategories(new ElectricArcFurnaceRecipeCategory(
|
||||
registration.getJeiHelpers().getGuiHelper()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(IRecipeRegistration registration) {
|
||||
var level = Minecraft.getInstance().level;
|
||||
if (level == null) return;
|
||||
|
||||
RecipeManager recipeManager = level.getRecipeManager();
|
||||
|
||||
List<ElectricArcFurnaceJeiRecipe> recipes = new ArrayList<>();
|
||||
|
||||
for (var holder : recipeManager.getAllRecipesFor(ModRecipes.ELECTRIC_ARC_FURNACE_RECIPE_TYPE.get())) {
|
||||
recipes.add(ElectricArcFurnaceJeiRecipe.fromAlloying(holder.value()));
|
||||
}
|
||||
|
||||
for (var holder : recipeManager.getAllRecipesFor(RecipeType.BLASTING)) {
|
||||
recipes.add(ElectricArcFurnaceJeiRecipe.fromBlasting(holder.value()));
|
||||
}
|
||||
|
||||
// List<ElectricArcFurnaceRecipe> electricArcFurnaceRecipes = recipeManager
|
||||
// .getAllRecipesFor(ModRecipes.ELECTRIC_ARC_FURNACE_RECIPE_TYPE.get()).stream().map(RecipeHolder::value).toList();
|
||||
registration.addRecipes(ElectricArcFurnaceRecipeCategory.ELECTRIC_ARC_FURNACE_RECIPE_TYPE, recipes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerGuiHandlers(IGuiHandlerRegistration registration) {
|
||||
registration.addRecipeClickArea(ElectricArcFurnaceScreen.class, 88, 35, 24, 16,
|
||||
ElectricArcFurnaceRecipeCategory.ELECTRIC_ARC_FURNACE_RECIPE_TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
registration.addRecipeCatalyst(
|
||||
new ItemStack(ModBlocks.ELECTRIC_ARC_FURNACE.get()), ElectricArcFurnaceRecipeCategory.ELECTRIC_ARC_FURNACE_RECIPE_TYPE
|
||||
);
|
||||
registration.addRecipeCatalyst(
|
||||
new ItemStack(ModBlocks.ELECTRIC_ARC_FURNACE.get()),
|
||||
RecipeTypes.BLASTING
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.block.entity.custom.DimensionChangerBlockEntity;
|
||||
import net.xevianlight.aphelion.block.entity.custom.EAFPartEntity;
|
||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
|
||||
|
||||
@@ -27,4 +28,9 @@ public class ModBlockEntities {
|
||||
BLOCK_ENTITIES.register("electric_arc_furnace_block_entity", () -> BlockEntityType.Builder.of(
|
||||
ElectricArcFurnaceEntity::new, ModBlocks.ELECTRIC_ARC_FURNACE.get()).build(null)
|
||||
);
|
||||
|
||||
public static final Supplier<BlockEntityType<EAFPartEntity>> EAF_PART_ENTITY =
|
||||
BLOCK_ENTITIES.register("eaf_part_entity", () -> BlockEntityType.Builder.of(
|
||||
EAFPartEntity::new, ModBlocks.ARC_FURNACE_CASING_BLOCK.get()).build(null)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@ import net.minecraft.world.level.block.Block;
|
||||
import net.neoforged.neoforge.registries.DeferredBlock;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.block.custom.BlockSteel;
|
||||
import net.xevianlight.aphelion.block.custom.DimensionChangerBlock;
|
||||
import net.xevianlight.aphelion.block.custom.ElectricArcFurnace;
|
||||
import net.xevianlight.aphelion.block.custom.TestBlock;
|
||||
import net.xevianlight.aphelion.block.custom.*;
|
||||
|
||||
public class ModBlocks {
|
||||
public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(Aphelion.MOD_ID);
|
||||
@@ -16,4 +13,5 @@ public class ModBlocks {
|
||||
public static final DeferredBlock<Block> BLOCK_STEEL = BLOCKS.register("block_steel", () -> new BlockSteel(BlockSteel.getProperties()));
|
||||
public static final DeferredBlock<Block> DIMENSION_CHANGER = BLOCKS.register("dimension_changer", () -> new DimensionChangerBlock(DimensionChangerBlock.getProperties()));
|
||||
public static final DeferredBlock<Block> ELECTRIC_ARC_FURNACE = BLOCKS.register("electric_arc_furnace", () -> new ElectricArcFurnace(ElectricArcFurnace.getProperties()));
|
||||
public static final DeferredBlock<Block> ARC_FURNACE_CASING_BLOCK = BLOCKS.register("arc_furnace_casing", () -> new ArcFurnaceCasingBlock(ArcFurnaceCasingBlock.getProperties()));
|
||||
}
|
||||
|
||||
@@ -39,5 +39,6 @@ public class ModCreativeTabs {
|
||||
output.accept(ModItems.TEST_BLOCK);
|
||||
output.accept(ModItems.ELECTRIC_ARC_FURNACE);
|
||||
output.accept(ModItems.BLOCK_STEEL);
|
||||
output.accept(ModItems.ARC_FURNACE_CASING_BLOCK);
|
||||
}).build());
|
||||
}
|
||||
|
||||
@@ -6,10 +6,7 @@ import net.minecraft.world.item.Rarity;
|
||||
import net.neoforged.neoforge.registries.DeferredItem;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.block.custom.BlockSteel;
|
||||
import net.xevianlight.aphelion.block.custom.DimensionChangerBlock;
|
||||
import net.xevianlight.aphelion.block.custom.ElectricArcFurnace;
|
||||
import net.xevianlight.aphelion.block.custom.TestBlock;
|
||||
import net.xevianlight.aphelion.block.custom.*;
|
||||
import net.xevianlight.aphelion.item.*;
|
||||
|
||||
public class ModItems {
|
||||
@@ -35,4 +32,5 @@ public static final DeferredItem<Item> MUSIC_DISC_BIT_SHIFT = ITEMS.register("mu
|
||||
public static final DeferredItem<BlockItem> DIMENSION_CHANGER = ITEMS.register("dimension_changer", () -> new BlockItem(ModBlocks.DIMENSION_CHANGER.get(), DimensionChangerBlock.getItemProperties()));
|
||||
public static final DeferredItem<BlockItem> ELECTRIC_ARC_FURNACE = ITEMS.register("electric_arc_furnace", () -> new BlockItem(ModBlocks.ELECTRIC_ARC_FURNACE.get(), ElectricArcFurnace.getItemProperties()));
|
||||
public static final DeferredItem<BlockItem> BLOCK_STEEL = ITEMS.register("block_steel", () -> new BlockItem(ModBlocks.BLOCK_STEEL.get(), BlockSteel.getItemProperties()));
|
||||
public static final DeferredItem<BlockItem> ARC_FURNACE_CASING_BLOCK = ITEMS.register("arc_furnace_casing", () -> new BlockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK.get(), ArcFurnaceCasingBlock.getItemProperties()));
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public class ModBlockLootTableProvider extends BlockLootSubProvider {
|
||||
dropSelf(ModBlocks.BLOCK_STEEL.get());
|
||||
dropSelf(ModBlocks.DIMENSION_CHANGER.get());
|
||||
dropSelf(ModBlocks.ELECTRIC_ARC_FURNACE.get());
|
||||
dropSelf(ModBlocks.ARC_FURNACE_CASING_BLOCK.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,14 +18,15 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
||||
protected void registerStatesAndModels() {
|
||||
blockWithItem(ModBlocks.TEST_BLOCK);
|
||||
|
||||
horizontalBlock(ModBlocks.ELECTRIC_ARC_FURNACE.get(), models().orientable("aphelion:electric_arc_furnace",
|
||||
mcLoc("block/blast_furnace_side"),
|
||||
modLoc("block/electric_arc_furnace_front"),
|
||||
mcLoc("block/blast_furnace_top")));
|
||||
// horizontalBlock(ModBlocks.ELECTRIC_ARC_FURNACE.get(), models().orientable("aphelion:electric_arc_furnace",
|
||||
// mcLoc("block/blast_furnace_side"),
|
||||
// modLoc("block/electric_arc_furnace_front"),
|
||||
// mcLoc("block/blast_furnace_top")));
|
||||
blockItem(ModBlocks.ELECTRIC_ARC_FURNACE);
|
||||
|
||||
blockWithItem(ModBlocks.BLOCK_STEEL);
|
||||
blockWithItem(ModBlocks.DIMENSION_CHANGER);
|
||||
blockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK);
|
||||
}
|
||||
|
||||
private void blockWithItem(DeferredBlock<?> deferredBlock) {
|
||||
|
||||
@@ -22,11 +22,14 @@ public class ModBlockTagProvider extends BlockTagsProvider {
|
||||
tag(BlockTags.MINEABLE_WITH_PICKAXE)
|
||||
.add(ModBlocks.TEST_BLOCK.get())
|
||||
.add(ModBlocks.ELECTRIC_ARC_FURNACE.get())
|
||||
.add(ModBlocks.BLOCK_STEEL.get());
|
||||
.add(ModBlocks.BLOCK_STEEL.get())
|
||||
.add(ModBlocks.ARC_FURNACE_CASING_BLOCK.get());
|
||||
|
||||
tag(BlockTags.NEEDS_STONE_TOOL)
|
||||
.add(ModBlocks.TEST_BLOCK.get())
|
||||
.add(ModBlocks.ELECTRIC_ARC_FURNACE.get())
|
||||
.add(ModBlocks.BLOCK_STEEL.get());
|
||||
.add(ModBlocks.BLOCK_STEEL.get())
|
||||
.add(ModBlocks.ARC_FURNACE_CASING_BLOCK.get());
|
||||
|
||||
tag(ModTags.Blocks.STORAGE_BLOCKS_STEEL)
|
||||
.add(ModBlocks.BLOCK_STEEL.get());
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package net.xevianlight.aphelion.recipe;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public record ElectricArcFurnaceRecipe(Ingredient base, int baseCount, Ingredient alloy, int alloyCount, int cookTime, ItemStack output) implements Recipe<ElectricArcFurnaceRecipeInput> {
|
||||
|
||||
@Override
|
||||
public NonNullList<Ingredient> getIngredients() {
|
||||
NonNullList<Ingredient> list = NonNullList.create();
|
||||
list.add(base);
|
||||
list.add(alloy);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(ElectricArcFurnaceRecipeInput electricArcFurnaceRecipeInput, Level level) {
|
||||
if (level.isClientSide()) { return false; }
|
||||
|
||||
return base.test(electricArcFurnaceRecipeInput.getItem(0)) && alloy.test(electricArcFurnaceRecipeInput.getItem(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack assemble(ElectricArcFurnaceRecipeInput electricArcFurnaceRecipeInput, HolderLookup.Provider provider) {
|
||||
return output.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCraftInDimensions(int i, int i1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getResultItem(HolderLookup.Provider provider) {
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return ModRecipes.EAF_SERIALIZER.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<?> getType() {
|
||||
return ModRecipes.ELECTRIC_ARC_FURNACE_RECIPE_TYPE.get();
|
||||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<ElectricArcFurnaceRecipe> {
|
||||
|
||||
public static final MapCodec<ElectricArcFurnaceRecipe> CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group(
|
||||
Ingredient.CODEC_NONEMPTY.fieldOf("base").forGetter(ElectricArcFurnaceRecipe::base),
|
||||
Codec.INT.optionalFieldOf("base_count", 1).forGetter(ElectricArcFurnaceRecipe::baseCount),
|
||||
Ingredient.CODEC_NONEMPTY.fieldOf("alloy").forGetter(ElectricArcFurnaceRecipe::alloy),
|
||||
Codec.INT.optionalFieldOf("alloy_count", 1).forGetter(ElectricArcFurnaceRecipe::alloyCount),
|
||||
Codec.INT.optionalFieldOf("cook_time", 100).forGetter(ElectricArcFurnaceRecipe::cookTime),
|
||||
ItemStack.CODEC.fieldOf("result").forGetter(ElectricArcFurnaceRecipe::output)
|
||||
).apply(inst, ElectricArcFurnaceRecipe::new));
|
||||
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ElectricArcFurnaceRecipe> STREAM_CODEC =
|
||||
StreamCodec.composite(
|
||||
Ingredient.CONTENTS_STREAM_CODEC, ElectricArcFurnaceRecipe::base,
|
||||
ByteBufCodecs.VAR_INT, ElectricArcFurnaceRecipe::baseCount,
|
||||
Ingredient.CONTENTS_STREAM_CODEC, ElectricArcFurnaceRecipe::alloy,
|
||||
ByteBufCodecs.VAR_INT, ElectricArcFurnaceRecipe::alloyCount,
|
||||
ByteBufCodecs.VAR_INT, ElectricArcFurnaceRecipe::cookTime,
|
||||
ItemStack.STREAM_CODEC, ElectricArcFurnaceRecipe::output,
|
||||
ElectricArcFurnaceRecipe::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public MapCodec<ElectricArcFurnaceRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamCodec<RegistryFriendlyByteBuf, ElectricArcFurnaceRecipe> streamCodec() {
|
||||
return STREAM_CODEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.xevianlight.aphelion.recipe;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeInput;
|
||||
|
||||
public record ElectricArcFurnaceRecipeInput (ItemStack base, ItemStack alloy) implements RecipeInput {
|
||||
@Override
|
||||
public ItemStack getItem(int i) {
|
||||
return switch (i) {
|
||||
case 0 -> base;
|
||||
case 1 -> alloy;
|
||||
default -> ItemStack.EMPTY;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.xevianlight.aphelion.recipe;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
|
||||
public class ModRecipes {
|
||||
public static final DeferredRegister<RecipeSerializer<?>> SERIALIZERS =
|
||||
DeferredRegister.create(Registries.RECIPE_SERIALIZER, Aphelion.MOD_ID);
|
||||
|
||||
public static final DeferredRegister<RecipeType<?>> TYPES =
|
||||
DeferredRegister.create(Registries.RECIPE_TYPE, Aphelion.MOD_ID);
|
||||
|
||||
public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<ElectricArcFurnaceRecipe>> EAF_SERIALIZER =
|
||||
SERIALIZERS.register("alloying", ElectricArcFurnaceRecipe.Serializer::new);
|
||||
public static final DeferredHolder<RecipeType<?>, RecipeType<ElectricArcFurnaceRecipe>> ELECTRIC_ARC_FURNACE_RECIPE_TYPE =
|
||||
TYPES.register("alloying", () -> new RecipeType<ElectricArcFurnaceRecipe>() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "alloying";
|
||||
}
|
||||
});
|
||||
|
||||
public static void register(IEventBus eventBus) {
|
||||
SERIALIZERS.register(eventBus);
|
||||
TYPES.register(eventBus);
|
||||
}
|
||||
}
|
||||
@@ -39,10 +39,10 @@ public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
||||
addPlayerInventory(inventory);
|
||||
addPlayerHotbar(inventory);
|
||||
|
||||
this.addSlot(new EnergyItemSlot(this.blockEntity.inventory, 3, 8, 54));
|
||||
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, 0, 63, 35));
|
||||
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, 1, 40, 35));
|
||||
this.addSlot(new ExtractOnlySlot(this.blockEntity.inventory, 2, 125, 35));
|
||||
this.addSlot(new EnergyItemSlot(this.blockEntity.inventory, ElectricArcFurnaceEntity.ENERGY_SLOT, 8, 54));
|
||||
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, ElectricArcFurnaceEntity.INPUT_SLOT, 63, 35));
|
||||
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, ElectricArcFurnaceEntity.SECONDARY_INPUT_SLOT, 40, 35));
|
||||
this.addSlot(new ExtractOnlySlot(this.blockEntity.inventory, ElectricArcFurnaceEntity.OUTPUT_SLOT, 125, 35));
|
||||
|
||||
addDataSlots(data);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"variants": {
|
||||
"formed=false": {
|
||||
"model": "aphelion:block/arc_furnace_casing"
|
||||
},
|
||||
"formed=true": {
|
||||
"model": "aphelion:block/arc_furnace_casing_formed"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,formed=false,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,formed=false,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,formed=true,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,formed=true,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,formed=false,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace"
|
||||
},
|
||||
"facing=north,formed=false,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace"
|
||||
},
|
||||
"facing=north,formed=true,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed"
|
||||
},
|
||||
"facing=north,formed=true,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed"
|
||||
},
|
||||
"facing=south,formed=false,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,formed=false,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,formed=true,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,formed=true,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,formed=false,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,formed=false,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace",
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,formed=true,lit=false": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,formed=true,lit=true": {
|
||||
"model": "aphelion:block/electric_arc_furnace_formed",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,11 @@
|
||||
"custom_sky": false,
|
||||
"custom_weather": false,
|
||||
"dimension": "aphelion:default",
|
||||
"has_fog": false,
|
||||
"has_thick_fog": true,
|
||||
"has_fog": true,
|
||||
"has_thick_fog": false,
|
||||
"render_in_rain": true,
|
||||
"sunrise_angle": 0,
|
||||
"sunrise_color": 14180147,
|
||||
"render_void_fog": false,
|
||||
"horizon_height": -128,
|
||||
"clear_color_scale": 1.0
|
||||
}
|
||||
@@ -3,12 +3,11 @@
|
||||
"custom_sky": false,
|
||||
"custom_weather": false,
|
||||
"dimension": "aphelion:earth",
|
||||
"has_fog": false,
|
||||
"has_fog": true,
|
||||
"has_thick_fog": false,
|
||||
"render_in_rain": true,
|
||||
"sunrise_angle": 0,
|
||||
"sunrise_color": 14180147,
|
||||
"render_void_fog": false,
|
||||
"horizon_height": -128,
|
||||
"clear_color_scale": 1.0
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
"render_in_rain": true,
|
||||
"sunrise_angle": 0,
|
||||
"sunrise_color": 14180147,
|
||||
"render_void_fog": false,
|
||||
"horizon_height": -128,
|
||||
"clear_color_scale": 1.0
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
"render_in_rain": true,
|
||||
"sunrise_angle": 0,
|
||||
"sunrise_color": 14180147,
|
||||
"render_void_fog": false,
|
||||
"horizon_height": -128,
|
||||
"clear_color_scale": 1.0
|
||||
}
|
||||
@@ -27,15 +27,15 @@
|
||||
"tag.item.c.ingots.aluminum": "Aluminum Ingots",
|
||||
|
||||
|
||||
"aphelion.command.station.orbit.set": "Set station (%s, %s)'s orbit to %s",
|
||||
"aphelion.command.station.orbit.get": "Station (%s, %s)'s orbit is assigned to %s",
|
||||
"aphelion.command.station.orbit.get.unassigned": "Station (%s, %s)'s orbit is not assigned",
|
||||
"aphelion.command.station.orbit.cleared": "Cleared station (%s, %s)'s orbit",
|
||||
"aphelion.command.station.orbit.clearall": "Cleared all station orbits",
|
||||
"aphelion.command.station.orbit.overwriteall": "Set all existing station orbits with %s (unassigned stations were not affected)",
|
||||
"aphelion.command.station.orbit.debug.posToKey": "Key of station (%s, %s) is %s",
|
||||
"aphelion.command.station.orbit.debug.keyToPos": "Key %s belongs to station %s",
|
||||
"aphelion.command.station.teleport.success": "Teleported %s to station %s, id: %s",
|
||||
"aphelion.command.station.teleport.failure": "Failed to teleport, entity is null",
|
||||
"aphelion.command.station.orbit.debug.getPartition": "Partition of %s, %s is %s"
|
||||
"command.aphelion.station.orbit.set": "Set station (%s, %s)'s orbit to %s",
|
||||
"command.aphelion.station.orbit.get": "Station (%s, %s)'s orbit is assigned to %s",
|
||||
"command.aphelion.station.orbit.get.unassigned": "Station (%s, %s)'s orbit is not assigned",
|
||||
"command.aphelion.station.orbit.cleared": "Cleared station (%s, %s)'s orbit",
|
||||
"command.aphelion.station.orbit.clearall": "Cleared all station orbits",
|
||||
"command.aphelion.station.orbit.overwriteall": "Set all existing station orbits with %s (unassigned stations were not affected)",
|
||||
"command.aphelion.station.orbit.debug.posToKey": "Key of station (%s, %s) is %s",
|
||||
"command.aphelion.station.orbit.debug.keyToPos": "Key %s belongs to station %s",
|
||||
"command.aphelion.station.teleport.success": "Teleported %s to station %s, id: %s",
|
||||
"command.aphelion.station.teleport.failure": "Failed to teleport, entity is null",
|
||||
"command.aphelion.station.orbit.debug.getPartition": "Partition of %s, %s is %s"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "aphelion:block/arc_furnace_casing"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "aphelion:block/arc_furnace_casing_formed"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/orientable",
|
||||
"textures": {
|
||||
"front": "aphelion:block/electric_arc_furnace_front_formed",
|
||||
"side": "minecraft:block/blast_furnace_side",
|
||||
"top": "minecraft:block/blast_furnace_top"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 247 B |
Binary file not shown.
|
After Width: | Height: | Size: 206 B |
Binary file not shown.
|
After Width: | Height: | Size: 206 B |
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
15
src/main/resources/data/aphelion/recipe/steel_alloying.json
Normal file
15
src/main/resources/data/aphelion/recipe/steel_alloying.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"type": "aphelion:alloying",
|
||||
"base": {
|
||||
"tag": "c:ingots/iron"
|
||||
},
|
||||
"base_count": 1,
|
||||
"alloy": {
|
||||
"tag": "minecraft:coals"
|
||||
},
|
||||
"alloy_count": 1,
|
||||
"result": {
|
||||
"id": "aphelion:ingot_steel",
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"type": "immersiveengineering:arc_furnace",
|
||||
"additives": [
|
||||
{
|
||||
"tag": "minecraft:coals"
|
||||
}
|
||||
],
|
||||
"energy": 204800,
|
||||
"input": {
|
||||
"tag": "c:ingots/iron"
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"tag": "c:ingots/titanium"
|
||||
}
|
||||
],
|
||||
"slag": {
|
||||
"tag": "c:slag"
|
||||
},
|
||||
"time": 400
|
||||
}
|
||||
Reference in New Issue
Block a user