Posted March 27, 20223 yr Hello, I am wondering how I would add ambient sounds to "silent" mobs (such as iron golems, snow golems, and players). I was looking at this forum and I have some questions... Suppose I want to add ambient noises to iron golems. Do I have to use an event handler that takes in a TickEvent.ServerTickEvent argument? And In order to get all iron golems to be able to emit noises, how would I get a list of all registered iron golems? Edited April 2, 20223 yr by LeeCrafts
March 28, 20223 yr Author Update: Don't use this solution. See my bottom comment for a solution involving capabilities. My solution works, but for those who are asking the same questions, this is a bit more complex than we wish it to be. If you want to add ambient noises to iron golems for example, you would first need to store each iron golem's relevant data in a list. The relevant data includes its UUID string and tick counter (an int value initialized at 0). I recommend using an extra class for this! Now you must make two event handlers. One handles EntityJoinWorldEvent events, and it checks if event.getEntity() is an iron golem. If so, then add its data to the list. The other event handler handles LivingUpdateEvent events, which--as @diesieben07 mentioned--fires every tick (entities get updated every tick). Get the UUID of the entity being updated (event.getEntity().getStringUUID()), and search through the list to get the matching entity data, aka. the list entry containing the same UUID. Increment that entry's tick counter, and if it reaches an x amount of ticks, then play the noise and reset the counter. Side note: Your LivingUpdateEvent handler probably should check if the entity (iron golem) has died, and if it has, then remove its respective entry from the list. I hope my solution is not unnecessarily complicated. Edit: maybe hash maps are more efficient than lists, but I’ll have to check and come back later. Edited April 2, 20223 yr by LeeCrafts
April 2, 20223 yr Author I just made a working solution with capabilities and it was one hell of a learning experience. There were many tutorials I had to follow because they were mostly from earlier versions. Below is an example code for anyone else who wants to add ambient noises to silent mobs--and learn how to use custom capabilities. I attach a custom capability (TimeCounter) to iron golems, making each store their own time counter. The counter gets incremented every tick, and once it reaches a certain limit, the iron golem plays a sound and the counter is reset. // must have an interface public interface ITimeCounter { void incrementCounter(); void resetCounter(); void rollLimit(); } // ...and a class implementing the interface public class TimeCounter implements ITimeCounter { public int counter; // current tick counter public int limit; // number of ticks counter must reach for the sound to be played public TimeCounter() { counter = 0; rollLimit(); } @Override public void incrementCounter() { this.counter++; if (counter < 0) resetCounter(); } @Override public void resetCounter() { this.counter = 0; } @Override public void rollLimit() { // adds randomness to limit Random random = new Random(); this.limit = random.nextInt(100) + 100; } } // provides the capability public class TimeCounterProvider implements ICapabilitySerializable<CompoundTag> { private final TimeCounter timeCounter = new TimeCounter(); private final LazyOptional<ITimeCounter> timeCounterLazyOptional = LazyOptional.of(() -> timeCounter); @NotNull @Override public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) { return timeCounterLazyOptional.cast(); } // exclude serializeNBT() and deserializeNBT() if you don't need to persist the data // (in that case, also replace ICapabilitySerializable interface with ICapabilityProvider) @Override public CompoundTag serializeNBT() { if (ModCapabilities.TIME_COUNTER_CAPABILITY == null) { return new CompoundTag(); } CompoundTag nbt = new CompoundTag(); nbt.putInt("counter", timeCounter.counter); nbt.putInt("limit", timeCounter.limit); return nbt; } @Override public void deserializeNBT(CompoundTag nbt) { if (ModCapabilities.TIME_COUNTER_CAPABILITY != null) { timeCounter.counter = nbt.getInt("counter"); timeCounter.limit = nbt.getInt("limit"); } } // invalidates capability public void invalidate() { timeCounterLazyOptional.invalidate(); } } public class ModCapabilities { // instance of the capability public static Capability<ITimeCounter> TIME_COUNTER_CAPABILITY = CapabilityManager.get(new CapabilityToken<>(){}); // can put other capabilities here } @Mod.EventBusSubscriber(modid = MyMod.MOD_ID) public class ModEvents { // registers the capability @SubscribeEvent public void registerCapabilities(RegisterCapabilitiesEvent event) { event.register(ITimeCounter.class); } // attaches the capability to iron golems @SubscribeEvent public static void onAttachCapabilitiesEvent(AttachCapabilitiesEvent<Entity> event) { if (event.getObject() instanceof IronGolem && !event.getObject().getCommandSenderWorld().isClientSide) { TimeCounterProvider timeCounterProvider = new TimeCounterProvider(); event.addCapability(new ResourceLocation(MyMod.MOD_ID, "time_cap"), timeCounterProvider); event.addListener(timeCounterProvider::invalidate); } } // entities get updated every tick @SubscribeEvent public static void ironGolemSound(LivingEvent.LivingUpdateEvent event) { Entity entity = event.getEntity(); if (entity instanceof IronGolem && !entity.level.isClientSide()) { entity.getCapability(ModCapabilities.TIME_COUNTER_CAPABILITY).ifPresent(iTimeCounter -> { TimeCounter timeCounter = (TimeCounter) iTimeCounter; timeCounter.incrementCounter(); // when the counter reaches the limit, sound is played if (timeCounter.counter >= timeCounter.limit) { entity.playSound(ModSounds.IRON_GOLEM_GRUNT.get(), 1.0F, 1.0F); // entity.level.playSound(null, entity.getX(), entity.getY(), entity.getZ(), ModSounds.IRON_GOLEM_GRUNT.get(), SoundSource.AMBIENT, 1.0F, 1.0F); timeCounter.resetCounter(); timeCounter.rollLimit(); } }); } } } Sources I mainly used: https://www.planetminecraft.com/blog/forge-tutorial-capability-system/ https://mcforge.readthedocs.io/en/1.18.x/datastorage/capabilities/ https://forums.minecraftforge.net/topic/106325-1171-forge-capability-how-to-save/ Edited July 9, 20232 yr by LeeCrafts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.