/
SoundCardItemDevice.java
95 lines (75 loc) · 3.59 KB
/
SoundCardItemDevice.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* SPDX-License-Identifier: MIT */
package li.cil.oc2.common.bus.device.rpc.item;
import li.cil.oc2.api.bus.device.object.Callback;
import li.cil.oc2.api.bus.device.object.Parameter;
import li.cil.oc2.common.Config;
import li.cil.oc2.common.util.BlockLocation;
import li.cil.oc2.common.util.TickUtils;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
public final class SoundCardItemDevice extends AbstractItemRPCDevice {
private final int COOLDOWN_IN_TICKS = TickUtils.toTicks(Duration.ofSeconds(Config.soundCardCoolDownSeconds));
private static final int MAX_FIND_RESULTS = 25;
///////////////////////////////////////////////////////////////////
private final Supplier<Optional<BlockLocation>> location;
private long gameTimeCooldownExpiresAt;
///////////////////////////////////////////////////////////////////
public SoundCardItemDevice(final ItemStack identity, final Supplier<Optional<BlockLocation>> location) {
super(identity, "sound");
this.location = location;
}
///////////////////////////////////////////////////////////////////
@Callback
public void playSound(@Nullable @Parameter("name") final String name) {
playSound(name, 1, 1);
}
@Callback
public void playSound(@Nullable @Parameter("name") final String name, @Parameter("volume") final float volume) {
playSound(name, volume, 1);
}
@Callback
public void playSound(@Nullable @Parameter("name") final String name, @Parameter("volume") final float volume, @Parameter("pitch") final float pitch) {
if (name == null) throw new IllegalArgumentException();
if (volume < 0 || volume > 1.0f) throw new IllegalArgumentException("volume must be between >= 0 and <= 1");
if (pitch < 0.5f || pitch > 2.0f) throw new IllegalArgumentException("pitch must be between >= 0.5 and <= 2");
if (volume == 0) return;
location.get().ifPresent(location -> location.tryGetLevel().ifPresent(level -> {
if (!(level instanceof final ServerLevel serverLevel)) {
return;
}
final long gameTime = serverLevel.getGameTime();
if (gameTime < gameTimeCooldownExpiresAt) {
return;
}
gameTimeCooldownExpiresAt = gameTime + COOLDOWN_IN_TICKS;
final SoundEvent soundEvent = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation(name));
if (soundEvent == null) throw new IllegalArgumentException("Sound not found.");
level.playSound(null, location.blockPos(), soundEvent, SoundSource.BLOCKS, volume, pitch);
}));
}
@Callback
public List<String> findSound(@Nullable @Parameter("name") final String name) {
if (name == null || name.length() == 0) throw new IllegalArgumentException();
final ArrayList<String> matches = new ArrayList<>();
for (final ResourceLocation key : ForgeRegistries.SOUND_EVENTS.getKeys()) {
final String keyName = key.toString();
if (keyName.contains(name)) {
matches.add(keyName);
if (matches.size() >= MAX_FIND_RESULTS) {
break;
}
}
}
return matches;
}
}