Skip to content

Commit

Permalink
Rewrote entity spawning logic to now specify entities for biomes.
Browse files Browse the repository at this point in the history
  • Loading branch information
LtxProgrammer committed Sep 16, 2024
1 parent d88ef2e commit 1e5bdf7
Show file tree
Hide file tree
Showing 17 changed files with 534 additions and 427 deletions.
36 changes: 24 additions & 12 deletions src/main/java/net/ltxprogrammer/changed/block/DarkLatexBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.ltxprogrammer.changed.init.ChangedGameRules;
import net.ltxprogrammer.changed.init.ChangedItems;
import net.ltxprogrammer.changed.item.AbstractLatexItem;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags;
Expand All @@ -26,18 +27,6 @@ public DarkLatexBlock(Properties p_49795_) {
super(p_49795_, LatexType.DARK_LATEX, ChangedItems.DARK_LATEX_GOO);
}

@Override
public void latexTick(@NotNull BlockState state, @NotNull ServerLevel level, @NotNull BlockPos position, @NotNull Random random) {
if (level.getGameRules().getInt(ChangedGameRules.RULE_LATEX_GROWTH_RATE) == 0 ||
random.nextInt(5000) > level.getGameRules().getInt(ChangedGameRules.RULE_LATEX_GROWTH_RATE))
return;

BlockPos above = position.above();
if (level.getBlockState(above).is(Blocks.AIR) && canSupportRigidBlock(level, position)) {
level.setBlockAndUpdate(above, ChangedBlocks.LATEX_CRYSTAL.get().defaultBlockState());
}
}

private static final List<Supplier<? extends TransfurCrystalBlock>> SMALL_CRYSTALS = List.of(
ChangedBlocks.LATEX_CRYSTAL,
ChangedBlocks.DARK_DRAGON_CRYSTAL,
Expand All @@ -51,6 +40,29 @@ public void latexTick(@NotNull BlockState state, @NotNull ServerLevel level, @No
ChangedBlocks.WOLF_CRYSTAL
);

@Override
public void latexTick(@NotNull BlockState state, @NotNull ServerLevel level, @NotNull BlockPos position, @NotNull Random random) {
if (level.getGameRules().getInt(ChangedGameRules.RULE_LATEX_GROWTH_RATE) == 0 ||
random.nextInt(5000) > level.getGameRules().getInt(ChangedGameRules.RULE_LATEX_GROWTH_RATE))
return;

BlockPos above = position.above();
BlockPos above2 = above.above();
boolean isAboveAir = level.getBlockState(above).is(Blocks.AIR);
boolean isAbove2Air = level.getBlockState(above2).is(Blocks.AIR);
if (isAboveAir && canSupportRigidBlock(level, position)) { // Do growth event
if (random.nextFloat() < 0.5f) return;

if (random.nextFloat() < 0.75f || !isAbove2Air) {
level.setBlockAndUpdate(above, Util.getRandom(SMALL_CRYSTALS, random).get().defaultBlockState());
} else {
final var newBlockState = Util.getRandom(CRYSTALS, random).get().defaultBlockState();
level.setBlockAndUpdate(above, newBlockState.setValue(AbstractDoubleTransfurCrystal.HALF, DoubleBlockHalf.LOWER));
level.setBlockAndUpdate(above2, newBlockState.setValue(AbstractDoubleTransfurCrystal.HALF, DoubleBlockHalf.UPPER));
}
}
}

@SubscribeEvent
public static void onLatexCover(AbstractLatexItem.CoveringBlockEvent event) {
if (event.latexType != LatexType.DARK_LATEX)
Expand Down
22 changes: 15 additions & 7 deletions src/main/java/net/ltxprogrammer/changed/entity/ChangedEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.Blocks;
Expand Down Expand Up @@ -386,15 +387,22 @@ public static boolean isDarkEnoughToSpawn(ServerLevelAccessor world, BlockPos po
}

public static <T extends ChangedEntity> boolean checkEntitySpawnRules(EntityType<T> entityType, ServerLevelAccessor world, MobSpawnType reason, BlockPos pos, Random random) {
if (world.getDifficulty() == Difficulty.PEACEFUL)
/*if (!isDarkEnoughToSpawn(world, pos, random))
return false;*/
if (pos.getY() < world.getSeaLevel() - 10)
return false;
if (!isDarkEnoughToSpawn(world, pos, random))
if (random.nextFloat() < 0.75f)
return false;
return Mob.checkMobSpawnRules(entityType, world, reason, pos, random);
return Monster.checkAnyLightMonsterSpawnRules(entityType, world, reason, pos, random);
}

public static <T extends ChangedEntity> ChangedEntities.VoidConsumer getInit(RegistryObject<EntityType<T>> registryObject, SpawnPlacements.Type spawnPlacement) {
return () -> SpawnPlacements.register(registryObject.get(), spawnPlacement, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, ChangedEntity::checkEntitySpawnRules);
@Override
public float getWalkTargetValue(BlockPos p_33013_, LevelReader p_33014_) {
return 0.0f;
}

public static <T extends ChangedEntity> ChangedEntities.VoidConsumer getInit(RegistryObject<EntityType<T>> registryObject, SpawnPlacements.Type spawnPlacement, SpawnPlacements.SpawnPredicate<T> spawnPredicate) {
return () -> SpawnPlacements.register(registryObject.get(), spawnPlacement, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, spawnPredicate);
}

public TransfurVariant<?> getTransfurVariant() {
Expand Down Expand Up @@ -724,7 +732,7 @@ else if (entity instanceof Player victimPlayer) {
}

public boolean tryTransfurTarget(Entity entity) {
if (this.getType().is(ChangedTags.EntityTypes.ORGANIC_LATEX))
if (!this.getType().is(ChangedTags.EntityTypes.LATEX))
return false;

float damage = (float)maybeGetUnderlying().getAttributeValue(ChangedAttributes.TRANSFUR_DAMAGE.get());
Expand Down Expand Up @@ -785,7 +793,7 @@ else if (this instanceof AbstractDarkLatexEntity)
this.targetSelector.addGoal(1, new HurtByTargetGoal(this));

this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, ChangedEntity.class, true, this::targetSelectorTest));
if (!(this.getType().is(ChangedTags.EntityTypes.ORGANIC_LATEX))) {
if (this.getType().is(ChangedTags.EntityTypes.LATEX)) {
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true, this::targetSelectorTest));
this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, LivingEntity.class, true, this::targetSelectorTest));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,57 @@
import net.ltxprogrammer.changed.entity.LatexType;
import net.ltxprogrammer.changed.entity.TransfurMode;
import net.ltxprogrammer.changed.util.Color3;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.Mth;
import net.minecraft.world.Difficulty;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.ai.goal.RandomSwimmingGoal;
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation;
import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.NotNull;

import java.util.Random;

public abstract class AbstractAquaticEntity extends ChangedEntity implements AquaticEntity {
protected final WaterBoundPathNavigation waterNavigation;
protected final GroundPathNavigation groundNavigation;

public static <T extends ChangedEntity> boolean checkEntitySpawnRules(EntityType<T> entityType, ServerLevelAccessor world, MobSpawnType reason, BlockPos pos, Random random) {
/*if (!isDarkEnoughToSpawn(world, pos, random))
return false;*/
if (!world.canSeeSkyFromBelowWater(pos))
return false;
if (random.nextFloat() < 0.75f)
return false;
return Monster.checkAnyLightMonsterSpawnRules(entityType, world, reason, pos, random);
}

@Override
public boolean checkSpawnRules(LevelAccessor level, MobSpawnType spawnType) {
return true;
}

@Override
public boolean checkSpawnObstruction(LevelReader level) {
return level.isUnobstructed(this);
}

public AbstractAquaticEntity(EntityType<? extends AbstractAquaticEntity> p_19870_, Level p_19871_) {
super(p_19870_, p_19871_);
this.moveControl = new AbstractAquaticEntity.AquaticMoveControl(this);
Expand All @@ -52,16 +80,6 @@ public MobType getMobType() {
return MobType.UNDEFINED;
}

@Override
public SoundEvent getHurtSound(DamageSource ds) {
return ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("entity.generic.hurt"));
}

@Override
public SoundEvent getDeathSound() {
return ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("entity.generic.death"));
}

@Override
public boolean canBreatheUnderwater() { return true; }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.ltxprogrammer.changed.entity.beast;

import net.ltxprogrammer.changed.entity.ChangedEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;

import java.util.Random;

public abstract class AbstractCaveEntity extends ChangedEntity {
public AbstractCaveEntity(EntityType<? extends ChangedEntity> type, Level level) {
super(type, level);
}

public static <T extends ChangedEntity> boolean checkEntitySpawnRules(EntityType<T> entityType, ServerLevelAccessor world, MobSpawnType reason, BlockPos pos, Random random) {
if (!isDarkEnoughToSpawn(world, pos, random))
return false;
if (pos.getY() > world.getSeaLevel() - 10)
return false;
if (random.nextFloat() < 0.75f)
return false;
return Monster.checkAnyLightMonsterSpawnRules(entityType, world, reason, pos, random);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,7 @@

import java.util.Random;

@Mod.EventBusSubscriber
public abstract class AbstractLatexShark extends AbstractAquaticEntity {
@SubscribeEvent
public static void canEntitySpawn(LivingSpawnEvent.CheckSpawn event) {
if (event.getEntityLiving() instanceof AquaticEntity && event.getSpawnReason() == MobSpawnType.NATURAL)
event.setResult(Event.Result.ALLOW);
}

public AbstractLatexShark(EntityType<? extends AbstractLatexShark> p_19870_, Level p_19871_) {
super(p_19870_, p_19871_);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,6 @@ public MobType getMobType() {
return MobType.UNDEFINED;
}

@Override
public SoundEvent getHurtSound(DamageSource ds) {
return ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("entity.generic.hurt"));
}

@Override
public SoundEvent getDeathSound() {
return ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("entity.generic.death"));
}

@Override
public void addAdditionalSaveData(CompoundTag p_20139_) {
super.addAdditionalSaveData(p_20139_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@

import net.ltxprogrammer.changed.entity.*;
import net.ltxprogrammer.changed.util.Color3;
import net.minecraft.core.BlockPos;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.MobType;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.ForgeMod;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Random;

public class LatexStiger extends ChangedEntity {
public class LatexStiger extends AbstractCaveEntity {
private static final EntityDataAccessor<Byte> DATA_FLAGS_ID = SynchedEntityData.defineId(LatexStiger.class, EntityDataSerializers.BYTE);
public LatexStiger(EntityType<? extends LatexStiger> p_19870_, Level p_19871_) {
super(p_19870_, p_19871_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@

import net.ltxprogrammer.changed.entity.*;
import net.ltxprogrammer.changed.util.Color3;
import net.minecraft.core.BlockPos;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraftforge.common.ForgeMod;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Random;

public class LatexTrafficConeDragon extends ChangedEntity {
public class LatexTrafficConeDragon extends AbstractCaveEntity {
public LatexTrafficConeDragon(EntityType<? extends LatexTrafficConeDragon> p_19870_, Level p_19871_) {
super(p_19870_, p_19871_);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@

import net.ltxprogrammer.changed.entity.*;
import net.ltxprogrammer.changed.util.Color3;
import net.minecraft.core.BlockPos;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraftforge.common.ForgeMod;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Random;

public class LatexTranslucentLizard extends ChangedEntity {
public class LatexTranslucentLizard extends AbstractCaveEntity {
public LatexTranslucentLizard(EntityType<? extends LatexTranslucentLizard> p_19870_, Level p_19871_) {
super(p_19870_, p_19871_);
}
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/net/ltxprogrammer/changed/init/ChangedBiomes.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.minecraft.data.worldgen.features.FeatureUtils;
import net.minecraft.data.worldgen.placement.PlacementUtils;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Mth;
import net.minecraft.world.level.biome.Biome;
Expand Down Expand Up @@ -44,16 +45,22 @@
public class ChangedBiomes {
public static final Climate.Parameter FULL_RANGE = Climate.Parameter.span(-1.0f, 1.0f);

public record BiomeHolder<T extends ChangedBiomeInterface>(T biomeInterface, RegistryObject<Biome> registryObject) {
public ResourceLocation getId() {
return registryObject.getId();
}
}

public static final Map<RegistryObject<Biome>, ChangedBiomeInterface> DESCRIPTORS = new HashMap<>();
public static final DeferredRegister<Biome> REGISTRY = DeferredRegister.create(ForgeRegistries.BIOMES, Changed.MODID);
public static final RegistryObject<Biome> DARK_LATEX_PLAINS = register("dark_latex_plains", DarkLatexPlains::new);
public static final RegistryObject<Biome> WHITE_LATEX_FOREST = register("white_latex_forest", WhiteLatexForest::new);
public static final BiomeHolder<DarkLatexPlains> DARK_LATEX_PLAINS = register("dark_latex_plains", DarkLatexPlains::new);
public static final BiomeHolder<WhiteLatexForest> WHITE_LATEX_FOREST = register("white_latex_forest", WhiteLatexForest::new);

public static <T extends ChangedBiomeInterface> RegistryObject<Biome> register(String name, Supplier<T> supplier) {
ChangedBiomeInterface biomeDesc = supplier.get();
public static <T extends ChangedBiomeInterface> BiomeHolder<T> register(String name, Supplier<T> supplier) {
T biomeDesc = supplier.get();
RegistryObject<Biome> regObj = REGISTRY.register(name, biomeDesc::build);
DESCRIPTORS.put(regObj, biomeDesc);
return regObj;
return new BiomeHolder<>(biomeDesc, regObj);
}

public static int calculateSkyColor(float p_194844_) {
Expand Down
Loading

0 comments on commit 1e5bdf7

Please sign in to comment.