mirror of
https://github.com/XevianLight/Aphelion.git
synced 2026-05-11 10:00:54 +01:00
Compare commits
4 Commits
2496e0cdd5
...
pipes-syst
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f44670d44e | ||
|
|
ab78582cce | ||
|
|
97879e47ef | ||
|
|
851645e93f |
@@ -1,2 +1 @@
|
|||||||
// 1.21.1 2026-03-14T19:22:23.3145075 Tags for minecraft:fluid mod id aphelion
|
// 1.21.1 2026-01-11T15:05:33.587044 Tags for minecraft:fluid mod id aphelion
|
||||||
36b33555f1ae6c80989afdd9d986ec0883959f49 data/minecraft/tags/fluid/rocket_fuel.json
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
// 1.21.1 2026-02-07T22:29:56.7198656 Loot Tables
|
// 1.21.1 2026-02-04T21:03:31.3164337 Loot Tables
|
||||||
69d8318ddba171526d1fabb87d9d93548ed8598e data/aphelion/loot_table/blocks/arc_furnace_casing.json
|
69d8318ddba171526d1fabb87d9d93548ed8598e data/aphelion/loot_table/blocks/arc_furnace_casing.json
|
||||||
05f08985e601d30116f67e2f07b48b03b40cdca6 data/aphelion/loot_table/blocks/block_steel.json
|
05f08985e601d30116f67e2f07b48b03b40cdca6 data/aphelion/loot_table/blocks/block_steel.json
|
||||||
ff43a9c3741faf10b1e156a7a74d5cfb035cc118 data/aphelion/loot_table/blocks/dimension_changer.json
|
ff43a9c3741faf10b1e156a7a74d5cfb035cc118 data/aphelion/loot_table/blocks/dimension_changer.json
|
||||||
b63130d9c10485676303d729807b6fcaac080294 data/aphelion/loot_table/blocks/electric_arc_furnace.json
|
b63130d9c10485676303d729807b6fcaac080294 data/aphelion/loot_table/blocks/electric_arc_furnace.json
|
||||||
b9cfe672ead8e2673a7b2f5c4cec831e7e8e7040 data/aphelion/loot_table/blocks/launch_pad.json
|
b9cfe672ead8e2673a7b2f5c4cec831e7e8e7040 data/aphelion/loot_table/blocks/launch_pad.json
|
||||||
afb6519a03415b8e0d5bafc9fadb70905a398046 data/aphelion/loot_table/blocks/oxygen_test_block.json
|
afb6519a03415b8e0d5bafc9fadb70905a398046 data/aphelion/loot_table/blocks/oxygen_test_block.json
|
||||||
87dfbcce4a96ea0ee6e9fc7908aa77d42d1904e5 data/aphelion/loot_table/blocks/rocket_assembler.json
|
f3178154dadee30cc28f5ff23af45be98f2766cf data/aphelion/loot_table/blocks/rocket_assembler_block.json
|
||||||
9e269f103ac1ce517c1a089b8ca5474af085bd66 data/aphelion/loot_table/blocks/rocket_seat.json
|
|
||||||
1ab50c99e9f478840b9d003fd56ebdcab12fbbce data/aphelion/loot_table/blocks/test_block.json
|
1ab50c99e9f478840b9d003fd56ebdcab12fbbce data/aphelion/loot_table/blocks/test_block.json
|
||||||
7d8eeb99a1bc942a6e2cf292b21fd4534062b5ab data/aphelion/loot_table/blocks/vacuum_arc_furnace_controller.json
|
7d8eeb99a1bc942a6e2cf292b21fd4534062b5ab data/aphelion/loot_table/blocks/vacuum_arc_furnace_controller.json
|
||||||
797bf9839d79e08b4832c9eaf3cb303b0471ed0c data/aphelion/loot_table/blocks/vaf_dummy_block.json
|
797bf9839d79e08b4832c9eaf3cb303b0471ed0c data/aphelion/loot_table/blocks/vaf_dummy_block.json
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// 1.21.1 2026-02-07T23:23:26.8270373 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
|
46f0160a007d32a06624ad98f25e8a1a8d01bb08 data/aphelion/tags/block/launch_pad.json
|
||||||
883d37ed36ecbde487d467ddb26b34082067aa09 data/aphelion/tags/block/rocket_seat.json
|
|
||||||
058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks.json
|
058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks.json
|
||||||
058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks/steel.json
|
058c56a0c17204ed5d9cadaffae84292b4752213 data/c/tags/block/storage_blocks/steel.json
|
||||||
7d420216f15b8f78d2a3b298f9bb773a9e5f79c3 data/minecraft/tags/block/mineable/pickaxe.json
|
7d420216f15b8f78d2a3b298f9bb773a9e5f79c3 data/minecraft/tags/block/mineable/pickaxe.json
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
// 1.21.1 2026-02-07T22:29:56.7183649 Block States: aphelion
|
// 1.21.1 2026-02-04T21:03:31.3154339 Block States: aphelion
|
||||||
851ff42f7b21dec86107c8e0cefb3934ae4ebc08 assets/aphelion/blockstates/block_steel.json
|
851ff42f7b21dec86107c8e0cefb3934ae4ebc08 assets/aphelion/blockstates/block_steel.json
|
||||||
30b9c0efd7aaadb5412d98e4568f98b3632adbb9 assets/aphelion/blockstates/dimension_changer.json
|
30b9c0efd7aaadb5412d98e4568f98b3632adbb9 assets/aphelion/blockstates/dimension_changer.json
|
||||||
cb4287104006c80c8396b290ab5258df65d62cef assets/aphelion/blockstates/electric_arc_furnace.json
|
cb4287104006c80c8396b290ab5258df65d62cef assets/aphelion/blockstates/electric_arc_furnace.json
|
||||||
28131a570d3666b7f323de4ad8a69e52ceec92e2 assets/aphelion/blockstates/oxygen_test_block.json
|
28131a570d3666b7f323de4ad8a69e52ceec92e2 assets/aphelion/blockstates/oxygen_test_block.json
|
||||||
|
85c7c0dab53d0219b315c822147a90ade9075844 assets/aphelion/blockstates/rocket_assembler_block.json
|
||||||
b86c50fddcf6c8c6c19cb748529239d5962a3ede assets/aphelion/blockstates/test_block.json
|
b86c50fddcf6c8c6c19cb748529239d5962a3ede assets/aphelion/blockstates/test_block.json
|
||||||
a810b97f4dace35d026f28d96cb9c47c93600d75 assets/aphelion/models/block/block_steel.json
|
a810b97f4dace35d026f28d96cb9c47c93600d75 assets/aphelion/models/block/block_steel.json
|
||||||
2d3592b7ab7132908709243e97540151e0fb762e assets/aphelion/models/block/dimension_changer.json
|
2d3592b7ab7132908709243e97540151e0fb762e assets/aphelion/models/block/dimension_changer.json
|
||||||
5f7e8674070f31a63875b5d6147153bfa0eef61a assets/aphelion/models/block/electric_arc_furnace.json
|
5f7e8674070f31a63875b5d6147153bfa0eef61a assets/aphelion/models/block/electric_arc_furnace.json
|
||||||
746f23f150a01524ad03cbd1eb822bfbb7cf453b assets/aphelion/models/block/oxygen_test_block.json
|
746f23f150a01524ad03cbd1eb822bfbb7cf453b assets/aphelion/models/block/oxygen_test_block.json
|
||||||
|
17eb7327e504f7a88028af804e046281d9719fdf assets/aphelion/models/block/rocket_assembler_block.json
|
||||||
e0971228b4a1c4bc9dbab58a7dacdc3ae6037e02 assets/aphelion/models/block/test_block.json
|
e0971228b4a1c4bc9dbab58a7dacdc3ae6037e02 assets/aphelion/models/block/test_block.json
|
||||||
cdc831b0f1c462be64825fd34bd446e5b95afac6 assets/aphelion/models/item/arc_furnace_casing.json
|
cdc831b0f1c462be64825fd34bd446e5b95afac6 assets/aphelion/models/item/arc_furnace_casing.json
|
||||||
3599f9037eb2f66de1765318b97ab564c3eae92f assets/aphelion/models/item/block_steel.json
|
3599f9037eb2f66de1765318b97ab564c3eae92f assets/aphelion/models/item/block_steel.json
|
||||||
db0ec473a016ce05c258cde18a217d47a9ea8324 assets/aphelion/models/item/dimension_changer.json
|
db0ec473a016ce05c258cde18a217d47a9ea8324 assets/aphelion/models/item/dimension_changer.json
|
||||||
279080c06ada87f54fd0a7b885b256dbe25a946a assets/aphelion/models/item/electric_arc_furnace.json
|
279080c06ada87f54fd0a7b885b256dbe25a946a assets/aphelion/models/item/electric_arc_furnace.json
|
||||||
24cf60e70f7d9450b0e70cf017662e80971bae17 assets/aphelion/models/item/oxygen_test_block.json
|
24cf60e70f7d9450b0e70cf017662e80971bae17 assets/aphelion/models/item/oxygen_test_block.json
|
||||||
ab6884315b8f6c99666a87f673b059b5659ff13d assets/aphelion/models/item/rocket_assembler.json
|
dafa6e1a3cfd753e211ae94179a433c69e9d2a28 assets/aphelion/models/item/rocket_assembler_block.json
|
||||||
74418ef1cf678e72e7534924274688ef5a68af0e assets/aphelion/models/item/test_block.json
|
74418ef1cf678e72e7534924274688ef5a68af0e assets/aphelion/models/item/test_block.json
|
||||||
88ca3602517e99f7feaed57eddfc96965a25761c assets/aphelion/models/item/vacuum_arc_furnace_controller.json
|
88ca3602517e99f7feaed57eddfc96965a25761c assets/aphelion/models/item/vacuum_arc_furnace_controller.json
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "aphelion:block/rocket_assembler"
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"parent": "aphelion:block/rocket_assembler_block"
|
||||||
|
}
|
||||||
@@ -11,11 +11,11 @@
|
|||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"name": "aphelion:rocket_assembler"
|
"name": "aphelion:rocket_assembler_block"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1.0
|
"rolls": 1.0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"random_sequence": "aphelion:blocks/rocket_assembler"
|
"random_sequence": "aphelion:blocks/rocket_assembler_block"
|
||||||
}
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "minecraft:block",
|
|
||||||
"pools": [
|
|
||||||
{
|
|
||||||
"bonus_rolls": 0.0,
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"condition": "minecraft:survives_explosion"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"type": "minecraft:item",
|
|
||||||
"name": "aphelion:rocket_seat"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rolls": 1.0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"random_sequence": "aphelion:blocks/rocket_seat"
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"values": [
|
|
||||||
"aphelion:rocket_seat"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"values": [
|
|
||||||
"aphelion:rocket_fuel"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package net.xevianlight.aphelion;
|
package net.xevianlight.aphelion;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
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.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.neoforged.api.distmarker.Dist;
|
import net.neoforged.api.distmarker.Dist;
|
||||||
@@ -129,15 +127,14 @@ public class Aphelion {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onClientSetup(FMLClientSetupEvent event) {
|
public static void onClientSetup(FMLClientSetupEvent event) {
|
||||||
event.enqueueWork(() -> {
|
event.enqueueWork(() -> {
|
||||||
ItemBlockRenderTypes.setRenderLayer(ModFluids.ROCKET_FUEL.get(), RenderType.translucent());
|
// ItemBlockRenderTypes.setRenderLayer(ModFluids.SOURCE_OIL_FLUID.get(), RenderType.translucent());
|
||||||
ItemBlockRenderTypes.setRenderLayer(ModFluids.FLOWING_ROCKET_FUEL.get(), RenderType.translucent());
|
// ItemBlockRenderTypes.setRenderLayer(ModFluids.FLOWING_OIL_FLUID.get(), RenderType.translucent());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onClientExtensions(RegisterClientExtensionsEvent event) {
|
public static void onClientExtensions(RegisterClientExtensionsEvent event) {
|
||||||
event.registerFluidType(((BaseFluidType) ModFluidTypes.OIL_FLUID_TYPE.get()).getClientFluidTypeExtensions(), ModFluidTypes.OIL_FLUID_TYPE.get());
|
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
|
@SubscribeEvent
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.custom;
|
|
||||||
|
|
||||||
import net.xevianlight.aphelion.block.custom.base.BaseRocketFuelTank;
|
|
||||||
|
|
||||||
public class BasicRocketFuelTank extends BaseRocketFuelTank {
|
|
||||||
public BasicRocketFuelTank(Properties properties) {
|
|
||||||
super(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getFuelCapacity() {
|
|
||||||
return 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,6 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
|||||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
|
||||||
import net.xevianlight.aphelion.block.custom.base.BasicEntityBlock;
|
import net.xevianlight.aphelion.block.custom.base.BasicEntityBlock;
|
||||||
import net.xevianlight.aphelion.block.custom.base.BasicHorizontalEntityBlock;
|
import net.xevianlight.aphelion.block.custom.base.BasicHorizontalEntityBlock;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||||
|
|||||||
@@ -2,12 +2,8 @@ package net.xevianlight.aphelion.block.custom;
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.registries.Registries;
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.SoundType;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
@@ -15,12 +11,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
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.BlockStateProperties;
|
||||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
|
||||||
import net.xevianlight.aphelion.core.init.ModDimensions;
|
|
||||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
|
||||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
|
||||||
import net.xevianlight.aphelion.util.ModTags;
|
import net.xevianlight.aphelion.util.ModTags;
|
||||||
import net.xevianlight.aphelion.util.SpacePartition;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class LaunchPad extends Block {
|
public class LaunchPad extends Block {
|
||||||
@@ -82,4 +73,5 @@ public class LaunchPad extends Block {
|
|||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,205 @@
|
|||||||
|
package net.xevianlight.aphelion.block.custom;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.kinds.Const;
|
||||||
|
import com.mojang.math.Constants;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
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.item.context.BlockPlaceContext;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraft.world.phys.shapes.BooleanOp;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
|
import net.xevianlight.aphelion.block.custom.base.BasicEntityBlock;
|
||||||
|
import net.xevianlight.aphelion.block.entity.custom.PipeTestBlockEntity;
|
||||||
|
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
// a lot of this is ai slop so take it with a grainlet of salt
|
||||||
|
public class PipeTestBlock extends BasicEntityBlock {
|
||||||
|
|
||||||
|
// shortcuts for each directional property because they're pretty verbose
|
||||||
|
// t/f here means is/isn't connected outgoing in that direction
|
||||||
|
public static final BooleanProperty NORTH = BlockStateProperties.NORTH;
|
||||||
|
public static final BooleanProperty SOUTH = BlockStateProperties.SOUTH;
|
||||||
|
public static final BooleanProperty EAST = BlockStateProperties.EAST;
|
||||||
|
public static final BooleanProperty WEST = BlockStateProperties.WEST;
|
||||||
|
public static final BooleanProperty UP = BlockStateProperties.UP;
|
||||||
|
public static final BooleanProperty DOWN = BlockStateProperties.DOWN;
|
||||||
|
|
||||||
|
// Voxel shape pieces to make the actual pipe model
|
||||||
|
private static final VoxelShape CORE = Block.box(6, 6, 6, 10, 10, 10);
|
||||||
|
private static final VoxelShape NORTH_SHAPE = Block.box(6, 6, 0, 10, 10, 6);
|
||||||
|
private static final VoxelShape SOUTH_SHAPE = Block.box(6, 6, 10, 10, 10, 16);
|
||||||
|
private static final VoxelShape EAST_SHAPE = Block.box(10, 6, 6, 16, 10, 10);
|
||||||
|
private static final VoxelShape WEST_SHAPE = Block.box(0, 6, 6, 6, 10, 10);
|
||||||
|
private static final VoxelShape UP_SHAPE = Block.box(6, 10, 6, 10, 16, 10);
|
||||||
|
private static final VoxelShape DOWN_SHAPE = Block.box(6, 0, 6, 10, 6, 10);
|
||||||
|
|
||||||
|
// Assembles the "VoxelShape" of the block which i assume is just the collision/place/mine hitbox
|
||||||
|
// later this should be cached for each different shape that we need
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
|
||||||
|
VoxelShape shape = CORE;
|
||||||
|
|
||||||
|
if (state.getValue(NORTH)) shape = Shapes.join(shape, NORTH_SHAPE, BooleanOp.OR);
|
||||||
|
if (state.getValue(SOUTH)) shape = Shapes.join(shape, SOUTH_SHAPE, BooleanOp.OR);
|
||||||
|
if (state.getValue(EAST)) shape = Shapes.join(shape, EAST_SHAPE, BooleanOp.OR);
|
||||||
|
if (state.getValue(WEST)) shape = Shapes.join(shape, WEST_SHAPE, BooleanOp.OR);
|
||||||
|
if (state.getValue(UP)) shape = Shapes.join(shape, UP_SHAPE, BooleanOp.OR);
|
||||||
|
if (state.getValue(DOWN)) shape = Shapes.join(shape, DOWN_SHAPE, BooleanOp.OR);
|
||||||
|
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PipeTestBlock(Properties properties) {
|
||||||
|
super(properties, true);
|
||||||
|
this.registerDefaultState(this.stateDefinition.any()
|
||||||
|
.setValue(NORTH, false).setValue(SOUTH, false)
|
||||||
|
.setValue(EAST, false).setValue(WEST, false)
|
||||||
|
.setValue(UP, false).setValue(DOWN, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MapCodec<? extends BaseEntityBlock> codec() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method determines the state; called when first placed
|
||||||
|
@Override
|
||||||
|
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||||
|
return makeConnections(context.getLevel(), context.getClickedPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the block; called when a neighbor changes
|
||||||
|
@Override
|
||||||
|
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) {
|
||||||
|
return makeConnections(level, currentPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Properties getProperties() {
|
||||||
|
return Properties.of().noOcclusion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasAttachment(@Nullable PipeTestBlockEntity BE, Direction direction) {
|
||||||
|
return (BE != null && BE.hasAttachment(direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockState makeConnections(LevelAccessor level, BlockPos pos) {
|
||||||
|
BlockEntity BE = level.getBlockEntity(pos);
|
||||||
|
PipeTestBlockEntity PTBE = null;
|
||||||
|
if (BE instanceof PipeTestBlockEntity found) {
|
||||||
|
PTBE = found;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.defaultBlockState()
|
||||||
|
.setValue(NORTH, canConnect(level, pos.north(), Direction.SOUTH) || hasAttachment(PTBE, Direction.NORTH))
|
||||||
|
.setValue(SOUTH, canConnect(level, pos.south(), Direction.NORTH) || hasAttachment(PTBE, Direction.SOUTH))
|
||||||
|
.setValue(EAST, canConnect(level, pos.east(), Direction.WEST) || hasAttachment(PTBE, Direction.EAST))
|
||||||
|
.setValue(WEST, canConnect(level, pos.west(), Direction.EAST) || hasAttachment(PTBE, Direction.WEST))
|
||||||
|
.setValue(UP, canConnect(level, pos.above(), Direction.DOWN) || hasAttachment(PTBE, Direction.UP))
|
||||||
|
.setValue(DOWN, canConnect(level, pos.below(), Direction.UP) || hasAttachment(PTBE, Direction.DOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If a PipeTestBlock can connect to this position from the given direction.
|
||||||
|
/// If you're going to the NORTH of yourself, you should be accessing the SOUTH side.
|
||||||
|
public static boolean canConnect(LevelAccessor levelA, BlockPos neighborPos, Direction accessSide) {
|
||||||
|
// Methinks this is not the best way to test this.
|
||||||
|
boolean isPipe = levelA.getBlockState(neighborPos).is(ModBlocks.PIPE_TEST_BLOCK.get());
|
||||||
|
|
||||||
|
/// This code is AI, but I think it works? I think the reason it's a levelAccessor instead of a level
|
||||||
|
/// is that we're not sure if we're in, for example, an inventory slot or not.
|
||||||
|
/// Either way, this should only trigger when it makes sense (assuming this is correct in the first place)
|
||||||
|
boolean isInventory;
|
||||||
|
if (levelA instanceof Level level) {
|
||||||
|
isInventory = level.getCapability(Capabilities.ItemHandler.BLOCK, neighborPos, accessSide) != null;
|
||||||
|
} else {
|
||||||
|
isInventory = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isPipe || isInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
|
BlockEntity BE = level.getBlockEntity(pos);
|
||||||
|
if (BE instanceof PipeTestBlockEntity pipe) {
|
||||||
|
// force everything connected to this pipe to reevaluate
|
||||||
|
if (pipe.graph != null) pipe.graph.invalidate();
|
||||||
|
}
|
||||||
|
super.onRemove(state, level, pos, newState, isMoving);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(NORTH, SOUTH, EAST, WEST, UP, DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
|
||||||
|
|
||||||
|
BlockEntity BE = level.getBlockEntity(pos);
|
||||||
|
if (BE instanceof PipeTestBlockEntity PTBE) {
|
||||||
|
ItemInteractionResult r = PTBE.useItemOn(stack, state, level, pos, player, hand, hitResult, this);
|
||||||
|
|
||||||
|
BlockState newState = makeConnections(level, pos);
|
||||||
|
level.setBlock(pos, newState, 3);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return super.useItemOn(stack, state, level, pos, player, hand, hitResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doesn't block sunlight
|
||||||
|
// @Override
|
||||||
|
// public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// This function doesn't do what the AI says it does. I have no idea what it actually does, though
|
||||||
|
// 2. Prevents the "black shadows" inside or around the pipe
|
||||||
|
// @Override
|
||||||
|
// public int getLightBlock(BlockState state, BlockGetter worldIn, BlockPos pos) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// I don't know what this does, because Properties.noOcclusion() is the part that made the leaves keep
|
||||||
|
/// rendering their faces.
|
||||||
|
// 3. Tells adjacent blocks (like leaves) to keep rendering their faces
|
||||||
|
// @Override
|
||||||
|
// public boolean isOcclusionShapeFullBlock(BlockState state, BlockGetter worldIn, BlockPos pos) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// This bit affects how strong the ambient occlusion effect is
|
||||||
|
@Override
|
||||||
|
public float getShadeBrightness(BlockState state, BlockGetter world, BlockPos pos) {
|
||||||
|
return 1.0F; // Maintains full brightness
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) {
|
||||||
|
return new PipeTestBlockEntity(blockPos, blockState);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,37 +2,27 @@ package net.xevianlight.aphelion.block.custom;
|
|||||||
|
|
||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.InteractionResult;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.*;
|
import net.minecraft.world.level.block.*;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
|
||||||
import net.xevianlight.aphelion.block.custom.base.BasicHorizontalEntityBlock;
|
import net.xevianlight.aphelion.block.custom.base.BasicHorizontalEntityBlock;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.RocketAssemblerBlockEntity;
|
import net.xevianlight.aphelion.block.entity.custom.RocketAssemblerBlockEntity;
|
||||||
import net.xevianlight.aphelion.core.init.ModDimensions;
|
|
||||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
|
||||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
|
||||||
import net.xevianlight.aphelion.entites.vehicles.RocketEntity;
|
|
||||||
import net.xevianlight.aphelion.util.AphelionBlockStateProperties;
|
import net.xevianlight.aphelion.util.AphelionBlockStateProperties;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class RocketAssembler extends BasicHorizontalEntityBlock {
|
public class RocketAssemblerBlock extends BasicHorizontalEntityBlock {
|
||||||
|
|
||||||
public static final BooleanProperty FORMED = AphelionBlockStateProperties.FORMED;
|
public static final BooleanProperty FORMED = AphelionBlockStateProperties.FORMED;
|
||||||
|
|
||||||
public RocketAssembler(Properties properties) {
|
public RocketAssemblerBlock(Properties properties) {
|
||||||
super(properties, true);
|
super(properties, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final MapCodec<RocketAssembler> CODEC = simpleCodec(RocketAssembler::new);
|
public static final MapCodec<RocketAssemblerBlock> CODEC = simpleCodec(RocketAssemblerBlock::new);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @NotNull MapCodec<? extends BaseEntityBlock> codec() {
|
protected @NotNull MapCodec<? extends BaseEntityBlock> codec() {
|
||||||
@@ -63,12 +53,4 @@ public class RocketAssembler extends BasicHorizontalEntityBlock {
|
|||||||
builder.add(FORMED);
|
builder.add(FORMED);
|
||||||
super.createBlockStateDefinition(builder);
|
super.createBlockStateDefinition(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NotNull InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
|
|
||||||
if (!level.isClientSide && player instanceof ServerPlayer serverPlayer && level.getBlockEntity(pos) instanceof RocketAssemblerBlockEntity rocketAssemblerBlockEntity) {
|
|
||||||
RocketEntity rocket = rocketAssemblerBlockEntity.assemble();
|
|
||||||
}
|
|
||||||
return InteractionResult.sidedSuccess(level.isClientSide());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.custom;
|
|
||||||
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.SoundType;
|
|
||||||
|
|
||||||
public class RocketSeat extends Block {
|
|
||||||
public RocketSeat(Properties properties) {
|
|
||||||
super(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Properties getProperties() {
|
|
||||||
return Properties
|
|
||||||
.of()
|
|
||||||
.sound(SoundType.STONE)
|
|
||||||
.destroyTime(2f)
|
|
||||||
.explosionResistance(10f)
|
|
||||||
.requiresCorrectToolForDrops();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Item.Properties getItemProperties() {
|
|
||||||
return new Item.Properties();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
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<StationFlightComputerBlock> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
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 BaseRocketFuelTank extends Block implements IRocketFuelUpgrade {
|
|
||||||
public BaseRocketFuelTank(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 getFuelCapacity() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,10 +29,6 @@ public abstract class BasicEntityBlock extends BaseEntityBlock {
|
|||||||
return RenderShape.MODEL;
|
return RenderShape.MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Properties getProperties() {
|
|
||||||
return Properties.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Item.Properties getItemProperties() {
|
public static Item.Properties getItemProperties() {
|
||||||
return new Item.Properties();
|
return new Item.Properties();
|
||||||
}
|
}
|
||||||
@@ -41,16 +37,14 @@ public abstract class BasicEntityBlock extends BaseEntityBlock {
|
|||||||
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(@NotNull Level level, @NotNull BlockState state, @NotNull BlockEntityType<T> blockEntityType) {
|
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(@NotNull Level level, @NotNull BlockState state, @NotNull BlockEntityType<T> blockEntityType) {
|
||||||
return !shouldTick ? null : (entityLevel, pos, blockState, blockEntity) -> {
|
return !shouldTick ? null : (entityLevel, pos, blockState, blockEntity) -> {
|
||||||
if (blockEntity instanceof TickableBlockEntity tickable) {
|
if (blockEntity instanceof TickableBlockEntity tickable) {
|
||||||
if (!tickable.isInitialized()) tickable.firstTick(entityLevel, blockState, pos);
|
long time = level.getGameTime() - pos.hashCode();
|
||||||
|
|
||||||
long time = entityLevel.getGameTime() - pos.hashCode();
|
|
||||||
tickable.tick(entityLevel, time, blockState, pos);
|
tickable.tick(entityLevel, time, blockState, pos);
|
||||||
|
if (level.isClientSide()) {
|
||||||
if (entityLevel.isClientSide()) {
|
tickable.clientTick((ClientLevel) level, time, state, pos);
|
||||||
tickable.clientTick((ClientLevel) entityLevel, time, blockState, pos);
|
|
||||||
} else {
|
} else {
|
||||||
tickable.serverTick((ServerLevel) entityLevel, time, blockState, pos);
|
tickable.serverTick((ServerLevel) level, time, state, pos);
|
||||||
}
|
}
|
||||||
|
if (!tickable.isInitialized()) tickable.firstTick(level, state, pos);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.custom.base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for blocks which should provide energy storage capacity to a rocket.
|
|
||||||
* <p>Note that blocks implementing this interface should not store energy themselves.
|
|
||||||
* Rockets determine their energy capacity from the sum of these blocks installed on them.</p>
|
|
||||||
* <p>Keep in mind that {@code TileEntity} blocks cannot be included in a {@code RocketStructure}.</p>
|
|
||||||
*/
|
|
||||||
public interface IRocketEnergyUpgrade {
|
|
||||||
/**
|
|
||||||
* Used to determine how much FE of energy storage a rocket receives from having this block is installed.
|
|
||||||
*/
|
|
||||||
int getEnergyCapacity();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to determine how much FE transfer rate bonus a rocket receives from having this block is installed. This is added onto the base rockets energy transfer limit.
|
|
||||||
*/
|
|
||||||
default int getMaxTransferBonus() {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.custom.base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for blocks which should provide fluid storage capacity to a rocket.
|
|
||||||
* <p>Note that blocks implementing this interface should not store fluids themselves.
|
|
||||||
* Rockets determine their fluid container capacity from the sum of these blocks installed on them.</p>
|
|
||||||
* <p>Keep in mind that {@code TileEntity} blocks cannot be included in a {@code RocketStructure}.</p>
|
|
||||||
*/
|
|
||||||
public interface IRocketFluidUpgrade {
|
|
||||||
/**
|
|
||||||
* Used to determine how many millibuckets of fluid storage a rocket receives from having this block is installed.
|
|
||||||
*/
|
|
||||||
int getFluidCapacity();
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.custom.base;
|
|
||||||
|
|
||||||
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for blocks which should provide fuel storage capacity to a rocket.
|
|
||||||
* <p>Note that blocks implementing this interface should not store fuel themselves.
|
|
||||||
* Rockets determine their fuel container capacity from the sum of these blocks installed on them.</p>
|
|
||||||
* <p>Keep in mind that {@code TileEntity} blocks cannot be included in a {@code RocketStructure}.</p>
|
|
||||||
*/
|
|
||||||
public interface IRocketFuelUpgrade {
|
|
||||||
/**
|
|
||||||
* Used to determine how many millibuckets of fuel storage a rocket receives from having this block is installed.
|
|
||||||
*/
|
|
||||||
int getFuelCapacity();
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.custom.base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for blocks which should provide item slots to a rockets inventory.
|
|
||||||
* <p>Note that blocks implementing this interface should not store items themselves.
|
|
||||||
* Rockets determine their inventory slot count from the sum of these blocks installed on them.</p>
|
|
||||||
* <p>Keep in mind that {@code TileEntity} blocks cannot be included in a {@code RocketStructure}.</p>
|
|
||||||
*/
|
|
||||||
public interface IRocketInventoryUpgrade {
|
|
||||||
/**
|
|
||||||
* Used to determine how many inventory slots a rocket receives from having this block installed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int getSlotCapacity();
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
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<StationEngineBlock> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,78 +9,41 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
public interface TickableBlockEntity {
|
public interface TickableBlockEntity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs on both the client and server once per tick.
|
* Runs on both the client AND server.
|
||||||
*
|
* @param level
|
||||||
* <p>This is intended for logic that is common to both sides. Side-specific logic
|
* @param time
|
||||||
* should go in {@link #clientTick(ClientLevel, long, BlockState, BlockPos)} or
|
* @param state
|
||||||
* {@link #serverTick(ServerLevel, long, BlockState, BlockPos)}.</p>
|
* @param pos
|
||||||
*
|
|
||||||
* @param level the current level
|
|
||||||
* @param time a deterministic per-position tick time (see ticker implementation)
|
|
||||||
* @param state the current block state
|
|
||||||
* @param pos the world position of the block entity
|
|
||||||
*/
|
*/
|
||||||
default void tick (Level level, long time, BlockState state, BlockPos pos) {};
|
default void tick (Level level, long time, BlockState state, BlockPos pos) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs on the client only once per tick.
|
* Runs on the client only
|
||||||
*
|
* @param level
|
||||||
* <p>Use this for client-side visual updates, particles, sounds, animation state,
|
* @param time
|
||||||
* or other logic that must not run on the logical server.</p>
|
* @param state
|
||||||
*
|
* @param pos
|
||||||
* @param level the client level
|
|
||||||
* @param time a deterministic per-position tick time (see ticker implementation)
|
|
||||||
* @param state the current block state
|
|
||||||
* @param pos the world position of the block entity
|
|
||||||
*/
|
*/
|
||||||
void clientTick(ClientLevel level, long time, BlockState state, BlockPos pos);
|
void clientTick(ClientLevel level, long time, BlockState state, BlockPos pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs on the server only once per tick.
|
* Runs on the server only
|
||||||
*
|
* @param level
|
||||||
* <p>Use this for authoritative game logic such as inventory processing, energy
|
* @param time
|
||||||
* generation/consumption, entity spawning, saving state, and network sync triggers.</p>
|
* @param state
|
||||||
*
|
* @param pos
|
||||||
* @param level the server level
|
|
||||||
* @param time a deterministic per-position tick time (see ticker implementation)
|
|
||||||
* @param state the current block state
|
|
||||||
* @param pos the world position of the block entity
|
|
||||||
*/
|
*/
|
||||||
void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos);
|
void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether this object has completed its initialization logic.
|
|
||||||
*
|
|
||||||
* <p>If this method returns {@code false}, {@link #firstTick(Level, BlockState, BlockPos)}
|
|
||||||
* will be invoked at the start of each tick on both the client and server until
|
|
||||||
* initialization is complete.</p>
|
|
||||||
*
|
|
||||||
* <p>Implementations should return {@code true} once initialization has finished
|
|
||||||
* to prevent {@code firstTick} from running again.</p>
|
|
||||||
*
|
|
||||||
* <p>Returns {@code true} if not implemented.</p>
|
|
||||||
*
|
|
||||||
* @return {@code true} if initialization has completed, {@code false} otherwise
|
|
||||||
*/
|
|
||||||
default boolean isInitialized() {
|
default boolean isInitialized() {
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs initialization logic for this object.
|
* Runs on client AND server, once only.
|
||||||
*
|
* @param level
|
||||||
* <p>This method is called at the start of each tick on both the client and server
|
* @param state
|
||||||
* whenever {@link #isInitialized()} returns {@code false}. It will continue to be
|
* @param pos
|
||||||
* invoked every tick until initialization is complete.</p>
|
|
||||||
*
|
|
||||||
* <p>Implementations should perform any required setup and ensure that
|
|
||||||
* {@code isInitialized()} returns {@code true} afterward.</p>
|
|
||||||
*
|
|
||||||
* <p>Will never run if {@link #isInitialized()} is not implemented.</p>
|
|
||||||
*
|
|
||||||
* @param level the level the block entity exists in
|
|
||||||
* @param state the current block state
|
|
||||||
* @param pos the world position of the block entity
|
|
||||||
*/
|
*/
|
||||||
void firstTick(Level level, BlockState state, BlockPos pos);
|
void firstTick(Level level, BlockState state, BlockPos pos);
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvider, TickableBlockEntity, IArcFurnaceLike {
|
public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvider, TickableBlockEntity {
|
||||||
|
|
||||||
private final int SIZE = 4;
|
private final int SIZE = 4;
|
||||||
private int ENERGY_CAPACITY = 64000;
|
private int ENERGY_CAPACITY = 64000;
|
||||||
@@ -309,11 +309,6 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
|||||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IEnergyStorage getTrueEnergyStorage() {
|
|
||||||
return ENERGY_STORAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final IItemHandler fullHandler = new SidedSlotHandler(inventory, new int[]{INPUT_SLOT, SECONDARY_INPUT_SLOT, OUTPUT_SLOT, ENERGY_SLOT}, true, true);
|
private final IItemHandler fullHandler = new SidedSlotHandler(inventory, new int[]{INPUT_SLOT, SECONDARY_INPUT_SLOT, OUTPUT_SLOT, ENERGY_SLOT}, true, true);
|
||||||
private final IItemHandler emptyJeiHandler = new SidedSlotHandler(inventory, new int[]{}, false, false);
|
private final IItemHandler emptyJeiHandler = new SidedSlotHandler(inventory, new int[]{}, false, false);
|
||||||
private final IItemHandler inputHandler = new SidedSlotHandler(inventory, new int[]{0,1}, true, true);
|
private final IItemHandler inputHandler = new SidedSlotHandler(inventory, new int[]{0,1}, true, true);
|
||||||
@@ -349,11 +344,6 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModEnergyStorage getEnergy() {
|
|
||||||
return ENERGY_STORAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drops() {
|
public void drops() {
|
||||||
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
|
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
|
||||||
for(int i = 0; i < inventory.getSlots(); i++) {
|
for(int i = 0; i < inventory.getSlots(); i++) {
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.entity.custom;
|
|
||||||
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.inventory.ContainerData;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.neoforged.neoforge.energy.IEnergyStorage;
|
|
||||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
|
||||||
import net.xevianlight.aphelion.block.entity.energy.ModEnergyStorage;
|
|
||||||
|
|
||||||
|
|
||||||
public interface IArcFurnaceLike {
|
|
||||||
ItemStackHandler getInventory();
|
|
||||||
ModEnergyStorage getEnergy();
|
|
||||||
|
|
||||||
void sendUpdate();
|
|
||||||
|
|
||||||
BlockState getBlockState();
|
|
||||||
|
|
||||||
IEnergyStorage getTrueEnergyStorage();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package net.xevianlight.aphelion.block.entity.custom;
|
||||||
|
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.ItemInteractionResult;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
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.minecraft.world.phys.Vec3;
|
||||||
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
|
import net.xevianlight.aphelion.block.custom.PipeTestBlock;
|
||||||
|
import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
|
||||||
|
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||||
|
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||||
|
import net.xevianlight.aphelion.systems.conveyor.*;
|
||||||
|
import net.xevianlight.aphelion.util.FloodFill3D;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class PipeTestBlockEntity extends BlockEntity implements TickableBlockEntity {
|
||||||
|
public @Nullable ConveyorNetwork graph = null;
|
||||||
|
public final Map<Direction, @Nullable ConveyorAttachment> attachments = new HashMap<>();
|
||||||
|
public final Map<Direction, @Nullable ConveyorOutput> outputs = new HashMap<>();
|
||||||
|
|
||||||
|
public PipeTestBlockEntity(BlockPos pos, BlockState blockState) {
|
||||||
|
super(ModBlockEntities.PIPE_TEST_BLOCK_ENTITY.get(), pos, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 (this.graph == null) initGraph(level, pos);
|
||||||
|
// TODO: Call this as little as necessary
|
||||||
|
makeOutputs(level, state, pos);
|
||||||
|
|
||||||
|
for (Direction dir : Direction.values()) {
|
||||||
|
ConveyorAttachment attachment = attachments.get(dir);
|
||||||
|
if (attachment != null) {
|
||||||
|
attachment.tick(level, state, pos, dir, graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void firstTick(Level level, BlockState state, BlockPos pos) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addOutput(Direction dir, ConveyorOutput output) {
|
||||||
|
outputs.put(dir, output);
|
||||||
|
if (graph != null) graph.outputs.add(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeOutput(Direction dir) {
|
||||||
|
ConveyorOutput old = outputs.get(dir);
|
||||||
|
if (graph != null) graph.outputs.remove(old);
|
||||||
|
outputs.remove(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canOutputTo(Level level, BlockPos pos, Direction accessSide) {
|
||||||
|
return level.getCapability(Capabilities.ItemHandler.BLOCK, pos, accessSide) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void makeOutputs(ServerLevel level, BlockState state, BlockPos pos) {
|
||||||
|
BlockPos.MutableBlockPos neighbor = new BlockPos.MutableBlockPos();
|
||||||
|
for (Direction dir : Direction.values()) {
|
||||||
|
neighbor.setWithOffset(pos, dir);
|
||||||
|
|
||||||
|
if (canOutputTo(level, neighbor, dir.getOpposite()) && attachments.get(dir) == null && outputs.get(dir) == null) {
|
||||||
|
addOutput(dir, new BasicItemOutput(level, pos, dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(canOutputTo(level, neighbor, dir.getOpposite()) && attachments.get(dir) == null) && outputs.get(dir) != null) {
|
||||||
|
removeOutput(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAttachment(Direction direction) {
|
||||||
|
return attachments.get(direction) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simplest implementation I can think of
|
||||||
|
public static void initGraph(Level level, BlockPos pos) {
|
||||||
|
Aphelion.LOGGER.info("Init graph from {}", pos);
|
||||||
|
if (!level.getBlockState(pos).is(ModBlocks.PIPE_TEST_BLOCK.get())) return;
|
||||||
|
Set<BlockPos> pipes = FloodFill3D.run(
|
||||||
|
level, pos, 1000,
|
||||||
|
(var v1, var v2, var state, var v4, var v5, var v6) -> state.is(ModBlocks.PIPE_TEST_BLOCK.get()),
|
||||||
|
false);
|
||||||
|
|
||||||
|
Aphelion.LOGGER.info("Got {} pipes", pipes.size());
|
||||||
|
ConveyorNetwork graph = new ConveyorNetwork();
|
||||||
|
for (BlockPos pipePos : pipes) {
|
||||||
|
BlockEntity BE = level.getBlockEntity(pipePos);
|
||||||
|
if (BE instanceof PipeTestBlockEntity pipe) {
|
||||||
|
// Invalidate any old graphs
|
||||||
|
if (pipe.graph != null) {
|
||||||
|
pipe.graph.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
graph.addPipe(pipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttachment(Direction side, ConveyorAttachment attachment) {
|
||||||
|
attachments.put(side, attachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean trySetAttachment(Direction side, ConveyorAttachment attachment) {
|
||||||
|
if (hasAttachment(side)) return false;
|
||||||
|
setAttachment(side, attachment);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAttachmentItem(ItemStack stack) {
|
||||||
|
//TODO: add actual attachment items instead of just stone
|
||||||
|
return stack.is(Item.byId(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server only
|
||||||
|
public ConveyorAttachment getAttachmentForItem(ItemStack stack, Direction side) {
|
||||||
|
if (level.isClientSide()) throw new RuntimeException("Cannot get attachment item on client side!");
|
||||||
|
return new BasicItemExtractAttachment((ServerLevel) level, getBlockPos(), side);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called from pipe test block's useItemOn
|
||||||
|
public ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult, PipeTestBlock block) {
|
||||||
|
if (level.isClientSide) return ItemInteractionResult.SUCCESS;
|
||||||
|
Vec3 relativePos = hitResult.getLocation().subtract(pos.getCenter());
|
||||||
|
Direction pipeSide = Direction.getNearest(relativePos);
|
||||||
|
|
||||||
|
if (isAttachmentItem(stack)) {
|
||||||
|
boolean success = trySetAttachment(pipeSide, getAttachmentForItem(stack, pipeSide));
|
||||||
|
|
||||||
|
return success ? ItemInteractionResult.SUCCESS : ItemInteractionResult.FAIL;
|
||||||
|
} else {
|
||||||
|
return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; // goes through with whatever other interaction (placing a block, etc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,15 +16,10 @@ import net.minecraft.world.level.block.Block;
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
|
import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
|
||||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||||
import net.xevianlight.aphelion.core.init.ModDimensions;
|
|
||||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
|
||||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
|
||||||
import net.xevianlight.aphelion.entites.vehicles.RocketEntity;
|
|
||||||
import net.xevianlight.aphelion.util.AphelionBlockStateProperties;
|
import net.xevianlight.aphelion.util.AphelionBlockStateProperties;
|
||||||
import net.xevianlight.aphelion.util.ModTags;
|
import net.xevianlight.aphelion.util.ModTags;
|
||||||
import net.xevianlight.aphelion.util.RocketStructure;
|
import net.xevianlight.aphelion.util.RocketStructure;
|
||||||
@@ -33,8 +28,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RocketAssemblerBlockEntity extends BlockEntity implements TickableBlockEntity {
|
public class RocketAssemblerBlockEntity extends BlockEntity implements TickableBlockEntity {
|
||||||
|
|
||||||
@@ -42,8 +35,6 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
BlockPos padScanStart = BlockPos.ZERO;
|
BlockPos padScanStart = BlockPos.ZERO;
|
||||||
private PadInfo padBounds;
|
private PadInfo padBounds;
|
||||||
|
|
||||||
private @Nullable PartitionData data;
|
|
||||||
|
|
||||||
public @Nullable PadInfo getPadBounds() {
|
public @Nullable PadInfo getPadBounds() {
|
||||||
return padBounds;
|
return padBounds;
|
||||||
}
|
}
|
||||||
@@ -66,21 +57,50 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
|
|
||||||
return dx * dy * dz;
|
return dx * dy * dz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockPos getCenter() {
|
|
||||||
int centerX = (min.getX() + max.getX()) / 2;
|
|
||||||
int centerZ = (min.getZ() + max.getZ()) / 2;
|
|
||||||
|
|
||||||
// bottom Y level
|
|
||||||
int y = min.getY();
|
|
||||||
|
|
||||||
return new BlockPos(centerX, y, centerZ);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Block TOWER_BLOCK = ModBlocks.BLOCK_STEEL.get();
|
private final Block TOWER_BLOCK = ModBlocks.BLOCK_STEEL.get();
|
||||||
public BlockPos towerBasePos;
|
public BlockPos towerBasePos;
|
||||||
|
|
||||||
|
public @Nullable PadInfo getPlatform() {
|
||||||
|
// TODO
|
||||||
|
int y = this.padScanStart.getY();
|
||||||
|
BlockPos start = this.padScanStart;
|
||||||
|
|
||||||
|
if (level == null) return null;
|
||||||
|
if (!isPad(level.getBlockState(start))) return null;
|
||||||
|
|
||||||
|
int minX = start.getX();
|
||||||
|
while (isPad(level.getBlockState(new BlockPos(minX - 1, y, start.getZ())))) minX--;
|
||||||
|
|
||||||
|
// Find maxX by walking east
|
||||||
|
int maxX = start.getX();
|
||||||
|
while (isPad(level.getBlockState(new BlockPos(maxX + 1, y, start.getZ())))) maxX++;
|
||||||
|
|
||||||
|
// Find minZ by walking north
|
||||||
|
int minZ = start.getZ();
|
||||||
|
while (isPad(level.getBlockState(new BlockPos(start.getX(), y, minZ - 1)))) minZ--;
|
||||||
|
|
||||||
|
// Find maxZ by walking south
|
||||||
|
int maxZ = start.getZ();
|
||||||
|
while (isPad(level.getBlockState(new BlockPos(start.getX(), y, maxZ + 1)))) maxZ++;
|
||||||
|
|
||||||
|
int width = (maxX - minX) + 1;
|
||||||
|
int length = (maxZ - minZ) + 1;
|
||||||
|
|
||||||
|
// Must be square
|
||||||
|
if (width != length) return null;
|
||||||
|
|
||||||
|
// Verify the entire rectangle is filled with pad blocks
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
if (!isPad(level.getBlockState(new BlockPos(x, y, z)))) return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PadInfo(new BlockPos(minX, y, minZ), new BlockPos(maxX, y, maxZ));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean connected(BlockState state, Direction dir) {
|
private boolean connected(BlockState state, Direction dir) {
|
||||||
return switch (dir) {
|
return switch (dir) {
|
||||||
case NORTH -> state.getValue(BlockStateProperties.NORTH);
|
case NORTH -> state.getValue(BlockStateProperties.NORTH);
|
||||||
@@ -91,7 +111,7 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable PadInfo getPlatformViaFill() {
|
public @Nullable PadInfo getPlatformFill() {
|
||||||
if (level == null) return null;
|
if (level == null) return null;
|
||||||
|
|
||||||
BlockPos start = this.padScanStart;
|
BlockPos start = this.padScanStart;
|
||||||
@@ -108,8 +128,8 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
visited.add(start.asLong());
|
visited.add(start.asLong());
|
||||||
|
|
||||||
final Direction[] CARDINALS = {Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST};
|
final Direction[] CARDINALS = {Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST};
|
||||||
// When the $#$# are we going to have a rocket larger than 32x32... don't...
|
// When the $#$# are we going to have a rocket larger than 64x64... don't...
|
||||||
final int MAX_PAD_BLOCKS = 1024;
|
final int MAX_PAD_BLOCKS = 4096;
|
||||||
|
|
||||||
boolean towerFound = false;
|
boolean towerFound = false;
|
||||||
while (!queue.isEmpty()) {
|
while (!queue.isEmpty()) {
|
||||||
@@ -124,7 +144,7 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
BlockPos n = p.relative(d);
|
BlockPos n = p.relative(d);
|
||||||
|
|
||||||
if (!connected(s, d)) {
|
if (!connected(s, d)) {
|
||||||
if (isTower(level.getBlockState(n))) {
|
if (level.getBlockState(n).is(TOWER_BLOCK)) {
|
||||||
if (!towerFound) {
|
if (!towerFound) {
|
||||||
towerBasePos = n;
|
towerBasePos = n;
|
||||||
towerFound = true;
|
towerFound = true;
|
||||||
@@ -174,154 +194,16 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
int h = 0;
|
int h = 0;
|
||||||
BlockPos p = base.above();
|
BlockPos p = base.above();
|
||||||
|
|
||||||
while (isTower(level.getBlockState(p))) {
|
while (level.getBlockState(p).is(TOWER_BLOCK)) {
|
||||||
h++;
|
h++;
|
||||||
p = p.above();
|
p = p.above();
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockPos seatPos;
|
public RocketStructure scan() {
|
||||||
|
// TODO
|
||||||
public @Nullable RocketStructure scan() {
|
throw new NotImplementedException();
|
||||||
if (level == null) return null;
|
|
||||||
|
|
||||||
seatPos = null;
|
|
||||||
|
|
||||||
PadInfo bounds = padBounds;
|
|
||||||
if (bounds == null) return null;
|
|
||||||
|
|
||||||
|
|
||||||
BlockPos min = bounds.min();
|
|
||||||
BlockPos max = bounds.max();
|
|
||||||
|
|
||||||
// Find seat, every rocket must have a seat and all blocks in the rocket must be attached to it
|
|
||||||
for (int y = min.getY(); y <= max.getY(); y++) {
|
|
||||||
for (int x = min.getX(); x <= max.getX(); x++) {
|
|
||||||
for (int z = min.getZ(); z <= max.getZ(); z++) {
|
|
||||||
BlockPos p = new BlockPos(x, y, z);
|
|
||||||
BlockState st = level.getBlockState(p);
|
|
||||||
|
|
||||||
if (!st.is(ModTags.Blocks.ROCKET_SEAT)) continue;
|
|
||||||
|
|
||||||
if (seatPos != null && !seatPos.equals(p)) {
|
|
||||||
Aphelion.LOGGER.warn("Rocket scan failed: multiple seats found");
|
|
||||||
seatPos = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
seatPos = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seatPos == null) {
|
|
||||||
Aphelion.LOGGER.warn("Rocket scan failed: no seat found");
|
|
||||||
seatPos = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Direction[] DIRS = Direction.values();
|
|
||||||
|
|
||||||
ArrayDeque<BlockPos> queue = new ArrayDeque<>();
|
|
||||||
LongOpenHashSet visited = new LongOpenHashSet();
|
|
||||||
|
|
||||||
queue.add(seatPos);
|
|
||||||
visited.add(seatPos.asLong());
|
|
||||||
|
|
||||||
RocketStructure structure = new RocketStructure(s -> {});
|
|
||||||
structure.addSeatOffset(0,0,0);
|
|
||||||
|
|
||||||
final int MAX_ROCKET_BLOCKS = 1000;
|
|
||||||
|
|
||||||
while (!queue.isEmpty()) {
|
|
||||||
BlockPos p = queue.removeFirst();
|
|
||||||
BlockState st = level.getBlockState(p);
|
|
||||||
|
|
||||||
if (!within(bounds, p)) continue;
|
|
||||||
|
|
||||||
// Any block cases we should IGNORE
|
|
||||||
if (st.isAir()) continue; // ignore air
|
|
||||||
if (isPad(st)) continue; // ignore the pad
|
|
||||||
if (isTower(st)) continue; // ignore the tower
|
|
||||||
if (p.equals(this.worldPosition)) continue; // ignore the assembler
|
|
||||||
|
|
||||||
// Reject block entities
|
|
||||||
if (st.hasBlockEntity() || level.getBlockEntity(p) != null) {
|
|
||||||
Aphelion.LOGGER.warn("Rocket scan failed: found block entity at {}", p);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dx = p.getX() - seatPos.getX();
|
|
||||||
int dy = p.getY() - seatPos.getY();
|
|
||||||
int dz = p.getZ() - seatPos.getZ();
|
|
||||||
|
|
||||||
if (!fitsSignedByte(dx) || !fitsSignedByte(dy) || !fitsSignedByte(dz)) {
|
|
||||||
Aphelion.LOGGER.warn("Rocket scan failed: structure too large to pack at {} (dx={},dy={},dz={})", p, dx, dy, dz);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// All checks succeeded, add the block to the rocket
|
|
||||||
structure.add(dx, dy, dz, st);
|
|
||||||
|
|
||||||
// Explore neighbors
|
|
||||||
for (Direction d : DIRS) {
|
|
||||||
BlockPos n = p.relative(d);
|
|
||||||
|
|
||||||
if (!within(bounds, n)) continue; // Skip neighbor outside of rocket assembler bounds
|
|
||||||
|
|
||||||
long key = n.asLong();
|
|
||||||
if (visited.contains(key)) continue; // Skip visited blocks
|
|
||||||
|
|
||||||
BlockState ns = level.getBlockState(n);
|
|
||||||
|
|
||||||
if (ns.isAir()) continue;
|
|
||||||
if (isPad(ns)) continue;
|
|
||||||
if (isTower(ns)) continue;
|
|
||||||
if (n.equals(this.worldPosition)) continue;
|
|
||||||
|
|
||||||
visited.add(key);
|
|
||||||
queue.addLast(n);
|
|
||||||
|
|
||||||
if (visited.size() >= MAX_ROCKET_BLOCKS) {
|
|
||||||
Aphelion.LOGGER.warn("Rocket scan failed: exceeded max blocks ({})", MAX_ROCKET_BLOCKS);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (structure.size() == 0) return null;
|
|
||||||
return structure;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable RocketEntity assemble() {
|
|
||||||
if (level == null) return null;
|
|
||||||
RocketStructure structure = scan();
|
|
||||||
RocketEntity rocket = null;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
return rocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean within(PadInfo pad, BlockPos p) {
|
|
||||||
BlockPos min = pad.min;
|
|
||||||
BlockPos max = pad.max;
|
|
||||||
|
|
||||||
return p.getX() >= min.getX() && p.getX() <= max.getX()
|
|
||||||
&& p.getY() >= min.getY() && p.getY() <= max.getY()
|
|
||||||
&& p.getZ() >= min.getZ() && p.getZ() <= max.getZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean fitsSignedByte(int v) {
|
|
||||||
return v >= -128 && v <= 127;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -331,84 +213,27 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
|
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
|
||||||
PadInfo newBounds = getPlatformViaFill();
|
PadInfo newBounds = getPlatformFill();
|
||||||
setPadBoundsAndSync(newBounds);
|
setPadBoundsAndSync(newBounds);
|
||||||
|
|
||||||
boolean formed = newBounds != null;
|
boolean formed = newBounds != null;
|
||||||
if (state.getValue(AphelionBlockStateProperties.FORMED) != formed) {
|
if (state.getValue(AphelionBlockStateProperties.FORMED) != formed) {
|
||||||
level.setBlockAndUpdate(pos, state.setValue(AphelionBlockStateProperties.FORMED, formed));
|
level.setBlockAndUpdate(pos, state.setValue(AphelionBlockStateProperties.FORMED, formed));
|
||||||
if (data != null) {
|
|
||||||
if (formed) {
|
|
||||||
data.addLandingPadController(pos);
|
|
||||||
} else {
|
|
||||||
data.removeLandingPadController(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void firstTick(Level level, BlockState state, BlockPos pos) {
|
public void firstTick(Level level, BlockState state, BlockPos pos) {
|
||||||
if (level.isClientSide()) return;
|
|
||||||
|
|
||||||
facing = getBlockState().getValue(BlockStateProperties.HORIZONTAL_FACING);
|
facing = getBlockState().getValue(BlockStateProperties.HORIZONTAL_FACING);
|
||||||
padScanStart = getBlockPos().mutable().below().relative(facing.getOpposite());
|
padScanStart = getBlockPos().mutable().below().relative(facing.getOpposite());
|
||||||
|
|
||||||
if (level instanceof ServerLevel serverLevel) {
|
|
||||||
if (serverLevel.dimension() == ModDimensions.SPACE) {
|
|
||||||
data = SpacePartitionSavedData.get(serverLevel).getDataForBlockPos(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRemoved() {
|
|
||||||
if (data == null) return;
|
|
||||||
data.removeLandingPadController(worldPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isPad(BlockState s) {
|
private static boolean isPad(BlockState s) {
|
||||||
return s.is(ModTags.Blocks.LAUNCH_PAD); // or s.getBlock() == ModBlocks.PAD.get()
|
return s.is(ModTags.Blocks.LAUNCH_PAD); // or s.getBlock() == ModBlocks.PAD.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isTower(BlockState s) {
|
|
||||||
return s.is(TOWER_BLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull List<RocketEntity> 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<RocketEntity> 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
|
@Override
|
||||||
protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) {
|
protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) {
|
||||||
super.saveAdditional(tag, registries);
|
super.saveAdditional(tag, registries);
|
||||||
@@ -471,6 +296,4 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
this.loadAdditional(tag, registries);
|
this.loadAdditional(tag, registries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
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<ClientGamePacketListener> getUpdatePacket() {
|
|
||||||
return ClientboundBlockEntityDataPacket.create(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class VacuumArcFurnaceControllerEntity extends BlockEntity implements MenuProvider, IMultiblockController, TickableBlockEntity, IArcFurnaceLike {
|
public class VacuumArcFurnaceControllerEntity extends BlockEntity implements MenuProvider, IMultiblockController, TickableBlockEntity {
|
||||||
|
|
||||||
private final int SIZE = 4;
|
private final int SIZE = 4;
|
||||||
private final int ENERGY_CAPACITY = 64000;
|
private final int ENERGY_CAPACITY = 64000;
|
||||||
@@ -357,8 +357,7 @@ public class VacuumArcFurnaceControllerEntity extends BlockEntity implements Men
|
|||||||
return isFormed() ? ENERGY_STORAGE : null;
|
return isFormed() ? ENERGY_STORAGE : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public IEnergyStorage getTrueEnergyStorage(@Nullable Direction direction) {
|
||||||
public IEnergyStorage getTrueEnergyStorage() {
|
|
||||||
return this.ENERGY_STORAGE;
|
return this.ENERGY_STORAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.block.entity.custom.base;
|
|
||||||
|
|
||||||
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.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;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public abstract class StationEngineBlockEntity extends BlockEntity implements TickableBlockEntity {
|
|
||||||
|
|
||||||
private boolean isInitialized = false;
|
|
||||||
protected @Nullable PartitionData data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The travel speed in AU/tick.
|
|
||||||
*/
|
|
||||||
public abstract double getTravelSpeed();
|
|
||||||
|
|
||||||
protected StationEngineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
|
|
||||||
super(type, pos, blockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clientTick(ClientLevel level, long time, BlockState state, BlockPos pos) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInitialized() {
|
|
||||||
return isInitialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
data.addEngine(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isInitialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,14 @@
|
|||||||
package net.xevianlight.aphelion.block.entity.custom.renderer;
|
package net.xevianlight.aphelion.block.entity.custom.renderer;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.RenderStateShard;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.RocketAssemblerBlockEntity;
|
import net.xevianlight.aphelion.block.entity.custom.RocketAssemblerBlockEntity;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -23,42 +19,9 @@ public class RocketAssemblerBlockEntityRenderer implements BlockEntityRenderer<R
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AABB getRenderBoundingBox(RocketAssemblerBlockEntity blockEntity) {
|
|
||||||
// If we don't know bounds yet, fall back to default BE culling.
|
|
||||||
RocketAssemblerBlockEntity.PadInfo pad = blockEntity.getPadBounds();
|
|
||||||
if (pad == null) {
|
|
||||||
return BlockEntityRenderer.super.getRenderBoundingBox(blockEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockPos min = pad.min();
|
|
||||||
BlockPos max = pad.max();
|
|
||||||
|
|
||||||
// Expand slightly to avoid edge precision culling
|
|
||||||
return new AABB(
|
|
||||||
min.getX(), min.getY(), min.getZ(),
|
|
||||||
max.getX() + 1, max.getY() + 1, max.getZ() + 1
|
|
||||||
).inflate(0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final RenderType CENTER_FACE = RenderType.create(
|
|
||||||
"aphelion_center_face",
|
|
||||||
DefaultVertexFormat.POSITION_COLOR,
|
|
||||||
VertexFormat.Mode.QUADS,
|
|
||||||
256,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
RenderType.CompositeState.builder()
|
|
||||||
.setShaderState(RenderStateShard.POSITION_COLOR_SHADER)
|
|
||||||
.setTransparencyState(RenderStateShard.TRANSLUCENT_TRANSPARENCY)
|
|
||||||
.setCullState(RenderStateShard.NO_CULL)
|
|
||||||
.setDepthTestState(RenderStateShard.LEQUAL_DEPTH_TEST)
|
|
||||||
.createCompositeState(false)
|
|
||||||
);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(@NotNull RocketAssemblerBlockEntity be, float v, @NotNull PoseStack poseStack, @NotNull MultiBufferSource multiBufferSource, int i, int i1) {
|
public void render(@NotNull RocketAssemblerBlockEntity be, float v, @NotNull PoseStack poseStack, @NotNull MultiBufferSource multiBufferSource, int i, int i1) {
|
||||||
// if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) return;
|
if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) return;
|
||||||
|
|
||||||
if (be.getPadBounds() == null) return;
|
if (be.getPadBounds() == null) return;
|
||||||
BlockPos min = be.getPadBounds().min();
|
BlockPos min = be.getPadBounds().min();
|
||||||
@@ -72,20 +35,10 @@ public class RocketAssemblerBlockEntityRenderer implements BlockEntityRenderer<R
|
|||||||
poseStack.pushPose();
|
poseStack.pushPose();
|
||||||
poseStack.translate(-be.getBlockPos().getX(), -be.getBlockPos().getY(), -be.getBlockPos().getZ());
|
poseStack.translate(-be.getBlockPos().getX(), -be.getBlockPos().getY(), -be.getBlockPos().getZ());
|
||||||
|
|
||||||
VertexConsumer lineVc = multiBufferSource.getBuffer(RenderType.lines());
|
VertexConsumer vc = multiBufferSource.getBuffer(RenderType.lines());
|
||||||
LevelRenderer.renderLineBox(poseStack, lineVc, box, 0f, 1f, 0f, 1f);
|
|
||||||
|
|
||||||
VertexConsumer faceVc = multiBufferSource.getBuffer(CENTER_FACE);
|
LevelRenderer.renderLineBox(poseStack, vc, box, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
BlockPos center = be.getPadBounds().getCenter();
|
|
||||||
float y = center.getY() + 0.01f; // avoid z-fighting
|
|
||||||
|
|
||||||
LevelRenderer.renderFace(
|
|
||||||
poseStack, faceVc, Direction.UP,
|
|
||||||
center.getX(), y, center.getZ(),
|
|
||||||
center.getX() + 1, y, center.getZ() + 1,
|
|
||||||
1f, 0f, 0f, 0.5f
|
|
||||||
);
|
|
||||||
poseStack.popPose();
|
poseStack.popPose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onEnergyChanged();
|
public abstract void onEnergyChanged();
|
||||||
|
|
||||||
public void setCapacity(int capacity) {
|
|
||||||
this.capacity = capacity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.xevianlight.aphelion.client;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
import net.neoforged.bus.api.SubscribeEvent;
|
import net.neoforged.bus.api.SubscribeEvent;
|
||||||
import net.neoforged.fml.common.EventBusSubscriber;
|
import net.neoforged.fml.common.EventBusSubscriber;
|
||||||
@@ -14,7 +15,7 @@ import net.xevianlight.aphelion.client.dimension.DimensionRendererCache;
|
|||||||
import net.xevianlight.aphelion.client.dimension.SpaceSkyEffects;
|
import net.xevianlight.aphelion.client.dimension.SpaceSkyEffects;
|
||||||
import net.xevianlight.aphelion.core.saveddata.EnvironmentSavedData;
|
import net.xevianlight.aphelion.core.saveddata.EnvironmentSavedData;
|
||||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
||||||
import net.xevianlight.aphelion.util.SpacePartition;
|
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||||
|
|
||||||
@EventBusSubscriber(modid = Aphelion.MOD_ID, value = Dist.CLIENT)
|
@EventBusSubscriber(modid = Aphelion.MOD_ID, value = Dist.CLIENT)
|
||||||
public class AphelionDebugOverlay {
|
public class AphelionDebugOverlay {
|
||||||
@@ -43,22 +44,16 @@ public class AphelionDebugOverlay {
|
|||||||
+ ", thickFog=" + r.hasThickFog()
|
+ ", thickFog=" + r.hasThickFog()
|
||||||
+ ", fog=" + r.hasFog());
|
+ ", fog=" + r.hasFog());
|
||||||
|
|
||||||
int x = SpacePartition.get(Math.floor(mc.player.position().x));
|
int x = SpacePartitionHelper.get(Math.floor(mc.player.position().x));
|
||||||
int z = SpacePartition.get(Math.floor(mc.player.position().z));
|
int z = SpacePartitionHelper.get(Math.floor(mc.player.position().z));
|
||||||
|
|
||||||
// Left side of F3
|
// Left side of F3
|
||||||
event.getLeft().add("");
|
event.getLeft().add("");
|
||||||
event.getLeft().add("Aphelion:");
|
event.getLeft().add("Aphelion:");
|
||||||
event.getLeft().add(" Orbit: " + PartitionClientState.lastData().getOrbit());
|
event.getLeft().add(" Orbit: " + orbitId);
|
||||||
// event.getLeft().add(" Sky: " + rendererSummary);
|
// event.getLeft().add(" Sky: " + rendererSummary);
|
||||||
event.getLeft().add(" Station: " + x + " " + z + " ID: " + SpacePartitionSavedData.pack(x,z));
|
event.getLeft().add(" Station: " + x + " " + z + " ID: " + SpacePartitionSavedData.pack(x,z));
|
||||||
event.getLeft().add(" Station Destination: " + PartitionClientState.lastData().getDestination());
|
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();
|
var server = mc.getSingleplayerServer();
|
||||||
ServerLevel singlePlayerLevel;
|
ServerLevel singlePlayerLevel;
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.client.PartitionClientState;
|
import net.xevianlight.aphelion.client.PartitionClientState;
|
||||||
import net.xevianlight.aphelion.util.SpacePartition;
|
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
@@ -61,8 +61,8 @@ public class DimensionSkyEffects extends DimensionSpecialEffects {
|
|||||||
|
|
||||||
public static ResourceLocation orbitForPos(Vec3 pos) {
|
public static ResourceLocation orbitForPos(Vec3 pos) {
|
||||||
|
|
||||||
int x = SpacePartition.get(pos.x);
|
int x = SpacePartitionHelper.get(pos.x);
|
||||||
int z = SpacePartition.get(pos.z);
|
int z = SpacePartitionHelper.get(pos.z);
|
||||||
|
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
if (mc.level == null) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
|
if (mc.level == null) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.client.PartitionClientState;
|
import net.xevianlight.aphelion.client.PartitionClientState;
|
||||||
import net.xevianlight.aphelion.util.SpacePartition;
|
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
@@ -67,18 +67,20 @@ public class SpaceSkyEffects extends DimensionSpecialEffects {
|
|||||||
|
|
||||||
public static ResourceLocation orbitForPos(Vec3 pos) {
|
public static ResourceLocation orbitForPos(Vec3 pos) {
|
||||||
|
|
||||||
int x = SpacePartition.get(pos.x);
|
int x = SpacePartitionHelper.get(pos.x);
|
||||||
int z = SpacePartition.get(pos.z);
|
int z = SpacePartitionHelper.get(pos.z);
|
||||||
|
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
if (mc.level == null) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
|
if (mc.level == null) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
|
||||||
|
|
||||||
// int px = PartitionClientState.pxOr(0);
|
// int px = PartitionClientState.pxOr(0);
|
||||||
// int py = PartitionClientState.pyOr(0);
|
// int py = PartitionClientState.pyOr(0);
|
||||||
|
var data = ResourceLocation.parse(PartitionClientState.idOrUnknown());
|
||||||
|
|
||||||
// var partitionData = SpacePartitionSavedData.get(serverLevel).getOrbitForPartition((int) x, (int) z);
|
// var partitionData = SpacePartitionSavedData.get(serverLevel).getOrbitForPartition((int) x, (int) z);
|
||||||
return ResourceLocation.parse(PartitionClientState.idOrUnknown());
|
if (data != null) return data;
|
||||||
|
|
||||||
|
return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package net.xevianlight.aphelion.commands;
|
package net.xevianlight.aphelion.commands;
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
import com.mojang.brigadier.arguments.LongArgumentType;
|
import com.mojang.brigadier.arguments.LongArgumentType;
|
||||||
@@ -23,15 +22,14 @@ import net.minecraft.world.level.Level;
|
|||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
||||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
|
||||||
import net.xevianlight.aphelion.entites.vehicles.RocketEntity;
|
import net.xevianlight.aphelion.entites.vehicles.RocketEntity;
|
||||||
|
import net.xevianlight.aphelion.planet.Planet;
|
||||||
import net.xevianlight.aphelion.util.RocketStructure;
|
import net.xevianlight.aphelion.util.RocketStructure;
|
||||||
import net.xevianlight.aphelion.util.SpacePartition;
|
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||||
|
import net.xevianlight.aphelion.util.registries.ModRegistries;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class AphelionCommand {
|
public class AphelionCommand {
|
||||||
|
|
||||||
@@ -44,8 +42,8 @@ public class AphelionCommand {
|
|||||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||||
.then(Commands.argument("orbit", ResourceLocationArgument.id())
|
.then(Commands.argument("orbit", ResourceLocationArgument.id())
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||||
ResourceLocation orbit = ResourceLocationArgument.getId(context, "orbit");
|
ResourceLocation orbit = ResourceLocationArgument.getId(context, "orbit");
|
||||||
|
|
||||||
ServerLevel level = context.getSource().getLevel();
|
ServerLevel level = context.getSource().getLevel();
|
||||||
@@ -82,8 +80,8 @@ public class AphelionCommand {
|
|||||||
.then(Commands.literal("get")
|
.then(Commands.literal("get")
|
||||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||||
|
|
||||||
ServerLevel level = context.getSource().getLevel();
|
ServerLevel level = context.getSource().getLevel();
|
||||||
ResourceLocation orbit = SpacePartitionSavedData.get(level).getOrbitForPartition(x, z);
|
ResourceLocation orbit = SpacePartitionSavedData.get(level).getOrbitForPartition(x, z);
|
||||||
@@ -107,8 +105,8 @@ public class AphelionCommand {
|
|||||||
.then(Commands.literal("clear")
|
.then(Commands.literal("clear")
|
||||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||||
|
|
||||||
ServerLevel level = context.getSource().getLevel();
|
ServerLevel level = context.getSource().getLevel();
|
||||||
|
|
||||||
@@ -145,8 +143,8 @@ public class AphelionCommand {
|
|||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
ServerLevel level = context.getSource().getLevel();
|
ServerLevel level = context.getSource().getLevel();
|
||||||
|
|
||||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context,"pos").x());
|
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context,"pos").x());
|
||||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context,"pos").z());
|
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context,"pos").z());
|
||||||
|
|
||||||
long key = SpacePartitionSavedData.pack(x,z);
|
long key = SpacePartitionSavedData.pack(x,z);
|
||||||
|
|
||||||
@@ -192,7 +190,7 @@ public class AphelionCommand {
|
|||||||
int x = ColumnPosArgument.getColumnPos(context, "pos").x();
|
int x = ColumnPosArgument.getColumnPos(context, "pos").x();
|
||||||
int z = ColumnPosArgument.getColumnPos(context, "pos").z();
|
int z = ColumnPosArgument.getColumnPos(context, "pos").z();
|
||||||
|
|
||||||
String stationCoord = SpacePartition.get(x) + " " + SpacePartition.get(z);
|
String stationCoord = SpacePartitionHelper.get(x) + " " + SpacePartitionHelper.get(z);
|
||||||
|
|
||||||
Component clickableOutput = getClickablePos(stationCoord, ChatFormatting.GREEN);
|
Component clickableOutput = getClickablePos(stationCoord, ChatFormatting.GREEN);
|
||||||
|
|
||||||
@@ -214,8 +212,8 @@ public class AphelionCommand {
|
|||||||
double x = (double) IntegerArgumentType.getInteger(context, "x");
|
double x = (double) IntegerArgumentType.getInteger(context, "x");
|
||||||
double z = (double) IntegerArgumentType.getInteger(context, "z");
|
double z = (double) IntegerArgumentType.getInteger(context, "z");
|
||||||
|
|
||||||
int destX = (int) Math.floor(x * SpacePartition.SIZE) + (SpacePartition.SIZE / 2);
|
int destX = (int) Math.floor(x * SpacePartitionHelper.SIZE) + (SpacePartitionHelper.SIZE / 2);
|
||||||
int destZ = (int) Math.floor(z * SpacePartition.SIZE) + (SpacePartition.SIZE / 2);
|
int destZ = (int) Math.floor(z * SpacePartitionHelper.SIZE) + (SpacePartitionHelper.SIZE / 2);
|
||||||
|
|
||||||
String stationCoord = x + ", " + z;
|
String stationCoord = x + ", " + z;
|
||||||
|
|
||||||
@@ -248,21 +246,16 @@ public class AphelionCommand {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then(Commands.literal("destination")
|
.then(Commands.literal("destination")
|
||||||
.then(Commands.literal("set")
|
.then(Commands.literal("set").then(
|
||||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||||
.then(Commands.argument("id", ResourceLocationArgument.id())
|
.then(Commands.argument("id", ResourceLocationArgument.id())
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
int px = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||||
int pz = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||||
ResourceLocation orbit = ResourceLocationArgument.getId(context, "id");
|
ResourceLocation orbit = ResourceLocationArgument.getId(context, "id");
|
||||||
|
|
||||||
ServerLevel level = context.getSource().getLevel();
|
ServerLevel level = context.getSource().getLevel();
|
||||||
PartitionData data = SpacePartitionSavedData.get(level).getData(px, pz);
|
SpacePartitionSavedData.get(level).getData(x,z).setDestination(orbit);
|
||||||
if (data == null) {
|
|
||||||
context.getSource().sendFailure(Component.translatable("command.aphelion.station.invalid"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
data.setDestination(orbit);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
@@ -270,67 +263,6 @@ public class AphelionCommand {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then(Commands.literal("owner")
|
|
||||||
.then(Commands.literal("get")
|
|
||||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
|
||||||
.executes(context -> {
|
|
||||||
int px = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
|
||||||
int pz = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
|
||||||
|
|
||||||
ServerLevel level = context.getSource().getLevel();
|
|
||||||
PartitionData data = SpacePartitionSavedData.get(level).getData(px, pz);
|
|
||||||
var cache = level.getServer().getProfileCache();
|
|
||||||
if (data == null) {
|
|
||||||
context.getSource().sendFailure(Component.translatable("command.aphelion.station.invalid"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (cache == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
UUID uuid = data.getOwner();
|
|
||||||
if (uuid == null) {
|
|
||||||
context.getSource().sendSuccess(() -> Component.translatable("command.aphelion.station.owner.unset"), true);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = cache.get(uuid).map(GameProfile::getName).orElse(null);
|
|
||||||
context.getSource().sendSuccess(() -> Component.translatable("command.aphelion.station.owner.get", px, pz, name), true);
|
|
||||||
return 1;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.then(Commands.literal("set")
|
|
||||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
|
||||||
.then(Commands.argument("player", GameProfileArgument.gameProfile())
|
|
||||||
.executes(context -> {
|
|
||||||
int px = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
|
||||||
int pz = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
|
||||||
|
|
||||||
ServerLevel level = context.getSource().getLevel();
|
|
||||||
PartitionData data = SpacePartitionSavedData.get(level).getData(px, pz);
|
|
||||||
if (data == null) {
|
|
||||||
context.getSource().sendFailure(Component.translatable("command.aphelion.station.invalid"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
Collection<GameProfile> profiles =
|
|
||||||
GameProfileArgument.getGameProfiles(context, "player");
|
|
||||||
|
|
||||||
if (profiles.size() != 1) {
|
|
||||||
context.getSource().sendFailure(Component.translatable("command.aphelion.player.invalid"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameProfile profile = profiles.iterator().next();
|
|
||||||
UUID uuid = profile.getId();
|
|
||||||
|
|
||||||
data.setOwner(uuid);
|
|
||||||
context.getSource().sendSuccess(() -> Component.translatable("command.aphelion.station.owner.set.success", px, pz, profile.getName()), true);
|
|
||||||
return 1;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
.then(Commands.literal("planet")
|
.then(Commands.literal("planet")
|
||||||
.then(Commands.literal("tp")
|
.then(Commands.literal("tp")
|
||||||
@@ -542,22 +474,6 @@ public class AphelionCommand {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then(Commands.literal("disassemble")
|
|
||||||
.executes(context -> {
|
|
||||||
Entity entity = EntityArgument.getEntity(context, "entity");
|
|
||||||
|
|
||||||
if (entity instanceof RocketEntity rocket) {
|
|
||||||
if (rocket.disassemble()) {
|
|
||||||
context.getSource().sendSuccess(() -> Component.translatable("command.aphelion.rocket.disassemble.success"), true);
|
|
||||||
} else {
|
|
||||||
context.getSource().sendFailure(Component.translatable("command.aphelion.rocket.disassemble.failure"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
context.getSource().sendFailure(Component.translatable("command.aphelion.rocket.entity_invalid"));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import net.minecraft.core.registries.BuiltInRegistries;
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
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.dummy.entity.VAFMultiblockDummyBlockEntity;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.*;
|
import net.xevianlight.aphelion.block.entity.custom.*;
|
||||||
|
|
||||||
@@ -50,16 +49,11 @@ public class ModBlockEntities {
|
|||||||
|
|
||||||
public static final Supplier<BlockEntityType<RocketAssemblerBlockEntity>> ROCKET_ASSEMBLER_BLOCK_ENTITY =
|
public static final Supplier<BlockEntityType<RocketAssemblerBlockEntity>> ROCKET_ASSEMBLER_BLOCK_ENTITY =
|
||||||
BLOCK_ENTITIES.register("rocket_assembler_block_entity", () -> BlockEntityType.Builder.of(
|
BLOCK_ENTITIES.register("rocket_assembler_block_entity", () -> BlockEntityType.Builder.of(
|
||||||
RocketAssemblerBlockEntity::new, ModBlocks.ROCKET_ASSEMBLER.get()).build(null)
|
RocketAssemblerBlockEntity::new, ModBlocks.ROCKET_ASSEMBLER_BLOCK.get()).build(null)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final Supplier<BlockEntityType<StationRocketEngineBlockEntity>> STATION_ROCKET_ENGINE_BLOCK_ENTITY =
|
public static final Supplier<BlockEntityType<PipeTestBlockEntity>> PIPE_TEST_BLOCK_ENTITY =
|
||||||
BLOCK_ENTITIES.register("station_rocket_engine_block_entity", () -> BlockEntityType.Builder.of(
|
BLOCK_ENTITIES.register("pipe_test_block_entity", () -> BlockEntityType.Builder.of(
|
||||||
StationRocketEngineBlockEntity::new, ModBlocks.STATION_ROCKET_ENGINE.get()).build(null)
|
PipeTestBlockEntity::new, ModBlocks.PIPE_TEST_BLOCK.get()).build(null)
|
||||||
);
|
|
||||||
|
|
||||||
public static final Supplier<BlockEntityType<StationFlightComputerBlockEntity>> 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)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ public class ModBlocks {
|
|||||||
public static final DeferredBlock<Block> VACUUM_ARC_FURNACE_CONTROLLER = BLOCKS.register("vacuum_arc_furnace_controller", () -> new VacuumArcFurnaceController(VacuumArcFurnaceController.getProperties()));
|
public static final DeferredBlock<Block> VACUUM_ARC_FURNACE_CONTROLLER = BLOCKS.register("vacuum_arc_furnace_controller", () -> new VacuumArcFurnaceController(VacuumArcFurnaceController.getProperties()));
|
||||||
public static final DeferredBlock<Block> VAF_MULTIBLOCK_DUMMY_BLOCK = BLOCKS.register("vaf_dummy_block", () -> new VAFMultiblockDummyBlock(VAFMultiblockDummyBlock.getProperties()));
|
public static final DeferredBlock<Block> VAF_MULTIBLOCK_DUMMY_BLOCK = BLOCKS.register("vaf_dummy_block", () -> new VAFMultiblockDummyBlock(VAFMultiblockDummyBlock.getProperties()));
|
||||||
public static final DeferredBlock<Block> OXYGEN_TEST_BLOCK = BLOCKS.register("oxygen_test_block", () -> new OxygenTestBlock(OxygenTestBlock.getProperties()));
|
public static final DeferredBlock<Block> OXYGEN_TEST_BLOCK = BLOCKS.register("oxygen_test_block", () -> new OxygenTestBlock(OxygenTestBlock.getProperties()));
|
||||||
public static final DeferredBlock<Block> ROCKET_ASSEMBLER = BLOCKS.register("rocket_assembler", () -> new RocketAssembler(RocketAssembler.getProperties()));
|
public static final DeferredBlock<Block> ROCKET_ASSEMBLER_BLOCK = BLOCKS.register("rocket_assembler_block", () -> new RocketAssemblerBlock(RocketAssemblerBlock.getProperties()));
|
||||||
public static final DeferredBlock<Block> ROCKET_SEAT = BLOCKS.register("rocket_seat", () -> new RocketSeat(RocketSeat.getProperties()));
|
public static final DeferredBlock<Block> PIPE_TEST_BLOCK = BLOCKS.register("pipe", () -> new PipeTestBlock(PipeTestBlock.getProperties()));
|
||||||
public static final DeferredBlock<Block> STATION_ROCKET_ENGINE = BLOCKS.register("station_rocket_engine", () -> new StationRocketEngineBlock(StationRocketEngineBlock.getProperties()));
|
|
||||||
public static final DeferredBlock<Block> BASIC_ROCKET_FUEL_TANK = BLOCKS.register("basic_rocket_fuel_tank", () -> new BasicRocketFuelTank(BasicRocketFuelTank.getProperties()));
|
|
||||||
public static final DeferredBlock<Block> BASIC_ROCKET_CONTAINER = BLOCKS.register("basic_rocket_container", () -> new BasicRocketContainer(BasicRocketContainer.getProperties()));
|
|
||||||
public static final DeferredBlock<Block> STATION_FLIGHT_COMPUTER_BLOCK = BLOCKS.register("station_flight_computer", () -> new StationFlightComputerBlock(StationFlightComputerBlock.getProperties()));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ public class ModCreativeTabs {
|
|||||||
output.accept(ModItems.INGOT_NEODYMIUM);
|
output.accept(ModItems.INGOT_NEODYMIUM);
|
||||||
output.accept(ModItems.INGOT_IRIDIUM);
|
output.accept(ModItems.INGOT_IRIDIUM);
|
||||||
output.accept(ModFluids.OIL_BUCKET);
|
output.accept(ModFluids.OIL_BUCKET);
|
||||||
output.accept(ModFluids.ROCKET_FUEL_BUCKET);
|
|
||||||
output.accept(ModItems.MUSIC_DISC_BIT_SHIFT);
|
output.accept(ModItems.MUSIC_DISC_BIT_SHIFT);
|
||||||
}).build());
|
}).build());
|
||||||
|
|
||||||
@@ -43,6 +42,6 @@ public class ModCreativeTabs {
|
|||||||
output.accept(ModItems.ARC_FURNACE_CASING_BLOCK);
|
output.accept(ModItems.ARC_FURNACE_CASING_BLOCK);
|
||||||
output.accept(ModItems.VACUUM_ARC_FURNACE_CONTROLLER);
|
output.accept(ModItems.VACUUM_ARC_FURNACE_CONTROLLER);
|
||||||
output.accept(ModItems.LAUNCH_PAD);
|
output.accept(ModItems.LAUNCH_PAD);
|
||||||
output.accept(ModItems.ROCKET_ASSEMBLER);
|
output.accept(ModItems.ROCKET_ASSEMBLER_BLOCK);
|
||||||
}).build());
|
}).build());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.core.init;
|
|
||||||
|
|
||||||
import net.minecraft.core.registries.Registries;
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
|
||||||
|
|
||||||
public final class ModDimensions {
|
|
||||||
public static final ResourceKey<Level> SPACE = ResourceKey.create(Registries.DIMENSION, Aphelion.id("space"));
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
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<Fluid> ROCKET_FUEL = create("rocket_fuel");
|
|
||||||
|
|
||||||
private static TagKey<Fluid> create(String name) {
|
|
||||||
return TagKey.create(Registries.FLUID, ResourceLocation.withDefaultNamespace(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TagKey<Fluid> create(ResourceLocation name) {
|
|
||||||
return TagKey.create(Registries.FLUID, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,7 @@ import net.neoforged.neoforge.registries.DeferredItem;
|
|||||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.block.custom.*;
|
import net.xevianlight.aphelion.block.custom.*;
|
||||||
|
import net.xevianlight.aphelion.block.dummy.VAFMultiblockDummyBlock;
|
||||||
import net.xevianlight.aphelion.item.*;
|
import net.xevianlight.aphelion.item.*;
|
||||||
|
|
||||||
public class ModItems {
|
public class ModItems {
|
||||||
@@ -35,11 +36,8 @@ public static final DeferredItem<Item> MUSIC_DISC_BIT_SHIFT = ITEMS.register("mu
|
|||||||
public static final DeferredItem<BlockItem> ARC_FURNACE_CASING_BLOCK = ITEMS.register("arc_furnace_casing", () -> new BlockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK.get(), ArcFurnaceCasingBlock.getItemProperties()));
|
public static final DeferredItem<BlockItem> ARC_FURNACE_CASING_BLOCK = ITEMS.register("arc_furnace_casing", () -> new BlockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK.get(), ArcFurnaceCasingBlock.getItemProperties()));
|
||||||
public static final DeferredItem<BlockItem> VACUUM_ARC_FURNACE_CONTROLLER = ITEMS.register("vacuum_arc_furnace_controller", () -> new BlockItem(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get(), VacuumArcFurnaceController.getItemProperties()));
|
public static final DeferredItem<BlockItem> VACUUM_ARC_FURNACE_CONTROLLER = ITEMS.register("vacuum_arc_furnace_controller", () -> new BlockItem(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get(), VacuumArcFurnaceController.getItemProperties()));
|
||||||
public static final DeferredItem<BlockItem> OXYGEN_TEST_BLOCK = ITEMS.register("oxygen_test_block", () -> new BlockItem(ModBlocks.OXYGEN_TEST_BLOCK.get(), new Item.Properties()));
|
public static final DeferredItem<BlockItem> OXYGEN_TEST_BLOCK = ITEMS.register("oxygen_test_block", () -> new BlockItem(ModBlocks.OXYGEN_TEST_BLOCK.get(), new Item.Properties()));
|
||||||
|
public static final DeferredItem<BlockItem> PIPE_TEST_BLOCK = ITEMS.register("pipe", () -> new BlockItem(ModBlocks.PIPE_TEST_BLOCK.get(), new Item.Properties()));
|
||||||
public static final DeferredItem<BlockItem> LAUNCH_PAD = ITEMS.register("launch_pad", () -> new BlockItem(ModBlocks.LAUNCH_PAD.get(), LaunchPad.getItemProperties()));
|
public static final DeferredItem<BlockItem> LAUNCH_PAD = ITEMS.register("launch_pad", () -> new BlockItem(ModBlocks.LAUNCH_PAD.get(), LaunchPad.getItemProperties()));
|
||||||
public static final DeferredItem<BlockItem> ROCKET_ASSEMBLER = ITEMS.register("rocket_assembler", () -> new BlockItem(ModBlocks.ROCKET_ASSEMBLER.get(), RocketAssembler.getItemProperties()));
|
public static final DeferredItem<BlockItem> ROCKET_ASSEMBLER_BLOCK = ITEMS.register("rocket_assembler_block", () -> new BlockItem(ModBlocks.ROCKET_ASSEMBLER_BLOCK.get(), RocketAssemblerBlock.getItemProperties()));
|
||||||
public static final DeferredItem<BlockItem> ROCKET_SEAT = ITEMS.register("rocket_seat", () -> new BlockItem(ModBlocks.ROCKET_SEAT.get(), RocketSeat.getItemProperties()));
|
|
||||||
public static final DeferredItem<BlockItem> STATION_ROCKET_ENGINE = ITEMS.register("station_rocket_engine", () -> new BlockItem(ModBlocks.STATION_ROCKET_ENGINE.get(), StationRocketEngineBlock.getItemProperties()));
|
|
||||||
public static final DeferredItem<BlockItem> BASIC_ROCKET_FUEL_TANK = ITEMS.register("basic_rocket_fuel_tank", () -> new BlockItem(ModBlocks.BASIC_ROCKET_FUEL_TANK.get(), BasicRocketFuelTank.getItemProperties()));
|
|
||||||
public static final DeferredItem<BlockItem> BASIC_ROCKET_CONTAINER = ITEMS.register("basic_rocket_container", () -> new BlockItem(ModBlocks.BASIC_ROCKET_CONTAINER.get(), BasicRocketContainer.getItemProperties()));
|
|
||||||
// public static final DeferredItem<BlockItem> VAF_MULTIBLOCK_DUMMY_BLOCK = ITEMS.register("vaf_multiblock_dummy_block", () -> new BlockItem(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), VAFMultiblockDummyBlock.getItemProperties()));
|
// public static final DeferredItem<BlockItem> VAF_MULTIBLOCK_DUMMY_BLOCK = ITEMS.register("vaf_multiblock_dummy_block", () -> new BlockItem(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), VAFMultiblockDummyBlock.getItemProperties()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package net.xevianlight.aphelion.core.saveddata;
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
@@ -11,7 +10,6 @@ import net.minecraft.server.level.ServerLevel;
|
|||||||
import net.minecraft.world.level.saveddata.SavedData;
|
import net.minecraft.world.level.saveddata.SavedData;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
||||||
import net.xevianlight.aphelion.util.SpacePartition;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -56,22 +54,10 @@ public class SpacePartitionSavedData extends SavedData {
|
|||||||
|
|
||||||
// Distances (optional; default 0.0)
|
// Distances (optional; default 0.0)
|
||||||
if (e.contains("DistanceTraveled", CompoundTag.TAG_DOUBLE)) {
|
if (e.contains("DistanceTraveled", CompoundTag.TAG_DOUBLE)) {
|
||||||
pd.setDistanceTraveledAU(e.getDouble("DistanceTraveled"));
|
pd.setDistanceTraveled(e.getDouble("DistanceTraveled"));
|
||||||
}
|
}
|
||||||
if (e.contains("DistanceToDest", CompoundTag.TAG_DOUBLE)) {
|
if (e.contains("DistanceToDest", CompoundTag.TAG_DOUBLE)) {
|
||||||
pd.setTripDistanceAU(e.getDouble("DistanceToDest"));
|
pd.setDistanceToDest(e.getDouble("DistanceToDest"));
|
||||||
}
|
|
||||||
|
|
||||||
if (e.hasUUID("Owner")) {
|
|
||||||
pd.setOwner(e.getUUID("Owner"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.contains("Generated", CompoundTag.TAG_BYTE)) {
|
|
||||||
pd.setGenerated(e.getBoolean("Generated"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.contains("LandingPads", CompoundTag.TAG_LONG_ARRAY)) {
|
|
||||||
pd.setLandingPadContollersFromArray(e.getLongArray("LandingPads"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.map.put(key, pd);
|
data.map.put(key, pd);
|
||||||
@@ -104,16 +90,8 @@ public class SpacePartitionSavedData extends SavedData {
|
|||||||
// Traveling + distances
|
// Traveling + distances
|
||||||
e.putBoolean("Traveling", pd.isTraveling());
|
e.putBoolean("Traveling", pd.isTraveling());
|
||||||
|
|
||||||
e.putDouble("DistanceTraveled", pd.getDistanceTraveledAU());
|
e.putDouble("DistanceTraveled", pd.getDistanceTraveled());
|
||||||
e.putDouble("DistanceToDest", pd.recalculateTripDistAU());
|
e.putDouble("DistanceToDest", pd.getDistanceToDest());
|
||||||
|
|
||||||
if (pd.getOwner() != null) {
|
|
||||||
e.putUUID("Owner", pd.getOwner());
|
|
||||||
}
|
|
||||||
|
|
||||||
e.putBoolean("Generated", pd.isGenerated());
|
|
||||||
|
|
||||||
e.putLongArray("LandingPads", pd.getLandingPadContollersAsArray());
|
|
||||||
|
|
||||||
entries.add(e);
|
entries.add(e);
|
||||||
});
|
});
|
||||||
@@ -159,24 +137,10 @@ public class SpacePartitionSavedData extends SavedData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public @Nullable PartitionData getData(int px, int pz) {
|
||||||
* Returns the {@link PartitionData} stored at the given partition indices.
|
|
||||||
*
|
|
||||||
* <p>The returned {@code PartitionData} is mutable. Any modifications to the returned
|
|
||||||
* object will be persisted to the server.</p>
|
|
||||||
*
|
|
||||||
* <p>If no {@code PartitionData} exists at the specified indices, a new instance is
|
|
||||||
* created using {@code aphelion:orbit/default}, stored in the server cache, and returned.</p>
|
|
||||||
*
|
|
||||||
* @param px the partition X index
|
|
||||||
* @param pz the partition Z index
|
|
||||||
* @return the {@code PartitionData} associated with the specified partition indices
|
|
||||||
*/
|
|
||||||
public @NotNull PartitionData getData(int px, int pz) {
|
|
||||||
long key = pack(px, pz);
|
long key = pack(px, pz);
|
||||||
PartitionData data = map.get(key);
|
PartitionData data = map.get(key);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
|
|
||||||
// pick a sensible default orbit, or null if you truly allow it
|
// pick a sensible default orbit, or null if you truly allow it
|
||||||
data = new PartitionData(Aphelion.id("orbit/default"));
|
data = new PartitionData(Aphelion.id("orbit/default"));
|
||||||
map.put(key, data);
|
map.put(key, data);
|
||||||
@@ -185,67 +149,12 @@ public class SpacePartitionSavedData extends SavedData {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link PartitionData} for the partition containing the given world position.
|
|
||||||
*
|
|
||||||
* <p>The returned {@code PartitionData} is mutable. Any modifications to the returned
|
|
||||||
* object will be persisted to the server.</p>
|
|
||||||
*
|
|
||||||
* <p>If no {@code PartitionData} exists for the partition containing the specified
|
|
||||||
* position, a new instance is created using {@code aphelion:orbit/default},
|
|
||||||
* stored in the server cache, and returned.</p>
|
|
||||||
*
|
|
||||||
* @param x the world X coordinate
|
|
||||||
* @param z the world Z coordinate
|
|
||||||
* @return the {@code PartitionData} associated with the partition containing the position
|
|
||||||
*/
|
|
||||||
public @NotNull PartitionData getDataForPos(int x, int z) {
|
|
||||||
int px = SpacePartition.get(x);
|
|
||||||
int pz = SpacePartition.get(z);
|
|
||||||
long key = pack(px, pz);
|
|
||||||
PartitionData data = map.get(key);
|
|
||||||
if (data == null) {
|
|
||||||
|
|
||||||
data = new PartitionData(Aphelion.id("orbit/default"));
|
|
||||||
map.put(key, data);
|
|
||||||
setDirty();
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link PartitionData} for the partition containing the given block position.
|
|
||||||
*
|
|
||||||
* <p>The returned {@code PartitionData} is mutable. Any modifications to the returned
|
|
||||||
* object will be persisted to the server.</p>
|
|
||||||
*
|
|
||||||
* <p>If no {@code PartitionData} exists for the partition containing the specified
|
|
||||||
* position, a new instance is created using {@code aphelion:orbit/default},
|
|
||||||
* stored in the server cache, and returned.</p>
|
|
||||||
*
|
|
||||||
* @param pos the world block position
|
|
||||||
* @return the {@code PartitionData} associated with the partition containing the position
|
|
||||||
*/
|
|
||||||
public @NotNull PartitionData getDataForBlockPos(BlockPos pos) {
|
|
||||||
int px = SpacePartition.get(pos.getX());
|
|
||||||
int pz = SpacePartition.get(pos.getZ());
|
|
||||||
long key = pack(px, pz);
|
|
||||||
PartitionData data = map.get(key);
|
|
||||||
if (data == null) {
|
|
||||||
|
|
||||||
data = new PartitionData(Aphelion.id("orbit/default"));
|
|
||||||
map.put(key, data);
|
|
||||||
setDirty();
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void overwriteAllExistingOrbits(ResourceLocation orbit) {
|
public void overwriteAllExistingOrbits(ResourceLocation orbit) {
|
||||||
if (map.isEmpty()) return;
|
if (map.isEmpty()) return;
|
||||||
|
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
for (var entry : map.long2ObjectEntrySet()) {
|
for (var entry : map.long2ObjectEntrySet()) {
|
||||||
if(!orbit.equals(entry.getValue().getOrbit())) {
|
if(!orbit.equals(entry.getValue())) {
|
||||||
entry.getValue().setOrbit(orbit);
|
entry.getValue().setOrbit(orbit);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,39 @@
|
|||||||
package net.xevianlight.aphelion.core.saveddata.types;
|
package net.xevianlight.aphelion.core.saveddata.types;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.UUIDUtil;
|
|
||||||
import net.minecraft.network.codec.ByteBufCodecs;
|
import net.minecraft.network.codec.ByteBufCodecs;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.xevianlight.aphelion.planet.PlanetCache;
|
|
||||||
import net.xevianlight.aphelion.util.BigCodec;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class PartitionData {
|
public class PartitionData {
|
||||||
public static final int MAX_PADS = 64;
|
|
||||||
private static final StreamCodec<ByteBuf, List<BlockPos>> BLOCKPOS_LIST_CODEC = BlockPos.STREAM_CODEC.apply(ByteBufCodecs.list(MAX_PADS));
|
|
||||||
|
|
||||||
@Nullable private ResourceLocation orbit;
|
@Nullable private ResourceLocation orbit;
|
||||||
@Nullable private ResourceLocation destination;
|
@Nullable private ResourceLocation destination;
|
||||||
private boolean traveling;
|
private boolean traveling;
|
||||||
/// How far we've already gone
|
private double distanceTraveled;
|
||||||
private double distanceTraveledAU;
|
private double distanceToDest;
|
||||||
/// Total trip distance, from start to finish
|
|
||||||
private double tripDistanceAU;
|
|
||||||
private boolean generated;
|
|
||||||
private UUID owner;
|
|
||||||
private List<BlockPos> landingPadControllers;
|
|
||||||
private List<BlockPos> engines;
|
|
||||||
private double currentOrbitDistanceAU;
|
|
||||||
|
|
||||||
public PartitionData() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public PartitionData(@Nullable ResourceLocation orbit) {
|
public PartitionData(@Nullable ResourceLocation orbit) {
|
||||||
this.orbit = orbit;
|
this.orbit = orbit;
|
||||||
this.destination = null;
|
this.destination = null;
|
||||||
this.traveling = false;
|
this.traveling = false;
|
||||||
this.distanceTraveledAU = 0;
|
this.distanceTraveled = 0;
|
||||||
this.tripDistanceAU = 0;
|
this.distanceToDest = 0;
|
||||||
this.generated = false;
|
|
||||||
this.owner = null;
|
|
||||||
this.landingPadControllers = List.of();
|
|
||||||
this.engines = new ArrayList<>(List.of());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PartitionData(PartitionData other) {
|
public PartitionData(PartitionData other) {
|
||||||
this.orbit = other.orbit;
|
this.orbit = other.orbit;
|
||||||
this.destination = other.destination;
|
this.destination = other.destination;
|
||||||
this.traveling = other.traveling;
|
this.traveling = other.traveling;
|
||||||
this.distanceTraveledAU = other.distanceTraveledAU;
|
this.distanceTraveled = other.distanceTraveled;
|
||||||
this.tripDistanceAU = other.tripDistanceAU;
|
this.distanceToDest = other.distanceToDest;
|
||||||
this.generated = other.generated;
|
|
||||||
this.owner = other.owner;
|
|
||||||
this.landingPadControllers = other.landingPadControllers;
|
|
||||||
this.engines = other.engines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final StreamCodec<ByteBuf, PartitionData> STREAM_CODEC =
|
public static final StreamCodec<ByteBuf, PartitionData> STREAM_CODEC =
|
||||||
BigCodec.composite(
|
StreamCodec.composite(
|
||||||
// orbit is nullable -> optional codec
|
// orbit is nullable -> optional codec
|
||||||
ByteBufCodecs.optional(ResourceLocation.STREAM_CODEC),
|
ByteBufCodecs.optional(ResourceLocation.STREAM_CODEC),
|
||||||
d -> Optional.ofNullable(d.getOrbit()),
|
d -> Optional.ofNullable(d.getOrbit()),
|
||||||
@@ -71,33 +46,17 @@ public class PartitionData {
|
|||||||
|
|
||||||
// doubles -> DOUBLE codec
|
// doubles -> DOUBLE codec
|
||||||
ByteBufCodecs.DOUBLE,
|
ByteBufCodecs.DOUBLE,
|
||||||
PartitionData::getDistanceTraveledAU,
|
PartitionData::getDistanceTraveled,
|
||||||
|
|
||||||
ByteBufCodecs.DOUBLE,
|
ByteBufCodecs.DOUBLE,
|
||||||
PartitionData::recalculateTripDistAU,
|
PartitionData::getDistanceToDest,
|
||||||
|
|
||||||
ByteBufCodecs.optional(UUIDUtil.STREAM_CODEC),
|
(orbitOpt, destOpt, traveling, distTraveled, distToDest) -> {
|
||||||
d -> Optional.ofNullable(d.getOwner()),
|
|
||||||
|
|
||||||
ByteBufCodecs.BOOL,
|
|
||||||
PartitionData::isGenerated,
|
|
||||||
|
|
||||||
BLOCKPOS_LIST_CODEC,
|
|
||||||
PartitionData::getLandingPadControllers,
|
|
||||||
|
|
||||||
BLOCKPOS_LIST_CODEC,
|
|
||||||
PartitionData::getEngines,
|
|
||||||
|
|
||||||
(orbitOpt, destOpt, traveling, distTraveled, distToDest, ownerOpt, generated, controllers, engines) -> {
|
|
||||||
PartitionData data = new PartitionData(orbitOpt.orElse(null));
|
PartitionData data = new PartitionData(orbitOpt.orElse(null));
|
||||||
data.destination = destOpt.orElse(null);
|
data.destination = destOpt.orElse(null);
|
||||||
data.traveling = traveling;
|
data.traveling = traveling;
|
||||||
data.distanceTraveledAU = distTraveled;
|
data.distanceTraveled = distTraveled;
|
||||||
data.tripDistanceAU = distToDest;
|
data.distanceToDest = distToDest;
|
||||||
data.owner = ownerOpt.orElse(null);
|
|
||||||
data.generated = generated;
|
|
||||||
data.landingPadControllers = controllers;
|
|
||||||
data.engines = engines;
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -106,10 +65,8 @@ public class PartitionData {
|
|||||||
return this.orbit;
|
return this.orbit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrbit(@Nullable ResourceLocation orbit) {
|
public void setOrbit(ResourceLocation orbit) {
|
||||||
this.orbit = orbit;
|
this.orbit = orbit;
|
||||||
recalculateTripDistAU();
|
|
||||||
distanceTraveledAU = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable ResourceLocation getDestination() {
|
public @Nullable ResourceLocation getDestination() {
|
||||||
@@ -118,8 +75,6 @@ public class PartitionData {
|
|||||||
|
|
||||||
public void setDestination(@Nullable ResourceLocation destination) {
|
public void setDestination(@Nullable ResourceLocation destination) {
|
||||||
this.destination = destination;
|
this.destination = destination;
|
||||||
recalculateTripDistAU();
|
|
||||||
distanceTraveledAU = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraveling() {
|
public boolean isTraveling() {
|
||||||
@@ -130,177 +85,24 @@ public class PartitionData {
|
|||||||
this.traveling = traveling;
|
this.traveling = traveling;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getDistanceTraveledAU() {
|
public double getDistanceTraveled() {
|
||||||
return distanceTraveledAU;
|
return distanceTraveled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDistanceTraveledAU(double distanceTraveledAU) {
|
public void setDistanceTraveled(double distanceTraveled) {
|
||||||
this.distanceTraveledAU = distanceTraveledAU;
|
this.distanceTraveled = distanceTraveled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double recalculateTripDistAU() {
|
public double getDistanceToDest() {
|
||||||
var currentPlanet = PlanetCache.getByOrbitOrNull(orbit);
|
return distanceToDest;
|
||||||
if (currentPlanet == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var destPlanet = PlanetCache.getOrDefault(destination);
|
public void setDistanceToDest(double distanceToDest) {
|
||||||
|
this.distanceToDest = distanceToDest;
|
||||||
var dist = destPlanet.orbitDistance() - currentPlanet.orbitDistance();
|
|
||||||
this.tripDistanceAU = dist;
|
|
||||||
return dist;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTripDistanceAU() {
|
public void travel(double distance) {
|
||||||
return tripDistanceAU;
|
distanceTraveled = Math.min( distanceTraveled + distance, distanceToDest);
|
||||||
}
|
|
||||||
|
|
||||||
public void setTripDistanceAU(double tripDistanceAU) {
|
|
||||||
this.tripDistanceAU = tripDistanceAU;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advances travel progress by the specified distance in AU.
|
|
||||||
*
|
|
||||||
* <p>This increases {@code distanceTraveledAU} by the given amount and clamps
|
|
||||||
* the result so it never exceeds {@code tripDistanceAU}.</p>
|
|
||||||
*
|
|
||||||
* <p>If the requested distance would overshoot the destination, the traveled
|
|
||||||
* distance is set to exactly {@code tripDistanceAU}.</p>
|
|
||||||
*
|
|
||||||
* @param distance the distance to advance in astronomical units (AU)
|
|
||||||
* @return {@code true} when we arrive at our destination, {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
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() {
|
|
||||||
return generated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGenerated(boolean generated) {
|
|
||||||
this.generated = generated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable UUID getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(@Nullable UUID owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a copy of the world positions of all landing pad controllers tracked
|
|
||||||
* by this partition.
|
|
||||||
*
|
|
||||||
* <p>This method returns only the stored {@link BlockPos} locations of known
|
|
||||||
* landing pad controllers, not the controller instances or block entities
|
|
||||||
* themselves. To interact with a controller, retrieve its block entity from
|
|
||||||
* the world using the returned positions.</p>
|
|
||||||
*
|
|
||||||
* <p>The returned list is a defensive copy and may be modified without affecting
|
|
||||||
* the underlying partition data. To persist changes, use
|
|
||||||
* {@code setLandingPadControllers(...)}.</p>
|
|
||||||
*
|
|
||||||
* @return a mutable copy of the landing pad controller positions known to this partition
|
|
||||||
*/
|
|
||||||
public List<BlockPos> getLandingPadControllers() {
|
|
||||||
return new ArrayList<>(landingPadControllers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLandingPadControllers(List<BlockPos> landingPadControllers) {
|
|
||||||
this.landingPadControllers = landingPadControllers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a landing pad controller at the specified world position.
|
|
||||||
*
|
|
||||||
* <p>If a controller does not already exist at the given position, it is added
|
|
||||||
* to the internal collection and the method returns {@code true}. If a controller
|
|
||||||
* is already present at that position, no changes are made.</p>
|
|
||||||
*
|
|
||||||
* @param pos the world position of the landing pad controller to add
|
|
||||||
* @return {@code true} if the controller was added, {@code false} if it already existed
|
|
||||||
*/
|
|
||||||
public boolean addLandingPadController(BlockPos pos) {
|
|
||||||
if (!landingPadControllers.contains(pos)) {
|
|
||||||
landingPadControllers.add(pos);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the landing pad controller at the specified world position.
|
|
||||||
*
|
|
||||||
* <p>If a controller exists at the given position, it is removed from the
|
|
||||||
* internal collection and the method returns {@code true}. If no controller
|
|
||||||
* is present at that position, no changes are made.</p>
|
|
||||||
*
|
|
||||||
* @param pos the world position of the landing pad controller to remove
|
|
||||||
* @return {@code true} if a controller was removed, {@code false} otherwise
|
|
||||||
*/
|
|
||||||
public boolean removeLandingPadController(BlockPos pos) {
|
|
||||||
return landingPadControllers.remove(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a defensive copy of the world positions of all engines tracked by this partition.
|
|
||||||
*
|
|
||||||
* <p>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.</p>
|
|
||||||
*
|
|
||||||
* <p>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.</p>
|
|
||||||
*
|
|
||||||
* <p>The returned list is a defensive copy and may be modified without affecting the
|
|
||||||
* underlying partition data. To persist changes, use {@code setEngines(...)}.</p>
|
|
||||||
*
|
|
||||||
* @return a mutable list containing the tracked engine positions
|
|
||||||
*/
|
|
||||||
public List<BlockPos> getEngines() {
|
|
||||||
return new ArrayList<>(engines);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEngines(List<BlockPos> engines) {
|
|
||||||
this.engines = engines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an engine at the specified world position.
|
|
||||||
*
|
|
||||||
* <p>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.</p>
|
|
||||||
*
|
|
||||||
* @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);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeEngine(BlockPos pos) {
|
|
||||||
return engines.remove(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -313,29 +115,7 @@ public class PartitionData {
|
|||||||
return Objects.equals(this.orbit, that.orbit)
|
return Objects.equals(this.orbit, that.orbit)
|
||||||
&& Objects.equals(this.destination, that.destination)
|
&& Objects.equals(this.destination, that.destination)
|
||||||
&& this.traveling == that.traveling
|
&& this.traveling == that.traveling
|
||||||
&& Double.compare(this.distanceTraveledAU, that.distanceTraveledAU) == 0
|
&& Double.compare(this.distanceTraveled, that.distanceTraveled) == 0
|
||||||
&& Double.compare(this.tripDistanceAU, that.tripDistanceAU) == 0
|
&& Double.compare(this.distanceToDest, that.distanceToDest) == 0;
|
||||||
&& this.generated == that.generated
|
|
||||||
&& Objects.equals(this.owner, that.owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long[] getLandingPadContollersAsArray() {
|
|
||||||
long[] out = new long[landingPadControllers.size()];
|
|
||||||
int i = 0;
|
|
||||||
for (BlockPos pos : landingPadControllers) {
|
|
||||||
out[i] = pos.asLong();
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLandingPadContollersFromArray(long[] in) {
|
|
||||||
List<BlockPos> newList = new java.util.ArrayList<>(List.of());
|
|
||||||
int i = 0;
|
|
||||||
for (Long packedPos : in) {
|
|
||||||
newList.add(BlockPos.of(packedPos));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
setLandingPadControllers(newList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ public class ModBlockLootTableProvider extends BlockLootSubProvider {
|
|||||||
dropSelf(ModBlocks.OXYGEN_TEST_BLOCK.get());
|
dropSelf(ModBlocks.OXYGEN_TEST_BLOCK.get());
|
||||||
dropOther(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), ItemStack.EMPTY.getItem());
|
dropOther(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), ItemStack.EMPTY.getItem());
|
||||||
dropSelf(ModBlocks.LAUNCH_PAD.get());
|
dropSelf(ModBlocks.LAUNCH_PAD.get());
|
||||||
dropSelf(ModBlocks.ROCKET_ASSEMBLER.get());
|
dropSelf(ModBlocks.ROCKET_ASSEMBLER_BLOCK.get());
|
||||||
dropSelf(ModBlocks.ROCKET_SEAT.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
|||||||
// modLoc("block/test_block"),
|
// modLoc("block/test_block"),
|
||||||
// mcLoc("block/furnace_front"),
|
// mcLoc("block/furnace_front"),
|
||||||
// modLoc("block/test_block")));
|
// modLoc("block/test_block")));
|
||||||
blockItem(ModBlocks.ROCKET_ASSEMBLER);
|
blockItem(ModBlocks.ROCKET_ASSEMBLER_BLOCK);
|
||||||
|
|
||||||
blockWithItem(ModBlocks.BLOCK_STEEL);
|
blockWithItem(ModBlocks.BLOCK_STEEL);
|
||||||
blockWithItem(ModBlocks.DIMENSION_CHANGER);
|
blockWithItem(ModBlocks.DIMENSION_CHANGER);
|
||||||
|
|||||||
@@ -44,8 +44,5 @@ public class ModBlockTagProvider extends BlockTagsProvider {
|
|||||||
tag(ModTags.Blocks.LAUNCH_PAD)
|
tag(ModTags.Blocks.LAUNCH_PAD)
|
||||||
.add(ModBlocks.LAUNCH_PAD.get());
|
.add(ModBlocks.LAUNCH_PAD.get());
|
||||||
|
|
||||||
tag(ModTags.Blocks.ROCKET_SEAT)
|
|
||||||
.add(ModBlocks.ROCKET_SEAT.get());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import net.minecraft.data.tags.FluidTagsProvider;
|
|||||||
import net.minecraft.tags.FluidTags;
|
import net.minecraft.tags.FluidTags;
|
||||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.core.init.ModFluidTags;
|
|
||||||
import net.xevianlight.aphelion.fluid.ModFluids;
|
import net.xevianlight.aphelion.fluid.ModFluids;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -23,7 +22,5 @@ public class ModFluidTagsProvider extends FluidTagsProvider {
|
|||||||
// tag(FluidTags.LAVA)
|
// tag(FluidTags.LAVA)
|
||||||
// .add(ModFluids.SOURCE_OIL_FLUID.get())
|
// .add(ModFluids.SOURCE_OIL_FLUID.get())
|
||||||
// .add(ModFluids.FLOWING_OIL_FLUID.get());
|
// .add(ModFluids.FLOWING_OIL_FLUID.get());
|
||||||
tag(ModFluidTags.ROCKET_FUEL)
|
|
||||||
.add(ModFluids.ROCKET_FUEL.get());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package net.xevianlight.aphelion.entites.vehicles;
|
|||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.HolderLookup;
|
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
@@ -14,16 +13,13 @@ import net.minecraft.resources.ResourceKey;
|
|||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.tags.FluidTags;
|
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.*;
|
import net.minecraft.world.entity.*;
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.entity.vehicle.VehicleEntity;
|
import net.minecraft.world.entity.vehicle.VehicleEntity;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
@@ -31,20 +27,14 @@ import net.minecraft.world.level.portal.DimensionTransition;
|
|||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
|
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
|
||||||
import net.neoforged.neoforge.fluids.FluidStack;
|
|
||||||
import net.neoforged.neoforge.fluids.FluidType;
|
import net.neoforged.neoforge.fluids.FluidType;
|
||||||
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
|
||||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.block.entity.energy.ModEnergyStorage;
|
|
||||||
import net.xevianlight.aphelion.core.init.ModEntities;
|
import net.xevianlight.aphelion.core.init.ModEntities;
|
||||||
import net.xevianlight.aphelion.fluid.ModFluids;
|
|
||||||
import net.xevianlight.aphelion.util.RocketStructure;
|
import net.xevianlight.aphelion.util.RocketStructure;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpawn {
|
public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpawn {
|
||||||
|
|
||||||
@@ -61,7 +51,7 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
private double landingPosX;
|
private double landingPosX;
|
||||||
private double landingPosZ;
|
private double landingPosZ;
|
||||||
|
|
||||||
private static final double TELEPORT_Y = 600.0;
|
private static final double TELEPORT_Y = 1000.0;
|
||||||
private static final double ASCEND_ACCEL = 0.0125;
|
private static final double ASCEND_ACCEL = 0.0125;
|
||||||
private static final double DESCEND_SPEED = 1;
|
private static final double DESCEND_SPEED = 1;
|
||||||
|
|
||||||
@@ -73,42 +63,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
private static final EntityDataAccessor<CompoundTag> STRUCTURE_TAG =
|
private static final EntityDataAccessor<CompoundTag> STRUCTURE_TAG =
|
||||||
SynchedEntityData.defineId(RocketEntity.class, EntityDataSerializers.COMPOUND_TAG);
|
SynchedEntityData.defineId(RocketEntity.class, EntityDataSerializers.COMPOUND_TAG);
|
||||||
|
|
||||||
private final FluidTank FUEL_TANK = newFuelTank(0);
|
|
||||||
private final FluidTank FLUID_STORAGE = newFluidTank(0);
|
|
||||||
private final ModEnergyStorage ENERGY_STORAGE = newEnergyStorage(0, 0);
|
|
||||||
private final ItemStackHandler INVENTORY = new ItemStackHandler(0);
|
|
||||||
|
|
||||||
public ItemStackHandler getInventory() {
|
|
||||||
return INVENTORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @NotNull FluidTank newFluidTank(int capacity) {
|
|
||||||
return new FluidTank(capacity) {
|
|
||||||
@Override
|
|
||||||
public boolean isFluidValid(@NotNull FluidStack stack) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @NotNull FluidTank newFuelTank(int capacity) {
|
|
||||||
return new FluidTank(capacity) {
|
|
||||||
@Override
|
|
||||||
public boolean isFluidValid(@NotNull FluidStack stack) {
|
|
||||||
return stack.is(FluidTags.WATER);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @NotNull ModEnergyStorage newEnergyStorage(int capacity, int transfer) {
|
|
||||||
return new ModEnergyStorage(capacity, transfer) {
|
|
||||||
@Override
|
|
||||||
public void onEnergyChanged() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RocketEntity spawnRocket(Level level, BlockPos pos, RocketStructure structure) {
|
public static RocketEntity spawnRocket(Level level, BlockPos pos, RocketStructure structure) {
|
||||||
if (level.isClientSide) return null;
|
if (level.isClientSide) return null;
|
||||||
|
|
||||||
@@ -122,38 +76,12 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
0.0f
|
0.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
// 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);
|
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);
|
level.addFreshEntity(rocket);
|
||||||
|
|
||||||
return rocket;
|
return rocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recalculateCapacitiesFromStructure() {
|
|
||||||
int inv = RocketStructure.calculateInventoryCapacity(structure);
|
|
||||||
int fuelCap = RocketStructure.calculateFuelCapacity(structure);
|
|
||||||
int fluidCap = RocketStructure.calculateFluidCapacity(structure);
|
|
||||||
int energyCap = RocketStructure.calculateEnergyCapacity(structure);
|
|
||||||
|
|
||||||
INVENTORY.setSize(inv);
|
|
||||||
FUEL_TANK.setCapacity(fuelCap);
|
|
||||||
FLUID_STORAGE.setCapacity(fluidCap);
|
|
||||||
ENERGY_STORAGE.setCapacity(energyCap);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void launchTo(ResourceKey<Level> dim, @Nullable BlockPos pos) {
|
public void launchTo(ResourceKey<Level> dim, @Nullable BlockPos pos) {
|
||||||
if (level().isClientSide) return;
|
if (level().isClientSide) return;
|
||||||
|
|
||||||
@@ -176,9 +104,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
|
|
||||||
if (!level().isClientSide) {
|
if (!level().isClientSide) {
|
||||||
|
|
||||||
if (INVENTORY.getSlots() > 0)
|
|
||||||
INVENTORY.insertItem(0, new ItemStack(Items.DIAMOND, 1), false);
|
|
||||||
|
|
||||||
switch (getPhase()) {
|
switch (getPhase()) {
|
||||||
case IDLE, LANDED -> tickIdle();
|
case IDLE, LANDED -> tickIdle();
|
||||||
case PREPARE -> tickPrepare();
|
case PREPARE -> tickPrepare();
|
||||||
@@ -194,14 +119,12 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
}
|
}
|
||||||
case DESCEND -> tickDescend();
|
case DESCEND -> tickDescend();
|
||||||
}
|
}
|
||||||
|
// Simple upward movement
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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());
|
move(MoverType.SELF, getDeltaMovement());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void tickIdle() {
|
private void tickIdle() {
|
||||||
resetDeltaMovement();
|
resetDeltaMovement();
|
||||||
@@ -301,7 +224,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
if (isOnGround()) {
|
if (isOnGround()) {
|
||||||
resetDeltaMovement();
|
resetDeltaMovement();
|
||||||
setPhase(FlightPhase.LANDED);
|
setPhase(FlightPhase.LANDED);
|
||||||
yVel = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setDeltaMovement(0, -DESCEND_SPEED, 0);
|
setDeltaMovement(0, -DESCEND_SPEED, 0);
|
||||||
@@ -357,13 +279,12 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
this.refreshDimensions();
|
this.refreshDimensions();
|
||||||
this.setBoundingBox(this.makeBoundingBox());
|
this.setBoundingBox(this.makeBoundingBox());
|
||||||
|
|
||||||
|
// prevent any internal “snap” from sticking
|
||||||
this.moveTo(x, y, z, yRot, xRot);
|
this.moveTo(x, y, z, yRot, xRot);
|
||||||
|
|
||||||
if (!level().isClientSide) {
|
if (!level().isClientSide) {
|
||||||
this.entityData.set(STRUCTURE_TAG, this.structure.save());
|
this.entityData.set(STRUCTURE_TAG, this.structure.save());
|
||||||
}
|
}
|
||||||
|
|
||||||
recalculateCapacitiesFromStructure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -404,12 +325,9 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readAdditionalSaveData(CompoundTag tag) {
|
protected void readAdditionalSaveData(CompoundTag tag) {
|
||||||
HolderLookup.Provider registries = level().registryAccess();
|
|
||||||
|
|
||||||
if (tag.contains("RocketStructure")) {
|
if (tag.contains("RocketStructure")) {
|
||||||
CompoundTag rocketTag = tag.getCompound("RocketStructure");
|
CompoundTag rocketTag = tag.getCompound("RocketStructure");
|
||||||
structure.load(rocketTag);
|
structure.load(rocketTag);
|
||||||
// recalculateCapacitiesFromStructure();
|
|
||||||
|
|
||||||
// Immediately apply correct bbox on load (server + client)
|
// Immediately apply correct bbox on load (server + client)
|
||||||
double x = getX(), y = getY(), z = getZ();
|
double x = getX(), y = getY(), z = getZ();
|
||||||
@@ -443,22 +361,10 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
if (tag.contains("FlightPhase", Tag.TAG_BYTE)) {
|
if (tag.contains("FlightPhase", Tag.TAG_BYTE)) {
|
||||||
setPhase(FlightPhase.values()[tag.getByte("FlightPhase")]);
|
setPhase(FlightPhase.values()[tag.getByte("FlightPhase")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.contains("Inventory", CompoundTag.TAG_COMPOUND)){
|
|
||||||
INVENTORY.deserializeNBT(registries, tag.getCompound("Inventory"));
|
|
||||||
}
|
|
||||||
|
|
||||||
FUEL_TANK.readFromNBT(registries, tag);
|
|
||||||
FLUID_STORAGE.readFromNBT(registries, tag);
|
|
||||||
|
|
||||||
if (tag.contains("Energy", CompoundTag.TAG_COMPOUND)) {
|
|
||||||
ENERGY_STORAGE.deserializeNBT(registries, tag.getCompound("Energy"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addAdditionalSaveData(CompoundTag tag) {
|
protected void addAdditionalSaveData(CompoundTag tag) {
|
||||||
HolderLookup.Provider registries = level().registryAccess();
|
|
||||||
tag.put("RocketStructure", structure.save());
|
tag.put("RocketStructure", structure.save());
|
||||||
if (targetDim != null)
|
if (targetDim != null)
|
||||||
tag.putString("TargetDim", targetDim.location().toString());
|
tag.putString("TargetDim", targetDim.location().toString());
|
||||||
@@ -469,10 +375,6 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
tag.putDouble("LandingX", landingPosX);
|
tag.putDouble("LandingX", landingPosX);
|
||||||
tag.putDouble("LandingZ", landingPosZ);
|
tag.putDouble("LandingZ", landingPosZ);
|
||||||
tag.putDouble("yVelocity", yVel);
|
tag.putDouble("yVelocity", yVel);
|
||||||
tag.put("Inventory", INVENTORY.serializeNBT(registries));
|
|
||||||
tag = FUEL_TANK.writeToNBT(registries, tag);
|
|
||||||
tag = FLUID_STORAGE.writeToNBT(registries, tag);
|
|
||||||
tag.put("Energy", ENERGY_STORAGE.serializeNBT(registries));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable BlockPos getTargetPos() {
|
public @Nullable BlockPos getTargetPos() {
|
||||||
@@ -534,24 +436,15 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
return EntityDimensions.scalable(w, h).withEyeHeight(Math.max(0.1f, h - 0.2f));
|
return EntityDimensions.scalable(w, h).withEyeHeight(Math.max(0.1f, h - 0.2f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Vec3 getSeatWorldPos(int seatIndex) {
|
|
||||||
int packed = structure.packedSeatAt(seatIndex);
|
|
||||||
|
|
||||||
int dx = RocketStructure.unpackX(packed);
|
|
||||||
int dy = RocketStructure.unpackY(packed);
|
|
||||||
int dz = RocketStructure.unpackZ(packed);
|
|
||||||
|
|
||||||
return this.position().add(dx, dy, dz);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void positionRider(@NotNull Entity passenger, @NotNull MoveFunction move) {
|
protected void positionRider(@NotNull Entity passenger, @NotNull MoveFunction moveFunction) {
|
||||||
if (!this.hasPassenger(passenger)) return;
|
if (!this.hasPassenger(passenger)) return;
|
||||||
|
|
||||||
Vec3 seat = getSeatWorldPos(0); // primary seat
|
// Choose a stable seat position relative to the rocket.
|
||||||
move.accept(passenger, seat.x, seat.y, seat.z);
|
// Example: centered, and 1.5 blocks above your base Y.
|
||||||
|
Vec3 seat = new Vec3(this.getX(), this.getY() + structure.computeExtents().toLocalAABB().getYsize() / 2, this.getZ());
|
||||||
|
|
||||||
|
moveFunction.accept(passenger, seat.x, seat.y, seat.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -570,7 +463,7 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
|
|
||||||
public void applyStructureTag(CompoundTag structureTag) {
|
public void applyStructureTag(CompoundTag structureTag) {
|
||||||
this.structure.load(structureTag);
|
this.structure.load(structureTag);
|
||||||
this.refreshDimensions();
|
this.refreshDimensions(); // if your hitbox/eye depends on structure
|
||||||
}
|
}
|
||||||
|
|
||||||
private AABB computeWorldAABBFromStructure() {
|
private AABB computeWorldAABBFromStructure() {
|
||||||
@@ -603,72 +496,4 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
return InteractionResult.sidedSuccess(level().isClientSide);
|
return InteractionResult.sidedSuccess(level().isClientSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
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().
|
|
||||||
// This SHOULD fix that
|
|
||||||
if (!this.isAlive()) return false; // dead
|
|
||||||
if (this.isRemoved()) return false; // discarded / removed
|
|
||||||
|
|
||||||
ejectPassengers();
|
|
||||||
|
|
||||||
BlockPos origin = BlockPos.containing(getX(), getY(), getZ());
|
|
||||||
|
|
||||||
// Place blocks
|
|
||||||
for (int i = 0; i < structure.size(); i++) {
|
|
||||||
int packed = structure.packedPosAt(i);
|
|
||||||
|
|
||||||
int dx = RocketStructure.unpackX(packed);
|
|
||||||
int dy = RocketStructure.unpackY(packed);
|
|
||||||
int dz = RocketStructure.unpackZ(packed);
|
|
||||||
|
|
||||||
BlockPos wp = origin.offset(dx, dy, dz);
|
|
||||||
var stateToPlace = structure.stateAt(i);
|
|
||||||
|
|
||||||
// Don't place air (shouldn't exist in structure anyway, but safe)
|
|
||||||
if (stateToPlace.isAir()) continue;
|
|
||||||
|
|
||||||
// Safety: don't overwrite existing blocks
|
|
||||||
if (!server.getBlockState(wp).isAir()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.setBlock(wp, stateToPlace, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the rocket entity
|
|
||||||
discard(); // preferred over kill() for "just remove this entity"
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dropItemStackHandler(ServerLevel level, Vec3 pos, ItemStackHandler handler) {
|
|
||||||
for (int i = 0; i < handler.getSlots(); i++) {
|
|
||||||
ItemStack stack = handler.getStackInSlot(i);
|
|
||||||
if (!stack.isEmpty()) {
|
|
||||||
ItemStack toDrop = stack.copy();
|
|
||||||
handler.setStackInSlot(i, ItemStack.EMPTY);
|
|
||||||
|
|
||||||
ItemEntity ent = new ItemEntity(level, pos.x, pos.y, pos.z, toDrop);
|
|
||||||
level.addFreshEntity(ent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void kill() {
|
|
||||||
if (!level().isClientSide())
|
|
||||||
dropItemStackHandler((ServerLevel) level(), position(), INVENTORY);
|
|
||||||
super.kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRemovedFromLevel() {
|
|
||||||
if (!level().isClientSide())
|
|
||||||
dropItemStackHandler((ServerLevel) level(), position(), INVENTORY);
|
|
||||||
super.onRemovedFromLevel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -8,13 +8,11 @@ import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
|
|||||||
import net.neoforged.neoforge.network.registration.HandlerThread;
|
import net.neoforged.neoforge.network.registration.HandlerThread;
|
||||||
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
|
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
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.dummy.entity.BaseMultiblockDummyBlockEntity;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
|
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.VacuumArcFurnaceControllerEntity;
|
import net.xevianlight.aphelion.block.entity.custom.VacuumArcFurnaceControllerEntity;
|
||||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||||
import net.xevianlight.aphelion.core.init.ModEntities;
|
|
||||||
import net.xevianlight.aphelion.network.RocketPayloadHandlers;
|
import net.xevianlight.aphelion.network.RocketPayloadHandlers;
|
||||||
import net.xevianlight.aphelion.network.PartitionPayloadHandler;
|
import net.xevianlight.aphelion.network.PartitionPayloadHandler;
|
||||||
import net.xevianlight.aphelion.network.packet.PartitionPayload;
|
import net.xevianlight.aphelion.network.packet.PartitionPayload;
|
||||||
@@ -25,20 +23,13 @@ public class ModBusEvents {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void registerCapabilities(RegisterCapabilitiesEvent event) {
|
public static void registerCapabilities(RegisterCapabilitiesEvent event) {
|
||||||
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.TEST_BLOCK_ENTITY.get(), TestBlockEntity::getItemHandler);
|
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.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.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.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.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(), VAFMultiblockDummyBlockEntity::getItemHandler);
|
||||||
|
|
||||||
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.VAF_MULTIBLOCK_DUMMY_ENTITY.get(), BaseMultiblockDummyBlockEntity::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.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
|
@SubscribeEvent
|
||||||
|
|||||||
@@ -7,11 +7,7 @@ import net.minecraft.client.Camera;
|
|||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
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.client.extensions.common.IClientFluidTypeExtensions;
|
||||||
import net.neoforged.neoforge.common.SoundAction;
|
|
||||||
import net.neoforged.neoforge.common.SoundActions;
|
|
||||||
import net.neoforged.neoforge.fluids.FluidType;
|
import net.neoforged.neoforge.fluids.FluidType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -57,17 +53,6 @@ public class BaseFluidType extends FluidType {
|
|||||||
this.fogEnd = fogEnd;
|
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() {
|
public IClientFluidTypeExtensions getClientFluidTypeExtensions() {
|
||||||
return new IClientFluidTypeExtensions() {
|
return new IClientFluidTypeExtensions() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -8,51 +8,23 @@ import net.neoforged.neoforge.registries.NeoForgeRegistries;
|
|||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ModFluidTypes {
|
public class ModFluidTypes {
|
||||||
public static final ResourceLocation WATER_STILL_RL =
|
public static final ResourceLocation WATER_STILL_RL = ResourceLocation.parse("block/water_still");
|
||||||
ResourceLocation.fromNamespaceAndPath("minecraft", "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_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<FluidType> FLUID_TYPES =
|
public static final DeferredRegister<FluidType> FLUID_TYPES =
|
||||||
DeferredRegister.create(NeoForgeRegistries.Keys.FLUID_TYPES, Aphelion.MOD_ID);
|
DeferredRegister.create(NeoForgeRegistries.Keys.FLUID_TYPES, Aphelion.MOD_ID);
|
||||||
|
|
||||||
public static final Supplier<FluidType> OIL_FLUID_TYPE = registerFluidType("oil",
|
public static final Supplier<FluidType> OIL_FLUID_TYPE = registerFluidType("oil",
|
||||||
new BaseFluidType(
|
new BaseFluidType(WATER_STILL_RL, WATER_FLOWING_RL, WATER_OVERLAY_RL, 0xFF101010,
|
||||||
WATER_STILL_RL,
|
new Vector3f(10f / 255f, 10f / 255f, 10f / 255f),
|
||||||
WATER_FLOWING_RL,
|
FluidType.Properties.create().canDrown(true), 0f, 2f
|
||||||
WATER_OVERLAY_RL,
|
|
||||||
oilColor.getRGB(),
|
|
||||||
colToVec(oilColor),
|
|
||||||
FluidType.Properties.create().canDrown(true),
|
|
||||||
0f,
|
|
||||||
0.5f
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
public static final Supplier<FluidType> 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<FluidType> registerFluidType(String name, FluidType fluidType) {
|
private static Supplier<FluidType> registerFluidType(String name, FluidType fluidType) {
|
||||||
return FLUID_TYPES.register(name, () -> fluidType);
|
return FLUID_TYPES.register(name, () -> fluidType);
|
||||||
}
|
}
|
||||||
@@ -60,8 +32,4 @@ public class ModFluidTypes {
|
|||||||
public static void register(IEventBus eventBus) {
|
public static void register(IEventBus eventBus) {
|
||||||
FLUID_TYPES.register(eventBus);
|
FLUID_TYPES.register(eventBus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector3f colToVec (Color color) {
|
|
||||||
return new Vector3f(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,35 +24,19 @@ public class ModFluids {
|
|||||||
public static final DeferredRegister<Fluid> FLUIDS =
|
public static final DeferredRegister<Fluid> FLUIDS =
|
||||||
DeferredRegister.create(BuiltInRegistries.FLUID, Aphelion.MOD_ID);
|
DeferredRegister.create(BuiltInRegistries.FLUID, Aphelion.MOD_ID);
|
||||||
|
|
||||||
public static final Supplier<FlowingFluid> ROCKET_FUEL = FLUIDS.register("rocket_fuel",
|
public static final Supplier<FlowingFluid> SOURCE_OIL_FLUID = FLUIDS.register("oil",
|
||||||
() -> new BaseFlowingFluid.Source(ModFluids.ROCKET_FUEL_PROPERTIES));
|
|
||||||
public static final Supplier<FlowingFluid> FLOWING_ROCKET_FUEL = FLUIDS.register("flowing_rocket_fuel",
|
|
||||||
() -> new BaseFlowingFluid.Flowing(ModFluids.ROCKET_FUEL_PROPERTIES));
|
|
||||||
|
|
||||||
public static final DeferredBlock<LiquidBlock> ROCKET_FUEL_BLOCK = ModBlocks.BLOCKS.register("rocket_fuel",
|
|
||||||
() -> new LiquidBlock(ModFluids.ROCKET_FUEL.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable()));
|
|
||||||
|
|
||||||
public static final DeferredItem<Item> 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<FlowingFluid> OIL = FLUIDS.register("oil",
|
|
||||||
() -> new BaseFlowingFluid.Source(ModFluids.OIL_PROPERTIES));
|
() -> new BaseFlowingFluid.Source(ModFluids.OIL_PROPERTIES));
|
||||||
public static final Supplier<FlowingFluid> FLOWING_OIL = FLUIDS.register("flowing_oil",
|
public static final Supplier<FlowingFluid> FLOWING_OIL_FLUID = FLUIDS.register("flowing_oil",
|
||||||
() -> new BaseFlowingFluid.Flowing(ModFluids.OIL_PROPERTIES));
|
() -> new BaseFlowingFluid.Flowing(ModFluids.OIL_PROPERTIES));
|
||||||
|
|
||||||
public static final DeferredBlock<LiquidBlock> OIL_BLOCK = ModBlocks.BLOCKS.register("oil",
|
public static final DeferredBlock<LiquidBlock> OIL_BLOCK = ModBlocks.BLOCKS.register("oil",
|
||||||
() -> new LiquidBlock(ModFluids.OIL.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable()));
|
() -> new LiquidBlock(ModFluids.SOURCE_OIL_FLUID.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable()));
|
||||||
|
|
||||||
public static final DeferredItem<Item> OIL_BUCKET = ModItems.ITEMS.registerItem("oil_bucket",
|
public static final DeferredItem<Item> OIL_BUCKET = ModItems.ITEMS.registerItem("oil_bucket",
|
||||||
properties -> new BucketItem(ModFluids.OIL.get(), properties.stacksTo(1).craftRemainder(Items.BUCKET)));
|
properties -> new BucketItem(ModFluids.SOURCE_OIL_FLUID.get(), properties.stacksTo(1).craftRemainder(Items.BUCKET)));
|
||||||
|
|
||||||
public static final BaseFlowingFluid.Properties OIL_PROPERTIES = new BaseFlowingFluid.Properties(
|
public static final BaseFlowingFluid.Properties OIL_PROPERTIES = new BaseFlowingFluid.Properties(
|
||||||
ModFluidTypes.OIL_FLUID_TYPE, OIL, FLOWING_OIL)
|
ModFluidTypes.OIL_FLUID_TYPE, SOURCE_OIL_FLUID, FLOWING_OIL_FLUID)
|
||||||
.slopeFindDistance(2).levelDecreasePerBlock(2).tickRate(10)
|
.slopeFindDistance(2).levelDecreasePerBlock(2).tickRate(10)
|
||||||
.block(ModFluids.OIL_BLOCK).bucket(ModFluids.OIL_BUCKET);
|
.block(ModFluids.OIL_BLOCK).bucket(ModFluids.OIL_BUCKET);
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import net.xevianlight.aphelion.Aphelion;
|
|||||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
||||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
||||||
import net.xevianlight.aphelion.network.packet.PartitionPayload;
|
import net.xevianlight.aphelion.network.packet.PartitionPayload;
|
||||||
import net.xevianlight.aphelion.util.SpacePartition;
|
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -42,8 +42,8 @@ public final class PartitionSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static PartitionPayload computePartitionFor(ServerPlayer sp) {
|
private static PartitionPayload computePartitionFor(ServerPlayer sp) {
|
||||||
int px = (int)Math.floor(sp.getX() / SpacePartition.SIZE);
|
int px = (int)Math.floor(sp.getX() / SpacePartitionHelper.SIZE);
|
||||||
int pz = (int)Math.floor(sp.getZ() / SpacePartition.SIZE);
|
int pz = (int)Math.floor(sp.getZ() / SpacePartitionHelper.SIZE);
|
||||||
|
|
||||||
PartitionData live = SpacePartitionSavedData.get(sp.serverLevel()).getData(px, pz);
|
PartitionData live = SpacePartitionSavedData.get(sp.serverLevel()).getData(px, pz);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
|||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -22,7 +21,7 @@ public record PartitionPayload(PartitionData partitionData) implements CustomPac
|
|||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
|
|||||||
import net.minecraft.util.GsonHelper;
|
import net.minecraft.util.GsonHelper;
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
|
import net.xevianlight.aphelion.client.dimension.DimensionRenderer;
|
||||||
import net.xevianlight.aphelion.util.Constants;
|
import net.xevianlight.aphelion.util.Constants;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
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<Orbit> CODEC = RecordCodecBuilder.create(inst -> inst.group(
|
|
||||||
Codec.INT.fieldOf("temp").forGetter(Orbit::temp)
|
|
||||||
).apply(inst, Orbit::new));
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,8 @@ import net.minecraft.resources.ResourceKey;
|
|||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.xevianlight.aphelion.util.registries.ModRegistries;
|
import net.xevianlight.aphelion.util.registries.ModRegistries;
|
||||||
|
|
||||||
public record Planet (
|
public record Planet(
|
||||||
ResourceKey<Level> dimension,
|
ResourceKey<Level> dimension,
|
||||||
ResourceKey<Orbit> orbit,
|
|
||||||
double orbitDistance,
|
double orbitDistance,
|
||||||
ResourceKey<StarSystem> system,
|
ResourceKey<StarSystem> system,
|
||||||
boolean oxygen,
|
boolean oxygen,
|
||||||
@@ -17,7 +16,6 @@ public record Planet (
|
|||||||
) {
|
) {
|
||||||
public static final Codec<Planet> CODEC = RecordCodecBuilder.create(inst -> inst.group(
|
public static final Codec<Planet> CODEC = RecordCodecBuilder.create(inst -> inst.group(
|
||||||
ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(Planet::dimension),
|
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),
|
Codec.DOUBLE.fieldOf("orbit_distance").forGetter(Planet::orbitDistance),
|
||||||
ResourceKey.codec(ModRegistries.STAR_SYSTEM).fieldOf("star_system").forGetter(Planet::system),
|
ResourceKey.codec(ModRegistries.STAR_SYSTEM).fieldOf("star_system").forGetter(Planet::system),
|
||||||
Codec.BOOL.fieldOf("oxygen").forGetter(Planet::oxygen),
|
Codec.BOOL.fieldOf("oxygen").forGetter(Planet::oxygen),
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.util.registries.ModRegistries;
|
import net.xevianlight.aphelion.util.registries.ModRegistries;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -18,7 +17,6 @@ public final class PlanetCache {
|
|||||||
|
|
||||||
public static final Planet DEFAULT = new Planet(
|
public static final Planet DEFAULT = new Planet(
|
||||||
ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")),
|
ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")),
|
||||||
ResourceKey.create(ModRegistries.ORBIT, Aphelion.id("orbit/overworld")),
|
|
||||||
1,
|
1,
|
||||||
ResourceKey.create(ModRegistries.STAR_SYSTEM, Aphelion.id("sol")),
|
ResourceKey.create(ModRegistries.STAR_SYSTEM, Aphelion.id("sol")),
|
||||||
true,
|
true,
|
||||||
@@ -50,17 +48,6 @@ public final class PlanetCache {
|
|||||||
return PLANETS.getOrDefault(id, DEFAULT);
|
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<Level> dimension) {
|
public static Planet getByDimensionOrNull(ResourceKey<Level> dimension) {
|
||||||
ResourceLocation planetId = PLANET_BY_DIMENSION.get(dimension);
|
ResourceLocation planetId = PLANET_BY_DIMENSION.get(dimension);
|
||||||
return planetId == null ? null : PLANETS.get(planetId);
|
return planetId == null ? null : PLANETS.get(planetId);
|
||||||
|
|||||||
@@ -12,14 +12,13 @@ import net.minecraft.world.level.Level;
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.neoforged.neoforge.items.SlotItemHandler;
|
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.IArcFurnaceLike;
|
|
||||||
import net.xevianlight.aphelion.util.EnergyItemSlot;
|
import net.xevianlight.aphelion.util.EnergyItemSlot;
|
||||||
import net.xevianlight.aphelion.util.ExtractOnlySlot;
|
import net.xevianlight.aphelion.util.ExtractOnlySlot;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
||||||
|
|
||||||
public final IArcFurnaceLike blockEntity;
|
public final ElectricArcFurnaceEntity blockEntity;
|
||||||
private final Level level;
|
private final Level level;
|
||||||
private final ContainerData data;
|
private final ContainerData data;
|
||||||
|
|
||||||
@@ -29,17 +28,17 @@ public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
|||||||
|
|
||||||
public ElectricArcFurnaceMenu(int i, Inventory inventory, BlockEntity blockEntity, ContainerData data) {
|
public ElectricArcFurnaceMenu(int i, Inventory inventory, BlockEntity blockEntity, ContainerData data) {
|
||||||
super(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), i);
|
super(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), i);
|
||||||
this.blockEntity = ((IArcFurnaceLike) blockEntity);
|
this.blockEntity = ((ElectricArcFurnaceEntity) blockEntity);
|
||||||
this.level = inventory.player.level();
|
this.level = inventory.player.level();
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|
||||||
addPlayerInventory(inventory);
|
addPlayerInventory(inventory);
|
||||||
addPlayerHotbar(inventory);
|
addPlayerHotbar(inventory);
|
||||||
|
|
||||||
this.addSlot(new EnergyItemSlot(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.ENERGY_SLOT, 8, 54));
|
this.addSlot(new EnergyItemSlot(this.blockEntity.inventory, ElectricArcFurnaceEntity.ENERGY_SLOT, 8, 54));
|
||||||
this.addSlot(new SlotItemHandler(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.INPUT_SLOT, 63, 35));
|
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, ElectricArcFurnaceEntity.INPUT_SLOT, 63, 35));
|
||||||
this.addSlot(new SlotItemHandler(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.SECONDARY_INPUT_SLOT, 40, 35));
|
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, ElectricArcFurnaceEntity.SECONDARY_INPUT_SLOT, 40, 35));
|
||||||
this.addSlot(new ExtractOnlySlot(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.OUTPUT_SLOT, 125, 35));
|
this.addSlot(new ExtractOnlySlot(this.blockEntity.inventory, ElectricArcFurnaceEntity.OUTPUT_SLOT, 125, 35));
|
||||||
|
|
||||||
addDataSlots(data);
|
addDataSlots(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ public class ElectricArcFurnaceScreen extends AbstractContainerScreen<ElectricAr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
||||||
int stored = menu.blockEntity.getTrueEnergyStorage().getEnergyStored();
|
int stored = menu.blockEntity.getTrueEnergyStorage(null).getEnergyStored();
|
||||||
int max = menu.blockEntity.getTrueEnergyStorage().getMaxEnergyStored();
|
int max = menu.blockEntity.getTrueEnergyStorage(null).getMaxEnergyStored();
|
||||||
|
|
||||||
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
||||||
h = Math.max(0, Math.min(42, h));
|
h = Math.max(0, Math.min(42, h));
|
||||||
@@ -79,7 +79,7 @@ public class ElectricArcFurnaceScreen extends AbstractContainerScreen<ElectricAr
|
|||||||
|
|
||||||
private void assignEnergyInfoArea() {
|
private void assignEnergyInfoArea() {
|
||||||
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
||||||
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(), 14, 42);
|
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(null), 14, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ public class VacuumArcFurnaceScreen extends AbstractContainerScreen<VacuumArcFur
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
||||||
int stored = menu.blockEntity.getTrueEnergyStorage().getEnergyStored();
|
int stored = menu.blockEntity.getTrueEnergyStorage(null).getEnergyStored();
|
||||||
int max = menu.blockEntity.getTrueEnergyStorage().getMaxEnergyStored();
|
int max = menu.blockEntity.getTrueEnergyStorage(null).getMaxEnergyStored();
|
||||||
|
|
||||||
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
||||||
h = Math.max(0, Math.min(42, h));
|
h = Math.max(0, Math.min(42, h));
|
||||||
@@ -79,7 +79,7 @@ public class VacuumArcFurnaceScreen extends AbstractContainerScreen<VacuumArcFur
|
|||||||
|
|
||||||
private void assignEnergyInfoArea() {
|
private void assignEnergyInfoArea() {
|
||||||
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
||||||
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(), 14, 42);
|
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(null), 14, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package net.xevianlight.aphelion.systems.conveyor;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
|
||||||
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
|
import net.neoforged.neoforge.items.IItemHandler;
|
||||||
|
import net.xevianlight.aphelion.block.entity.custom.PipeTestBlockEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class BasicItemExtractAttachment extends ConveyorAttachment implements ConveyorInput {
|
||||||
|
|
||||||
|
BlockCapabilityCache<IItemHandler, @Nullable Direction> capabilityCache;
|
||||||
|
|
||||||
|
public BasicItemExtractAttachment(ServerLevel level, BlockPos pos, Direction facingDirection) {
|
||||||
|
super(level, pos, facingDirection);
|
||||||
|
|
||||||
|
capabilityCache = BlockCapabilityCache.create(
|
||||||
|
Capabilities.ItemHandler.BLOCK,
|
||||||
|
level,
|
||||||
|
pos.relative(facingDirection),
|
||||||
|
facingDirection.getOpposite()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(ServerLevel level, BlockState state, BlockPos pos, Direction facingDirection, ConveyorNetwork network) {
|
||||||
|
// do an extract and distribute
|
||||||
|
IItemHandler container = capabilityCache.getCapability();
|
||||||
|
if (container == null) return;
|
||||||
|
|
||||||
|
final int EXTRACT_PER_TICK = 4;
|
||||||
|
int to_extract = EXTRACT_PER_TICK;
|
||||||
|
|
||||||
|
int extract_slot_id = container.getSlots() - 1;
|
||||||
|
while (extract_slot_id >= 0 && container.getStackInSlot(extract_slot_id).isEmpty()) extract_slot_id--;
|
||||||
|
if (extract_slot_id == -1) return;
|
||||||
|
|
||||||
|
|
||||||
|
// Do a simulated extract, then run through every output side on the graph and do real inserts.
|
||||||
|
// By the end, remove as many items as we successfully inserted with a real extract
|
||||||
|
ItemStack to_distribute = container.extractItem(extract_slot_id, to_extract, true);
|
||||||
|
int extracted_amount = to_distribute.getCount();
|
||||||
|
|
||||||
|
to_distribute = network.insertItem(to_distribute, false);
|
||||||
|
|
||||||
|
int distributed_amount = extracted_amount;
|
||||||
|
if (!to_distribute.isEmpty()) {
|
||||||
|
distributed_amount = extracted_amount - to_distribute.getCount();
|
||||||
|
}
|
||||||
|
container.extractItem(extract_slot_id, distributed_amount, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package net.xevianlight.aphelion.systems.conveyor;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
|
||||||
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
|
import net.neoforged.neoforge.items.IItemHandler;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class BasicItemOutput implements ConveyorOutput {
|
||||||
|
BlockCapabilityCache<IItemHandler, @Nullable Direction> capabilityCache;
|
||||||
|
|
||||||
|
public BasicItemOutput(ServerLevel level, BlockPos pos, Direction facingDirection) {
|
||||||
|
capabilityCache = BlockCapabilityCache.create(
|
||||||
|
Capabilities.ItemHandler.BLOCK,
|
||||||
|
level,
|
||||||
|
pos.relative(facingDirection),
|
||||||
|
facingDirection.getOpposite()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insertItem(ItemStack stack, boolean simulate) {
|
||||||
|
ItemStack toInsert = stack.copy();
|
||||||
|
|
||||||
|
IItemHandler container = capabilityCache.getCapability();
|
||||||
|
if (container == null) return toInsert;
|
||||||
|
|
||||||
|
for (int insertIndex = 0; insertIndex < container.getSlots(); insertIndex++) {
|
||||||
|
if (toInsert.isEmpty()) break;
|
||||||
|
|
||||||
|
toInsert = container.insertItem(insertIndex, toInsert, simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toInsert;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package net.xevianlight.aphelion.systems.conveyor;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.xevianlight.aphelion.block.entity.custom.PipeTestBlockEntity;
|
||||||
|
|
||||||
|
public class ConveyorAttachment {
|
||||||
|
ConveyorAttachment(ServerLevel level, BlockPos pos, Direction facingDirection) {}
|
||||||
|
|
||||||
|
//TODO: put in the right interface for a render function
|
||||||
|
void render() {};
|
||||||
|
|
||||||
|
public void tick(ServerLevel level, BlockState state, BlockPos pos, Direction facingDirection, ConveyorNetwork network) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.xevianlight.aphelion.systems.conveyor;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
public interface ConveyorInput {
|
||||||
|
void tick(ServerLevel level, BlockState state, BlockPos pos, Direction facingDirection, ConveyorNetwork graph);
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package net.xevianlight.aphelion.systems.conveyor;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.xevianlight.aphelion.block.entity.custom.PipeTestBlockEntity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
// I'm naming and structuring the conveyor stuff like this bc i kinda wanna try making a space-engineers
|
||||||
|
// style request system later... though it might not be necessary, given that the reason it needs to be like that
|
||||||
|
// in space engineers is mostly space constraints if i had to guess
|
||||||
|
public class ConveyorNetwork {
|
||||||
|
boolean isInvalid = false;
|
||||||
|
public List<PipeTestBlockEntity> pipes = new ArrayList<>();
|
||||||
|
public Set<ConveyorOutput> outputs = new HashSet<>();
|
||||||
|
|
||||||
|
public ItemStack insertItem(ItemStack stack, boolean simulate) {
|
||||||
|
if (isInvalid) return stack;
|
||||||
|
for (ConveyorOutput output : outputs) {
|
||||||
|
stack = output.insertItem(stack, simulate);
|
||||||
|
if (stack.isEmpty()) break;
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPipe(PipeTestBlockEntity pipe) {
|
||||||
|
pipes.add(pipe);
|
||||||
|
pipe.graph = this;
|
||||||
|
for (ConveyorOutput output : pipe.outputs.values()) {
|
||||||
|
if (output != null) this.outputs.add(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called whenever a pipe is removed from a graph, or when a new graph comes across an old one.
|
||||||
|
public void invalidate() {
|
||||||
|
for (PipeTestBlockEntity pipe : pipes) {
|
||||||
|
pipe.graph = null;
|
||||||
|
for (ConveyorOutput output : pipe.outputs.values()) {
|
||||||
|
if (output != null) this.outputs.remove(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.isInvalid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.xevianlight.aphelion.systems.conveyor;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
public interface ConveyorOutput {
|
||||||
|
/// @return Rejected items
|
||||||
|
ItemStack insertItem(ItemStack stack, boolean simulate);
|
||||||
|
}
|
||||||
@@ -1,500 +0,0 @@
|
|||||||
package net.xevianlight.aphelion.util;
|
|
||||||
|
|
||||||
import com.mojang.datafixers.util.*;
|
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Since mojang only wanted to implement codecs up to 6 types, here's all the codecs 7-16. You're welcome.
|
|
||||||
* @param <B>
|
|
||||||
* @param <V>
|
|
||||||
*/
|
|
||||||
public interface BigCodec<B, V> extends StreamCodec<B, V> {
|
|
||||||
|
|
||||||
// ---------- 7 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final Function7<T1, T2, T3, T4, T5, T6, T7, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<B, C>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 8 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final Function8<T1, T2, T3, T4, T5, T6, T7, T8, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<B, C>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 9 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
Function9<T1, T2, T3, T4, T5, T6, T7, T8, T9, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 10 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
final StreamCodec<? super B, T10> c10, final Function<C, T10> g10,
|
|
||||||
Function10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
T10 t10 = (T10)c10.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
c10.encode(b, g10.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 11 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
final StreamCodec<? super B, T10> c10, final Function<C, T10> g10,
|
|
||||||
final StreamCodec<? super B, T11> c11, final Function<C, T11> g11,
|
|
||||||
Function11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
T10 t10 = (T10)c10.decode(b);
|
|
||||||
T11 t11 = (T11)c11.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
c10.encode(b, g10.apply(v));
|
|
||||||
c11.encode(b, g11.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 12 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
final StreamCodec<? super B, T10> c10, final Function<C, T10> g10,
|
|
||||||
final StreamCodec<? super B, T11> c11, final Function<C, T11> g11,
|
|
||||||
final StreamCodec<? super B, T12> c12, final Function<C, T12> g12,
|
|
||||||
Function12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
T10 t10 = (T10)c10.decode(b);
|
|
||||||
T11 t11 = (T11)c11.decode(b);
|
|
||||||
T12 t12 = (T12)c12.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
c10.encode(b, g10.apply(v));
|
|
||||||
c11.encode(b, g11.apply(v));
|
|
||||||
c12.encode(b, g12.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 13 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
final StreamCodec<? super B, T10> c10, final Function<C, T10> g10,
|
|
||||||
final StreamCodec<? super B, T11> c11, final Function<C, T11> g11,
|
|
||||||
final StreamCodec<? super B, T12> c12, final Function<C, T12> g12,
|
|
||||||
final StreamCodec<? super B, T13> c13, final Function<C, T13> g13,
|
|
||||||
Function13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
T10 t10 = (T10)c10.decode(b);
|
|
||||||
T11 t11 = (T11)c11.decode(b);
|
|
||||||
T12 t12 = (T12)c12.decode(b);
|
|
||||||
T13 t13 = (T13)c13.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
c10.encode(b, g10.apply(v));
|
|
||||||
c11.encode(b, g11.apply(v));
|
|
||||||
c12.encode(b, g12.apply(v));
|
|
||||||
c13.encode(b, g13.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 14 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
final StreamCodec<? super B, T10> c10, final Function<C, T10> g10,
|
|
||||||
final StreamCodec<? super B, T11> c11, final Function<C, T11> g11,
|
|
||||||
final StreamCodec<? super B, T12> c12, final Function<C, T12> g12,
|
|
||||||
final StreamCodec<? super B, T13> c13, final Function<C, T13> g13,
|
|
||||||
final StreamCodec<? super B, T14> c14, final Function<C, T14> g14,
|
|
||||||
Function14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
T10 t10 = (T10)c10.decode(b);
|
|
||||||
T11 t11 = (T11)c11.decode(b);
|
|
||||||
T12 t12 = (T12)c12.decode(b);
|
|
||||||
T13 t13 = (T13)c13.decode(b);
|
|
||||||
T14 t14 = (T14)c14.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
c10.encode(b, g10.apply(v));
|
|
||||||
c11.encode(b, g11.apply(v));
|
|
||||||
c12.encode(b, g12.apply(v));
|
|
||||||
c13.encode(b, g13.apply(v));
|
|
||||||
c14.encode(b, g14.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 15 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
final StreamCodec<? super B, T10> c10, final Function<C, T10> g10,
|
|
||||||
final StreamCodec<? super B, T11> c11, final Function<C, T11> g11,
|
|
||||||
final StreamCodec<? super B, T12> c12, final Function<C, T12> g12,
|
|
||||||
final StreamCodec<? super B, T13> c13, final Function<C, T13> g13,
|
|
||||||
final StreamCodec<? super B, T14> c14, final Function<C, T14> g14,
|
|
||||||
final StreamCodec<? super B, T15> c15, final Function<C, T15> g15,
|
|
||||||
Function15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
T10 t10 = (T10)c10.decode(b);
|
|
||||||
T11 t11 = (T11)c11.decode(b);
|
|
||||||
T12 t12 = (T12)c12.decode(b);
|
|
||||||
T13 t13 = (T13)c13.decode(b);
|
|
||||||
T14 t14 = (T14)c14.decode(b);
|
|
||||||
T15 t15 = (T15)c15.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
c10.encode(b, g10.apply(v));
|
|
||||||
c11.encode(b, g11.apply(v));
|
|
||||||
c12.encode(b, g12.apply(v));
|
|
||||||
c13.encode(b, g13.apply(v));
|
|
||||||
c14.encode(b, g14.apply(v));
|
|
||||||
c15.encode(b, g15.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 16 ----------
|
|
||||||
static <B, C, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> StreamCodec<B, C> composite(
|
|
||||||
final StreamCodec<? super B, T1> c1, final Function<C, T1> g1,
|
|
||||||
final StreamCodec<? super B, T2> c2, final Function<C, T2> g2,
|
|
||||||
final StreamCodec<? super B, T3> c3, final Function<C, T3> g3,
|
|
||||||
final StreamCodec<? super B, T4> c4, final Function<C, T4> g4,
|
|
||||||
final StreamCodec<? super B, T5> c5, final Function<C, T5> g5,
|
|
||||||
final StreamCodec<? super B, T6> c6, final Function<C, T6> g6,
|
|
||||||
final StreamCodec<? super B, T7> c7, final Function<C, T7> g7,
|
|
||||||
final StreamCodec<? super B, T8> c8, final Function<C, T8> g8,
|
|
||||||
final StreamCodec<? super B, T9> c9, final Function<C, T9> g9,
|
|
||||||
final StreamCodec<? super B, T10> c10, final Function<C, T10> g10,
|
|
||||||
final StreamCodec<? super B, T11> c11, final Function<C, T11> g11,
|
|
||||||
final StreamCodec<? super B, T12> c12, final Function<C, T12> g12,
|
|
||||||
final StreamCodec<? super B, T13> c13, final Function<C, T13> g13,
|
|
||||||
final StreamCodec<? super B, T14> c14, final Function<C, T14> g14,
|
|
||||||
final StreamCodec<? super B, T15> c15, final Function<C, T15> g15,
|
|
||||||
final StreamCodec<? super B, T16> c16, final Function<C, T16> g16,
|
|
||||||
Function16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, C> factory
|
|
||||||
) {
|
|
||||||
return new StreamCodec<>() {
|
|
||||||
public @NotNull C decode(@NotNull B b) {
|
|
||||||
T1 t1 = (T1)c1.decode(b);
|
|
||||||
T2 t2 = (T2)c2.decode(b);
|
|
||||||
T3 t3 = (T3)c3.decode(b);
|
|
||||||
T4 t4 = (T4)c4.decode(b);
|
|
||||||
T5 t5 = (T5)c5.decode(b);
|
|
||||||
T6 t6 = (T6)c6.decode(b);
|
|
||||||
T7 t7 = (T7)c7.decode(b);
|
|
||||||
T8 t8 = (T8)c8.decode(b);
|
|
||||||
T9 t9 = (T9)c9.decode(b);
|
|
||||||
T10 t10 = (T10)c10.decode(b);
|
|
||||||
T11 t11 = (T11)c11.decode(b);
|
|
||||||
T12 t12 = (T12)c12.decode(b);
|
|
||||||
T13 t13 = (T13)c13.decode(b);
|
|
||||||
T14 t14 = (T14)c14.decode(b);
|
|
||||||
T15 t15 = (T15)c15.decode(b);
|
|
||||||
T16 t16 = (T16)c16.decode(b);
|
|
||||||
return (C)factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encode(@NotNull B b, @NotNull C v) {
|
|
||||||
c1.encode(b, g1.apply(v));
|
|
||||||
c2.encode(b, g2.apply(v));
|
|
||||||
c3.encode(b, g3.apply(v));
|
|
||||||
c4.encode(b, g4.apply(v));
|
|
||||||
c5.encode(b, g5.apply(v));
|
|
||||||
c6.encode(b, g6.apply(v));
|
|
||||||
c7.encode(b, g7.apply(v));
|
|
||||||
c8.encode(b, g8.apply(v));
|
|
||||||
c9.encode(b, g9.apply(v));
|
|
||||||
c10.encode(b, g10.apply(v));
|
|
||||||
c11.encode(b, g11.apply(v));
|
|
||||||
c12.encode(b, g12.apply(v));
|
|
||||||
c13.encode(b, g13.apply(v));
|
|
||||||
c14.encode(b, g14.apply(v));
|
|
||||||
c15.encode(b, g15.apply(v));
|
|
||||||
c16.encode(b, g16.apply(v));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ public final class FloodFill3D {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static Set<BlockPos> run(Level level, BlockPos start, int limit, SolidBlockPredicate predicate, boolean retainOrder) {
|
public static Set<BlockPos> run(Level level, BlockPos start, int limit, SolidBlockPredicate predicate, boolean retainOrder) {
|
||||||
level.getProfiler().push("aphelion-floodfill");
|
level.getProfiler().push("adastra-floodfill");
|
||||||
|
|
||||||
LongSet positions = retainOrder ? new LongLinkedOpenHashSet(limit) : new LongOpenHashSet(limit);
|
LongSet positions = retainOrder ? new LongLinkedOpenHashSet(limit) : new LongOpenHashSet(limit);
|
||||||
LongArrayFIFOQueue queue = new LongArrayFIFOQueue(limit);
|
LongArrayFIFOQueue queue = new LongArrayFIFOQueue(limit);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ public class ModTags {
|
|||||||
public static final TagKey<Block> LAUNCH_PAD = createTag("launch_pad");
|
public static final TagKey<Block> LAUNCH_PAD = createTag("launch_pad");
|
||||||
public static final TagKey<Block> PASSES_FLOOD_FILL = createTag("passes_flood_fill");
|
public static final TagKey<Block> PASSES_FLOOD_FILL = createTag("passes_flood_fill");
|
||||||
public static final TagKey<Block> BLOCKS_FLOOD_FILL = createTag("blocks_flood_fill");
|
public static final TagKey<Block> BLOCKS_FLOOD_FILL = createTag("blocks_flood_fill");
|
||||||
public static final TagKey<Block> ROCKET_SEAT = createTag("rocket_seat");
|
|
||||||
|
|
||||||
private static TagKey<Block> commonTag(String name) {
|
private static TagKey<Block> commonTag(String name) {
|
||||||
return BlockTags.create(ResourceLocation.fromNamespaceAndPath("c", name));
|
return BlockTags.create(ResourceLocation.fromNamespaceAndPath("c", name));
|
||||||
|
|||||||
@@ -5,17 +5,9 @@ import it.unimi.dsi.fastutil.ints.IntList;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.*;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
|
||||||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.xevianlight.aphelion.block.custom.base.IRocketEnergyUpgrade;
|
|
||||||
import net.xevianlight.aphelion.block.custom.base.IRocketFluidUpgrade;
|
|
||||||
import net.xevianlight.aphelion.block.custom.base.IRocketFuelUpgrade;
|
|
||||||
import net.xevianlight.aphelion.block.custom.base.IRocketInventoryUpgrade;
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -27,8 +19,6 @@ public final class RocketStructure {
|
|||||||
private final IntList packedPositions = new IntArrayList();
|
private final IntList packedPositions = new IntArrayList();
|
||||||
private final IntList paletteIndices = new IntArrayList();
|
private final IntList paletteIndices = new IntArrayList();
|
||||||
|
|
||||||
private final IntList seatOffsets = new IntArrayList();
|
|
||||||
|
|
||||||
public RocketStructure(Builder builder) {
|
public RocketStructure(Builder builder) {
|
||||||
builder.build(this);
|
builder.build(this);
|
||||||
}
|
}
|
||||||
@@ -44,7 +34,6 @@ public final class RocketStructure {
|
|||||||
palette.clear();
|
palette.clear();
|
||||||
packedPositions.clear();
|
packedPositions.clear();
|
||||||
paletteIndices.clear();
|
paletteIndices.clear();
|
||||||
seatOffsets.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(int x, int y, int z, BlockState state) {
|
public void add(int x, int y, int z, BlockState state) {
|
||||||
@@ -80,8 +69,6 @@ public final class RocketStructure {
|
|||||||
tag.put("pos", posArr);
|
tag.put("pos", posArr);
|
||||||
tag.put("idx", idxArr);
|
tag.put("idx", idxArr);
|
||||||
|
|
||||||
tag.put("seats", new IntArrayTag(seatOffsets.toIntArray()));
|
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,11 +92,6 @@ public final class RocketStructure {
|
|||||||
packedPositions.add(pos[i]);
|
packedPositions.add(pos[i]);
|
||||||
paletteIndices.add(idx[i]);
|
paletteIndices.add(idx[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.contains("seats", Tag.TAG_INT_ARRAY)) {
|
|
||||||
int[] seats = tag.getIntArray("seats");
|
|
||||||
for (int s : seats) seatOffsets.add(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int packPos (int x, int y, int z) {
|
public static int packPos (int x, int y, int z) {
|
||||||
@@ -156,118 +138,36 @@ public final class RocketStructure {
|
|||||||
return new Extents(minX, minY, minZ, maxX, maxY, maxZ);
|
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) {
|
public static void clearCaptured(Level level, BlockPos origin, RocketStructure struct) {
|
||||||
final int flags = Block.UPDATE_CLIENTS;
|
|
||||||
|
|
||||||
// Pass 1: remove blocks which implement DOUBLE_BLOCK_HALF like doors to try and prevent duplication.
|
|
||||||
for (int i = 0; i < struct.size(); i++) {
|
for (int i = 0; i < struct.size(); i++) {
|
||||||
int packed = struct.packedPosAt(i);
|
int packed = struct.packedPosAt(i);
|
||||||
BlockPos wp = origin.offset(
|
int dx = RocketStructure.unpackX(packed);
|
||||||
RocketStructure.unpackX(packed),
|
int dy = RocketStructure.unpackY(packed);
|
||||||
RocketStructure.unpackY(packed),
|
int dz = RocketStructure.unpackZ(packed);
|
||||||
RocketStructure.unpackZ(packed)
|
|
||||||
);
|
|
||||||
|
|
||||||
BlockState st = level.getBlockState(wp);
|
BlockPos wp = origin.offset(dx, dy, dz);
|
||||||
if (st.isAir()) continue;
|
level.setBlock(wp, Blocks.AIR.defaultBlockState(), 3);
|
||||||
|
|
||||||
if (st.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)) {
|
|
||||||
DoubleBlockHalf half = st.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF);
|
|
||||||
BlockPos bottom = (half == DoubleBlockHalf.LOWER) ? wp : null;
|
|
||||||
|
|
||||||
// Break the BOTTOM block to stop potential dupes, as it seems that is the "master" block for doors.
|
|
||||||
// If you set the top block to air, the bottom one breaks a moment later and drops.
|
|
||||||
// If this doesn't work I declare it NOT MY FAULT!
|
|
||||||
// DoubleBlockHalf blocks should have a way to delete the entire thing at once god damnit
|
|
||||||
if (bottom != null && !level.getBlockState(bottom).isAir()) {
|
|
||||||
level.setBlock(bottom, Blocks.AIR.defaultBlockState(), flags);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Pass 2: remove likely-attached blocks first. This should stop duplication of torches/buttons/whatever else may break due to its supporting block being broken
|
|
||||||
for (int i = 0; i < struct.size(); i++) {
|
|
||||||
int packed = struct.packedPosAt(i);
|
|
||||||
BlockPos wp = origin.offset(unpackX(packed), unpackY(packed), unpackZ(packed));
|
|
||||||
BlockState st = level.getBlockState(wp);
|
|
||||||
if (st.isAir()) continue;
|
|
||||||
|
|
||||||
// Heuristic: if it isn't a full collision cube, it's often "attached" (buttons, torches, etc.)
|
|
||||||
if (!st.isCollisionShapeFullBlock(level, wp)) {
|
|
||||||
level.setBlock(wp, Blocks.AIR.defaultBlockState(), flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass 3: remove the rest
|
|
||||||
for (int i = 0; i < struct.size(); i++) {
|
|
||||||
int packed = struct.packedPosAt(i);
|
|
||||||
BlockPos wp = origin.offset(unpackX(packed), unpackY(packed), unpackZ(packed));
|
|
||||||
if (!level.getBlockState(wp).isAir()) {
|
|
||||||
level.setBlock(wp, Blocks.AIR.defaultBlockState(), flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int seatCount() { return seatOffsets.size(); }
|
|
||||||
public int packedSeatAt(int i) { return seatOffsets.getInt(i); }
|
|
||||||
|
|
||||||
public void addSeatOffset(int dx, int dy, int dz) {
|
|
||||||
seatOffsets.add(packPos(dx, dy, dz));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int calculateInventoryCapacity(RocketStructure structure) {
|
|
||||||
int totalSlots = 0;
|
|
||||||
for (int i = 0; i < structure.size(); i++) {
|
|
||||||
BlockState st = structure.stateAt(i);
|
|
||||||
Block block = st.getBlock();
|
|
||||||
|
|
||||||
if (block instanceof IRocketInventoryUpgrade upgrade) {
|
|
||||||
int slots = upgrade.getSlotCapacity();
|
|
||||||
if (slots > 0) totalSlots += slots;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalSlots;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int calculateFuelCapacity(RocketStructure structure) {
|
|
||||||
int totalMB = 0;
|
|
||||||
for (int i = 0; i < structure.size(); i++) {
|
|
||||||
BlockState st = structure.stateAt(i);
|
|
||||||
Block block = st.getBlock();
|
|
||||||
|
|
||||||
if (block instanceof IRocketFuelUpgrade upgrade) {
|
|
||||||
int mb = upgrade.getFuelCapacity();
|
|
||||||
if (mb > 0) totalMB += mb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalMB;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int calculateFluidCapacity(RocketStructure structure) {
|
|
||||||
int totalMB = 0;
|
|
||||||
for (int i = 0; i < structure.size(); i++) {
|
|
||||||
BlockState st = structure.stateAt(i);
|
|
||||||
Block block = st.getBlock();
|
|
||||||
|
|
||||||
if (block instanceof IRocketFluidUpgrade upgrade) {
|
|
||||||
int mb = upgrade.getFluidCapacity();
|
|
||||||
if (mb > 0) totalMB += mb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalMB;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int calculateEnergyCapacity(RocketStructure structure) {
|
|
||||||
int totalFE = 0;
|
|
||||||
for (int i = 0; i < structure.size(); i++) {
|
|
||||||
BlockState st = structure.stateAt(i);
|
|
||||||
Block block = st.getBlock();
|
|
||||||
|
|
||||||
if (block instanceof IRocketEnergyUpgrade upgrade) {
|
|
||||||
int fe = upgrade.getEnergyCapacity();
|
|
||||||
if (fe > 0) totalFE += fe;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalFE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.xevianlight.aphelion.util;
|
package net.xevianlight.aphelion.util;
|
||||||
|
|
||||||
public class SpacePartition {
|
public class SpacePartitionHelper {
|
||||||
|
|
||||||
public static final int SIZE = 16;
|
public static final int SIZE = 16;
|
||||||
|
|
||||||
@@ -3,14 +3,12 @@ package net.xevianlight.aphelion.util.registries;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.planet.Orbit;
|
|
||||||
import net.xevianlight.aphelion.planet.Planet;
|
import net.xevianlight.aphelion.planet.Planet;
|
||||||
import net.xevianlight.aphelion.planet.StarSystem;
|
import net.xevianlight.aphelion.planet.StarSystem;
|
||||||
|
|
||||||
public class ModRegistries {
|
public class ModRegistries {
|
||||||
public static final ResourceKey<Registry<StarSystem>> STAR_SYSTEM = createRegistryKey("star_system");
|
public static final ResourceKey<Registry<StarSystem>> STAR_SYSTEM = createRegistryKey("star_system");
|
||||||
public static final ResourceKey<Registry<Planet>> PLANET = createRegistryKey("planet");
|
public static final ResourceKey<Registry<Planet>> PLANET = createRegistryKey("planet");
|
||||||
public static final ResourceKey<Registry<Orbit>> ORBIT = createRegistryKey("orbit");
|
|
||||||
|
|
||||||
private static <T> ResourceKey<Registry<T>> createRegistryKey(String name) {
|
private static <T> ResourceKey<Registry<T>> createRegistryKey(String name) {
|
||||||
return ResourceKey.createRegistryKey(Aphelion.id(name));
|
return ResourceKey.createRegistryKey(Aphelion.id(name));
|
||||||
|
|||||||
11
src/main/resources/assets/aphelion/blockstates/pipe.json
Normal file
11
src/main/resources/assets/aphelion/blockstates/pipe.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"multipart": [
|
||||||
|
{ "apply": { "model": "aphelion:block/pipe_core" }},
|
||||||
|
{ "when": { "north": "true" }, "apply": { "model": "aphelion:block/pipe_side" }},
|
||||||
|
{ "when": { "east": "true" }, "apply": { "model": "aphelion:block/pipe_side", "y": 90 }},
|
||||||
|
{ "when": { "south": "true" }, "apply": { "model": "aphelion:block/pipe_side", "y": 180 }},
|
||||||
|
{ "when": { "west": "true" }, "apply": { "model": "aphelion:block/pipe_side", "y": 270 }},
|
||||||
|
{ "when": { "up": "true" }, "apply": { "model": "aphelion:block/pipe_side", "x": 270 }},
|
||||||
|
{ "when": { "down": "true" }, "apply": { "model": "aphelion:block/pipe_side", "x": 90 }}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"variants": {
|
|
||||||
"facing=east,formed=false": {
|
|
||||||
"model": "aphelion:block/rocket_assembler",
|
|
||||||
"y": 90
|
|
||||||
},
|
|
||||||
"facing=north,formed=false": {
|
|
||||||
"model": "aphelion:block/rocket_assembler"
|
|
||||||
},
|
|
||||||
"facing=south,formed=false": {
|
|
||||||
"model": "aphelion:block/rocket_assembler",
|
|
||||||
"y": 180
|
|
||||||
},
|
|
||||||
"facing=west,formed=false": {
|
|
||||||
"model": "aphelion:block/rocket_assembler",
|
|
||||||
"y": 270
|
|
||||||
},
|
|
||||||
"facing=east,formed=true": {
|
|
||||||
"model": "aphelion:block/rocket_assembler_formed",
|
|
||||||
"y": 90
|
|
||||||
},
|
|
||||||
"facing=north,formed=true": {
|
|
||||||
"model": "aphelion:block/rocket_assembler_formed"
|
|
||||||
},
|
|
||||||
"facing=south,formed=true": {
|
|
||||||
"model": "aphelion:block/rocket_assembler_formed",
|
|
||||||
"y": 180
|
|
||||||
},
|
|
||||||
"facing=west,formed=true": {
|
|
||||||
"model": "aphelion:block/rocket_assembler_formed",
|
|
||||||
"y": 270
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"facing=east,formed=false": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block",
|
||||||
|
"y": 90
|
||||||
|
},
|
||||||
|
"facing=north,formed=false": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block"
|
||||||
|
},
|
||||||
|
"facing=south,formed=false": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block",
|
||||||
|
"y": 180
|
||||||
|
},
|
||||||
|
"facing=west,formed=false": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block",
|
||||||
|
"y": 270
|
||||||
|
},
|
||||||
|
"facing=east,formed=true": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block_formed",
|
||||||
|
"y": 90
|
||||||
|
},
|
||||||
|
"facing=north,formed=true": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block_formed"
|
||||||
|
},
|
||||||
|
"facing=south,formed=true": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block_formed",
|
||||||
|
"y": 180
|
||||||
|
},
|
||||||
|
"facing=west,formed=true": {
|
||||||
|
"model": "aphelion:block/rocket_assembler_block_formed",
|
||||||
|
"y": 270
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
@@ -52,12 +52,5 @@
|
|||||||
"command.aphelion.rocket.get_dim.success": "Target dimension of rocket is %s",
|
"command.aphelion.rocket.get_dim.success": "Target dimension of rocket is %s",
|
||||||
"command.aphelion.rocket.set_pos.success": "Set target position of rocket to %s",
|
"command.aphelion.rocket.set_pos.success": "Set target position of rocket to %s",
|
||||||
"command.aphelion.rocket.get_pos.success": "Target position of rocket is %s",
|
"command.aphelion.rocket.get_pos.success": "Target position of rocket is %s",
|
||||||
"command.aphelion.rocket.get_pos.success.null": "Target position of rocket is not set",
|
"command.aphelion.rocket.get_pos.success.null": "Target position of rocket is not set"
|
||||||
"command.aphelion.rocket.disassemble.success": "Rocket disassembled",
|
|
||||||
"command.aphelion.rocket.disassemble.failure": "Could not disassemble rocket",
|
|
||||||
"command.aphelion.station.invalid": "Station is invalid!",
|
|
||||||
"command.aphelion.station.owner.unset": "Station has no owner",
|
|
||||||
"command.aphelion.station.owner.get": "Station (%s %s) belongs to %s",
|
|
||||||
"command.aphelion.station.owner.set.success": "Set station (%s %s)'s owner to %s",
|
|
||||||
"command.aphelion.player.invalid": "Player is invalid"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/0010",
|
"top": "aphelion:block/launch_pad/0010",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/1000"
|
"bottom": "aphelion:block/launch_pad/0010"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/0011",
|
"top": "aphelion:block/launch_pad/0011",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/1001"
|
"bottom": "aphelion:block/launch_pad/0011"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/0110",
|
"top": "aphelion:block/launch_pad/0110",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/1100"
|
"bottom": "aphelion:block/launch_pad/0110"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/0111",
|
"top": "aphelion:block/launch_pad/0111",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/1101"
|
"bottom": "aphelion:block/launch_pad/0111"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/1000",
|
"top": "aphelion:block/launch_pad/1000",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/0010"
|
"bottom": "aphelion:block/launch_pad/1000"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/1001",
|
"top": "aphelion:block/launch_pad/1001",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/0011"
|
"bottom": "aphelion:block/launch_pad/1001"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/1100",
|
"top": "aphelion:block/launch_pad/1100",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/0110"
|
"bottom": "aphelion:block/launch_pad/1100"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"textures": {
|
"textures": {
|
||||||
"top": "aphelion:block/launch_pad/1101",
|
"top": "aphelion:block/launch_pad/1101",
|
||||||
"side": "aphelion:block/launch_pad/topbottom",
|
"side": "aphelion:block/launch_pad/topbottom",
|
||||||
"bottom": "aphelion:block/launch_pad/0111"
|
"bottom": "aphelion:block/launch_pad/1101"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"ambientocclusion": false,
|
||||||
|
"textures": {
|
||||||
|
"texture": "aphelion:block/pipe_texture"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [ 6, 6, 6 ],
|
||||||
|
"to": [ 10, 10, 10 ],
|
||||||
|
"faces": {
|
||||||
|
"down": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] },
|
||||||
|
"up": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] },
|
||||||
|
"north": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] },
|
||||||
|
"south": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] },
|
||||||
|
"west": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] },
|
||||||
|
"east": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"textures": {
|
||||||
|
"texture": "aphelion:block/pipe_texture"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [ 6, 6, 0 ],
|
||||||
|
"to": [ 10, 10, 6 ],
|
||||||
|
"faces": {
|
||||||
|
"down": { "texture": "#texture", "uv": [ 6, 0, 10, 6 ] },
|
||||||
|
"up": { "texture": "#texture", "uv": [ 6, 0, 10, 6 ] },
|
||||||
|
"north": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] },
|
||||||
|
"west": { "texture": "#texture", "uv": [ 0, 6, 6, 10 ] },
|
||||||
|
"east": { "texture": "#texture", "uv": [ 0, 6, 6, 10 ] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 374 B |
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"dimension": "aphelion:mars",
|
|
||||||
"orbit": "aphelion:orbit/mars",
|
|
||||||
"orbit_distance": 1.5,
|
|
||||||
"star_system": "aphelion:sol",
|
|
||||||
"gravity": 1,
|
|
||||||
"oxygen": false
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user