Skip to content

Commit

Permalink
Multiple tweaks to flower spreading.
Browse files Browse the repository at this point in the history
  • Loading branch information
MerchantPug committed Dec 6, 2024
1 parent a30b8f1 commit d8d6ca1
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 22 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
## Changes
- Removed distance restriction on custom block renderers.
- Updated Moobloom Spawn Egg to match Minecraft Earth's spawn egg.
- Updated Moobloom Spawn Egg to match Minecraft Earth's spawn egg.
- Allowed Mooblooms to spawn flowers every 4 seconds that a flower hasn't been placed if they are not moving enough.
- Added a plant sound whenever Mooblooms plant flowers.
- Mooblooms now emit game events when planting flowers.

## Bugfixes
- Fixed Mooblooms spreading flowers immediately upon feeding them bone meal.
- Fixed Mooblooms being able to spread flowers on blocks where flowers cannot be placed.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package house.greenhouse.bovinesandbuttercups.gradle

object Versions {
const val MOD = "2.0.0"
const val MOD = "2.0.1"

// Minecraft
const val MINECRAFT = "1.21.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package house.greenhouse.bovinesandbuttercups.content.block.entity;

import house.greenhouse.bovinesandbuttercups.content.entity.Moobloom;
import house.greenhouse.bovinesandbuttercups.mixin.DefaultDispenseItemBehaviorAccessor;
import net.minecraft.core.BlockPos;
import net.minecraft.core.dispenser.BlockSource;
import net.minecraft.core.dispenser.DispenseItemBehavior;
import net.minecraft.core.dispenser.OptionalDispenseItemBehavior;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.phys.AABB;

import java.util.List;

public class MoobloomEatDispenseBehavior extends OptionalDispenseItemBehavior {
public static final MoobloomEatDispenseBehavior INSTANCE = new MoobloomEatDispenseBehavior(DispenserBlock.DISPENSER_REGISTRY.get(Items.BONE_MEAL));
private final DispenseItemBehavior boneMealBehavior;

protected MoobloomEatDispenseBehavior(DispenseItemBehavior boneMealBehavior) {
this.boneMealBehavior = boneMealBehavior;
}

public static void registerBehavior(MoobloomEatDispenseBehavior behavior) {
DispenserBlock.registerBehavior(Items.BONE_MEAL, behavior);
}

@Override
public ItemStack execute(BlockSource source, ItemStack stack) {
setSuccess(true);
if (handleMoobloom(source, stack)) {
return stack;
}

if (boneMealBehavior instanceof OptionalDispenseItemBehavior optional) {
((DefaultDispenseItemBehaviorAccessor)optional).bovinesandbuttercups$invokeExecute(source, stack);
if (!optional.isSuccess())
setSuccess(false);
return stack;
}

boneMealBehavior.dispense(source, stack);
return stack;
}

private boolean handleMoobloom(BlockSource source, ItemStack stack) {
ServerLevel level = source.level();
BlockPos relativePos = source.pos().relative(source.state().getValue(DispenserBlock.FACING));
List<Moobloom> mooblooms = level.getEntitiesOfClass(Moobloom.class, new AABB(relativePos), EntitySelector.NO_SPECTATORS);

if (mooblooms.isEmpty())
return false;
else {
for (Moobloom moobloom : mooblooms) {
moobloom.feed();
stack.shrink(1);
}

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
Expand Down Expand Up @@ -92,11 +93,15 @@ public class Moobloom extends Cow {
private static final EntityDataAccessor<Boolean> ALLOW_CONVERSION = SynchedEntityData.defineId(Moobloom.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Boolean> HAS_SNOW = SynchedEntityData.defineId(Moobloom.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Boolean> SNOW_LAYER_PERSISTENT = SynchedEntityData.defineId(Moobloom.class, EntityDataSerializers.BOOLEAN);

public static final int TICKS_UNTIL_SPREAD = 80;

@Nullable
public Bee bee;
private boolean hasRefreshedDimensionsForLaying;
@Nullable
private BlockPos previousPos = null;
private int ticksUntilSpread = -1;
@Nullable private UUID lastLightningBoltUUID;
private final Map<Holder<CowType<?>>, List<Vec3>> particlePositions = new HashMap<>();

Expand Down Expand Up @@ -131,6 +136,9 @@ public void registerGoals() {
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.putInt("flower_spread_attempts", getFlowerSpreadAttempts());
if (previousPos != null)
tag.put("previous_flower_pos", BlockPos.CODEC.encodeStart(NbtOps.INSTANCE, previousPos).getOrThrow());
tag.putInt("ticks_until_spread", ticksUntilSpread);
tag.putInt("pollinated_reset_ticks", getPollinatedResetTicks());
tag.putBoolean("allow_shearing", shouldAllowShearing());
tag.putBoolean("allow_conversion", shouldAllowConversion());
Expand All @@ -145,6 +153,10 @@ public void readAdditionalSaveData(CompoundTag tag) {
backwardsCompat(tag);
if (tag.contains("flower_spread_attempts", Tag.TAG_INT))
setFlowerSpreadAttempts(tag.getInt("flower_spread_attempts"));
if (tag.contains("previous_flower_pos", Tag.TAG_INT_ARRAY))
previousPos = BlockPos.CODEC.decode(NbtOps.INSTANCE, tag.get("previous_flower_pos")).getOrThrow().getFirst();
if (tag.contains("ticks_until_spread", Tag.TAG_INT))
ticksUntilSpread = tag.getInt("ticks_until_spread");
if (tag.contains("pollinated_reset_ticks", Tag.TAG_INT))
setPollinatedResetTicks(tag.getInt("pollinated_reset_ticks"));
if (tag.contains("allow_shearing", Tag.TAG_BYTE))
Expand Down Expand Up @@ -264,12 +276,21 @@ else if (layDownAnimationState.isStarted() && getStandingStillForBeeTicks() == 0
if (getUpAnimationState.isStarted() && getUpAnimationState.getAccumulatedTime() >= 1000)
getUpAnimationState.stop();
} else {
if ((previousPos == null || blockPosition().distSqr(previousPos) > 4) && getFlowerSpreadAttempts() > 0) {
if (spreadFlowers())
if (ticksUntilSpread > 0)
--ticksUntilSpread;

if ((previousPos == null || blockPosition().distSqr(previousPos) > 4 || ticksUntilSpread == 0) && getFlowerSpreadAttempts() > 0) {
if (spreadFlowers()) {
level().playSound(null, blockPosition(), BovinesSoundEvents.MOOBLOOM_PLANT, getSoundSource(), 1.0F, (random.nextFloat() * 0.2F) + 0.9F);
gameEvent(GameEvent.ENTITY_ACTION);
setFlowerSpreadAttempts(getFlowerSpreadAttempts() - 1);
previousPos = blockPosition();
if (getFlowerSpreadAttempts() <= 0)
ticksUntilSpread = TICKS_UNTIL_SPREAD;
previousPos = blockPosition();
}
if (getFlowerSpreadAttempts() <= 0) {
previousPos = null;
ticksUntilSpread = -1;
}
}

if (bee != null && !bee.isAlive()) {
Expand All @@ -287,10 +308,11 @@ else if (layDownAnimationState.isStarted() && getStandingStillForBeeTicks() == 0
setSnow(false);
BovinesAndButtercups.getHelper().sendTrackingClientboundPacket(this, new SyncMoobloomSnowLayerClientboundPacket(getId(), false));
}

if (getPollinatedResetTicks() > 0)
setPollinatedResetTicks(getPollinatedResetTicks() - 1);
}

if (getPollinatedResetTicks() > 0)
setPollinatedResetTicks(getPollinatedResetTicks() - 1);

if (getStandingStillForBeeTicks() > 0) {
if (!hasRefreshedDimensionsForLaying) {
Expand Down Expand Up @@ -363,7 +385,7 @@ else if (getCowType().value().configuration().flower().customType().isPresent())
}

public void setBlockToFlower(BlockState state, BlockPos pos) {
if (level().isClientSide) return;
if (level().isClientSide || !state.canSurvive(level(), pos.below())) return;
((ServerLevel) level()).sendParticles(ParticleTypes.HAPPY_VILLAGER, pos.getX() + 0.5D, pos.getY() + 0.3D, pos.getZ() + 0.5D, 4, 0.2, 0.1, 0.2, 0.0);
if (state.getBlock() == BovinesBlocks.CUSTOM_FLOWER && getCowType().value().configuration().flower().customType().isPresent()) {
level().setBlock(pos, state, Block.UPDATE_ALL);
Expand All @@ -389,15 +411,10 @@ public EntityDimensions getDefaultDimensions(Pose pose) {
public InteractionResult mobInteract(Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
if (!isBaby()) {
if (stack.is(Items.BONE_MEAL) && getFlowerSpreadAttempts() < 8) {
if (stack.is(Items.BONE_MEAL) && feed()) {
if (!player.getAbilities().instabuild) {
stack.shrink(1);
}
if (!level().isClientSide) {
((ServerLevel) level()).sendParticles(ParticleTypes.HAPPY_VILLAGER, position().x(), position().y() + 1.6D, position().z(), 8, 0.5, 0.1, 0.4, 0.0);
setFlowerSpreadAttempts(getFlowerSpreadAttempts() + 8);
}
playSound(BovinesSoundEvents.MOOBLOOM_EAT, 1.0f, (random.nextFloat() * 0.4F) + 0.8F);
return InteractionResult.sidedSuccess(level().isClientSide);
} else if (stack.is(Items.BOWL)) {
ItemStack stack2;
Expand All @@ -420,6 +437,19 @@ public InteractionResult mobInteract(Player player, InteractionHand hand) {
return super.mobInteract(player, hand);
}

public boolean feed() {
if (getFlowerSpreadAttempts() >= 8)
return false;
if (!level().isClientSide) {
((ServerLevel) level()).sendParticles(ParticleTypes.HAPPY_VILLAGER, position().x(), position().y() + 1.6D, position().z(), 8, 0.5, 0.1, 0.4, 0.0);
previousPos = blockPosition();
ticksUntilSpread = TICKS_UNTIL_SPREAD;
setFlowerSpreadAttempts(getFlowerSpreadAttempts() + 8);
}
playSound(BovinesSoundEvents.MOOBLOOM_EAT, 1.0f, (random.nextFloat() * 0.4F) + 0.8F);
return true;
}

public Pair<Holder<CowType<MoobloomConfiguration>>, Optional<Holder<CowType<MoobloomConfiguration>>>> chooseBabyType(ServerLevel level, Moobloom otherParent, Moobloom child) {
List<Holder<CowType<MoobloomConfiguration>>> eligibleCowTypes = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ public class BovinesSoundEvents {
public static final SoundEvent MOOBLOOM_MILK = SoundEvent.createVariableRangeEvent(BovinesAndButtercups.asResource("entity.moobloom.milk"));
public static final SoundEvent MOOBLOOM_SHEAR = SoundEvent.createVariableRangeEvent(BovinesAndButtercups.asResource("entity.moobloom.shear"));
public static final SoundEvent MOOBLOOM_CONVERT = SoundEvent.createVariableRangeEvent(BovinesAndButtercups.asResource("entity.moobloom.convert"));
public static final SoundEvent MOOBLOOM_PLANT = SoundEvent.createVariableRangeEvent(BovinesAndButtercups.asResource("entity.moobloom.plant"));
public static Holder<SoundEvent> EQUIP_FLOWER_CROWN;

public static void registerAll(RegistrationCallback<SoundEvent> callback) {
callback.register(BuiltInRegistries.SOUND_EVENT, BovinesAndButtercups.asResource("entity.moobloom.eat"), MOOBLOOM_EAT);
callback.register(BuiltInRegistries.SOUND_EVENT, BovinesAndButtercups.asResource("entity.moobloom.milk"), MOOBLOOM_MILK);
callback.register(BuiltInRegistries.SOUND_EVENT, BovinesAndButtercups.asResource("entity.moobloom.shear"), MOOBLOOM_SHEAR);
callback.register(BuiltInRegistries.SOUND_EVENT, BovinesAndButtercups.asResource("entity.moobloom.convert"), MOOBLOOM_CONVERT);
callback.register(BuiltInRegistries.SOUND_EVENT, BovinesAndButtercups.asResource("entity.moobloom.plant"), MOOBLOOM_PLANT);
}

public static void registerHolders(HolderRegistrationCallback<SoundEvent> callback) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package house.greenhouse.bovinesandbuttercups.mixin;

import net.minecraft.core.dispenser.BlockSource;
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(DefaultDispenseItemBehavior.class)
public interface DefaultDispenseItemBehaviorAccessor {
@Invoker("execute")
ItemStack bovinesandbuttercups$invokeExecute(BlockSource blockSource, ItemStack item);
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"subtitles.entity.bovinesandbuttercups.moobloom.convert": "Moobloom transforms",
"subtitles.entity.bovinesandbuttercups.moobloom.eat": "Moobloom eats",
"subtitles.entity.bovinesandbuttercups.moobloom.milk": "Moobloom gets milked",
"subtitles.entity.bovinesandbuttercups.moobloom.plant": "Moobloom plants",

"effect.bovinesandbuttercups.lockdown": "Lockdown",
"potion.bovinesandbuttercups.lockdown": "Lockdown (%s) (%s)",
Expand Down
18 changes: 12 additions & 6 deletions common/src/main/resources/assets/bovinesandbuttercups/sounds.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,33 @@
"subtitle": "subtitles.entity.bovinesandbuttercups.moobloom.convert"
},
"entity.moobloom.eat": {
"subtitle": "subtitles.entity.bovinesandbuttercups.moobloom.eat",
"sounds": [
"mob/mooshroom/eat1",
"mob/mooshroom/eat2",
"mob/mooshroom/eat3",
"mob/mooshroom/eat4"
]
],
"subtitle": "subtitles.entity.bovinesandbuttercups.moobloom.eat"
},
"entity.moobloom.milk": {
"subtitle": "subtitles.entity.bovinesandbuttercups.moobloom.milk",
"sounds": [
"bovinesandbuttercups:mob/moobloom/milk1",
"bovinesandbuttercups:mob/moobloom/milk2",
"bovinesandbuttercups:mob/moobloom/milk3"
]
],
"subtitle": "subtitles.entity.bovinesandbuttercups.moobloom.milk"
},
"entity.moobloom.shear": {
"subtitle": "subtitles.item.shears.shear",
"sounds": [
"mob/sheep/shear"
]
],
"subtitle": "subtitles.item.shears.shear"
},
"entity.moobloom.plant": {
"sounds": [
"bovinesandbuttercups:mob/moobloom/plant"
],
"subtitle": "subtitles.entity.bovinesandbuttercups.moobloom.plant"
},
"item.armor.equip_flower_crown": {
"sounds": [
Expand Down
Binary file not shown.
3 changes: 2 additions & 1 deletion common/src/main/resources/bovinesandbuttercups.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
"BeePollinateGoalMixin",
"BodyRotationControlMixin",
"ChunkGeneratorMixin",
"CowSuperMixin",
"DefaultDispenseItemBehaviorAccessor",
"EntityAccessor",
"EntityDataAccessorMixin",
"CowSuperMixin",
"FarmBlockMixin",
"FlowerPotBlockMixin",
"HoneyBlockAccessor",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import house.greenhouse.bovinesandbuttercups.access.MooshroomInitializedTypeAccess;
import house.greenhouse.bovinesandbuttercups.api.cowtype.CowModelLayer;
import house.greenhouse.bovinesandbuttercups.api.cowtype.modifier.TextureModifierFactory;
import house.greenhouse.bovinesandbuttercups.content.block.entity.MoobloomEatDispenseBehavior;
import house.greenhouse.bovinesandbuttercups.content.command.BovinesCommands;
import house.greenhouse.bovinesandbuttercups.content.recipe.ingredient.BovinesIngredients;
import house.greenhouse.bovinesandbuttercups.integration.accessories.BovinesAccessoriesEvents;
Expand Down Expand Up @@ -87,6 +88,7 @@ public void onInitialize() {
registerCompostables();
registerBiomeModifications();
registerResourcePacks();
MoobloomEatDispenseBehavior.registerBehavior(MoobloomEatDispenseBehavior.INSTANCE);

EntityTrackingEvents.START_TRACKING.register((entity, player) -> {
if (entity instanceof LivingEntity living) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import house.greenhouse.bovinesandbuttercups.api.cowtype.modifier.TextureModifierFactory;
import house.greenhouse.bovinesandbuttercups.content.advancement.criterion.LockEffectTrigger;
import house.greenhouse.bovinesandbuttercups.content.advancement.criterion.PreventEffectTrigger;
import house.greenhouse.bovinesandbuttercups.content.block.entity.MoobloomEatDispenseBehavior;
import house.greenhouse.bovinesandbuttercups.content.command.BovinesCommands;
import house.greenhouse.bovinesandbuttercups.content.effect.LockdownEffect;
import house.greenhouse.bovinesandbuttercups.content.entity.Moobloom;
Expand Down Expand Up @@ -68,6 +69,7 @@
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.event.AddPackFindersEvent;
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
Expand Down Expand Up @@ -100,6 +102,11 @@ public BovinesAndButtercupsNeoForge(IEventBus eventBus) {

@EventBusSubscriber(modid = BovinesAndButtercups.MOD_ID, bus = EventBusSubscriber.Bus.GAME)
public static class GameEvents {
@SubscribeEvent
public static void onCommonSetup(FMLCommonSetupEvent event) {
MoobloomEatDispenseBehavior.registerBehavior(MoobloomEatDispenseBehavior.INSTANCE);
}

@SubscribeEvent
public static void registerCommands(RegisterCommandsEvent event) {
BovinesCommands.register(event.getDispatcher(), event.getBuildContext());
Expand Down

0 comments on commit d8d6ca1

Please sign in to comment.