tangled
alpha
login
or
join now
codexarchonic.nekoweb.org
/
ProjectInfinity
0
fork
atom
Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
0
fork
atom
overview
issues
6
pulls
pipelines
this is pure insanity
Lera
11 months ago
a61cacc2
6e2b1c42
+144
-70
10 changed files
expand all
collapse all
unified
split
common
src
main
java
net
lerariemann
infinity
access
BlockEntityTypeAccess.java
dimensions
RandomFeaturesList.java
features
raw_generation
RandomBonusChest.java
top_layer
RandomBonusChest.java
features
RandomBonusChestFeature.java
mixin
qol
BlockEntityTypeMixin.java
util
config
ConfigGenerator.java
core
ConfigType.java
resources
config
hardcoded
features
toplayermodification.json
infinity.mixins.json
+12
common/src/main/java/net/lerariemann/infinity/access/BlockEntityTypeAccess.java
···
1
1
+
package net.lerariemann.infinity.access;
2
2
+
3
3
+
import net.minecraft.block.Block;
4
4
+
import net.minecraft.block.entity.BlockEntity;
5
5
+
import net.minecraft.block.entity.BlockEntityType;
6
6
+
7
7
+
import java.util.Set;
8
8
+
9
9
+
public interface BlockEntityTypeAccess<T extends BlockEntity> {
10
10
+
BlockEntityType.BlockEntityFactory<? extends T> infinity$getFactory();
11
11
+
Set<Block> infinity$getBlocks();
12
12
+
}
+8
-3
common/src/main/java/net/lerariemann/infinity/dimensions/RandomFeaturesList.java
···
6
6
import net.lerariemann.infinity.dimensions.features.local_modifications.RandomGeode;
7
7
import net.lerariemann.infinity.dimensions.features.local_modifications.RandomIceberg;
8
8
import net.lerariemann.infinity.dimensions.features.local_modifications.RandomRock;
9
9
-
import net.lerariemann.infinity.dimensions.features.raw_generation.RandomBonusChest;
9
9
+
import net.lerariemann.infinity.dimensions.features.top_layer.RandomBonusChest;
10
10
import net.lerariemann.infinity.dimensions.features.raw_generation.RandomEndIsland;
11
11
import net.lerariemann.infinity.dimensions.features.raw_generation.RandomShape;
12
12
import net.lerariemann.infinity.dimensions.features.surface_structures.*;
···
54
54
data.add(undergroundDecoration());
55
55
data.add(fluidSprings());
56
56
data.add(vegetation());
57
57
-
data.add(getAllElements(ConfigType.TOP_LAYER));
57
57
+
data.add(topLayer());
58
58
}
59
59
60
60
NbtList getAllElements(ConfigType name) {
···
82
82
NbtList rawGeneration() {
83
83
NbtList res = new NbtList();
84
84
addRandomFeature("end_island", res, RandomEndIsland::new);
85
85
-
addRandomFeature("bonus_chest", res, RandomBonusChest::new);
86
85
if (roll("shape")) addRandomFeature(res, new RandomShape(this, PROVIDER.randomName(random, ConfigType.SHAPE_TYPES)));
87
86
return res;
88
87
}
···
158
157
addRandomFeature("water_plants", res, RandomPickle::new);
159
158
addRandomFeature("water_plants", res, RandomKelp::new);
160
159
}
160
160
+
return res;
161
161
+
}
162
162
+
163
163
+
NbtList topLayer() {
164
164
+
NbtList res = getAllElements(ConfigType.TOP_LAYER);
165
165
+
addRandomFeature("bonus_chest", res, RandomBonusChest::new);
161
166
return res;
162
167
}
163
168
-31
common/src/main/java/net/lerariemann/infinity/dimensions/features/raw_generation/RandomBonusChest.java
···
1
1
-
package net.lerariemann.infinity.dimensions.features.raw_generation;
2
2
-
3
3
-
import net.lerariemann.infinity.dimensions.RandomFeaturesList;
4
4
-
import net.lerariemann.infinity.dimensions.features.Placement;
5
5
-
import net.lerariemann.infinity.dimensions.features.RandomisedFeature;
6
6
-
import net.lerariemann.infinity.util.core.ConfigType;
7
7
-
import net.minecraft.nbt.NbtCompound;
8
8
-
import net.minecraft.nbt.NbtList;
9
9
-
10
10
-
public class RandomBonusChest extends RandomisedFeature {
11
11
-
public RandomBonusChest(RandomFeaturesList lst) {
12
12
-
super(lst, "chest");
13
13
-
id = "infinity:bonus_chest";
14
14
-
savePlacement();
15
15
-
}
16
16
-
17
17
-
@Override
18
18
-
public NbtCompound feature() {
19
19
-
NbtCompound config = new NbtCompound();
20
20
-
config.putString("loot", PROVIDER.randomName(random, ConfigType.LOOT_TABLES));
21
21
-
return feature(config);
22
22
-
}
23
23
-
24
24
-
@Override
25
25
-
public NbtList placement() {
26
26
-
Placement res = new Placement();
27
27
-
res.addCount(random.nextInt(1, 16));
28
28
-
res.addBiome();
29
29
-
return res.data;
30
30
-
}
31
31
-
}
+44
common/src/main/java/net/lerariemann/infinity/dimensions/features/top_layer/RandomBonusChest.java
···
1
1
+
package net.lerariemann.infinity.dimensions.features.top_layer;
2
2
+
3
3
+
import net.lerariemann.infinity.dimensions.RandomFeaturesList;
4
4
+
import net.lerariemann.infinity.dimensions.features.Placement;
5
5
+
import net.lerariemann.infinity.dimensions.features.RandomisedFeature;
6
6
+
import net.lerariemann.infinity.util.core.ConfigType;
7
7
+
import net.lerariemann.infinity.util.core.NbtUtils;
8
8
+
import net.minecraft.loot.LootTables;
9
9
+
import net.minecraft.nbt.NbtCompound;
10
10
+
import net.minecraft.nbt.NbtList;
11
11
+
12
12
+
public class RandomBonusChest extends RandomisedFeature {
13
13
+
boolean isFrequent;
14
14
+
15
15
+
public RandomBonusChest(RandomFeaturesList lst) {
16
16
+
super(lst, "chest");
17
17
+
id = "infinity:bonus_chest";
18
18
+
isFrequent = random.nextBoolean();
19
19
+
savePlacement();
20
20
+
}
21
21
+
22
22
+
@Override
23
23
+
public NbtCompound feature() {
24
24
+
NbtCompound config = new NbtCompound();
25
25
+
config.putString("loot", random.nextBoolean() ? LootTables.SPAWN_BONUS_CHEST.getValue().toString() :
26
26
+
random.nextBoolean() ? "infinity:random" : PROVIDER.randomName(random, ConfigType.LOOT_TABLES));
27
27
+
config.put("block", NbtUtils.nameToElement(random.nextBoolean() ? "minecraft:chest" :
28
28
+
isFrequent ? "minecraft:barrel" : PROVIDER.randomName(random, ConfigType.CHESTS)));
29
29
+
return feature(config);
30
30
+
}
31
31
+
32
32
+
@Override
33
33
+
public NbtList placement() {
34
34
+
Placement res = new Placement();
35
35
+
if (isFrequent) {
36
36
+
res.addCountEveryLayer(random.nextInt(1, 8));
37
37
+
} else {
38
38
+
res.addCountEveryLayer(1);
39
39
+
res.addRarityFilter(random.nextInt(1, 8));
40
40
+
}
41
41
+
res.addBiome();
42
42
+
return res.data;
43
43
+
}
44
44
+
}
+20
-27
common/src/main/java/net/lerariemann/infinity/features/RandomBonusChestFeature.java
···
2
2
3
3
import com.mojang.serialization.Codec;
4
4
import com.mojang.serialization.codecs.RecordCodecBuilder;
5
5
-
import it.unimi.dsi.fastutil.ints.IntArrayList;
5
5
+
import net.lerariemann.infinity.InfinityMod;
6
6
+
import net.lerariemann.infinity.util.core.ConfigType;
6
7
import net.minecraft.block.BlockState;
7
8
import net.minecraft.block.Blocks;
8
9
import net.minecraft.inventory.LootableInventory;
9
10
import net.minecraft.registry.RegistryKey;
10
11
import net.minecraft.registry.RegistryKeys;
11
12
import net.minecraft.util.Identifier;
12
12
-
import net.minecraft.util.Util;
13
13
import net.minecraft.util.math.BlockPos;
14
14
-
import net.minecraft.util.math.ChunkPos;
15
14
import net.minecraft.util.math.Direction;
16
15
import net.minecraft.util.math.random.Random;
17
17
-
import net.minecraft.world.Heightmap;
18
16
import net.minecraft.world.StructureWorldAccess;
19
17
import net.minecraft.world.gen.feature.Feature;
20
18
import net.minecraft.world.gen.feature.FeatureConfig;
21
19
import net.minecraft.world.gen.feature.util.FeatureContext;
22
20
23
23
-
import java.util.stream.IntStream;
21
21
+
import java.util.Optional;
24
22
25
23
public class RandomBonusChestFeature extends Feature<RandomBonusChestFeature.Config> {
26
24
public RandomBonusChestFeature(Codec<Config> codec) {
···
31
29
public boolean generate(FeatureContext<Config> context) {
32
30
Random random = context.getRandom();
33
31
StructureWorldAccess structureWorldAccess = context.getWorld();
34
34
-
ChunkPos chunkPos = new ChunkPos(context.getOrigin());
35
35
-
IntArrayList intArrayList = Util.shuffle(IntStream.rangeClosed(chunkPos.getStartX(), chunkPos.getEndX()), random);
36
36
-
IntArrayList intArrayList2 = Util.shuffle(IntStream.rangeClosed(chunkPos.getStartZ(), chunkPos.getEndZ()), random);
37
37
-
BlockPos.Mutable mutable = new BlockPos.Mutable();
38
32
39
39
-
for (Integer integer : intArrayList) {
40
40
-
for (Integer integer2 : intArrayList2) {
41
41
-
mutable.set(integer, 0, integer2);
42
42
-
BlockPos blockPos = structureWorldAccess.getTopPosition(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, mutable);
43
43
-
if (structureWorldAccess.isAir(blockPos) || structureWorldAccess.getBlockState(blockPos).getCollisionShape(structureWorldAccess, blockPos).isEmpty()) {
44
44
-
structureWorldAccess.setBlockState(blockPos, Blocks.CHEST.getDefaultState(), 2);
45
45
-
LootableInventory.setLootTable(structureWorldAccess, random, blockPos, RegistryKey.of(RegistryKeys.LOOT_TABLE, context.getConfig().loot));
46
46
-
BlockState blockState = Blocks.TORCH.getDefaultState();
33
33
+
BlockPos blockPos = context.getOrigin();
34
34
+
if (structureWorldAccess.isAir(blockPos) || structureWorldAccess.getBlockState(blockPos).getCollisionShape(structureWorldAccess, blockPos).isEmpty()) {
35
35
+
BlockState state = context.getConfig().block.orElseGet(Blocks.CHEST::getDefaultState);
36
36
+
structureWorldAccess.setBlockState(blockPos, state, 2);
37
37
+
Identifier id = context.getConfig().loot;
38
38
+
if (id.toString().equals("infinity:random")) id = Identifier.of(InfinityMod.provider.randomName(context.getRandom(), ConfigType.LOOT_TABLES));
39
39
+
LootableInventory.setLootTable(structureWorldAccess, random, blockPos, RegistryKey.of(RegistryKeys.LOOT_TABLE, id));
40
40
+
BlockState blockState = Blocks.TORCH.getDefaultState();
47
41
48
48
-
for (Direction direction : Direction.Type.HORIZONTAL) {
49
49
-
BlockPos blockPos2 = blockPos.offset(direction);
50
50
-
if (blockState.canPlaceAt(structureWorldAccess, blockPos2)) {
51
51
-
structureWorldAccess.setBlockState(blockPos2, blockState, 2);
52
52
-
}
53
53
-
}
54
54
-
55
55
-
return true;
42
42
+
for (Direction direction : Direction.Type.HORIZONTAL) {
43
43
+
BlockPos blockPos2 = blockPos.offset(direction);
44
44
+
if (blockState.canPlaceAt(structureWorldAccess, blockPos2)) {
45
45
+
structureWorldAccess.setBlockState(blockPos2, blockState, 2);
56
46
}
57
47
}
48
48
+
49
49
+
return true;
58
50
}
59
51
return false;
60
52
}
61
53
62
62
-
public record Config(Identifier loot) implements FeatureConfig {
54
54
+
public record Config(Identifier loot, Optional<BlockState> block) implements FeatureConfig {
63
55
public static final Codec<Config> CODEC = RecordCodecBuilder.create(instance -> instance.group(
64
64
-
(Identifier.CODEC.fieldOf("loot")).forGetter(a -> a.loot)).apply(
56
56
+
(Identifier.CODEC.fieldOf("loot")).forGetter(a -> a.loot),
57
57
+
(BlockState.CODEC.optionalFieldOf("block")).forGetter(a -> a.block)).apply(
65
58
instance, Config::new));
66
59
}
67
60
}
+28
common/src/main/java/net/lerariemann/infinity/mixin/qol/BlockEntityTypeMixin.java
···
1
1
+
package net.lerariemann.infinity.mixin.qol;
2
2
+
3
3
+
import net.lerariemann.infinity.access.BlockEntityTypeAccess;
4
4
+
import net.minecraft.block.Block;
5
5
+
import net.minecraft.block.entity.BlockEntity;
6
6
+
import net.minecraft.block.entity.BlockEntityType;
7
7
+
import org.spongepowered.asm.mixin.Final;
8
8
+
import org.spongepowered.asm.mixin.Mixin;
9
9
+
import org.spongepowered.asm.mixin.Shadow;
10
10
+
11
11
+
import java.util.Set;
12
12
+
13
13
+
@Mixin(BlockEntityType.class)
14
14
+
public class BlockEntityTypeMixin<T extends BlockEntity> implements BlockEntityTypeAccess<T> {
15
15
+
@Shadow @Final private BlockEntityType.BlockEntityFactory<? extends T> factory;
16
16
+
17
17
+
@Shadow @Final private Set<Block> blocks;
18
18
+
19
19
+
@Override
20
20
+
public BlockEntityType.BlockEntityFactory<? extends T> infinity$getFactory() {
21
21
+
return factory;
22
22
+
}
23
23
+
24
24
+
@Override
25
25
+
public Set<Block> infinity$getBlocks() {
26
26
+
return blocks;
27
27
+
}
28
28
+
}
+29
-5
common/src/main/java/net/lerariemann/infinity/util/config/ConfigGenerator.java
···
1
1
package net.lerariemann.infinity.util.config;
2
2
3
3
import net.lerariemann.infinity.InfinityMod;
4
4
+
import net.lerariemann.infinity.access.BlockEntityTypeAccess;
4
5
import net.lerariemann.infinity.block.entity.CosmicAltarBlockEntity;
5
6
import net.lerariemann.infinity.util.core.ConfigType;
6
7
import net.lerariemann.infinity.util.var.ColorLogic;
7
8
import net.minecraft.block.Block;
8
9
import net.minecraft.block.BlockState;
9
10
import net.minecraft.block.FallingBlock;
11
11
+
import net.minecraft.block.entity.BlockEntity;
12
12
+
import net.minecraft.block.entity.BlockEntityType;
13
13
+
import net.minecraft.block.entity.LootableContainerBlockEntity;
14
14
+
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
10
15
import net.minecraft.block.enums.BlockFace;
11
16
import net.minecraft.entity.EntityType;
12
17
import net.minecraft.entity.SpawnGroup;
···
54
59
ConfigFactory.of(Registries.STATUS_EFFECT, ConfigGenerator::extractEffect).generate(ConfigType.EFFECTS);
55
60
generateSounds();
56
61
generateBlockTags();
62
62
+
generateBEs();
57
63
SurfaceRuleScanner.scan(server);
58
64
DynamicRegistryManager manager = server.getRegistryManager();
59
65
ConfigFactory.of(manager.get(RegistryKeys.JUKEBOX_SONG)).generate(ConfigType.JUKEBOXES);
···
66
72
67
73
static void generateSounds() {
68
74
Registry<SoundEvent> r = Registries.SOUND_EVENT;
69
69
-
DataCollection.Logged music = new DataCollection.Logged(ConfigType.MUSIC, "music tracks");
70
70
-
DataCollection.Logged sounds = new DataCollection.Logged(ConfigType.SOUNDS);
75
75
+
DataCollection music = new DataCollection.Logged(ConfigType.MUSIC, "music tracks");
76
76
+
DataCollection sounds = new DataCollection.Logged(ConfigType.SOUNDS);
71
77
r.getKeys().forEach(a -> {
72
78
Identifier id = a.getValue();
73
79
if (id.toString().contains("music")) music.addIdentifier(id);
···
78
84
}
79
85
80
86
static void generateBlockTags() {
81
81
-
DataCollection.Logged tagMap = new DataCollection.Logged(ConfigType.TAGS, "block tags");
87
87
+
DataCollection tagMap = new DataCollection.Logged(ConfigType.TAGS, "block tags");
82
88
Registries.BLOCK.streamTags().forEach(tagKey -> tagMap.addIdentifier(tagKey.id()));
83
89
tagMap.save();
84
90
}
85
91
86
92
static Set<String> generateFluids() {
87
87
-
DataCollection.Logged fluidMap = new DataCollection.Logged(ConfigType.FLUIDS);
93
93
+
DataCollection fluidMap = new DataCollection.Logged(ConfigType.FLUIDS);
88
94
Registry<Fluid> r = Registries.FLUID;
89
95
Set<String> fluidBlockNames = new HashSet<>();
90
96
r.getKeys().forEach(key -> {
···
105
111
}
106
112
107
113
static void generateBlocks(ServerWorld serverWorld, BlockPos inAir, BlockPos onAltar, Set<String> excludedBlockNames) {
108
108
-
DataCollection.Logged blockMap = new DataCollection.Logged(ConfigType.BLOCKS);
114
114
+
DataCollection blockMap = new DataCollection.Logged(ConfigType.BLOCKS);
109
115
DataCollection colorPresetMap = new DataCollection(ConfigType.COLOR_PRESETS);
110
116
DataCollection flowerMap = new DataCollection(ConfigType.FLOWERS);
111
117
Registry<Block> r = Registries.BLOCK;
···
124
130
blockMap.save();
125
131
colorPresetMap.save();
126
132
flowerMap.save();
133
133
+
}
134
134
+
135
135
+
static void generateBEs() {
136
136
+
Registry<BlockEntityType<?>> r = Registries.BLOCK_ENTITY_TYPE;
137
137
+
DataCollection chests = new DataCollection.Logged(ConfigType.CHESTS);
138
138
+
Set<Identifier> allBlocks = new HashSet<>();
139
139
+
r.getKeys().forEach(key -> {
140
140
+
BlockEntityTypeAccess<? extends BlockEntity> bet = (BlockEntityTypeAccess<?>)(r.get(key));
141
141
+
assert bet != null;
142
142
+
Set<Block> blocks = bet.infinity$getBlocks();
143
143
+
144
144
+
BlockEntity be = bet.infinity$getFactory().create(BlockPos.ORIGIN, ((Block)blocks.toArray()[0]).getDefaultState());
145
145
+
if (be instanceof LootableContainerBlockEntity && !(be instanceof ShulkerBoxBlockEntity)) {
146
146
+
for (Block b : blocks) allBlocks.add(Registries.BLOCK.getId(b));
147
147
+
}
148
148
+
});
149
149
+
allBlocks.forEach(chests::addIdentifier);
150
150
+
chests.save();
127
151
}
128
152
129
153
static boolean checkColorSet(String block) {
+1
common/src/main/java/net/lerariemann/infinity/util/core/ConfigType.java
···
14
14
FULL_BLOCKS("full_blocks", "minecraft:stone"),
15
15
FULL_BLOCKS_WG("full_blocks_worldgen", "minecraft:stone"),
16
16
FLOWERS("flowers", "minecraft:poppy"),
17
17
+
CHESTS("chests", "minecraft:chest"),
17
18
FLUIDS("fluids", "minecraft:water", NbtUtils::nameToFluid),
18
19
ITEMS("items", "minecraft:stick"),
19
20
SOUNDS("sounds", "minecraft:block.stone.step"),
+1
-4
common/src/main/resources/config/hardcoded/features/toplayermodification.json
···
1
1
{
2
2
+
"infinity_version": 2004006,
2
3
"elements": [
3
4
{
4
5
"key": "minecraft:freeze_top_layer",
···
7
8
{
8
9
"key": "minecraft:void_start_platform",
9
10
"weight": 0.5
10
10
-
},
11
11
-
{
12
12
-
"key": "infinity:bonus_chest",
13
13
-
"weight": 0.2
14
11
}
15
12
]
16
13
}
+1
common/src/main/resources/infinity.mixins.json
···
47
47
"options.EntityMixin",
48
48
"options.PlayerManagerMixin",
49
49
"options.ServerWorldMixin",
50
50
+
"qol.BlockEntityTypeMixin",
50
51
"qol.EnderDragonEntityMixin",
51
52
"qol.FireBlockMixin",
52
53
"qol.LavaFluidMixin"