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