Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 258 lines 9.6 kB view raw
1package net.lerariemann.infinity.entity.custom; 2 3import net.lerariemann.infinity.InfinityMod; 4import net.lerariemann.infinity.iridescence.Iridescence; 5import net.lerariemann.infinity.registry.var.ModEntityDataSerializers; 6import net.lerariemann.infinity.util.InfinityMethods; 7import net.lerariemann.infinity.util.VersionMethods; 8import net.lerariemann.infinity.util.core.ConfigType; 9import net.lerariemann.infinity.util.core.NbtUtils; 10import net.lerariemann.infinity.util.core.RandomProvider; 11//? if >1.21 { 12import net.minecraft.core.component.DataComponentMap; 13import net.minecraft.core.component.DataComponents; 14//?} 15//? if >1.21.4 { 16import net.minecraft.world.level.storage.ValueInput; 17import net.minecraft.world.level.storage.ValueOutput; 18//?} 19import net.minecraft.core.registries.Registries; 20import net.minecraft.nbt.CompoundTag; 21import net.minecraft.network.chat.Component; 22import net.minecraft.network.syncher.EntityDataAccessor; 23import net.minecraft.network.syncher.EntityDataSerializers; 24import net.minecraft.network.syncher.SynchedEntityData; 25import net.minecraft.resources.ResourceKey; 26import net.minecraft.resources.ResourceLocation; 27import net.minecraft.server.level.ServerLevel; 28import net.minecraft.world.*; 29import net.minecraft.world.damagesource.DamageSource; 30import net.minecraft.world.entity.EntityType; 31import net.minecraft.world.entity.SpawnGroupData; 32import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 33import net.minecraft.world.entity.ai.attributes.Attributes; 34import net.minecraft.world.entity.ai.goal.EatBlockGoal; 35import net.minecraft.world.entity.monster.Monster; 36import net.minecraft.world.item.ItemStack; 37import net.minecraft.world.level.Level; 38import net.minecraft.world.level.ServerLevelAccessor; 39import net.minecraft.world.level.block.Blocks; 40import net.minecraft.world.level.block.state.BlockState; 41import net.minecraft.world.level.storage.loot.LootTable; 42import org.jspecify.annotations.Nullable; 43import java.util.*; 44import java.util.function.Supplier; 45 46public class ChaosPawn extends AbstractChessFigure { 47 48 public static final EntityDataAccessor<HumanoidColors> colors = SynchedEntityData.defineId(ChaosPawn.class, ModEntityDataSerializers.HUMANOID_COLORS); 49 public static final EntityDataAccessor<Integer> special_case = SynchedEntityData.defineId(ChaosPawn.class, EntityDataSerializers.INT); 50 51 public ChaosPawn(EntityType<? extends ChaosPawn> entityType, Level world) { 52 super(entityType, world); 53 } 54 public void setColors(HumanoidColors i) { 55 this.entityData.set(colors, i); 56 } 57 public HumanoidColors getColors() { 58 return this.entityData.get(colors); 59 } 60 61 public static AttributeSupplier.Builder createAttributes() { 62 return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 5.0) 63 .add(Attributes.FOLLOW_RANGE, 35.0) 64 //? if >1.21 65 .add(Attributes.SCALE, 0.9) 66 .add(Attributes.MOVEMENT_SPEED, 0.25F); 67 } 68 @Override 69 protected void defineSynchedData( 70 //? if >1.21 { 71 SynchedEntityData.Builder builder 72 //?} 73 ) { 74 super.defineSynchedData( 75 //? if >1.21 { 76 builder 77 //?} 78 ); 79 //? if <1.21 { 80 /*var builder = this.entityData; 81 *///?} 82 builder.define(colors, new HumanoidColors()); 83 builder.define(special_case, -1); 84 } 85 @Override 86 protected void registerGoals() { 87 super.registerGoals(); 88 this.goalSelector.addGoal(5, new EatBlockGoal(this)); 89 } 90 91 @Override 92 public void ate() { 93 super.ate(); 94 this.setAllColors(this.level().getBiome(this.blockPosition()).value().getGrassColor(this.getX(), this.getZ())); 95 } 96 97 @Override 98 public Component getTypeName() { 99 int i = getCase(); 100 return switch (i) { 101 case 0 -> Component.translatable("entity.infinity.pawn_black"); 102 case 1 -> Component.translatable("entity.infinity.pawn_white"); 103 default -> super.getTypeName(); 104 }; 105 } 106 107 public int getCase() { 108 return entityData.get(special_case); 109 } 110 111 @Override 112 public void addAdditionalSaveData( 113 //? if >1.21.2 { 114 ValueOutput 115 //?} else { 116 /*CompoundTag 117 *///?} 118 nbt) { 119 super.addAdditionalSaveData(nbt); 120 //? if >1.21.4 { 121 nbt.store("colors", HumanoidColors.CODEC, getColors()); 122 //?} else { 123 /*nbt.put("colors", getColors().encode()); 124 *///?} 125 nbt.putInt("case", getCase()); 126 } 127 @Override 128 public void readAdditionalSaveData( 129 //? if >1.21.2 { 130 ValueInput 131 //?} else { 132 /*CompoundTag 133 *///?} 134 nbt) { 135 super.readAdditionalSaveData(nbt); 136 //? if >1.21.4 { 137 this.setColors(nbt.read("colors", HumanoidColors.CODEC).orElse(new HumanoidColors())); 138 //?} else { 139 /*this.setColors(HumanoidColors.decode(nbt.getCompound("colors"))); 140 *///?} 141 this.entityData.set(special_case, NbtUtils.getInt(nbt, "case")); 142 } 143 144// @Override 145 public 146 //? if >1.21 { 147 ResourceKey<LootTable> 148 //?} else { 149 /*ResourceLocation 150 *///?} 151 getDefaultLootTable() { 152 ResourceLocation i = switch (getCase()) { 153 case 0 -> InfinityMethods.getId("entities/chaos_pawn_black"); 154 case 1 -> InfinityMethods.getId("entities/chaos_pawn_white"); 155 default -> { 156 boolean bl = RandomProvider.rule("pawnsCanDropIllegalItems"); 157 if (bl) yield VersionMethods.id(""); //loot is defined in dropEquipment instead 158 else yield VersionMethods.id(InfinityMod.provider.randomName(random, ConfigType.LOOT_TABLES)); 159 } 160 }; 161 //? if >1.21 { 162 return ResourceKey.create(Registries.LOOT_TABLE, i); 163 //?} else { 164 /*return i; 165 *///?} 166 } 167 168 public static HumanoidColors getColorSetup(Supplier<Integer> colorSupplier) { 169 HumanoidColors c = new HumanoidColors(); 170 Arrays.stream((new String[]{"body", "left_arm", "right_arm", "left_leg", "right_leg"})).forEach( 171 s -> c.putInt(s, colorSupplier.get())); 172 int head = colorSupplier.get(); 173 c.putInt("head", head); 174 c.putInt("hat", 0xFFFFFF ^ head); 175 return c; 176 } 177 178 public void setAllColors(int color) { 179 this.setColors(new HumanoidColors(color)); 180 } 181 182 @Override 183 public boolean isBlackOrWhite() { 184 return entityData.get(special_case) != -1 && !Iridescence.isUnderEffect(this); 185 } 186 187 public void initFromBlock(BlockState state) { 188 if (state.is(Blocks.WHITE_WOOL) || state.is(Blocks.WHITE_CONCRETE)) { 189 chess(true); 190 } 191 else if (state.is(Blocks.BLACK_WOOL) || state.is(Blocks.BLACK_CONCRETE)) { 192 chess(false); 193 } 194 else unchess(); 195 } 196 197 public void chess(boolean white) { 198 entityData.set(special_case, white ? 1 : 0); 199 setAllColors(white ? 0xFFFFFF : 0); 200 } 201 202 public void unchess() { 203 entityData.set(special_case, -1); 204 setColors(getColorSetup(() -> random.nextInt(16777216))); 205 } 206 207 @Override 208 @Nullable 209 public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, 210 211 //? if >1.21.2 { 212 net.minecraft.world.entity.EntitySpawnReason 213 //?} else { 214 /*net.minecraft.world.entity.MobSpawnType 215 *///?} 216 spawnReason, @Nullable SpawnGroupData entityData 217 //? if <1.21 { 218 /*,CompoundTag tag 219 *///?} 220 ) { 221 initFromBlock(world.getBlockState(this.blockPosition().below())); 222 double i = random.nextDouble() * 40; 223 Objects.requireNonNull(this.getAttribute(Attributes.MAX_HEALTH)).setBaseValue(i); 224 this.setHealth((float)i); 225 return super.finalizeSpawn(world, difficulty, spawnReason, entityData 226 //? if <1.21 227 /*,tag*/ 228 ); 229 } 230 231 //? if >1.21 { 232 @Override 233 protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) { 234 super.dropCustomDeathLoot(world, source, causedByPlayer); 235 //?} else { 236 /*@Override 237 protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) { 238 super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops); 239 *///?} 240 dropLootInternal(); 241 } 242 243 protected void dropLootInternal() { 244 if (!this.isBlackOrWhite() && RandomProvider.rule("pawnsCanDropIllegalItems")) { 245 String s = InfinityMod.provider.randomName(random, ConfigType.ITEMS); 246 double i = Objects.requireNonNull(this.getAttribute(Attributes.MAX_HEALTH)).getBaseValue() / 10; 247 ItemStack stack = VersionMethods.getItem(s).getDefaultInstance().copyWithCount((int) (i * i)); 248 //? if >1.21 { 249 stack.applyComponents(DataComponentMap.builder().set(DataComponents.MAX_STACK_SIZE, 64).build()); 250 //?} 251 this.spawnAtLocation( 252 //? if >1.21.2 { 253 (ServerLevel) this.level(), 254 //?} 255 stack); 256 } 257 } 258}