Skip to content

Commit cc6f51e

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents bf747ac + 888dcd1 commit cc6f51e

File tree

15 files changed

+240
-12
lines changed

15 files changed

+240
-12
lines changed

common/src/main/java/net/cjsah/skyland/Skyland.java

+3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import dev.anvilcraft.lib.event.EventManager;
44
import net.minecraft.resources.ResourceLocation;
55
import org.jetbrains.annotations.NotNull;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
68

79
public class Skyland {
10+
public static final Logger LOGGER = LoggerFactory.getLogger(Skyland.class);
811
public static final String MOD_ID = "anvilcraft_skyland";
912
public static final ResourceLocation SKYLAND_ID = Skyland.of("skyland");
1013
public static final EventManager EVENT_BUS = new EventManager();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package net.cjsah.skyland.feature;
2+
3+
import com.mojang.serialization.Codec;
4+
import net.cjsah.skyland.Skyland;
5+
import net.cjsah.skyland.feature.configuration.LocatableStructureFeatureConfiguration;
6+
import net.minecraft.server.MinecraftServer;
7+
import net.minecraft.world.level.WorldGenLevel;
8+
import net.minecraft.world.level.block.Block;
9+
import net.minecraft.world.level.levelgen.feature.Feature;
10+
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
11+
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
12+
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
public class LocatableStructureFeature extends Feature<LocatableStructureFeatureConfiguration> {
16+
public LocatableStructureFeature(Codec<LocatableStructureFeatureConfiguration> codec) {
17+
super(codec);
18+
}
19+
20+
@SuppressWarnings("DataFlowIssue")
21+
@Override
22+
public boolean place(@NotNull FeaturePlaceContext<LocatableStructureFeatureConfiguration> context) {
23+
WorldGenLevel level = context.level();
24+
MinecraftServer server = level.getServer();
25+
if (server == null) {
26+
return false;
27+
}
28+
LocatableStructureFeatureConfiguration config = context.config();
29+
StructureTemplate structure =
30+
server.getStructureManager().get(config.structure()).orElse(null);
31+
if (structure == null) {
32+
Skyland.LOGGER.warn("Missing structure {}", config.structure());
33+
return false;
34+
}
35+
36+
return structure.placeInWorld(
37+
level,
38+
context.origin().offset(config.pos()),
39+
null,
40+
new StructurePlaceSettings(),
41+
context.random(),
42+
Block.UPDATE_CLIENTS);
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.cjsah.skyland.feature;
2+
3+
import com.mojang.serialization.Codec;
4+
import net.cjsah.skyland.feature.configuration.SpawnPlatformFeatureConfiguration;
5+
import net.cjsah.skyland.init.ModFeatures;
6+
import net.minecraft.core.BlockPos;
7+
import net.minecraft.world.level.levelgen.feature.Feature;
8+
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
9+
import org.jetbrains.annotations.NotNull;
10+
11+
public class SpawnPlatformFeature extends Feature<SpawnPlatformFeatureConfiguration> {
12+
public SpawnPlatformFeature(Codec<SpawnPlatformFeatureConfiguration> codec) {
13+
super(codec);
14+
}
15+
16+
@Override
17+
public boolean place(@NotNull FeaturePlaceContext<SpawnPlatformFeatureConfiguration> context) {
18+
SpawnPlatformFeatureConfiguration config = context.config();
19+
BlockPos origin = config.spawnRelative() ? context.origin().atY(0) : BlockPos.ZERO;
20+
return ModFeatures.LOCATABLE_STRUCTURE.place(config.platformConfig(), context.level(), context.chunkGenerator(), context.random(), origin);
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.cjsah.skyland.feature.configuration;
2+
3+
import com.mojang.serialization.Codec;
4+
import com.mojang.serialization.codecs.RecordCodecBuilder;
5+
import net.minecraft.core.BlockPos;
6+
import net.minecraft.resources.ResourceLocation;
7+
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
8+
9+
public record LocatableStructureFeatureConfiguration(ResourceLocation structure, BlockPos pos)
10+
implements FeatureConfiguration {
11+
public static final Codec<LocatableStructureFeatureConfiguration> CODEC =
12+
RecordCodecBuilder.create(instance -> instance.group(
13+
ResourceLocation.CODEC.fieldOf("structure").forGetter(config -> config.structure),
14+
BlockPos.CODEC.fieldOf("pos").forGetter(config -> config.pos))
15+
.apply(instance, LocatableStructureFeatureConfiguration::new));
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package net.cjsah.skyland.feature.configuration;
2+
3+
import com.mojang.serialization.Codec;
4+
import com.mojang.serialization.codecs.RecordCodecBuilder;
5+
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
6+
7+
public record SpawnPlatformFeatureConfiguration(LocatableStructureFeatureConfiguration platformConfig, boolean spawnRelative) implements FeatureConfiguration {
8+
public static final Codec<SpawnPlatformFeatureConfiguration> CODEC =
9+
RecordCodecBuilder.create(instance -> instance.group(
10+
LocatableStructureFeatureConfiguration.CODEC
11+
.fieldOf("platform")
12+
.forGetter(config -> config.platformConfig),
13+
Codec.BOOL.fieldOf("spawn_relative").forGetter(config -> config.spawnRelative))
14+
.apply(instance, SpawnPlatformFeatureConfiguration::new));
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.cjsah.skyland.init;
2+
3+
import net.cjsah.skyland.Skyland;
4+
import net.minecraft.core.registries.Registries;
5+
import net.minecraft.resources.ResourceKey;
6+
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
7+
import org.jetbrains.annotations.NotNull;
8+
9+
public class ModConfiguredFeatures {
10+
public static final ResourceKey<ConfiguredFeature<?, ?>> SPAWN_PLATFORM = feature("spawn_platform");
11+
12+
@SuppressWarnings("SameParameterValue")
13+
private static @NotNull ResourceKey<ConfiguredFeature<?, ?>> feature(String path) {
14+
return ResourceKey.create(Registries.CONFIGURED_FEATURE, Skyland.of(path));
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package net.cjsah.skyland.init;
2+
3+
import net.cjsah.skyland.feature.LocatableStructureFeature;
4+
import net.cjsah.skyland.feature.configuration.LocatableStructureFeatureConfiguration;
5+
import net.cjsah.skyland.feature.SpawnPlatformFeature;
6+
import net.cjsah.skyland.feature.configuration.SpawnPlatformFeatureConfiguration;
7+
import net.minecraft.world.level.levelgen.feature.Feature;
8+
9+
public class ModFeatures {
10+
public static final Feature<LocatableStructureFeatureConfiguration> LOCATABLE_STRUCTURE =
11+
new LocatableStructureFeature(LocatableStructureFeatureConfiguration.CODEC);
12+
13+
public static final Feature<SpawnPlatformFeatureConfiguration> SPAWN_PLATFORM =
14+
new SpawnPlatformFeature(SpawnPlatformFeatureConfiguration.CODEC);
15+
}

common/src/main/java/net/cjsah/skyland/integration/anvilcraft/event/SkylandChunkGenerateEventListener.java

+11-11
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ public class SkylandChunkGenerateEventListener {
1414
@SuppressWarnings("deprecation")
1515
@SubscribeEvent
1616
public void generate(@NotNull SkylandChunkGenerateEvent event) {
17-
WorldGenRegion level = event.getLevel();
18-
ServerLevel serverLevel = event.getLevel().getLevel();
19-
if (serverLevel.dimension() != ServerLevel.OVERWORLD) return;
20-
BlockPos spawnPos = new BlockPos(8, 64, 8);
21-
LevelData levelData = level.getLevelData();
22-
ChunkPos pos = event.getChunk().getPos();
23-
if (pos.x == levelData.getXSpawn() && pos.z == levelData.getYSpawn()) {
24-
serverLevel.setDefaultSpawnPos(spawnPos, 0.0f);
25-
}
26-
if (pos.x != 0 || pos.z != 0) return;
27-
LandFeature.place(level, spawnPos);
17+
// WorldGenRegion level = event.getLevel();
18+
// ServerLevel serverLevel = event.getLevel().getLevel();
19+
// if (serverLevel.dimension() != ServerLevel.OVERWORLD) return;
20+
// BlockPos spawnPos = new BlockPos(8, 64, 8);
21+
// LevelData levelData = level.getLevelData();
22+
// ChunkPos pos = event.getChunk().getPos();
23+
// if (pos.x == levelData.getXSpawn() && pos.z == levelData.getYSpawn()) {
24+
// serverLevel.setDefaultSpawnPos(spawnPos, 0.0f);
25+
// }
26+
// if (pos.x != 0 || pos.z != 0) return;
27+
// LandFeature.place(level, spawnPos);
2828
}
2929
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package net.cjsah.skyland.mixin;
2+
3+
import net.cjsah.skyland.Skyland;
4+
import net.cjsah.skyland.generator.SkylandChunkGenerator;
5+
import net.cjsah.skyland.init.ModConfiguredFeatures;
6+
import net.minecraft.core.BlockPos;
7+
import net.minecraft.core.Holder;
8+
import net.minecraft.core.registries.Registries;
9+
import net.minecraft.server.MinecraftServer;
10+
import net.minecraft.server.level.ServerChunkCache;
11+
import net.minecraft.server.level.ServerLevel;
12+
import net.minecraft.world.level.ChunkPos;
13+
import net.minecraft.world.level.chunk.ChunkGenerator;
14+
import net.minecraft.world.level.levelgen.LegacyRandomSource;
15+
import net.minecraft.world.level.levelgen.WorldgenRandom;
16+
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
17+
import net.minecraft.world.level.storage.ServerLevelData;
18+
import org.spongepowered.asm.mixin.Mixin;
19+
import org.spongepowered.asm.mixin.injection.At;
20+
import org.spongepowered.asm.mixin.injection.Inject;
21+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
22+
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
23+
24+
@Mixin(value = MinecraftServer.class)
25+
public class MinecraftServerMixin {
26+
@Inject(
27+
method = "setInitialSpawn",
28+
locals = LocalCapture.CAPTURE_FAILHARD,
29+
at =
30+
@At(
31+
value = "INVOKE",
32+
target = "Lnet/minecraft/world/level/storage/ServerLevelData;setSpawn(Lnet/minecraft/core/BlockPos;F)V",
33+
ordinal = 1,
34+
shift = At.Shift.AFTER
35+
),
36+
cancellable = true
37+
)
38+
private static void generateSpawnPlatform(
39+
ServerLevel level,
40+
ServerLevelData levelData,
41+
boolean bonusChest,
42+
boolean debugWorld,
43+
CallbackInfo ci,
44+
ServerChunkCache serverChunkManager,
45+
ChunkPos spawnChunk,
46+
int spawnHeight
47+
) {
48+
ServerChunkCache chunkManager = level.getChunkSource();
49+
ChunkGenerator chunkGenerator = chunkManager.getGenerator();
50+
if (!(chunkGenerator instanceof SkylandChunkGenerator)) return;
51+
BlockPos worldSpawn = spawnChunk.getMiddleBlockPosition(spawnHeight);
52+
53+
WorldgenRandom random = new WorldgenRandom(new LegacyRandomSource(0));
54+
random.setLargeFeatureSeed(level.getSeed(), spawnChunk.x, spawnChunk.z);
55+
56+
Holder.Reference<ConfiguredFeature<?, ?>> spawnPlatformFeature = level.registryAccess()
57+
.registryOrThrow(Registries.CONFIGURED_FEATURE)
58+
.getHolderOrThrow(ModConfiguredFeatures.SPAWN_PLATFORM);
59+
60+
if (!spawnPlatformFeature.value().place(level, chunkGenerator, random, worldSpawn)) {
61+
Skyland.LOGGER.error("Couldn't generate spawn platform");
62+
}
63+
64+
ci.cancel();
65+
}
66+
}

common/src/main/resources/anvilcraft_skyland-common.mixins.json

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"EndCityStructureMixin",
1010
"EndPodiumFeatureMixin",
1111
"FeatureMixin",
12+
"MinecraftServerMixin",
1213
"NoiseChunkAccessor",
1314
"RegisterChunkGeneratorMixin",
1415
"TestCommandMixin",
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"type": "anvilcraft_skyland:spawn_platform",
3+
"config": {
4+
"platform": {
5+
"structure": "anvilcraft_skyland:spawn_platform",
6+
"pos": [
7+
-4,
8+
63,
9+
-1
10+
]
11+
},
12+
"spawn_relative": true
13+
}
14+
}

fabric/src/main/java/net/cjsah/skyland/fabric/SkylandFabric.java

+5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package net.cjsah.skyland.fabric;
22

33
import net.cjsah.skyland.Skyland;
4+
import net.cjsah.skyland.init.ModFeatures;
45
import net.fabricmc.api.ModInitializer;
56
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
67
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
78
import net.fabricmc.loader.api.FabricLoader;
89
import net.fabricmc.loader.api.ModContainer;
10+
import net.minecraft.core.Registry;
11+
import net.minecraft.core.registries.BuiltInRegistries;
912
import net.minecraft.network.chat.Component;
1013
import net.minecraft.resources.ResourceLocation;
1114

@@ -14,6 +17,8 @@ public class SkylandFabric implements ModInitializer {
1417
public void onInitialize() {
1518
Skyland.init();
1619
SkylandFabric.loadResource();
20+
Registry.register(BuiltInRegistries.FEATURE, Skyland.of("locatable_structure"), ModFeatures.LOCATABLE_STRUCTURE);
21+
Registry.register(BuiltInRegistries.FEATURE, Skyland.of("spawn_platform"), ModFeatures.SPAWN_PLATFORM);
1722
}
1823

1924
public static void loadResource() {

forge/src/main/java/net/cjsah/skyland/forge/SkylandForge.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,25 @@
22

33
import dev.architectury.platform.forge.EventBuses;
44
import net.cjsah.skyland.Skyland;
5+
import net.cjsah.skyland.init.ModFeatures;
6+
import net.minecraft.core.registries.Registries;
7+
import net.minecraftforge.common.MinecraftForge;
58
import net.minecraftforge.fml.common.Mod;
69
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
10+
import net.minecraftforge.registries.RegisterEvent;
11+
import org.jetbrains.annotations.NotNull;
712

813
@Mod(Skyland.MOD_ID)
914
public class SkylandForge {
1015
public SkylandForge() {
11-
// Submit our event bus to let architectury register our content on the right time
16+
// Submit our event bus to let architectury register our content on the right time
1217
EventBuses.registerModEventBus(Skyland.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus());
1318
Skyland.init();
19+
MinecraftForge.EVENT_BUS.addListener(SkylandForge::register);
20+
}
21+
22+
public static void register(@NotNull RegisterEvent event) {
23+
event.register(Registries.FEATURE, Skyland.of("locatable_structure"), () -> ModFeatures.LOCATABLE_STRUCTURE);
24+
event.register(Registries.FEATURE, Skyland.of("spawn_platform"), () -> ModFeatures.SPAWN_PLATFORM);
1425
}
1526
}

0 commit comments

Comments
 (0)