Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 246 lines 9.6 kB view raw
1package net.lerariemann.infinity.entity.custom; 2 3import net.lerariemann.infinity.InfinityMod; 4import net.lerariemann.infinity.util.InfinityMethods; 5import net.lerariemann.infinity.util.VersionMethods; 6import net.lerariemann.infinity.util.core.ConfigType; 7import net.lerariemann.infinity.util.core.NbtUtils; 8import net.minecraft.MethodsReturnNonnullByDefault; 9import net.minecraft.core.BlockPos; 10import net.minecraft.core.particles.DustParticleOptions; 11import net.minecraft.core.particles.ParticleOptions; 12import net.minecraft.core.registries.BuiltInRegistries; 13import net.minecraft.nbt.CompoundTag; 14import net.minecraft.network.syncher.EntityDataAccessor; 15import net.minecraft.network.syncher.EntityDataSerializers; 16import net.minecraft.network.syncher.SynchedEntityData; 17import net.minecraft.resources.ResourceKey; 18import net.minecraft.resources.ResourceLocation; 19import net.minecraft.server.level.ServerLevel; 20import net.minecraft.sounds.SoundEvent; 21import net.minecraft.world.*; 22import net.minecraft.world.damagesource.DamageSource; 23import net.minecraft.world.entity.EntityType; 24import net.minecraft.world.entity.SpawnGroupData; 25import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 26import net.minecraft.world.entity.ai.attributes.Attributes; 27import net.minecraft.world.entity.monster.Monster; 28import net.minecraft.world.entity.monster.Slime; 29import net.minecraft.world.entity.player.Player; 30import net.minecraft.world.item.ItemStack; 31import net.minecraft.world.level.Level; 32import net.minecraft.world.level.LevelReader; 33import net.minecraft.world.level.ServerLevelAccessor; 34import net.minecraft.world.level.WorldGenLevel; 35import net.minecraft.world.level.block.Block; 36import net.minecraft.world.level.block.Blocks; 37import net.minecraft.world.level.block.state.BlockState; 38//? if >1.21.4 { 39import net.minecraft.world.level.storage.ValueInput; 40import net.minecraft.world.level.storage.ValueOutput; 41//?} 42import net.minecraft.world.level.storage.loot.LootParams; 43import net.minecraft.world.level.storage.loot.LootTable; 44import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; 45import net.minecraft.world.level.storage.loot.parameters.LootContextParams; 46import org.jetbrains.annotations.Nullable; 47 48//? if neoforge { 49/*import javax.annotation.ParametersAreNonnullByDefault; 50*///?} 51import java.util.Optional; 52import java.util.Random; 53import java.util.function.BiConsumer; 54import java.util.function.Function; 55 56@MethodsReturnNonnullByDefault 57//? if neoforge { 58/*@ParametersAreNonnullByDefault 59*///?} 60public class ChaosSlime extends Slime implements TintableEntity { 61 public static final EntityDataAccessor<BlockState> core = SynchedEntityData.defineId(ChaosSlime.class, EntityDataSerializers.BLOCK_STATE); 62 public static final EntityDataAccessor<Integer> color = SynchedEntityData.defineId(ChaosSlime.class, EntityDataSerializers.INT); 63 64 public ChaosSlime(EntityType<? extends ChaosSlime> entityType, Level world) { 65 super(entityType, world); 66 } 67 68 @Override 69 public int getColorNamed() { 70 return hasCustomName() ? TintableEntity.getColorNamed(getName().getString(), tickCount, getId()) : -1; 71 } 72 73 @Override 74 protected void defineSynchedData( 75 //? if >1.21 { 76 SynchedEntityData.Builder builder 77 //?} 78 ) { 79 super.defineSynchedData( 80 //? if >1.21 { 81 builder 82 //?} 83 ); 84 //? if <1.21 { 85 /*var builder = this.entityData; 86 *///?} 87 builder.define(core, Blocks.STONE.defaultBlockState()); 88 builder.define(color, 0); 89 } 90 91 public static AttributeSupplier.Builder createAttributes() { 92 return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2f); 93 } 94 95 @Override 96 @Nullable 97 public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, 98 //? if >1.21.2 { 99 net.minecraft.world.entity.EntitySpawnReason 100 //?} else { 101 /*net.minecraft.world.entity.MobSpawnType 102 *///?} 103 spawnReason, @Nullable SpawnGroupData entityData 104 //? if <1.21 { 105 /*,CompoundTag tag 106 *///?} 107 ) { 108 Random r = InfinityMod.random; 109 this.entityData.set(core, VersionMethods.getFromRegistry(BuiltInRegistries.BLOCK, VersionMethods.id(InfinityMod.provider.randomName(r, ConfigType.ALL_BLOCKS))).defaultBlockState()); 110 this.entityData.set(color, r.nextInt(16777216)); 111 SpawnGroupData res = super.finalizeSpawn(world, difficulty, spawnReason, entityData 112 //? if <1.21 113 /*, tag*/ 114 ); 115 this.setSize(1 << r.nextInt(3), true); 116 return res; 117 } 118 119 @Override 120 public boolean checkSpawnObstruction(LevelReader world) { 121 return world.isUnobstructed(this); 122 } 123 124 public void setColor(int c) { 125 this.entityData.set(color, c); 126 } 127 @Override 128 public int getColor() { 129 return this.entityData.get(color); 130 } 131 132 public void setCore(BlockState c) { 133 this.entityData.set(core, c); 134 } 135 public BlockState getCore() { 136 return this.entityData.get(core); 137 } 138 public BlockState getCoreForChild() { 139 return Blocks.AIR.defaultBlockState(); 140 } 141 142 @Override 143 protected ParticleOptions getParticleType() { 144 return new DustParticleOptions( 145 //? if >1.21.2 { 146 this.getColorForRender() 147 //?} else { 148 /*particleColorFromInt(this.getColorForRender()) 149 *///?} 150 , 1.0f); 151 } 152 @Override 153 protected SoundEvent getHurtSound(DamageSource source) { 154 return this.getCore().getSoundType().getHitSound(); 155 } 156 @Override 157 protected SoundEvent getDeathSound() { 158 return this.getCore().getSoundType().getBreakSound(); 159 } 160 @Override 161 protected SoundEvent getSquishSound() { 162 return this.getCore().getSoundType().getStepSound(); 163 } 164 @Override 165 protected SoundEvent getJumpSound() { 166 return this.getCore().getSoundType().getFallSound(); 167 } 168 169 public 170 //? if >1.21.4 { 171 Optional<ResourceKey<LootTable>> 172 //?} else if >1.21 { 173 /*ResourceKey<LootTable> 174 *///?} else { 175 /*ResourceLocation 176 *///?} 177 getDefaultLootTable() { 178 return this.getCore().getBlock().getLootTable(); 179 } 180 181 //? if >1.21.4 { 182 @Override 183 protected void dropFromLootTable(ServerLevel level, DamageSource damageSource, boolean playerKill) { 184 Optional<ResourceKey<LootTable>> optional = getDefaultLootTable(); 185 if (optional.isPresent()) { 186 LootTable loottable = level.getServer().reloadableRegistries().getLootTable(optional.get()); 187 LootParams.Builder lootparams$builder = new LootParams.Builder(level) 188 .withParameter(LootContextParams.THIS_ENTITY, this) 189 .withParameter(LootContextParams.ORIGIN, this.position()) 190 .withParameter(LootContextParams.DAMAGE_SOURCE, damageSource) 191 .withOptionalParameter(LootContextParams.ATTACKING_ENTITY, damageSource.getEntity()) 192 .withOptionalParameter(LootContextParams.DIRECT_ATTACKING_ENTITY, damageSource.getDirectEntity()); 193 Player player = this.getLastHurtByPlayer(); 194 if (playerKill && player != null) { 195 lootparams$builder = lootparams$builder.withParameter(LootContextParams.LAST_DAMAGE_PLAYER, player).withLuck(player.getLuck()); 196 } 197 198 LootParams lootparams = lootparams$builder.create(LootContextParamSets.ENTITY); 199 loottable.getRandomItems(lootparams, this.getLootTableSeed(), stack -> this.spawnAtLocation(level, stack)); 200 } 201 } 202 //?} 203 204 @Override 205 public void addAdditionalSaveData( 206 //? if >1.21.2 { 207 ValueOutput 208 //?} else { 209 /*CompoundTag 210 *///?} 211 nbt) { 212 super.addAdditionalSaveData(nbt); 213 nbt.putInt("color", getColor()); 214 nbt.putString("core", BuiltInRegistries.BLOCK.getKey(this.getCore().getBlock()).toString()); 215 } 216 217 @Override 218 public void readAdditionalSaveData( 219 //? if >1.21.2 { 220 ValueInput 221 //?} else { 222 /*CompoundTag 223 *///?} 224 nbt) { 225 super.readAdditionalSaveData(nbt); 226 this.setColor(NbtUtils.getInt(nbt, "color")); 227 Block b = VersionMethods.getBlock(VersionMethods.id(NbtUtils.getString(nbt,"core"))); 228 this.setCore(b.defaultBlockState()); 229 } 230 231 public static boolean canSpawn(EntityType<ChaosSlime> type, ServerLevelAccessor world, 232 //? if >1.21.2 { 233 net.minecraft.world.entity.EntitySpawnReason 234 //?} else { 235 /*net.minecraft.world.entity.MobSpawnType 236 *///?} 237 spawnReason, BlockPos pos, net.minecraft.util.RandomSource random) { 238 if (world.getDifficulty() != Difficulty.PEACEFUL && InfinityMethods.chaosMobsEnabled()) { 239 if (!(world instanceof WorldGenLevel)) { 240 return false; 241 } 242 return Slime.checkMobSpawnRules(type, world, spawnReason, pos, random); 243 } 244 return false; 245 } 246}