mirror of
https://github.com/XevianLight/Aphelion.git
synced 2026-05-11 01:50:56 +01:00
More stuff for stations. Cleanup.
This commit is contained in:
@@ -2,8 +2,12 @@ package net.xevianlight.aphelion.block.custom;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
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.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
@@ -11,7 +15,12 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.xevianlight.aphelion.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.SpacePartition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class LaunchPad extends Block {
|
||||
@@ -73,5 +82,4 @@ public class LaunchPad extends Block {
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.xevianlight.aphelion.block.custom;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -15,6 +16,9 @@ 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.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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -37,14 +37,16 @@ public abstract class BasicEntityBlock extends BaseEntityBlock {
|
||||
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) -> {
|
||||
if (blockEntity instanceof TickableBlockEntity tickable) {
|
||||
long time = level.getGameTime() - pos.hashCode();
|
||||
if (!tickable.isInitialized()) tickable.firstTick(entityLevel, blockState, pos);
|
||||
|
||||
long time = entityLevel.getGameTime() - pos.hashCode();
|
||||
tickable.tick(entityLevel, time, blockState, pos);
|
||||
if (level.isClientSide()) {
|
||||
tickable.clientTick((ClientLevel) level, time, state, pos);
|
||||
|
||||
if (entityLevel.isClientSide()) {
|
||||
tickable.clientTick((ClientLevel) entityLevel, time, blockState, pos);
|
||||
} else {
|
||||
tickable.serverTick((ServerLevel) level, time, state, pos);
|
||||
tickable.serverTick((ServerLevel) entityLevel, time, blockState, pos);
|
||||
}
|
||||
if (!tickable.isInitialized()) tickable.firstTick(level, state, pos);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package net.xevianlight.aphelion.block.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.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;
|
||||
private @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) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles station travel logic for this engine.
|
||||
*
|
||||
* <p>If the associated station is currently traveling, this method advances
|
||||
* its movement using the value returned by {@link #getTravelSpeed()}.</p>
|
||||
*
|
||||
* <p>Subclasses may override this method to add additional server-side behavior.
|
||||
* When doing so, {@code super.serverTick(...)} should be called to preserve
|
||||
* the default travel logic.</p>
|
||||
*
|
||||
* <p>This method is invoked once per server tick.</p>
|
||||
*
|
||||
* @param level the server level the block entity exists in
|
||||
* @param time the current tick time offset used for scheduling
|
||||
* @param state the current block state
|
||||
* @param pos the world position of the block entity
|
||||
*/
|
||||
@Override
|
||||
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
|
||||
double speed = getTravelSpeed();
|
||||
if (data != null) {
|
||||
if (data.isTraveling()) {
|
||||
data.travel(speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.xevianlight.aphelion.block.custom.base;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
||||
import net.xevianlight.aphelion.util.Constants;
|
||||
|
||||
public class StationRocketEngineBlockEntity extends StationEngineBlockEntity {
|
||||
|
||||
/// Seconds to travel 1 AU
|
||||
private final double SECONDS_PER_AU = 60;
|
||||
/// AU per tick
|
||||
private final double SPEED = 1/(SECONDS_PER_AU*20);
|
||||
|
||||
@Override
|
||||
public double getTravelSpeed() {
|
||||
return SPEED;
|
||||
}
|
||||
|
||||
protected StationRocketEngineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
|
||||
// TODO change type to ModBlockEntities.STATION_ROCKET_ENGINE_BLOCK_ENTITY.get()
|
||||
super(type, pos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
|
||||
super.serverTick(level, time, state, pos); // IMPORTANT!!!
|
||||
}
|
||||
}
|
||||
@@ -9,41 +9,74 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
public interface TickableBlockEntity {
|
||||
|
||||
/**
|
||||
* Runs on both the client AND server.
|
||||
* @param level
|
||||
* @param time
|
||||
* @param state
|
||||
* @param pos
|
||||
* Runs on both the client and server once per tick.
|
||||
*
|
||||
* <p>This is intended for logic that is common to both sides. Side-specific logic
|
||||
* should go in {@link #clientTick(ClientLevel, long, BlockState, BlockPos)} or
|
||||
* {@link #serverTick(ServerLevel, long, BlockState, BlockPos)}.</p>
|
||||
*
|
||||
* @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) {};
|
||||
|
||||
/**
|
||||
* Runs on the client only
|
||||
* @param level
|
||||
* @param time
|
||||
* @param state
|
||||
* @param pos
|
||||
* Runs on the client only once per tick.
|
||||
*
|
||||
* <p>Use this for client-side visual updates, particles, sounds, animation state,
|
||||
* or other logic that must not run on the logical server.</p>
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Runs on the server only
|
||||
* @param level
|
||||
* @param time
|
||||
* @param state
|
||||
* @param pos
|
||||
* Runs on the server only once per tick.
|
||||
*
|
||||
* <p>Use this for authoritative game logic such as inventory processing, energy
|
||||
* generation/consumption, entity spawning, saving state, and network sync triggers.</p>
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
* @return {@code true} if initialization has completed, {@code false} otherwise
|
||||
*/
|
||||
default boolean isInitialized() {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs on client AND server, once only.
|
||||
* @param level
|
||||
* @param state
|
||||
* @param pos
|
||||
* Performs initialization logic for this object.
|
||||
*
|
||||
* <p>This method is called at the start of each tick on both the client and server
|
||||
* whenever {@link #isInitialized()} returns {@code false}. It will continue to be
|
||||
* 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>
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ import net.xevianlight.aphelion.Aphelion;
|
||||
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.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.ModTags;
|
||||
@@ -38,6 +41,8 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
||||
private PadInfo padBounds;
|
||||
RocketEntity lastRocket;
|
||||
|
||||
private @Nullable PartitionData data;
|
||||
|
||||
public @Nullable PadInfo getPadBounds() {
|
||||
return padBounds;
|
||||
}
|
||||
@@ -60,9 +65,19 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
||||
|
||||
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 final Block TOWER_BLOCK = ModBlocks.BLOCK_STEEL.get();
|
||||
private static final Block TOWER_BLOCK = ModBlocks.BLOCK_STEEL.get();
|
||||
public BlockPos towerBasePos;
|
||||
|
||||
private boolean connected(BlockState state, Direction dir) {
|
||||
@@ -318,23 +333,44 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
||||
boolean formed = newBounds != null;
|
||||
if (state.getValue(AphelionBlockStateProperties.FORMED) != formed) {
|
||||
level.setBlockAndUpdate(pos, state.setValue(AphelionBlockStateProperties.FORMED, formed));
|
||||
if (data != null) {
|
||||
if (formed) {
|
||||
data.addLandingPadController(pos);
|
||||
} else {
|
||||
data.removeLandingPadController(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void firstTick(Level level, BlockState state, BlockPos pos) {
|
||||
if (level.isClientSide()) return;
|
||||
|
||||
facing = getBlockState().getValue(BlockStateProperties.HORIZONTAL_FACING);
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved() {
|
||||
if (data == null) return;
|
||||
data.removeLandingPadController(worldPosition);
|
||||
}
|
||||
|
||||
private static boolean isPad(BlockState s) {
|
||||
return s.is(ModTags.Blocks.LAUNCH_PAD); // or s.getBlock() == ModBlocks.PAD.get()
|
||||
}
|
||||
|
||||
private static boolean isTower(BlockState s) {
|
||||
return s.is(ModBlocks.BLOCK_STEEL);
|
||||
return s.is(TOWER_BLOCK);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
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.VertexConsumer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderStateShard;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.xevianlight.aphelion.block.entity.custom.RocketAssemblerBlockEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -37,6 +41,21 @@ public class RocketAssemblerBlockEntityRenderer implements BlockEntityRenderer<R
|
||||
).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
|
||||
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;
|
||||
@@ -53,10 +72,20 @@ public class RocketAssemblerBlockEntityRenderer implements BlockEntityRenderer<R
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(-be.getBlockPos().getX(), -be.getBlockPos().getY(), -be.getBlockPos().getZ());
|
||||
|
||||
VertexConsumer vc = multiBufferSource.getBuffer(RenderType.lines());
|
||||
VertexConsumer lineVc = multiBufferSource.getBuffer(RenderType.lines());
|
||||
LevelRenderer.renderLineBox(poseStack, lineVc, box, 0f, 1f, 0f, 1f);
|
||||
|
||||
LevelRenderer.renderLineBox(poseStack, vc, box, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
VertexConsumer faceVc = multiBufferSource.getBuffer(CENTER_FACE);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package net.xevianlight.aphelion.client;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
@@ -15,7 +14,7 @@ import net.xevianlight.aphelion.client.dimension.DimensionRendererCache;
|
||||
import net.xevianlight.aphelion.client.dimension.SpaceSkyEffects;
|
||||
import net.xevianlight.aphelion.core.saveddata.EnvironmentSavedData;
|
||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
||||
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||
import net.xevianlight.aphelion.util.SpacePartition;
|
||||
|
||||
@EventBusSubscriber(modid = Aphelion.MOD_ID, value = Dist.CLIENT)
|
||||
public class AphelionDebugOverlay {
|
||||
@@ -44,8 +43,8 @@ public class AphelionDebugOverlay {
|
||||
+ ", thickFog=" + r.hasThickFog()
|
||||
+ ", fog=" + r.hasFog());
|
||||
|
||||
int x = SpacePartitionHelper.get(Math.floor(mc.player.position().x));
|
||||
int z = SpacePartitionHelper.get(Math.floor(mc.player.position().z));
|
||||
int x = SpacePartition.get(Math.floor(mc.player.position().x));
|
||||
int z = SpacePartition.get(Math.floor(mc.player.position().z));
|
||||
|
||||
// Left side of F3
|
||||
event.getLeft().add("");
|
||||
|
||||
@@ -8,7 +8,7 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.client.PartitionClientState;
|
||||
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||
import net.xevianlight.aphelion.util.SpacePartition;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
@@ -61,8 +61,8 @@ public class DimensionSkyEffects extends DimensionSpecialEffects {
|
||||
|
||||
public static ResourceLocation orbitForPos(Vec3 pos) {
|
||||
|
||||
int x = SpacePartitionHelper.get(pos.x);
|
||||
int z = SpacePartitionHelper.get(pos.z);
|
||||
int x = SpacePartition.get(pos.x);
|
||||
int z = SpacePartition.get(pos.z);
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
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.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.client.PartitionClientState;
|
||||
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||
import net.xevianlight.aphelion.util.SpacePartition;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
@@ -67,8 +67,8 @@ public class SpaceSkyEffects extends DimensionSpecialEffects {
|
||||
|
||||
public static ResourceLocation orbitForPos(Vec3 pos) {
|
||||
|
||||
int x = SpacePartitionHelper.get(pos.x);
|
||||
int z = SpacePartitionHelper.get(pos.z);
|
||||
int x = SpacePartition.get(pos.x);
|
||||
int z = SpacePartition.get(pos.z);
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.level == null) return ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "orbit/default");
|
||||
|
||||
@@ -11,7 +11,6 @@ import net.minecraft.commands.arguments.*;
|
||||
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
|
||||
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.*;
|
||||
@@ -26,10 +25,8 @@ import net.xevianlight.aphelion.Aphelion;
|
||||
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.planet.Planet;
|
||||
import net.xevianlight.aphelion.util.RocketStructure;
|
||||
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||
import net.xevianlight.aphelion.util.registries.ModRegistries;
|
||||
import net.xevianlight.aphelion.util.SpacePartition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -47,8 +44,8 @@ public class AphelionCommand {
|
||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||
.then(Commands.argument("orbit", ResourceLocationArgument.id())
|
||||
.executes(context -> {
|
||||
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
ResourceLocation orbit = ResourceLocationArgument.getId(context, "orbit");
|
||||
|
||||
ServerLevel level = context.getSource().getLevel();
|
||||
@@ -85,8 +82,8 @@ public class AphelionCommand {
|
||||
.then(Commands.literal("get")
|
||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||
.executes(context -> {
|
||||
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
|
||||
ServerLevel level = context.getSource().getLevel();
|
||||
ResourceLocation orbit = SpacePartitionSavedData.get(level).getOrbitForPartition(x, z);
|
||||
@@ -110,8 +107,8 @@ public class AphelionCommand {
|
||||
.then(Commands.literal("clear")
|
||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||
.executes(context -> {
|
||||
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
|
||||
ServerLevel level = context.getSource().getLevel();
|
||||
|
||||
@@ -148,8 +145,8 @@ public class AphelionCommand {
|
||||
.executes(context -> {
|
||||
ServerLevel level = context.getSource().getLevel();
|
||||
|
||||
int x = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context,"pos").x());
|
||||
int z = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context,"pos").z());
|
||||
int x = SpacePartition.get(ColumnPosArgument.getColumnPos(context,"pos").x());
|
||||
int z = SpacePartition.get(ColumnPosArgument.getColumnPos(context,"pos").z());
|
||||
|
||||
long key = SpacePartitionSavedData.pack(x,z);
|
||||
|
||||
@@ -195,7 +192,7 @@ public class AphelionCommand {
|
||||
int x = ColumnPosArgument.getColumnPos(context, "pos").x();
|
||||
int z = ColumnPosArgument.getColumnPos(context, "pos").z();
|
||||
|
||||
String stationCoord = SpacePartitionHelper.get(x) + " " + SpacePartitionHelper.get(z);
|
||||
String stationCoord = SpacePartition.get(x) + " " + SpacePartition.get(z);
|
||||
|
||||
Component clickableOutput = getClickablePos(stationCoord, ChatFormatting.GREEN);
|
||||
|
||||
@@ -217,8 +214,8 @@ public class AphelionCommand {
|
||||
double x = (double) IntegerArgumentType.getInteger(context, "x");
|
||||
double z = (double) IntegerArgumentType.getInteger(context, "z");
|
||||
|
||||
int destX = (int) Math.floor(x * SpacePartitionHelper.SIZE) + (SpacePartitionHelper.SIZE / 2);
|
||||
int destZ = (int) Math.floor(z * SpacePartitionHelper.SIZE) + (SpacePartitionHelper.SIZE / 2);
|
||||
int destX = (int) Math.floor(x * SpacePartition.SIZE) + (SpacePartition.SIZE / 2);
|
||||
int destZ = (int) Math.floor(z * SpacePartition.SIZE) + (SpacePartition.SIZE / 2);
|
||||
|
||||
String stationCoord = x + ", " + z;
|
||||
|
||||
@@ -255,8 +252,8 @@ public class AphelionCommand {
|
||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||
.then(Commands.argument("id", ResourceLocationArgument.id())
|
||||
.executes(context -> {
|
||||
int px = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int pz = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
int px = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int pz = SpacePartition.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
ResourceLocation orbit = ResourceLocationArgument.getId(context, "id");
|
||||
|
||||
ServerLevel level = context.getSource().getLevel();
|
||||
@@ -277,8 +274,8 @@ public class AphelionCommand {
|
||||
.then(Commands.literal("get")
|
||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||
.executes(context -> {
|
||||
int px = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int pz = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
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);
|
||||
@@ -306,8 +303,8 @@ public class AphelionCommand {
|
||||
.then(Commands.argument("pos", ColumnPosArgument.columnPos())
|
||||
.then(Commands.argument("player", GameProfileArgument.gameProfile())
|
||||
.executes(context -> {
|
||||
int px = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").x());
|
||||
int pz = SpacePartitionHelper.get(ColumnPosArgument.getColumnPos(context, "pos").z());
|
||||
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);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
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"));
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package net.xevianlight.aphelion.core.saveddata;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
@@ -10,6 +11,7 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.saveddata.SavedData;
|
||||
import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
||||
import net.xevianlight.aphelion.util.SpacePartition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -54,10 +56,10 @@ public class SpacePartitionSavedData extends SavedData {
|
||||
|
||||
// Distances (optional; default 0.0)
|
||||
if (e.contains("DistanceTraveled", CompoundTag.TAG_DOUBLE)) {
|
||||
pd.setDistanceTraveled(e.getDouble("DistanceTraveled"));
|
||||
pd.setDistanceTraveledAU(e.getDouble("DistanceTraveled"));
|
||||
}
|
||||
if (e.contains("DistanceToDest", CompoundTag.TAG_DOUBLE)) {
|
||||
pd.setDistanceToDest(e.getDouble("DistanceToDest"));
|
||||
pd.setTripDistanceAU(e.getDouble("DistanceToDest"));
|
||||
}
|
||||
|
||||
if (e.hasUUID("Owner")) {
|
||||
@@ -102,8 +104,8 @@ public class SpacePartitionSavedData extends SavedData {
|
||||
// Traveling + distances
|
||||
e.putBoolean("Traveling", pd.isTraveling());
|
||||
|
||||
e.putDouble("DistanceTraveled", pd.getDistanceTraveled());
|
||||
e.putDouble("DistanceToDest", pd.getDistanceToDest());
|
||||
e.putDouble("DistanceTraveled", pd.getDistanceTraveledAU());
|
||||
e.putDouble("DistanceToDest", pd.getTripDistanceAU());
|
||||
|
||||
if (pd.getOwner() != null) {
|
||||
e.putUUID("Owner", pd.getOwner());
|
||||
@@ -158,15 +160,23 @@ public class SpacePartitionSavedData extends SavedData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mutable PartitionData object stored at px, pz
|
||||
* @param px
|
||||
* @param pz
|
||||
* @return
|
||||
* 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 @Nullable PartitionData getData(int px, int pz) {
|
||||
public @NotNull PartitionData getData(int px, int pz) {
|
||||
long key = pack(px, pz);
|
||||
PartitionData data = map.get(key);
|
||||
if (data == null) {
|
||||
|
||||
// pick a sensible default orbit, or null if you truly allow it
|
||||
data = new PartitionData(Aphelion.id("orbit/default"));
|
||||
map.put(key, data);
|
||||
@@ -175,6 +185,61 @@ public class SpacePartitionSavedData extends SavedData {
|
||||
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) {
|
||||
if (map.isEmpty()) return;
|
||||
|
||||
|
||||
@@ -3,17 +3,13 @@ package net.xevianlight.aphelion.core.saveddata.types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.xevianlight.aphelion.util.BigCodec;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
public class PartitionData {
|
||||
public static final int MAX_PADS = 64;
|
||||
@@ -22,32 +18,37 @@ public class PartitionData {
|
||||
@Nullable private ResourceLocation orbit;
|
||||
@Nullable private ResourceLocation destination;
|
||||
private boolean traveling;
|
||||
private double distanceTraveled;
|
||||
private double distanceToDest;
|
||||
/// How far we've already gone
|
||||
private double distanceTraveledAU;
|
||||
/// Total trip distance, from start to finish
|
||||
private double tripDistanceAU;
|
||||
private boolean generated;
|
||||
private UUID owner;
|
||||
private List<BlockPos> landingPadControllers;
|
||||
private List<BlockPos> engines;
|
||||
|
||||
public PartitionData(@Nullable ResourceLocation orbit) {
|
||||
this.orbit = orbit;
|
||||
this.destination = null;
|
||||
this.traveling = false;
|
||||
this.distanceTraveled = 0;
|
||||
this.distanceToDest = 0;
|
||||
this.distanceTraveledAU = 0;
|
||||
this.tripDistanceAU = 0;
|
||||
this.generated = false;
|
||||
this.owner = null;
|
||||
this.landingPadControllers = List.of();
|
||||
this.engines = List.of();
|
||||
}
|
||||
|
||||
public PartitionData(PartitionData other) {
|
||||
this.orbit = other.orbit;
|
||||
this.destination = other.destination;
|
||||
this.traveling = other.traveling;
|
||||
this.distanceTraveled = other.distanceTraveled;
|
||||
this.distanceToDest = other.distanceToDest;
|
||||
this.distanceTraveledAU = other.distanceTraveledAU;
|
||||
this.tripDistanceAU = other.tripDistanceAU;
|
||||
this.generated = other.generated;
|
||||
this.owner = other.owner;
|
||||
this.landingPadControllers = other.landingPadControllers;
|
||||
this.engines = other.engines;
|
||||
}
|
||||
|
||||
public static final StreamCodec<ByteBuf, PartitionData> STREAM_CODEC =
|
||||
@@ -64,10 +65,10 @@ public class PartitionData {
|
||||
|
||||
// doubles -> DOUBLE codec
|
||||
ByteBufCodecs.DOUBLE,
|
||||
PartitionData::getDistanceTraveled,
|
||||
PartitionData::getDistanceTraveledAU,
|
||||
|
||||
ByteBufCodecs.DOUBLE,
|
||||
PartitionData::getDistanceToDest,
|
||||
PartitionData::getTripDistanceAU,
|
||||
|
||||
ByteBufCodecs.optional(UUIDUtil.STREAM_CODEC),
|
||||
d -> Optional.ofNullable(d.getOwner()),
|
||||
@@ -78,15 +79,19 @@ public class PartitionData {
|
||||
BLOCKPOS_LIST_CODEC,
|
||||
PartitionData::getLandingPadControllers,
|
||||
|
||||
(orbitOpt, destOpt, traveling, distTraveled, distToDest, ownerOpt, generated, controllers) -> {
|
||||
BLOCKPOS_LIST_CODEC,
|
||||
PartitionData::getEngines,
|
||||
|
||||
(orbitOpt, destOpt, traveling, distTraveled, distToDest, ownerOpt, generated, controllers, engines) -> {
|
||||
PartitionData data = new PartitionData(orbitOpt.orElse(null));
|
||||
data.destination = destOpt.orElse(null);
|
||||
data.traveling = traveling;
|
||||
data.distanceTraveled = distTraveled;
|
||||
data.distanceToDest = distToDest;
|
||||
data.distanceTraveledAU = distTraveled;
|
||||
data.tripDistanceAU = distToDest;
|
||||
data.owner = ownerOpt.orElse(null);
|
||||
data.generated = generated;
|
||||
data.landingPadControllers = controllers;
|
||||
data.engines = engines;
|
||||
return data;
|
||||
}
|
||||
);
|
||||
@@ -115,24 +120,35 @@ public class PartitionData {
|
||||
this.traveling = traveling;
|
||||
}
|
||||
|
||||
public double getDistanceTraveled() {
|
||||
return distanceTraveled;
|
||||
public double getDistanceTraveledAU() {
|
||||
return distanceTraveledAU;
|
||||
}
|
||||
|
||||
public void setDistanceTraveled(double distanceTraveled) {
|
||||
this.distanceTraveled = distanceTraveled;
|
||||
public void setDistanceTraveledAU(double distanceTraveledAU) {
|
||||
this.distanceTraveledAU = distanceTraveledAU;
|
||||
}
|
||||
|
||||
public double getDistanceToDest() {
|
||||
return distanceToDest;
|
||||
public double getTripDistanceAU() {
|
||||
return tripDistanceAU;
|
||||
}
|
||||
|
||||
public void setDistanceToDest(double distanceToDest) {
|
||||
this.distanceToDest = 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)
|
||||
*/
|
||||
public void travel(double distance) {
|
||||
distanceTraveled = Math.min( distanceTraveled + distance, distanceToDest);
|
||||
distanceTraveledAU = Math.min(distanceTraveledAU + distance, tripDistanceAU);
|
||||
}
|
||||
|
||||
public boolean isGenerated() {
|
||||
@@ -151,14 +167,40 @@ public class PartitionData {
|
||||
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 landingPadControllers;
|
||||
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);
|
||||
@@ -167,10 +209,40 @@ public class PartitionData {
|
||||
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);
|
||||
}
|
||||
|
||||
public List<BlockPos> getEngines() {
|
||||
return engines;
|
||||
}
|
||||
|
||||
public void setEngines(List<BlockPos> engines) {
|
||||
this.engines = engines;
|
||||
}
|
||||
|
||||
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
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
@@ -181,8 +253,8 @@ public class PartitionData {
|
||||
return Objects.equals(this.orbit, that.orbit)
|
||||
&& Objects.equals(this.destination, that.destination)
|
||||
&& this.traveling == that.traveling
|
||||
&& Double.compare(this.distanceTraveled, that.distanceTraveled) == 0
|
||||
&& Double.compare(this.distanceToDest, that.distanceToDest) == 0
|
||||
&& Double.compare(this.distanceTraveledAU, that.distanceTraveledAU) == 0
|
||||
&& Double.compare(this.tripDistanceAU, that.tripDistanceAU) == 0
|
||||
&& this.generated == that.generated
|
||||
&& Objects.equals(this.owner, that.owner);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import net.xevianlight.aphelion.Aphelion;
|
||||
import net.xevianlight.aphelion.core.saveddata.SpacePartitionSavedData;
|
||||
import net.xevianlight.aphelion.core.saveddata.types.PartitionData;
|
||||
import net.xevianlight.aphelion.network.packet.PartitionPayload;
|
||||
import net.xevianlight.aphelion.util.SpacePartitionHelper;
|
||||
import net.xevianlight.aphelion.util.SpacePartition;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -42,8 +42,8 @@ public final class PartitionSync {
|
||||
}
|
||||
|
||||
private static PartitionPayload computePartitionFor(ServerPlayer sp) {
|
||||
int px = (int)Math.floor(sp.getX() / SpacePartitionHelper.SIZE);
|
||||
int pz = (int)Math.floor(sp.getZ() / SpacePartitionHelper.SIZE);
|
||||
int px = (int)Math.floor(sp.getX() / SpacePartition.SIZE);
|
||||
int pz = (int)Math.floor(sp.getZ() / SpacePartition.SIZE);
|
||||
|
||||
PartitionData live = SpacePartitionSavedData.get(sp.serverLevel()).getData(px, pz);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.xevianlight.aphelion.util;
|
||||
|
||||
public class SpacePartitionHelper {
|
||||
public class SpacePartition {
|
||||
|
||||
public static final int SIZE = 16;
|
||||
|
||||
Reference in New Issue
Block a user