package com.hypixel.hytale.builtin.adventure.memories.interactions;
import com.hypixel.hytale.builtin.adventure.memories.MemoriesPlugin;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.codec.codecs.map.Int2ObjectMapCodec;
import com.hypixel.hytale.codec.validation.Validators;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.protocol.InteractionState;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.protocol.WaitForDataFrom;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.server.core.entity.InteractionManager;
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.Collector;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.CollectorTag;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.StringTag;
import com.hypixel.hytale.server.core.modules.interaction.interaction.operation.Label;
import com.hypixel.hytale.server.core.modules.interaction.interaction.operation.OperationsBuilder;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.Arrays;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class MemoriesConditionInteraction extends Interaction {
@Nonnull
public static final BuilderCodec<MemoriesConditionInteraction> CODEC;
@Nonnull
private static final StringTag TAG_FAILED;
@Nonnull
private Int2ObjectMap<String> next = Int2ObjectMaps.<String>emptyMap();
private transient int[] sortedKeys;
@Nonnull
private final Int2IntOpenHashMap levelToLabel = new Int2IntOpenHashMap();
@Nullable
private String failed;
public MemoriesConditionInteraction() {
}
protected void tick0(boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler) {
CommandBuffer<EntityStore> commandBuffer = context.getCommandBuffer();
assert commandBuffer != null;
World world = ((EntityStore)commandBuffer.getExternalData()).getWorld();
int memoriesLevel = MemoriesPlugin.get().getMemoriesLevel(world.getGameplayConfig());
context.getState().chainingIndex = memoriesLevel;
int labelIndex = this.levelToLabel.get(memoriesLevel);
if (labelIndex == -1) {
labelIndex = this.sortedKeys.length;
context.getState().state = InteractionState.Failed;
} else {
context.getState().state = InteractionState.Finished;
}
context.jump(context.getLabel(labelIndex));
}
protected void simulateTick0(boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler) {
int memoriesLevel = context.getServerState().chainingIndex;
int labelIndex = this.levelToLabel.get(memoriesLevel);
if (labelIndex == -1) {
labelIndex = this.sortedKeys.length;
context.getState().state = InteractionState.Failed;
} else {
context.getState().state = InteractionState.Finished;
}
context.jump(context.getLabel(labelIndex));
}
public void compile(@Nonnull OperationsBuilder builder) {
Label end = builder.createUnresolvedLabel();
Label[] labels = new Label[this.next.size() + 1];
for(int i = 0; i < labels.length; ++i) {
labels[i] = builder.createUnresolvedLabel();
}
builder.addOperation(this, labels);
builder.jump(end);
for(int i = 0; i < this.sortedKeys.length; ++i) {
int key = this.sortedKeys[i];
builder.resolveLabel(labels[i]);
Interaction interaction = Interaction.getInteractionOrUnknown((String)this.next.get(key));
interaction.compile(builder);
builder.jump(end);
}
int failedIndex = this.sortedKeys.length;
builder.resolveLabel(labels[failedIndex]);
if (this.failed != null) {
Interaction interaction = Interaction.getInteractionOrUnknown(this.failed);
interaction.compile(builder);
}
builder.resolveLabel(end);
}
@Nonnull
protected com.hypixel.hytale.protocol.Interaction generatePacket() {
return new com.hypixel.hytale.protocol.MemoriesConditionInteraction();
}
protected void configurePacket(com.hypixel.hytale.protocol.Interaction packet) {
super.configurePacket(packet);
com.hypixel.hytale.protocol.MemoriesConditionInteraction p = (com.hypixel.hytale.protocol.MemoriesConditionInteraction)packet;
p.memoriesNext = new Int2IntOpenHashMap(this.next.size());
for(Int2ObjectMap.Entry<String> e : this.next.int2ObjectEntrySet()) {
p.memoriesNext.put(e.getIntKey(), Interaction.getInteractionIdOrUnknown((String)e.getValue()));
}
p.failed = Interaction.getInteractionIdOrUnknown(this.failed);
}
public boolean walk(@Nonnull Collector collector, @Nonnull InteractionContext context) {
if (this.next != null) {
for(Int2ObjectMap.Entry<String> entry : this.next.int2ObjectEntrySet()) {
if (InteractionManager.walkInteraction(collector, context, new MemoriesTag(entry.getIntKey()), (String)entry.getValue())) {
return true;
}
}
}
return this.failed != null ? InteractionManager.walkInteraction(collector, context, TAG_FAILED, this.failed) : false;
}
public boolean needsRemoteSync() {
return false;
}
public WaitForDataFrom getWaitForDataFrom() {
return WaitForDataFrom.Server;
}
static {
CODEC = ((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)BuilderCodec.builder(MemoriesConditionInteraction.class, MemoriesConditionInteraction::new, ABSTRACT_CODEC).appendInherited(new KeyedCodec("Next", new Int2ObjectMapCodec(Interaction.CHILD_ASSET_CODEC, Int2ObjectOpenHashMap::new)), (o, v) -> o.next = v, (o) -> o.next, (o, p) -> o.next = p.next).documentation("The interaction to run if the player's memories level matches the key.").addValidator(Validators.nonNull()).add()).appendInherited(new KeyedCodec("Failed", Interaction.CHILD_ASSET_CODEC), (o, v) -> o.failed = v, (o) -> o.failed, (o, p) -> o.failed = p.failed).documentation("The interaction to run if the player's memories level does not match any key.").add()).afterDecode((o) -> {
o.levelToLabel.defaultReturnValue(-1);
o.sortedKeys = o.next.keySet().toIntArray();
Arrays.sort(o.sortedKeys);
o.levelToLabel.clear();
for(int i = 0; i < o.sortedKeys.length; ++i) {
o.levelToLabel.put(o.sortedKeys[i], i);
}
})).build();
TAG_FAILED = StringTag.of("Failed");
}
private static record MemoriesTag(int memoryLevel) implements CollectorTag {
}
}