VolumeUpdateObserver interface
Пакет: com.hypixel.hytale.builtin.triggervolumes.manager
Файл: com/hypixel/hytale/builtin/triggervolumes/manager/TriggerVolumeManager.java
Методы (2)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
abstract |
void |
onVolumeRemovedvoid onVolumeRemoved(@Nonnull String var1) |
abstract |
void |
onVolumeUpdatedvoid onVolumeUpdated(@Nonnull VolumeEntry var1) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.triggervolumes.manager;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.EntityTargetType;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.component.TriggerVolumeGroup;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.SignalTag;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.TriggerEventType;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.TriggerRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.TaggedVolumeEffectUtil;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoBuildRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoDamageRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoDestroyRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoHarvestRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoTickRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.RuleEntityFilter;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.BoxShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.CylinderShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.SphereShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.TriggerVolumeShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.system.DelayedEffectScheduler;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.system.VolumeSpatialIndex;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.map.MapCodec;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Resource;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.protocol.packets.player.AddOrUpdateTriggerVolumeDisplay;
class="kw">import com.hypixel.hytale.protocol.packets.player.ClientRuleVolume;
class="kw">import com.hypixel.hytale.protocol.packets.player.RemoveTriggerVolumeDisplay;
class="kw">import com.hypixel.hytale.protocol.packets.player.TriggerVolumeConditionTiming;
class="kw">import com.hypixel.hytale.protocol.packets.player.TriggerVolumeDisplayEntry;
class="kw">import com.hypixel.hytale.protocol.packets.player.TriggerVolumeShapeType;
class="kw">import com.hypixel.hytale.protocol.packets.player.UpdateClientRuleVolumes;
class="kw">import com.hypixel.hytale.protocol.packets.player.UpdateTriggerVolumeDisplay;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.universe.world.TickSuppressionRegistry;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import java.util.ArrayDeque;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Collection;
class="kw">import java.util.Collections;
class="kw">import java.util.Deque;
class="kw">import java.util.EnumSet;
class="kw">import java.util.HashMap;
class="kw">import java.util.HashSet;
class="kw">import java.util.Iterator;
class="kw">import java.util.LinkedHashMap;
class="kw">import java.util.LinkedHashSet;
class="kw">import java.util.List;
class="kw">import java.util.Locale;
class="kw">import java.util.Map;
class="kw">import java.util.Objects;
class="kw">import java.util.Set;
class="kw">import java.util.UUID;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import java.util.function.Predicate;
class="kw">import java.util.regex.Matcher;
class="kw">import java.util.regex.Pattern;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3f;
class="kw">public class TriggerVolumeManager class="kw">implements Resource<EntityStore> {
@Nonnull
class="kw">public class="kw">static class="kw">final UUID ENVIRONMENT_ACTOR_UUID = new UUID(0L, 0L);
@Nonnull
class="kw">public class="kw">static class="kw">final BuilderCodec<TriggerVolumeManager> CODEC = BuilderCodec.builder(TriggerVolumeManager.class, TriggerVolumeManager::new)
.append(
new KeyedCodec<>("Volumes", new MapCodec<>(VolumeEntry.CODEC, ConcurrentHashMap::new, false), false),
(var0, var1) -> var0.volumes.putAll(var1),
var0 -> var0.volumes.isEmpty() ? null : var0.volumes
)
.add()
.append(
new KeyedCodec<>("Groups", new MapCodec<>(GroupEntry.CODEC, ConcurrentHashMap::new, false), false),
(var0, var1) -> var0.groups.putAll(var1),
var0 -> var0.groups.isEmpty() ? null : var0.groups
)
.add()
.afterDecode(TriggerVolumeManager::postDecode)
.build();
class="kw">private class="kw">static class="kw">final Vector3f COLOR_ENABLED = new Vector3f(0.0F, 0.8F, 0.8F);
class="kw">private class="kw">static class="kw">final Vector3f COLOR_DISABLED = new Vector3f(0.8F, 0.2F, 0.2F);
class="kw">private class="kw">static class="kw">final float OPACITY_ENABLED = 0.3F;
class="kw">private class="kw">static class="kw">final float OPACITY_DISABLED = 0.15F;
class="kw">private class="kw">static class="kw">final String NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789";
class="kw">private class="kw">static class="kw">final int DEFAULT_NAME_LENGTH = 6;
class="kw">private class="kw">static class="kw">final Pattern NUMBERED_SUFFIX = Pattern.compile("^(.+) \\(\\d+\\)$");
class="kw">private class="kw">final Map<String, VolumeEntry> volumes = new ConcurrentHashMap<>();
class="kw">private class="kw">final Map<String, GroupEntry> groups = new ConcurrentHashMap<>();
class="kw">private class="kw">final ConcurrentHashMap<String, String> prefabGroupLinkRemap = new ConcurrentHashMap<>();
class="kw">private class="kw">final Map<UUID, EnumSet<TriggerVolumeManager.ViewSource>> activeViewers = new ConcurrentHashMap<>();
class="kw">private class="kw">final Map<UUID, String> playerSelections = new ConcurrentHashMap<>();
class="kw">private class="kw">final class="kw">transient Map<UUID, TriggerVolumeManager.SelectionObserver> selectionObservers = new ConcurrentHashMap<>();
class="kw">private class="kw">final class="kw">transient Map<UUID, TriggerVolumeManager.VolumeUpdateObserver> volumeUpdateObservers = new ConcurrentHashMap<>();
@Nonnull
class="kw">private class="kw">final class="kw">transient Deque<TriggerVolumeManager.PendingTriggerEvent> pendingEvents = new ArrayDeque<>();
@Nonnull
class="kw">private class="kw">final VolumeSpatialIndex spatialIndex = new VolumeSpatialIndex();
@Nonnull
class="kw">private class="kw">final class="kw">transient Set<VolumeEntry> activeVolumes = ConcurrentHashMap.newKeySet();
@Nonnull
class="kw">private class="kw">final class="kw">transient DelayedEffectScheduler delayedEffectScheduler = new DelayedEffectScheduler();
@Nullable
class="kw">private World world;
class="kw">private class="kw">transient class="kw">volatile boolean clientRuleVolumesDirty;
class="kw">private class="kw">transient class="kw">volatile boolean tickSuppressionDirty = true;
class="kw">private class="kw">transient class="kw">volatile boolean entityTargetCounterDirty = true;
class="kw">private class="kw">transient class="kw">volatile boolean hasEntityTargetVolumes;
class="kw">private class="kw">static class="kw">final byte RULE_NO_BUILD = 1;
class="kw">private class="kw">static class="kw">final byte RULE_NO_DESTROY = 2;
class="kw">private class="kw">static class="kw">final byte RULE_NO_HARVEST = 4;
class="kw">private class="kw">static class="kw">final byte RULE_NO_DAMAGE_ALL = 8;
class="kw">private class="kw">static class="kw">final byte RULE_NO_DAMAGE_PLAYERS = 16;
class="kw">public TriggerVolumeManager() {
}
class="kw">private void postDecode() {
this.migrateLegacyIds();
for (Entry var2 : this.volumes.entrySet()) {
var2.getValue().setId(var2.getKey());
var2.getValue().expandTags();
}
for (Entry var7 : this.groups.entrySet()) {
var7.getValue().setId(var7.getKey());
var7.getValue().expandTags();
}
for (VolumeEntry var8 : this.volumes.values()) {
if (var8.getGroupId() != null) {
GroupEntry var3 = this.groups.get(var8.getGroupId());
if (var3 != null) {
var3.addMember(var8.getId());
}
}
}
for (VolumeEntry var9 : this.volumes.values()) {
var9.attachOwnerSilently(this);
}
this.spatialIndex.rebuild(this.volumes.values());
this.entityTargetCounterDirty = true;
}
class="kw">private void migrateLegacyIds() {
HashMap var1 = new HashMap<>();
for (Entry var3 : new ArrayList<>(this.volumes.entrySet())) {
String var4 = var3.getKey();
VolumeEntry var5 = var3.getValue();
if (!var5.isFromWorldGen() && !isUuid(var4)) {
if (var5.getName() == null) {
var5.setName(var4);
}
var1.put(var4, this.generateUniqueVolumeId());
}
}
HashMap var7 = new HashMap<>();
for (Entry var12 : new ArrayList<>(this.groups.entrySet())) {
String var16 = var12.getKey();
GroupEntry var6 = var12.getValue();
if (!var16.startsWith("tvg_wg_") && !isUuid(var16)) {
if (var6.getName() == null) {
var6.setName(var16);
}
var7.put(var16, this.generateUniquePastedGroupId());
}
}
if (!var1.isEmpty() || !var7.isEmpty()) {
for (Entry var13 : var1.entrySet()) {
VolumeEntry var17 = this.volumes.remove(var13.getKey());
if (var17 != null) {
this.volumes.put(var13.getValue(), var17);
}
}
for (Entry var14 : var7.entrySet()) {
GroupEntry var18 = this.groups.remove(var14.getKey());
if (var18 != null) {
this.groups.put(var14.getValue(), var18);
}
}
for (VolumeEntry var15 : this.volumes.values()) {
String var19 = var15.getGroupId() != null ? var7.get(var15.getGroupId()) : null;
if (var19 != null) {
var15.setGroupId(var19);
}
}
}
}
class="kw">private class="kw">static boolean isUuid(@Nonnull String var0) {
try {
UUID.fromString(var0);
class="kw">return true;
} catch (IllegalArgumentException var2) {
class="kw">return false;
}
}
class="kw">public void register(@Nonnull String var1, @Nonnull VolumeEntry var2) {
if (var2.getName() == null) {
var2.setName(generateDefaultName("tv_"));
}
this.volumes.put(var1, var2);
var2.attachOwner(this);
this.updateTrackingState(var2);
this.entityTargetCounterDirty = true;
this.markClientRuleVolumesDirty();
}
class="kw">public void unregister(@Nonnull String var1) {
VolumeEntry var2 = this.volumes.remove(var1);
if (var2 != null) {
var2.markPendingDestroy();
this.spatialIndex.markRemoved(var2, SpatialSnapshot.of(var2));
var2.detachOwner();
this.activeVolumes.remove(var2);
String var3 = var2.getGroupId();
if (var3 != null) {
GroupEntry var4 = this.groups.get(var3);
if (var4 != null) {
var4.removeMember(var1);
if (var4.getMemberVolumeIds().isEmpty()) {
this.unregisterGroup(var3);
}
}
}
}
this.entityTargetCounterDirty = true;
this.markClientRuleVolumesDirty();
}
void onVolumeAttached(@Nonnull VolumeEntry var1) {
this.spatialIndex.markChanged(var1, SpatialSnapshot.of(var1));
}
void onVolumeSpatialChanged(@Nonnull VolumeEntry var1, @Nullable SpatialSnapshot var2) {
this.spatialIndex.markChanged(var1, var2 != null ? var2 : SpatialSnapshot.of(var1));
this.markClientRuleVolumesDirty();
}
void onVolumeEnabledChanged(@Nonnull VolumeEntry var1, @Nullable SpatialSnapshot var2) {
this.spatialIndex.markChanged(var1, var2 != null ? var2 : SpatialSnapshot.of(var1));
this.entityTargetCounterDirty = true;
this.markClientRuleVolumesDirty();
}
class="kw">public void updateTrackingState(@Nonnull VolumeEntry var1) {
if (var1.getTrackedEntities().isEmpty()) {
this.activeVolumes.remove(var1);
} else {
this.activeVolumes.add(var1);
}
}
@Nonnull
class="kw">public Set<VolumeEntry> getActiveVolumes() {
class="kw">return this.activeVolumes;
}
class="kw">public boolean hasEntityTargetVolumes() {
if (this.entityTargetCounterDirty) {
this.entityTargetCounterDirty = false;
boolean var1 = false;
for (VolumeEntry var3 : this.volumes.values()) {
if (var3.isEnabled() && usesEntitySpatial(var3)) {
var1 = true;
break;
}
}
this.hasEntityTargetVolumes = var1;
}
class="kw">return this.hasEntityTargetVolumes;
}
class="kw">private class="kw">static boolean usesEntitySpatial(@Nonnull VolumeEntry var0) {
Set var1 = var0.getTargetTypes();
class="kw">return var1.contains(EntityTargetType.NPC) || var1.contains(EntityTargetType.ITEM_DROP) || var1.contains(EntityTargetType.PROJECTILE);
}
@Nullable
class="kw">public VolumeEntry renameVolume(@Nonnull String var1, @Nonnull String var2) {
if (var1.equals(var2)) {
class="kw">return this.volumes.get(var1);
}
VolumeEntry var3 = this.volumes.remove(var1);
if (var3 == null) {
class="kw">return null;
}
if (this.volumes.putIfAbsent(var2, var3) != null) {
this.volumes.put(var1, var3);
class="kw">return null;
}
var3.setId(var2);
for (GroupEntry var5 : this.groups.values()) {
if (var5.getMemberVolumeIds().remove(var1)) {
var5.addMember(var2);
}
}
for (Entry var7 : this.playerSelections.entrySet()) {
if (var1.equals(var7.getValue())) {
var7.setValue(var2);
}
}
this.markClientRuleVolumesDirty();
class="kw">return var3;
}
class="kw">public void removeWorldGenVolumesInChunk(long var1) {
ArrayList var3 = new ArrayList<>();
boolean var4 = false;
Iterator var5 = this.volumes.values().iterator();
while (var5.hasNext()) {
VolumeEntry var6 = var5.next();
if (var6.isFromWorldGen()) {
Vector3d var7 = var6.getPosition();
if (ChunkUtil.indexChunkFromBlock(var7.x(), var7.z()) == var1) {
String var8 = var6.getGroupId();
if (var8 != null) {
GroupEntry var9 = this.groups.get(var8);
if (var9 != null) {
var9.removeMember(var6.getId());
if (var9.getMemberVolumeIds().isEmpty()) {
var3.add(var8);
}
}
}
var6.markPendingDestroy();
this.spatialIndex.markRemoved(var6, SpatialSnapshot.of(var6));
var6.detachOwner();
this.activeVolumes.remove(var6);
var5.remove();
this.notifyViewersRemove(var6.getId());
var4 = true;
}
}
}
for (String var11 : var3) {
this.unregisterGroup(var11);
}
if (var4) {
this.entityTargetCounterDirty = true;
this.markClientRuleVolumesDirty();
}
}
class="kw">public int removeAllVolumes() {
int var1 = this.volumes.size();
if (var1 == 0 && this.groups.isEmpty()) {
class="kw">return 0;
}
for (VolumeEntry var3 : this.volumes.values()) {
var3.markPendingDestroy();
var3.detachOwner();
this.notifyViewersRemove(var3.getId());
}
this.volumes.clear();
this.groups.clear();
this.spatialIndex.clear();
this.activeVolumes.clear();
this.entityTargetCounterDirty = true;
this.markClientRuleVolumesDirty();
class="kw">return var1;
}
@Nullable
class="kw">public VolumeEntry getVolume(@Nonnull String var1) {
class="kw">return this.volumes.get(var1);
}
@Nonnull
class="kw">public Collection<VolumeEntry> getVolumes() {
class="kw">return Collections.unmodifiableCollection(this.volumes.values());
}
class="kw">public boolean hasVolumes() {
class="kw">return !this.volumes.isEmpty();
}
@Nonnull
class="kw">public Map<String, VolumeEntry> getVolumesMap() {
class="kw">return Collections.unmodifiableMap(this.volumes);
}
class="kw">public boolean hasVolume(@Nonnull String var1) {
class="kw">return this.volumes.containsKey(var1);
}
class="kw">public void markSpatialDirty() {
this.entityTargetCounterDirty = true;
}
class="kw">public boolean hasActiveRule(@Nonnull Vector3d var1, @Nonnull Class<? class="kw">extends TriggerRule> var2) {
this.spatialIndex.applyPendingChanges();
ArrayList var3 = new ArrayList<>();
this.spatialIndex.collectCandidates(var1, var3);
for (VolumeEntry var5 : var3) {
if (isRuleCandidate(var5, var1)) {
if (containsRule(var5.getRules(), var2)) {
class="kw">return true;
}
GroupEntry var6 = var5.getGroupId() != null ? this.groups.get(var5.getGroupId()) : null;
if (var6 != null && var6.isEnabled() && containsRule(var6.getRules(), var2)) {
class="kw">return true;
}
}
}
class="kw">return false;
}
@Nonnull
class="kw">public <T class="kw">extends TriggerRule> List<T> getActiveRules(@Nonnull Vector3d var1, @Nonnull Class<T> var2) {
this.spatialIndex.applyPendingChanges();
ArrayList var3 = new ArrayList<>();
this.spatialIndex.collectCandidates(var1, var3);
ArrayList var4 = new ArrayList<>();
for (VolumeEntry var6 : var3) {
if (isRuleCandidate(var6, var1)) {
collectRules(var6.getRules(), var2, var4);
GroupEntry var7 = var6.getGroupId() != null ? this.groups.get(var6.getGroupId()) : null;
if (var7 != null && var7.isEnabled()) {
collectRules(var7.getRules(), var2, var4);
}
}
}
class="kw">return var4;
}
@Nonnull
class="kw">public <T class="kw">extends TriggerRule> List<TriggerVolumeManager.ActiveRule<T>> getActiveRulesWithVolume(@Nonnull Vector3d var1, @Nonnull Class<T> var2) {
this.spatialIndex.applyPendingChanges();
ArrayList var3 = new ArrayList<>();
this.spatialIndex.collectCandidates(var1, var3);
ArrayList var4 = new ArrayList<>();
for (VolumeEntry var6 : var3) {
if (isRuleCandidate(var6, var1)) {
collectRulesWithVolume(var6.getRules(), var2, var6, var4);
GroupEntry var7 = var6.getGroupId() != null ? this.groups.get(var6.getGroupId()) : null;
if (var7 != null && var7.isEnabled()) {
collectRulesWithVolume(var7.getRules(), var2, var6, var4);
}
}
}
class="kw">return var4;
}
class="kw">private class="kw">static <T class="kw">extends TriggerRule> void collectRulesWithVolume(
@Nonnull List<TriggerRule> var0, @Nonnull Class<T> var1, @Nonnull VolumeEntry var2, @Nonnull List<TriggerVolumeManager.ActiveRule<T>> var3
) {
for (TriggerRule var5 : var0) {
if (var5.isEnabled() && var1.isInstance(var5)) {
var3.add(new TriggerVolumeManager.ActiveRule<>(var1.cast(var5), var2));
}
}
}
class="kw">private class="kw">static boolean isRuleCandidate(@Nonnull VolumeEntry var0, @Nonnull Vector3d var1) {
class="kw">return var0.isEnabled() && var0.isRulesActive() && var0.getShape().contains(var0.getPosition(), var1);
}
class="kw">private class="kw">static boolean containsRule(@Nonnull List<TriggerRule> var0, @Nonnull Class<? class="kw">extends TriggerRule> var1) {
for (TriggerRule var3 : var0) {
if (var3.isEnabled() && var1.isInstance(var3)) {
class="kw">return true;
}
}
class="kw">return false;
}
class="kw">private class="kw">static <T class="kw">extends TriggerRule> void collectRules(@Nonnull List<TriggerRule> var0, @Nonnull Class<T> var1, @Nonnull List<T> var2) {
for (TriggerRule var4 : var0) {
if (var4.isEnabled() && var1.isInstance(var4)) {
var2.add(var1.cast(var4));
}
}
}
@Nonnull
class="kw">public VolumeSpatialIndex getSpatialIndex() {
class="kw">return this.spatialIndex;
}
@Nonnull
class="kw">public DelayedEffectScheduler getDelayedEffectScheduler() {
class="kw">return this.delayedEffectScheduler;
}
class="kw">public void setWorld(@Nullable World var1) {
this.world = var1;
}
@Nullable
class="kw">public World getWorld() {
class="kw">return this.world;
}
class="kw">public void registerGroup(@Nonnull String var1, @Nonnull GroupEntry var2) {
if (var2.getName() == null) {
var2.setName(generateDefaultName("tvg_"));
}
this.groups.put(var1, var2);
}
class="kw">private class="kw">static String generateDefaultName(@Nonnull String var0) {
ThreadLocalRandom var1 = ThreadLocalRandom.current();
StringBuilder var2 = new StringBuilder(var0);
for (int var3 = 0; var3 < 6; var3++) {
var2.append("abcdefghijklmnopqrstuvwxyz0123456789".charAt(var1.nextInt("abcdefghijklmnopqrstuvwxyz0123456789".length())));
}
class="kw">return var2.toString();
}
@Nonnull
class="kw">public String makeUniqueVolumeName(@Nullable String var1, @Nullable String var2) {
class="kw">return this.makeUniqueName(var1, "tv_", var2x -> this.isVolumeNameFree(var2x, var2));
}
class="kw">private boolean isVolumeNameFree(@Nonnull String var1, @Nullable String var2) {
for (Entry var4 : this.volumes.entrySet()) {
if (!var4.getKey().equals(var2) && var1.equals(var4.getValue().getName())) {
class="kw">return false;
}
}
class="kw">return true;
}
@Nonnull
class="kw">public String makeUniqueGroupName(@Nullable String var1, @Nullable String var2) {
class="kw">return this.makeUniqueName(var1, "tvg_", var2x -> this.isGroupNameFree(var2x, var2));
}
@Nonnull
class="kw">private String makeUniqueName(@Nullable String var1, @Nonnull String var2, @Nonnull Predicate<String> var3) {
String var4 = var1 != null ? var1.trim() : "";
if (var4.isEmpty()) {
class="kw">return generateDefaultName(var2);
}
if (var3.test(var4)) {
class="kw">return var4;
}
Matcher var5 = NUMBERED_SUFFIX.matcher(var4);
String var6 = var5.matches() ? var5.group(1) : var4;
int var7 = 2;
while (true) {
String var8 = var6 + " (" + var7 + ")";
if (var3.test(var8)) {
class="kw">return var8;
}
var7++;
}
}
class="kw">private boolean isGroupNameFree(@Nonnull String var1, @Nullable String var2) {
for (Entry var4 : this.groups.entrySet()) {
if (!var4.getKey().equals(var2) && var1.equals(var4.getValue().getName())) {
class="kw">return false;
}
}
class="kw">return true;
}
class="kw">public void unregisterGroup(@Nonnull String var1) {
this.groups.remove(var1);
}
@Nullable
class="kw">public GroupEntry getGroup(@Nonnull String var1) {
class="kw">return this.groups.get(var1);
}
class="kw">public boolean hasGroup(@Nonnull String var1) {
class="kw">return this.groups.containsKey(var1);
}
class="kw">public void clearPrefabGroupLinkRemap() {
this.prefabGroupLinkRemap.clear();
}
@Nonnull
class="kw">public String ensureGroupForPrefabLink(@Nonnull String var1, @Nonnull VolumeEntry var2, @Nonnull String var3) {
class="kw">return this.prefabGroupLinkRemap
.computeIfAbsent(
var1,
var3x -> {
String var4 = this.generateUniquePastedGroupId();
int var5 = var2.getColor() != null
? packRgb(var2.getColor())
: (int)(COLOR_ENABLED.x() * 255.0F) << 16 | (int)(COLOR_ENABLED.y() * 255.0F) << 8 | (int)(COLOR_ENABLED.z() * 255.0F);
GroupEntry var6 = new GroupEntry(
var4, var3, new Vector3d(var2.getPosition()), new ArrayList<>(), EnumSet.copyOf(var2.getTargetTypes()), var2.isEnabled(), var5
);
this.registerGroup(var4, var6);
class="kw">return var4;
}
);
}
@Nonnull
class="kw">public String upsertGroupForPrefabLink(@Nonnull String var1, @Nonnull TriggerVolumeGroup var2, @Nonnull String var3, @Nonnull Vector3d var4, float var5) {
String var6 = this.prefabGroupLinkRemap.computeIfAbsent(var1, var1x -> this.generateUniquePastedGroupId());
GroupEntry var7 = this.groups.get(var6);
if (var7 == null) {
GroupEntry var8 = var2.toGroupEntry(var6, var3, new Vector3d(var4), var5);
var8.setName(this.makeUniqueGroupName(var8.getName(), var6));
this.registerGroup(var6, var8);
} else {
var2.applyTo(var7, new Vector3d(var4), var5);
var7.setName(this.makeUniqueGroupName(var7.getName(), var6));
}
class="kw">return var6;
}
@Nullable
class="kw">public String ensureWorldGenGroup(int var1, @Nonnull String var2, @Nonnull VolumeEntry var3, @Nonnull String var4) {
String var5 = getWorldGenGroupId(var1, var2);
if (var5 == null) {
class="kw">return null;
}
if (this.groups.containsKey(var5)) {
class="kw">return var5;
}
int var6 = var3.getColor() != null
? packRgb(var3.getColor())
: (int)(COLOR_ENABLED.x() * 255.0F) << 16 | (int)(COLOR_ENABLED.y() * 255.0F) << 8 | (int)(COLOR_ENABLED.z() * 255.0F);
GroupEntry var7 = new GroupEntry(
var5, var4, new Vector3d(var3.getPosition()), new ArrayList<>(), EnumSet.copyOf(var3.getTargetTypes()), var3.isEnabled(), var6
);
this.registerGroup(var5, var7);
class="kw">return var5;
}
@Nullable
class="kw">public String upsertWorldGenGroup(int var1, @Nonnull String var2, @Nonnull TriggerVolumeGroup var3, @Nonnull String var4, @Nonnull Vector3d var5, float var6) {
String var7 = getWorldGenGroupId(var1, var2);
if (var7 == null) {
class="kw">return null;
}
GroupEntry var8 = this.groups.get(var7);
if (var8 == null) {
this.registerGroup(var7, var3.toGroupEntry(var7, var4, new Vector3d(var5), var6));
} else {
var3.applyTo(var8, new Vector3d(var5), var6);
}
class="kw">return var7;
}
@Nullable
class="kw">private class="kw">static String getWorldGenGroupId(int var0, @Nonnull String var1) {
String var2 = sanitizeWorldGenLinkId(var1);
class="kw">return var2.isEmpty() ? null : "tvg_wg_" + Integer.toUnsignedString(var0, 36) + "_" + var2;
}
@Nonnull
class="kw">private class="kw">static String sanitizeWorldGenLinkId(@Nonnull String var0) {
String var1 = var0.toLowerCase(Locale.ROOT);
StringBuilder var2 = new StringBuilder(var1.length());
for (int var3 = 0; var3 < var1.length(); var3++) {
char var4 = var1.charAt(var3);
if (var4 >= 'a' && var4 <= 'z' || var4 >= '0' && var4 <= '9' || var4 == '_') {
var2.append(var4);
}
}
class="kw">return var2.toString();
}
@Nonnull
class="kw">public String generateUniqueVolumeId() {
String var1;
do {
var1 = UUID.randomUUID().toString();
} while (this.hasVolume(var1));
class="kw">return var1;
}
@Nonnull
class="kw">private String generateUniquePastedGroupId() {
String var1;
do {
var1 = UUID.randomUUID().toString();
} while (this.hasGroup(var1));
class="kw">return var1;
}
class="kw">private class="kw">static int packRgb(@Nonnull Vector3f var0) {
int var1 = Math.min(255, Math.max(0, Math.round(var0.x() * 255.0F))) & 0xFF;
int var2 = Math.min(255, Math.max(0, Math.round(var0.y() * 255.0F))) & 0xFF;
int var3 = Math.min(255, Math.max(0, Math.round(var0.z() * 255.0F))) & 0xFF;
class="kw">return var1 << 16 | var2 << 8 | var3;
}
@Nonnull
class="kw">public Map<String, GroupEntry> getGroupsMap() {
class="kw">return Collections.unmodifiableMap(this.groups);
}
@Nonnull
class="kw">public List<VolumeEntry> getGroupMembers(@Nonnull String var1) {
ArrayList var2 = new ArrayList<>();
for (VolumeEntry var4 : this.volumes.values()) {
if (var1.equals(var4.getGroupId())) {
var2.add(var4);
}
}
class="kw">return var2;
}
@Nonnull
class="kw">public List<VolumeEntry> getVolumesByTag(int var1) {
ArrayList var2 = new ArrayList<>();
for (VolumeEntry var4 : this.volumes.values()) {
if (var4.hasTag(var1)) {
var2.add(var4);
}
}
class="kw">return var2;
}
@Nonnull
class="kw">public List<GroupEntry> getGroupsByTag(int var1) {
ArrayList var2 = new ArrayList<>();
for (GroupEntry var4 : this.groups.values()) {
if (var4.hasTag(var1)) {
var2.add(var4);
}
}
class="kw">return var2;
}
class="kw">public boolean setTag(@Nonnull String var1, @Nonnull String var2, @Nullable String var3, @Nullable Ref<EntityStore> var4, @Nonnull UUID var5) {
VolumeEntry var6 = this.volumes.get(var1);
if (var6 == null) {
class="kw">return false;
}
String var7 = var2.trim();
if (var7.isEmpty()) {
class="kw">return false;
}
String var8 = TaggedVolumeEffectUtil.normalizeTagValue(var3);
String var9 = var6.getRawTags().get(var7);
if (Objects.equals(var9, var8)) {
class="kw">return false;
}
LinkedHashMap var10 = new LinkedHashMap<>(var6.getRawTags());
var10.put(var7, var8);
var6.setTags(var10);
this.enqueuePendingEvent(
new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.TAG_ADDED, var4, var5, var1, null, null, List.of(new SignalTag(var7, var8)), null)
);
class="kw">return true;
}
class="kw">public boolean removeTag(@Nonnull String var1, @Nonnull String var2, @Nullable Ref<EntityStore> var3, @Nonnull UUID var4) {
class="kw">return this.removeTag(var1, var2, null, var3, var4);
}
class="kw">public boolean removeTag(@Nonnull String var1, @Nonnull String var2, @Nullable String var3, @Nullable Ref<EntityStore> var4, @Nonnull UUID var5) {
VolumeEntry var6 = this.volumes.get(var1);
if (var6 == null) {
class="kw">return false;
}
String var7 = var2.trim();
if (!var7.isEmpty() && var6.getRawTags().containsKey(var7)) {
String var8 = var6.getRawTags().get(var7);
String var9 = TaggedVolumeEffectUtil.blankToNull(var3);
if (var9 != null && !Objects.equals(var8, var9)) {
class="kw">return false;
}
LinkedHashMap var10 = new LinkedHashMap<>(var6.getRawTags());
var10.remove(var7);
var6.setTags(var10);
this.enqueuePendingEvent(
new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.TAG_REMOVED, var4, var5, var1, null, null, List.of(new SignalTag(var7, var8)), null)
);
class="kw">return true;
} else {
class="kw">return false;
}
}
class="kw">public void enqueueBlockEvent(
@Nonnull TriggerEventType var1, @Nonnull Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull Vector3d var4, @Nonnull String var5
) {
this.enqueueBlockEvent(var1, var2, var3, var4, var5, null);
}
class="kw">public void enqueueBlockEvent(
@Nonnull TriggerEventType var1,
@Nonnull Ref<EntityStore> var2,
@Nonnull UUID var3,
@Nonnull Vector3d var4,
@Nonnull String var5,
@Nullable InteractionType var6
) {
this.enqueuePendingEvent(new TriggerVolumeManager.PendingTriggerEvent(var1, var2, var3, null, new Vector3d(var4), var5, List.of(), var6));
}
class="kw">public void enqueueEntityUseEvent(
@Nonnull Ref<EntityStore> var1, @Nonnull UUID var2, @Nonnull Vector3d var3, @Nullable String var4, @Nullable InteractionType var5
) {
this.enqueuePendingEvent(
new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.BLOCK_USED, var1, var2, null, new Vector3d(var3), var4, List.of(), var5)
);
}
class="kw">public void enqueueEnvironmentBlockEvent(@Nonnull TriggerEventType var1, @Nonnull Vector3d var2, @Nonnull String var3) {
this.enqueuePendingEvent(
new TriggerVolumeManager.PendingTriggerEvent(var1, null, ENVIRONMENT_ACTOR_UUID, null, new Vector3d(var2), var3, List.of(), null)
);
}
class="kw">public void enqueuePositionalEvent(@Nonnull TriggerEventType var1, @Nonnull Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull Vector3d var4) {
this.enqueuePendingEvent(new TriggerVolumeManager.PendingTriggerEvent(var1, var2, var3, null, new Vector3d(var4), null, List.of(), null));
}
class="kw">public void enqueueVolumeCreateEvent(@Nonnull VolumeEntry var1, @Nullable Ref<EntityStore> var2, @Nonnull UUID var3) {
this.enqueuePendingEvent(
new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.VOLUME_CREATE, var2, var3, var1.getId(), null, null, List.of(), null)
);
}
class="kw">public void enqueueVolumeEvent(
@Nonnull TriggerEventType var1, @Nonnull Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull String var4, @Nullable String var5, @Nullable String var6
) {
this.enqueueVolumeEvent(var1, var2, var3, var4, var5 == null ? List.of() : List.of(new SignalTag(var5, var6)));
}
class="kw">public void enqueueVolumeEvent(
@Nonnull TriggerEventType var1, @Nullable Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull String var4, @Nonnull List<SignalTag> var5
) {
this.enqueueVolumeEvent(var1, var2, var3, var4, var5, null, null);
}
class="kw">public void enqueueVolumeEvent(
@Nonnull TriggerEventType var1,
@Nullable Ref<EntityStore> var2,
@Nonnull UUID var3,
@Nonnull String var4,
@Nonnull List<SignalTag> var5,
@Nullable Vector3d var6,
@Nullable String var7
) {
this.enqueuePendingEvent(new TriggerVolumeManager.PendingTriggerEvent(var1, var2, var3, var4, var6 != null ? new Vector3d(var6) : null, var7, var5, null));
}
@Nullable
class="kw">public TriggerVolumeManager.PendingTriggerEvent pollPendingEvent() {
class="kw">return this.pendingEvents.pollFirst();
}
class="kw">public boolean hasPendingEvents() {
class="kw">return !this.pendingEvents.isEmpty();
}
class="kw">private void enqueuePendingEvent(@Nonnull TriggerVolumeManager.PendingTriggerEvent var1) {
this.pendingEvents.addLast(var1);
}
class="kw">public boolean isViewing(@Nonnull UUID var1) {
EnumSet var2 = this.activeViewers.get(var1);
class="kw">return var2 != null && !var2.isEmpty();
}
class="kw">public boolean isViewing(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.ViewSource var2) {
EnumSet var3 = this.activeViewers.get(var1);
class="kw">return var3 != null && var3.contains(var2);
}
@Nullable
class="kw">public EnumSet<TriggerVolumeManager.ViewSource> peekViewerSources(@Nonnull UUID var1) {
EnumSet var2 = this.activeViewers.get(var1);
class="kw">return var2 != null ? EnumSet.copyOf(var2) : null;
}
class="kw">public void addViewer(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.ViewSource var2) {
this.activeViewers.computeIfAbsent(var1, var0 -> EnumSet.noneOf(TriggerVolumeManager.ViewSource.class)).add(var2);
}
class="kw">public void removeViewer(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.ViewSource var2) {
this.activeViewers.computeIfPresent(var1, (var1x, var2x) -> {
var2x.remove(var2);
class="kw">return var2x.isEmpty() ? null : var2x;
});
}
class="kw">public void setPlayerSelection(@Nonnull UUID var1, @Nullable String var2) {
if (var2 == null) {
this.playerSelections.remove(var1);
} else {
this.playerSelections.put(var1, var2);
}
TriggerVolumeManager.SelectionObserver var3 = this.selectionObservers.get(var1);
if (var3 != null) {
var3.onSelectionChanged(var2);
}
}
@Nullable
class="kw">public String getPlayerSelection(@Nonnull UUID var1) {
class="kw">return this.playerSelections.get(var1);
}
class="kw">public void setSelectionObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.SelectionObserver var2) {
this.selectionObservers.put(var1, var2);
}
class="kw">public void clearSelectionObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.SelectionObserver var2) {
this.selectionObservers.remove(var1, var2);
}
class="kw">public void setVolumeUpdateObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.VolumeUpdateObserver var2) {
this.volumeUpdateObservers.put(var1, var2);
}
class="kw">public void clearVolumeUpdateObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.VolumeUpdateObserver var2) {
this.volumeUpdateObservers.remove(var1, var2);
}
class="kw">public void notifyViewers() {
this.markClientRuleVolumesDirty();
if (!this.activeViewers.isEmpty()) {
TriggerVolumeDisplayEntry[] var1 = this.buildDisplayEntries();
UpdateTriggerVolumeDisplay var2 = new UpdateTriggerVolumeDisplay(var1);
for (UUID var4 : this.activeViewers.keySet()) {
PlayerRef var5 = Universe.get().getPlayer(var4);
if (var5 != null) {
var5.getPacketHandler().write(var2);
}
}
}
}
class="kw">public int getViewerCount() {
class="kw">return this.activeViewers.size();
}
@Nonnull
class="kw">public Set<UUID> getViewerUuids() {
class="kw">return new HashSet<>(this.activeViewers.keySet());
}
class="kw">public void clearViewers() {
this.activeViewers.clear();
this.playerSelections.clear();
}
class="kw">public void notifyViewersAdd(@Nonnull VolumeEntry var1) {
this.markClientRuleVolumesDirty();
if (!this.activeViewers.isEmpty()) {
AddOrUpdateTriggerVolumeDisplay var2 = new AddOrUpdateTriggerVolumeDisplay(var1.getId(), this.buildDisplayEntry(var1));
for (UUID var4 : this.activeViewers.keySet()) {
PlayerRef var5 = Universe.get().getPlayer(var4);
if (var5 != null) {
var5.getPacketHandler().write(var2);
}
}
}
for (TriggerVolumeManager.VolumeUpdateObserver var7 : this.volumeUpdateObservers.values()) {
var7.onVolumeUpdated(var1);
}
}
class="kw">public void notifyViewersRemove(@Nonnull String var1) {
this.markClientRuleVolumesDirty();
if (!this.activeViewers.isEmpty()) {
RemoveTriggerVolumeDisplay var2 = new RemoveTriggerVolumeDisplay(var1);
for (UUID var4 : this.activeViewers.keySet()) {
PlayerRef var5 = Universe.get().getPlayer(var4);
if (var5 != null) {
var5.getPacketHandler().write(var2);
}
}
}
for (TriggerVolumeManager.VolumeUpdateObserver var7 : this.volumeUpdateObservers.values()) {
var7.onVolumeRemoved(var1);
}
}
class="kw">public void notifyViewersLegacyVolumeSkipped() {
if (!this.activeViewers.isEmpty()) {
Message var1 = Message.translation("server.triggervolumes.legacyVolumeSkipped");
for (UUID var3 : this.activeViewers.keySet()) {
PlayerRef var4 = Universe.get().getPlayer(var3);
if (var4 != null) {
var4.sendMessage(var1);
}
}
}
}
class="kw">public void sendVolumeDisplay(@Nonnull PlayerRef var1) {
var1.getPacketHandler().write(new UpdateTriggerVolumeDisplay(this.buildDisplayEntries()));
}
@Nonnull
class="kw">private TriggerVolumeDisplayEntry[] buildDisplayEntries() {
Collection var1 = this.volumes.values();
TriggerVolumeDisplayEntry[] var2 = new TriggerVolumeDisplayEntry[var1.size()];
int var3 = 0;
for (VolumeEntry var5 : var1) {
var2[var3++] = this.buildDisplayEntry(var5);
}
class="kw">return var2;
}
@Nonnull
class="kw">public TriggerVolumeDisplayEntry buildDisplayEntry(@Nonnull VolumeEntry var1) {
TriggerVolumeDisplayEntry var2 = new TriggerVolumeDisplayEntry();
TriggerVolumeManager.VolumeGeometry var3 = computeGeometry(var1);
var2.shapeType = var3.shapeType();
var2.position = var3.position();
var2.dimensions = var3.dimensions();
if (var3.rotation() != null) {
var2.rotation = var3.rotation();
}
var2.color = var1.getColor() != null ? var1.getColor() : (var1.isEnabled() ? COLOR_ENABLED : COLOR_DISABLED);
var2.opacity = var1.isEnabled() ? 0.3F : 0.15F;
var2.volumeId = var1.getId();
var2.name = var1.getName();
var2.effectAssetRef = var1.getEffectAssetRef();
int var4 = 0;
for (EntityTargetType var6 : var1.getTargetTypes()) {
var4 |= class="kw">switch (var6) {
case PLAYER -> 1;
case NPC -> 2;
case ITEM_DROP -> 4;
case PROJECTILE -> 8;
};
}
var2.targetTypes = (byte)var4;
var2.keepLoaded = var1.isKeepLoaded();
var2.cancelDelayedOnExit = var1.isCancelDelayedEffectsOnExit();
var2.cooldown = var1.getCooldown();
var2.cooldownMode = (byte)var1.getCooldownMode().ordinal();
var2.activationDelay = var1.getActivationDelay();
var2.conditionTiming = var1.getConditionTiming() == ConditionTiming.BEFORE_VOLUME_DELAY
? TriggerVolumeConditionTiming.BeforeVolumeDelay
: TriggerVolumeConditionTiming.AfterVolumeDelay;
if (var1.getGroupId() != null) {
var2.groupId = var1.getGroupId();
GroupEntry var9 = this.groups.get(var1.getGroupId());
if (var9 != null) {
var2.groupColor = var9.getColor();
float var10 = (var9.getColor() >> 16 & 0xFF) / 255.0F;
float var7 = (var9.getColor() >> 8 & 0xFF) / 255.0F;
float var8 = (var9.getColor() & 0xFF) / 255.0F;
var2.color = new Vector3f(var10, var7, var8);
}
}
class="kw">return var2;
}
@Nonnull
class="kw">private class="kw">static TriggerVolumeManager.VolumeGeometry computeGeometry(@Nonnull VolumeEntry var0) {
Vector3d var1 = var0.getPosition();
TriggerVolumeShape var2 = var0.getShape();
if (var2 class="kw">instanceof BoxShape var12) {
Vector3d var14 = var12.getMin();
Vector3d var15 = var12.getMax();
Vector3f var8 = new Vector3f(
(float)(var1.x() + (var14.x() + var15.x()) * 0.5),
(float)(var1.y() + (var14.y() + var15.y()) * 0.5),
(float)(var1.z() + (var14.z() + var15.z()) * 0.5)
);
Vector3f var9 = new Vector3f((float)((var15.x() - var14.x()) * 0.5), (float)((var15.y() - var14.y()) * 0.5), (float)((var15.z() - var14.z()) * 0.5));
Vector3d var10 = var12.getRotation();
Vector3f var11 = var10 != null ? new Vector3f((float)var10.x(), (float)var10.y(), (float)var10.z()) : null;
class="kw">return new TriggerVolumeManager.VolumeGeometry(TriggerVolumeShapeType.Box, var8, var9, var11);
} else if (var2 class="kw">instanceof SphereShape var4) {
Vector3d var13 = var4.getCenter();
class="kw">return new TriggerVolumeManager.VolumeGeometry(
TriggerVolumeShapeType.Sphere,
new Vector3f((float)(var1.x() + var13.x()), (float)(var1.y() + var13.y()), (float)(var1.z() + var13.z())),
new Vector3f((float)var4.getRadius(), 0.0F, 0.0F),
null
);
} else if (var2 class="kw">instanceof CylinderShape var5) {
Vector3d var6 = var5.getCenter();
double var7 = var5.getHeight() * 0.5;
class="kw">return new TriggerVolumeManager.VolumeGeometry(
TriggerVolumeShapeType.Cylinder,
new Vector3f((float)(var1.x() + var6.x()), (float)(var1.y() + var6.y() + var7), (float)(var1.z() + var6.z())),
new Vector3f((float)var5.getRadius(), (float)var5.getHeight(), 0.0F),
null
);
} else {
double var3 = var2.getBoundingRadius();
class="kw">return new TriggerVolumeManager.VolumeGeometry(
TriggerVolumeShapeType.Sphere, new Vector3f((float)var1.x(), (float)var1.y(), (float)var1.z()), new Vector3f((float)var3, 0.0F, 0.0F), null
);
}
}
class="kw">public void markClientRuleVolumesDirty() {
this.clientRuleVolumesDirty = true;
this.tickSuppressionDirty = true;
}
class="kw">public void flushTickSuppressionIfDirty(@Nonnull TickSuppressionRegistry var1) {
if (this.tickSuppressionDirty) {
this.tickSuppressionDirty = false;
TickSuppressionSnapshot var2 = this.buildTickSuppressionSnapshot();
var1.setSnapshot(var2, var2 == null ? 0 : var2.activeKinds());
}
}
@Nullable
class="kw">private TickSuppressionSnapshot buildTickSuppressionSnapshot() {
ArrayList var1 = new ArrayList<>();
for (VolumeEntry var3 : this.volumes.values()) {
if (var3.isEnabled() && var3.isRulesActive()) {
NoTickRule var4 = this.findActiveNoTickRule(var3);
if (var4 != null) {
int var5 = (var4.suppressesScheduled() ? 1 : 0) | (var4.suppressesRandom() ? 2 : 0);
if (var5 != 0) {
var1.add(new TickSuppressionSnapshot.Region(new Vector3d(var3.getPosition()), var3.getShape(), var5));
}
}
}
}
class="kw">return var1.isEmpty() ? null : new TickSuppressionSnapshot(var1);
}
@Nullable
class="kw">private NoTickRule findActiveNoTickRule(@Nonnull VolumeEntry var1) {
for (TriggerRule var3 : var1.getRules()) {
if (var3.isEnabled() && var3 class="kw">instanceof NoTickRule var4) {
class="kw">return var4;
}
}
GroupEntry var6 = var1.getGroupId() != null ? this.groups.get(var1.getGroupId()) : null;
if (var6 != null && var6.isEnabled()) {
for (TriggerRule var8 : var6.getRules()) {
if (var8.isEnabled() && var8 class="kw">instanceof NoTickRule var5) {
class="kw">return var5;
}
}
}
class="kw">return null;
}
class="kw">public void flushClientRuleVolumesIfDirty() {
if (this.clientRuleVolumesDirty) {
this.clientRuleVolumesDirty = false;
this.broadcastClientRuleVolumes();
}
}
class="kw">public void broadcastClientRuleVolumes() {
if (this.world != null) {
UpdateClientRuleVolumes var1 = new UpdateClientRuleVolumes(this.buildClientRuleVolumes());
for (PlayerRef var3 : this.world.getPlayerRefs()) {
var3.getPacketHandler().write(var1);
}
}
}
class="kw">public void sendClientRuleVolumes(@Nonnull PlayerRef var1) {
var1.getPacketHandler().write(new UpdateClientRuleVolumes(this.buildClientRuleVolumes()));
}
@Nonnull
class="kw">private ClientRuleVolume[] buildClientRuleVolumes() {
ArrayList var1 = new ArrayList<>();
for (VolumeEntry var3 : this.volumes.values()) {
ClientRuleVolume var4 = this.buildClientRuleVolume(var3);
if (var4 != null) {
var1.add(var4);
}
}
class="kw">return var1.toArray(new ClientRuleVolume[0]);
}
@Nullable
class="kw">private ClientRuleVolume buildClientRuleVolume(@Nonnull VolumeEntry var1) {
if (var1.isEnabled() && var1.isRulesActive()) {
byte var2 = 0;
IntOpenHashSet var3 = new IntOpenHashSet();
IntOpenHashSet var4 = new IntOpenHashSet();
IntOpenHashSet var5 = new IntOpenHashSet();
LinkedHashSet var6 = new LinkedHashSet<>();
for (TriggerRule var8 : var1.getRules()) {
var2 = accumulateRule(var8, var2, var3, var4, var5, var6);
}
if (var1.getGroupId() != null) {
GroupEntry var10 = this.groups.get(var1.getGroupId());
if (var10 != null && var10.isEnabled()) {
for (TriggerRule var9 : var10.getRules()) {
var2 = accumulateRule(var9, var2, var3, var4, var5, var6);
}
}
}
if (var2 == 0) {
class="kw">return null;
}
TriggerVolumeManager.VolumeGeometry var11 = computeGeometry(var1);
ClientRuleVolume var13 = new ClientRuleVolume();
var13.rules = var2;
var13.shapeType = var11.shapeType();
var13.position = var11.position();
var13.dimensions = var11.dimensions();
var13.rotation = var11.rotation() != null ? var11.rotation() : new Vector3f();
var13.buildExceptBlocks = toIntArrayOrNull(var3);
var13.destroyExceptBlocks = toIntArrayOrNull(var4);
var13.harvestExceptBlocks = toIntArrayOrNull(var5);
var13.destroyExceptTools = var6.isEmpty() ? null : var6.toArray(new String[0]);
class="kw">return var13;
} else {
class="kw">return null;
}
}
class="kw">private class="kw">static byte accumulateRule(
@Nonnull TriggerRule var0, byte var1, @Nonnull IntOpenHashSet var2, @Nonnull IntOpenHashSet var3, @Nonnull IntOpenHashSet var4, @Nonnull Set<String> var5
) {
if (!var0.isEnabled()) {
class="kw">return var1;
}
if (var0 class="kw">instanceof NoBuildRule var6) {
var1 = (byte)(var1 | 1);
var6.collectExceptBlockIds(var2);
} else if (var0 class="kw">instanceof NoDestroyRule var7) {
var1 = (byte)(var1 | 2);
var7.collectExceptBlockIds(var3);
var7.collectExceptToolKeys(var5);
} else if (var0 class="kw">instanceof NoHarvestRule var8) {
var1 = (byte)(var1 | 4);
var8.collectExceptBlockIds(var4);
} else if (var0 class="kw">instanceof NoDamageRule var9 && var9.getEntityFilter() == RuleEntityFilter.ALL) {
var1 = (byte)(var1 | (var9.isPvpOnly() ? 16 : 8));
}
class="kw">return var1;
}
@Nullable
class="kw">private class="kw">static int[] toIntArrayOrNull(@Nonnull IntOpenHashSet var0) {
class="kw">return var0.isEmpty() ? null : var0.toIntArray();
}
@Nonnull
@Override
class="kw">public Resource<EntityStore> clone() {
throw new UnsupportedOperationException("TriggerVolumeManager cannot be cloned");
}
class="kw">public record ActiveRule<T class="kw">extends TriggerRule>(@Nonnull T rule, @Nonnull VolumeEntry volume) {
class="kw">public ActiveRule {
}
}
class="kw">public record PendingTriggerEvent(
@Nonnull TriggerEventType eventType,
@Nullable Ref<EntityStore> actorRef,
@Nonnull UUID actorUuid,
@Nullable String volumeId,
@Nullable Vector3d blockPosition,
@Nullable String blockId,
@Nonnull List<SignalTag> signalTags,
@Nullable InteractionType interactionType
) {
class="kw">public PendingTriggerEvent {
}
}
class="kw">public class="kw">interface SelectionObserver {
void onSelectionChanged(@Nullable String var1);
}
class="kw">public enum ViewSource {
COMMAND,
TOOL,
SELECTION_TOOL;
ViewSource() {
}
}
class="kw">private record VolumeGeometry(
@Nonnull TriggerVolumeShapeType shapeType, @Nonnull Vector3f position, @Nonnull Vector3f dimensions, @Nullable Vector3f rotation
) {
class="kw">private VolumeGeometry {
}
}
class="kw">public class="kw">interface VolumeUpdateObserver {
void onVolumeUpdated(@Nonnull VolumeEntry var1);
void onVolumeRemoved(@Nonnull String var1);
}
}