Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,15 @@ public static void clearLastLaunchOrigin(ServerPlayer player) {
}

public static void recordLaunchOrigin(ServerPlayer player, BlockPos pos, ResourceKey<Level> dimension) {
ResourceKey<Level> groundDimension = normalizeGroundDimension(dimension);
if (groundDimension == null) {
if (!Level.OVERWORLD.equals(dimension)) {
return;
}

CompoundTag persistentData = player.getPersistentData();
CompoundTag rootTag = persistentData.getCompound(ROOT_TAG);
CompoundTag launchOriginTag = new CompoundTag();

launchOriginTag.putString("Dimension", groundDimension.location().toString());
launchOriginTag.putString("Dimension", dimension.location().toString());
launchOriginTag.putInt("X", pos.getX());
launchOriginTag.putInt("Y", pos.getY());
launchOriginTag.putInt("Z", pos.getZ());
Expand All @@ -63,6 +62,15 @@ public static boolean hasValidEarthLaunchOrigin(ServerPlayer player) {
return launchOrigin != null && Level.OVERWORLD.equals(launchOrigin.dimension());
}

@Nullable
public static BlockPos getLastEarthLaunchOrigin(ServerPlayer player) {
LaunchOrigin launchOrigin = getLastLaunchOrigin(player);
if (launchOrigin == null || !Level.OVERWORLD.equals(launchOrigin.dimension())) {
return null;
}
return launchOrigin.pos();
}

public static boolean buildEarthBaseFromLastLaunch(ServerPlayer player, ServerLevel orbitLevel) {
if (!Planet.EARTH_ORBIT.equals(orbitLevel.dimension())) {
return false;
Expand Down Expand Up @@ -92,13 +100,13 @@ private static LaunchOrigin getLastLaunchOrigin(ServerPlayer player) {
}

CompoundTag launchOriginTag = rootTag.getCompound(LAST_LAUNCH_TAG);
ResourceKey<Level> dimension = readGroundDimension(launchOriginTag.getString("Dimension"));
if (dimension == null) {
String dimensionId = launchOriginTag.getString("Dimension");
if (!Level.OVERWORLD.location().toString().equals(dimensionId)) {
return null;
}

return new LaunchOrigin(
dimension,
Level.OVERWORLD,
new BlockPos(
launchOriginTag.getInt("X"),
launchOriginTag.getInt("Y"),
Expand Down Expand Up @@ -163,22 +171,6 @@ private static void placePillar(ServerLevel level, BlockPos startPos, BlockState
}
}

@Nullable
private static ResourceKey<Level> normalizeGroundDimension(ResourceKey<Level> dimension) {
if (Level.OVERWORLD.equals(dimension)) {
return dimension;
}
return null;
}

@Nullable
private static ResourceKey<Level> readGroundDimension(String dimensionId) {
if (Level.OVERWORLD.location().toString().equals(dimensionId)) {
return Level.OVERWORLD;
}
return null;
}

private record LaunchOrigin(ResourceKey<Level> dimension, BlockPos pos) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package dev.celestiacraft.cmi.compat.adastra;

import earth.terrarium.adastra.api.planets.Planet;
import earth.terrarium.adastra.common.recipes.SpaceStationRecipe;
import earth.terrarium.adastra.common.registry.ModBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.RotatedPillarBlock;
import net.minecraft.world.level.block.SlabBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.SlabType;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;

public class AdAstraSpaceElevatorStationCompat {
private static final int SPACE_STATION_Y = 100;
private static final int BASE_RADIUS = 4;

private AdAstraSpaceElevatorStationCompat() {
}

public static void decorateEarthOrbitStation(ServerLevel level, ChunkPos stationChunk) {
if (!Planet.EARTH_ORBIT.equals(level.dimension())) {
return;
}

SpaceStationRecipe recipe = SpaceStationRecipe.getSpaceStation(level, level.dimension()).orElse(null);
if (recipe == null) {
return;
}

StructureTemplate structure = level.getStructureManager().getOrCreate(recipe.structure());
BlockPos stationOrigin = BlockPos.containing(
stationChunk.getMiddleBlockX() - (structure.getSize().getX() / 2.0f),
SPACE_STATION_Y,
stationChunk.getMiddleBlockZ() - (structure.getSize().getZ() / 2.0f)
);
BlockPos anchorCenter = stationOrigin.offset(structure.getSize().getX() / 2, -1, structure.getSize().getZ() / 2);
buildMirroredGroundBase(level, anchorCenter);
SpaceElevatorLinkHandler.setOrbitAnchor(level, stationChunk, anchorCenter);
}

private static void buildMirroredGroundBase(ServerLevel level, BlockPos centerPos) {
BlockState floorState = ModBlocks.STEEL_PLATING.get().defaultBlockState();
BlockState centerSlabState = ModBlocks.STEEL_PLATING_SLAB.get().defaultBlockState()
.setValue(SlabBlock.TYPE, SlabType.TOP);
BlockState supportState = ModBlocks.STEEL_BLOCK.get().defaultBlockState();
BlockState pillarState = ModBlocks.GLOWING_STEEL_PILLAR.get().defaultBlockState()
.setValue(RotatedPillarBlock.AXIS, Direction.Axis.Y);

for (int xOffset = -BASE_RADIUS; xOffset <= BASE_RADIUS; xOffset++) {
for (int zOffset = -BASE_RADIUS; zOffset <= BASE_RADIUS; zOffset++) {
BlockPos floorPos = centerPos.offset(xOffset, 0, zOffset);
boolean isCenterPad = Math.abs(xOffset) <= 1 && Math.abs(zOffset) <= 1;

level.setBlock(floorPos, isCenterPad ? centerSlabState : floorState, 3);

if (Math.abs(xOffset) == BASE_RADIUS || Math.abs(zOffset) == BASE_RADIUS) {
fillSupportColumnUp(level, floorPos.above(), supportState);
}
}
}

placePillarDown(level, centerPos.offset(BASE_RADIUS, -1, BASE_RADIUS), pillarState, 3);
placePillarDown(level, centerPos.offset(BASE_RADIUS, -1, -BASE_RADIUS), pillarState, 3);
placePillarDown(level, centerPos.offset(-BASE_RADIUS, -1, BASE_RADIUS), pillarState, 3);
placePillarDown(level, centerPos.offset(-BASE_RADIUS, -1, -BASE_RADIUS), pillarState, 3);

placePillarDown(level, centerPos.offset(0, -1, BASE_RADIUS), pillarState, 2);
placePillarDown(level, centerPos.offset(0, -1, -BASE_RADIUS), pillarState, 2);
placePillarDown(level, centerPos.offset(BASE_RADIUS, -1, 0), pillarState, 2);
placePillarDown(level, centerPos.offset(-BASE_RADIUS, -1, 0), pillarState, 2);
}

private static void fillSupportColumnUp(ServerLevel level, BlockPos startPos, BlockState supportState) {
for (int depth = 0; depth < 6; depth++) {
BlockPos pos = startPos.above(depth);
if (!level.getBlockState(pos).isAir()) {
return;
}
level.setBlock(pos, supportState, 3);
}
}

private static void placePillarDown(ServerLevel level, BlockPos startPos, BlockState pillarState, int height) {
for (int yOffset = 0; yOffset < height; yOffset++) {
level.setBlock(startPos.below(yOffset), pillarState, 3);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public static boolean hasBuiltBase(ServerLevel level, ChunkPos stationPos) {
return read(level).builtStations.contains(stationPos.toLong());
}

public static boolean hasBuiltStructure(ServerLevel level, ChunkPos stationPos) {
return hasBuiltBase(level, stationPos) || SpaceElevatorLinkHandler.getGroundBase(level, stationPos) != null || SpaceElevatorLinkHandler.getOrbitAnchor(level, stationPos) != null;
}

public static void markBaseBuilt(ServerLevel level, ChunkPos stationPos) {
read(level).builtStations.add(stationPos.toLong());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package dev.celestiacraft.cmi.compat.adastra;

import com.teamresourceful.resourcefullib.common.utils.SaveHandler;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;

public class SpaceElevatorLinkHandler extends SaveHandler {
private static final String LINKS_KEY = "Links";
private static final String STATION_POS_KEY = "StationPos";
private static final String ORBIT_ANCHOR_KEY = "OrbitAnchor";
private static final String GROUND_BASE_KEY = "GroundBase";
private static final String GROUND_DIMENSION_KEY = "GroundDimension";

private final Map<Long, SpaceElevatorLink> links = new HashMap<>();

@Override
public void loadData(CompoundTag tag) {
links.clear();
ListTag linkTags = tag.getList(LINKS_KEY, Tag.TAG_COMPOUND);
for (Tag value : linkTags) {
CompoundTag linkTag = (CompoundTag) value;
long stationPos = linkTag.getLong(STATION_POS_KEY);
SpaceElevatorLink link = new SpaceElevatorLink();
if (linkTag.contains(ORBIT_ANCHOR_KEY, Tag.TAG_COMPOUND)) {
link.orbitAnchor = NbtUtils.readBlockPos(linkTag.getCompound(ORBIT_ANCHOR_KEY));
}
if (linkTag.contains(GROUND_BASE_KEY, Tag.TAG_COMPOUND)) {
link.groundBase = NbtUtils.readBlockPos(linkTag.getCompound(GROUND_BASE_KEY));
}
if (linkTag.contains(GROUND_DIMENSION_KEY, Tag.TAG_STRING)) {
link.groundDimension = ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(linkTag.getString(GROUND_DIMENSION_KEY)));
}
links.put(stationPos, link);
}
}

@Override
public void saveData(CompoundTag tag) {
ListTag linkTags = new ListTag();
for (Map.Entry<Long, SpaceElevatorLink> entry : links.entrySet()) {
CompoundTag linkTag = new CompoundTag();
linkTag.putLong(STATION_POS_KEY, entry.getKey());
SpaceElevatorLink link = entry.getValue();
if (link.orbitAnchor != null) {
linkTag.put(ORBIT_ANCHOR_KEY, NbtUtils.writeBlockPos(link.orbitAnchor));
}
if (link.groundBase != null) {
linkTag.put(GROUND_BASE_KEY, NbtUtils.writeBlockPos(link.groundBase));
}
if (link.groundDimension != null) {
linkTag.putString(GROUND_DIMENSION_KEY, link.groundDimension.location().toString());
}
linkTags.add(linkTag);
}
tag.put(LINKS_KEY, linkTags);
}

public static SpaceElevatorLinkHandler read(ServerLevel level) {
return read(level.getDataStorage(), SpaceElevatorLinkHandler::new, "cmi_space_elevator_links");
}

public static void setOrbitAnchor(ServerLevel level, ChunkPos stationPos, BlockPos orbitAnchor) {
read(level).getOrCreate(stationPos).orbitAnchor = orbitAnchor.immutable();
}

public static void setGroundBase(ServerLevel level, ChunkPos stationPos, ResourceKey<Level> groundDimension, BlockPos groundBase) {
SpaceElevatorLink link = read(level).getOrCreate(stationPos);
link.groundDimension = groundDimension;
link.groundBase = groundBase.immutable();
}

@Nullable
public static BlockPos getOrbitAnchor(ServerLevel level, ChunkPos stationPos) {
SpaceElevatorLink link = read(level).links.get(stationPos.toLong());
return link == null ? null : link.orbitAnchor;
}

@Nullable
public static BlockPos getGroundBase(ServerLevel level, ChunkPos stationPos) {
SpaceElevatorLink link = read(level).links.get(stationPos.toLong());
return link == null ? null : link.groundBase;
}

@Nullable
public static ResourceKey<Level> getGroundDimension(ServerLevel level, ChunkPos stationPos) {
SpaceElevatorLink link = read(level).links.get(stationPos.toLong());
return link == null ? null : link.groundDimension;
}

private SpaceElevatorLink getOrCreate(ChunkPos stationPos) {
return links.computeIfAbsent(stationPos.toLong(), key -> new SpaceElevatorLink());
}

@Override
public boolean isDirty() {
return true;
}

private static class SpaceElevatorLink {
private BlockPos orbitAnchor;
private BlockPos groundBase;
private ResourceKey<Level> groundDimension;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public static void addLang() {

addCustomLang(
"text.cmi.space_elevator_base.already_built",
"This space station already has a ground base.",
"这个空间站已经建立过地面基站了"
"This space station already has a ground base and docking station.",
"这个空间站已经建立过地面基站和对接站了"
);
addCustomLang(
"text.cmi.space_elevator_base.need_earth_launch",
Expand All @@ -52,8 +52,8 @@ public static void addLang() {
);
addCustomLang(
"text.cmi.space_elevator_base.success",
"Ground base built on Earth.",
"已在地球建立地面基站"
"Ground base and docking station built successfully.",
"地面基站和对接站已建立成功"
);
}
}
Loading