Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
1package net.lerariemann.infinity.block.entity;
2
3import net.lerariemann.infinity.block.custom.BiomeBottleBlock;
4import net.lerariemann.infinity.registry.core.ModBlockEntities;
5import net.lerariemann.infinity.registry.core.ModItems;
6import net.lerariemann.infinity.util.VersionMethods;
7import net.lerariemann.infinity.util.core.NbtUtils;
8import net.minecraft.MethodsReturnNonnullByDefault;
9import net.minecraft.core.BlockPos;
10import net.minecraft.core.Holder;
11//? if >1.21.4 {
12import net.minecraft.core.component.DataComponentGetter;
13//?}
14import net.minecraft.nbt.CompoundTag;
15import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
16import net.minecraft.resources.ResourceLocation;
17import net.minecraft.server.level.ServerLevel;
18import net.minecraft.util.Mth;
19import net.minecraft.world.inventory.ContainerData;
20import net.minecraft.world.item.ItemStack;
21import net.minecraft.world.level.Level;
22import net.minecraft.world.level.biome.Biome;
23import net.minecraft.world.level.block.state.BlockState;
24//? if >1.21.4 {
25import net.minecraft.world.level.storage.ValueInput;
26import net.minecraft.world.level.storage.ValueOutput;
27//?}
28import org.jetbrains.annotations.Nullable;
29
30//? if >1.21 {
31import net.lerariemann.infinity.registry.core.ModComponentTypes;
32import net.minecraft.core.HolderLookup;
33import net.minecraft.core.component.DataComponentMap;
34//?}
35//? if neoforge {
36/*import javax.annotation.ParametersAreNonnullByDefault;
37*///?}
38
39@MethodsReturnNonnullByDefault
40//? if neoforge {
41/*@ParametersAreNonnullByDefault
42*///?}
43public class BiomeBottleBlockEntity extends TintableBlockEntity {
44 private final ContainerData propertyDelegate;
45 private ResourceLocation biome;
46 private int color;
47 public int charge;
48 private int from_charge;
49
50 public BiomeBottleBlockEntity(BlockPos pos, BlockState state) {
51 super(ModBlockEntities.BIOME_BOTTLE.get(), pos, state);
52 this.propertyDelegate = new ContainerData() {
53 public int get(int index) {
54 if (index == 0) {
55 return BiomeBottleBlockEntity.this.color;
56 }
57 return 0;
58 }
59
60 public void set(int index, int value) {
61 if (index == 0) {
62 BiomeBottleBlockEntity.this.color = value;
63 }
64
65 }
66 public int getCount() {
67 return 1;
68 }
69 };
70 this.empty();
71 }
72
73 public void setBiome(Holder<Biome> biome) {
74 if (biome.unwrapKey().isPresent()) setBiome(biome.value().getSkyColor(), biome.unwrapKey().get().location());
75 }
76
77 public void setBiome(int c, ResourceLocation i) {
78 this.color = c;
79 this.biome = i;
80 }
81
82 //? if >1.21 {
83 public void saveAdditional(
84 //? if >1.21.4 {
85 ValueOutput tag
86 //?} else {
87 /*CompoundTag tag, HolderLookup.Provider registryLookup
88 *///?}
89 ) {
90 super.saveAdditional(tag
91 //? if <1.21.4 {
92 /*, registryLookup
93 *///?}
94 );
95 tag.putString("Biome", biome.toString());
96 tag.putInt("Color", color);
97 tag.putInt("Charge", charge);
98 if (from_charge > 0) tag.putInt("from_charge", from_charge);
99 }
100
101 public void loadAdditional(
102 //? if >1.21.4 {
103 ValueInput tag
104 //?} else {
105 /*CompoundTag tag, HolderLookup.Provider registryLookup
106 *///?}
107 ) {
108 super.loadAdditional(tag
109 //? if <1.21.4 {
110 /*, registryLookup
111 *///?}
112 );
113 this.charge = NbtUtils.getInt(tag, "Charge");
114 this.biome = VersionMethods.id(NbtUtils.getString(tag, "Biome"));
115 this.color = NbtUtils.getInt(tag, "Color");
116 this.from_charge = NbtUtils.getInt(tag, "from_charge", 0);
117 }
118
119 @Override
120 protected void collectImplicitComponents(DataComponentMap.Builder componentMapBuilder) {
121 super.collectImplicitComponents(componentMapBuilder);
122 BiomeBottleBlock.addComponents(componentMapBuilder, biome, color, charge);
123 }
124
125 @Override
126 protected void applyImplicitComponents(
127 //? if >1.21.4 {
128 DataComponentGetter
129 //?} else {
130 /*DataComponentInput
131 *///?}
132 components) {
133 super.applyImplicitComponents(components);
134 this.biome = components.getOrDefault(ModComponentTypes.BIOME_CONTENTS.get(), BiomeBottleBlock.defaultBiome());
135 this.color = components.getOrDefault(ModComponentTypes.COLOR.get(), 0xFFFFFF);
136 this.charge = components.getOrDefault(ModComponentTypes.CHARGE.get(), 0);
137 }
138 @Override
139 public CompoundTag getUpdateTag(HolderLookup.Provider registryLookup) {
140 return saveWithoutMetadata(registryLookup);
141 }
142 //?} else {
143 /*public void saveAdditional(CompoundTag tag) {
144 super.saveAdditional(tag);
145 tag.putString("Biome", biome.toString());
146 tag.putInt("Color", color);
147 tag.putInt("Charge", charge);
148 if (from_charge > 0) tag.putInt("from_charge", from_charge);
149 }
150
151 public void load(CompoundTag tag) {
152 super.load(tag);
153 this.charge = NbtUtils.getInt(tag, "Charge");
154 this.biome = VersionMethods.id(tag.getString("Biome"));
155 this.color = NbtUtils.getInt(tag, "Color");
156 this.from_charge = NbtUtils.getInt(tag, "from_charge", 0);
157 }
158 *///?}
159
160 @Nullable
161 @Override
162 public ClientboundBlockEntityDataPacket getUpdatePacket() {
163 return ClientboundBlockEntityDataPacket.create(this);
164 }
165
166
167
168 public int getTint() {
169 return propertyDelegate.get(0);
170 }
171
172 public ItemStack asStack() {
173 ItemStack itemStack = ModItems.BIOME_BOTTLE_ITEM.get().getDefaultInstance();
174 //? if >1.21
175 itemStack.applyComponents(this.collectComponents());
176 return itemStack;
177 }
178
179 public boolean isTicking() {
180 return from_charge > 0;
181 }
182
183 public void startTicking() {
184 from_charge = charge;
185 }
186
187 public void empty() {
188 color = 0xFFFFFF;
189 biome = BiomeBottleBlock.defaultBiome();
190 charge = 0;
191 from_charge = 0;
192 }
193
194 public static void serverTick(Level world, BlockPos pos, BlockState state, BiomeBottleBlockEntity be) {
195 if (be.isTicking() && world instanceof ServerLevel w) {
196 if (w.getGameTime() % 20 == 0) {
197 int level = be.charge/100;
198 if (level <= 0) {
199 be.empty();
200 }
201 else {
202 int diff2 = be.charge > 1500 ? 500 : 100;
203 int diff = be.charge%diff2;
204 if (diff == 0) diff = diff2;
205 int charge_new = be.charge - diff;
206 BiomeBottleBlock.spreadRing(w, pos, be.biome, be.from_charge - be.charge, be.from_charge - charge_new);
207 be.charge = charge_new;
208 world.setBlockAndUpdate(pos, state.setValue(BiomeBottleBlock.LEVEL, Mth.clamp(level - 1, 0, 10)));
209 BiomeBottleBlock.playSploosh(w, pos);
210 be.setChanged();
211 }
212 }
213 }
214 }
215}