Skip to content

Commit 4d38577

Browse files
Add WorldUtils#addSpreadStructureLoot
Remove WorldUtils#addLocalCommonLootToStructurePiece
1 parent 904957c commit 4d38577

17 files changed

+516
-44
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package com.mmodding.mmodding_lib.ducks;
22

33
import net.minecraft.util.Identifier;
4+
import net.minecraft.util.math.BlockPos;
5+
6+
import java.util.function.BiConsumer;
7+
import java.util.function.Consumer;
48

59
public interface StructureDuckInterface {
610

711
void mmodding_lib$setIdentifier(Identifier identifier);
12+
13+
void mmodding_lib$provideCollectors(Consumer<BlockPos> structureContainersCollector, BiConsumer<Identifier, BlockPos> structurePieceContainersCollector);
814
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.mmodding.mmodding_lib.ducks;
2+
3+
import net.minecraft.util.Identifier;
4+
import net.minecraft.util.math.BlockPos;
5+
6+
import java.util.function.BiConsumer;
7+
import java.util.function.Consumer;
8+
9+
public interface StructurePieceDuckInterface {
10+
11+
default void mmodding_lib$provideCollectors(Consumer<BlockPos> structureContainersCollector, BiConsumer<Identifier, BlockPos> structurePieceContainersCollector) {}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.mmodding.mmodding_lib.ducks;
2+
3+
import net.minecraft.util.Identifier;
4+
import net.minecraft.util.math.BlockPos;
5+
6+
import java.util.function.BiConsumer;
7+
import java.util.function.Consumer;
8+
9+
public interface StructurePoolElementDuckInterface {
10+
11+
default void mmodding_lib$provideCollectors(Consumer<BlockPos> structureContainersCollector, BiConsumer<Identifier, BlockPos> structurePieceContainersCollector) {}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.mmodding.mmodding_lib.ducks;
2+
3+
import net.minecraft.util.Identifier;
4+
import net.minecraft.util.math.BlockPos;
5+
6+
import java.util.function.BiConsumer;
7+
import java.util.function.Consumer;
8+
9+
public interface StructureStartDuckInterface {
10+
11+
void mmodding_lib$provideCollectors(Consumer<BlockPos> structureContainersCollector, BiConsumer<Identifier, BlockPos> structurePieceContainersCollector);
12+
}

src/main/java/com/mmodding/mmodding_lib/library/utils/MModdingGlobalMaps.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import com.mmodding.mmodding_lib.library.portals.squared.CustomSquaredPortal;
55
import com.mmodding.mmodding_lib.library.portals.squared.UnlinkedCustomSquaredPortal;
66
import com.mmodding.mmodding_lib.library.stellar.StellarCycle;
7+
import com.mmodding.mmodding_lib.library.worldgen.structures.StructureSpreadLoot;
78
import com.mmodding.mmodding_lib.library.worldgen.veins.CustomVeinType;
8-
import net.minecraft.item.ItemStack;
99
import net.minecraft.util.Identifier;
1010
import net.minecraft.util.registry.RegistryKey;
1111
import net.minecraft.world.World;
12+
import net.minecraft.world.gen.feature.StructureFeature;
1213

1314
import java.util.*;
1415

@@ -24,7 +25,7 @@ public class MModdingGlobalMaps {
2425

2526
static final List<RegistryKey<World>> DIFFERED_DIMENSION_SEEDS = new ArrayList<>();
2627

27-
static final Map<Identifier, List<ItemStack>> LOCAL_COMMON_STRUCTURE_PIECE_LOOT = new HashMap<>();
28+
static final Map<RegistryKey<StructureFeature>, StructureSpreadLoot> SPREAD_STRUCTURE_LOOTS = new HashMap<>();
2829

2930
public static Set<Identifier> getStellarCycleKeys() {
3031
return STELLAR_CYCLES.keySet();
@@ -69,12 +70,12 @@ public static Set<CustomVeinType> getCustomVeinTypes(Identifier chunkGeneratorSe
6970
return new HashSet<>(CUSTOM_VEIN_TYPES.get(chunkGeneratorSettingsIdentifier));
7071
}
7172

72-
public static boolean hasLocalCommonLootOfStructurePiece(Identifier structure) {
73-
return LOCAL_COMMON_STRUCTURE_PIECE_LOOT.containsKey(structure) && !LOCAL_COMMON_STRUCTURE_PIECE_LOOT.get(structure).isEmpty();
73+
public static boolean hasSpreadLootInStructure(RegistryKey<StructureFeature> structureKey) {
74+
return SPREAD_STRUCTURE_LOOTS.containsKey(structureKey);
7475
}
7576

76-
public static List<ItemStack> getLocalCommonLootOfStructurePiece(Identifier structure) {
77-
return LOCAL_COMMON_STRUCTURE_PIECE_LOOT.get(structure);
77+
public static StructureSpreadLoot getSpreadLootInStructure(RegistryKey<StructureFeature> structureKey) {
78+
return SPREAD_STRUCTURE_LOOTS.get(structureKey);
7879
}
7980

8081
public static List<RegistryKey<World>> getDifferedDimensionSeeds() {

src/main/java/com/mmodding/mmodding_lib/library/utils/WorldUtils.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mmodding.mmodding_lib.library.utils;
22

33
import com.mmodding.mmodding_lib.library.MModdingDamageSources;
4+
import com.mmodding.mmodding_lib.library.worldgen.structures.StructureSpreadLoot;
45
import com.mmodding.mmodding_lib.library.worldgen.veins.CustomVeinType;
56
import net.minecraft.client.world.ClientWorld;
67
import net.minecraft.item.ItemStack;
@@ -14,6 +15,7 @@
1415
import net.minecraft.world.World;
1516
import net.minecraft.world.WorldAccess;
1617
import net.minecraft.world.explosion.Explosion;
18+
import net.minecraft.world.gen.feature.StructureFeature;
1719

1820
import java.util.List;
1921
import java.util.Set;
@@ -22,16 +24,8 @@
2224

2325
public class WorldUtils {
2426

25-
public static void addLocalCommonLootToStructurePiece(Identifier structure, ItemStack... stacks) {
26-
MModdingGlobalMaps.LOCAL_COMMON_STRUCTURE_PIECE_LOOT.compute(structure, (key, itemStacks) -> {
27-
if (itemStacks == null) {
28-
return List.of(stacks);
29-
}
30-
else {
31-
itemStacks.addAll(List.of(stacks));
32-
return itemStacks;
33-
}
34-
});
27+
public static void addSpreadStructureLoot(RegistryKey<StructureFeature> structureRegistryKey, StructureSpreadLoot structureSpreadLoot) {
28+
MModdingGlobalMaps.SPREAD_STRUCTURE_LOOTS.put(structureRegistryKey, structureSpreadLoot);
3529
}
3630

3731
public static void addDifferedSeed(Identifier dimensionIdentifier) {
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.mmodding.mmodding_lib.library.worldgen.structures;
2+
3+
import com.mmodding.mmodding_lib.ducks.LootableContainerBlockEntityDuckInterface;
4+
import net.minecraft.block.entity.LootableContainerBlockEntity;
5+
import net.minecraft.item.ItemStack;
6+
import net.minecraft.util.Identifier;
7+
import net.minecraft.util.math.BlockPos;
8+
import net.minecraft.util.random.RandomGenerator;
9+
import net.minecraft.world.ServerWorldAccess;
10+
import org.jetbrains.annotations.ApiStatus;
11+
12+
import java.util.*;
13+
import java.util.function.BiConsumer;
14+
import java.util.function.Consumer;
15+
16+
public class StructureSpreadLoot {
17+
18+
private final Set<ItemStack> structureCommonLoot = new HashSet<>();
19+
private final Map<Identifier, Set<ItemStack>> structurePieceCommonLoots = new HashMap<>();
20+
21+
private StructureSpreadLoot() {}
22+
23+
public static StructureSpreadLoot create() {
24+
return new StructureSpreadLoot();
25+
}
26+
27+
public StructureSpreadLoot addStructureCommonLoot(ItemStack... stacks) {
28+
this.structureCommonLoot.addAll(Set.of(stacks));
29+
return this;
30+
}
31+
32+
public StructureSpreadLoot addStructurePieceCommonLoot(Identifier structurePiece, ItemStack... stacks) {
33+
this.structurePieceCommonLoots.compute(structurePiece, ((identifier, itemStacks) -> {
34+
if (itemStacks == null) {
35+
return new HashSet<>(Set.of(stacks));
36+
}
37+
else {
38+
itemStacks.addAll(Set.of(stacks));
39+
return itemStacks;
40+
}
41+
}));
42+
return this;
43+
}
44+
45+
@ApiStatus.Internal
46+
public StructureSpreadLootProvider createProvider() {
47+
return new StructureSpreadLootProvider(this);
48+
}
49+
50+
@ApiStatus.Internal
51+
public static class StructureSpreadLootProvider {
52+
53+
private final StructureSpreadLoot structureSpreadLoot;
54+
55+
private final List<BlockPos> structureContainers;
56+
private final Map<Identifier, List<BlockPos>> structurePieceContainers;
57+
58+
private StructureSpreadLootProvider(StructureSpreadLoot structureSpreadLoot) {
59+
this.structureSpreadLoot = structureSpreadLoot;
60+
this.structureContainers = new ArrayList<>();
61+
this.structurePieceContainers = new HashMap<>();
62+
}
63+
64+
public Consumer<BlockPos> structureContainersCollector() {
65+
return this.structureContainers::add;
66+
}
67+
68+
public BiConsumer<Identifier, BlockPos> structurePieceContainersCollector() {
69+
return (structurePiece, pos) -> this.structurePieceContainers.compute(structurePiece, (ignored, blockPos) -> {
70+
if (blockPos == null) {
71+
return new ArrayList<>(List.of(pos));
72+
}
73+
else {
74+
blockPos.add(pos);
75+
return blockPos;
76+
}
77+
});
78+
}
79+
80+
public void spreadLoots(ServerWorldAccess world, RandomGenerator random) {
81+
if (!this.structureContainers.isEmpty()) {
82+
this.structureSpreadLoot.structureCommonLoot.forEach(stack -> {
83+
BlockPos pos = this.structureContainers.get(random.nextInt(this.structureContainers.size()));
84+
if (world.getBlockEntity(pos) instanceof LootableContainerBlockEntity lootableContainerBlockEntity) {
85+
((LootableContainerBlockEntityDuckInterface) lootableContainerBlockEntity).mmodding_lib$addPredeterminedLoot(stack);
86+
}
87+
});
88+
this.structureContainers.clear();
89+
for (Identifier structurePiece : this.structureSpreadLoot.structurePieceCommonLoots.keySet()) {
90+
if (this.structurePieceContainers.containsKey(structurePiece)) {
91+
this.structureSpreadLoot.structurePieceCommonLoots.get(structurePiece).forEach(stack -> {
92+
List<BlockPos> positions = this.structurePieceContainers.get(structurePiece);
93+
BlockPos pos = positions.get(random.nextInt(positions.size()));
94+
if (world.getBlockEntity(pos) instanceof LootableContainerBlockEntity lootableContainerBlockEntity) {
95+
((LootableContainerBlockEntityDuckInterface) lootableContainerBlockEntity).mmodding_lib$addPredeterminedLoot(stack);
96+
}
97+
});
98+
}
99+
}
100+
}
101+
}
102+
}
103+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.mmodding.mmodding_lib.mixin.injectors;
2+
3+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
4+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import com.mmodding.mmodding_lib.ducks.StructurePoolElementDuckInterface;
6+
import net.minecraft.structure.StructureManager;
7+
import net.minecraft.structure.StructureTemplateManager;
8+
import net.minecraft.structure.pool.ListPoolElement;
9+
import net.minecraft.structure.pool.StructurePoolElement;
10+
import net.minecraft.util.BlockRotation;
11+
import net.minecraft.util.Identifier;
12+
import net.minecraft.util.math.BlockBox;
13+
import net.minecraft.util.math.BlockPos;
14+
import net.minecraft.util.random.RandomGenerator;
15+
import net.minecraft.world.StructureWorldAccess;
16+
import net.minecraft.world.gen.chunk.ChunkGenerator;
17+
import org.spongepowered.asm.mixin.Mixin;
18+
import org.spongepowered.asm.mixin.injection.At;
19+
import org.spongepowered.asm.mixin.injection.Inject;
20+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
21+
22+
import java.util.function.BiConsumer;
23+
import java.util.function.Consumer;
24+
25+
@Mixin(ListPoolElement.class)
26+
public class ListPoolElementMixin extends StructurePoolElementMixin {
27+
28+
@WrapOperation(method = "generate", at = @At(value = "INVOKE", target = "Lnet/minecraft/structure/pool/StructurePoolElement;generate(Lnet/minecraft/structure/StructureTemplateManager;Lnet/minecraft/world/StructureWorldAccess;Lnet/minecraft/structure/StructureManager;Lnet/minecraft/world/gen/chunk/ChunkGenerator;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/BlockRotation;Lnet/minecraft/util/math/BlockBox;Lnet/minecraft/util/random/RandomGenerator;Z)Z"))
29+
private boolean injectCollectors(StructurePoolElement instance, StructureTemplateManager structureTemplateManager, StructureWorldAccess structureWorldAccess, StructureManager structureManager, ChunkGenerator chunkGenerator, BlockPos blockPos0, BlockPos blockPos1, BlockRotation blockRotation, BlockBox blockBox, RandomGenerator randomGenerator, boolean b, Operation<Boolean> original) {
30+
((StructurePoolElementDuckInterface) instance).mmodding_lib$provideCollectors(this.structureContainersCollector, this.structurePieceContainersCollector);
31+
return original.call(instance, structureTemplateManager, structureWorldAccess, structureManager, chunkGenerator, blockPos0, blockPos1, blockRotation, blockBox, randomGenerator, b);
32+
}
33+
34+
/* @Inject(method = "generate", at = @At("TAIL"))
35+
private void clearCollectors(StructureTemplateManager structureTemplateManager, StructureWorldAccess world, StructureManager structureManager, ChunkGenerator chunkGenerator, BlockPos pos, BlockPos pivot, BlockRotation rotation, BlockBox box, RandomGenerator random, boolean keepJigsaws, CallbackInfoReturnable<Boolean> cir) {
36+
this.structureContainersCollector = null;
37+
this.structurePieceContainersCollector = null;
38+
} */
39+
40+
@Override
41+
public void mmodding_lib$provideCollectors(Consumer<BlockPos> structureContainersCollector, BiConsumer<Identifier, BlockPos> structurePieceContainersCollector) {
42+
this.structureContainersCollector = structureContainersCollector;
43+
this.structurePieceContainersCollector = structurePieceContainersCollector;
44+
}
45+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.mmodding.mmodding_lib.mixin.injectors;
2+
3+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4+
import com.llamalad7.mixinextras.sugar.Share;
5+
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
6+
import com.mmodding.mmodding_lib.ducks.StructureStartDuckInterface;
7+
import com.mmodding.mmodding_lib.library.utils.MModdingGlobalMaps;
8+
import com.mmodding.mmodding_lib.library.worldgen.structures.StructureSpreadLoot;
9+
import net.minecraft.server.command.PlaceComand;
10+
import net.minecraft.server.command.ServerCommandSource;
11+
import net.minecraft.structure.StructureStart;
12+
import net.minecraft.util.Holder;
13+
import net.minecraft.util.math.BlockPos;
14+
import net.minecraft.util.registry.RegistryKey;
15+
import net.minecraft.world.gen.feature.StructureFeature;
16+
import org.spongepowered.asm.mixin.Mixin;
17+
import org.spongepowered.asm.mixin.injection.At;
18+
import org.spongepowered.asm.mixin.injection.Inject;
19+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
20+
21+
@Mixin(PlaceComand.class)
22+
public class PlaceCommandMixin {
23+
24+
@Inject(method = "executePlaceStructure", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Holder;value()Ljava/lang/Object;", shift = At.Shift.AFTER))
25+
private static void initializeProvider(ServerCommandSource source, Holder<StructureFeature> structure, BlockPos pos, CallbackInfoReturnable<Integer> cir, @Share("structure_spread_loot") LocalRef<StructureSpreadLoot.StructureSpreadLootProvider> structureSpreadLoot) {
26+
RegistryKey<StructureFeature> structureKey = structure.getKey().orElseThrow();
27+
if (MModdingGlobalMaps.hasSpreadLootInStructure(structureKey)) {
28+
structureSpreadLoot.set(MModdingGlobalMaps.getSpreadLootInStructure(structureKey).createProvider());
29+
}
30+
}
31+
32+
@ModifyExpressionValue(method = "executePlaceStructure", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/gen/feature/StructureFeature;generate(Lnet/minecraft/util/registry/DynamicRegistryManager;Lnet/minecraft/world/gen/chunk/ChunkGenerator;Lnet/minecraft/world/biome/source/BiomeSource;Lnet/minecraft/world/gen/RandomState;Lnet/minecraft/structure/StructureTemplateManager;JLnet/minecraft/util/math/ChunkPos;ILnet/minecraft/world/HeightLimitView;Ljava/util/function/Predicate;)Lnet/minecraft/structure/StructureStart;"))
33+
private static StructureStart injectCollectors(StructureStart original, ServerCommandSource source, Holder<StructureFeature> structure, BlockPos pos, @Share("structure_spread_loot") LocalRef<StructureSpreadLoot.StructureSpreadLootProvider> structureSpreadLoot) {
34+
RegistryKey<StructureFeature> structureKey = structure.getKey().orElseThrow();
35+
if (MModdingGlobalMaps.hasSpreadLootInStructure(structureKey)) {
36+
((StructureStartDuckInterface) (Object) original).mmodding_lib$provideCollectors(structureSpreadLoot.get().structureContainersCollector(), structureSpreadLoot.get().structurePieceContainersCollector());
37+
}
38+
return original;
39+
}
40+
41+
@Inject(method = "executePlaceStructure", at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;forEach(Ljava/util/function/Consumer;)V", shift = At.Shift.AFTER))
42+
private static void executeProvider(ServerCommandSource source, Holder<StructureFeature> structure, BlockPos pos, CallbackInfoReturnable<Integer> cir, @Share("structure_spread_loot") LocalRef<StructureSpreadLoot.StructureSpreadLootProvider> structureSpreadLoot) {
43+
RegistryKey<StructureFeature> structureKey = structure.getKey().orElseThrow();
44+
if (MModdingGlobalMaps.hasSpreadLootInStructure(structureKey)) {
45+
structureSpreadLoot.get().spreadLoots(source.getWorld(), source.getWorld().getRandom());
46+
}
47+
}
48+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.mmodding.mmodding_lib.mixin.injectors;
2+
3+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
4+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import com.mmodding.mmodding_lib.ducks.StructurePoolElementDuckInterface;
6+
import net.minecraft.structure.StructureManager;
7+
import net.minecraft.structure.StructureTemplateManager;
8+
import net.minecraft.structure.piece.PoolStructurePiece;
9+
import net.minecraft.structure.pool.StructurePoolElement;
10+
import net.minecraft.util.BlockRotation;
11+
import net.minecraft.util.Identifier;
12+
import net.minecraft.util.math.BlockBox;
13+
import net.minecraft.util.math.BlockPos;
14+
import net.minecraft.util.random.RandomGenerator;
15+
import net.minecraft.world.StructureWorldAccess;
16+
import net.minecraft.world.gen.chunk.ChunkGenerator;
17+
import org.spongepowered.asm.mixin.Mixin;
18+
import org.spongepowered.asm.mixin.injection.At;
19+
20+
import java.util.function.BiConsumer;
21+
import java.util.function.Consumer;
22+
23+
@Mixin(PoolStructurePiece.class)
24+
public class PoolStructurePieceMixin extends StructurePieceMixin {
25+
26+
@WrapOperation(method = "generate(Lnet/minecraft/world/StructureWorldAccess;Lnet/minecraft/structure/StructureManager;Lnet/minecraft/world/gen/chunk/ChunkGenerator;Lnet/minecraft/util/random/RandomGenerator;Lnet/minecraft/util/math/BlockBox;Lnet/minecraft/util/math/BlockPos;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/structure/pool/StructurePoolElement;generate(Lnet/minecraft/structure/StructureTemplateManager;Lnet/minecraft/world/StructureWorldAccess;Lnet/minecraft/structure/StructureManager;Lnet/minecraft/world/gen/chunk/ChunkGenerator;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/BlockRotation;Lnet/minecraft/util/math/BlockBox;Lnet/minecraft/util/random/RandomGenerator;Z)Z"))
27+
private boolean injectCollectors(StructurePoolElement instance, StructureTemplateManager structureTemplateManager, StructureWorldAccess structureWorldAccess, StructureManager structureManager, ChunkGenerator chunkGenerator, BlockPos blockPos0, BlockPos blockPos1, BlockRotation blockRotation, BlockBox blockBox, RandomGenerator randomGenerator, boolean b, Operation<Boolean> original) {
28+
((StructurePoolElementDuckInterface) instance).mmodding_lib$provideCollectors(this.structureContainersCollector, this.structurePieceContainersCollector);
29+
return original.call(instance, structureTemplateManager, structureWorldAccess, structureManager, chunkGenerator, blockPos0, blockPos1, blockRotation, blockBox, randomGenerator, b);
30+
}
31+
32+
@Override
33+
public void mmodding_lib$provideCollectors(Consumer<BlockPos> structureContainersCollector, BiConsumer<Identifier, BlockPos> structurePieceContainersCollector) {
34+
this.structureContainersCollector = structureContainersCollector;
35+
this.structurePieceContainersCollector = structurePieceContainersCollector;
36+
}
37+
38+
@Override
39+
protected boolean isSimple() {
40+
return false;
41+
}
42+
43+
@Override
44+
protected Identifier getIdentifier() {
45+
return null;
46+
}
47+
}

0 commit comments

Comments
 (0)