Skip to content

Commit 5260a74

Browse files
committed
Support registering SoundEvents without SoundGenerator
Now can register via ResourcePack's sounds.json
1 parent fff7072 commit 5260a74

11 files changed

Lines changed: 102 additions & 35 deletions

File tree

logics/src/main/java/dev/stashy/extrasounds/logics/SoundManager.java

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void handleInventorySlot(Player player, InventoryClickState state) {
7474
final ItemStack slotStack = state.getSlotStack();
7575
if (actionType == SlotActionType.QUICK_MOVE) {
7676
// cursor holding an item, then Shift + mouse (double) click.
77-
this.handleQuickMoveSound(slotStack.getItem());
77+
this.handleQuickMoveSound(slotStack);
7878
return;
7979
}
8080
if (state.isSlotBlocked()) {
@@ -133,9 +133,9 @@ public void handleInventorySlot(Player player, InventoryClickState state) {
133133
* --> PICKUP
134134
*/
135135
if (!hasSlot || hasCursor && ExtraSounds.MAIN.canItemsCombine(slotStack, cursorStack)) {
136-
this.playSound2D(cursorStack.getItem(), SoundType.PLACE);
136+
this.playSound2D(cursorStack, SoundType.PLACE);
137137
} else {
138-
this.playSound2D(slotStack.getItem(), SoundType.GRAB);
138+
this.playSound2D(slotStack, SoundType.GRAB);
139139
}
140140
}
141141
}
@@ -152,11 +152,11 @@ public void hotbar(int i) {
152152
return;
153153
}
154154

155-
ItemStack stack = player.getInventory().getItem(i);
155+
ItemStack stack = player.getInventory().getItem(i).copy();
156156
if (stack.isEmpty()) {
157157
this.playSound2D(Sounds.HOTBAR_SCROLL, SoundType.HOTBAR);
158158
} else {
159-
this.playSound2D(stack.getItem(), SoundType.HOTBAR);
159+
this.playSound2D(stack, SoundType.HOTBAR);
160160
}
161161
}
162162

@@ -166,31 +166,32 @@ public void blockInteract(VersionedSoundEventWrapper snd, BlockPos position) {
166166
}
167167

168168
public void blockInteract(Item item, BlockPos position) {
169-
this.blockInteract(this.getSoundByItem(item, SoundType.DEFAULT), position);
169+
this.blockInteract(this.getSoundByItem(item.getDefaultInstance(), SoundType.DEFAULT), position);
170170
}
171171

172172
public void playSound2D(VersionedSoundEventWrapper snd, SoundType type) {
173173
this.playSound2D(snd, type.category, type.pitch);
174174
}
175175

176-
public void playSound2D(Item item, SoundType type) {
176+
public void playSound2D(ItemStack item, SoundType type) {
177177
this.playSound2D(this.getSoundByItem(item, type), type.category, type.pitch);
178178
}
179179

180180
/**
181181
* SlotActionType.QUICK_MOVE is too many method calls
182182
*
183-
* @param item Target item to quickMove
183+
* @param itemStack Target ItemStack to quickMove
184184
* @see net.minecraft.client.multiplayer.MultiPlayerGameMode#handleContainerInput
185185
* @see net.minecraft.world.inventory.AbstractContainerMenu#doClick
186186
*/
187-
private void handleQuickMoveSound(Item item) {
187+
private void handleQuickMoveSound(ItemStack itemStack) {
188+
final Item item = itemStack.getItem();
188189
if (item == Items.AIR) {
189190
return;
190191
}
191192
long now = System.currentTimeMillis();
192193
if (now - this.lastPlayed > 10 || item != this.quickMovingItem) {
193-
this.playSound2D(item, SoundType.GRAB);
194+
this.playSound2D(itemStack, SoundType.GRAB);
194195
this.lastPlayed = now;
195196
this.quickMovingItem = item;
196197
}
@@ -294,18 +295,26 @@ public void stopSound(VersionedSoundEventWrapper e, SoundType type) {
294295
ExtraSounds.MAIN.stopSound(e, type);
295296
}
296297

297-
public VersionedSoundEventWrapper getSoundByItem(Item item, SoundType type) {
298-
var itemId = ExtraSounds.MAIN.getItemId(item);
299-
var id = ExtraSounds.getClickId(itemId, type);
300-
VersionedSoundEventWrapper sound = SoundPackLoader.CUSTOM_SOUND_EVENT.getOrDefault(id, null);
301-
if (sound == null) {
302-
if (!this.missingSoundId.contains(id)) {
303-
this.missingSoundId.add(id);
304-
LOGGER.error("Sound '{}' cannot be found in packs.", id);
298+
public VersionedSoundEventWrapper getSoundByItem(ItemStack item, SoundType type) {
299+
final var itemCompoId = ExtraSounds.getClickId(ExtraSounds.MAIN.getItemIdWithComponents(item), type);
300+
final var itemId = ExtraSounds.getClickId(ExtraSounds.MAIN.getItemId(item.getItem()), type);
301+
final var sound = SoundPackLoader.getSoundEventById(itemCompoId, itemId);
302+
if (sound.isEmpty()) {
303+
logMissingSoundId(itemId);
304+
if (!itemCompoId.equals(itemId)) {
305+
logMissingSoundId(itemCompoId);
305306
}
306307
return FALLBACK_SOUND_EVENT;
308+
} else {
309+
return sound.get();
310+
}
311+
}
312+
313+
private void logMissingSoundId(Identifier id) {
314+
if (!this.missingSoundId.contains(id)) {
315+
this.missingSoundId.add(id);
316+
LOGGER.error("Sound '{}' cannot be found in packs.", id);
307317
}
308-
return sound;
309318
}
310319

311320
public VersionedHotbarSoundHandler getHotbarSoundHandler() {

logics/src/main/java/dev/stashy/extrasounds/logics/VersionedMain.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import me.lonefelidae16.groominglib.api.McVersionInterchange;
77
import net.minecraft.client.resources.sounds.SoundInstance;
88
import net.minecraft.core.IdMap;
9+
import net.minecraft.core.component.DataComponentMap;
10+
import net.minecraft.core.component.DataComponents;
911
import net.minecraft.resources.Identifier;
1012
import net.minecraft.sounds.SoundSource;
1113
import net.minecraft.world.item.Item;
@@ -37,4 +39,13 @@ public static VersionedMain newInstance() {
3739
public abstract float getSoundVolume(SoundSource soundCategory);
3840

3941
public abstract void stopSound(VersionedSoundEventWrapper event, SoundType type);
42+
43+
public Identifier getItemIdWithComponents(ItemStack itemStack) {
44+
DataComponentMap map = itemStack.getComponents();
45+
if (map.has(DataComponents.ITEM_MODEL)) {
46+
return map.get(DataComponents.ITEM_MODEL);
47+
} else {
48+
return this.getItemId(itemStack.getItem());
49+
}
50+
}
4051
}

logics/src/main/java/dev/stashy/extrasounds/logics/entry/SoundPackLoader.java

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import net.fabricmc.loader.api.FabricLoader;
1818
import net.fabricmc.loader.api.ModContainer;
1919
import net.fabricmc.loader.api.metadata.ModMetadata;
20+
import net.minecraft.client.Minecraft;
2021
import net.minecraft.client.resources.sounds.SoundEventRegistration;
2122
import net.minecraft.resources.Identifier;
2223
import net.minecraft.world.item.BlockItem;
@@ -38,7 +39,8 @@ public final class SoundPackLoader {
3839
private static final String CACHE_FNAME = ExtraSounds.MODID + ".cache";
3940
private static final Path CACHE_PATH = Path.of(System.getProperty("java.io.tmpdir"), ".minecraft_fabric", CACHE_FNAME);
4041

41-
public static final Map<Identifier, VersionedSoundEventWrapper> CUSTOM_SOUND_EVENT = new HashMap<>();
42+
private static final Map<Identifier, VersionedSoundEventWrapper> BUILT_IN_SOUND_EVENT = new HashMap<>();
43+
private static final Map<Identifier, VersionedSoundEventWrapper> EXTERNAL_SOUND_EVENT = new HashMap<>();
4244
public static final VersionedClientResource EXTRA_SOUNDS_RESOURCE = Objects.requireNonNull(
4345
VersionedClientResource.newInstance(ExtraSounds.MODID, "%s Runtime Resources".formatted(ExtraSounds.class.getSimpleName()))
4446
);
@@ -50,7 +52,7 @@ public final class SoundPackLoader {
5052
))
5153
);
5254

53-
private static final Gson GSON = new GsonBuilder()
55+
public static final Gson GSON = new GsonBuilder()
5456
.registerTypeAdapter(SoundEventRegistration.class, new SoundEntrySerializer())
5557
.registerTypeHierarchyAdapter(VersionedSoundWrapper.class, Objects.requireNonNull(VersionedSoundSerializer.newInstance()))
5658
.create();
@@ -139,7 +141,7 @@ public static void init() {
139141
} else if (DebugUtils.DEBUG) {
140142
LOGGER.info("init finished; took {}ms.", tookMillis);
141143
}
142-
LOGGER.info("sound pack successfully loaded; {} entries.", CUSTOM_SOUND_EVENT.size());
144+
LOGGER.info("Built-in sound pack successfully loaded; {} entries.", BUILT_IN_SOUND_EVENT.size());
143145
}
144146

145147
/**
@@ -165,6 +167,7 @@ private static void processSounds(Map<String, SoundGenerator> soundGenerator, Ma
165167
}
166168
}
167169

170+
// process for registered item.
168171
for (Item item : ExtraSounds.MAIN.getItemRegistry()) {
169172
final Identifier itemId = ExtraSounds.MAIN.getItemId(item);
170173
final SoundDefinition definition;
@@ -217,7 +220,43 @@ private static void generateSoundEntry(Identifier clickId, SoundEventRegistratio
217220
* @param clickId Target id.
218221
*/
219222
private static void putSoundEvent(Identifier clickId) {
220-
CUSTOM_SOUND_EVENT.put(clickId, ExtraSounds.createEvent(clickId));
223+
BUILT_IN_SOUND_EVENT.put(clickId, ExtraSounds.createEvent(clickId));
224+
}
225+
226+
private static void putExternalSoundEvent(Identifier identifier) {
227+
EXTERNAL_SOUND_EVENT.put(identifier, ExtraSounds.createEvent(identifier));
228+
}
229+
230+
public static Optional<VersionedSoundEventWrapper> getSoundEventById(Identifier... ids) {
231+
for (Identifier target : ids) {
232+
if (EXTERNAL_SOUND_EVENT.containsKey(target)) {
233+
return Optional.of(EXTERNAL_SOUND_EVENT.get(target));
234+
}
235+
if (BUILT_IN_SOUND_EVENT.containsKey(target)) {
236+
return Optional.of(BUILT_IN_SOUND_EVENT.get(target));
237+
}
238+
}
239+
return Optional.empty();
240+
}
241+
242+
public static void reloadExternalSoundEvent() {
243+
for (var pack : Minecraft.getInstance().getResourceManager().getResourceStack(SOUNDS_JSON_ID)) {
244+
if (pack.sourcePackId().equals(ExtraSounds.MODID)) {
245+
// Avoid built-in resource via SoundPackLoader.
246+
continue;
247+
}
248+
try (InputStream stream = pack.open()) {
249+
final BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(stream)));
250+
final JsonObject jsonObject = JsonParser.parseString(reader.lines().collect(Collectors.joining())).getAsJsonObject();
251+
for (String idStr : jsonObject.keySet()) {
252+
putExternalSoundEvent(Identifier.fromNamespaceAndPath(ExtraSounds.MODID, idStr));
253+
}
254+
} catch (Exception ignored) {
255+
}
256+
}
257+
if (!EXTERNAL_SOUND_EVENT.isEmpty()) {
258+
LOGGER.info("External sound pack was found; {} entries.", EXTERNAL_SOUND_EVENT.size());
259+
}
221260
}
222261

223262
/**

logics/src/main/java/dev/stashy/extrasounds/logics/impl/AbstractCreativeInventoryHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void onClick(Player player, @Nullable Slot slot, int slotId, int button,
7474
if (bOnCreativeTab && !bOnHotbar) {
7575
if (ExtraSounds.MAIN.canItemsCombine(state.getSlotStack(), state.cursorStack) && !state.isRMB) {
7676
// Left Mouse Clicked on the same slot in CreativeInventory tab except Hotbar.
77-
ExtraSounds.MANAGER.playSound2D(state.cursorStack.getItem(), SoundType.DEFAULT);
77+
ExtraSounds.MANAGER.playSound2D(state.cursorStack, SoundType.DEFAULT);
7878
return;
7979
} else if (slotId >= 0) {
8080
// Clicking on another slot will delete or decrement the cursor stack.

logics/src/main/java/dev/stashy/extrasounds/logics/impl/EntitySoundHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import net.minecraft.util.Mth;
1010
import net.minecraft.world.effect.MobEffect;
1111
import net.minecraft.world.entity.Entity;
12-
import net.minecraft.world.item.Item;
12+
import net.minecraft.world.item.ItemStack;
1313
import net.minecraft.world.item.Items;
1414

1515
/**
@@ -51,8 +51,8 @@ public void onDeath(Entity entity, BlockPos blockPos) {
5151
ExtraSounds.MANAGER.playSound(Sounds.Entities.POOF, SoundType.ENTITY.category, .7f, pitch, blockPos);
5252
}
5353

54-
public void onItemUse(Item item) {
55-
if (item == Items.AIR) {
54+
public void onItemUse(ItemStack item) {
55+
if (item.getItem() == Items.AIR) {
5656
return;
5757
}
5858

logics/src/main/java/dev/stashy/extrasounds/logics/impl/VersionedHotbarSoundHandler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ public static VersionedHotbarSoundHandler newInstance() {
3131
return null;
3232
}
3333

34-
public void onSwap(Item mainHand, Item offHand) {
35-
if (offHand != ITEM_EMPTY) {
34+
public void onSwap(ItemStack mainHand, ItemStack offHand) {
35+
if (offHand.getItem() != ITEM_EMPTY) {
3636
ExtraSounds.MANAGER.playSound2D(offHand, SoundType.HOTBAR);
37-
} else if (mainHand != ITEM_EMPTY) {
37+
} else if (mainHand.getItem() != ITEM_EMPTY) {
3838
ExtraSounds.MANAGER.playSound2D(mainHand, SoundType.HOTBAR);
3939
}
4040
}
@@ -79,7 +79,7 @@ public void onItemPick() {
7979

8080
final Item item = this.popPickingItem();
8181
if (!player.getMainHandItem().is(item) && item != ITEM_EMPTY) {
82-
ExtraSounds.MANAGER.playSound2D(item, SoundType.HOTBAR);
82+
ExtraSounds.MANAGER.playSound2D(item.getDefaultInstance(), SoundType.HOTBAR);
8383
}
8484
}
8585

logics/src/main/java/dev/stashy/extrasounds/logics/mixin/screens/AdvancementsScreenMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public abstract class AdvancementsScreenMixin {
2626
@Inject(method = "mouseClicked", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientAdvancements;setSelectedTab(Lnet/minecraft/advancements/AdvancementHolder;Z)V"))
2727
private void extrasounds$changeAdvancementsTab(CallbackInfoReturnable<Boolean> cir, @Local AdvancementTab tab) {
2828
if (currentTab != tab && tab instanceof AdvancementTabAccessor accessor) {
29-
ExtraSounds.MANAGER.playSound2D(accessor.getIcon().getItem(), SoundType.DEFAULT);
29+
ExtraSounds.MANAGER.playSound2D(accessor.getIcon().copy(), SoundType.DEFAULT);
3030
}
3131
}
3232

versioned/es26.1/src/main/java/dev/stashy/extrasounds/mc26_1/mixin/action/entity/MultiPlayerGameModeMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public abstract class MultiPlayerGameModeMixin {
3535

3636
final ItemStack stackInHand = player.getItemInHand(hand);
3737
if (stackInHand.is(Items.NAME_TAG) && stackInHand.getComponents().has(DataComponents.CUSTOM_NAME)) {
38-
this.soundHandler.onItemUse(Items.NAME_TAG);
38+
this.soundHandler.onItemUse(Items.NAME_TAG.getDefaultInstance());
3939
}
4040
}
4141
}

versioned/es26.1/src/main/java/dev/stashy/extrasounds/mc26_1/mixin/hotbar/ConnectionMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ public abstract class ConnectionMixin {
3939
return;
4040
}
4141

42-
this.soundHandler.onSwap(player.getMainHandItem().getItem(), player.getOffhandItem().getItem());
42+
this.soundHandler.onSwap(player.getMainHandItem().copy(), player.getOffhandItem().copy());
4343
}
4444
}

versioned/es26.1/src/main/java/dev/stashy/extrasounds/mc26_1/mixin/resource/ReloadableResourceManagerMixin.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
import dev.stashy.extrasounds.logics.entry.SoundPackLoader;
55
import net.minecraft.server.packs.PackResources;
66
import net.minecraft.server.packs.PackType;
7+
import net.minecraft.server.packs.resources.ReloadInstance;
78
import net.minecraft.server.packs.resources.ReloadableResourceManager;
89
import org.spongepowered.asm.mixin.Final;
910
import org.spongepowered.asm.mixin.Mixin;
1011
import org.spongepowered.asm.mixin.Shadow;
1112
import org.spongepowered.asm.mixin.injection.At;
13+
import org.spongepowered.asm.mixin.injection.Inject;
1214
import org.spongepowered.asm.mixin.injection.ModifyVariable;
15+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1316

1417
import java.util.LinkedList;
1518
import java.util.List;
@@ -30,4 +33,9 @@ public abstract class ReloadableResourceManagerMixin {
3033
modifiable.add(0, (PackResources) SoundPackLoader.EXTRA_SOUNDS_RESOURCE);
3134
return modifiable;
3235
}
36+
37+
@Inject(method = "createReload", at = @At("RETURN"))
38+
private void injected(CallbackInfoReturnable<ReloadInstance> cir) {
39+
SoundPackLoader.reloadExternalSoundEvent();
40+
}
3341
}

0 commit comments

Comments
 (0)