Basic development
@@ -26,9 +26,9 @@ loader_version_range=[1,)
|
||||
|
||||
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
|
||||
# Must match the String constant located in the main mod class annotated with @Mod.
|
||||
mod_id=extreme_rocketry
|
||||
mod_id=aphelion
|
||||
# The human-readable display name for the mod.
|
||||
mod_name=Extreme Rocketry
|
||||
mod_name=Aphelion
|
||||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=GNU GPLv3
|
||||
# The mod version. See https://semver.org/
|
||||
@@ -36,4 +36,4 @@ mod_version=0.0.1
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
mod_group_id=net.xevianlight.extremerocketry
|
||||
mod_group_id=net.xevianlight.aphelion
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
package net.xevianlight.extreme_rocketry;
|
||||
package net.xevianlight.aphelion;
|
||||
|
||||
import net.xevianlight.extreme_rocketry.core.init.ModBlocks;
|
||||
import net.xevianlight.extreme_rocketry.core.init.ModCreativeTabs;
|
||||
import net.xevianlight.extreme_rocketry.core.init.ModItems;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
||||
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
|
||||
import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent;
|
||||
import net.xevianlight.aphelion.client.AphelionConfig;
|
||||
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.screen.ElectricArcFurnaceScreen;
|
||||
import net.xevianlight.aphelion.screen.ModMenuTypes;
|
||||
import net.xevianlight.aphelion.screen.TestBlockScreen;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
@@ -19,10 +30,10 @@ import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStartingEvent;
|
||||
|
||||
// The value here should match an entry in the META-INF/neoforge.mods.toml file
|
||||
@Mod(ExtremeRocketry.MOD_ID)
|
||||
public class ExtremeRocketry {
|
||||
@Mod(Aphelion.MOD_ID)
|
||||
public class Aphelion {
|
||||
// Define mod id in a common place for everything to reference
|
||||
public static final String MOD_ID = "extreme_rocketry";
|
||||
public static final String MOD_ID = "aphelion";
|
||||
// Directly reference a slf4j logger
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
@@ -30,7 +41,7 @@ public class ExtremeRocketry {
|
||||
|
||||
// The constructor for the mod class is the first code that is run when your mod is loaded.
|
||||
// FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically.
|
||||
public ExtremeRocketry(IEventBus modEventBus, ModContainer modContainer) {
|
||||
public Aphelion(IEventBus modEventBus, ModContainer modContainer) {
|
||||
// Register the commonSetup method for modloading
|
||||
modEventBus.addListener(this::commonSetup);
|
||||
|
||||
@@ -39,6 +50,11 @@ public class ExtremeRocketry {
|
||||
ModItems.ITEMS.register(MOD_BUS);
|
||||
ModBlocks.BLOCKS.register(MOD_BUS);
|
||||
ModCreativeTabs.CREATIVE_MODE_TAB.register(MOD_BUS);
|
||||
ModBlockEntities.BLOCK_ENTITIES.register(MOD_BUS);
|
||||
ModMenuTypes.MENUS.register(MOD_BUS);
|
||||
ModFluidTypes.FLUID_TYPES.register(MOD_BUS);
|
||||
ModFluids.register(MOD_BUS);
|
||||
ModSounds.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.
|
||||
@@ -49,7 +65,7 @@ public class ExtremeRocketry {
|
||||
modEventBus.addListener(this::addCreative);
|
||||
|
||||
// Register our mod's ModConfigSpec so that FML can create and load the config file for us
|
||||
modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC);
|
||||
modContainer.registerConfig(ModConfig.Type.COMMON, AphelionConfig.SPEC);
|
||||
}
|
||||
|
||||
private void commonSetup(FMLCommonSetupEvent event) {
|
||||
@@ -71,5 +87,35 @@ public class ExtremeRocketry {
|
||||
public void onServerStarting(ServerStartingEvent event) {
|
||||
// Do something when the server starts
|
||||
LOGGER.info("HELLO from server starting");
|
||||
|
||||
|
||||
}
|
||||
|
||||
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
|
||||
@EventBusSubscriber(modid = MOD_ID, value = Dist.CLIENT)
|
||||
public static class ClientModEvents {
|
||||
@SubscribeEvent
|
||||
public static void onClientSetup(FMLClientSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
// ItemBlockRenderTypes.setRenderLayer(ModFluids.SOURCE_OIL_FLUID.get(), RenderType.translucent());
|
||||
// ItemBlockRenderTypes.setRenderLayer(ModFluids.FLOWING_OIL_FLUID.get(), RenderType.translucent());
|
||||
});
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientExtensions(RegisterClientExtensionsEvent event) {
|
||||
event.registerFluidType(((BaseFluidType) ModFluidTypes.OIL_FLUID_TYPE.get()).getClientFluidTypeExtensions(), ModFluidTypes.OIL_FLUID_TYPE.get());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerBER(EntityRenderersEvent.RegisterRenderers event) {
|
||||
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerScreens(RegisterMenuScreensEvent event) {
|
||||
event.register(ModMenuTypes.TEST_BLOCK_MENU.get(), TestBlockScreen::new);
|
||||
event.register(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), ElectricArcFurnaceScreen::new);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.xevianlight.aphelion.block.custom;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
|
||||
public class BlockSteel extends Block {
|
||||
public BlockSteel(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return Properties
|
||||
.of()
|
||||
.sound(SoundType.NETHERITE_BLOCK)
|
||||
.destroyTime(2f)
|
||||
.explosionResistance(10f)
|
||||
.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
public static Item.Properties getItemProperties() {
|
||||
return new Item.Properties();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package net.xevianlight.aphelion.block.custom;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
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.portal.DimensionTransition;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.xevianlight.aphelion.block.entity.custom.DimensionChangerBlockEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DimensionChangerBlock extends BaseEntityBlock {
|
||||
|
||||
public DimensionChangerBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MapCodec<? extends BaseEntityBlock> codec() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return Properties
|
||||
.of()
|
||||
.sound(SoundType.ANVIL)
|
||||
.destroyTime(2f)
|
||||
.explosionResistance(10f)
|
||||
.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
public static Item.Properties getItemProperties() {
|
||||
return new Item.Properties().stacksTo(3);
|
||||
}
|
||||
|
||||
@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 DimensionChangerBlockEntity dimensionChangerBlockEntity) {
|
||||
ServerLevel sourceDim = serverPlayer.serverLevel();
|
||||
ServerLevel targetDim = serverPlayer.server.getLevel(Level.NETHER);
|
||||
serverPlayer.changeDimension(new DimensionTransition(
|
||||
targetDim,
|
||||
serverPlayer.position().multiply(
|
||||
sourceDim.dimensionType().coordinateScale() / targetDim.dimensionType().coordinateScale(),
|
||||
1,
|
||||
sourceDim.dimensionType().coordinateScale() / targetDim.dimensionType().coordinateScale()),
|
||||
Vec3.ZERO, serverPlayer.getYRot(),
|
||||
serverPlayer.getXRot(),
|
||||
DimensionTransition.PLAY_PORTAL_SOUND
|
||||
));
|
||||
}
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
super.tick(state, level, pos, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new DimensionChangerBlockEntity(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState pState) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
if (state.getBlock() != newState.getBlock()) {
|
||||
BlockEntity blockEntity= level.getBlockEntity(pos);
|
||||
if (blockEntity instanceof DimensionChangerBlockEntity dimensionChangerBlockEntity) {
|
||||
dimensionChangerBlockEntity.drops();
|
||||
}
|
||||
}
|
||||
super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package net.xevianlight.aphelion.block.custom;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ElectricArcFurnace extends BaseEntityBlock {
|
||||
|
||||
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
public static final BooleanProperty LIT = BlockStateProperties.LIT;
|
||||
|
||||
public ElectricArcFurnace(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public static final MapCodec<ElectricArcFurnace> CODEC = simpleCodec(ElectricArcFurnace::new);
|
||||
|
||||
@Override
|
||||
protected MapCodec<? extends BaseEntityBlock> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return Properties
|
||||
.of()
|
||||
.sound(SoundType.METAL)
|
||||
.destroyTime(2f)
|
||||
.explosionResistance(10f)
|
||||
.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
public static Item.Properties getItemProperties() {
|
||||
return new Item.Properties();
|
||||
}
|
||||
|
||||
@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) {
|
||||
serverPlayer.openMenu(new SimpleMenuProvider(electricArcFurnaceEntity, Component.literal("Electric Arc Furnace")), pos);
|
||||
}
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new ElectricArcFurnaceEntity(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState pState) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
if (state.getBlock() != newState.getBlock()) {
|
||||
BlockEntity blockEntity= level.getBlockEntity(pos);
|
||||
if (blockEntity instanceof ElectricArcFurnaceEntity electricArcFurnaceEntity) {
|
||||
electricArcFurnaceEntity.drops();
|
||||
}
|
||||
}
|
||||
super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
}
|
||||
|
||||
public static int getRedstoneSignalFromItemHandler(@javax.annotation.Nullable ItemStackHandler itemStackHandler, List<Integer> slots) {
|
||||
if (itemStackHandler == null) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = 0;
|
||||
float f = 0.0F;
|
||||
|
||||
for(int slot : slots) {
|
||||
ItemStack itemstack = itemStackHandler.getStackInSlot(slot);
|
||||
if (!itemstack.isEmpty()) {
|
||||
f += (float)itemstack.getCount() / (float)Math.min(itemStackHandler.getSlotLimit(slot), itemstack.getMaxStackSize());
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
f /= (float)slots.size();
|
||||
return Mth.floor(f * 14.0F) + (i > 0 ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSignalSource(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return super.getSignal(state, level, pos, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasAnalogOutputSignal(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@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);
|
||||
ElectricArcFurnaceEntity electricArcFurnaceEntity = ((ElectricArcFurnaceEntity) level.getBlockEntity(pos));
|
||||
return getRedstoneSignalFromItemHandler(electricArcFurnaceEntity.inventory, slots);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {
|
||||
if (level.isClientSide) {
|
||||
return null;
|
||||
}
|
||||
return createTickerHelper(blockEntityType, ModBlockEntities.ELECTRIC_ARC_FURNACE_ENTITY.get(), (level1, blockPos, blockState, electricArcFurnaceEntity) -> electricArcFurnaceEntity.tick(level1, blockPos, blockState));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState rotate(BlockState state, Rotation rotation) {
|
||||
return state.setValue(FACING, rotation.rotate(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState mirror(BlockState state, Mirror mirror) {
|
||||
return state.rotate(mirror.getRotation(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()).setValue(LIT, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(FACING, LIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package net.xevianlight.aphelion.block.custom;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
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.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TestBlock extends BaseEntityBlock {
|
||||
public TestBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MapCodec<? extends BaseEntityBlock> codec() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return Properties
|
||||
.of()
|
||||
.sound(SoundType.ANVIL)
|
||||
.destroyTime(2f)
|
||||
.explosionResistance(10f)
|
||||
.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
public static Item.Properties getItemProperties() {
|
||||
return new Item.Properties().stacksTo(3);
|
||||
}
|
||||
|
||||
@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 TestBlockEntity testBlockEntity) {
|
||||
serverPlayer.openMenu(new SimpleMenuProvider(testBlockEntity, Component.literal("Test Block")), pos);
|
||||
}
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new TestBlockEntity(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState pState) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
if (state.getBlock() != newState.getBlock()) {
|
||||
BlockEntity blockEntity= level.getBlockEntity(pos);
|
||||
if (blockEntity instanceof TestBlockEntity testBlockEntity) {
|
||||
testBlockEntity.drops();
|
||||
}
|
||||
}
|
||||
super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
}
|
||||
|
||||
public static int getRedstoneSignalFromItemHandler(@javax.annotation.Nullable ItemStackHandler itemStackHandler, List<Integer> slots) {
|
||||
if (itemStackHandler == null) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = 0;
|
||||
float f = 0.0F;
|
||||
|
||||
for(int slot : slots) {
|
||||
ItemStack itemstack = itemStackHandler.getStackInSlot(slot);
|
||||
if (!itemstack.isEmpty()) {
|
||||
f += (float)itemstack.getCount() / (float)Math.min(itemStackHandler.getSlotLimit(slot), itemstack.getMaxStackSize());
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
f /= (float)slots.size();
|
||||
return Mth.floor(f * 14.0F) + (i > 0 ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSignalSource(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return super.getSignal(state, level, pos, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasAnalogOutputSignal(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getAnalogOutputSignal(BlockState blockState, Level level, BlockPos pos) {
|
||||
List<Integer> slots = new ArrayList<>();
|
||||
slots.add(0);
|
||||
TestBlockEntity testBlockEntity = ((TestBlockEntity) level.getBlockEntity(pos));
|
||||
return getRedstoneSignalFromItemHandler(testBlockEntity.inventory, slots);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {
|
||||
if (level.isClientSide) {
|
||||
return null;
|
||||
}
|
||||
return createTickerHelper(blockEntityType, ModBlockEntities.TEST_BLOCK_ENTITY.get(), (level1, blockPos, blockState, testBlockEntity) -> testBlockEntity.tick(level1, blockPos, blockState));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
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.NonNullList;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
import net.xevianlight.aphelion.screen.TestBlockMenu;
|
||||
import net.xevianlight.aphelion.util.SidedSlotHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DimensionChangerBlockEntity extends BlockEntity implements MenuProvider {
|
||||
|
||||
private final int SIZE = 1;
|
||||
|
||||
private NonNullList<ItemStack> items = NonNullList.withSize(SIZE, ItemStack.EMPTY);
|
||||
|
||||
public DimensionChangerBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.DIMENSION_CHANGER_BLOCK_ENTITY.get(), pos, blockState);
|
||||
}
|
||||
|
||||
public final ItemStackHandler inventory = new ItemStackHandler(SIZE) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void sendUpdate() {
|
||||
setChanged();
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
|
||||
private final IItemHandler topHandler = new SidedSlotHandler(inventory, new int[]{0}, true, false);
|
||||
private final IItemHandler bottomHandler = new SidedSlotHandler(inventory, new int[]{0}, false, true);
|
||||
private final IItemHandler jadeHandler = new SidedSlotHandler(inventory, new int[]{0}, false, false);
|
||||
|
||||
public IItemHandler getItemHandler(Direction direction) {
|
||||
if (direction == Direction.UP) return topHandler;
|
||||
if (direction == Direction.DOWN) return bottomHandler;
|
||||
if (direction == null) return jadeHandler;
|
||||
return null;
|
||||
}
|
||||
|
||||
public ItemStackHandler getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void drops() {
|
||||
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
|
||||
for(int i = 0; i < inventory.getSlots(); i++) {
|
||||
inv.setItem(i, inventory.getStackInSlot(i));
|
||||
}
|
||||
|
||||
Containers.dropContents(this.level, this.worldPosition, inv);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) {
|
||||
pTag.put("inventory", inventory.serializeNBT(pRegistries));
|
||||
super.saveAdditional(pTag, pRegistries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) {
|
||||
super.loadAdditional(pTag, pRegistries);
|
||||
inventory.deserializeNBT(pRegistries, pTag.getCompound("inventory"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getDisplayName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
|
||||
return new TestBlockMenu(i, inventory, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
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.world.Containers;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
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.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.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.screen.ElectricArcFurnaceMenu;
|
||||
import net.xevianlight.aphelion.util.SidedSlotHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvider {
|
||||
|
||||
private final int SIZE = 4;
|
||||
private int ENERGY_CAPACITY = 64000;
|
||||
private int MAX_TRANSFER = 320;
|
||||
private int progress = 0;
|
||||
private int maxProgress = 100;
|
||||
private final int DEFAULT_MAX_PROGRESS = 100;
|
||||
private final ContainerData data;
|
||||
private int Blasting_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 ElectricArcFurnaceEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.ELECTRIC_ARC_FURNACE_ENTITY.get(), pos, blockState);
|
||||
this.data = new ContainerData() {
|
||||
@Override
|
||||
public int get(int index) {
|
||||
return switch (index) {
|
||||
case 0 -> ElectricArcFurnaceEntity.this.progress;
|
||||
case 1 -> ElectricArcFurnaceEntity.this.maxProgress;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int index, int pValue) {
|
||||
switch (index) {
|
||||
case 0: ElectricArcFurnaceEntity.this.progress = pValue;
|
||||
case 1: ElectricArcFurnaceEntity.this.maxProgress = pValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public final ItemStackHandler inventory = new ItemStackHandler(SIZE) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isItemValid(int slot, ItemStack stack) {
|
||||
// if (slot == ENERGY_SLOT) {
|
||||
// var capability = stack.getCapability(Capabilities.EnergyStorage.ITEM);
|
||||
// return capability != null;
|
||||
// }
|
||||
// return super.isItemValid(slot, stack);
|
||||
// }
|
||||
};
|
||||
|
||||
public void tick(Level level, BlockPos pos, BlockState blockState) {
|
||||
|
||||
if (inventory.getStackInSlot(SECONDARY_INPUT_SLOT).isEmpty()) {
|
||||
if (hasFurnaceRecipe(INPUT_SLOT) && hasEnoughEnergyToCraft(Blasting_ENERGY_COST)) {
|
||||
progress++;
|
||||
useEnergyForBlasting();
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, true));
|
||||
setChanged(level, pos, blockState);
|
||||
|
||||
if (hasCraftingFinished()) {
|
||||
outputBlastingResult(INPUT_SLOT, OUTPUT_SLOT);
|
||||
resetProgress();
|
||||
}
|
||||
} else if (hasFurnaceRecipe(INPUT_SLOT) && !hasEnoughEnergyToCraft(Blasting_ENERGY_COST)) {
|
||||
level.setBlockAndUpdate(pos, blockState.setValue(ElectricArcFurnace.LIT, false));
|
||||
setChanged(level, pos, blockState);
|
||||
progress = progress > 0 ? progress - 1 : 0;
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
chargeFromItem();
|
||||
}
|
||||
|
||||
private void chargeFromItem() {
|
||||
ItemStack stack;
|
||||
|
||||
try {
|
||||
stack = inventory.getStackInSlot(ENERGY_SLOT);
|
||||
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
IEnergyStorage itemEnergy = stack.getCapability(Capabilities.EnergyStorage.ITEM);
|
||||
if (itemEnergy == null || !itemEnergy.canExtract()) return;
|
||||
|
||||
int freeCapacity = ENERGY_STORAGE.getMaxEnergyStored() - ENERGY_STORAGE.getEnergyStored();
|
||||
if (freeCapacity <= 0) return;
|
||||
|
||||
int maxMove = Math.min(MAX_TRANSFER, freeCapacity);
|
||||
|
||||
// Simulate extraction first
|
||||
int canExtract = itemEnergy.extractEnergy(maxMove, true);
|
||||
if (canExtract <= 0) return;
|
||||
|
||||
// Receive into block (simulate then execute is safest)
|
||||
int canReceive = ENERGY_STORAGE.receiveEnergy(canExtract, true);
|
||||
if (canReceive <= 0) return;
|
||||
|
||||
int extracted = itemEnergy.extractEnergy(canReceive, false);
|
||||
ENERGY_STORAGE.receiveEnergy(maxMove, false);
|
||||
|
||||
setChanged();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void outputBlastingResult(int slot, int resultSlot) {
|
||||
Optional<RecipeHolder<BlastingRecipe>> recipe = getFurnaceRecipe(inventory.getStackInSlot(slot));
|
||||
ItemStack output = recipe.get().value().getResultItem(null);
|
||||
|
||||
// 2x multiplier for smelting recipes
|
||||
|
||||
inventory.extractItem(slot, 1, false);
|
||||
inventory.setStackInSlot(resultSlot, new ItemStack(output.getItem(),
|
||||
inventory.getStackInSlot(resultSlot).getCount() + (output.getCount() * 2)));
|
||||
}
|
||||
|
||||
private void resetProgress() {
|
||||
this.progress = 0;
|
||||
this.maxProgress = DEFAULT_MAX_PROGRESS;
|
||||
}
|
||||
|
||||
private void useEnergyForBlasting() {
|
||||
this.ENERGY_STORAGE.extractEnergy(Blasting_ENERGY_COST, false);
|
||||
}
|
||||
|
||||
private boolean hasEnoughEnergyToCraft(int energyCost) {
|
||||
return ENERGY_STORAGE.getEnergyStored() >= energyCost;
|
||||
}
|
||||
|
||||
private boolean canInsertItemIntoOutputSlot(ItemStack output, int slot) {
|
||||
return inventory.getStackInSlot(slot).isEmpty() ||
|
||||
inventory.getStackInSlot(slot).getItem() == output.getItem();
|
||||
}
|
||||
|
||||
private boolean canInsertAmountIntoOutputSlot(int count, int slot) {
|
||||
int maxCount = inventory.getStackInSlot(slot).isEmpty() ? 64 : inventory.getStackInSlot(slot).getMaxStackSize();
|
||||
int currentCount = inventory.getStackInSlot(slot).getCount();
|
||||
|
||||
return maxCount >= currentCount + count;
|
||||
}
|
||||
|
||||
private boolean isOutputSlotEmptyOrReceivable(int slot) {
|
||||
return this.inventory.getStackInSlot(slot).isEmpty() ||
|
||||
this.inventory.getStackInSlot(slot).getCount() < this.inventory.getStackInSlot(slot).getMaxStackSize();
|
||||
}
|
||||
|
||||
private boolean hasCraftingFinished() {
|
||||
return this.progress >= this.maxProgress;
|
||||
}
|
||||
|
||||
private boolean hasFurnaceRecipe(int slot) {
|
||||
Optional<RecipeHolder<BlastingRecipe>> recipe = getFurnaceRecipe(new ItemStack(inventory.getStackInSlot(slot).getItem().asItem(), 1));
|
||||
if (recipe.isEmpty())
|
||||
return false;
|
||||
|
||||
ItemStack output = recipe.get().value().getResultItem(null);
|
||||
return canInsertAmountIntoOutputSlot(output.getCount() * 2, OUTPUT_SLOT) && canInsertItemIntoOutputSlot(output, OUTPUT_SLOT);
|
||||
}
|
||||
|
||||
private Optional<RecipeHolder<BlastingRecipe>> getFurnaceRecipe(ItemStack stack) {
|
||||
if (stack.isEmpty()) return Optional.empty();
|
||||
|
||||
return this.level.getRecipeManager()
|
||||
.getRecipeFor(RecipeType.BLASTING, new SingleRecipeInput(stack), level);
|
||||
|
||||
}
|
||||
|
||||
public void sendUpdate() {
|
||||
setChanged();
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
|
||||
private final IItemHandler fullHandler = new SidedSlotHandler(inventory, new int[]{0,1}, 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);
|
||||
|
||||
public IItemHandler getItemHandler(Direction direction) {
|
||||
return fullHandler;
|
||||
}
|
||||
|
||||
public IEnergyStorage getEnergyStorage(@Nullable Direction direction) {
|
||||
return this.ENERGY_STORAGE;
|
||||
}
|
||||
|
||||
private final ModEnergyStorage ENERGY_STORAGE = createEnergyStorage();
|
||||
private ModEnergyStorage createEnergyStorage() {
|
||||
return new ModEnergyStorage(ENERGY_CAPACITY, MAX_TRANSFER) {
|
||||
@Override
|
||||
public void onEnergyChanged() {
|
||||
setChanged();
|
||||
getLevel().sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ItemStackHandler getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void drops() {
|
||||
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
|
||||
for(int i = 0; i < inventory.getSlots(); i++) {
|
||||
inv.setItem(i, inventory.getStackInSlot(i));
|
||||
}
|
||||
|
||||
Containers.dropContents(this.level, this.worldPosition, inv);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider pRegistries) {
|
||||
tag.put("inventory", inventory.serializeNBT(pRegistries));
|
||||
tag.putInt("electric_arc_furnace.progress", progress);
|
||||
tag.putInt("electric_arc_furnace.maxProgress", maxProgress);
|
||||
tag.putInt("electric_arc_furnace.energy", ENERGY_STORAGE.getEnergyStored());
|
||||
super.saveAdditional(tag, pRegistries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider pRegistries) {
|
||||
super.loadAdditional(tag, pRegistries);
|
||||
inventory.deserializeNBT(pRegistries, tag.getCompound("inventory"));
|
||||
progress = tag.getInt("electric_arc_furnace.progress");
|
||||
maxProgress = tag.getInt("electric_arc_furnace.maxProgress");
|
||||
ENERGY_STORAGE.setEnergy(tag.getInt("electric_arc_furnace.energy"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getDisplayName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
|
||||
return new ElectricArcFurnaceMenu(i, inventory, this, this.data);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Packet<ClientGamePacketListener> getUpdatePacket() {
|
||||
return ClientboundBlockEntityDataPacket.create(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider pRegistries) {
|
||||
return saveWithoutMetadata(pRegistries);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
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.NonNullList;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.*;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
import net.xevianlight.aphelion.screen.TestBlockMenu;
|
||||
import net.xevianlight.aphelion.util.SidedSlotHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TestBlockEntity extends BlockEntity implements MenuProvider {
|
||||
|
||||
private final int SIZE = 1;
|
||||
|
||||
private NonNullList<ItemStack> items = NonNullList.withSize(SIZE, ItemStack.EMPTY);
|
||||
|
||||
public TestBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.TEST_BLOCK_ENTITY.get(), pos, blockState);
|
||||
}
|
||||
|
||||
public final ItemStackHandler inventory = new ItemStackHandler(SIZE) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void tick(Level level, BlockPos pos, BlockState blockState) {
|
||||
inventory.insertItem(0, new ItemStack(Items.DIAMOND), false);
|
||||
|
||||
}
|
||||
|
||||
public void sendUpdate() {
|
||||
setChanged();
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
|
||||
private final IItemHandler topHandler = new SidedSlotHandler(inventory, new int[]{0}, true, false);
|
||||
private final IItemHandler bottomHandler = new SidedSlotHandler(inventory, new int[]{0}, false, true);
|
||||
private final IItemHandler jadeHandler = new SidedSlotHandler(inventory, new int[]{0}, false, false);
|
||||
|
||||
public IItemHandler getItemHandler(Direction direction) {
|
||||
if (direction == Direction.UP) return topHandler;
|
||||
if (direction == Direction.DOWN) return bottomHandler;
|
||||
if (direction == null) return jadeHandler;
|
||||
return null;
|
||||
}
|
||||
|
||||
public ItemStackHandler getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void drops() {
|
||||
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
|
||||
for(int i = 0; i < inventory.getSlots(); i++) {
|
||||
inv.setItem(i, inventory.getStackInSlot(i));
|
||||
}
|
||||
|
||||
Containers.dropContents(this.level, this.worldPosition, inv);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) {
|
||||
pTag.put("inventory", inventory.serializeNBT(pRegistries));
|
||||
super.saveAdditional(pTag, pRegistries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) {
|
||||
super.loadAdditional(pTag, pRegistries);
|
||||
inventory.deserializeNBT(pRegistries, pTag.getCompound("inventory"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getDisplayName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
|
||||
return new TestBlockMenu(i, inventory, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
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.NonNullList;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.*;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TestBlockEntity2 extends BaseContainerBlockEntity implements WorldlyContainer {
|
||||
|
||||
// The constructor, like before.
|
||||
public TestBlockEntity2 (BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.TEST_BLOCK_ENTITY.get(), pos, blockState);
|
||||
}
|
||||
// The container size. This can of course be any value you want.
|
||||
public static final int SIZE = 9;
|
||||
// Our item stack list. This is not final due to #setItems existing.
|
||||
private NonNullList<ItemStack> items = NonNullList.withSize(SIZE, ItemStack.EMPTY);
|
||||
|
||||
// The container size, like before.
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
// The getter for our item stack list.
|
||||
@Override
|
||||
protected NonNullList<ItemStack> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
// The setter for our item stack list.
|
||||
@Override
|
||||
protected void setItems(NonNullList<ItemStack> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
// The display name of the menu. Don't forget to add a translation!
|
||||
@Override
|
||||
protected Component getDefaultName() {
|
||||
return Component.translatable("container.examplemod.myblockentity");
|
||||
}
|
||||
|
||||
// The menu to create from this container. See below for what to return here.
|
||||
@Override
|
||||
protected AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getSlotsForFace(Direction direction) {
|
||||
return new int[] {0,1,2,3,4,5,6,7,8};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItemThroughFace(int i, ItemStack itemStack, @Nullable Direction direction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeItemThroughFace(int i, ItemStack itemStack, Direction direction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAdditional(CompoundTag nbt, HolderLookup.Provider provider) {
|
||||
super.loadAdditional(nbt, provider);
|
||||
this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
|
||||
ContainerHelper.loadAllItems(nbt, this.items, provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider provider) {
|
||||
super.saveAdditional(nbt, provider);
|
||||
ContainerHelper.saveAllItems(nbt, this.items, provider);
|
||||
}
|
||||
|
||||
public void dropContents() {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ItemStack stack = getItem(i);
|
||||
Containers.dropItemStack(level, (double) worldPosition.getX(), (double) worldPosition.getY(), (double) worldPosition.getZ(), stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package net.xevianlight.aphelion.block.entity.energy;
|
||||
|
||||
import net.neoforged.neoforge.energy.EnergyStorage;
|
||||
|
||||
public abstract class ModEnergyStorage extends EnergyStorage {
|
||||
public ModEnergyStorage(int capacity, int maxTransfer) {
|
||||
super(capacity, maxTransfer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
int extractedEnergy = super.extractEnergy(maxExtract, simulate);
|
||||
if(extractedEnergy != 0) {
|
||||
onEnergyChanged();
|
||||
}
|
||||
|
||||
return extractedEnergy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiveEnergy(int maxReceive, boolean simulate) {
|
||||
int receiveEnergy = super.receiveEnergy(maxReceive, simulate);
|
||||
if(receiveEnergy != 0) {
|
||||
onEnergyChanged();
|
||||
}
|
||||
|
||||
return receiveEnergy;
|
||||
}
|
||||
|
||||
public int setEnergy(int energy) {
|
||||
this.energy = energy;
|
||||
return energy;
|
||||
}
|
||||
|
||||
public abstract void onEnergyChanged();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.xevianlight.aphelion.block.entity.energy;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.energy.IEnergyStorage;
|
||||
|
||||
public class ModEnergyUtil {
|
||||
public static boolean move(BlockPos from, BlockPos to, int amount, Level level) {
|
||||
IEnergyStorage fromStorage = level.getCapability(Capabilities.EnergyStorage.BLOCK, from, null);
|
||||
IEnergyStorage toStorage = level.getCapability(Capabilities.EnergyStorage.BLOCK, to, null);
|
||||
|
||||
if(canEnergyStorageExtractThisAmount(fromStorage, amount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(canEnergyStorageStillReceiveEnergy(toStorage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int maxAmountToReceive = toStorage.receiveEnergy(amount, true);
|
||||
|
||||
int extractedEnergy = fromStorage.extractEnergy(maxAmountToReceive, false);
|
||||
toStorage.receiveEnergy(extractedEnergy, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean canEnergyStorageStillReceiveEnergy(IEnergyStorage toStorage) {
|
||||
// No more Energy to draw or cannot extract
|
||||
return toStorage.getEnergyStored() >= toStorage.getMaxEnergyStored() || !toStorage.canReceive();
|
||||
}
|
||||
|
||||
private static boolean canEnergyStorageExtractThisAmount(IEnergyStorage fromStorage, int amount) {
|
||||
// No more Space to receive or cannot receive
|
||||
return fromStorage.getEnergyStored() <= 0 || fromStorage.getEnergyStored() < amount || !fromStorage.canExtract();
|
||||
}
|
||||
|
||||
public static boolean doesBlockHaveEnergyStorage(BlockPos positionToCheck, Level level) {
|
||||
return level.getBlockEntity(positionToCheck) != null
|
||||
&& level.getCapability(Capabilities.EnergyStorage.BLOCK, positionToCheck, null) != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package net.xevianlight.aphelion.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.DimensionSpecialEffects;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.ModContainer;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent;
|
||||
import net.neoforged.neoforge.client.event.RegisterDimensionSpecialEffectsEvent;
|
||||
import net.neoforged.neoforge.client.gui.ConfigurationScreen;
|
||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.client.dimension.AphelionDimensionRenderers;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
// This class will not load on dedicated servers. Accessing client side code from here is safe.
|
||||
@Mod(value = Aphelion.MOD_ID, dist = Dist.CLIENT)
|
||||
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
|
||||
@EventBusSubscriber(modid = Aphelion.MOD_ID, value = Dist.CLIENT)
|
||||
public class AphelionClient {
|
||||
public AphelionClient(ModContainer container) {
|
||||
// Allows NeoForge to create a config screen for this mod's configs.
|
||||
// The config screen is accessed by going to the Mods screen > clicking on your mod > clicking on config.
|
||||
// Do not forget to add translations for your config options to the en_us.json file.
|
||||
container.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
static void onClientSetup(FMLClientSetupEvent event) {
|
||||
// Some client setup code
|
||||
Aphelion.LOGGER.info("HELLO FROM CLIENT SETUP");
|
||||
Aphelion.LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientReloadListeners(RegisterClientReloadListenersEvent event) {
|
||||
onAddReloadListener((id, listener) -> event.registerReloadListener(listener));
|
||||
}
|
||||
|
||||
public static void onAddReloadListener(BiConsumer<ResourceLocation, PreparableReloadListener> consumer) {
|
||||
consumer.accept(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "planet_renderers"), new AphelionDimensionRenderers());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRegisterDimensionEffects(RegisterDimensionSpecialEffectsEvent event) {
|
||||
event.register(
|
||||
ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "space"),
|
||||
new net.xevianlight.aphelion.client.dimension.SpaceSkyEffects()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.xevianlight.extreme_rocketry;
|
||||
package net.xevianlight.aphelion.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -8,7 +8,7 @@ import net.neoforged.neoforge.common.ModConfigSpec;
|
||||
|
||||
// An example config class. This is not required, but it's a good idea to have one to keep your config organized.
|
||||
// Demonstrates how to use Neo's config APIs
|
||||
public class Config {
|
||||
public class AphelionConfig {
|
||||
private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder();
|
||||
|
||||
public static final ModConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER
|
||||
@@ -26,9 +26,9 @@ public class Config {
|
||||
// a list of strings that are treated as resource locations for items
|
||||
public static final ModConfigSpec.ConfigValue<List<? extends String>> ITEM_STRINGS = BUILDER
|
||||
.comment("A list of items to log on common setup.")
|
||||
.defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), () -> "", Config::validateItemName);
|
||||
.defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), () -> "", AphelionConfig::validateItemName);
|
||||
|
||||
static final ModConfigSpec SPEC = BUILDER.build();
|
||||
public static final ModConfigSpec SPEC = BUILDER.build();
|
||||
|
||||
private static boolean validateItemName(final Object obj) {
|
||||
return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName));
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.xevianlight.aphelion.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.client.dimension.DimensionRenderer;
|
||||
import net.xevianlight.aphelion.client.dimension.DimensionRendererCache;
|
||||
import net.xevianlight.aphelion.client.dimension.SpaceSkyEffects;
|
||||
|
||||
@EventBusSubscriber(modid = Aphelion.MOD_ID, value = Dist.CLIENT)
|
||||
public class AphelionDebugOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onDebugText(CustomizeGuiOverlayEvent.DebugText event) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.level == null || mc.player == null) return;
|
||||
|
||||
// Only show in your space dimension (optional)
|
||||
if (!mc.level.dimension().location().equals(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "space"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
var camPos = mc.gameRenderer.getMainCamera().getPosition();
|
||||
ResourceLocation orbitId = SpaceSkyEffects.orbitForPos(camPos);
|
||||
|
||||
DimensionRenderer r = DimensionRendererCache.getOrDefault(orbitId);
|
||||
|
||||
String rendererSummary = (r == null)
|
||||
? "<missing>"
|
||||
: ("customSky=" + r.customSky()
|
||||
+ ", thickFog=" + r.hasThickFog()
|
||||
+ ", fog=" + r.hasFog());
|
||||
|
||||
// Left side of F3
|
||||
event.getLeft().add("");
|
||||
event.getLeft().add("Aphelion:");
|
||||
event.getLeft().add(" Orbit: " + orbitId);
|
||||
event.getLeft().add(" Sky: " + rendererSummary);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package net.xevianlight.aphelion.client.dimension;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.util.Constants;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AphelionDimensionRenderers extends SimpleJsonResourceReloadListener {
|
||||
|
||||
public AphelionDimensionRenderers() {
|
||||
super(Constants.GSON, "dimension_renderers");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(Map<ResourceLocation, JsonElement> object,
|
||||
ResourceManager resourceManager,
|
||||
ProfilerFiller profiler) {
|
||||
|
||||
Map<ResourceLocation, DimensionRenderer> renderers = new HashMap<>();
|
||||
object.forEach((key, value) -> {
|
||||
JsonObject json = GsonHelper.convertToJsonObject(value, "dimension_renderer");
|
||||
DimensionRenderer renderer = DimensionRenderer.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow();
|
||||
|
||||
// IMPORTANT: use the *resource id* of the json as the lookup key
|
||||
// so "effects": "aphelion:space" maps to space.json automatically.
|
||||
renderers.put(key, renderer);
|
||||
});
|
||||
|
||||
DimensionRendererCache.registerPlanetRenderers(renderers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.xevianlight.aphelion.client.dimension;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public record DimensionRenderer(
|
||||
ResourceKey<Level> dimension,
|
||||
boolean customClouds,
|
||||
boolean customSky,
|
||||
boolean customWeather,
|
||||
boolean hasThickFog,
|
||||
boolean hasFog,
|
||||
int sunriseColor,
|
||||
int sunriseAngle,
|
||||
boolean renderInRain,
|
||||
boolean renderVoidFog,
|
||||
double horizonHeight,
|
||||
float clearColorScale
|
||||
) {
|
||||
public static final Codec<DimensionRenderer> CODEC = RecordCodecBuilder.create(inst -> inst.group(
|
||||
ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(DimensionRenderer::dimension),
|
||||
Codec.BOOL.fieldOf("custom_clouds").forGetter(DimensionRenderer::customClouds),
|
||||
Codec.BOOL.fieldOf("custom_sky").forGetter(DimensionRenderer::customSky),
|
||||
Codec.BOOL.fieldOf("custom_weather").forGetter(DimensionRenderer::customWeather),
|
||||
Codec.BOOL.fieldOf("has_thick_fog").forGetter(DimensionRenderer::hasThickFog),
|
||||
Codec.BOOL.fieldOf("has_fog").forGetter(DimensionRenderer::hasFog),
|
||||
Codec.INT.fieldOf("sunrise_color").forGetter(DimensionRenderer::sunriseColor),
|
||||
Codec.INT.fieldOf("sunrise_angle").forGetter(DimensionRenderer::sunriseAngle),
|
||||
Codec.BOOL.fieldOf("render_in_rain").forGetter(DimensionRenderer::renderInRain),
|
||||
Codec.BOOL.fieldOf("render_void_fog").forGetter(DimensionRenderer::renderVoidFog),
|
||||
Codec.DOUBLE.fieldOf("horizon_height").forGetter(DimensionRenderer::horizonHeight),
|
||||
Codec.FLOAT.fieldOf("clear_color_scale").forGetter(DimensionRenderer::clearColorScale)
|
||||
).apply(inst, DimensionRenderer::new));
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.xevianlight.aphelion.client.dimension;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class DimensionRendererCache {
|
||||
|
||||
public static final Map<ResourceLocation, DimensionRenderer> RENDERERS = new HashMap<>();
|
||||
|
||||
public static void registerPlanetRenderers(Map<ResourceLocation, DimensionRenderer> renderers) {
|
||||
RENDERERS.clear();
|
||||
RENDERERS.putAll(renderers);
|
||||
|
||||
}
|
||||
|
||||
public static DimensionRenderer getOrDefault(ResourceLocation id) {
|
||||
return RENDERERS.getOrDefault(id, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package net.xevianlight.aphelion.client.dimension;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.DimensionSpecialEffects;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
public class DimensionSkyEffects extends DimensionSpecialEffects {
|
||||
|
||||
private final ResourceLocation effectsId;
|
||||
|
||||
boolean customSky;
|
||||
|
||||
public DimensionSkyEffects(ResourceLocation effectsId) {
|
||||
super(192, false, SkyType.NORMAL, false, false);
|
||||
this.effectsId = effectsId;
|
||||
}
|
||||
|
||||
private DimensionRenderer renderer() {
|
||||
return DimensionRendererCache.getOrDefault(effectsId);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean renderVoidFog() {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public boolean renderSky(ClientLevel level, int ticks, float partialTick, Matrix4f modelViewMatrix, Camera camera, Matrix4f projectionMatrix, boolean isFoggy, Runnable setupFog) {
|
||||
return super.renderSky(level, ticks, partialTick, modelViewMatrix, camera, projectionMatrix, isFoggy, setupFog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getBrightnessDependentFogColor(Vec3 fogColor, float brightness) {
|
||||
if (renderer().hasFog()) {
|
||||
return fogColor.multiply(
|
||||
brightness * 0.94 + 0.06,
|
||||
brightness * 0.94 + 0.06,
|
||||
brightness * 0.91 + 0.09);
|
||||
}
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoggyAt(int x, int z) {
|
||||
return renderer().hasThickFog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable float[] getSunriseColor(float timeOfDay, float partialTicks) {
|
||||
return new float[]{0,0,0,0};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.client.dimension;
|
||||
|
||||
public class DimensionSkyRenderer {
|
||||
|
||||
DimensionRenderer renderer;
|
||||
|
||||
DimensionSkyRenderer(DimensionRenderer renderer) { this.renderer = renderer; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package net.xevianlight.aphelion.client.dimension;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public record OrbitSkyDefinition(
|
||||
ResourceLocation id,
|
||||
Vec3 skyColor
|
||||
|
||||
) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package net.xevianlight.aphelion.client.dimension;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.DimensionSpecialEffects;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
public class SpaceSkyEffects extends DimensionSpecialEffects {
|
||||
|
||||
public SpaceSkyEffects() {
|
||||
super(192, false, SkyType.NORMAL, false, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean renderSky(ClientLevel level, int ticks, float partialTick, Matrix4f modelViewMatrix, Camera camera, Matrix4f projectionMatrix, boolean isFoggy, Runnable setupFog) {
|
||||
ResourceLocation id = orbitForPos(net.minecraft.client.Minecraft.getInstance()
|
||||
.gameRenderer.getMainCamera().getPosition());
|
||||
// Aphelion.LOGGER.info("Loaded dimension_renderers: {}", DimensionRendererCache.getOrDefault(id).toString());
|
||||
// Return true, meaning we are rendering the sky ourselves. Vanilla will not draw its sky.
|
||||
if (DimensionRendererCache.getOrDefault(id).customSky())
|
||||
return true;
|
||||
return super.renderSky(level, ticks, partialTick, modelViewMatrix, camera, projectionMatrix, isFoggy, setupFog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getBrightnessDependentFogColor(Vec3 fogColor, float brightness) {
|
||||
ResourceLocation id = orbitForPos(net.minecraft.client.Minecraft.getInstance()
|
||||
.gameRenderer.getMainCamera().getPosition());
|
||||
if (DimensionRendererCache.getOrDefault(id).hasFog()) {
|
||||
return fogColor.multiply(
|
||||
brightness * 0.94 + 0.06,
|
||||
brightness * 0.94 + 0.06,
|
||||
brightness * 0.91 + 0.09);
|
||||
}
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoggyAt(int i, int i1) {
|
||||
ResourceLocation id = orbitForPos(net.minecraft.client.Minecraft.getInstance()
|
||||
.gameRenderer.getMainCamera().getPosition());
|
||||
|
||||
return DimensionRendererCache.getOrDefault(id).hasThickFog();
|
||||
}
|
||||
|
||||
public static ResourceLocation orbitForPos(Vec3 pos) {
|
||||
double r = Math.sqrt(pos.x * pos.x + pos.z * pos.z);
|
||||
|
||||
if (r < 100) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/earth");
|
||||
if (r < 200) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/mars");
|
||||
if (r < 300) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/venus");
|
||||
|
||||
return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.xevianlight.aphelion.core.init;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
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.ElectricArcFurnaceEntity;
|
||||
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModBlockEntities {
|
||||
public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITIES = DeferredRegister.create(BuiltInRegistries.BLOCK_ENTITY_TYPE, Aphelion.MOD_ID);
|
||||
|
||||
public static final Supplier<BlockEntityType<TestBlockEntity>> TEST_BLOCK_ENTITY =
|
||||
BLOCK_ENTITIES.register("test_block_entity", () -> BlockEntityType.Builder.of(
|
||||
TestBlockEntity::new, ModBlocks.TEST_BLOCK.get()).build(null)
|
||||
);
|
||||
|
||||
public static final Supplier<BlockEntityType<DimensionChangerBlockEntity>> DIMENSION_CHANGER_BLOCK_ENTITY =
|
||||
BLOCK_ENTITIES.register("dimension_changer_block_entity", () -> BlockEntityType.Builder.of(
|
||||
DimensionChangerBlockEntity::new, ModBlocks.DIMENSION_CHANGER.get()).build(null)
|
||||
);
|
||||
|
||||
public static final Supplier<BlockEntityType<ElectricArcFurnaceEntity>> ELECTRIC_ARC_FURNACE_ENTITY =
|
||||
BLOCK_ENTITIES.register("electric_arc_furnace_block_entity", () -> BlockEntityType.Builder.of(
|
||||
ElectricArcFurnaceEntity::new, ModBlocks.ELECTRIC_ARC_FURNACE.get()).build(null)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.xevianlight.aphelion.core.init;
|
||||
|
||||
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;
|
||||
|
||||
public class ModBlocks {
|
||||
public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(Aphelion.MOD_ID);
|
||||
|
||||
public static final DeferredBlock<Block> TEST_BLOCK = BLOCKS.register("test_block", () -> new TestBlock(TestBlock.getProperties()));
|
||||
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()));
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.xevianlight.aphelion.core.init;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.fluid.ModFluids;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModCreativeTabs {
|
||||
public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TAB = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, Aphelion.MOD_ID);
|
||||
|
||||
public static final Supplier<CreativeModeTab> APHELION_ITEMS_TAB = CREATIVE_MODE_TAB.register("aphelion_items_tab",
|
||||
() -> CreativeModeTab.builder().icon(() -> new ItemStack(ModItems.TEST_ITEM.get()))
|
||||
.title(Component.translatable("creativetab.aphelion.aphelion_items"))
|
||||
.displayItems((itemDisplayParameters, output) -> {
|
||||
output.accept(ModItems.TEST_ITEM);
|
||||
output.accept(ModItems.INGOT_ALUMINUM);
|
||||
output.accept(ModItems.INGOT_STEEL);
|
||||
output.accept(ModItems.INGOT_TITANIUM);
|
||||
output.accept(ModItems.INGOT_URANIUM);
|
||||
output.accept(ModItems.INGOT_COBALT);
|
||||
output.accept(ModItems.INGOT_TUNGSTEN);
|
||||
output.accept(ModItems.INGOT_NEODYMIUM);
|
||||
output.accept(ModItems.INGOT_IRIDIUM);
|
||||
output.accept(ModFluids.OIL_BUCKET);
|
||||
output.accept(ModItems.MUSIC_DISC_BIT_SHIFT);
|
||||
}).build());
|
||||
|
||||
public static final Supplier<CreativeModeTab> APHELION_BLOCKS_TAB = CREATIVE_MODE_TAB.register("aphelion_blocks_tab",
|
||||
() -> CreativeModeTab.builder().icon(() -> new ItemStack(ModItems.TEST_BLOCK.get()))
|
||||
.withTabsBefore(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "aphelion_items_tab"))
|
||||
.title(Component.translatable("creativetab.aphelion.aphelion_blocks"))
|
||||
.displayItems((itemDisplayParameters, output) -> {
|
||||
output.accept(ModItems.TEST_BLOCK);
|
||||
output.accept(ModItems.ELECTRIC_ARC_FURNACE);
|
||||
output.accept(ModItems.BLOCK_STEEL);
|
||||
}).build());
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.xevianlight.aphelion.core.init;
|
||||
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
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.item.*;
|
||||
|
||||
public class ModItems {
|
||||
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(Aphelion.MOD_ID);
|
||||
|
||||
public static final DeferredItem<Item> TEST_ITEM = ITEMS.register("test_item", TestItem::new);
|
||||
public static final DeferredItem<Item> INGOT_ALUMINUM = ITEMS.register("ingot_aluminum", IngotAluminum::new);
|
||||
public static final DeferredItem<Item> INGOT_STEEL = ITEMS.register("ingot_steel", IngotSteel::new);
|
||||
public static final DeferredItem<Item> INGOT_TITANIUM = ITEMS.register("ingot_titanium", IngotTitanium::new);
|
||||
public static final DeferredItem<Item> INGOT_URANIUM = ITEMS.register("ingot_uranium", IngotUranium::new);
|
||||
public static final DeferredItem<Item> INGOT_COBALT = ITEMS.register("ingot_cobalt", IngotCobalt::new);
|
||||
public static final DeferredItem<Item> INGOT_TUNGSTEN = ITEMS.register("ingot_tungsten", IngotTungsten::new);
|
||||
public static final DeferredItem<Item> INGOT_NEODYMIUM = ITEMS.register("ingot_neodymium", IngotNeodymium::new);
|
||||
public static final DeferredItem<Item> INGOT_IRIDIUM = ITEMS.register("ingot_iridium", IngotIridium::new);
|
||||
|
||||
public static final DeferredItem<Item> MUSIC_DISC_BIT_SHIFT = ITEMS.register("music_disc_bit_shift",
|
||||
() -> new Item(new Item.Properties().jukeboxPlayable(ModSounds.BIT_SHIFT_KEY).stacksTo(1).rarity(Rarity.RARE)));
|
||||
|
||||
|
||||
// Block Items
|
||||
|
||||
public static final DeferredItem<BlockItem> TEST_BLOCK = ITEMS.register("test_block", () -> new BlockItem(ModBlocks.TEST_BLOCK.get(), TestBlock.getItemProperties().stacksTo(9999)));
|
||||
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()));
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.xevianlight.aphelion.core.init;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.item.JukeboxSong;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModSounds {
|
||||
public static final DeferredRegister<SoundEvent> SOUND_EVENTS =
|
||||
DeferredRegister.create(Registries.SOUND_EVENT, Aphelion.MOD_ID);
|
||||
|
||||
private static ResourceKey<JukeboxSong> createSong(String name) {
|
||||
return ResourceKey.create(Registries.JUKEBOX_SONG, ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, name));
|
||||
}
|
||||
|
||||
public static final Supplier<SoundEvent> BIT_SHIFT = registerSoundEvent("bit_shift");
|
||||
public static final ResourceKey<JukeboxSong> BIT_SHIFT_KEY = createSong("bit_shift");
|
||||
|
||||
private static Supplier<SoundEvent> registerSoundEvent(String name) {
|
||||
ResourceLocation id = ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, name);
|
||||
return SOUND_EVENTS.register(name, () -> SoundEvent.createVariableRangeEvent(id));
|
||||
}
|
||||
|
||||
public static void register(IEventBus eventBus) {
|
||||
SOUND_EVENTS.register(eventBus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.loot.LootTableProvider;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.common.data.BlockTagsProvider;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import net.neoforged.neoforge.data.event.GatherDataEvent;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@EventBusSubscriber(modid = Aphelion.MOD_ID)
|
||||
public class DataGenerators {
|
||||
@SubscribeEvent
|
||||
public static void gatherData(GatherDataEvent event) {
|
||||
DataGenerator generator = event.getGenerator();
|
||||
PackOutput packOutput = generator.getPackOutput();
|
||||
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
|
||||
CompletableFuture<HolderLookup.Provider> lookupProvider =event.getLookupProvider();
|
||||
|
||||
generator.addProvider(event.includeServer(), new LootTableProvider(packOutput, Collections.emptySet(),
|
||||
List.of(new LootTableProvider.SubProviderEntry(ModBlockLootTableProvider::new, LootContextParamSets.BLOCK)), lookupProvider));
|
||||
|
||||
generator.addProvider(event.includeClient(), new ModItemModelProvider(packOutput, existingFileHelper));
|
||||
generator.addProvider(event.includeClient(), new ModBlockStateProvider(packOutput, existingFileHelper));
|
||||
|
||||
BlockTagsProvider blockTagsProvider = new ModBlockTagProvider(packOutput, lookupProvider, existingFileHelper);
|
||||
generator.addProvider(event.includeServer(), blockTagsProvider);
|
||||
generator.addProvider(event.includeServer(), new ModItemTagProvider(packOutput, lookupProvider, blockTagsProvider.contentsGetter(), existingFileHelper));
|
||||
generator.addProvider(event.includeServer(), new ModFluidTagsProvider(packOutput, lookupProvider, existingFileHelper));
|
||||
|
||||
generator.addProvider(event.includeServer(), new ModRecipeProvider(packOutput, lookupProvider));
|
||||
generator.addProvider(event.includeServer(), new ModDataMapProvider(packOutput, lookupProvider));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.loot.BlockLootSubProvider;
|
||||
import net.minecraft.world.flag.FeatureFlags;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class ModBlockLootTableProvider extends BlockLootSubProvider {
|
||||
protected ModBlockLootTableProvider(HolderLookup.Provider registries) {
|
||||
super(Set.of(), FeatureFlags.REGISTRY.allFlags(), registries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generate() {
|
||||
dropSelf(ModBlocks.TEST_BLOCK.get());
|
||||
dropSelf(ModBlocks.BLOCK_STEEL.get());
|
||||
dropSelf(ModBlocks.DIMENSION_CHANGER.get());
|
||||
dropSelf(ModBlocks.ELECTRIC_ARC_FURNACE.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Block> getKnownBlocks() {
|
||||
return ModBlocks.BLOCKS.getEntries().stream().map(Holder::value)::iterator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.neoforged.neoforge.client.model.generators.BlockStateProvider;
|
||||
import net.neoforged.neoforge.client.model.generators.ModelFile;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import net.neoforged.neoforge.registries.DeferredBlock;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||
|
||||
public class ModBlockStateProvider extends BlockStateProvider {
|
||||
public ModBlockStateProvider(PackOutput output, ExistingFileHelper exFileHelper) {
|
||||
super(output, Aphelion.MOD_ID, exFileHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
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")));
|
||||
blockItem(ModBlocks.ELECTRIC_ARC_FURNACE);
|
||||
|
||||
blockWithItem(ModBlocks.BLOCK_STEEL);
|
||||
blockWithItem(ModBlocks.DIMENSION_CHANGER);
|
||||
}
|
||||
|
||||
private void blockWithItem(DeferredBlock<?> deferredBlock) {
|
||||
simpleBlockWithItem(deferredBlock.get(), cubeAll(deferredBlock.get()));
|
||||
}
|
||||
|
||||
private void blockItem(DeferredBlock<Block> deferredBlock) {
|
||||
simpleBlockItem(deferredBlock.get(), new ModelFile.UncheckedModelFile("aphelion:block/" + deferredBlock.getId().getPath()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.neoforged.neoforge.common.data.BlockTagsProvider;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||
import net.xevianlight.aphelion.util.ModTags;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModBlockTagProvider extends BlockTagsProvider {
|
||||
public ModBlockTagProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, @Nullable ExistingFileHelper existingFileHelper) {
|
||||
super(output, lookupProvider, Aphelion.MOD_ID, existingFileHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTags(HolderLookup.Provider provider) {
|
||||
tag(BlockTags.MINEABLE_WITH_PICKAXE)
|
||||
.add(ModBlocks.TEST_BLOCK.get())
|
||||
.add(ModBlocks.ELECTRIC_ARC_FURNACE.get())
|
||||
.add(ModBlocks.BLOCK_STEEL.get());
|
||||
tag(BlockTags.NEEDS_STONE_TOOL)
|
||||
.add(ModBlocks.TEST_BLOCK.get())
|
||||
.add(ModBlocks.ELECTRIC_ARC_FURNACE.get())
|
||||
.add(ModBlocks.BLOCK_STEEL.get());
|
||||
|
||||
tag(ModTags.Blocks.STORAGE_BLOCKS_STEEL)
|
||||
.add(ModBlocks.BLOCK_STEEL.get());
|
||||
|
||||
tag(ModTags.Blocks.STORAGE_BLOCKS)
|
||||
.add(ModBlocks.BLOCK_STEEL.get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.neoforged.neoforge.common.data.DataMapProvider;
|
||||
import net.neoforged.neoforge.registries.datamaps.builtin.FurnaceFuel;
|
||||
import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps;
|
||||
import net.xevianlight.aphelion.core.init.ModItems;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModDataMapProvider extends DataMapProvider {
|
||||
protected ModDataMapProvider(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> lookupProvider) {
|
||||
super(packOutput, lookupProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void gather(HolderLookup.Provider provider) {
|
||||
this.builder(NeoForgeDataMaps.FURNACE_FUELS)
|
||||
.add(ModItems.TEST_ITEM.getId(), new FurnaceFuel(1200), false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.tags.FluidTagsProvider;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.fluid.ModFluids;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModFluidTagsProvider extends FluidTagsProvider {
|
||||
|
||||
public ModFluidTagsProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> provider, @Nullable ExistingFileHelper existingFileHelper) {
|
||||
super(output, provider, Aphelion.MOD_ID, existingFileHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTags(HolderLookup.Provider provider) {
|
||||
// tag(FluidTags.LAVA)
|
||||
// .add(ModFluids.SOURCE_OIL_FLUID.get())
|
||||
// .add(ModFluids.FLOWING_OIL_FLUID.get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.neoforged.neoforge.client.model.generators.ItemModelProvider;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModItems;
|
||||
import net.xevianlight.aphelion.fluid.ModFluids;
|
||||
|
||||
public class ModItemModelProvider extends ItemModelProvider {
|
||||
public ModItemModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
|
||||
super(output, Aphelion.MOD_ID, existingFileHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerModels() {
|
||||
basicItem(ModItems.TEST_ITEM.get());
|
||||
basicItem(ModItems.INGOT_ALUMINUM.get());
|
||||
basicItem(ModItems.INGOT_STEEL.get());
|
||||
basicItem(ModItems.INGOT_TITANIUM.get());
|
||||
basicItem(ModItems.INGOT_URANIUM.get());
|
||||
basicItem(ModItems.INGOT_COBALT.get());
|
||||
basicItem(ModItems.INGOT_TUNGSTEN.get());
|
||||
basicItem(ModItems.INGOT_NEODYMIUM.get());
|
||||
basicItem(ModItems.INGOT_IRIDIUM.get());
|
||||
|
||||
basicItem(ModFluids.OIL_BUCKET.get());
|
||||
basicItem(ModItems.MUSIC_DISC_BIT_SHIFT.get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.tags.ItemTagsProvider;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModItems;
|
||||
import net.xevianlight.aphelion.util.ModTags;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModItemTagProvider extends ItemTagsProvider {
|
||||
public ModItemTagProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, CompletableFuture<TagLookup<Block>> blockTags, @Nullable ExistingFileHelper existingFileHelper) {
|
||||
super(output, lookupProvider, blockTags, Aphelion.MOD_ID, existingFileHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTags(HolderLookup.Provider provider) {
|
||||
tag(ModTags.Items.TEST_TAG)
|
||||
.add(ModItems.TEST_ITEM.get());
|
||||
|
||||
tag(ModTags.Items.INGOTS)
|
||||
.add(ModItems.INGOT_ALUMINUM.get())
|
||||
.add(ModItems.INGOT_STEEL.get())
|
||||
.add(ModItems.INGOT_TITANIUM.get())
|
||||
.add(ModItems.INGOT_URANIUM.get())
|
||||
.add(ModItems.INGOT_COBALT.get())
|
||||
.add(ModItems.INGOT_TUNGSTEN.get())
|
||||
.add(ModItems.INGOT_NEODYMIUM.get())
|
||||
.add(ModItems.INGOT_IRIDIUM.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_ALUMINUM)
|
||||
.add(ModItems.INGOT_ALUMINUM.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_STEEL)
|
||||
.add(ModItems.INGOT_STEEL.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_TITANIUM)
|
||||
.add(ModItems.INGOT_TITANIUM.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_URANIUM)
|
||||
.add(ModItems.INGOT_URANIUM.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_COBALT)
|
||||
.add(ModItems.INGOT_COBALT.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_TUNGSTEN)
|
||||
.add(ModItems.INGOT_TUNGSTEN.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_NEODYMIUM)
|
||||
.add(ModItems.INGOT_NEODYMIUM.get());
|
||||
|
||||
tag(ModTags.Items.INGOT_IRIDIUM)
|
||||
.add(ModItems.INGOT_IRIDIUM.get());
|
||||
|
||||
|
||||
tag(ModTags.Items.STORAGE_BLOCKS)
|
||||
.add(ModItems.BLOCK_STEEL.get());
|
||||
|
||||
tag(ModTags.Items.STORAGE_BLOCKS_STEEL)
|
||||
.add(ModItems.BLOCK_STEEL.get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package net.xevianlight.aphelion.datagen;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.recipes.*;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.*;
|
||||
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.neoforged.neoforge.common.conditions.IConditionBuilder;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||
import net.xevianlight.aphelion.core.init.ModItems;
|
||||
import net.xevianlight.aphelion.util.ModTags;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModRecipeProvider extends RecipeProvider implements IConditionBuilder {
|
||||
public ModRecipeProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries) {
|
||||
super(output, registries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildRecipes(RecipeOutput recipeOutput) {
|
||||
|
||||
List<ItemLike> TEST_SMELTABLES = List.of(ModItems.TEST_ITEM, ModBlocks.TEST_BLOCK);
|
||||
|
||||
|
||||
//TEST BLOCK
|
||||
ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ModBlocks.TEST_BLOCK.get())
|
||||
.pattern("TTT")
|
||||
.pattern("TTT")
|
||||
.pattern("TTT")
|
||||
.define('T', ModItems.TEST_ITEM.get())
|
||||
.unlockedBy("has_test_item", has(ModItems.TEST_ITEM)).save(recipeOutput, "aphelion:test_shaped_recipe");
|
||||
|
||||
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItems.TEST_ITEM.get(), 9)
|
||||
.requires(ModBlocks.TEST_BLOCK)
|
||||
.unlockedBy("has_test_block", has(ModBlocks.TEST_BLOCK)).save(recipeOutput, "aphelion:test_shapeless_recipe");
|
||||
|
||||
//STEEL BLOCK
|
||||
ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ModBlocks.BLOCK_STEEL.get())
|
||||
.pattern("III")
|
||||
.pattern("III")
|
||||
.pattern("III")
|
||||
.define('I', ModTags.Items.INGOT_STEEL)
|
||||
.unlockedBy("has_steel_ingot", has(ModItems.INGOT_ALUMINUM)).save(recipeOutput, "aphelion:steel_to_block");
|
||||
|
||||
|
||||
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItems.INGOT_STEEL.get(), 9)
|
||||
.requires(ModBlocks.BLOCK_STEEL)
|
||||
.unlockedBy("has_steel_block", has(ModBlocks.BLOCK_STEEL)).save(recipeOutput, "aphelion:steel_to_ingot");
|
||||
|
||||
oreSmelting(recipeOutput, TEST_SMELTABLES, RecipeCategory.MISC, Items.IRON_INGOT, 0.25f, 200, "test");
|
||||
}
|
||||
|
||||
|
||||
protected static void oreSmelting(RecipeOutput recipeOutput, List<ItemLike> pIngredients, RecipeCategory pCategory, ItemLike pResult,
|
||||
float pExperience, int pCookingTIme, String pGroup) {
|
||||
oreCooking(recipeOutput, RecipeSerializer.SMELTING_RECIPE, SmeltingRecipe::new, pIngredients, pCategory, pResult,
|
||||
pExperience, pCookingTIme, pGroup, "_from_smelting");
|
||||
}
|
||||
|
||||
protected static void oreBlasting(RecipeOutput recipeOutput, List<ItemLike> pIngredients, RecipeCategory pCategory, ItemLike pResult,
|
||||
float pExperience, int pCookingTime, String pGroup) {
|
||||
oreCooking(recipeOutput, RecipeSerializer.BLASTING_RECIPE, BlastingRecipe::new, pIngredients, pCategory, pResult,
|
||||
pExperience, pCookingTime, pGroup, "_from_blasting");
|
||||
}
|
||||
|
||||
protected static <T extends AbstractCookingRecipe> void oreCooking(RecipeOutput recipeOutput, RecipeSerializer<T> pCookingSerializer, AbstractCookingRecipe.Factory<T> factory,
|
||||
List<ItemLike> pIngredients, RecipeCategory pCategory, ItemLike pResult, float pExperience, int pCookingTime, String pGroup, String pRecipeName) {
|
||||
for(ItemLike itemlike : pIngredients) {
|
||||
SimpleCookingRecipeBuilder.generic(Ingredient.of(itemlike), pCategory, pResult, pExperience, pCookingTime, pCookingSerializer, factory).group(pGroup).unlockedBy(getHasName(itemlike), has(itemlike))
|
||||
.save(recipeOutput, Aphelion.MOD_ID + ":" + getItemName(pResult) + pRecipeName + "_" + getItemName(itemlike));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.xevianlight.aphelion.event;
|
||||
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
|
||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||
|
||||
@EventBusSubscriber(modid = Aphelion.MOD_ID)
|
||||
public class ModBusEvents {
|
||||
@SubscribeEvent
|
||||
public static void registerCapabilities(RegisterCapabilitiesEvent event) {
|
||||
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.TEST_BLOCK_ENTITY.get(), TestBlockEntity::getItemHandler);
|
||||
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.ELECTRIC_ARC_FURNACE_ENTITY.get(), ElectricArcFurnaceEntity::getItemHandler);
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.ELECTRIC_ARC_FURNACE_ENTITY.get(), ElectricArcFurnaceEntity::getEnergyStorage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package net.xevianlight.aphelion.fluid;
|
||||
|
||||
|
||||
import com.mojang.blaze3d.shaders.FogShape;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import net.neoforged.neoforge.fluids.FluidType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
* Basic implementation of {@link FluidType} that supports specifying still and flowing textures in the constructor.
|
||||
*
|
||||
* @author Choonster (<a href="https://github.com/Choonster-Minecraft-Mods/TestMod3/blob/1.19.x/LICENSE.txt">MIT License</a>)
|
||||
* Change by: Kaupenjoe
|
||||
* Added overlayTexture and tintColor as well. Also converts tint color into fog color
|
||||
*/
|
||||
public class BaseFluidType extends FluidType {
|
||||
private final ResourceLocation stillTexture;
|
||||
private final ResourceLocation flowingTexture;
|
||||
private final ResourceLocation overlayTexture;
|
||||
private final int tintColor;
|
||||
private final Vector3f fogColor;
|
||||
private float fogStart;
|
||||
private float fogEnd;
|
||||
|
||||
public BaseFluidType(final ResourceLocation stillTexture, final ResourceLocation flowingTexture, final ResourceLocation overlayTexture,
|
||||
final int tintColor, final Vector3f fogColor, final Properties properties) {
|
||||
super(properties);
|
||||
this.stillTexture = stillTexture;
|
||||
this.flowingTexture = flowingTexture;
|
||||
this.overlayTexture = overlayTexture;
|
||||
this.tintColor = tintColor;
|
||||
this.fogColor = fogColor;
|
||||
fogStart = 1f;
|
||||
fogEnd = 6f;
|
||||
}
|
||||
|
||||
public BaseFluidType(final ResourceLocation stillTexture, final ResourceLocation flowingTexture, final ResourceLocation overlayTexture,
|
||||
final int tintColor, final Vector3f fogColor, final Properties properties, float fogStart, float fogEnd) {
|
||||
super(properties);
|
||||
this.stillTexture = stillTexture;
|
||||
this.flowingTexture = flowingTexture;
|
||||
this.overlayTexture = overlayTexture;
|
||||
this.tintColor = tintColor;
|
||||
this.fogColor = fogColor;
|
||||
this.fogStart = fogStart;
|
||||
this.fogEnd = fogEnd;
|
||||
}
|
||||
|
||||
public IClientFluidTypeExtensions getClientFluidTypeExtensions() {
|
||||
return new IClientFluidTypeExtensions() {
|
||||
@Override
|
||||
public ResourceLocation getStillTexture() {
|
||||
return stillTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture() {
|
||||
return flowingTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ResourceLocation getOverlayTexture() {
|
||||
return overlayTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTintColor() {
|
||||
return tintColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Vector3f modifyFogColor(Camera camera, float partialTick, ClientLevel level,
|
||||
int renderDistance, float darkenWorldAmount, Vector3f fluidFogColor) {
|
||||
return fogColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyFogRender(Camera camera, FogRenderer.FogMode mode, float renderDistance, float partialTick,
|
||||
float nearDistance, float farDistance, FogShape shape) {
|
||||
RenderSystem.setShaderFogStart(fogStart);
|
||||
RenderSystem.setShaderFogEnd(fogEnd); // distance when the fog starts
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.xevianlight.aphelion.fluid;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.fluids.FluidType;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.neoforged.neoforge.registries.NeoForgeRegistries;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModFluidTypes {
|
||||
public static final ResourceLocation WATER_STILL_RL = ResourceLocation.parse("block/water_still");
|
||||
public static final ResourceLocation WATER_FLOWING_RL = ResourceLocation.parse("block/water_flow");
|
||||
public static final ResourceLocation WATER_OVERLAY_RL = ResourceLocation.parse("block/water_overlay");
|
||||
|
||||
public static final DeferredRegister<FluidType> FLUID_TYPES =
|
||||
DeferredRegister.create(NeoForgeRegistries.Keys.FLUID_TYPES, Aphelion.MOD_ID);
|
||||
|
||||
public static final Supplier<FluidType> OIL_FLUID_TYPE = registerFluidType("oil",
|
||||
new BaseFluidType(WATER_STILL_RL, WATER_FLOWING_RL, WATER_OVERLAY_RL, 0xFF101010,
|
||||
new Vector3f(10f / 255f, 10f / 255f, 10f / 255f),
|
||||
FluidType.Properties.create().canDrown(true), 0f, 2f
|
||||
)
|
||||
);
|
||||
|
||||
private static Supplier<FluidType> registerFluidType(String name, FluidType fluidType) {
|
||||
return FLUID_TYPES.register(name, () -> fluidType);
|
||||
}
|
||||
|
||||
public static void register(IEventBus eventBus) {
|
||||
FLUID_TYPES.register(eventBus);
|
||||
}
|
||||
}
|
||||
46
src/main/java/net/xevianlight/aphelion/fluid/ModFluids.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package net.xevianlight.aphelion.fluid;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.item.BucketItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.fluids.BaseFlowingFluid;
|
||||
import net.neoforged.neoforge.registries.DeferredBlock;
|
||||
import net.neoforged.neoforge.registries.DeferredItem;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||
import net.xevianlight.aphelion.core.init.ModItems;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModFluids {
|
||||
public static final DeferredRegister<Fluid> FLUIDS =
|
||||
DeferredRegister.create(BuiltInRegistries.FLUID, Aphelion.MOD_ID);
|
||||
|
||||
public static final Supplier<FlowingFluid> SOURCE_OIL_FLUID = FLUIDS.register("oil",
|
||||
() -> new BaseFlowingFluid.Source(ModFluids.OIL_PROPERTIES));
|
||||
public static final Supplier<FlowingFluid> FLOWING_OIL_FLUID = FLUIDS.register("flowing_oil",
|
||||
() -> new BaseFlowingFluid.Flowing(ModFluids.OIL_PROPERTIES));
|
||||
|
||||
public static final DeferredBlock<LiquidBlock> OIL_BLOCK = ModBlocks.BLOCKS.register("oil",
|
||||
() -> new LiquidBlock(ModFluids.SOURCE_OIL_FLUID.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable()));
|
||||
|
||||
public static final DeferredItem<Item> OIL_BUCKET = ModItems.ITEMS.registerItem("oil_bucket",
|
||||
properties -> new BucketItem(ModFluids.SOURCE_OIL_FLUID.get(), properties.stacksTo(1).craftRemainder(Items.BUCKET)));
|
||||
|
||||
public static final BaseFlowingFluid.Properties OIL_PROPERTIES = new BaseFlowingFluid.Properties(
|
||||
ModFluidTypes.OIL_FLUID_TYPE, SOURCE_OIL_FLUID, FLOWING_OIL_FLUID)
|
||||
.slopeFindDistance(2).levelDecreasePerBlock(2).tickRate(10)
|
||||
.block(ModFluids.OIL_BLOCK).bucket(ModFluids.OIL_BUCKET);
|
||||
|
||||
public static void register(IEventBus eventBus) {
|
||||
FLUIDS.register(eventBus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotAluminum extends Item {
|
||||
public IngotAluminum() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotCobalt extends Item {
|
||||
public IngotCobalt() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotIridium extends Item {
|
||||
public IngotIridium() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotNeodymium extends Item {
|
||||
public IngotNeodymium() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotSteel extends Item {
|
||||
public IngotSteel() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotTitanium extends Item {
|
||||
public IngotTitanium() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotTungsten extends Item {
|
||||
public IngotTungsten() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class IngotUranium extends Item {
|
||||
public IngotUranium() {
|
||||
super(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.xevianlight.extreme_rocketry.item;
|
||||
package net.xevianlight.aphelion.item;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package net.xevianlight.aphelion.mixins.common;
|
||||
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.xevianlight.aphelion.client.dimension.DimensionRendererCache;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ClientLevel.ClientLevelData.class)
|
||||
public abstract class ClientLevelMixin {
|
||||
|
||||
@Inject(method = "getHorizonHeight", at = @At("HEAD"), cancellable = true)
|
||||
private void aphelion$horizonHeight(LevelHeightAccessor level, CallbackInfoReturnable<Double> cir) {
|
||||
var mc = Minecraft.getInstance();
|
||||
var clientLevel = mc.level;
|
||||
if (clientLevel == null) return;
|
||||
|
||||
// effectsLocation is what your dimension JSON sets in "effects"
|
||||
ResourceLocation effectsId = clientLevel.dimensionType().effectsLocation();
|
||||
|
||||
var i = DimensionRendererCache.getOrDefault(effectsId);
|
||||
|
||||
cir.setReturnValue((i == null) ? 1.0F : i.horizonHeight());
|
||||
}
|
||||
|
||||
@Inject(method = "getClearColorScale", at = @At("HEAD"), cancellable = true)
|
||||
private void aphelion$clearColorScale(CallbackInfoReturnable<Float> cir) {
|
||||
var mc = Minecraft.getInstance();
|
||||
var clientLevel = mc.level;
|
||||
if (clientLevel == null) return;
|
||||
|
||||
ResourceLocation effectsId = clientLevel.dimensionType().effectsLocation();
|
||||
|
||||
var i = DimensionRendererCache.getOrDefault(effectsId);
|
||||
|
||||
cir.setReturnValue((i == null) ? 1.0F : i.clearColorScale());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.xevianlight.aphelion.mixins.common;
|
||||
|
||||
import net.minecraft.client.renderer.DimensionSpecialEffects;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.xevianlight.aphelion.client.dimension.DimensionRendererCache;
|
||||
import net.xevianlight.aphelion.client.dimension.DimensionSkyEffects;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(DimensionSpecialEffects.class)
|
||||
public abstract class DimensionSpecialEffectsMixin {
|
||||
|
||||
@Inject(method = "forType", at = @At("HEAD"), cancellable = true)
|
||||
private static void aphelion$forType(DimensionType type, CallbackInfoReturnable<DimensionSpecialEffects> cir) {
|
||||
ResourceLocation effectsId = type.effectsLocation();
|
||||
|
||||
if (DimensionRendererCache.RENDERERS.containsKey(effectsId)) {
|
||||
cir.setReturnValue(new DimensionSkyEffects(effectsId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package net.xevianlight.aphelion.screen;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
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.inventory.SimpleContainerData;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||
import net.xevianlight.aphelion.util.EnergyItemSlot;
|
||||
import net.xevianlight.aphelion.util.ExtractOnlySlot;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
||||
|
||||
public final ElectricArcFurnaceEntity blockEntity;
|
||||
private final Level level;
|
||||
private final ContainerData data;
|
||||
|
||||
public ElectricArcFurnaceMenu(int i, Inventory inventory, FriendlyByteBuf extraData) {
|
||||
this(i, inventory, inventory.player.level().getBlockEntity(extraData.readBlockPos()), new SimpleContainerData(4));
|
||||
}
|
||||
|
||||
public ElectricArcFurnaceMenu(int i, Inventory inventory, BlockEntity blockEntity, ContainerData data) {
|
||||
super(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), i);
|
||||
this.blockEntity = ((ElectricArcFurnaceEntity) blockEntity);
|
||||
this.level = inventory.player.level();
|
||||
this.data = data;
|
||||
|
||||
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));
|
||||
|
||||
addDataSlots(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
|
||||
// must assign a slot number to each of the slots used by the GUI.
|
||||
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
|
||||
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
|
||||
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
|
||||
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
|
||||
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
|
||||
private static final int HOTBAR_SLOT_COUNT = 9;
|
||||
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
|
||||
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
|
||||
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
|
||||
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
|
||||
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
|
||||
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
|
||||
|
||||
// THIS YOU HAVE TO DEFINE!
|
||||
private static final int TE_INVENTORY_SLOT_COUNT = 3; // must be the number of slots you have!
|
||||
@Override
|
||||
public @NotNull ItemStack quickMoveStack(Player playerIn, int pIndex) {
|
||||
Slot sourceSlot = slots.get(pIndex);
|
||||
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
|
||||
ItemStack sourceStack = sourceSlot.getItem();
|
||||
ItemStack copyOfSourceStack = sourceStack.copy();
|
||||
|
||||
// Check if the slot clicked is one of the vanilla container slots
|
||||
if (pIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
|
||||
// This is a vanilla container slot so merge the stack into the tile inventory
|
||||
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
|
||||
+ TE_INVENTORY_SLOT_COUNT, false)) {
|
||||
blockEntity.sendUpdate();
|
||||
return ItemStack.EMPTY; // EMPTY_ITEM
|
||||
}
|
||||
} else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
|
||||
// This is a TE slot so merge the stack into the players inventory
|
||||
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
|
||||
blockEntity.sendUpdate();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else {
|
||||
System.out.println("Invalid slotIndex:" + pIndex);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
// If stack size == 0 (the entire stack was moved) set slot contents to null
|
||||
if (sourceStack.getCount() == 0) {
|
||||
sourceSlot.set(ItemStack.EMPTY);
|
||||
blockEntity.sendUpdate();
|
||||
} else {
|
||||
blockEntity.sendUpdate();
|
||||
sourceSlot.setChanged();
|
||||
}
|
||||
sourceSlot.onTake(playerIn, sourceStack);
|
||||
blockEntity.sendUpdate();
|
||||
return copyOfSourceStack;
|
||||
}
|
||||
|
||||
public int getScaledArrowProgress() {
|
||||
int progress = this.data.get(0);
|
||||
int maxProgress = this.data.get(1);
|
||||
int arrowPixelSize = 24;
|
||||
|
||||
return maxProgress != 0 && progress != 0 ? progress * arrowPixelSize / maxProgress : 0;
|
||||
}
|
||||
|
||||
private void addPlayerInventory(Inventory playerInventory) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int l = 0; l < 9; ++l) {
|
||||
this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 84 + i * 18));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addPlayerHotbar(Inventory playerInventory) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package net.xevianlight.aphelion.screen;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.screen.renderer.EnergyDisplayTooltipArea;
|
||||
import net.xevianlight.aphelion.util.MouseUtil;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class ElectricArcFurnaceScreen extends AbstractContainerScreen<ElectricArcFurnaceMenu> {
|
||||
|
||||
private static final ResourceLocation GUI_TEXTURE =
|
||||
ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "textures/gui/electric_arc_furnace/gui.png");
|
||||
private static final ResourceLocation ARROW_TEXTURE =
|
||||
ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID,"textures/gui/base/arrow_progress.png");
|
||||
|
||||
private EnergyDisplayTooltipArea energyInfoArea;
|
||||
|
||||
public ElectricArcFurnaceScreen(ElectricArcFurnaceMenu menu, Inventory playerInventory, Component title) {
|
||||
super(menu, playerInventory, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
// Gets rid of labels
|
||||
this.inventoryLabelY = 73;
|
||||
this.titleLabelY = 5;
|
||||
this.titleLabelX = 35;
|
||||
|
||||
assignEnergyInfoArea();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.setShaderTexture(0, GUI_TEXTURE);
|
||||
int x = (width - imageWidth) / 2;
|
||||
int y = (height - imageHeight) / 2;
|
||||
|
||||
guiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
renderProgressArrow(guiGraphics, x, y);
|
||||
if (menu.blockEntity.getBlockState().getValue(BlockStateProperties.LIT)) {
|
||||
guiGraphics.blit(GUI_TEXTURE, x + 54, y + 14, 176, 75, 13, 18);
|
||||
}
|
||||
|
||||
renderEnergyBar(guiGraphics, x , y);
|
||||
}
|
||||
|
||||
private void renderProgressArrow(GuiGraphics guiGraphics, int x, int y) {
|
||||
guiGraphics.blit(ARROW_TEXTURE,x + 88, y + 35, 0, 0, menu.getScaledArrowProgress(), 16, 24, 16);
|
||||
}
|
||||
|
||||
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
||||
int stored = menu.blockEntity.getEnergyStorage(null).getEnergyStored();
|
||||
int max = menu.blockEntity.getEnergyStorage(null).getMaxEnergyStored();
|
||||
|
||||
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
||||
h = Math.max(0, Math.min(42, h));
|
||||
int w = 14;
|
||||
|
||||
int drawX = x + 9;
|
||||
int drawY = y + 9 + (42 - h); // move up as it fills
|
||||
int u = 176;
|
||||
int v = 15 + (42 - h); // sample lower part of bar texture
|
||||
|
||||
guiGraphics.blit(GUI_TEXTURE, drawX, drawY, u, v, w, h);
|
||||
}
|
||||
|
||||
private void assignEnergyInfoArea() {
|
||||
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
||||
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getEnergyStorage(null), 14, 42);
|
||||
}
|
||||
|
||||
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
||||
if(isMouseAboveArea(pMouseX, pMouseY, x, y, 9, 9, 14, 42)) {
|
||||
guiGraphics.renderTooltip(this.font, energyInfoArea.getTooltips(),
|
||||
Optional.empty(), pMouseX - x, pMouseY - y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) {
|
||||
renderBackground(guiGraphics, mouseX, mouseY, delta);
|
||||
super.render(guiGraphics, mouseX, mouseY, delta);
|
||||
renderTooltip(guiGraphics, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) {
|
||||
super.renderLabels(guiGraphics, mouseX, mouseY);
|
||||
int x = (width - imageWidth) / 2;
|
||||
int y = (height - imageHeight) / 2;
|
||||
|
||||
renderEnergyAreaTooltip(guiGraphics, mouseX, mouseY, x, y);
|
||||
}
|
||||
|
||||
public static boolean isMouseAboveArea(int pMouseX, int pMouseY, int x, int y, int offsetX, int offsetY, int width, int height) {
|
||||
return MouseUtil.isMouseOver(pMouseX, pMouseY, x + offsetX, y + offsetY, width, height);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.xevianlight.aphelion.screen;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
|
||||
import net.neoforged.neoforge.network.IContainerFactory;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
|
||||
public class ModMenuTypes {
|
||||
public static final DeferredRegister<MenuType<?>> MENUS =
|
||||
DeferredRegister.create(Registries.MENU, Aphelion.MOD_ID);
|
||||
|
||||
public static DeferredHolder<MenuType<?>,MenuType<TestBlockMenu>> TEST_BLOCK_MENU =
|
||||
registerMenuType("test_block_menu", TestBlockMenu::new);
|
||||
public static DeferredHolder<MenuType<?>,MenuType<ElectricArcFurnaceMenu>> ELECTRIC_ARC_FURNACE_MENU =
|
||||
registerMenuType("electric_arc_furnace_menu", ElectricArcFurnaceMenu::new);
|
||||
|
||||
private static <T extends AbstractContainerMenu>DeferredHolder<MenuType<?>, MenuType<T>> registerMenuType(String name,
|
||||
IContainerFactory<T> factory) {
|
||||
return MENUS.register(name, () -> IMenuTypeExtension.create(factory));
|
||||
}
|
||||
|
||||
public static void register(IEventBus eventBus) {
|
||||
MENUS.register(eventBus);
|
||||
}
|
||||
}
|
||||
107
src/main/java/net/xevianlight/aphelion/screen/TestBlockMenu.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package net.xevianlight.aphelion.screen;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
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.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TestBlockMenu extends AbstractContainerMenu {
|
||||
public final TestBlockEntity blockEntity;
|
||||
private final Level level;
|
||||
|
||||
public TestBlockMenu(int i, Inventory inventory, FriendlyByteBuf extraData) {
|
||||
this(i, inventory, inventory.player.level().getBlockEntity(extraData.readBlockPos()));
|
||||
}
|
||||
|
||||
public TestBlockMenu(int i, Inventory inventory, BlockEntity blockEntity) {
|
||||
super(ModMenuTypes.TEST_BLOCK_MENU.get(), i);
|
||||
this.blockEntity = ((TestBlockEntity) blockEntity);
|
||||
this.level = inventory.player.level();
|
||||
|
||||
addPlayerInventory(inventory);
|
||||
addPlayerHotbar(inventory);
|
||||
|
||||
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, 0, 80, 35));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
|
||||
// must assign a slot number to each of the slots used by the GUI.
|
||||
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
|
||||
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
|
||||
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
|
||||
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
|
||||
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
|
||||
private static final int HOTBAR_SLOT_COUNT = 9;
|
||||
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
|
||||
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
|
||||
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
|
||||
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
|
||||
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
|
||||
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
|
||||
|
||||
// THIS YOU HAVE TO DEFINE!
|
||||
private static final int TE_INVENTORY_SLOT_COUNT = 1; // must be the number of slots you have!
|
||||
@Override
|
||||
public @NotNull ItemStack quickMoveStack(Player playerIn, int pIndex) {
|
||||
Slot sourceSlot = slots.get(pIndex);
|
||||
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
|
||||
ItemStack sourceStack = sourceSlot.getItem();
|
||||
ItemStack copyOfSourceStack = sourceStack.copy();
|
||||
|
||||
// Check if the slot clicked is one of the vanilla container slots
|
||||
if (pIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
|
||||
// This is a vanilla container slot so merge the stack into the tile inventory
|
||||
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
|
||||
+ TE_INVENTORY_SLOT_COUNT, false)) {
|
||||
blockEntity.sendUpdate();
|
||||
return ItemStack.EMPTY; // EMPTY_ITEM
|
||||
}
|
||||
} else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
|
||||
// This is a TE slot so merge the stack into the players inventory
|
||||
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
|
||||
blockEntity.sendUpdate();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else {
|
||||
System.out.println("Invalid slotIndex:" + pIndex);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
// If stack size == 0 (the entire stack was moved) set slot contents to null
|
||||
if (sourceStack.getCount() == 0) {
|
||||
sourceSlot.set(ItemStack.EMPTY);
|
||||
blockEntity.sendUpdate();
|
||||
} else {
|
||||
blockEntity.sendUpdate();
|
||||
sourceSlot.setChanged();
|
||||
}
|
||||
sourceSlot.onTake(playerIn, sourceStack);
|
||||
blockEntity.sendUpdate();
|
||||
return copyOfSourceStack;
|
||||
}
|
||||
|
||||
private void addPlayerInventory(Inventory playerInventory) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int l = 0; l < 9; ++l) {
|
||||
this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 84 + i * 18));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addPlayerHotbar(Inventory playerInventory) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.xevianlight.aphelion.screen;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
|
||||
public class TestBlockScreen extends AbstractContainerScreen<TestBlockMenu> {
|
||||
|
||||
private static final ResourceLocation GUI_TEXTURE =
|
||||
ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "textures/gui/test_block/gui.png");
|
||||
|
||||
public TestBlockScreen(TestBlockMenu menu, Inventory playerInventory, Component title) {
|
||||
super(menu, playerInventory, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
// Gets rid of labels
|
||||
this.inventoryLabelY = 73;
|
||||
this.titleLabelY = 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.setShaderTexture(0, GUI_TEXTURE);
|
||||
int x = (width - imageWidth) / 2;
|
||||
int y = (height - imageHeight) / 2;
|
||||
|
||||
pGuiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) {
|
||||
renderBackground(guiGraphics, mouseX, mouseY, delta);
|
||||
super.render(guiGraphics, mouseX, mouseY, delta);
|
||||
renderTooltip(guiGraphics, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.xevianlight.aphelion.screen.renderer;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.neoforged.neoforge.energy.IEnergyStorage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* BluSunrize
|
||||
* Copyright (c) 2021
|
||||
*
|
||||
* This code is licensed under "Blu's License of Common Sense"
|
||||
* https://github.com/BluSunrize/ImmersiveEngineering/blob/1.19.2/LICENSE
|
||||
*
|
||||
* Slightly Modified Version by: Kaupenjoe
|
||||
*/
|
||||
public class EnergyDisplayTooltipArea {
|
||||
private final int xPos;
|
||||
private final int yPos;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final IEnergyStorage energy;
|
||||
|
||||
public EnergyDisplayTooltipArea(int xMin, int yMin, IEnergyStorage energy) {
|
||||
this(xMin, yMin, energy,8,64);
|
||||
}
|
||||
|
||||
public EnergyDisplayTooltipArea(int xMin, int yMin, IEnergyStorage energy, int width, int height) {
|
||||
xPos = xMin;
|
||||
yPos = yMin;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.energy = energy;
|
||||
}
|
||||
|
||||
public List<Component> getTooltips() {
|
||||
return List.of(Component.literal(energy.getEnergyStored()+" / "+energy.getMaxEnergyStored()+" FE"));
|
||||
}
|
||||
|
||||
public void render(GuiGraphics guiGraphics) {
|
||||
int stored = (int)(height * (energy.getEnergyStored() / (float)energy.getMaxEnergyStored()));
|
||||
guiGraphics.fillGradient(xPos,yPos + (height - stored),xPos + width,
|
||||
yPos + height,0xffb51500, 0xff600b00);
|
||||
}
|
||||
}
|
||||
12
src/main/java/net/xevianlight/aphelion/util/Constants.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package net.xevianlight.aphelion.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class Constants {
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final Gson GSON = new Gson();
|
||||
public static final Gson PRETTY_GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.xevianlight.aphelion.util;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||
|
||||
public class EnergyItemSlot extends SlotItemHandler {
|
||||
public EnergyItemSlot(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
|
||||
super(itemHandler, index, xPosition, yPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
if (stack.getCapability(Capabilities.EnergyStorage.ITEM) != null)
|
||||
return stack.getCapability(Capabilities.EnergyStorage.ITEM).canExtract();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.xevianlight.aphelion.util;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||
|
||||
public class ExtractOnlySlot extends SlotItemHandler {
|
||||
public ExtractOnlySlot(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
|
||||
super(itemHandler, index, xPosition, yPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
49
src/main/java/net/xevianlight/aphelion/util/ModTags.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package net.xevianlight.aphelion.util;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
|
||||
public class ModTags {
|
||||
public static class Blocks {
|
||||
private static TagKey<Block> createTag(String name) {
|
||||
return BlockTags.create(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, name));
|
||||
}
|
||||
|
||||
public static final TagKey<Block> STORAGE_BLOCKS = commonTag("storage_blocks");
|
||||
public static final TagKey<Block> STORAGE_BLOCKS_STEEL = commonTag("storage_blocks/steel");
|
||||
|
||||
private static TagKey<Block> commonTag(String name) {
|
||||
return BlockTags.create(ResourceLocation.fromNamespaceAndPath("c", name));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Items {
|
||||
public static final TagKey<Item> TEST_TAG = createTag("test_tag");
|
||||
public static final TagKey<Item> INGOTS = commonTag("ingots");
|
||||
|
||||
public static final TagKey<Item> STORAGE_BLOCKS = commonTag("storage_blocks");
|
||||
public static final TagKey<Item> STORAGE_BLOCKS_STEEL = commonTag("storage_blocks/steel");
|
||||
public static final TagKey<Item> INGOT_ALUMINUM = commonTag("ingots/aluminum");
|
||||
public static final TagKey<Item> INGOT_STEEL = commonTag("ingots/steel");
|
||||
public static final TagKey<Item> INGOT_TITANIUM = commonTag("ingots/titanium");
|
||||
public static final TagKey<Item> INGOT_URANIUM = commonTag("ingots/uranium");
|
||||
public static final TagKey<Item> INGOT_COBALT = commonTag("ingots/cobalt");
|
||||
public static final TagKey<Item> INGOT_TUNGSTEN = commonTag("ingots/tungsten");
|
||||
public static final TagKey<Item> INGOT_NEODYMIUM = commonTag("ingots/neodymium");
|
||||
public static final TagKey<Item> INGOT_IRIDIUM = commonTag("ingots/iridium");
|
||||
|
||||
public static TagKey<Item> createTag(String name) {
|
||||
return ItemTags.create(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, name));
|
||||
}
|
||||
|
||||
private static TagKey<Item> commonTag(String name) {
|
||||
return ItemTags.create(ResourceLocation.fromNamespaceAndPath("c", name));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
15
src/main/java/net/xevianlight/aphelion/util/MouseUtil.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package net.xevianlight.aphelion.util;
|
||||
|
||||
public class MouseUtil {
|
||||
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y) {
|
||||
return isMouseOver(mouseX, mouseY, x, y, 16);
|
||||
}
|
||||
|
||||
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int size) {
|
||||
return isMouseOver(mouseX, mouseY, x, y, size, size);
|
||||
}
|
||||
|
||||
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int sizeX, int sizeY) {
|
||||
return (mouseX >= x && mouseX <= x + sizeX) && (mouseY >= y && mouseY <= y + sizeY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package net.xevianlight.aphelion.util;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.IItemHandlerModifiable;
|
||||
|
||||
public class SidedSlotHandler implements IItemHandler {
|
||||
|
||||
private final IItemHandlerModifiable backing;
|
||||
private final int[] slots;
|
||||
private final boolean allowInsert;
|
||||
private final boolean allowExtract;
|
||||
|
||||
public SidedSlotHandler(IItemHandlerModifiable backing, int[] slots, boolean allowInsert, boolean allowExtract) {
|
||||
this.backing = backing;
|
||||
this.slots = slots;
|
||||
this.allowInsert = allowInsert;
|
||||
this.allowExtract = allowExtract;
|
||||
}
|
||||
|
||||
private int toBackingSlot(int localSlot) {
|
||||
if (localSlot < 0 || localSlot >= slots.length) return -1;
|
||||
return slots[localSlot];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
return slots.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
int s = toBackingSlot(slot);
|
||||
return s < 0 ? ItemStack.EMPTY : backing.getStackInSlot(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||
if (!allowInsert || stack.isEmpty()) return stack;
|
||||
int s = toBackingSlot(slot);
|
||||
return s < 0 ? stack : backing.insertItem(s, stack, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
if (!allowExtract || amount <= 0) return ItemStack.EMPTY;
|
||||
int s = toBackingSlot(slot);
|
||||
return s < 0 ? ItemStack.EMPTY : backing.extractItem(s, amount, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
int s = toBackingSlot(slot);
|
||||
return s < 0 ? 0 : backing.getSlotLimit(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
if (!allowInsert) return false;
|
||||
int s = toBackingSlot(slot);
|
||||
return s >= 0 && backing.isItemValid(s, stack);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package net.xevianlight.extreme_rocketry;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.ModContainer;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.gui.ConfigurationScreen;
|
||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||
|
||||
// This class will not load on dedicated servers. Accessing client side code from here is safe.
|
||||
@Mod(value = ExtremeRocketry.MOD_ID, dist = Dist.CLIENT)
|
||||
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
|
||||
@EventBusSubscriber(modid = ExtremeRocketry.MOD_ID, value = Dist.CLIENT)
|
||||
public class ExtremeRocketryClient {
|
||||
public ExtremeRocketryClient(ModContainer container) {
|
||||
// Allows NeoForge to create a config screen for this mod's configs.
|
||||
// The config screen is accessed by going to the Mods screen > clicking on your mod > clicking on config.
|
||||
// Do not forget to add translations for your config options to the en_us.json file.
|
||||
container.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
static void onClientSetup(FMLClientSetupEvent event) {
|
||||
// Some client setup code
|
||||
ExtremeRocketry.LOGGER.info("HELLO FROM CLIENT SETUP");
|
||||
ExtremeRocketry.LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package net.xevianlight.extreme_rocketry.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
public class TestBlock extends Block {
|
||||
public TestBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return Properties
|
||||
.of()
|
||||
.sound(SoundType.ANVIL)
|
||||
.destroyTime(2f)
|
||||
.explosionResistance(10f)
|
||||
.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
public static Item.Properties getItemProperties() {
|
||||
return new Item.Properties().stacksTo(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package net.xevianlight.extreme_rocketry.core.init;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.neoforged.neoforge.registries.DeferredBlock;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.extreme_rocketry.ExtremeRocketry;
|
||||
import net.xevianlight.extreme_rocketry.block.TestBlock;
|
||||
|
||||
public class ModBlocks {
|
||||
public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(ExtremeRocketry.MOD_ID);
|
||||
|
||||
public static final DeferredBlock<Block> TEST_BLOCK = BLOCKS.register("test_block", () -> new TestBlock(TestBlock.getProperties()));
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package net.xevianlight.extreme_rocketry.core.init;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.extreme_rocketry.ExtremeRocketry;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModCreativeTabs {
|
||||
public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TAB = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ExtremeRocketry.MOD_ID);
|
||||
|
||||
public static final Supplier<CreativeModeTab> EXTREME_ROCKETRY_ITEMS_TAB = CREATIVE_MODE_TAB.register("extreme_rocketry_items_tab",
|
||||
() -> CreativeModeTab.builder().icon(() -> new ItemStack(ModItems.TEST_ITEM.get()))
|
||||
.title(Component.translatable("creativetab.extreme_rocketry.extreme_rocketry_items"))
|
||||
.displayItems((itemDisplayParameters, output) -> {
|
||||
output.accept(ModItems.TEST_ITEM);
|
||||
}).build());
|
||||
|
||||
public static final Supplier<CreativeModeTab> EXTREME_ROCKETRY_BLOCKS_TAB = CREATIVE_MODE_TAB.register("extreme_rocketry_blocks_tab",
|
||||
() -> CreativeModeTab.builder().icon(() -> new ItemStack(ModItems.TEST_BLOCK.get()))
|
||||
.withTabsBefore(ResourceLocation.fromNamespaceAndPath(ExtremeRocketry.MOD_ID, "extreme_rocketry_items_tab"))
|
||||
.title(Component.translatable("creativetab.extreme_rocketry.extreme_rocketry_blocks"))
|
||||
.displayItems((itemDisplayParameters, output) -> {
|
||||
output.accept(ModItems.TEST_BLOCK);
|
||||
}).build());
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package net.xevianlight.extreme_rocketry.core.init;
|
||||
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.neoforged.neoforge.registries.DeferredItem;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.xevianlight.extreme_rocketry.ExtremeRocketry;
|
||||
import net.xevianlight.extreme_rocketry.block.TestBlock;
|
||||
import net.xevianlight.extreme_rocketry.item.TestItem;
|
||||
|
||||
public class ModItems {
|
||||
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(ExtremeRocketry.MOD_ID);
|
||||
|
||||
public static final DeferredItem<Item> TEST_ITEM = ITEMS.register("test_item", TestItem::new);
|
||||
|
||||
|
||||
// Block Items
|
||||
|
||||
public static final DeferredItem<BlockItem> TEST_BLOCK = ITEMS.register("test_block", () -> new BlockItem(ModBlocks.TEST_BLOCK.get(), TestBlock.getItemProperties()));
|
||||
}
|
||||
@@ -8,11 +8,11 @@
|
||||
modLoader="javafml" #mandatory
|
||||
|
||||
# A version range to match for said mod loader - for regular FML @Mod it will be the FML version. This is currently 2.
|
||||
loaderVersion="${loader_version_range}" #mandatory
|
||||
loaderVersion="[4,)" #mandatory
|
||||
|
||||
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
|
||||
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
|
||||
license="${mod_license}"
|
||||
license="GNU GPLv3"
|
||||
|
||||
# A URL to refer people to when problems occur with this mod
|
||||
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
|
||||
@@ -21,13 +21,13 @@ license="${mod_license}"
|
||||
[[mods]] #mandatory
|
||||
|
||||
# The modid of the mod
|
||||
modId="${mod_id}" #mandatory
|
||||
modId="aphelion" #mandatory
|
||||
|
||||
# The version number of the mod
|
||||
version="${mod_version}" #mandatory
|
||||
version="1.0.0" #mandatory
|
||||
|
||||
# A display name for the mod
|
||||
displayName="${mod_name}" #mandatory
|
||||
displayName="Aphelion" #mandatory
|
||||
|
||||
# A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/
|
||||
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
|
||||
@@ -46,12 +46,12 @@ authors="XevianLight"
|
||||
|
||||
# The description text for the mod (multi line!) (#mandatory)
|
||||
description='''
|
||||
Extreme Rocketry!
|
||||
Aphelion!
|
||||
'''
|
||||
|
||||
# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded.
|
||||
#[[mixins]]
|
||||
#config="${mod_id}.mixins.json"
|
||||
[[mixins]]
|
||||
config = "aphelion.mixins.json"
|
||||
|
||||
# The [[accessTransformers]] block allows you to declare where your AT file is.
|
||||
# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg
|
||||
@@ -61,7 +61,7 @@ Extreme Rocketry!
|
||||
# The coremods config file path is not configurable and is always loaded from META-INF/coremods.json
|
||||
|
||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||
[[dependencies.${mod_id}]] #optional
|
||||
[[dependencies.aphelion]] #optional
|
||||
# the modid of the dependency
|
||||
modId="neoforge" #mandatory
|
||||
# The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive).
|
||||
@@ -80,7 +80,7 @@ Extreme Rocketry!
|
||||
side="BOTH"
|
||||
|
||||
# Here's another dependency
|
||||
[[dependencies.${mod_id}]]
|
||||
[[dependencies.aphelion]]
|
||||
modId="minecraft"
|
||||
type="required"
|
||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||
15
src/main/resources/aphelion.mixins.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.xevianlight.aphelion.mixins",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"common.ClientLevelMixin",
|
||||
"common.DimensionSpecialEffectsMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"custom_clouds": false,
|
||||
"custom_sky": false,
|
||||
"custom_weather": false,
|
||||
"dimension": "aphelion:default",
|
||||
"has_fog": false,
|
||||
"has_thick_fog": true,
|
||||
"render_in_rain": true,
|
||||
"sunrise_angle": 0,
|
||||
"sunrise_color": 14180147,
|
||||
"render_void_fog": false,
|
||||
"horizon_height": -128,
|
||||
"clear_color_scale": 1.0
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"custom_clouds": false,
|
||||
"custom_sky": false,
|
||||
"custom_weather": false,
|
||||
"dimension": "aphelion:earth",
|
||||
"has_fog": false,
|
||||
"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
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"custom_clouds": false,
|
||||
"custom_sky": true,
|
||||
"custom_weather": false,
|
||||
"dimension": "aphelion:mars",
|
||||
"has_fog": false,
|
||||
"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
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"custom_clouds": false,
|
||||
"custom_sky": false,
|
||||
"custom_weather": false,
|
||||
"dimension": "aphelion:venus",
|
||||
"has_fog": false,
|
||||
"has_thick_fog": true,
|
||||
"render_in_rain": true,
|
||||
"sunrise_angle": 0,
|
||||
"sunrise_color": 14180147,
|
||||
"render_void_fog": false,
|
||||
"horizon_height": -128,
|
||||
"clear_color_scale": 1.0
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"custom_clouds": false,
|
||||
"custom_sky": true,
|
||||
"custom_weather": false,
|
||||
"dimension": "aphelion:test",
|
||||
"has_fog": false,
|
||||
"has_thick_fog": true,
|
||||
"render_in_rain": true,
|
||||
"sunrise_angle": 0,
|
||||
"sunrise_color": 14180147,
|
||||
"render_void_fog": false,
|
||||
"horizon_height": -128,
|
||||
"clear_color_scale": 1.0
|
||||
}
|
||||
28
src/main/resources/assets/aphelion/lang/en_us.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"item.aphelion.test_item": "Test Item",
|
||||
"block.aphelion.test_block": "Test Block",
|
||||
"block.aphelion.electric_arc_furnace": "Electric Arc Furnace",
|
||||
|
||||
"item.aphelion.ingot_steel": "Steel Ingot",
|
||||
"block.aphelion.block_steel": "Steel Block",
|
||||
"block.aphelion.oil": "Oil",
|
||||
|
||||
"item.aphelion.ingot_aluminum": "Aluminum Ingot",
|
||||
"item.aphelion.ingot_tungsten": "Tungsten Ingot",
|
||||
"item.aphelion.ingot_titanium": "Titanium Ingot",
|
||||
"item.aphelion.ingot_uranium": "Uranium Ingot",
|
||||
"item.aphelion.ingot_cobalt": "Cobalt Ingot",
|
||||
"item.aphelion.ingot_neodymium": "Neodymium Ingot",
|
||||
"item.aphelion.ingot_iridium": "Iridium Ingot",
|
||||
|
||||
"item.aphelion.oil_bucket": "Oil Bucket",
|
||||
|
||||
"item.aphelion.music_disc_bit_shift": "Music Disc",
|
||||
"item.aphelion.music_disc_bit_shift.desc": "XevianLight - Bit Shift",
|
||||
|
||||
"creativetab.aphelion.aphelion_items": "Aphelion Items",
|
||||
"creativetab.aphelion.aphelion_blocks": "Aphelion Blocks",
|
||||
|
||||
"tag.item.c.ingots.steel": "Steel Ingots",
|
||||
"tag.item.c.ingots.aluminum": "Aluminum Ingots"
|
||||
}
|
||||
10
src/main/resources/assets/aphelion/sounds.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"bit_shift": {
|
||||
"sounds": [
|
||||
{
|
||||
"name": "aphelion:bit_shift",
|
||||
"stream": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/assets/aphelion/sounds/bit_shift.ogg
Normal file
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 247 B |
BIN
src/main/resources/assets/aphelion/textures/block/test_block.png
Normal file
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 143 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 366 B |
|
After Width: | Height: | Size: 224 B |
|
After Width: | Height: | Size: 213 B |
|
After Width: | Height: | Size: 215 B |
BIN
src/main/resources/assets/aphelion/textures/item/ingot_steel.png
Normal file
|
After Width: | Height: | Size: 322 B |
|
After Width: | Height: | Size: 446 B |
|
After Width: | Height: | Size: 216 B |
|
After Width: | Height: | Size: 357 B |
|
After Width: | Height: | Size: 266 B |
BIN
src/main/resources/assets/aphelion/textures/item/oil_bucket.png
Normal file
|
After Width: | Height: | Size: 219 B |
BIN
src/main/resources/assets/aphelion/textures/item/test_item.png
Normal file
|
After Width: | Height: | Size: 247 B |
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "extreme_rocketry:block/test_block"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"item.extreme_rocketry.test_item": "Test Item",
|
||||
"block.extreme_rocketry.test_block": "Test Block",
|
||||
|
||||
"creativetab.extreme_rocketry.extreme_rocketry_items": "Extreme Rocketry Items",
|
||||
"creativetab.extreme_rocketry.extreme_rocketry_blocks": "Extreme Rocketry Blocks"
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "extreme_rocketry:block/test_block"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"parent": "extreme_rocketry:block/test_block"
|
||||
}
|
||||