diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d index 52e1b85..475924f 100644 --- a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d +++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -1,8 +1,9 @@ -// 1.21.1 2026-01-23T22:32:50.7204827 Loot Tables +// 1.21.1 2026-01-26T19:04:46.4976369 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 +b9cfe672ead8e2673a7b2f5c4cec831e7e8e7040 data/aphelion/loot_table/blocks/launch_pad.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 bea8b37..bc024f0 100644 --- a/src/generated/resources/.cache/9c517586575525115dfb9b0c4d592f540cb43d3e +++ b/src/generated/resources/.cache/9c517586575525115dfb9b0c4d592f540cb43d3e @@ -1,4 +1,5 @@ -// 1.21.1 2026-01-23T22:32:50.7214756 Tags for minecraft:block mod id aphelion +// 1.21.1 2026-01-26T19:04:46.4981336 Tags for minecraft:block mod id aphelion +46f0160a007d32a06624ad98f25e8a1a8d01bb08 data/aphelion/tags/block/launch_pad.json 058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks.json 058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks/steel.json 7d420216f15b8f78d2a3b298f9bb773a9e5f79c3 data/minecraft/tags/block/mineable/pickaxe.json diff --git a/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f b/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f index 5980f6c..444ea84 100644 --- a/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f +++ b/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f @@ -1,4 +1,4 @@ -// 1.21.1 2026-01-18T19:51:57.3548439 Block States: aphelion +// 1.21.1 2026-01-26T20:40:43.8251623 Block States: aphelion 851ff42f7b21dec86107c8e0cefb3934ae4ebc08 assets/aphelion/blockstates/block_steel.json 30b9c0efd7aaadb5412d98e4568f98b3632adbb9 assets/aphelion/blockstates/dimension_changer.json cb4287104006c80c8396b290ab5258df65d62cef assets/aphelion/blockstates/electric_arc_furnace.json diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/LaunchPad.java b/src/main/java/net/xevianlight/aphelion/block/custom/LaunchPad.java new file mode 100644 index 0000000..c6355ef --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/custom/LaunchPad.java @@ -0,0 +1,77 @@ +package net.xevianlight.aphelion.block.custom; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.xevianlight.aphelion.util.ModTags; +import org.jetbrains.annotations.NotNull; + +public class LaunchPad extends Block { + + public static final BooleanProperty NORTH = BlockStateProperties.NORTH; + public static final BooleanProperty EAST = BlockStateProperties.EAST; + public static final BooleanProperty SOUTH = BlockStateProperties.SOUTH; + public static final BooleanProperty WEST = BlockStateProperties.WEST; + + public LaunchPad(Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any() + .setValue(NORTH, false) + .setValue(EAST, false) + .setValue(SOUTH, false) + .setValue(WEST, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(NORTH, EAST, SOUTH, WEST); + } + + private static boolean isPad(BlockState st) { + return st.is(ModTags.Blocks.LAUNCH_PAD); // <- make a tag, recommended + } + + private BlockState withConnections(LevelAccessor level, BlockPos pos, BlockState state) { + return state + .setValue(NORTH, isPad(level.getBlockState(pos.north()))) + .setValue(EAST, isPad(level.getBlockState(pos.east()))) + .setValue(SOUTH, isPad(level.getBlockState(pos.south()))) + .setValue(WEST, isPad(level.getBlockState(pos.west()))); + } + + public static Properties getProperties() { + return Properties + .of() + .sound(SoundType.STONE) + .destroyTime(2f) + .explosionResistance(10f) + .requiresCorrectToolForDrops(); + } + + public static Item.Properties getItemProperties() { + return new Item.Properties(); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + return withConnections(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState()); + } + + @Override + public @NotNull BlockState updateShape(@NotNull BlockState state, Direction dir, @NotNull BlockState neighborState, + @NotNull LevelAccessor level, @NotNull BlockPos pos, @NotNull BlockPos neighborPos) { + if (dir.getAxis().isHorizontal()) { + return withConnections(level, pos, state); + } + return state; + } + +} diff --git a/src/main/java/net/xevianlight/aphelion/client/PartitionClientState.java b/src/main/java/net/xevianlight/aphelion/client/PartitionClientState.java index 89b7869..76cefec 100644 --- a/src/main/java/net/xevianlight/aphelion/client/PartitionClientState.java +++ b/src/main/java/net/xevianlight/aphelion/client/PartitionClientState.java @@ -1,15 +1,15 @@ package net.xevianlight.aphelion.client; -import net.xevianlight.aphelion.network.packet.PartitionData; +import net.xevianlight.aphelion.network.packet.PartitionPayload; import java.util.Optional; public final class PartitionClientState { - private static volatile PartitionData last = null; + private static volatile PartitionPayload last = null; - public static void set(PartitionData d) { last = d; } + public static void set(PartitionPayload d) { last = d; } - public static Optional get() { + public static Optional get() { return Optional.ofNullable(last); } 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 82f43d0..174ee38 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java @@ -12,6 +12,7 @@ public class ModBlocks { 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())); 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 659dda0..7a55913 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModCreativeTabs.java @@ -41,5 +41,6 @@ public class ModCreativeTabs { output.accept(ModItems.BLOCK_STEEL); output.accept(ModItems.ARC_FURNACE_CASING_BLOCK); output.accept(ModItems.VACUUM_ARC_FURNACE_CONTROLLER); + output.accept(ModItems.LAUNCH_PAD); }).build()); } 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 c11f8cf..c6e161e 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java @@ -35,5 +35,6 @@ public static final DeferredItem MUSIC_DISC_BIT_SHIFT = ITEMS.register("mu public static final DeferredItem BLOCK_STEEL = ITEMS.register("block_steel", () -> new BlockItem(ModBlocks.BLOCK_STEEL.get(), BlockSteel.getItemProperties())); public static final DeferredItem ARC_FURNACE_CASING_BLOCK = ITEMS.register("arc_furnace_casing", () -> new BlockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK.get(), ArcFurnaceCasingBlock.getItemProperties())); public static final DeferredItem VACUUM_ARC_FURNACE_CONTROLLER = ITEMS.register("vacuum_arc_furnace_controller", () -> new BlockItem(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get(), VacuumArcFurnaceController.getItemProperties())); + public static final DeferredItem LAUNCH_PAD = ITEMS.register("launch_pad", () -> new BlockItem(ModBlocks.LAUNCH_PAD.get(), LaunchPad.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/init/ModSounds.java b/src/main/java/net/xevianlight/aphelion/core/init/ModSounds.java index f175133..4cdbef5 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModSounds.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModSounds.java @@ -23,6 +23,8 @@ public class ModSounds { public static final Supplier BIT_SHIFT = registerSoundEvent("bit_shift"); public static final ResourceKey BIT_SHIFT_KEY = createSong("bit_shift"); + public static final Supplier ROCKET_ENGINE = registerSoundEvent("rocket_engine"); + private static Supplier registerSoundEvent(String name) { ResourceLocation id = ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, name); return SOUND_EVENTS.register(name, () -> SoundEvent.createVariableRangeEvent(id)); diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java index f8e3ee1..ed1b88f 100644 --- a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java +++ b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java @@ -24,6 +24,7 @@ public class ModBlockLootTableProvider extends BlockLootSubProvider { dropSelf(ModBlocks.ARC_FURNACE_CASING_BLOCK.get()); dropSelf(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get()); dropOther(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), ItemStack.EMPTY.getItem()); + dropSelf(ModBlocks.LAUNCH_PAD.get()); } @Override diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java index e873abb..faf0538 100644 --- a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java +++ b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java @@ -27,6 +27,10 @@ public class ModBlockStateProvider extends BlockStateProvider { blockWithItem(ModBlocks.BLOCK_STEEL); blockWithItem(ModBlocks.DIMENSION_CHANGER); + +// this is already defined ourselves +// blockItem(ModBlocks.LAUNCH_PAD); + blockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK); } diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java index c815000..9316350 100644 --- a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java +++ b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockTagProvider.java @@ -40,5 +40,9 @@ public class ModBlockTagProvider extends BlockTagsProvider { tag(ModTags.Blocks.STORAGE_BLOCKS) .add(ModBlocks.BLOCK_STEEL.get()); + + tag(ModTags.Blocks.LAUNCH_PAD) + .add(ModBlocks.LAUNCH_PAD.get()); + } } diff --git a/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEngineSound.java b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEngineSound.java new file mode 100644 index 0000000..121438c --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEngineSound.java @@ -0,0 +1,42 @@ +package net.xevianlight.aphelion.entites.vehicles; + +import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.sounds.SoundSource; +import net.xevianlight.aphelion.core.init.ModSounds; + +public class RocketEngineSound extends AbstractTickableSoundInstance { + private final RocketEntity rocket; + + public RocketEngineSound (RocketEntity rocket) { + super(ModSounds.ROCKET_ENGINE.get(), SoundSource.AMBIENT, SoundInstance.createUnseededRandom()); + this.rocket = rocket; + + this.looping = true; + this.delay = 0; + this.volume = 1; + this.pitch = 1.0f; + + this.x = rocket.getX(); + this.y = rocket.getY(); + this.z = rocket.getZ(); + } + + @Override + public void tick() { + if (rocket.isRemoved() || rocket.getPhase() != RocketEntity.FlightPhase.ASCEND) { + this.stop(); + return; + } + + // follow entity + this.x = rocket.getX(); + this.y = rocket.getY(); + this.z = rocket.getZ(); + } + + public void killSound() { + stop(); + } + +} 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 43e8198..28a3a60 100644 --- a/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEntity.java +++ b/src/main/java/net/xevianlight/aphelion/entites/vehicles/RocketEntity.java @@ -1,5 +1,6 @@ package net.xevianlight.aphelion.entites.vehicles; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; @@ -10,7 +11,6 @@ import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ColumnPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; @@ -29,14 +29,12 @@ import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.entity.IEntityWithComplexSpawn; import net.neoforged.neoforge.fluids.FluidType; import net.xevianlight.aphelion.Aphelion; -import net.xevianlight.aphelion.core.KeyVariables; import net.xevianlight.aphelion.core.init.ModEntities; import net.xevianlight.aphelion.util.RocketStructure; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Objects; public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpawn { @@ -53,12 +51,11 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa private double landingPosX; private double landingPosZ; - private static final double TELEPORT_Y = 600.0; - private static final double ASCEND_ACCEL = 0.05; - private static final double DESCEND_SPEED = 2; + private static final double TELEPORT_Y = 1000.0; + private static final double ASCEND_ACCEL = 0.0125; + private static final double DESCEND_SPEED = 1; private double yVel = 0.0; - private boolean jumpWasDown = false; private static final EntityDataAccessor FLIGHT_PHASE = SynchedEntityData.defineId(RocketEntity.class, EntityDataSerializers.BYTE); @@ -101,18 +98,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa setPhase(FlightPhase.PREPARE); } - public Player getFirstPlayerPassenger() { - if (!this.getPassengers().isEmpty()) { - for (int i = 0; i < this.getPassengers().size(); i++) { - if (this.getPassengers().get(i) instanceof Player player) { - return player; - } - } - } - - return null; - } - @Override public void tick() { super.tick(); @@ -146,11 +131,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa } private void tickPrepare() { -// if (targetDim == this.level().dimension()) { -// setPhase(FlightPhase.IDLE); -// Aphelion.LOGGER.info("Target dimension matches current dimension"); -// return; -// } setPhase(FlightPhase.ASCEND); } @@ -189,10 +169,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa landingPosZ = getZ(); } - // Compute landing Y in destination - int hx = (int) Math.floor(landingPosX); - int hz = (int) Math.floor(landingPosZ); - double arrivalY = TELEPORT_Y; var passengers = List.copyOf(getPassengers()); @@ -326,26 +302,24 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa } } + private RocketEngineSound ascendLoopSound; + private void handleClientFlightPhaseChange(FlightPhase phase) { switch (phase) { - case IDLE -> { -// var x = 0; - } - case PREPARE -> { -// var x = 1; + case IDLE, PREPARE, TRANSIT, DESCEND, LANDED -> { + Aphelion.LOGGER.info("Rocket state updated to {}", phase); + if (ascendLoopSound != null) { + ascendLoopSound.killSound(); + ascendLoopSound = null; + } } case ASCEND -> { -// var x = 2; - } - case TRANSIT -> { -// var x = 3; - } - case DESCEND -> { -// var x = 4; - } - case LANDED -> { -// var x = 5; + if (ascendLoopSound == null || ascendLoopSound.isStopped()) { + ascendLoopSound = new RocketEngineSound(this); + Minecraft.getInstance().getSoundManager().play(ascendLoopSound); + } } + } } @@ -382,6 +356,7 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa landingPosX = tag.getDouble("LandingX"); landingPosZ = tag.getDouble("LandingZ"); + yVel = tag.getDouble("yVelocity"); if (tag.contains("FlightPhase", Tag.TAG_BYTE)) { setPhase(FlightPhase.values()[tag.getByte("FlightPhase")]); @@ -399,9 +374,10 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa tag.putDouble("LandingX", landingPosX); tag.putDouble("LandingZ", landingPosZ); + tag.putDouble("yVelocity", yVel); } - public BlockPos getTargetPos() { + public @Nullable BlockPos getTargetPos() { return targetPos; } diff --git a/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java b/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java index 0ec0575..e0d3e92 100644 --- a/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java +++ b/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java @@ -5,19 +5,17 @@ import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; -import net.neoforged.neoforge.network.handlers.ClientPayloadHandler; import net.neoforged.neoforge.network.registration.HandlerThread; import net.neoforged.neoforge.network.registration.PayloadRegistrar; import net.xevianlight.aphelion.Aphelion; import net.xevianlight.aphelion.block.dummy.entity.BaseMultiblockDummyBlockEntity; -import net.xevianlight.aphelion.block.dummy.entity.VAFMultiblockDummyBlockEntity; 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.network.RocketPayloadHandlers; -import net.xevianlight.aphelion.network.ServerPayloadHandler; -import net.xevianlight.aphelion.network.packet.PartitionData; +import net.xevianlight.aphelion.network.PartitionPayloadHandler; +import net.xevianlight.aphelion.network.packet.PartitionPayload; import net.xevianlight.aphelion.network.packet.RocketLaunchPayload; @EventBusSubscriber(modid = Aphelion.MOD_ID) @@ -40,9 +38,9 @@ public class ModBusEvents { .executesOn(HandlerThread.MAIN); registrar.playToClient( - PartitionData.TYPE, - PartitionData.STREAM_CODEC, - ServerPayloadHandler::handleDataOnMain + PartitionPayload.TYPE, + PartitionPayload.STREAM_CODEC, + PartitionPayloadHandler::handleDataOnMain ); registrar.playToServer( diff --git a/src/main/java/net/xevianlight/aphelion/network/KeyNetwork.java b/src/main/java/net/xevianlight/aphelion/network/KeyNetwork.java index 1b8cfc9..850de24 100644 --- a/src/main/java/net/xevianlight/aphelion/network/KeyNetwork.java +++ b/src/main/java/net/xevianlight/aphelion/network/KeyNetwork.java @@ -22,6 +22,8 @@ public final class KeyNetwork { // consumeClick makes it fire once per press, not every tick held if (AphelionClient.ROCKET_LAUNCH_KEY.consumeClick() && mc.player.getVehicle() instanceof RocketEntity rocket) { + + // Send a packet to the server telling it to try launching the rocket matching this id. The packet only contains the rocketId as an integer. PacketDistributor.sendToServer(new RocketLaunchPayload(rocket.getId())); } } diff --git a/src/main/java/net/xevianlight/aphelion/network/ServerPayloadHandler.java b/src/main/java/net/xevianlight/aphelion/network/PartitionPayloadHandler.java similarity index 59% rename from src/main/java/net/xevianlight/aphelion/network/ServerPayloadHandler.java rename to src/main/java/net/xevianlight/aphelion/network/PartitionPayloadHandler.java index 06fef72..d4dca81 100644 --- a/src/main/java/net/xevianlight/aphelion/network/ServerPayloadHandler.java +++ b/src/main/java/net/xevianlight/aphelion/network/PartitionPayloadHandler.java @@ -3,12 +3,13 @@ package net.xevianlight.aphelion.network; import net.neoforged.neoforge.network.handling.IPayloadContext; import net.xevianlight.aphelion.Aphelion; import net.xevianlight.aphelion.client.PartitionClientState; -import net.xevianlight.aphelion.network.packet.PartitionData; +import net.xevianlight.aphelion.network.packet.PartitionPayload; // Handle packets TO the client FROM the server -public class ServerPayloadHandler { +public class PartitionPayloadHandler { - public static void handleDataOnMain(PartitionData data, IPayloadContext context) { + public static void handleDataOnMain(PartitionPayload data, IPayloadContext context) { + // Set our local partition state to the packet we just received. PartitionClientState.set(data); Aphelion.LOGGER.info("Partition packet received! id={}", data.id()); } diff --git a/src/main/java/net/xevianlight/aphelion/network/PartitionSync.java b/src/main/java/net/xevianlight/aphelion/network/PartitionSync.java index 20d2163..a64f5e5 100644 --- a/src/main/java/net/xevianlight/aphelion/network/PartitionSync.java +++ b/src/main/java/net/xevianlight/aphelion/network/PartitionSync.java @@ -9,28 +9,18 @@ import net.neoforged.neoforge.event.tick.ServerTickEvent; import net.neoforged.neoforge.network.PacketDistributor; import net.xevianlight.aphelion.Aphelion; import net.xevianlight.aphelion.core.space.SpacePartitionSavedData; -import net.xevianlight.aphelion.network.packet.PartitionData; +import net.xevianlight.aphelion.network.packet.PartitionPayload; import net.xevianlight.aphelion.util.SpacePartitionHelper; import java.util.HashSet; -import java.util.Objects; import java.util.Set; import java.util.UUID; @EventBusSubscriber(modid = Aphelion.MOD_ID) public final class PartitionSync { - // send once right after join (safe: delayed to next server tick) - private static final Set PENDING_JOIN_SEND = new HashSet<>(); - - @SubscribeEvent - public static void onLogin(PlayerEvent.PlayerLoggedInEvent e) { - if (e.getEntity() instanceof ServerPlayer sp) { - PENDING_JOIN_SEND.add(sp.getUUID()); - } - } - - private static final java.util.Map LAST_SENT = new java.util.HashMap<>(); + // Stora all packets we send to all players in a map so we can look it up later + private static final java.util.Map LAST_SENT = new java.util.HashMap<>(); @SubscribeEvent public static void onServerTick(ServerTickEvent.Post e) { @@ -39,24 +29,29 @@ public final class PartitionSync { // Aphelion.LOGGER.info("WORKS!!!"); for (ServerPlayer sp : server.getPlayerList().getPlayers()) { - PartitionData now = computePartitionFor(sp); // your logic - PartitionData prev = LAST_SENT.get(sp.getUUID()); + // Prepare a new packet and compare it with the last one we sent the player + PartitionPayload now = computePartitionFor(sp); + PartitionPayload prev = LAST_SENT.get(sp.getUUID()); + + // If it is different, send them the new one if (prev == null || !prev.equals(now)) { PacketDistributor.sendToPlayer(sp, now); + // Store this packet for later LAST_SENT.put(sp.getUUID(), now); } } } - private static PartitionData computePartitionFor(ServerPlayer sp) { - // Example: convert player position to partition coords + private static PartitionPayload computePartitionFor(ServerPlayer sp) { + // convert player position to partition coords int px = (int)Math.floor(sp.getX() / SpacePartitionHelper.SIZE); int pz = (int)Math.floor(sp.getZ() / SpacePartitionHelper.SIZE); + // Get the orbit for the partition the player is in and create a packet for it var orbit = SpacePartitionSavedData.get(sp.serverLevel()).getOrbitForPartition(px, pz); String orbitId = (orbit != null) ? orbit.toString() : "aphelion:orbit/default"; - return new PartitionData(orbitId); + return new PartitionPayload(orbitId); } } diff --git a/src/main/java/net/xevianlight/aphelion/network/packet/PartitionData.java b/src/main/java/net/xevianlight/aphelion/network/packet/PartitionPayload.java similarity index 54% rename from src/main/java/net/xevianlight/aphelion/network/packet/PartitionData.java rename to src/main/java/net/xevianlight/aphelion/network/packet/PartitionPayload.java index 2aa51f3..723612e 100644 --- a/src/main/java/net/xevianlight/aphelion/network/packet/PartitionData.java +++ b/src/main/java/net/xevianlight/aphelion/network/packet/PartitionPayload.java @@ -7,14 +7,14 @@ import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.xevianlight.aphelion.Aphelion; -public record PartitionData (String id) implements CustomPacketPayload { - public static final Type TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "partition_data")); +public record PartitionPayload(String id) implements CustomPacketPayload { + public static final Type TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "partition_data")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.STRING_UTF8, - PartitionData::id, + PartitionPayload::id, - PartitionData::new + PartitionPayload::new ); @Override diff --git a/src/main/java/net/xevianlight/aphelion/util/ModTags.java b/src/main/java/net/xevianlight/aphelion/util/ModTags.java index 5a2b675..a22954d 100644 --- a/src/main/java/net/xevianlight/aphelion/util/ModTags.java +++ b/src/main/java/net/xevianlight/aphelion/util/ModTags.java @@ -17,6 +17,8 @@ public class ModTags { public static final TagKey STORAGE_BLOCKS = commonTag("storage_blocks"); public static final TagKey STORAGE_BLOCKS_STEEL = commonTag("storage_blocks/steel"); + public static final TagKey LAUNCH_PAD = createTag("launch_pad"); + private static TagKey commonTag(String name) { return BlockTags.create(ResourceLocation.fromNamespaceAndPath("c", name)); } @@ -25,7 +27,6 @@ public class ModTags { public static class Items { public static final TagKey TEST_TAG = createTag("test_tag"); public static final TagKey INGOTS = commonTag("ingots"); - public static final TagKey STORAGE_BLOCKS = commonTag("storage_blocks"); public static final TagKey STORAGE_BLOCKS_STEEL = commonTag("storage_blocks/steel"); public static final TagKey INGOT_ALUMINUM = commonTag("ingots/aluminum"); diff --git a/src/main/java/net/xevianlight/aphelion/util/RocketStructure.java b/src/main/java/net/xevianlight/aphelion/util/RocketStructure.java index f371fbe..c24f042 100644 --- a/src/main/java/net/xevianlight/aphelion/util/RocketStructure.java +++ b/src/main/java/net/xevianlight/aphelion/util/RocketStructure.java @@ -2,7 +2,9 @@ package net.xevianlight.aphelion.util; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.*; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; @@ -135,4 +137,37 @@ public final class RocketStructure { return new Extents(minX, minY, minZ, maxX, maxY, maxZ); } + + public static RocketStructure capture(Level level, BlockPos origin, int rx, int ry, int rz) { + return new RocketStructure(s -> { + for (int dy = -ry; dy <= ry; dy++) { + for (int dx = -rx; dx <= rx; dx++) { + for (int dz = -rz; dz <= rz; dz++) { + BlockPos p = origin.offset(dx, dy, dz); + BlockState st = level.getBlockState(p); + + // Skip air and unbreakables/forbidden blocks as you like + if (st.isAir()) continue; + + // Optional: ignore the assembler block itself + // if (p.equals(origin)) continue; + + s.add(dx, dy, dz, st); + } + } + } + }); + } + + public static void clearCaptured(Level level, BlockPos origin, RocketStructure struct) { + for (int i = 0; i < struct.size(); i++) { + int packed = struct.packedPosAt(i); + int dx = RocketStructure.unpackX(packed); + int dy = RocketStructure.unpackY(packed); + int dz = RocketStructure.unpackZ(packed); + + BlockPos wp = origin.offset(dx, dy, dz); + level.setBlock(wp, Blocks.AIR.defaultBlockState(), 3); + } + } } diff --git a/src/main/resources/assets/aphelion/blockstates/launch_pad.json b/src/main/resources/assets/aphelion/blockstates/launch_pad.json new file mode 100644 index 0000000..83bb1b4 --- /dev/null +++ b/src/main/resources/assets/aphelion/blockstates/launch_pad.json @@ -0,0 +1,20 @@ +{ + "variants": { + "north=true,east=true,south=true,west=true": { "model": "aphelion:block/launch_pad/0000" }, + "north=false,east=true,south=true,west=true": { "model": "aphelion:block/launch_pad/1000" }, + "north=true,east=false,south=true,west=true": { "model": "aphelion:block/launch_pad/0100" }, + "north=true,east=true,south=false,west=true": { "model": "aphelion:block/launch_pad/0010" }, + "north=true,east=true,south=true,west=false": { "model": "aphelion:block/launch_pad/0001" }, + "north=false,east=false,south=true,west=true": { "model": "aphelion:block/launch_pad/1100" }, + "north=false,east=true,south=false,west=true": { "model": "aphelion:block/launch_pad/1010" }, + "north=false,east=true,south=true,west=false": { "model": "aphelion:block/launch_pad/1001" }, + "north=true,east=false,south=false,west=true": { "model": "aphelion:block/launch_pad/0110" }, + "north=true,east=false,south=true,west=false": { "model": "aphelion:block/launch_pad/0101" }, + "north=true,east=true,south=false,west=false": { "model": "aphelion:block/launch_pad/0011" }, + "north=false,east=false,south=false,west=true": { "model": "aphelion:block/launch_pad/1110" }, + "north=false,east=false,south=true,west=false": { "model": "aphelion:block/launch_pad/1101" }, + "north=false,east=true,south=false,west=false": { "model": "aphelion:block/launch_pad/1011" }, + "north=true,east=false,south=false,west=false": { "model": "aphelion:block/launch_pad/0111" }, + "north=false,east=false,south=false,west=false": { "model": "aphelion:block/launch_pad/1111" } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/lang/en_us.json b/src/main/resources/assets/aphelion/lang/en_us.json index 509563d..842bcd2 100644 --- a/src/main/resources/assets/aphelion/lang/en_us.json +++ b/src/main/resources/assets/aphelion/lang/en_us.json @@ -3,6 +3,7 @@ "block.aphelion.test_block": "Test Block", "block.aphelion.electric_arc_furnace": "Electric Arc Furnace", "block.aphelion.vacuum_arc_furnace_controller": "Vacuum Arc Furnace Controller", + "block.aphelion.arc_furnace_casing": "Arc Furnace Casing", "block.aphelion.vaf_dummy_block": "Vacuum Arc Furnace", "item.aphelion.ingot_steel": "Steel Ingot", @@ -28,6 +29,10 @@ "tag.item.c.ingots.steel": "Steel Ingots", "tag.item.c.ingots.aluminum": "Aluminum Ingots", + "entity.aphelion.rocket": "Rocket", + + "fluid_type.aphelion.oil": "Oil", + "command.aphelion.station.orbit.set": "Set station (%s, %s)'s orbit to %s", "command.aphelion.station.orbit.get": "Station (%s, %s)'s orbit is assigned to %s", diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0000.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0000.json new file mode 100644 index 0000000..f7adc8d --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0000.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0000", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0000" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0001.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0001.json new file mode 100644 index 0000000..f9404ae --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0001.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0001", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0001" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0010.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0010.json new file mode 100644 index 0000000..abe8a7d --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0010.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0010", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0010" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0011.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0011.json new file mode 100644 index 0000000..1f56f7a --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0011.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0011", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0011" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0100.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0100.json new file mode 100644 index 0000000..4f60d98 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0100.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0100", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0100" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0101.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0101.json new file mode 100644 index 0000000..c960fec --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0101.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0101", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0101" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0110.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0110.json new file mode 100644 index 0000000..66b9dd2 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0110.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0110", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0110" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/0111.json b/src/main/resources/assets/aphelion/models/block/launch_pad/0111.json new file mode 100644 index 0000000..7e21cf9 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/0111.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/0111", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/0111" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1000.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1000.json new file mode 100644 index 0000000..13a527f --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1000.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1000", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1000" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1001.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1001.json new file mode 100644 index 0000000..b7e6827 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1001.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1001", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1001" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1010.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1010.json new file mode 100644 index 0000000..c23af13 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1010.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1010", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1010" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1011.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1011.json new file mode 100644 index 0000000..b89563d --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1011.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1011", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1011" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1100.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1100.json new file mode 100644 index 0000000..a7dcf91 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1100.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1100", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1100" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1101.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1101.json new file mode 100644 index 0000000..74a0be8 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1101.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1101", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1101" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1110.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1110.json new file mode 100644 index 0000000..1320a63 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1110.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1110", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1110" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/launch_pad/1111.json b/src/main/resources/assets/aphelion/models/block/launch_pad/1111.json new file mode 100644 index 0000000..52d7644 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/launch_pad/1111.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "aphelion:block/launch_pad/1111", + "side": "aphelion:block/launch_pad/topbottom", + "bottom": "aphelion:block/launch_pad/1111" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/item/launch_pad.json b/src/main/resources/assets/aphelion/models/item/launch_pad.json new file mode 100644 index 0000000..674505e --- /dev/null +++ b/src/main/resources/assets/aphelion/models/item/launch_pad.json @@ -0,0 +1,3 @@ +{ + "parent": "aphelion:block/launch_pad/1111" +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/sounds.json b/src/main/resources/assets/aphelion/sounds.json index c3bebb5..daa8c19 100644 --- a/src/main/resources/assets/aphelion/sounds.json +++ b/src/main/resources/assets/aphelion/sounds.json @@ -6,5 +6,13 @@ "stream": true } ] + }, + "rocket_engine": { + "sounds": [ + { + "name": "aphelion:rocket_engine", + "stream": true + } + ] } } \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/sounds/rocket_engine.ogg b/src/main/resources/assets/aphelion/sounds/rocket_engine.ogg new file mode 100644 index 0000000..9881c2f Binary files /dev/null and b/src/main/resources/assets/aphelion/sounds/rocket_engine.ogg differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0000.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0000.png new file mode 100644 index 0000000..8fbc157 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0000.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0001.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0001.png new file mode 100644 index 0000000..7ebaed3 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0001.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0010.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0010.png new file mode 100644 index 0000000..b31871b Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0010.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0011.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0011.png new file mode 100644 index 0000000..005f9b8 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0011.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0100.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0100.png new file mode 100644 index 0000000..8534be0 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0100.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0101.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0101.png new file mode 100644 index 0000000..1865d54 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0101.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0110.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0110.png new file mode 100644 index 0000000..5859c98 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0110.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/0111.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/0111.png new file mode 100644 index 0000000..600de4f Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/0111.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1000.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1000.png new file mode 100644 index 0000000..0187d54 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1000.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1001.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1001.png new file mode 100644 index 0000000..576edfc Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1001.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1010.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1010.png new file mode 100644 index 0000000..314fc17 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1010.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1011.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1011.png new file mode 100644 index 0000000..164c382 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1011.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1100.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1100.png new file mode 100644 index 0000000..cd61aae Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1100.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1101.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1101.png new file mode 100644 index 0000000..f10d62e Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1101.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1110.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1110.png new file mode 100644 index 0000000..d994c0b Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1110.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/1111.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/1111.png new file mode 100644 index 0000000..5a95cd7 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/1111.png differ diff --git a/src/main/resources/assets/aphelion/textures/block/launch_pad/topbottom.png b/src/main/resources/assets/aphelion/textures/block/launch_pad/topbottom.png new file mode 100644 index 0000000..314fc17 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/launch_pad/topbottom.png differ