From 2496e0cdd5474c460fa5b89de671f6c14ae27ad7 Mon Sep 17 00:00:00 2001
From: XevianLight <63034748+XevianLight@users.noreply.github.com>
Date: Sat, 28 Mar 2026 19:56:15 -0600
Subject: [PATCH] Basic StationRocketEngineBlock functionality.
StationFlightComputerBlock simply sets traveling to true. Rocket crash fixes,
---
.../2d1f2c039f0862e5e3cc1b1be2d8239e0b04ec90 | 3 +-
.../minecraft/tags/fluid/rocket_fuel.json | 5 +
.../net/xevianlight/aphelion/Aphelion.java | 7 +-
.../block/custom/BasicRocketContainer.java | 15 +++
.../custom/StationFlightComputerBlock.java | 42 ++++++++
.../custom/StationRocketEngineBlock.java | 99 +++++++++++++++++++
.../custom/base/BaseRocketContainer.java | 29 ++++++
.../block/custom/base/BasicEntityBlock.java | 4 +
.../block/custom/base/StationEngineBlock.java | 27 +++++
.../base/StationRocketEngineBlockEntity.java | 32 ------
.../custom/base/TickableBlockEntity.java | 4 +
.../custom/RocketAssemblerBlockEntity.java | 44 ++++++++-
.../StationFlightComputerBlockEntity.java | 61 ++++++++++++
.../StationRocketEngineBlockEntity.java | 90 +++++++++++++++++
.../custom/base/StationEngineBlockEntity.java | 30 +-----
.../aphelion/client/AphelionDebugOverlay.java | 11 ++-
.../client/dimension/SpaceSkyEffects.java | 4 +-
.../aphelion/core/init/ModBlockEntities.java | 11 +++
.../aphelion/core/init/ModBlocks.java | 20 ++--
.../aphelion/core/init/ModCreativeTabs.java | 1 +
.../aphelion/core/init/ModFluidTags.java | 18 ++++
.../aphelion/core/init/ModItems.java | 3 +
.../saveddata/SpacePartitionSavedData.java | 2 +-
.../core/saveddata/types/PartitionData.java | 70 ++++++++++++-
.../datagen/ModFluidTagsProvider.java | 3 +
.../entites/vehicles/RocketEntity.java | 33 +++++--
.../aphelion/event/ModBusEvents.java | 7 +-
.../aphelion/fluid/BaseFluidType.java | 15 +++
.../aphelion/fluid/ModFluidTypes.java | 44 +++++++--
.../xevianlight/aphelion/fluid/ModFluids.java | 18 +++-
.../planet/AphelionPlanetJSONLoader.java | 1 -
.../xevianlight/aphelion/planet/Orbit.java | 12 +++
.../xevianlight/aphelion/planet/Planet.java | 4 +-
.../aphelion/planet/PlanetCache.java | 13 +++
.../util/registries/ModRegistries.java | 2 +
.../dimension_renderers/orbit/overworld.json | 13 +++
.../resources/data/aphelion/planet/mars.json | 8 ++
.../data/aphelion/planet/overworld.json | 3 +-
38 files changed, 705 insertions(+), 103 deletions(-)
create mode 100644 src/generated/resources/data/minecraft/tags/fluid/rocket_fuel.json
create mode 100644 src/main/java/net/xevianlight/aphelion/block/custom/BasicRocketContainer.java
create mode 100644 src/main/java/net/xevianlight/aphelion/block/custom/StationFlightComputerBlock.java
create mode 100644 src/main/java/net/xevianlight/aphelion/block/custom/StationRocketEngineBlock.java
create mode 100644 src/main/java/net/xevianlight/aphelion/block/custom/base/BaseRocketContainer.java
create mode 100644 src/main/java/net/xevianlight/aphelion/block/custom/base/StationEngineBlock.java
delete mode 100644 src/main/java/net/xevianlight/aphelion/block/custom/base/StationRocketEngineBlockEntity.java
create mode 100644 src/main/java/net/xevianlight/aphelion/block/entity/custom/StationFlightComputerBlockEntity.java
create mode 100644 src/main/java/net/xevianlight/aphelion/block/entity/custom/StationRocketEngineBlockEntity.java
rename src/main/java/net/xevianlight/aphelion/block/{ => entity}/custom/base/StationEngineBlockEntity.java (62%)
create mode 100644 src/main/java/net/xevianlight/aphelion/core/init/ModFluidTags.java
create mode 100644 src/main/java/net/xevianlight/aphelion/planet/Orbit.java
create mode 100644 src/main/resources/assets/aphelion/dimension_renderers/orbit/overworld.json
create mode 100644 src/main/resources/data/aphelion/planet/mars.json
diff --git a/src/generated/resources/.cache/2d1f2c039f0862e5e3cc1b1be2d8239e0b04ec90 b/src/generated/resources/.cache/2d1f2c039f0862e5e3cc1b1be2d8239e0b04ec90
index 53e0e17..9e2a848 100644
--- a/src/generated/resources/.cache/2d1f2c039f0862e5e3cc1b1be2d8239e0b04ec90
+++ b/src/generated/resources/.cache/2d1f2c039f0862e5e3cc1b1be2d8239e0b04ec90
@@ -1 +1,2 @@
-// 1.21.1 2026-01-11T15:05:33.587044 Tags for minecraft:fluid mod id aphelion
+// 1.21.1 2026-03-14T19:22:23.3145075 Tags for minecraft:fluid mod id aphelion
+36b33555f1ae6c80989afdd9d986ec0883959f49 data/minecraft/tags/fluid/rocket_fuel.json
diff --git a/src/generated/resources/data/minecraft/tags/fluid/rocket_fuel.json b/src/generated/resources/data/minecraft/tags/fluid/rocket_fuel.json
new file mode 100644
index 0000000..3a6348c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/tags/fluid/rocket_fuel.json
@@ -0,0 +1,5 @@
+{
+ "values": [
+ "aphelion:rocket_fuel"
+ ]
+}
\ 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 7cf27cd..6ee310f 100644
--- a/src/main/java/net/xevianlight/aphelion/Aphelion.java
+++ b/src/main/java/net/xevianlight/aphelion/Aphelion.java
@@ -1,6 +1,8 @@
package net.xevianlight.aphelion;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.ItemBlockRenderTypes;
+import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.api.distmarker.Dist;
@@ -127,14 +129,15 @@ public class Aphelion {
@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());
+ ItemBlockRenderTypes.setRenderLayer(ModFluids.ROCKET_FUEL.get(), RenderType.translucent());
+ ItemBlockRenderTypes.setRenderLayer(ModFluids.FLOWING_ROCKET_FUEL.get(), RenderType.translucent());
});
}
@SubscribeEvent
public static void onClientExtensions(RegisterClientExtensionsEvent event) {
event.registerFluidType(((BaseFluidType) ModFluidTypes.OIL_FLUID_TYPE.get()).getClientFluidTypeExtensions(), ModFluidTypes.OIL_FLUID_TYPE.get());
+ event.registerFluidType(((BaseFluidType) ModFluidTypes.ROCKET_FUEL_FLUID_TYPE.get()).getClientFluidTypeExtensions(), ModFluidTypes.ROCKET_FUEL_FLUID_TYPE.get());
}
@SubscribeEvent
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/BasicRocketContainer.java b/src/main/java/net/xevianlight/aphelion/block/custom/BasicRocketContainer.java
new file mode 100644
index 0000000..9dcbb88
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/block/custom/BasicRocketContainer.java
@@ -0,0 +1,15 @@
+package net.xevianlight.aphelion.block.custom;
+
+import net.xevianlight.aphelion.block.custom.base.BaseRocketContainer;
+import net.xevianlight.aphelion.block.custom.base.BaseRocketFuelTank;
+
+public class BasicRocketContainer extends BaseRocketContainer {
+ public BasicRocketContainer(Properties properties) {
+ super(properties);
+ }
+
+ @Override
+ public int getSlotCapacity() {
+ return 9;
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/StationFlightComputerBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/StationFlightComputerBlock.java
new file mode 100644
index 0000000..5a0a1ac
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/block/custom/StationFlightComputerBlock.java
@@ -0,0 +1,42 @@
+package net.xevianlight.aphelion.block.custom;
+
+import com.mojang.serialization.MapCodec;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.BaseEntityBlock;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import net.xevianlight.aphelion.block.custom.base.BasicHorizontalEntityBlock;
+import net.xevianlight.aphelion.block.entity.custom.StationFlightComputerBlockEntity;
+import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class StationFlightComputerBlock extends BasicHorizontalEntityBlock {
+
+ public static final MapCodec CODEC = simpleCodec(StationFlightComputerBlock::new);
+
+ public StationFlightComputerBlock(Properties properties) {
+ super(properties, true);
+ }
+
+ @Override
+ protected @NotNull MapCodec extends BaseEntityBlock> codec() {
+ return CODEC;
+ }
+
+ @Override
+ public @Nullable BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) {
+ return new StationFlightComputerBlockEntity(blockPos, blockState);
+ }
+
+ @Override
+ protected void onRemove(BlockState state, @NotNull Level level, @NotNull BlockPos pos, BlockState newState, boolean movedByPiston) {
+ if (level.getBlockEntity(pos) instanceof StationFlightComputerBlockEntity computerBE) {
+ PartitionData data = computerBE.getData();
+ if (data != null) {
+ data.setTraveling(false);
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/StationRocketEngineBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/StationRocketEngineBlock.java
new file mode 100644
index 0000000..5a7f603
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/block/custom/StationRocketEngineBlock.java
@@ -0,0 +1,99 @@
+package net.xevianlight.aphelion.block.custom;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.sounds.SoundEvent;
+import net.minecraft.sounds.SoundSource;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.ItemInteractionResult;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.phys.BlockHitResult;
+import net.neoforged.neoforge.capabilities.Capabilities;
+import net.neoforged.neoforge.common.SoundActions;
+import net.neoforged.neoforge.fluids.FluidStack;
+import net.neoforged.neoforge.fluids.FluidType;
+import net.neoforged.neoforge.fluids.FluidUtil;
+import net.neoforged.neoforge.fluids.capability.IFluidHandler;
+import net.xevianlight.aphelion.Aphelion;
+import net.xevianlight.aphelion.block.custom.base.StationEngineBlock;
+import net.xevianlight.aphelion.block.entity.custom.StationRocketEngineBlockEntity;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class StationRocketEngineBlock extends StationEngineBlock {
+ public StationRocketEngineBlock(Properties properties) {
+ super(properties);
+ }
+
+ @Override
+ public @Nullable BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) {
+ return new StationRocketEngineBlockEntity(blockPos, blockState);
+ }
+
+ @Override
+ public @NotNull ItemInteractionResult useItemOn(
+ ItemStack stack,
+ BlockState state,
+ Level level,
+ BlockPos pos,
+ Player player,
+ InteractionHand hand,
+ BlockHitResult hit) {
+
+ // Only intercept on client if holding a fluid container, otherwise let block placement through
+ if (level.isClientSide) {
+ return FluidUtil.getFluidHandler(stack).isPresent()
+ ? ItemInteractionResult.SUCCESS
+ : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
+ }
+
+ BlockEntity be = level.getBlockEntity(pos);
+ if (!(be instanceof StationRocketEngineBlockEntity engineBE)) {
+ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
+ }
+
+ IFluidHandler tankHandler = level.getCapability(
+ Capabilities.FluidHandler.BLOCK, pos, state, be, null
+ );
+
+ if (tankHandler == null) {
+ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
+ }
+
+ FluidStack fluidBeforeInteraction = FluidUtil.getFluidContained(player.getItemInHand(hand))
+ .orElse(FluidStack.EMPTY);
+
+ boolean success = FluidUtil.interactWithFluidHandler(player, hand, tankHandler);
+
+ if (success) {
+ FluidStack tankFluid = tankHandler.getFluidInTank(0);
+ FluidStack relevantFluid = fluidBeforeInteraction.isEmpty() ? tankFluid : fluidBeforeInteraction;
+
+ Aphelion.LOGGER.info("fluidBeforeInteraction: {}", fluidBeforeInteraction);
+ Aphelion.LOGGER.info("tankFluid: {}", tankFluid);
+ Aphelion.LOGGER.info("relevantFluid: {}", relevantFluid);
+
+ if (!relevantFluid.isEmpty()) {
+ FluidType fluidType = relevantFluid.getFluid().getFluidType();
+ SoundEvent sound = fluidBeforeInteraction.isEmpty()
+ ? fluidType.getSound(SoundActions.BUCKET_FILL)
+ : fluidType.getSound(SoundActions.BUCKET_EMPTY);
+
+ Aphelion.LOGGER.info("fluidType: {}", fluidType);
+ Aphelion.LOGGER.info("sound: {}", sound);
+
+ if (sound != null) {
+ Aphelion.LOGGER.info("Playing sound!");
+ level.playSound(null, pos, sound, SoundSource.BLOCKS, 1.0F, 1.0F);
+ }
+ }
+
+ return ItemInteractionResult.CONSUME;
+ }
+
+ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/BaseRocketContainer.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/BaseRocketContainer.java
new file mode 100644
index 0000000..4bb6cbb
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/block/custom/base/BaseRocketContainer.java
@@ -0,0 +1,29 @@
+package net.xevianlight.aphelion.block.custom.base;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.SoundType;
+
+public class BaseRocketContainer extends Block implements IRocketInventoryUpgrade {
+ public BaseRocketContainer(Properties properties) {
+ super(properties);
+ }
+
+ 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 int getSlotCapacity() {
+ return 0;
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicEntityBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicEntityBlock.java
index 402cf68..0f508ce 100644
--- a/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicEntityBlock.java
+++ b/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicEntityBlock.java
@@ -29,6 +29,10 @@ public abstract class BasicEntityBlock extends BaseEntityBlock {
return RenderShape.MODEL;
}
+ public static Properties getProperties() {
+ return Properties.of();
+ }
+
public static Item.Properties getItemProperties() {
return new Item.Properties();
}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/StationEngineBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/StationEngineBlock.java
new file mode 100644
index 0000000..b77e9d6
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/block/custom/base/StationEngineBlock.java
@@ -0,0 +1,27 @@
+package net.xevianlight.aphelion.block.custom.base;
+
+import com.mojang.serialization.MapCodec;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.block.BaseEntityBlock;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import org.jetbrains.annotations.Nullable;
+
+public class StationEngineBlock extends BasicEntityBlock {
+
+ public static final MapCodec CODEC = simpleCodec(StationEngineBlock::new);
+
+ protected StationEngineBlock(Properties properties) {
+ super(properties, true);
+ }
+
+ @Override
+ protected MapCodec extends BaseEntityBlock> codec() {
+ return CODEC;
+ }
+
+ @Override
+ public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
+ return null;
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/StationRocketEngineBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/StationRocketEngineBlockEntity.java
deleted file mode 100644
index da83d25..0000000
--- a/src/main/java/net/xevianlight/aphelion/block/custom/base/StationRocketEngineBlockEntity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.xevianlight.aphelion.block.custom.base;
-
-import net.minecraft.core.BlockPos;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.block.entity.BlockEntityType;
-import net.minecraft.world.level.block.state.BlockState;
-import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
-import net.xevianlight.aphelion.util.Constants;
-
-public class StationRocketEngineBlockEntity extends StationEngineBlockEntity {
-
- /// Seconds to travel 1 AU
- private final double SECONDS_PER_AU = 60;
- /// AU per tick
- private final double SPEED = 1/(SECONDS_PER_AU*20);
-
- @Override
- public double getTravelSpeed() {
- return SPEED;
- }
-
- protected StationRocketEngineBlockEntity(BlockEntityType> type, BlockPos pos, BlockState blockState) {
- // TODO change type to ModBlockEntities.STATION_ROCKET_ENGINE_BLOCK_ENTITY.get()
- super(type, pos, blockState);
- }
-
- @Override
- public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
- super.serverTick(level, time, state, pos); // IMPORTANT!!!
- }
-}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/TickableBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/TickableBlockEntity.java
index 131f9f1..2e8a196 100644
--- a/src/main/java/net/xevianlight/aphelion/block/custom/base/TickableBlockEntity.java
+++ b/src/main/java/net/xevianlight/aphelion/block/custom/base/TickableBlockEntity.java
@@ -58,6 +58,8 @@ public interface TickableBlockEntity {
* Implementations should return {@code true} once initialization has finished
* to prevent {@code firstTick} from running again.
*
+ * Returns {@code true} if not implemented.
+ *
* @return {@code true} if initialization has completed, {@code false} otherwise
*/
default boolean isInitialized() {
@@ -74,6 +76,8 @@ public interface TickableBlockEntity {
* Implementations should perform any required setup and ensure that
* {@code isInitialized()} returns {@code true} afterward.
*
+ * Will never run if {@link #isInitialized()} is not implemented.
+ *
* @param level the level the block entity exists in
* @param state the current block state
* @param pos the world position of the block entity
diff --git a/src/main/java/net/xevianlight/aphelion/block/entity/custom/RocketAssemblerBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/RocketAssemblerBlockEntity.java
index 44d4b15..2700ac1 100644
--- a/src/main/java/net/xevianlight/aphelion/block/entity/custom/RocketAssemblerBlockEntity.java
+++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/RocketAssemblerBlockEntity.java
@@ -33,13 +33,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.List;
public class RocketAssemblerBlockEntity extends BlockEntity implements TickableBlockEntity {
Direction facing;
BlockPos padScanStart = BlockPos.ZERO;
private PadInfo padBounds;
- RocketEntity lastRocket;
private @Nullable PartitionData data;
@@ -296,14 +297,17 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
if (level == null) return null;
RocketStructure structure = scan();
RocketEntity rocket = null;
- if (lastRocket != null)
- lastRocket.disassemble();
+
+ var rockets = getRocketsInPad();
+ if (rockets.size() == 1) rocket = rockets.getFirst();
+ if (rocket != null)
+ rocket.disassemble();
+
if (structure != null && seatPos != null) {
RocketStructure.clearCaptured(level, seatPos, structure);
rocket = RocketEntity.spawnRocket(level, seatPos, structure);
Aphelion.LOGGER.info("Spawn rocket result: {}", rocket);
}
- lastRocket = rocket;
return rocket;
}
@@ -373,6 +377,38 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
return s.is(TOWER_BLOCK);
}
+ public @NotNull List getRocketsInPad() {
+ if (level == null || padBounds == null) return List.of();
+
+ AABB padBox = new AABB(
+ padBounds.min().getX(),
+ padBounds.min().getY(),
+ padBounds.min().getZ(),
+ padBounds.max().getX() + 1,
+ padBounds.max().getY() + 1,
+ padBounds.max().getZ() + 1
+ );
+
+ var rockets = new ArrayList<>(level.getEntitiesOfClass(RocketEntity.class, padBox.inflate(0.2)));
+
+ List found = new java.util.ArrayList<>(List.of());
+
+ for (RocketEntity rocket : rockets) {
+ AABB rocketBox = rocket.getBoundingBox();
+ if (!isFullyInside(padBox, rocketBox)) continue;
+
+ found.add(rocket);
+ }
+
+ return found;
+ }
+
+ private static boolean isFullyInside(AABB outer, AABB inner) {
+ return inner.minX >= outer.minX && inner.maxX <= outer.maxX
+ && inner.minY >= outer.minY && inner.maxY <= outer.maxY
+ && inner.minZ >= outer.minZ && inner.maxZ <= outer.maxZ;
+ }
+
@Override
protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) {
super.saveAdditional(tag, registries);
diff --git a/src/main/java/net/xevianlight/aphelion/block/entity/custom/StationFlightComputerBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/StationFlightComputerBlockEntity.java
new file mode 100644
index 0000000..ae1af7a
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/StationFlightComputerBlockEntity.java
@@ -0,0 +1,61 @@
+package net.xevianlight.aphelion.block.entity.custom;
+
+import net.minecraft.client.multiplayer.ClientLevel;
+import net.minecraft.core.BlockPos;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
+import net.xevianlight.aphelion.core.init.ModBlockEntities;
+import net.xevianlight.aphelion.core.init.ModDimensions;
+import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
+import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
+import org.jetbrains.annotations.Nullable;
+
+public class StationFlightComputerBlockEntity extends BlockEntity implements TickableBlockEntity {
+ public StationFlightComputerBlockEntity(BlockPos pos, BlockState blockState) {
+ super(ModBlockEntities.STATION_FLIGHT_COMPUTER_BLOCK_ENTITY.get(), pos, blockState);
+ }
+
+ protected PartitionData data;
+ private boolean isInitialized = false;
+
+ @Override
+ public void clientTick(ClientLevel level, long time, BlockState state, BlockPos pos) {
+
+ }
+
+ @Override
+ public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
+ if (data == null) return;
+ data.setTraveling(true);
+ }
+
+ public @Nullable PartitionData getData() {
+ return data;
+ }
+
+ @Override
+ public void firstTick(Level level, BlockState state, BlockPos pos) {
+ if (level.isClientSide()) return;
+ if (level instanceof ServerLevel serverLevel) {
+ if (serverLevel.dimension() == ModDimensions.SPACE) {
+ data = SpacePartitionSavedData.get(serverLevel).getDataForBlockPos(pos);
+
+ }
+ }
+ isInitialized = true;
+ }
+
+ protected boolean setTraveling(boolean value) {
+ if (data == null) return false;
+ data.setTraveling(value);
+ return true;
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return isInitialized;
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/block/entity/custom/StationRocketEngineBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/StationRocketEngineBlockEntity.java
new file mode 100644
index 0000000..dd34ff7
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/StationRocketEngineBlockEntity.java
@@ -0,0 +1,90 @@
+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.nbt.CompoundTag;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.network.protocol.game.ClientGamePacketListener;
+import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.block.state.BlockState;
+import net.neoforged.neoforge.fluids.capability.IFluidHandler;
+import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
+import net.xevianlight.aphelion.block.entity.custom.base.StationEngineBlockEntity;
+import net.xevianlight.aphelion.core.init.ModBlockEntities;
+import net.xevianlight.aphelion.core.init.ModFluidTags;
+
+public class StationRocketEngineBlockEntity extends StationEngineBlockEntity {
+
+ /// Seconds to travel 1 AU
+ private final double SECONDS_PER_AU = 60;
+ /// AU per tick
+ private final double SPEED = 1/(SECONDS_PER_AU*20);
+ /// Fuel consumption per tick in millibuckets
+ private static final int FUEL_CONSUMPTION = 10;
+
+ private FluidTank tank = new FluidTank(
+ 2000,
+ fluidStack -> fluidStack.is(ModFluidTags.ROCKET_FUEL)
+ );
+
+ @Override
+ public double getTravelSpeed() {
+ return SPEED;
+ }
+
+ public IFluidHandler getFluidStorage(Direction direction) {
+ return tank;
+ }
+
+ public StationRocketEngineBlockEntity(BlockPos pos, BlockState blockState) {
+ super(ModBlockEntities.STATION_ROCKET_ENGINE_BLOCK_ENTITY.get(), pos, blockState);
+ }
+
+ @Override
+ public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
+ super.serverTick(level, time, state, pos);
+ burn();
+ }
+
+ private void burn() {
+ if (data == null)
+ return;
+
+ if (data.getDestination() != null && data.isTraveling()) {
+ if (!tank.isEmpty() && tank.getFluid().is(ModFluidTags.ROCKET_FUEL) && tank.getFluidAmount() >= FUEL_CONSUMPTION) { // has enough fuel?
+ if (data.travel(getTravelSpeed()))
+ tank.drain(FUEL_CONSUMPTION, IFluidHandler.FluidAction.EXECUTE);
+ } else {
+ // not enough fuel
+ }
+ }
+ }
+
+ @Override
+ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+ super.saveAdditional(tag, registries);
+ tag.put("fluid", tank.writeToNBT(registries, new CompoundTag()));
+ }
+
+ @Override
+ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+ super.loadAdditional(tag, registries);
+ if (tag.contains("fluid")) {
+ tank.readFromNBT(registries, tag.getCompound("fluid"));
+ }
+ }
+
+ @Override
+ public CompoundTag getUpdateTag(HolderLookup.Provider registries) {
+ CompoundTag tag = new CompoundTag();
+ saveAdditional(tag, registries);
+ return tag;
+ }
+
+ @Override
+ public Packet getUpdatePacket() {
+ return ClientboundBlockEntityDataPacket.create(this);
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/StationEngineBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/base/StationEngineBlockEntity.java
similarity index 62%
rename from src/main/java/net/xevianlight/aphelion/block/custom/base/StationEngineBlockEntity.java
rename to src/main/java/net/xevianlight/aphelion/block/entity/custom/base/StationEngineBlockEntity.java
index 646865e..187a543 100644
--- a/src/main/java/net/xevianlight/aphelion/block/custom/base/StationEngineBlockEntity.java
+++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/base/StationEngineBlockEntity.java
@@ -1,4 +1,4 @@
-package net.xevianlight.aphelion.block.custom.base;
+package net.xevianlight.aphelion.block.entity.custom.base;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
@@ -7,6 +7,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
+import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
import net.xevianlight.aphelion.core.init.ModDimensions;
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
@@ -16,7 +17,7 @@ import javax.annotation.Nullable;
public abstract class StationEngineBlockEntity extends BlockEntity implements TickableBlockEntity {
private boolean isInitialized = false;
- private @Nullable PartitionData data;
+ protected @Nullable PartitionData data;
/**
* The travel speed in AU/tick.
@@ -32,31 +33,9 @@ public abstract class StationEngineBlockEntity extends BlockEntity implements Ti
}
- /**
- * Handles station travel logic for this engine.
- *
- * If the associated station is currently traveling, this method advances
- * its movement using the value returned by {@link #getTravelSpeed()}.
- *
- * Subclasses may override this method to add additional server-side behavior.
- * When doing so, {@code super.serverTick(...)} should be called to preserve
- * the default travel logic.
- *
- * This method is invoked once per server tick.
- *
- * @param level the server level the block entity exists in
- * @param time the current tick time offset used for scheduling
- * @param state the current block state
- * @param pos the world position of the block entity
- */
@Override
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
- double speed = getTravelSpeed();
- if (data != null) {
- if (data.isTraveling()) {
- data.travel(speed);
- }
- }
+
}
@Override
@@ -70,6 +49,7 @@ public abstract class StationEngineBlockEntity extends BlockEntity implements Ti
if (level instanceof ServerLevel serverLevel) {
if (serverLevel.dimension() == ModDimensions.SPACE) {
data = SpacePartitionSavedData.get(serverLevel).getDataForBlockPos(pos);
+ data.addEngine(pos);
}
}
isInitialized = true;
diff --git a/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java b/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java
index 0ca6784..8ceee27 100644
--- a/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java
+++ b/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java
@@ -49,11 +49,16 @@ public class AphelionDebugOverlay {
// Left side of F3
event.getLeft().add("");
event.getLeft().add("Aphelion:");
- event.getLeft().add(" Orbit: " + orbitId);
+ event.getLeft().add(" Orbit: " + PartitionClientState.lastData().getOrbit());
// event.getLeft().add(" Sky: " + rendererSummary);
event.getLeft().add(" Station: " + x + " " + z + " ID: " + SpacePartitionSavedData.pack(x,z));
- event.getLeft().add(" Station Destination:" + PartitionClientState.lastData().getDestination());
- event.getLeft().add(" Station Owner:" + PartitionClientState.lastData().getOwner());
+ event.getLeft().add(" Station Destination: " + PartitionClientState.lastData().getDestination());
+ event.getLeft().add(" Station Owner: " + PartitionClientState.lastData().getOwner());
+ event.getLeft().add(" Station Engines: " + PartitionClientState.lastData().getEngines().toArray().length);
+ event.getLeft().add(" Station Landing Pads: " + PartitionClientState.lastData().getLandingPadContollersAsArray().length);
+ event.getLeft().add(" Station Traveling: " + PartitionClientState.lastData().isTraveling());
+ event.getLeft().add(" Station Trip Distance AU: " + PartitionClientState.lastData().getTripDistanceAU());
+ event.getLeft().add(" Station Distance Traveled AU: " + PartitionClientState.lastData().getDistanceTraveledAU());
var server = mc.getSingleplayerServer();
ServerLevel singlePlayerLevel;
if (server != null) {
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 7d6224d..7bc4090 100644
--- a/src/main/java/net/xevianlight/aphelion/client/dimension/SpaceSkyEffects.java
+++ b/src/main/java/net/xevianlight/aphelion/client/dimension/SpaceSkyEffects.java
@@ -75,12 +75,10 @@ public class SpaceSkyEffects extends DimensionSpecialEffects {
// int px = PartitionClientState.pxOr(0);
// int py = PartitionClientState.pyOr(0);
- var data = ResourceLocation.parse(PartitionClientState.idOrUnknown());
// var partitionData = SpacePartitionSavedData.get(serverLevel).getOrbitForPartition((int) x, (int) z);
- if (data != null) return data;
+ return ResourceLocation.parse(PartitionClientState.idOrUnknown());
- return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
}
}
diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java b/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java
index a2b7a13..d1fdfc8 100644
--- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java
+++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java
@@ -4,6 +4,7 @@ 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.StationRocketEngineBlockEntity;
import net.xevianlight.aphelion.block.dummy.entity.VAFMultiblockDummyBlockEntity;
import net.xevianlight.aphelion.block.entity.custom.*;
@@ -51,4 +52,14 @@ public class ModBlockEntities {
BLOCK_ENTITIES.register("rocket_assembler_block_entity", () -> BlockEntityType.Builder.of(
RocketAssemblerBlockEntity::new, ModBlocks.ROCKET_ASSEMBLER.get()).build(null)
);
+
+ public static final Supplier> STATION_ROCKET_ENGINE_BLOCK_ENTITY =
+ BLOCK_ENTITIES.register("station_rocket_engine_block_entity", () -> BlockEntityType.Builder.of(
+ StationRocketEngineBlockEntity::new, ModBlocks.STATION_ROCKET_ENGINE.get()).build(null)
+ );
+
+ public static final Supplier> STATION_FLIGHT_COMPUTER_BLOCK_ENTITY =
+ BLOCK_ENTITIES.register("station_flight_computer_block_entity", () -> BlockEntityType.Builder.of(
+ StationFlightComputerBlockEntity::new, ModBlocks.STATION_FLIGHT_COMPUTER_BLOCK.get()).build(null)
+ );
}
diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java
index ca922bc..6edc76d 100644
--- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java
+++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java
@@ -10,15 +10,19 @@ import net.xevianlight.aphelion.block.dummy.VAFMultiblockDummyBlock;
public class ModBlocks {
public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(Aphelion.MOD_ID);
- public static final DeferredBlock TEST_BLOCK = BLOCKS.register("test_block", () -> new TestBlock(TestBlock.getProperties()));
- public static final DeferredBlock BLOCK_STEEL = BLOCKS.register("block_steel", () -> new BlockSteel(BlockSteel.getProperties()));
- public static final DeferredBlock LAUNCH_PAD = BLOCKS.register("launch_pad", () -> new LaunchPad(LaunchPad.getProperties()));
- public static final DeferredBlock DIMENSION_CHANGER = BLOCKS.register("dimension_changer", () -> new DimensionChangerBlock(DimensionChangerBlock.getProperties()));
- public static final DeferredBlock ELECTRIC_ARC_FURNACE = BLOCKS.register("electric_arc_furnace", () -> new ElectricArcFurnace(ElectricArcFurnace.getProperties()));
- public static final DeferredBlock ARC_FURNACE_CASING_BLOCK = BLOCKS.register("arc_furnace_casing", () -> new ArcFurnaceCasingBlock(ArcFurnaceCasingBlock.getProperties()));
- public static final DeferredBlock VACUUM_ARC_FURNACE_CONTROLLER = BLOCKS.register("vacuum_arc_furnace_controller", () -> new VacuumArcFurnaceController(VacuumArcFurnaceController.getProperties()));
- public static final DeferredBlock VAF_MULTIBLOCK_DUMMY_BLOCK = BLOCKS.register("vaf_dummy_block", () -> new VAFMultiblockDummyBlock(VAFMultiblockDummyBlock.getProperties()));
+ public static final DeferredBlock TEST_BLOCK = BLOCKS.register("test_block", () -> new TestBlock(TestBlock.getProperties()));
+ public static final DeferredBlock BLOCK_STEEL = BLOCKS.register("block_steel", () -> new BlockSteel(BlockSteel.getProperties()));
+ public static final DeferredBlock LAUNCH_PAD = BLOCKS.register("launch_pad", () -> new LaunchPad(LaunchPad.getProperties()));
+ public static final DeferredBlock DIMENSION_CHANGER = BLOCKS.register("dimension_changer", () -> new DimensionChangerBlock(DimensionChangerBlock.getProperties()));
+ public static final DeferredBlock ELECTRIC_ARC_FURNACE = BLOCKS.register("electric_arc_furnace", () -> new ElectricArcFurnace(ElectricArcFurnace.getProperties()));
+ public static final DeferredBlock ARC_FURNACE_CASING_BLOCK = BLOCKS.register("arc_furnace_casing", () -> new ArcFurnaceCasingBlock(ArcFurnaceCasingBlock.getProperties()));
+ public static final DeferredBlock VACUUM_ARC_FURNACE_CONTROLLER = BLOCKS.register("vacuum_arc_furnace_controller", () -> new VacuumArcFurnaceController(VacuumArcFurnaceController.getProperties()));
+ public static final DeferredBlock VAF_MULTIBLOCK_DUMMY_BLOCK = BLOCKS.register("vaf_dummy_block", () -> new VAFMultiblockDummyBlock(VAFMultiblockDummyBlock.getProperties()));
public static final DeferredBlock OXYGEN_TEST_BLOCK = BLOCKS.register("oxygen_test_block", () -> new OxygenTestBlock(OxygenTestBlock.getProperties()));
public static final DeferredBlock ROCKET_ASSEMBLER = BLOCKS.register("rocket_assembler", () -> new RocketAssembler(RocketAssembler.getProperties()));
public static final DeferredBlock ROCKET_SEAT = BLOCKS.register("rocket_seat", () -> new RocketSeat(RocketSeat.getProperties()));
+ public static final DeferredBlock STATION_ROCKET_ENGINE = BLOCKS.register("station_rocket_engine", () -> new StationRocketEngineBlock(StationRocketEngineBlock.getProperties()));
+ public static final DeferredBlock BASIC_ROCKET_FUEL_TANK = BLOCKS.register("basic_rocket_fuel_tank", () -> new BasicRocketFuelTank(BasicRocketFuelTank.getProperties()));
+ public static final DeferredBlock BASIC_ROCKET_CONTAINER = BLOCKS.register("basic_rocket_container", () -> new BasicRocketContainer(BasicRocketContainer.getProperties()));
+ public static final DeferredBlock STATION_FLIGHT_COMPUTER_BLOCK = BLOCKS.register("station_flight_computer", () -> new StationFlightComputerBlock(StationFlightComputerBlock.getProperties()));
}
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 d997703..6ddffed 100644
--- a/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java
+++ b/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java
@@ -28,6 +28,7 @@ public class ModCreativeTabs {
output.accept(ModItems.INGOT_NEODYMIUM);
output.accept(ModItems.INGOT_IRIDIUM);
output.accept(ModFluids.OIL_BUCKET);
+ output.accept(ModFluids.ROCKET_FUEL_BUCKET);
output.accept(ModItems.MUSIC_DISC_BIT_SHIFT);
}).build());
diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModFluidTags.java b/src/main/java/net/xevianlight/aphelion/core/init/ModFluidTags.java
new file mode 100644
index 0000000..e8e41e2
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/core/init/ModFluidTags.java
@@ -0,0 +1,18 @@
+package net.xevianlight.aphelion.core.init;
+
+import net.minecraft.core.registries.Registries;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.tags.TagKey;
+import net.minecraft.world.level.material.Fluid;
+
+public class ModFluidTags {
+ public static final TagKey ROCKET_FUEL = create("rocket_fuel");
+
+ private static TagKey create(String name) {
+ return TagKey.create(Registries.FLUID, ResourceLocation.withDefaultNamespace(name));
+ }
+
+ public static TagKey create(ResourceLocation name) {
+ return TagKey.create(Registries.FLUID, name);
+ }
+}
diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java b/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java
index b513112..10b610f 100644
--- a/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java
+++ b/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java
@@ -38,5 +38,8 @@ public static final DeferredItem- MUSIC_DISC_BIT_SHIFT = ITEMS.register("mu
public static final DeferredItem LAUNCH_PAD = ITEMS.register("launch_pad", () -> new BlockItem(ModBlocks.LAUNCH_PAD.get(), LaunchPad.getItemProperties()));
public static final DeferredItem ROCKET_ASSEMBLER = ITEMS.register("rocket_assembler", () -> new BlockItem(ModBlocks.ROCKET_ASSEMBLER.get(), RocketAssembler.getItemProperties()));
public static final DeferredItem ROCKET_SEAT = ITEMS.register("rocket_seat", () -> new BlockItem(ModBlocks.ROCKET_SEAT.get(), RocketSeat.getItemProperties()));
+ public static final DeferredItem STATION_ROCKET_ENGINE = ITEMS.register("station_rocket_engine", () -> new BlockItem(ModBlocks.STATION_ROCKET_ENGINE.get(), StationRocketEngineBlock.getItemProperties()));
+ public static final DeferredItem BASIC_ROCKET_FUEL_TANK = ITEMS.register("basic_rocket_fuel_tank", () -> new BlockItem(ModBlocks.BASIC_ROCKET_FUEL_TANK.get(), BasicRocketFuelTank.getItemProperties()));
+ public static final DeferredItem BASIC_ROCKET_CONTAINER = ITEMS.register("basic_rocket_container", () -> new BlockItem(ModBlocks.BASIC_ROCKET_CONTAINER.get(), BasicRocketContainer.getItemProperties()));
// public static final DeferredItem VAF_MULTIBLOCK_DUMMY_BLOCK = ITEMS.register("vaf_multiblock_dummy_block", () -> new BlockItem(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), VAFMultiblockDummyBlock.getItemProperties()));
}
diff --git a/src/main/java/net/xevianlight/aphelion/core/saveddata/SpacePartitionSavedData.java b/src/main/java/net/xevianlight/aphelion/core/saveddata/SpacePartitionSavedData.java
index 209f25c..8fa81d3 100644
--- a/src/main/java/net/xevianlight/aphelion/core/saveddata/SpacePartitionSavedData.java
+++ b/src/main/java/net/xevianlight/aphelion/core/saveddata/SpacePartitionSavedData.java
@@ -105,7 +105,7 @@ public class SpacePartitionSavedData extends SavedData {
e.putBoolean("Traveling", pd.isTraveling());
e.putDouble("DistanceTraveled", pd.getDistanceTraveledAU());
- e.putDouble("DistanceToDest", pd.getTripDistanceAU());
+ e.putDouble("DistanceToDest", pd.recalculateTripDistAU());
if (pd.getOwner() != null) {
e.putUUID("Owner", pd.getOwner());
diff --git a/src/main/java/net/xevianlight/aphelion/core/saveddata/types/PartitionData.java b/src/main/java/net/xevianlight/aphelion/core/saveddata/types/PartitionData.java
index 25a80bf..baf3d2d 100644
--- a/src/main/java/net/xevianlight/aphelion/core/saveddata/types/PartitionData.java
+++ b/src/main/java/net/xevianlight/aphelion/core/saveddata/types/PartitionData.java
@@ -6,6 +6,7 @@ import net.minecraft.core.UUIDUtil;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.ResourceLocation;
+import net.xevianlight.aphelion.planet.PlanetCache;
import net.xevianlight.aphelion.util.BigCodec;
import org.jetbrains.annotations.Nullable;
@@ -26,6 +27,11 @@ public class PartitionData {
private UUID owner;
private List landingPadControllers;
private List engines;
+ private double currentOrbitDistanceAU;
+
+ public PartitionData() {
+
+ }
public PartitionData(@Nullable ResourceLocation orbit) {
this.orbit = orbit;
@@ -36,7 +42,7 @@ public class PartitionData {
this.generated = false;
this.owner = null;
this.landingPadControllers = List.of();
- this.engines = List.of();
+ this.engines = new ArrayList<>(List.of());
}
public PartitionData(PartitionData other) {
@@ -68,7 +74,7 @@ public class PartitionData {
PartitionData::getDistanceTraveledAU,
ByteBufCodecs.DOUBLE,
- PartitionData::getTripDistanceAU,
+ PartitionData::recalculateTripDistAU,
ByteBufCodecs.optional(UUIDUtil.STREAM_CODEC),
d -> Optional.ofNullable(d.getOwner()),
@@ -102,6 +108,8 @@ public class PartitionData {
public void setOrbit(@Nullable ResourceLocation orbit) {
this.orbit = orbit;
+ recalculateTripDistAU();
+ distanceTraveledAU = 0;
}
public @Nullable ResourceLocation getDestination() {
@@ -110,6 +118,8 @@ public class PartitionData {
public void setDestination(@Nullable ResourceLocation destination) {
this.destination = destination;
+ recalculateTripDistAU();
+ distanceTraveledAU = 0;
}
public boolean isTraveling() {
@@ -128,6 +138,19 @@ public class PartitionData {
this.distanceTraveledAU = distanceTraveledAU;
}
+ public double recalculateTripDistAU() {
+ var currentPlanet = PlanetCache.getByOrbitOrNull(orbit);
+ if (currentPlanet == null) {
+ return -1;
+ }
+
+ var destPlanet = PlanetCache.getOrDefault(destination);
+
+ var dist = destPlanet.orbitDistance() - currentPlanet.orbitDistance();
+ this.tripDistanceAU = dist;
+ return dist;
+ }
+
public double getTripDistanceAU() {
return tripDistanceAU;
}
@@ -146,9 +169,20 @@ public class PartitionData {
* distance is set to exactly {@code tripDistanceAU}.
*
* @param distance the distance to advance in astronomical units (AU)
+ * @return {@code true} when we arrive at our destination, {@code false} otherwise.
*/
- public void travel(double distance) {
- distanceTraveledAU = Math.min(distanceTraveledAU + distance, tripDistanceAU);
+ public boolean travel(double distance) {
+ if (distanceTraveledAU + distance > tripDistanceAU) {
+ distanceTraveledAU = tripDistanceAU;
+ var destinationPlanet = PlanetCache.getOrNull(destination);
+ if (destinationPlanet != null) {
+ setOrbit(destinationPlanet.orbit().location());
+ }
+ return false;
+ } else {
+ distanceTraveledAU += distance;
+ return true;
+ }
}
public boolean isGenerated() {
@@ -223,14 +257,40 @@ public class PartitionData {
return landingPadControllers.remove(pos);
}
+ /**
+ * Returns a defensive copy of the world positions of all engines tracked by this partition.
+ *
+ * This method returns only the stored {@link BlockPos} locations of known engines,
+ * not the engine instances or their corresponding block entities. To interact with an
+ * engine, retrieve the block entity from the world using the returned positions.
+ *
+ * It is not guaranteed that an engine exists at every returned position. If changes
+ * fail to synchronize with this partition, the stored data may become inaccurate.
+ * Always verify that the block entity at a given position is an engine before use.
+ *
+ * The returned list is a defensive copy and may be modified without affecting the
+ * underlying partition data. To persist changes, use {@code setEngines(...)}.
+ *
+ * @return a mutable list containing the tracked engine positions
+ */
public List getEngines() {
- return engines;
+ return new ArrayList<>(engines);
}
public void setEngines(List engines) {
this.engines = engines;
}
+ /**
+ * Adds an engine at the specified world position.
+ *
+ * If an engine does not already exist at the given position, it is added
+ * to the internal collection and the method returns {@code true}. If an engine
+ * is already present at that position, no changes are made.
+ *
+ * @param pos the world position of the engine to add
+ * @return {@code true} if the engine was added, {@code false} if it already existed
+ */
public boolean addEngine(BlockPos pos) {
if (!engines.contains(pos)) {
engines.add(pos);
diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModFluidTagsProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModFluidTagsProvider.java
index 8d590e2..4e19667 100644
--- a/src/main/java/net/xevianlight/aphelion/datagen/ModFluidTagsProvider.java
+++ b/src/main/java/net/xevianlight/aphelion/datagen/ModFluidTagsProvider.java
@@ -6,6 +6,7 @@ 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.core.init.ModFluidTags;
import net.xevianlight.aphelion.fluid.ModFluids;
import org.jetbrains.annotations.Nullable;
@@ -22,5 +23,7 @@ public class ModFluidTagsProvider extends FluidTagsProvider {
// tag(FluidTags.LAVA)
// .add(ModFluids.SOURCE_OIL_FLUID.get())
// .add(ModFluids.FLOWING_OIL_FLUID.get());
+ tag(ModFluidTags.ROCKET_FUEL)
+ .add(ModFluids.ROCKET_FUEL.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
index 8034db2..48df7bf 100644
--- a/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEntity.java
+++ b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEntity.java
@@ -44,6 +44,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
+import java.util.UUID;
public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpawn {
@@ -108,7 +109,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
};
}
-
public static RocketEntity spawnRocket(Level level, BlockPos pos, RocketStructure structure) {
if (level.isClientSide) return null;
@@ -122,12 +122,22 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
0.0f
);
- rocket.setStructure(structure);
- level.addFreshEntity(rocket);
+// rocket.FUEL_TANK.setFluid(new FluidStack(ModFluids.OIL.get(), 1000));
+// rocket.INVENTORY.setSize(rocket.INVENTORY.getSlots() + 1);
+// rocket.INVENTORY.insertItem(0, new ItemStack(Items.DIAMOND, 1), false);
- rocket.FUEL_TANK.setFluid(new FluidStack(ModFluids.OIL.get(), 1000));
- rocket.INVENTORY.setSize(rocket.INVENTORY.getSlots() + 1);
- rocket.INVENTORY.insertItem(0, new ItemStack(Items.DIAMOND, 1), false);
+ // Fully initialize structure and containers
+ rocket.setStructure(structure);
+
+ if (rocket.INVENTORY.getSlots() > 0)
+ rocket.INVENTORY.insertItem(0, new ItemStack(Items.DIAMOND), false);
+ if (rocket.FUEL_TANK.getCapacity() != 0)
+ rocket.FUEL_TANK.setFluid(new FluidStack(ModFluids.OIL.get(), 1000));
+ if (rocket.FLUID_STORAGE.getCapacity() != 0)
+ rocket.FLUID_STORAGE.setFluid(FluidStack.EMPTY);
+
+
+ level.addFreshEntity(rocket);
return rocket;
}
@@ -166,6 +176,9 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
if (!level().isClientSide) {
+ if (INVENTORY.getSlots() > 0)
+ INVENTORY.insertItem(0, new ItemStack(Items.DIAMOND, 1), false);
+
switch (getPhase()) {
case IDLE, LANDED -> tickIdle();
case PREPARE -> tickPrepare();
@@ -184,7 +197,10 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
}
- move(MoverType.SELF, getDeltaMovement());
+ // Catch ANY edge cases which may cause a crash trying to move an entity as its chunk is unloading
+ if (!this.isRemoved() && this.isAlive() && level().hasChunkAt(blockPosition())) {
+ move(MoverType.SELF, getDeltaMovement());
+ }
}
private void tickIdle() {
@@ -393,7 +409,7 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
if (tag.contains("RocketStructure")) {
CompoundTag rocketTag = tag.getCompound("RocketStructure");
structure.load(rocketTag);
- recalculateCapacitiesFromStructure();
+// recalculateCapacitiesFromStructure();
// Immediately apply correct bbox on load (server + client)
double x = getX(), y = getY(), z = getZ();
@@ -590,6 +606,7 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
public boolean disassemble() {
if (level().isClientSide) return false;
if (!(level() instanceof ServerLevel server)) return false;
+ Aphelion.LOGGER.info("Disassemble called for rocket: " + getId());
// In rare instances we can disassemble a rocket AFTER it has been killed.
// This usually only happens if another class instance still has a reference to this object stored and calls rocketEntity.disassemble().
diff --git a/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java b/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java
index 4767b1f..1e385e1 100644
--- a/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java
+++ b/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java
@@ -8,13 +8,13 @@ import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.HandlerThread;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import net.xevianlight.aphelion.Aphelion;
+import net.xevianlight.aphelion.block.entity.custom.StationRocketEngineBlockEntity;
import net.xevianlight.aphelion.block.dummy.entity.BaseMultiblockDummyBlockEntity;
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
import net.xevianlight.aphelion.block.entity.custom.VacuumArcFurnaceControllerEntity;
import net.xevianlight.aphelion.core.init.ModBlockEntities;
import net.xevianlight.aphelion.core.init.ModEntities;
-import net.xevianlight.aphelion.entites.vehicles.RocketEntity;
import net.xevianlight.aphelion.network.RocketPayloadHandlers;
import net.xevianlight.aphelion.network.PartitionPayloadHandler;
import net.xevianlight.aphelion.network.packet.PartitionPayload;
@@ -25,15 +25,20 @@ 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);
+
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.VACUUM_ARC_FURNACE_ENTITY.get(), VacuumArcFurnaceControllerEntity::getItemHandler);
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.VACUUM_ARC_FURNACE_ENTITY.get(), VacuumArcFurnaceControllerEntity::getEnergyStorage);
// event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.VAF_MULTIBLOCK_DUMMY_ENTITY.get(), VAFMultiblockDummyBlockEntity::getItemHandler);
+
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.VAF_MULTIBLOCK_DUMMY_ENTITY.get(), BaseMultiblockDummyBlockEntity::getItemHandler);
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.VAF_MULTIBLOCK_DUMMY_ENTITY.get(), BaseMultiblockDummyBlockEntity::getEnergyStorage);
event.registerEntity(Capabilities.ItemHandler.ENTITY, ModEntities.ROCKET.get(), (rocket, ctx) -> rocket.getInventory());
+
+ event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, ModBlockEntities.STATION_ROCKET_ENGINE_BLOCK_ENTITY.get(), StationRocketEngineBlockEntity::getFluidStorage);
}
@SubscribeEvent
diff --git a/src/main/java/net/xevianlight/aphelion/fluid/BaseFluidType.java b/src/main/java/net/xevianlight/aphelion/fluid/BaseFluidType.java
index 3675871..caf4bf9 100644
--- a/src/main/java/net/xevianlight/aphelion/fluid/BaseFluidType.java
+++ b/src/main/java/net/xevianlight/aphelion/fluid/BaseFluidType.java
@@ -7,7 +7,11 @@ import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.sounds.SoundEvent;
+import net.minecraft.sounds.SoundEvents;
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
+import net.neoforged.neoforge.common.SoundAction;
+import net.neoforged.neoforge.common.SoundActions;
import net.neoforged.neoforge.fluids.FluidType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -53,6 +57,17 @@ public class BaseFluidType extends FluidType {
this.fogEnd = fogEnd;
}
+ @Override
+ public @Nullable SoundEvent getSound(SoundAction action) {
+ if (action == SoundActions.BUCKET_FILL) {
+ return SoundEvents.BUCKET_FILL;
+ }
+ if (action == SoundActions.BUCKET_EMPTY) {
+ return SoundEvents.BUCKET_EMPTY;
+ }
+ return super.getSound(action);
+ }
+
public IClientFluidTypeExtensions getClientFluidTypeExtensions() {
return new IClientFluidTypeExtensions() {
@Override
diff --git a/src/main/java/net/xevianlight/aphelion/fluid/ModFluidTypes.java b/src/main/java/net/xevianlight/aphelion/fluid/ModFluidTypes.java
index 61c6435..f4bfa21 100644
--- a/src/main/java/net/xevianlight/aphelion/fluid/ModFluidTypes.java
+++ b/src/main/java/net/xevianlight/aphelion/fluid/ModFluidTypes.java
@@ -8,23 +8,51 @@ import net.neoforged.neoforge.registries.NeoForgeRegistries;
import net.xevianlight.aphelion.Aphelion;
import org.joml.Vector3f;
+import java.awt.*;
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 ResourceLocation WATER_STILL_RL =
+ ResourceLocation.fromNamespaceAndPath("minecraft", "block/water_still");
+
+ public static final ResourceLocation WATER_FLOWING_RL =
+ ResourceLocation.fromNamespaceAndPath("minecraft", "block/water_flow");
+
+ public static final ResourceLocation WATER_OVERLAY_RL =
+ ResourceLocation.fromNamespaceAndPath("minecraft", "block/water_overlay");
+
+ static final Color oilColor = new Color(10, 10, 10, 255);
+ static final Color rocketFuelColor = new Color(73, 59, 28, 255);
public static final DeferredRegister FLUID_TYPES =
DeferredRegister.create(NeoForgeRegistries.Keys.FLUID_TYPES, Aphelion.MOD_ID);
public static final Supplier 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
+ new BaseFluidType(
+ WATER_STILL_RL,
+ WATER_FLOWING_RL,
+ WATER_OVERLAY_RL,
+ oilColor.getRGB(),
+ colToVec(oilColor),
+ FluidType.Properties.create().canDrown(true),
+ 0f,
+ 0.5f
)
);
+
+ public static final Supplier ROCKET_FUEL_FLUID_TYPE = registerFluidType("rocket_fuel",
+ new BaseFluidType(
+ WATER_STILL_RL,
+ WATER_FLOWING_RL,
+ WATER_OVERLAY_RL,
+ rocketFuelColor.getRGB(),
+ colToVec(rocketFuelColor),
+ FluidType.Properties.create().canDrown(true),
+ 0f,
+ 2f)
+ );
+
private static Supplier registerFluidType(String name, FluidType fluidType) {
return FLUID_TYPES.register(name, () -> fluidType);
}
@@ -32,4 +60,8 @@ public class ModFluidTypes {
public static void register(IEventBus eventBus) {
FLUID_TYPES.register(eventBus);
}
+
+ public static Vector3f colToVec (Color color) {
+ return new Vector3f(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f);
+ }
}
diff --git a/src/main/java/net/xevianlight/aphelion/fluid/ModFluids.java b/src/main/java/net/xevianlight/aphelion/fluid/ModFluids.java
index 749ddd7..c4f76db 100644
--- a/src/main/java/net/xevianlight/aphelion/fluid/ModFluids.java
+++ b/src/main/java/net/xevianlight/aphelion/fluid/ModFluids.java
@@ -24,13 +24,29 @@ public class ModFluids {
public static final DeferredRegister FLUIDS =
DeferredRegister.create(BuiltInRegistries.FLUID, Aphelion.MOD_ID);
+ public static final Supplier ROCKET_FUEL = FLUIDS.register("rocket_fuel",
+ () -> new BaseFlowingFluid.Source(ModFluids.ROCKET_FUEL_PROPERTIES));
+ public static final Supplier FLOWING_ROCKET_FUEL = FLUIDS.register("flowing_rocket_fuel",
+ () -> new BaseFlowingFluid.Flowing(ModFluids.ROCKET_FUEL_PROPERTIES));
+
+ public static final DeferredBlock ROCKET_FUEL_BLOCK = ModBlocks.BLOCKS.register("rocket_fuel",
+ () -> new LiquidBlock(ModFluids.ROCKET_FUEL.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable()));
+
+ public static final DeferredItem- ROCKET_FUEL_BUCKET = ModItems.ITEMS.registerItem("rocket_fuel_bucket",
+ properties -> new BucketItem(ModFluids.ROCKET_FUEL.get(), properties.stacksTo(1).craftRemainder(Items.BUCKET)));
+
+ public static final BaseFlowingFluid.Properties ROCKET_FUEL_PROPERTIES = new BaseFlowingFluid.Properties(
+ ModFluidTypes.ROCKET_FUEL_FLUID_TYPE, ROCKET_FUEL, FLOWING_ROCKET_FUEL)
+ .slopeFindDistance(2).levelDecreasePerBlock(2).tickRate(10)
+ .block(ModFluids.ROCKET_FUEL_BLOCK).bucket(ModFluids.ROCKET_FUEL_BUCKET);
+
public static final Supplier OIL = FLUIDS.register("oil",
() -> new BaseFlowingFluid.Source(ModFluids.OIL_PROPERTIES));
public static final Supplier FLOWING_OIL = FLUIDS.register("flowing_oil",
() -> new BaseFlowingFluid.Flowing(ModFluids.OIL_PROPERTIES));
public static final DeferredBlock OIL_BLOCK = ModBlocks.BLOCKS.register("oil",
- () -> new LiquidBlock(ModFluids.OIL.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable()));
+ () -> new LiquidBlock(ModFluids.OIL.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable()));
public static final DeferredItem
- OIL_BUCKET = ModItems.ITEMS.registerItem("oil_bucket",
properties -> new BucketItem(ModFluids.OIL.get(), properties.stacksTo(1).craftRemainder(Items.BUCKET)));
diff --git a/src/main/java/net/xevianlight/aphelion/planet/AphelionPlanetJSONLoader.java b/src/main/java/net/xevianlight/aphelion/planet/AphelionPlanetJSONLoader.java
index f096d7f..aa9685c 100644
--- a/src/main/java/net/xevianlight/aphelion/planet/AphelionPlanetJSONLoader.java
+++ b/src/main/java/net/xevianlight/aphelion/planet/AphelionPlanetJSONLoader.java
@@ -9,7 +9,6 @@ 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;
diff --git a/src/main/java/net/xevianlight/aphelion/planet/Orbit.java b/src/main/java/net/xevianlight/aphelion/planet/Orbit.java
new file mode 100644
index 0000000..eb8a7ac
--- /dev/null
+++ b/src/main/java/net/xevianlight/aphelion/planet/Orbit.java
@@ -0,0 +1,12 @@
+package net.xevianlight.aphelion.planet;
+
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+
+public record Orbit(
+ int temp
+) {
+ public static final Codec CODEC = RecordCodecBuilder.create(inst -> inst.group(
+ Codec.INT.fieldOf("temp").forGetter(Orbit::temp)
+ ).apply(inst, Orbit::new));
+}
diff --git a/src/main/java/net/xevianlight/aphelion/planet/Planet.java b/src/main/java/net/xevianlight/aphelion/planet/Planet.java
index 3e84bd1..48e5eaa 100644
--- a/src/main/java/net/xevianlight/aphelion/planet/Planet.java
+++ b/src/main/java/net/xevianlight/aphelion/planet/Planet.java
@@ -7,8 +7,9 @@ import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
import net.xevianlight.aphelion.util.registries.ModRegistries;
-public record Planet(
+public record Planet (
ResourceKey dimension,
+ ResourceKey orbit,
double orbitDistance,
ResourceKey system,
boolean oxygen,
@@ -16,6 +17,7 @@ public record Planet(
) {
public static final Codec CODEC = RecordCodecBuilder.create(inst -> inst.group(
ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(Planet::dimension),
+ ResourceKey.codec(ModRegistries.ORBIT).fieldOf("orbit").forGetter(Planet::orbit),
Codec.DOUBLE.fieldOf("orbit_distance").forGetter(Planet::orbitDistance),
ResourceKey.codec(ModRegistries.STAR_SYSTEM).fieldOf("star_system").forGetter(Planet::system),
Codec.BOOL.fieldOf("oxygen").forGetter(Planet::oxygen),
diff --git a/src/main/java/net/xevianlight/aphelion/planet/PlanetCache.java b/src/main/java/net/xevianlight/aphelion/planet/PlanetCache.java
index b7d32c6..4659ed4 100644
--- a/src/main/java/net/xevianlight/aphelion/planet/PlanetCache.java
+++ b/src/main/java/net/xevianlight/aphelion/planet/PlanetCache.java
@@ -6,6 +6,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.xevianlight.aphelion.Aphelion;
import net.xevianlight.aphelion.util.registries.ModRegistries;
+import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
@@ -17,6 +18,7 @@ public final class PlanetCache {
public static final Planet DEFAULT = new Planet(
ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")),
+ ResourceKey.create(ModRegistries.ORBIT, Aphelion.id("orbit/overworld")),
1,
ResourceKey.create(ModRegistries.STAR_SYSTEM, Aphelion.id("sol")),
true,
@@ -48,6 +50,17 @@ public final class PlanetCache {
return PLANETS.getOrDefault(id, DEFAULT);
}
+ public static @Nullable Planet getOrNull(ResourceLocation id) {
+ return PLANETS.getOrDefault(id, null);
+ }
+
+ public static @Nullable Planet getByOrbitOrNull(ResourceLocation id) {
+ return PLANETS.values().stream()
+ .filter(planet -> planet.orbit().location().equals(id))
+ .findFirst()
+ .orElse(null);
+ }
+
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/util/registries/ModRegistries.java b/src/main/java/net/xevianlight/aphelion/util/registries/ModRegistries.java
index 2551616..e2cb996 100644
--- a/src/main/java/net/xevianlight/aphelion/util/registries/ModRegistries.java
+++ b/src/main/java/net/xevianlight/aphelion/util/registries/ModRegistries.java
@@ -3,12 +3,14 @@ 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.Orbit;
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");
+ public static final ResourceKey> ORBIT = createRegistryKey("orbit");
private static ResourceKey> createRegistryKey(String name) {
return ResourceKey.createRegistryKey(Aphelion.id(name));
diff --git a/src/main/resources/assets/aphelion/dimension_renderers/orbit/overworld.json b/src/main/resources/assets/aphelion/dimension_renderers/orbit/overworld.json
new file mode 100644
index 0000000..6eb02bc
--- /dev/null
+++ b/src/main/resources/assets/aphelion/dimension_renderers/orbit/overworld.json
@@ -0,0 +1,13 @@
+{
+ "custom_clouds": false,
+ "custom_sky": false,
+ "custom_weather": false,
+ "dimension": "minecraft:overworld",
+ "has_fog": true,
+ "has_thick_fog": false,
+ "render_in_rain": true,
+ "sunrise_angle": 45,
+ "sunrise_color": 14180147,
+ "horizon_height": -128,
+ "clear_color_scale": 1.0
+}
\ No newline at end of file
diff --git a/src/main/resources/data/aphelion/planet/mars.json b/src/main/resources/data/aphelion/planet/mars.json
new file mode 100644
index 0000000..cba3012
--- /dev/null
+++ b/src/main/resources/data/aphelion/planet/mars.json
@@ -0,0 +1,8 @@
+{
+ "dimension": "aphelion:mars",
+ "orbit": "aphelion:orbit/mars",
+ "orbit_distance": 1.5,
+ "star_system": "aphelion:sol",
+ "gravity": 1,
+ "oxygen": false
+}
\ No newline at end of file
diff --git a/src/main/resources/data/aphelion/planet/overworld.json b/src/main/resources/data/aphelion/planet/overworld.json
index d875eb5..210efac 100644
--- a/src/main/resources/data/aphelion/planet/overworld.json
+++ b/src/main/resources/data/aphelion/planet/overworld.json
@@ -1,7 +1,8 @@
{
"dimension": "minecraft:overworld",
+ "orbit": "aphelion:orbit/overworld",
"orbit_distance": 1,
- "star_system": "aphelon:sol",
+ "star_system": "aphelion:sol",
"gravity": 1,
"oxygen": false
}
\ No newline at end of file