BlockSearchConsumer class
Пакет: com.hypixel.hytale.server.core.modules.interaction.interaction.config.server
Файл: com/hypixel/hytale/server/core/modules/interaction/interaction/config/server/RunOnBlockTypesInteraction.java
implements: IntConsumer
Поля (20)
| Модификаторы | Тип | Имя |
|---|---|---|
|
private int |
chunkWorldX |
|
private int |
chunkWorldZ |
|
private final int |
maxCount |
|
private final int |
originX |
|
private final int |
originY |
|
private final int |
originZ |
|
private final List<Vector3i> |
picked |
|
private final int |
radiusSquared |
|
private int |
sectionBaseY |
|
private int |
seen |
|
int |
var10 |
|
int |
var11 |
|
int |
var2 |
|
int |
var3 |
|
int |
var4 |
|
int |
var5 |
|
int |
var6 |
|
int |
var7 |
|
int |
var8 |
|
int |
var9 |
Методы (5)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
|
public void |
acceptpublic void accept(int var1) |
|
List<Vector3i> |
getPickedPositionsList<Vector3i> getPickedPositions() |
|
|
if if(var8 * var8 + var9 * var9 + var10 * var10 <= this.radiusSquared) |
|
|
if if(var11 < this.maxCount) |
|
void |
setSectionvoid setSection(int var1, int var2, int var3) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.modules.interaction.interaction.config.server;
class="kw">import com.hypixel.hytale.codec.Codec;
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.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.protocol.BlockPosition;
class="kw">import com.hypixel.hytale.protocol.InteractionState;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.protocol.WaitForDataFrom;
class="kw">import com.hypixel.hytale.server.core.asset.type.blockset.config.BlockSet;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionChain;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionContext;
class="kw">import com.hypixel.hytale.server.core.meta.DynamicMetaStore;
class="kw">import com.hypixel.hytale.server.core.meta.MetaKey;
class="kw">import com.hypixel.hytale.server.core.modules.blockset.BlockSetModule;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.SimpleInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.client.SimpleBlockInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.operation.Label;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.operation.OperationsBuilder;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.ints.IntArrayList;
class="kw">import it.unimi.dsi.fastutil.ints.IntConsumer;
class="kw">import it.unimi.dsi.fastutil.ints.IntList;
class="kw">import it.unimi.dsi.fastutil.ints.IntSet;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.util.List;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.checkerframework.checker.nullness.compatqual.NonNullDecl;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3i;
class="kw">public class RunOnBlockTypesInteraction class="kw">extends SimpleInteraction {
@Nonnull
class="kw">public class="kw">static class="kw">final BuilderCodec<RunOnBlockTypesInteraction> CODEC = BuilderCodec.builder(
RunOnBlockTypesInteraction.class, RunOnBlockTypesInteraction::new, SimpleInteraction.CODEC
)
.documentation("Searches for matching block types within a radius and runs interactions on each found block up to a configured maximum number of blocks.")
.<Integer>appendInherited(
new KeyedCodec<>("Range", Codec.INTEGER, true), (var0, var1) -> var0.range = var1, var0 -> var0.range, (var0, var1) -> var0.range = var1.range
)
.documentation("The spherical radius to search for matching block types.")
.addValidator(Validators.greaterThan(0))
.add()
.<String[]>appendInherited(
new KeyedCodec<>("BlockSets", new ArrayCodec<>(Codec.STRING, String[]::new), true),
(var0, var1) -> var0.blockSets = var1,
var0 -> var0.blockSets,
(var0, var1) -> var0.blockSets = var1.blockSets
)
.documentation("Array of BlockSet IDs to match within the search radius.")
.addValidator(Validators.nonEmptyArray())
.addValidatorLate(() -> BlockSet.VALIDATOR_CACHE.getArrayValidator().late())
.add()
.<Integer>appendInherited(
new KeyedCodec<>("MaxCount", Codec.INTEGER, true),
(var0, var1) -> var0.maxCount = var1,
var0 -> var0.maxCount,
(var0, var1) -> var0.maxCount = var1.maxCount
)
.documentation("Maximum number of block positions to select for running interactions (uses reservoir sampling).")
.addValidator(Validators.greaterThan(0))
.add()
.<String>appendInherited(
new KeyedCodec<>("Interactions", RootInteraction.CHILD_ASSET_CODEC, true),
(var0, var1) -> var0.interactions = var1,
var0 -> var0.interactions,
(var0, var1) -> var0.interactions = var1.interactions
)
.documentation("The interaction chain to run on each found block. Can be defined inline or as a reference.")
.addValidatorLate(() -> RootInteraction.VALIDATOR_CACHE.getValidator().late())
.add()
.build();
@Nonnull
class="kw">private class="kw">static class="kw">final MetaKey<List<InteractionChain>> FORKED_CHAINS = Interaction.META_REGISTRY.registerMetaObject(var0 -> null);
@Nonnull
class="kw">private class="kw">static class="kw">final MetaKey<Boolean> ANY_SUCCEEDED = Interaction.META_REGISTRY.registerMetaObject(var0 -> Boolean.FALSE);
@Nonnull
class="kw">public class="kw">static class="kw">final String[] EMPTY_BLOCKSETS = new String[0];
class="kw">protected int range;
@Nonnull
class="kw">protected String[] blockSets = EMPTY_BLOCKSETS;
class="kw">protected int maxCount;
@Nullable
class="kw">protected String interactions;
class="kw">protected RunOnBlockTypesInteraction() {
}
@Nonnull
@Override
class="kw">public WaitForDataFrom getWaitForDataFrom() {
class="kw">return WaitForDataFrom.Server;
}
@Override
class="kw">protected void tick0(boolean var1, float var2, @NonNullDecl InteractionType var3, @Nonnull InteractionContext var4, @NonNullDecl CooldownHandler var5) {
DynamicMetaStore var6 = var4.getInstanceStore();
if (!var1) {
List var21 = var6.getMetaObject(FORKED_CHAINS);
if (var21 != null && !var21.isEmpty()) {
boolean var22 = true;
boolean var23 = var6.getMetaObject(ANY_SUCCEEDED);
for (InteractionChain var25 : var21) {
class="kw">switch (var25.getServerState()) {
case NotFinished:
var22 = false;
break;
case Finished:
var23 = true;
case Failed:
case Skip:
case ItemChanged:
}
}
var6.putMetaObject(ANY_SUCCEEDED, var23);
if (!var22) {
var4.getState().state = InteractionState.NotFinished;
} else {
if (var23) {
var4.getState().state = InteractionState.Finished;
} else {
var4.getState().state = InteractionState.Failed;
}
super.tick0(var1, var2, var3, var4, var5);
}
} else {
var4.getState().state = InteractionState.Failed;
super.tick0(var1, var2, var3, var4, var5);
}
} else {
CommandBuffer var7 = var4.getCommandBuffer();
assert var7 != null;
Ref var8 = var4.getEntity();
TransformComponent var9 = var7.getComponent(var8, TransformComponent.getComponentType());
if (var9 == null) {
var4.getState().state = InteractionState.Failed;
super.tick0(var1, var2, var3, var4, var5);
} else {
World var10 = var7.getExternalData().getWorld();
Vector3d var11 = var9.getPosition();
List var12 = this.searchBlocks(var10, var11);
if (var12.isEmpty()) {
var4.getState().state = InteractionState.Failed;
super.tick0(var1, var2, var3, var4, var5);
} else if (this.interactions == null) {
var4.getState().state = InteractionState.Failed;
super.tick0(var1, var2, var3, var4, var5);
} else {
RootInteraction var13 = RootInteraction.getRootInteractionOrUnknown(this.interactions);
ObjectArrayList var14 = new ObjectArrayList(var12.size());
for (Vector3i var16 : var12) {
InteractionContext var17 = var4.duplicate();
BlockPosition var18 = new BlockPosition(var16.x, var16.y, var16.z);
var17.getMetaStore().putMetaObject(Interaction.TARGET_BLOCK, var18);
var17.getMetaStore().putMetaObject(Interaction.TARGET_BLOCK_RAW, var18);
BlockPosition var19 = SimpleBlockInteraction.resolveBaseBlockPosition(var10, var18);
var17.getMetaStore().putMetaObject(Interaction.TARGET_BLOCK, var19);
InteractionChain var20 = var4.fork(var17, var13, false);
var14.add(var20);
}
var6.putMetaObject(FORKED_CHAINS, var14);
var6.putMetaObject(ANY_SUCCEEDED, Boolean.FALSE);
var4.getState().state = InteractionState.NotFinished;
}
}
}
}
@Override
class="kw">protected void simulateTick0(
boolean var1, float var2, @NonNullDecl InteractionType var3, @Nonnull InteractionContext var4, @NonNullDecl CooldownHandler var5
) {
}
@Override
class="kw">public void compile(@Nonnull OperationsBuilder var1) {
if (this.next == null && this.failed == null) {
var1.addOperation(this);
} else {
Label var2 = var1.createUnresolvedLabel();
Label var3 = var1.createUnresolvedLabel();
var1.addOperation(this, var2);
if (this.next != null) {
Interaction var4 = Interaction.getInteractionOrUnknown(this.next);
var4.compile(var1);
}
if (this.failed != null) {
var1.jump(var3);
}
var1.resolveLabel(var2);
if (this.failed != null) {
Interaction var5 = Interaction.getInteractionOrUnknown(this.failed);
var5.compile(var1);
}
var1.resolveLabel(var3);
}
}
@Nonnull
class="kw">private List<Vector3i> searchBlocks(@Nonnull World var1, @Nonnull Vector3d var2) {
IntList var3 = this.getBlockIds();
if (var3.isEmpty()) {
class="kw">return List.of();
}
int var4 = MathUtil.floor(var2.x);
int var5 = MathUtil.floor(var2.y);
int var6 = MathUtil.floor(var2.z);
int var7 = this.range * this.range;
RunOnBlockTypesInteraction.BlockSearchConsumer var8 = new RunOnBlockTypesInteraction.BlockSearchConsumer(var4, var5, var6, var7, this.maxCount);
ChunkStore var9 = var1.getChunkStore();
Store var10 = var9.getStore();
for (int var11 = var4 - this.range & -32; var11 < var4 + this.range; var11 += 32) {
for (int var12 = var6 - this.range & -32; var12 < var6 + this.range; var12 += 32) {
for (int var13 = var5 - this.range & -32; var13 < var5 + this.range; var13 += 32) {
Ref var14 = var9.getChunkSectionReferenceAtBlock(var11, var13, var12);
if (var14 != null && var14.isValid()) {
BlockSection var15 = var10.getComponent(var14, BlockSection.getComponentType());
if (var15 != null && !var15.isSolidAir() && var15.containsAny(var3)) {
var8.setSection(var11, var12, ChunkUtil.chunkCoordinate(var13));
var15.find(var3, var8);
}
}
}
}
}
class="kw">return var8.getPickedPositions();
}
@Nonnull
class="kw">private IntList getBlockIds() {
IntArrayList var1 = new IntArrayList();
BlockSetModule var2 = BlockSetModule.getInstance();
Int2ObjectMap var3 = var2.getBlockSets();
for (String var7 : this.blockSets) {
int var8 = BlockSet.getAssetMap().getIndex(var7);
if (var8 != Integer.MIN_VALUE) {
IntSet var9 = (IntSet)var3.get(var8);
if (var9 != null) {
var1.addAll(var9);
}
}
}
class="kw">return var1;
}
@Override
class="kw">public boolean needsRemoteSync() {
class="kw">return true;
}
@Nonnull
@Override
class="kw">protected com.hypixel.hytale.protocol.Interaction generatePacket() {
class="kw">return new com.hypixel.hytale.protocol.SimpleInteraction();
}
@Override
class="kw">protected void configurePacket(com.hypixel.hytale.protocol.Interaction var1) {
super.configurePacket(var1);
com.hypixel.hytale.protocol.SimpleInteraction var2 = (com.hypixel.hytale.protocol.SimpleInteraction)var1;
var2.next = Interaction.getInteractionIdOrUnknown(this.next);
var2.failed = Interaction.getInteractionIdOrUnknown(this.failed);
}
@Nonnull
@Override
class="kw">public String toString() {
class="kw">return "RunOnBlockTypesInteraction{range="
+ this.range
+ ", maxCount="
+ this.maxCount
+ ", interactions='"
+ this.interactions
+ "'} "
+ super.toString();
}
class="kw">private class="kw">static class BlockSearchConsumer class="kw">implements IntConsumer {
class="kw">private class="kw">final int originX;
class="kw">private class="kw">final int originY;
class="kw">private class="kw">final int originZ;
class="kw">private class="kw">final int radiusSquared;
class="kw">private class="kw">final int maxCount;
class="kw">private class="kw">final List<Vector3i> picked;
class="kw">private int seen;
class="kw">private int chunkWorldX;
class="kw">private int chunkWorldZ;
class="kw">private int sectionBaseY;
BlockSearchConsumer(int var1, int var2, int var3, int var4, int var5) {
this.originX = var1;
this.originY = var2;
this.originZ = var3;
this.radiusSquared = var4;
this.maxCount = var5;
this.picked = new ObjectArrayList(var5);
}
void setSection(int var1, int var2, int var3) {
this.chunkWorldX = var1;
this.chunkWorldZ = var2;
this.sectionBaseY = var3 * 32;
}
class="kw">public void accept(int var1) {
int var2 = ChunkUtil.xFromIndex(var1);
int var3 = ChunkUtil.yFromIndex(var1);
int var4 = ChunkUtil.zFromIndex(var1);
int var5 = this.chunkWorldX + var2;
int var6 = this.sectionBaseY + var3;
int var7 = this.chunkWorldZ + var4;
int var8 = var5 - this.originX;
int var9 = var6 - this.originY;
int var10 = var7 - this.originZ;
if (var8 * var8 + var9 * var9 + var10 * var10 <= this.radiusSquared) {
if (this.picked.size() < this.maxCount) {
this.picked.add(new Vector3i(var5, var6, var7));
} else {
int var11 = ThreadLocalRandom.current().nextInt(this.seen + 1);
if (var11 < this.maxCount) {
this.picked.set(var11, new Vector3i(var5, var6, var7));
}
}
this.seen++;
}
}
@Nonnull
List<Vector3i> getPickedPositions() {
class="kw">return this.picked;
}
}
}