Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 233 lines 8.2 kB view raw
1package net.lerariemann.infinity.block.entity; 2 3import net.lerariemann.infinity.registry.core.ModBlockEntities; 4import net.lerariemann.infinity.registry.core.ModComponentTypes; 5import net.lerariemann.infinity.registry.core.ModItems; 6import net.lerariemann.infinity.util.VersionMethods; 7import net.lerariemann.infinity.util.core.NbtUtils; 8import net.lerariemann.infinity.util.var.ColorLogic; 9import net.minecraft.core.BlockPos; 10//? if >1.21 { 11import net.minecraft.core.HolderLookup; 12import net.minecraft.core.component.DataComponentMap; 13//?} 14//? if >1.21.4 { 15import net.minecraft.core.component.DataComponentGetter; 16import net.minecraft.world.level.storage.ValueInput; 17import net.minecraft.world.level.storage.ValueOutput; 18//?} 19import net.minecraft.nbt.CompoundTag; 20import net.minecraft.nbt.Tag; 21import net.minecraft.network.protocol.Packet; 22import net.minecraft.network.protocol.game.ClientGamePacketListener; 23import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; 24import net.minecraft.sounds.SoundEvent; 25import net.minecraft.sounds.SoundEvents; 26import net.minecraft.sounds.SoundSource; 27import net.minecraft.world.item.DyeItem; 28import net.minecraft.world.item.ItemStack; 29import net.minecraft.world.item.Items; 30import net.minecraft.world.level.Level; 31import net.minecraft.world.level.block.state.BlockState; 32import org.jspecify.annotations.Nullable; 33 34import java.awt.*; 35import java.util.concurrent.atomic.AtomicBoolean; 36 37public class ChromaticBlockEntity extends SpecialBlockEntity.Boopable { 38 public short hue; 39 public short saturation; 40 public short brightness; 41 public int color; 42 public ChromaticBlockEntity(BlockPos pos, BlockState state) { 43 super(ModBlockEntities.CHROMATIC.get(), pos, state); 44 hue = 0; 45 saturation = 0; 46 brightness = 255; 47 } 48 49 public void setColor(int colorHex) { 50 setColor(colorHex, null); 51 } 52 53 public void setColor(int hue, int saturation, int brightness, @Nullable AtomicBoolean cancel) { 54 if (cancel != null && this.hue == hue && this.saturation == saturation && this.brightness == brightness) { 55 cancel.set(true); 56 return; 57 } 58 this.hue = (short)hue; 59 this.saturation = (short)saturation; 60 this.brightness = (short)brightness; 61 updateColor(); 62 sync(); 63 } 64 65 public void setColor(int colorHex, @Nullable AtomicBoolean cancel) { 66 if (cancel != null && colorHex == color) { 67 cancel.set(true); 68 return; 69 } 70 Color c = (new Color(colorHex)); 71 float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null); 72 hue = (short)(hsb[0] * 360); 73 saturation = (short)(hsb[1] * 255); 74 brightness = (short)(hsb[2] * 255); 75 color = colorHex; 76 sync(); 77 } 78 public void updateColor() { 79 color = Color.HSBtoRGB(hue / 360f, saturation / 255f, brightness / 255f) & 0xFFFFFF; 80 } 81 82 //? if >1.21 { 83 @Override 84 protected void collectImplicitComponents(DataComponentMap.Builder componentMapBuilder) { 85 super.collectImplicitComponents(componentMapBuilder); 86 componentMapBuilder.set(ModComponentTypes.COLOR.get(), color); 87 } 88 @Override 89 protected void applyImplicitComponents( 90 //? if >1.21.4 { 91 DataComponentGetter 92 //?} else { 93 /*DataComponentInput 94 *///?} 95 components) { 96 super.applyImplicitComponents(components); 97 setColor(components.getOrDefault(ModComponentTypes.COLOR.get(), 0xFFFFFF)); 98 } 99 100 public static DataComponentMap asMap(int i) { 101 return DataComponentMap.builder() 102 .set(ModComponentTypes.COLOR.get(), i) 103 .build(); 104 } 105 public DataComponentMap asMap() { 106 return asMap(getTint()); 107 } 108 //?} else { 109 /*public CompoundTag asMap() { 110 CompoundTag compoundTag = new CompoundTag(); 111 compoundTag.putInt(ModComponentTypes.COLOR, getTint()); 112 return compoundTag; 113 } 114 *///?} 115 public short offset(short orig, short amount, AtomicBoolean cancel) { 116 if (amount < 0 ? orig == 0 : orig == 255) { 117 cancel.set(true); 118 return orig; 119 } 120 orig += amount; 121 if (orig < 0) orig = 0; 122 else if (orig > 255) orig = 255; 123 return orig; 124 } 125 public boolean onUse(Level world, BlockPos pos, ItemStack stack) { 126 SoundEvent event = SoundEvents.NOTE_BLOCK_GUITAR.value(); 127 float pitch = -1f; 128 float volume = 1f; 129 AtomicBoolean cancel = new AtomicBoolean(false); 130 131 if (stack.is(Items.AMETHYST_SHARD)) { 132 saturation = offset(saturation, (short) 16, cancel); 133 pitch = saturation / 255f; 134 } 135 else if (stack.is(ModItems.FOOTPRINT.get())) { 136 saturation = offset(saturation, (short) -16, cancel); 137 pitch = saturation / 255f; 138 } 139 else if (stack.is(ModItems.WHITE_MATTER.get())) { 140 brightness = offset(brightness, (short) 16, cancel); 141 pitch = brightness / 255f; 142 } 143 else if (stack.is(ModItems.BLACK_MATTER.get())) { 144 brightness = offset(brightness, (short) -16, cancel); 145 pitch = brightness / 255f; 146 } 147 else if (stack.getItem() instanceof DyeItem dye) { 148 setColor(ColorLogic.getChromaticColor(dye.getDyeColor()), cancel); 149 event = SoundEvents.DYE_USE; 150 } 151 else return false; 152 if (cancel.get()) return false; //block was already at extremal saturation / brightness, no need for side effects 153 updateColor(); 154 pitch = pitch < 0 ? 1f : 0.5f + 1.5f * pitch; //scaling for Minecraft's sound system 155 if (!world.isClientSide()) world.playSound(null, pos, event, SoundSource.BLOCKS, volume, pitch); 156 sync(); 157 return true; 158 } 159 160 public void onIridStarUse(boolean reverse) { 161 if (reverse) { 162 hue -= 10; 163 if (hue < 0) hue += 360; 164 } 165 else { 166 hue += 10; 167 if (hue > 360) hue -= 360; 168 } 169 updateColor(); 170 sync(); 171 } 172 173 //? if >1.21.4 { 174 public void loadAdditional(ValueInput tag) { 175 super.loadAdditional(tag); 176//?} else if >1.21 { 177 /*public void loadAdditional(CompoundTag tag, HolderLookup.Provider registryLookup) { 178 super.loadAdditional(tag, registryLookup); 179*///?} else { 180 /*public void load(CompoundTag tag) { 181 super.load(tag); 182*///?} 183 CompoundTag nbt = VersionMethods.loadBlockEntityData(tag); 184 if (NbtUtils.compoundHasInt(nbt, "color")) 185 setColor(NbtUtils.getInt(nbt,"color")); 186 else if (NbtUtils.compoundHasCompound(nbt, "color")) { 187 CompoundTag color = NbtUtils.getCompound(nbt, "color"); 188 hue = NbtUtils.getShort(color, "h"); 189 saturation = NbtUtils.getShort(color, "s"); 190 brightness = NbtUtils.getShort(color, "b"); 191 updateColor(); 192 } 193 } 194 195 //? if >1.21.4 { 196 public void saveAdditional(ValueOutput tag) { 197 super.saveAdditional(tag); 198//?} else if >1.21 { 199 /*public void saveAdditional(CompoundTag tag, HolderLookup.Provider registryLookup) { 200 super.saveAdditional(tag, registryLookup); 201*///?} else { 202 /*public void saveAdditional(CompoundTag tag) { 203 super.saveAdditional(tag); 204*///?} 205 CompoundTag res = new CompoundTag(); 206 CompoundTag color = new CompoundTag(); 207 color.putShort("h", hue); 208 color.putShort("s", saturation); 209 color.putShort("b", brightness); 210 res.put("color", color); 211 VersionMethods.saveBlockEntityData(tag, res); 212 } 213 214 public int getTint() { 215 return color; 216 } 217 218 @Nullable 219 @Override 220 public Packet<ClientGamePacketListener> getUpdatePacket() { 221 return ClientboundBlockEntityDataPacket.create(this); 222 } 223 @Override 224 public CompoundTag getUpdateTag( 225 //? if >1.21 226 HolderLookup.Provider registryLookup 227 ) { 228 return saveWithoutMetadata( 229 //? if >1.21 230 registryLookup 231 ); 232 } 233}