feat: Ancient Cities

This commit is contained in:
LordMZTE 2023-09-23 16:05:22 +02:00
parent d683e61c98
commit 857517c0e1
Signed by: LordMZTE
GPG Key ID: B64802DC33A64FF6
21 changed files with 375 additions and 35 deletions

View File

@ -78,7 +78,6 @@ IndentWidth: 4
IndentWrappedFunctionNames: false
#InsertBraces: false
InsertTrailingCommas: Wrapped
JavaImportGroups: ["java"]
JavaScriptQuotes: Double
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
@ -94,7 +93,7 @@ ReflowComments: true
#RequiresClausePosition: OwnLine
#RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
SortIncludes: CaseInsensitive
SortIncludes: false
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: true

3
.gitignore vendored
View File

@ -16,4 +16,5 @@ classes/
.metadata
.vscode
.settings
*.launch
*.launch
.factorypath

View File

@ -1,9 +1,9 @@
package com.cursedcauldron.wildbackport;
import org.slf4j.Logger;
import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.access.Recovery;
import com.cursedcauldron.wildbackport.common.items.CompassItemPropertyFunction;
import com.cursedcauldron.wildbackport.common.registry.Instruments;
import com.cursedcauldron.wildbackport.common.registry.WBBiomes;
import com.cursedcauldron.wildbackport.common.registry.WBBlockEntities;
@ -20,6 +20,7 @@ import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.registry.entity.WBSensorTypes;
import com.cursedcauldron.wildbackport.common.registry.worldgen.RootPlacerType;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBFeatures;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBStructures;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBTreeDecorators;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBTrunkPlacers;
import com.cursedcauldron.wildbackport.common.tag.InstrumentTags;
@ -29,10 +30,6 @@ import com.cursedcauldron.wildbackport.common.tag.WBEntityTypeTags;
import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags;
import com.cursedcauldron.wildbackport.common.tag.WBItemTags;
import com.mojang.logging.LogUtils;
import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import org.slf4j.Logger;
//<>
@ -64,6 +61,8 @@ public class WildBackport {
WBGameRules.setup();
WBStructures.setup();
// Tags
WBBiomeTags.TAGS.bootstrap();
WBBlockTags.BUILDER.bootstrap();
@ -72,11 +71,14 @@ public class WildBackport {
WBItemTags.TAGS.bootstrap();
InstrumentTags.TAGS.bootstrap();
// ItemProperties.register(WBItems.RECOVERY_COMPASS.get(), new
// ResourceLocation("angle"), new CompassItemPropertyFunction((level,
// stack, entity) -> {
// return entity instanceof Player player ?
// Recovery.of(player).getLastDeathLocation().orElse(null) : null;
// }));
//ItemProperties.register(
// WBItems.RECOVERY_COMPASS.get(),
// new ResourceLocation("angle"),
// new CompassItemPropertyFunction((level, stack, entity) -> {
// return entity instanceof Player player
// ? Recovery.of(player).getLastDeathLocation().orElse(null)
// : null;
// })
//);
}
}
}

View File

@ -2,7 +2,8 @@ package com.cursedcauldron.wildbackport.common.registry.worldgen;
import java.util.function.Supplier;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.common.worldgen.AdvancedJigsawConfiguration;
import com.cursedcauldron.wildbackport.common.worldgen.features.AncientCityFeature;
import com.cursedcauldron.wildbackport.common.worldgen.features.GrassDiskConfiguration;
import com.cursedcauldron.wildbackport.common.worldgen.features.GrassDiskFeature;
import com.cursedcauldron.wildbackport.common.worldgen.features.RootedTreeConfig;
@ -11,7 +12,10 @@ import com.cursedcauldron.wildbackport.common.worldgen.features.SculkGrowthFeatu
import com.cursedcauldron.wildbackport.common.worldgen.features.SculkPatchConfiguration;
import com.cursedcauldron.wildbackport.common.worldgen.features.SculkPatchFeature;
import com.cursedcauldron.wildbackport.core.api.CoreRegistry;
import com.cursedcauldron.wildbackport.core.mixin.access.StructureFeatureAccessor;
import net.minecraft.core.Registry;
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.GlowLichenConfiguration;
@ -36,4 +40,11 @@ public class WBFeatures {
= FEATURES.register(
"sculk_growth", () -> new SculkGrowthFeature(GlowLichenConfiguration.CODEC)
);
}
public static final AncientCityFeature ANCIENT_CITY
= StructureFeatureAccessor.callRegister(
"ancient_city",
new AncientCityFeature(AdvancedJigsawConfiguration.CODEC),
Decoration.UNDERGROUND_STRUCTURES
);
}

View File

@ -1,18 +1,66 @@
package com.cursedcauldron.wildbackport.common.registry.worldgen;
import com.cursedcauldron.wildbackport.WildBackport;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;
import com.cursedcauldron.wildbackport.common.tag.WBBiomeTags;
import com.cursedcauldron.wildbackport.common.worldgen.AdvancedJigsawConfiguration;
import com.cursedcauldron.wildbackport.common.worldgen.structure.AncientCityStructurePieces;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.random.WeightedRandomList;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureSet;
import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride;
import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadStructurePlacement;
import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadType;
public class WBStructures {
// public static final Holder<ConfiguredStructureFeature<?, ?>> ANCIENT_CITY =
// create("ancient_city", )
public static final Holder<ConfiguredStructureFeature<?, ?>> ANCIENT_CITY = create(
"ancient_city",
WBFeatures.ANCIENT_CITY.configured(
new AdvancedJigsawConfiguration(
AncientCityStructurePieces.START,
7,
116,
Optional.of(new ResourceLocation("city_anchor"))
),
WBBiomeTags.HAS_ANCIENT_CITY,
true,
Arrays.stream(MobCategory.values())
.collect(Collectors.toMap(
mobCategory
-> mobCategory,
mobCategory
-> new StructureSpawnOverride(
StructureSpawnOverride.BoundingBoxType.STRUCTURE,
WeightedRandomList.create()
)
))
)
);
public static final Holder<StructureSet> ANCIENT_CITIES = BuiltinRegistries.register(
BuiltinRegistries.STRUCTURE_SETS,
ResourceKey.create(
Registry.STRUCTURE_SET_REGISTRY, new ResourceLocation("ancient_cities")
),
new StructureSet(
ANCIENT_CITY,
new RandomSpreadStructurePlacement(24, 8, RandomSpreadType.LINEAR, 20083232)
)
);
public static void setup() {
AncientCityStructurePieces.bootstrap();
}
private static <FC extends FeatureConfiguration, F extends StructureFeature<FC>>
Holder<ConfiguredStructureFeature<?, ?>>
@ -25,4 +73,4 @@ public class WBStructures {
feature
);
}
}
}

View File

@ -1,7 +1,7 @@
package com.cursedcauldron.wildbackport.common.tag;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.api.TagBuilder;
import net.minecraft.core.Registry;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.block.Block;
@ -32,4 +32,4 @@ public class WBBlockTags {
// Compatibility
public static final TagKey<Block> MUD = BUILDER.create("mud");
}
}

View File

@ -0,0 +1,53 @@
package com.cursedcauldron.wildbackport.common.worldgen;
import java.util.Optional;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.feature.configurations.JigsawConfiguration;
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
public class AdvancedJigsawConfiguration extends JigsawConfiguration {
public static final Codec<JigsawConfiguration> CODEC = RecordCodecBuilder.create(
(instance) -> {
return instance
.group(
StructureTemplatePool.CODEC.fieldOf("start_pool")
.forGetter(
(self) -> ((AdvancedJigsawConfiguration) self).startPool()
),
Codec.intRange(0, 7).fieldOf("size").forGetter(
(self) -> ((AdvancedJigsawConfiguration) self).maxDepth()
),
Codec.INT.fieldOf("max_distance_from_center")
.forGetter(
(self)
-> ((AdvancedJigsawConfiguration) self)
.maxDistanceFromCenter
),
ResourceLocation.CODEC.optionalFieldOf("start_jigsaw_name")
.forGetter(
(self) -> ((AdvancedJigsawConfiguration) self).startJigsawName
)
)
.apply(instance, AdvancedJigsawConfiguration::new);
}
);
public int maxDistanceFromCenter;
public Optional<ResourceLocation> startJigsawName;
public AdvancedJigsawConfiguration(
Holder<StructureTemplatePool> holder,
int i,
int maxDistanceFromCenter,
Optional<ResourceLocation> startJigsawName
) {
super(holder, i);
this.maxDistanceFromCenter = maxDistanceFromCenter;
this.startJigsawName = startJigsawName;
}
}

View File

@ -0,0 +1,21 @@
package com.cursedcauldron.wildbackport.common.worldgen.features;
import com.mojang.serialization.Codec;
import net.minecraft.world.level.levelgen.feature.JigsawFeature;
import net.minecraft.world.level.levelgen.feature.configurations.JigsawConfiguration;
public class AncientCityFeature extends JigsawFeature {
public AncientCityFeature(Codec<JigsawConfiguration> codec) {
super(
codec,
// Y level
-27,
// disable placement hack (?)
false,
// don't generate on surface
false,
// placable predicate
(alec) -> true
);
}
}

View File

@ -1,10 +1,10 @@
package com.cursedcauldron.wildbackport.common.worldgen.structure;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.common.worldgen.structure.pools.AncientCityStructurePools;
import com.cursedcauldron.wildbackport.common.worldgen.structure.processors.WBProcessorLists;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.Holder;
import net.minecraft.data.worldgen.Pools;
import net.minecraft.resources.ResourceLocation;
@ -45,4 +45,4 @@ public class AncientCityStructurePieces {
public static void bootstrap() {
AncientCityStructurePools.bootstrap();
}
}
}

View File

@ -2,9 +2,9 @@ package com.cursedcauldron.wildbackport.common.worldgen.structure;
import java.util.List;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.mixin.access.StructureTemplatePoolAccessor;
import com.mojang.datafixers.util.Pair;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.data.worldgen.PillagerOutpostPools;
import net.minecraft.data.worldgen.ProcessorLists;
@ -44,4 +44,4 @@ public class StructureGeneration {
templates.add(piece);
rawTemplates.add(Pair.of(piece, weight));
}
}
}

View File

@ -1,10 +1,10 @@
package com.cursedcauldron.wildbackport.common.worldgen.structure.pools;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBWorldGeneration;
import com.cursedcauldron.wildbackport.common.worldgen.structure.processors.WBProcessorLists;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import net.minecraft.data.worldgen.Pools;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
@ -484,4 +484,4 @@ public class AncientCityStructurePools {
StructureTemplatePool.Projection.RIGID
));
}
}
}

View File

@ -34,7 +34,7 @@ public class BlockTagRotProcessor extends StructureProcessor {
});
private static final StructureProcessorType<BlockTagRotProcessor> BLOCK_TAG_ROT
= Registry.register(
Registry.STRUCTURE_PROCESSOR, new ResourceLocation("block_rot"), () -> CODEC
Registry.STRUCTURE_PROCESSOR, new ResourceLocation("block_rot_alec"), () -> CODEC
);
private final Optional<HolderSet<Block>> rottableBlocks;
private final float integrity;
@ -70,4 +70,4 @@ public class BlockTagRotProcessor extends StructureProcessor {
protected StructureProcessorType<?> getType() {
return BLOCK_TAG_ROT;
}
}
}

View File

@ -1,8 +1,8 @@
package com.cursedcauldron.wildbackport.common.worldgen.structure.processors;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.common.tag.WBBlockTags;
import com.google.common.collect.ImmutableList;
import net.minecraft.core.Holder;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceLocation;
@ -107,4 +107,4 @@ public class WBProcessorLists {
new StructureProcessorList(processors)
);
}
}
}

View File

@ -0,0 +1,15 @@
package com.cursedcauldron.wildbackport.core.mixin.access;
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(StructureFeature.class)
public interface StructureFeatureAccessor {
@Invoker
public static <F extends StructureFeature<?>>
F callRegister(String string, F arg, Decoration arg2) {
throw new AssertionError();
}
}

View File

@ -0,0 +1,126 @@
package com.cursedcauldron.wildbackport.core.mixin.common;
import java.util.HashMap;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArgs;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
import com.cursedcauldron.wildbackport.common.worldgen.features.AncientCityFeature;
import com.cursedcauldron.wildbackport.core.mixinhelper.BeardifierLocals;
import net.minecraft.util.Mth;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.levelgen.Beardifier;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.StructurePiece;
import net.minecraft.world.level.levelgen.structure.StructureStart;
/**
* This mixin is responsible for reimplementing 1.19's BEARD_BOX which causes terrain
* to be removed around ancient city structures.
*/
@Mixin(Beardifier.class)
public class BeardifierMixin {
private static ThreadLocal<BeardifierLocals> currentLocals = new ThreadLocal<>();
@Unique
private Map<Object, StructureFeature<?>> featureMap = new HashMap<>();
@ModifyArgs(
method = "method_38319",
at = @At(
value = "INVOKE",
target = "Lit/unimi/dsi/fastutil/objects/ObjectList;add(Ljava/lang/Object;)Z"
)
)
private void
addStructurePieceToMap(
Args args, ChunkPos alec1, int alec2, int alec3, StructureStart ss
) {
featureMap.put(args.get(0), ss.getFeature().feature);
}
@Inject(
method = "compute",
at = @At(
value = "INVOKE",
target
= "Lnet/minecraft/world/level/levelgen/structure/StructurePiece;getNoiseEffect()Lnet/minecraft/world/level/levelgen/feature/NoiseEffect;"
),
locals = LocalCapture.CAPTURE_FAILHARD
)
private void
collectVariables(
DensityFunction.FunctionContext alec1,
CallbackInfoReturnable<Double> ci,
int i,
int j,
int k,
double alec2,
StructurePiece structurePiece,
BoundingBox boundingBox,
int l,
int m
) {
currentLocals.set(new BeardifierLocals(i, j, k, structurePiece, boundingBox, l, m)
);
}
@Shadow
private static double getBeardContribution(int l, int m, int n) {
throw new AssertionError();
}
@Redirect(
method = "compute",
at = @At(
value = "INVOKE",
target
= "Lnet/minecraft/world/level/levelgen/Beardifier;getBeardContribution(III)D"
)
)
private double
beardContribution(int l, int m, int n) {
BeardifierLocals locals = currentLocals.get();
if (locals == null)
return getBeardContribution(l, m, n);
currentLocals.remove();
StructureFeature<?> sf = this.featureMap.get(locals.structurePiece());
if (sf == null /* WTF */ || !(sf instanceof AncientCityFeature))
return getBeardContribution(l, m, n);
int q = Math.max(0, Math.max(-m, locals.y() - locals.boundingBox().maxY()));
return getAncientCityBeardContribution(l, q, n, m);
}
private static double getAncientCityBeardContribution(int i, int j, int k, int l) {
int m = i + 12;
int n = j + 12;
int o = k + 12;
if (!(m >= 0 && m < 24 && n >= 0 && n < 24 && o >= 0 && o < 24)) {
return 0.0;
}
double d = (double) l + 0.5;
double e = Mth.lengthSquared(i, d, k);
double f = -d * Mth.fastInvSqrt(e / 2.0) / 2.0;
return f * (double) computeBeardContribution(o - 12, m - 12, n - 12);
}
private static double computeBeardContribution(int i, double d, int j) {
double e = Mth.lengthSquared(i, d, j);
double f = Math.pow(Math.E, -e / 16.0);
return f;
}
}

View File

@ -0,0 +1,31 @@
package com.cursedcauldron.wildbackport.core.mixin.common;
import com.cursedcauldron.wildbackport.common.worldgen.AdvancedJigsawConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.JigsawConfiguration;
import net.minecraft.world.level.levelgen.structure.PoolElementStructurePiece;
import net.minecraft.world.level.levelgen.structure.pools.JigsawPlacement;
import net.minecraft.world.phys.AABB;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(JigsawPlacement.class)
public class JigsawPlacementMixin {
// this is a lambda
@ModifyVariable(method = "method_39824", at = @At(value = "STORE", ordinal = 0))
private static AABB adjustAncientCityBoundingBox(
AABB aabb, PoolElementStructurePiece alec, JigsawConfiguration conf
) {
if (conf instanceof AdvancedJigsawConfiguration aconf) {
return new AABB(
aabb.minX + 80 - aconf.maxDistanceFromCenter,
aabb.minY + 80 - aconf.maxDistanceFromCenter,
aabb.minZ + 80 - aconf.maxDistanceFromCenter,
aabb.maxX - 80 + aconf.maxDistanceFromCenter,
aabb.maxY - 80 + aconf.maxDistanceFromCenter,
aabb.maxZ - 80 + aconf.maxDistanceFromCenter
);
}
return aabb;
}
}

View File

@ -0,0 +1,14 @@
package com.cursedcauldron.wildbackport.core.mixinhelper;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.StructurePiece;
public record BeardifierLocals(
int x,
int y,
int z,
StructurePiece structurePiece,
BoundingBox boundingBox,
int l,
int m
) {}

View File

@ -0,0 +1,16 @@
{
"values": [
"minecraft:deepslate",
"minecraft:deepslate_bricks",
"minecraft:deepslate_tiles",
"minecraft:deepslate_brick_slab",
"minecraft:deepslate_tile_slab",
"minecraft:deepslate_brick_stairs",
"minecraft:deepslate_tile_wall",
"minecraft:deepslate_brick_wall",
"minecraft:cobbled_deepslate",
"minecraft:cracked_deepslate_bricks",
"minecraft:cracked_deepslate_tiles",
"minecraft:gray_wool"
]
}

View File

@ -24,6 +24,7 @@
"access.SheetsAccessor",
"access.SimpleParticleTypeAccessor",
"access.StairBlockAccessor",
"access.StructureFeatureAccessor",
"access.StructureTemplatePoolAccessor",
"access.TrapDoorBlockAccessor",
"access.TreeDecoratorTypeAccessor",
@ -32,7 +33,9 @@
"access.WalkNodeEvaluatorAccessor",
"access.WoodButtonBlockAccessor",
"access.WoodTypeAccessor",
"common.BeardifierMixin",
"common.ItemsMixin",
"common.JigsawPlacementMixin",
"common.BlockEntityTypeMixin",
"common.FlyNodeEvaluatorMixin",
"common.LivingEntityMixin",

View File

@ -12,4 +12,4 @@ fabric_api_version=0.57.0+1.18.2
forge_version=1.18.2-40.1.54
terrablender_version=1.1.0.95
terrablender_version=1.1.0.95

0
gradlew vendored Normal file → Executable file
View File