diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d index 33cc7e8..52e1b85 100644 --- a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d +++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -1,7 +1,8 @@ -// 1.21.1 2026-01-18T19:51:57.3558369 Loot Tables +// 1.21.1 2026-01-23T22:32:50.7204827 Loot Tables 69d8318ddba171526d1fabb87d9d93548ed8598e data/aphelion/loot_table/blocks/arc_furnace_casing.json 05f08985e601d30116f67e2f07b48b03b40cdca6 data/aphelion/loot_table/blocks/block_steel.json ff43a9c3741faf10b1e156a7a74d5cfb035cc118 data/aphelion/loot_table/blocks/dimension_changer.json b63130d9c10485676303d729807b6fcaac080294 data/aphelion/loot_table/blocks/electric_arc_furnace.json 1ab50c99e9f478840b9d003fd56ebdcab12fbbce data/aphelion/loot_table/blocks/test_block.json 7d8eeb99a1bc942a6e2cf292b21fd4534062b5ab data/aphelion/loot_table/blocks/vacuum_arc_furnace_controller.json +797bf9839d79e08b4832c9eaf3cb303b0471ed0c data/aphelion/loot_table/blocks/vaf_dummy_block.json diff --git a/src/generated/resources/.cache/9c517586575525115dfb9b0c4d592f540cb43d3e b/src/generated/resources/.cache/9c517586575525115dfb9b0c4d592f540cb43d3e index ccbfac6..bea8b37 100644 --- a/src/generated/resources/.cache/9c517586575525115dfb9b0c4d592f540cb43d3e +++ b/src/generated/resources/.cache/9c517586575525115dfb9b0c4d592f540cb43d3e @@ -1,5 +1,5 @@ -// 1.21.1 2026-01-17T21:22:18.4350515 Tags for minecraft:block mod id aphelion +// 1.21.1 2026-01-23T22:32:50.7214756 Tags for minecraft:block mod id aphelion 058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks.json 058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks/steel.json -51e9ab2ffa3ba81700cbaab7f39985bb2ab673fa data/minecraft/tags/block/mineable/pickaxe.json -51e9ab2ffa3ba81700cbaab7f39985bb2ab673fa data/minecraft/tags/block/needs_stone_tool.json +7d420216f15b8f78d2a3b298f9bb773a9e5f79c3 data/minecraft/tags/block/mineable/pickaxe.json +7d420216f15b8f78d2a3b298f9bb773a9e5f79c3 data/minecraft/tags/block/needs_stone_tool.json diff --git a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json index e7f32a7..60f9650 100644 --- a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -3,6 +3,8 @@ "aphelion:test_block", "aphelion:electric_arc_furnace", "aphelion:block_steel", - "aphelion:arc_furnace_casing" + "aphelion:arc_furnace_casing", + "aphelion:vacuum_arc_furnace_controller", + "aphelion:vaf_dummy_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/needs_stone_tool.json b/src/generated/resources/data/minecraft/tags/block/needs_stone_tool.json index e7f32a7..60f9650 100644 --- a/src/generated/resources/data/minecraft/tags/block/needs_stone_tool.json +++ b/src/generated/resources/data/minecraft/tags/block/needs_stone_tool.json @@ -3,6 +3,8 @@ "aphelion:test_block", "aphelion:electric_arc_furnace", "aphelion:block_steel", - "aphelion:arc_furnace_casing" + "aphelion:arc_furnace_casing", + "aphelion:vacuum_arc_furnace_controller", + "aphelion:vaf_dummy_block" ] } \ No newline at end of file diff --git a/src/main/java/net/xevianlight/aphelion/Aphelion.java b/src/main/java/net/xevianlight/aphelion/Aphelion.java index 80bfa74..e64d09f 100644 --- a/src/main/java/net/xevianlight/aphelion/Aphelion.java +++ b/src/main/java/net/xevianlight/aphelion/Aphelion.java @@ -1,13 +1,17 @@ package net.xevianlight.aphelion; +import net.minecraft.client.renderer.entity.ThrownItemRenderer; +import net.minecraft.resources.ResourceLocation; 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.neoforged.neoforge.event.AddReloadListenerEvent; import net.xevianlight.aphelion.block.dummy.renderer.MultiblockDummyRenderer; import net.xevianlight.aphelion.client.AphelionConfig; +import net.xevianlight.aphelion.planet.AphelionPlanetJSONLoader; import net.xevianlight.aphelion.core.init.*; import net.xevianlight.aphelion.fluid.BaseFluidType; import net.xevianlight.aphelion.fluid.ModFluidTypes; @@ -18,6 +22,7 @@ import net.xevianlight.aphelion.screen.ModMenuTypes; import net.xevianlight.aphelion.screen.TestBlockScreen; import net.xevianlight.aphelion.screen.VacuumArcFurnaceScreen; import org.slf4j.Logger; +import net.xevianlight.aphelion.entites.vehicles.RocketRenderer; import com.mojang.logging.LogUtils; @@ -59,6 +64,7 @@ public class Aphelion { ModFluids.register(MOD_BUS); ModSounds.register(MOD_BUS); ModRecipes.register(MOD_BUS); + ModEntities.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. @@ -74,6 +80,10 @@ public class Aphelion { modContainer.registerConfig(ModConfig.Type.COMMON, AphelionConfig.SPEC); } + public static ResourceLocation id(String path) { + return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, path); + } + private void commonSetup(FMLCommonSetupEvent event) { } @@ -97,6 +107,12 @@ public class Aphelion { } + @SubscribeEvent + public void onAddReloadListeners(AddReloadListenerEvent event) { + // Set up the planet json listener. This reloads on /reload + event.addListener(new AphelionPlanetJSONLoader()); + } + // 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 { @@ -124,5 +140,10 @@ public class Aphelion { event.register(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), ElectricArcFurnaceScreen::new); event.register(ModMenuTypes.VACUUM_ARC_FURNACE_MENU.get(), VacuumArcFurnaceScreen::new); } + + @SubscribeEvent + public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { + event.registerEntityRenderer(ModEntities.ROCKET.get(), RocketRenderer::new); + } } } diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/VacuumArcFurnaceController.java b/src/main/java/net/xevianlight/aphelion/block/custom/VacuumArcFurnaceController.java index fb84222..7ea271d 100644 --- a/src/main/java/net/xevianlight/aphelion/block/custom/VacuumArcFurnaceController.java +++ b/src/main/java/net/xevianlight/aphelion/block/custom/VacuumArcFurnaceController.java @@ -68,7 +68,8 @@ public class VacuumArcFurnaceController extends BaseEntityBlock { .sound(SoundType.NETHERITE_BLOCK) .destroyTime(2f) .explosionResistance(10f) - .requiresCorrectToolForDrops(); + .requiresCorrectToolForDrops() + .lightLevel(state -> state.getValue(BlockStateProperties.LIT) ? 15 : 0); } public static Item.Properties getItemProperties() { diff --git a/src/main/java/net/xevianlight/aphelion/block/dummy/entity/BaseMultiblockDummyBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/dummy/entity/BaseMultiblockDummyBlockEntity.java index 19504ea..cf03ce1 100644 --- a/src/main/java/net/xevianlight/aphelion/block/dummy/entity/BaseMultiblockDummyBlockEntity.java +++ b/src/main/java/net/xevianlight/aphelion/block/dummy/entity/BaseMultiblockDummyBlockEntity.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable; public class BaseMultiblockDummyBlockEntity extends BlockEntity implements IMultiblockPart { @Nullable private BlockPos controllerPos; - private BlockState mimicing = Blocks.AIR.defaultBlockState(); + private BlockState mimicking = Blocks.AIR.defaultBlockState(); @Nullable private ItemStackHandler getControllerInventory() { @@ -116,7 +116,7 @@ public class BaseMultiblockDummyBlockEntity extends BlockEntity implements IMult protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.saveAdditional(tag, registries); if (controllerPos != null) tag.putLong("controller", controllerPos.asLong()); - tag.put("mimic", NbtUtils.writeBlockState(mimicing)); + tag.put("mimic", NbtUtils.writeBlockState(mimicking)); } @Override @@ -170,12 +170,12 @@ public class BaseMultiblockDummyBlockEntity extends BlockEntity implements IMult @Override public BlockState getMimicing() { - return mimicing; + return mimicking; } @Override public void setMimicing(BlockState newState) { - mimicing = newState; + mimicking = newState; setChanged(); if (level != null) { level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); diff --git a/src/main/java/net/xevianlight/aphelion/client/AphelionClient.java b/src/main/java/net/xevianlight/aphelion/client/AphelionClient.java index cf23b43..0462342 100644 --- a/src/main/java/net/xevianlight/aphelion/client/AphelionClient.java +++ b/src/main/java/net/xevianlight/aphelion/client/AphelionClient.java @@ -1,7 +1,6 @@ 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; @@ -44,6 +43,7 @@ public class AphelionClient { } public static void onAddReloadListener(BiConsumer consumer) { + // Set up the dimension renderers json listener. This reloads on F3+T consumer.accept(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "planet_renderers"), new AphelionDimensionRenderers()); } @@ -51,7 +51,7 @@ public class AphelionClient { public static void onRegisterDimensionEffects(RegisterDimensionSpecialEffectsEvent event) { event.register( ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "space"), - new net.xevianlight.aphelion.client.dimension.SpaceSkyEffects() + new net.xevianlight.aphelion.client.dimension.SpaceSkyEffects(null) ); } } diff --git a/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java b/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java index 56455d9..ed9a2ca 100644 --- a/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java +++ b/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java @@ -2,6 +2,7 @@ package net.xevianlight.aphelion.client; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.dimension.DimensionType; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.api.distmarker.Dist; @@ -21,13 +22,16 @@ public class AphelionDebugOverlay { 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; - } +// // 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); + DimensionType type = mc.level.dimensionType(); + ResourceLocation effectsId = type.effectsLocation(); + + var camPos = mc.gameRenderer.getMainCamera(); + ResourceLocation orbitId = SpaceSkyEffects.resolvedId(effectsId, camPos); DimensionRenderer r = DimensionRendererCache.getOrDefault(orbitId); diff --git a/src/main/java/net/xevianlight/aphelion/client/dimension/DimensionSkyEffects.java b/src/main/java/net/xevianlight/aphelion/client/dimension/DimensionSkyEffects.java index d2a225c..d917fde 100644 --- a/src/main/java/net/xevianlight/aphelion/client/dimension/DimensionSkyEffects.java +++ b/src/main/java/net/xevianlight/aphelion/client/dimension/DimensionSkyEffects.java @@ -1,11 +1,14 @@ package net.xevianlight.aphelion.client.dimension; import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; 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 net.xevianlight.aphelion.client.PartitionClientState; +import net.xevianlight.aphelion.util.SpacePartitionHelper; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; @@ -56,5 +59,23 @@ public class DimensionSkyEffects extends DimensionSpecialEffects { return new float[]{0,0,0,0}; } + public static ResourceLocation orbitForPos(Vec3 pos) { + + int x = SpacePartitionHelper.get(pos.x); + int z = SpacePartitionHelper.get(pos.z); + + Minecraft mc = Minecraft.getInstance(); + if (mc.level == null) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default"); + +// int px = PartitionClientState.pxOr(0); +// int py = PartitionClientState.pyOr(0); + var data = ResourceLocation.parse(PartitionClientState.idOrUnknown()); + +// var data = SpacePartitionSavedData.get(serverLevel).getOrbitForPartition((int) x, (int) z); + if (data != null) return data; + + return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default"); + } + } diff --git a/src/main/java/net/xevianlight/aphelion/client/dimension/DimensionSkyRenderer.java b/src/main/java/net/xevianlight/aphelion/client/dimension/DimensionSkyRenderer.java deleted file mode 100644 index d024d47..0000000 --- a/src/main/java/net/xevianlight/aphelion/client/dimension/DimensionSkyRenderer.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.xevianlight.aphelion.client.dimension; - -public class DimensionSkyRenderer { - - DimensionRenderer renderer; - - DimensionSkyRenderer(DimensionRenderer renderer) { this.renderer = renderer; } - -} diff --git a/src/main/java/net/xevianlight/aphelion/client/dimension/OrbitSkyDefinition.java b/src/main/java/net/xevianlight/aphelion/client/dimension/OrbitSkyDefinition.java deleted file mode 100644 index b33f7d1..0000000 --- a/src/main/java/net/xevianlight/aphelion/client/dimension/OrbitSkyDefinition.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.xevianlight.aphelion.client.dimension; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.phys.Vec3; - -public record OrbitSkyDefinition( - ResourceLocation id, - Vec3 skyColor - -) { - -} diff --git a/src/main/java/net/xevianlight/aphelion/client/dimension/SpaceSkyEffects.java b/src/main/java/net/xevianlight/aphelion/client/dimension/SpaceSkyEffects.java index f893d52..9a56231 100644 --- a/src/main/java/net/xevianlight/aphelion/client/dimension/SpaceSkyEffects.java +++ b/src/main/java/net/xevianlight/aphelion/client/dimension/SpaceSkyEffects.java @@ -12,14 +12,27 @@ import net.xevianlight.aphelion.Aphelion; import net.xevianlight.aphelion.client.PartitionClientState; import net.xevianlight.aphelion.core.space.SpacePartitionSavedData; import net.xevianlight.aphelion.util.SpacePartitionHelper; +import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; public class SpaceSkyEffects extends DimensionSpecialEffects { - public SpaceSkyEffects() { + private final ResourceLocation effectsId; + + public SpaceSkyEffects(@Nullable ResourceLocation effectsId) { super(192, false, SkyType.NORMAL, false, false); + this.effectsId = effectsId; } + public static ResourceLocation resolvedId(ResourceLocation effectsId, Camera camera) { + if (effectsId == null) { + return ResourceLocation.withDefaultNamespace("overworld"); + } + if (effectsId.equals(Aphelion.id("space"))) { + return SpaceSkyEffects.orbitForPos(camera.getPosition()); // or inline this logic + } + return effectsId; + } @Override @@ -49,8 +62,8 @@ public class SpaceSkyEffects extends DimensionSpecialEffects { @Override public boolean isFoggyAt(int i, int i1) { - ResourceLocation id = orbitForPos(net.minecraft.client.Minecraft.getInstance() - .gameRenderer.getMainCamera().getPosition()); + ResourceLocation id = resolvedId(effectsId ,net.minecraft.client.Minecraft.getInstance() + .gameRenderer.getMainCamera()); return DimensionRendererCache.getOrDefault(id).hasThickFog(); } diff --git a/src/main/java/net/xevianlight/aphelion/commands/AphelionCommand.java b/src/main/java/net/xevianlight/aphelion/commands/AphelionCommand.java index 16d8ea9..0c82f8e 100644 --- a/src/main/java/net/xevianlight/aphelion/commands/AphelionCommand.java +++ b/src/main/java/net/xevianlight/aphelion/commands/AphelionCommand.java @@ -10,6 +10,7 @@ import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.*; import net.minecraft.commands.arguments.coordinates.ColumnPosArgument; import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentUtils; @@ -17,10 +18,13 @@ import net.minecraft.network.chat.HoverEvent; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.RelativeMovement; -import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; import net.xevianlight.aphelion.Aphelion; import net.xevianlight.aphelion.core.space.SpacePartitionSavedData; +import net.xevianlight.aphelion.entites.vehicles.RocketEntity; +import net.xevianlight.aphelion.util.RocketStructure; import net.xevianlight.aphelion.util.SpacePartitionHelper; import java.util.EnumSet; @@ -62,7 +66,7 @@ public class AphelionCommand { SpacePartitionSavedData.get(level).overwriteAllExistingOrbits(orbit); context.getSource().sendSuccess( - () -> Component.translatable("command.aphelion.station.orbit.overwriteall", orbit.toString()), + () -> Component.translatable("command.aphelion.station.orbit.overwrite_all", orbit.toString()), true ); @@ -123,7 +127,7 @@ public class AphelionCommand { SpacePartitionSavedData.get(level).clearAllOrbits(); context.getSource().sendSuccess( - () -> Component.translatable("command.aphelion.station.orbit.clearall"), + () -> Component.translatable("command.aphelion.station.orbit.clear_all"), true ); @@ -280,6 +284,92 @@ public class AphelionCommand { ) ) ) + .then(Commands.literal("planet") + .then(Commands.literal("tp") + .then(Commands.argument("dimension", DimensionArgument.dimension()) + .executes(context -> { + + var player = context.getSource().getEntity(); + if (player == null || player.getServer() == null) { + context.getSource().sendFailure(Component.translatable("command.aphelion.station.teleport.failure")); + return Command.SINGLE_SUCCESS; + } + + var targetDim = DimensionArgument.getDimension(context, "dimension"); + + ServerLevel targetLevel = player.getServer().getLevel(targetDim.dimension()); + + if (targetLevel == null) { + context.getSource().sendFailure(Component.translatable("command.aphelion.station.teleport.failure.invalid_level")); + return Command.SINGLE_SUCCESS; + } + + player.teleportTo(targetLevel, player.position().x, player.position().y, player.position().z, EnumSet.noneOf(RelativeMovement.class), player.getYRot(), player.getXRot()); + + return Command.SINGLE_SUCCESS; + })) + ) + ) + .then(Commands.literal("rocket") + .then(Commands.literal("summon") + .executes(context -> { + RocketStructure structure = new RocketStructure(s -> { + s.add(0,0,0, Blocks.IRON_BLOCK.defaultBlockState()); + }); + context.getSource().sendSuccess(() -> Component.translatable("command.aphelion.rocket.spawn.success"), true); + RocketEntity rocket = RocketEntity.spawnRocket(context.getSource().getLevel(), context.getSource().getEntity().blockPosition(), structure); + return Command.SINGLE_SUCCESS; + }) + ) + .then(Commands.argument("entity", EntityArgument.entity()) + .then(Commands.literal("structure") + .then(Commands.literal("set") + .then(Commands.argument("nbt", CompoundTagArgument.compoundTag()) + .executes(context -> { + Entity entity = EntityArgument.getEntity(context, "entity"); + if (entity instanceof RocketEntity rocket) { + RocketStructure structure = new RocketStructure(RocketStructure::clear); + structure.load(CompoundTagArgument.getCompoundTag(context, "nbt")); + rocket.setStructure(structure); + } else { + context.getSource().sendFailure(Component.translatable("command.aphelion.rocket.entity_invalid")); + } + return Command.SINGLE_SUCCESS; + }) + ) + ) + .then(Commands.literal("get") + .executes(context -> { + Entity entity = EntityArgument.getEntity(context, "entity"); + + if (entity instanceof RocketEntity rocket) { + RocketStructure structure = rocket.getStructure(); + CompoundTag tag = structure.save(); + + Component clickableId = Component.literal(tag.toString()) + .withStyle(style -> style + .withClickEvent(new ClickEvent( + ClickEvent.Action.COPY_TO_CLIPBOARD, + tag.toString() + )) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("chat.copy.click"))) + .withColor(ChatFormatting.AQUA) + ); + + context.getSource().sendSuccess( + () -> clickableId, + true + ); + } else { + context.getSource().sendFailure(Component.translatable("command.aphelion.rocket.entity_invalid")); + } + return Command.SINGLE_SUCCESS; + }) + ) + ) + ) + ) + ); } } diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java b/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java index cd16135..659dda0 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java @@ -40,5 +40,6 @@ public class ModCreativeTabs { output.accept(ModItems.ELECTRIC_ARC_FURNACE); output.accept(ModItems.BLOCK_STEEL); output.accept(ModItems.ARC_FURNACE_CASING_BLOCK); + output.accept(ModItems.VACUUM_ARC_FURNACE_CONTROLLER); }).build()); } diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModEntities.java b/src/main/java/net/xevianlight/aphelion/core/init/ModEntities.java new file mode 100644 index 0000000..fbb13a1 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModEntities.java @@ -0,0 +1,29 @@ +package net.xevianlight.aphelion.core.init; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.xevianlight.aphelion.Aphelion; +import net.xevianlight.aphelion.entites.vehicles.RocketEntity; + +import java.util.function.Supplier; + +public class ModEntities { + public static final DeferredRegister> ENTITIES = + DeferredRegister.create(Registries.ENTITY_TYPE, Aphelion.MOD_ID); + + public static final Supplier> ROCKET = + ENTITIES.register("rocket", () -> + EntityType.Builder.of(RocketEntity::new, MobCategory.MISC) + .sized(0.75f, 2.0f) // tall-ish rocket + .clientTrackingRange(8) + .updateInterval(1) + .build("rocket") + ); + + public static void register(IEventBus bus) { + ENTITIES.register(bus); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java index bea13a3..f8e3ee1 100644 --- a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java +++ b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java @@ -4,6 +4,7 @@ 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.item.ItemStack; import net.minecraft.world.level.block.Block; import net.xevianlight.aphelion.core.init.ModBlocks; @@ -22,6 +23,7 @@ public class ModBlockLootTableProvider extends BlockLootSubProvider { dropSelf(ModBlocks.ELECTRIC_ARC_FURNACE.get()); dropSelf(ModBlocks.ARC_FURNACE_CASING_BLOCK.get()); dropSelf(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get()); + dropOther(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), ItemStack.EMPTY.getItem()); } @Override diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java index 2612ce4..c815000 100644 --- a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java +++ b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java @@ -23,13 +23,17 @@ public class ModBlockTagProvider extends BlockTagsProvider { .add(ModBlocks.TEST_BLOCK.get()) .add(ModBlocks.ELECTRIC_ARC_FURNACE.get()) .add(ModBlocks.BLOCK_STEEL.get()) - .add(ModBlocks.ARC_FURNACE_CASING_BLOCK.get()); + .add(ModBlocks.ARC_FURNACE_CASING_BLOCK.get()) + .add(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get()) + .add(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get()); tag(BlockTags.NEEDS_STONE_TOOL) .add(ModBlocks.TEST_BLOCK.get()) .add(ModBlocks.ELECTRIC_ARC_FURNACE.get()) .add(ModBlocks.BLOCK_STEEL.get()) - .add(ModBlocks.ARC_FURNACE_CASING_BLOCK.get()); + .add(ModBlocks.ARC_FURNACE_CASING_BLOCK.get()) + .add(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get()) + .add(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get()); tag(ModTags.Blocks.STORAGE_BLOCKS_STEEL) .add(ModBlocks.BLOCK_STEEL.get()); diff --git a/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEntity.java b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEntity.java new file mode 100644 index 0000000..1a26169 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEntity.java @@ -0,0 +1,190 @@ +package net.xevianlight.aphelion.entites.vehicles; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.*; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.AABB; +import net.neoforged.neoforge.entity.IEntityWithComplexSpawn; +import net.neoforged.neoforge.fluids.FluidType; +import net.xevianlight.aphelion.core.init.ModEntities; +import net.xevianlight.aphelion.util.RocketStructure; +import org.jetbrains.annotations.NotNull; + +public class RocketEntity extends Entity implements IEntityWithComplexSpawn { + + RocketStructure structure = new RocketStructure(s -> { + s.add(0,0,0, Blocks.NETHERITE_BLOCK.defaultBlockState()); + s.add(0,1,0, Blocks.NETHERITE_BLOCK.defaultBlockState()); + s.add(0,2,0, Blocks.NETHERITE_BLOCK.defaultBlockState()); + }); + + private static final EntityDataAccessor STRUCTURE_TAG = + SynchedEntityData.defineId(RocketEntity.class, EntityDataSerializers.COMPOUND_TAG); + + public static RocketEntity spawnRocket(Level level, BlockPos pos, RocketStructure structure) { + if (level.isClientSide) return null; + + RocketEntity rocket = new RocketEntity(ModEntities.ROCKET.get(), level); + + rocket.moveTo( + pos.getX() + 0.5f, + pos.getY(), + pos.getZ() + 0.5f, + 0.0f, + 0.0f + ); + + rocket.setStructure(structure); + level.addFreshEntity(rocket); + + return rocket; + } + + public RocketStructure getStructure() { + return structure; + } + + public RocketEntity(EntityType type, Level level) { + super(type, level); + } + + @Override + protected void defineSynchedData(SynchedEntityData.Builder builder) { + builder.define(STRUCTURE_TAG, new CompoundTag()); + } + + public void setStructure(RocketStructure structure) { + + this.structure.clear(); + CompoundTag tag = structure.save(); + this.structure.load(tag); + this.refreshDimensions(); + this.setBoundingBox(this.makeBoundingBox()); + // sync to clients + if (!level().isClientSide) { + this.entityData.set(STRUCTURE_TAG, this.structure.save()); + } + } + + @Override + public void onSyncedDataUpdated(@NotNull EntityDataAccessor key) { + super.onSyncedDataUpdated(key); + if (STRUCTURE_TAG.equals(key)) { + CompoundTag tag = this.entityData.get(STRUCTURE_TAG); + this.applyStructureTag(tag); + } + } + + @Override + protected void readAdditionalSaveData(CompoundTag tag) { + if (tag.contains("RocketStructure")) { + CompoundTag rocketTag = tag.getCompound("RocketStructure"); + structure.load(rocketTag); + } + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + tag.put("RocketStructure", structure.save()); + } + + @Override + public boolean isNoGravity() { + return true; + } + + @Override + public boolean canBeCollidedWith() { + return true; + } + + @Override + public boolean isPushedByFluid(@NotNull FluidType type) { + return false; + } + + @Override @NotNull + protected AABB makeBoundingBox() { + if (structure == null) { + double half = 0.5; + return new AABB( + getX() - half, getY() - half + 0.5, getZ() - half, + getX() + half, getY() + half + 0.5, getZ() + half + ); + } + return computeWorldAABBFromStructure(); + } + + @Override @NotNull + public AABB getBoundingBoxForCulling() { + if (structure == null) + return super.getBoundingBoxForCulling(); + return computeWorldAABBFromStructure(); + } + + @Override @NotNull + public EntityDimensions getDimensions(@NotNull Pose pose) { + // Example: dynamic size you already compute for your rocket + EntityDimensions base = EntityDimensions.scalable(1, 1); + + // Put “eyes” near the top (1 block below top here) + return base.withEyeHeight(0); + } + + @Override + public void tick() { + super.tick(); + + if (!level().isClientSide) { + // Simple upward movement + setDeltaMovement(0, 0, 0); + } + + move(MoverType.SELF, getDeltaMovement()); + } + + @Override + public void writeSpawnData(RegistryFriendlyByteBuf buf) { + buf.writeNbt(structure.save()); + } + + @Override + public void readSpawnData(RegistryFriendlyByteBuf buf) { + CompoundTag tag = buf.readNbt(); + if (tag != null) { + structure.load(tag); + refreshDimensions(); + } + } + + public void applyStructureTag(CompoundTag structureTag) { + this.structure.load(structureTag); + this.refreshDimensions(); // if your hitbox/eye depends on structure + } + + private AABB computeWorldAABBFromStructure() { + RocketStructure.Extents e = structure.computeExtents(); + AABB local = e.toLocalAABB(); // [min, max+1] in local structure coords + + return local.move(getX(), getY(), getZ()); + } + + @Override + public boolean hurt(DamageSource source, float amount) { + return super.hurt(source, amount); + } + + @Override + public boolean isPickable() { + return true; + } + +} \ No newline at end of file diff --git a/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketRenderer.java b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketRenderer.java new file mode 100644 index 0000000..a87c99d --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketRenderer.java @@ -0,0 +1,65 @@ +package net.xevianlight.aphelion.entites.vehicles; + + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.xevianlight.aphelion.util.RocketStructure; +import org.jetbrains.annotations.NotNull; + +public class RocketRenderer extends EntityRenderer { + + private final BlockRenderDispatcher blockRenderer; + + public RocketRenderer(EntityRendererProvider.Context ctx) { + super(ctx); + this.blockRenderer = ctx.getBlockRenderDispatcher(); // ✅ correct source + this.shadowRadius = 0.8f; + } + + @Override + public void render(@NotNull RocketEntity entity, + float entityYaw, + float partialTicks, + PoseStack poseStack, + @NotNull MultiBufferSource buffers, + int packedLight) { + + RocketStructure s = entity.getStructure(); + + for (int i = 0; i < s.size(); i++) { + int p = s.packedPosAt(i); + + poseStack.pushPose(); + poseStack.translate( + RocketStructure.unpackX(p) - 0.5d, + RocketStructure.unpackY(p), + RocketStructure.unpackZ(p) - 0.5d + ); + + blockRenderer.renderSingleBlock( + s.stateAt(i), + poseStack, + buffers, + packedLight, + OverlayTexture.NO_OVERLAY + ); + + poseStack.popPose(); + } + + + super.render(entity, entityYaw, partialTicks, poseStack, buffers, packedLight); + } + + @Override + public ResourceLocation getTextureLocation(RocketEntity entity) { + // Not used by block rendering, but required. + return ResourceLocation.withDefaultNamespace("textures/misc/white.png"); + } +} + diff --git a/src/main/java/net/xevianlight/aphelion/mixins/common/DimensionSpecialEffectsMixin.java b/src/main/java/net/xevianlight/aphelion/mixins/common/DimensionSpecialEffectsMixin.java index 3b4f0eb..7097c6d 100644 --- a/src/main/java/net/xevianlight/aphelion/mixins/common/DimensionSpecialEffectsMixin.java +++ b/src/main/java/net/xevianlight/aphelion/mixins/common/DimensionSpecialEffectsMixin.java @@ -5,6 +5,7 @@ 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 net.xevianlight.aphelion.client.dimension.SpaceSkyEffects; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -18,7 +19,7 @@ public abstract class DimensionSpecialEffectsMixin { ResourceLocation effectsId = type.effectsLocation(); if (DimensionRendererCache.RENDERERS.containsKey(effectsId)) { - cir.setReturnValue(new DimensionSkyEffects(effectsId)); + cir.setReturnValue(new SpaceSkyEffects(effectsId)); } } } diff --git a/src/main/java/net/xevianlight/aphelion/planet/AphelionPlanetJSONLoader.java b/src/main/java/net/xevianlight/aphelion/planet/AphelionPlanetJSONLoader.java new file mode 100644 index 0000000..f096d7f --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/planet/AphelionPlanetJSONLoader.java @@ -0,0 +1,43 @@ +package net.xevianlight.aphelion.planet; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.serialization.JsonOps; +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.xevianlight.aphelion.Aphelion; +import net.xevianlight.aphelion.client.dimension.DimensionRenderer; +import net.xevianlight.aphelion.util.Constants; + +import java.util.HashMap; +import java.util.Map; + +public class AphelionPlanetJSONLoader extends SimpleJsonResourceReloadListener { + + public AphelionPlanetJSONLoader() { + super(Constants.GSON, "planet"); + } + + @Override + protected void apply(Map object, + ResourceManager resourceManager, + ProfilerFiller profiler) { + + Map planets = new HashMap<>(); + object.forEach((key, value) -> { + JsonObject json = GsonHelper.convertToJsonObject(value, "planet"); + Planet planet = Planet.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. + planets.put(key, planet); + }); + + Aphelion.LOGGER.info("Loaded planets " + planets); + + PlanetCache.registerPlanets(planets); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/planet/Planet.java b/src/main/java/net/xevianlight/aphelion/planet/Planet.java new file mode 100644 index 0000000..5901d93 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/planet/Planet.java @@ -0,0 +1,21 @@ +package net.xevianlight.aphelion.planet; + +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 net.xevianlight.aphelion.util.registries.ModRegistries; + +public record Planet( + ResourceKey dimension, + double orbitDistance, + ResourceKey system +) { + public static final Codec CODEC = RecordCodecBuilder.create(inst -> inst.group( + ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(Planet::dimension), + Codec.DOUBLE.fieldOf("orbit_distance").forGetter(Planet::orbitDistance), + ResourceKey.codec(ModRegistries.STAR_SYSTEM).fieldOf("star_system").forGetter(Planet::system) + + ).apply(inst, Planet::new)); +} diff --git a/src/main/java/net/xevianlight/aphelion/planet/PlanetCache.java b/src/main/java/net/xevianlight/aphelion/planet/PlanetCache.java new file mode 100644 index 0000000..c1ce7c1 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/planet/PlanetCache.java @@ -0,0 +1,53 @@ +package net.xevianlight.aphelion.planet; + +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; +import net.xevianlight.aphelion.Aphelion; +import net.xevianlight.aphelion.util.registries.ModRegistries; + +import java.util.HashMap; +import java.util.Map; + +public final class PlanetCache { + + public static final Map PLANETS = new HashMap<>(); + public static final Map, ResourceLocation> PLANET_BY_DIMENSION = new HashMap<>(); + + public static final Planet DEFAULT = new Planet( + ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")), + 1, + ResourceKey.create(ModRegistries.STAR_SYSTEM, Aphelion.id("sol")) + ); + + public static void registerPlanets(Map planets) { + PLANETS.clear(); + PLANET_BY_DIMENSION.clear(); + + PLANETS.putAll(planets); + + planets.forEach((planetId, planet) -> { + var dim = planet.dimension(); + var prev = PLANET_BY_DIMENSION.put(dim, planetId); + if (prev != null) { + Aphelion.LOGGER.warn( + "Dimension {} is claimed by multiple planets: {} and {}. Keeping latest: {}", + dim.location(), prev, planetId, planetId + ); + } + }); + + Aphelion.LOGGER.info("Loaded {} planets; {} dimension mappings", + PLANETS.size(), PLANET_BY_DIMENSION.size()); + } + + public static Planet getOrDefault(ResourceLocation id) { + return PLANETS.getOrDefault(id, DEFAULT); + } + + public static Planet getByDimensionOrNull(ResourceKey dimension) { + ResourceLocation planetId = PLANET_BY_DIMENSION.get(dimension); + return planetId == null ? null : PLANETS.get(planetId); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/planet/StarSystem.java b/src/main/java/net/xevianlight/aphelion/planet/StarSystem.java new file mode 100644 index 0000000..67f617f --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/planet/StarSystem.java @@ -0,0 +1,12 @@ +package net.xevianlight.aphelion.planet; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +public record StarSystem( + int temp +) { + public static final Codec CODEC = RecordCodecBuilder.create(inst -> inst.group( + Codec.INT.fieldOf("dimension").forGetter(StarSystem::temp) + ).apply(inst, StarSystem::new)); +} diff --git a/src/main/java/net/xevianlight/aphelion/util/RocketStructure.java b/src/main/java/net/xevianlight/aphelion/util/RocketStructure.java new file mode 100644 index 0000000..f371fbe --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/util/RocketStructure.java @@ -0,0 +1,138 @@ +package net.xevianlight.aphelion.util; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.nbt.*; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; + +import java.util.ArrayList; +import java.util.List; + +public final class RocketStructure { + + + private final List palette = new ArrayList<>(); + private final IntList packedPositions = new IntArrayList(); + private final IntList paletteIndices = new IntArrayList(); + + public RocketStructure(Builder builder) { + builder.build(this); + } + + @FunctionalInterface + public interface Builder { + void build(RocketStructure s); + } + + public int size() { return packedPositions.size(); } + + public void clear() { + palette.clear(); + packedPositions.clear(); + paletteIndices.clear(); + } + + public void add(int x, int y, int z, BlockState state) { + if (state == Blocks.AIR.defaultBlockState()) return; + int idx = palette.indexOf(state); + if (idx < 0) { + palette.add(state); + idx = palette.size() - 1; + } + + packedPositions.add(packPos(x, y, z)); + paletteIndices.add(idx); // ← REQUIRED + } + + + public BlockState stateAt(int i) { return palette.get(paletteIndices.getInt(i)); } + public int packedPosAt(int i) { return packedPositions.getInt(i); } + + public CompoundTag save() { + CompoundTag tag = new CompoundTag(); + + // palette + ListTag pal = new ListTag(); + for (BlockState st : palette) { + pal.add(BlockState.CODEC.encodeStart(NbtOps.INSTANCE, st) + .getOrThrow()); + } + tag.put("palette", pal); + + // blocks + IntArrayTag posArr = new IntArrayTag(packedPositions.toIntArray()); + IntArrayTag idxArr = new IntArrayTag(paletteIndices.toIntArray()); + tag.put("pos", posArr); + tag.put("idx", idxArr); + + return tag; + } + + public void load(CompoundTag tag) { + clear(); + + // palette + ListTag pal = tag.getList("palette", Tag.TAG_COMPOUND); + for (int i = 0; i < pal.size(); i++) { + Tag stTag = pal.get(i); + BlockState st = BlockState.CODEC.parse(NbtOps.INSTANCE, stTag) + .getOrThrow(); + palette.add(st); + } + + // blocks + int[] pos = tag.getIntArray("pos"); + int[] idx = tag.getIntArray("idx"); + + for (int i = 0; i < pos.length; i++) { + packedPositions.add(pos[i]); + paletteIndices.add(idx[i]); + } + } + + public static int packPos (int x, int y, int z) { + return (x & 0xFF) | ((y & 0xFF) << 8) | ((z & 0xFF) << 16); + } + + public static int unpackX (int p) { return (byte) (p & 0xFF); } + public static int unpackY (int p) { return (byte) (( p >> 8) & 0xFF); } + public static int unpackZ (int p) { return (byte) (( p >> 16) & 0xFF); } + + public record Extents(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + public int sizeX() { return maxX - minX + 1; } + public int sizeY() { return maxY - minY + 1; } + public int sizeZ() { return maxZ - minZ + 1; } + + public AABB toLocalAABB() { + return new AABB(minX - 0.5, minY, minZ - 0.5, maxX + 0.5, maxY + 1, maxZ + 0.5); + } + } + + public Extents computeExtents() { + if (size() == 0) { + return new Extents(0, 0, 0, 0, 0, 0); + } + + int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, minZ = Integer.MAX_VALUE; + int maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE, maxZ = Integer.MIN_VALUE; + + for (int i = 0; i < size(); i++) { + int p = packedPosAt(i); + int x = unpackX(p); + int y = unpackY(p); + int z = unpackZ(p); + + if (x < minX) minX = x; + if (y < minY) minY = y; + if (z < minZ) minZ = z; + + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + if (z > maxZ) maxZ = z; + } + + return new Extents(minX, minY, minZ, maxX, maxY, maxZ); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/util/registries/ModRegistries.java b/src/main/java/net/xevianlight/aphelion/util/registries/ModRegistries.java new file mode 100644 index 0000000..2551616 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/util/registries/ModRegistries.java @@ -0,0 +1,16 @@ +package net.xevianlight.aphelion.util.registries; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.xevianlight.aphelion.Aphelion; +import net.xevianlight.aphelion.planet.Planet; +import net.xevianlight.aphelion.planet.StarSystem; + +public class ModRegistries { + public static final ResourceKey> STAR_SYSTEM = createRegistryKey("star_system"); + public static final ResourceKey> PLANET = createRegistryKey("planet"); + + private static ResourceKey> createRegistryKey(String name) { + return ResourceKey.createRegistryKey(Aphelion.id(name)); + } +} diff --git a/src/main/resources/assets/aphelion/lang/en_us.json b/src/main/resources/assets/aphelion/lang/en_us.json index 29e4c51..d4d5fdf 100644 --- a/src/main/resources/assets/aphelion/lang/en_us.json +++ b/src/main/resources/assets/aphelion/lang/en_us.json @@ -33,11 +33,14 @@ "command.aphelion.station.orbit.get": "Station (%s, %s)'s orbit is assigned to %s", "command.aphelion.station.orbit.get.unassigned": "Station (%s, %s)'s orbit is not assigned", "command.aphelion.station.orbit.cleared": "Cleared station (%s, %s)'s orbit", - "command.aphelion.station.orbit.clearall": "Cleared all station orbits", - "command.aphelion.station.orbit.overwriteall": "Set all existing station orbits with %s (unassigned stations were not affected)", + "command.aphelion.station.orbit.clear_all": "Cleared all station orbits", + "command.aphelion.station.orbit.overwrite_all": "Set all existing station orbits with %s (unassigned stations were not affected)", "command.aphelion.station.orbit.debug.posToKey": "Key of station (%s, %s) is %s", "command.aphelion.station.orbit.debug.keyToPos": "Key %s belongs to station %s", "command.aphelion.station.teleport.success": "Teleported %s to station %s, id: %s", "command.aphelion.station.teleport.failure": "Failed to teleport, entity is null", - "command.aphelion.station.orbit.debug.getPartition": "Partition of %s, %s is %s" + "command.aphelion.station.teleport.failure.invalid_level": "Failed to teleport, target level is null", + "command.aphelion.station.orbit.debug.getPartition": "Partition of %s, %s is %s", + "command.aphelion.rocket.entity_invalid": "Entity is not a valid rocket", + "command.aphelion.rocket.spawn.success": "Summoned new rocket" } diff --git a/src/main/resources/data/aphelion/planet/overworld.json b/src/main/resources/data/aphelion/planet/overworld.json new file mode 100644 index 0000000..763f65d --- /dev/null +++ b/src/main/resources/data/aphelion/planet/overworld.json @@ -0,0 +1,5 @@ +{ + "dimension": "minecraft:overworld", + "orbit_distance": 1, + "star_system": "aphelon:sol" +} \ No newline at end of file