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