package com.hypixel.hytale.builtin.adventure.objectives.task;
import com.hypixel.hytale.builtin.adventure.objectives.Objective;
import com.hypixel.hytale.builtin.adventure.objectives.ObjectivePlugin;
import com.hypixel.hytale.builtin.adventure.objectives.config.task.ObjectiveTaskAsset;
import com.hypixel.hytale.builtin.adventure.objectives.config.taskcondition.TaskConditionAsset;
import com.hypixel.hytale.builtin.adventure.objectives.transaction.TransactionRecord;
import com.hypixel.hytale.builtin.adventure.objectives.transaction.TransactionUtil;
import com.hypixel.hytale.builtin.adventure.objectives.transaction.WorldTransactionRecord;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import com.hypixel.hytale.codec.lookup.CodecMapCodec;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.event.EventRegistry;
import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.packets.assets.UpdateObjectiveTask;
import com.hypixel.hytale.protocol.packets.worldmap.ContextMenuItem;
import com.hypixel.hytale.protocol.packets.worldmap.MapMarker;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.codec.ProtocolCodecs;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.io.NetworkSerializer;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.core.util.PositionUtil;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class ObjectiveTask implements NetworkSerializer<Objective, com.hypixel.hytale.protocol.ObjectiveTask> {
public static final CodecMapCodec<ObjectiveTask> CODEC = new CodecMapCodec<ObjectiveTask>("Type");
public static final BuilderCodec<ObjectiveTask> BASE_CODEC;
protected ObjectiveTaskAsset asset;
protected boolean complete = false;
@Nullable
protected EventRegistry eventRegistry;
@Nullable
protected TransactionRecord[] serializedTransactionRecords;
@Nullable
protected TransactionRecord[] nonSerializedTransactionRecords;
protected int taskIndex;
@Nonnull
protected List<MapMarker> markers = new ObjectArrayList<MapMarker>();
protected int taskSetIndex;
protected ObjectiveTaskRef<? extends ObjectiveTask> taskRef;
public ObjectiveTask(@Nonnull ObjectiveTaskAsset asset, int taskSetIndex, int taskIndex) {
this.asset = asset;
this.taskIndex = taskIndex;
this.taskSetIndex = taskSetIndex;
}
protected ObjectiveTask() {
}
@Nonnull
public ObjectiveTaskAsset getAsset() {
return this.asset;
}
public void setAsset(@Nonnull ObjectiveTaskAsset asset) {
this.asset = asset;
}
public boolean isComplete() {
return this.complete;
}
@Nullable
public TransactionRecord[] getSerializedTransactionRecords() {
return this.serializedTransactionRecords;
}
@Nullable
public TransactionRecord[] getNonSerializedTransactionRecords() {
return this.nonSerializedTransactionRecords;
}
@Nonnull
public Message getInfoMessage(@Nonnull Objective objective) {
return Message.translation(this.asset.getDescriptionKey(objective.getObjectiveId(), this.taskSetIndex, this.taskIndex));
}
@Nonnull
public List<MapMarker> getMarkers() {
return this.markers;
}
public void addMarker(@Nonnull MapMarker marker) {
this.markers.add(marker);
}
public void removeMarker(String id) {
for(MapMarker marker : this.markers) {
if (marker.id.equals(id)) {
this.markers.remove(marker);
return;
}
}
}
public abstract boolean checkCompletion();
@Nullable
protected abstract TransactionRecord[] setup0(@Nonnull Objective var1, @Nonnull World var2, @Nonnull Store<EntityStore> var3);
@Nullable
public final TransactionRecord[] setup(@Nonnull Objective objective, @Nonnull Store<EntityStore> store) {
World world = Universe.get().getWorld(objective.getWorldUUID());
if (world == null) {
String transactionMessage = "This World doesn't exist in this Universe: " + String.valueOf(objective.getWorldUUID());
return TransactionRecord.appendFailedTransaction(this.nonSerializedTransactionRecords, new WorldTransactionRecord(), transactionMessage);
} else if (this.eventRegistry != null) {
throw new IllegalStateException("ObjectiveTask.eventRegistry is not null, setup() shouldn't be run more than once!");
} else {
this.eventRegistry = new EventRegistry(new CopyOnWriteArrayList(), () -> true, (String)null, world.getEventRegistry());
Vector3i[] mapMarkerPositions = this.asset.getMapMarkers();
if (mapMarkerPositions != null) {
String objectiveUUIDString = objective.getObjectiveUUID().toString();
for(int i = 0; i < mapMarkerPositions.length; ++i) {
Vector3i mapMarkerPosition = mapMarkerPositions[i];
this.addMarker(new MapMarker("ObjectiveMarker_" + objectiveUUIDString + "_" + i, "Objective", "Home.png", PositionUtil.toTransformPacket(new Transform(mapMarkerPosition)), (ContextMenuItem[])null));
}
}
this.taskRef = new ObjectiveTaskRef<ObjectiveTask>(objective.getObjectiveUUID(), this);
this.registerTaskRef();
TransactionRecord[] transactionRecords = this.setup0(objective, world, store);
if (transactionRecords == null) {
return null;
} else {
int serializedCount = 0;
for(TransactionRecord transactionRecord : transactionRecords) {
if (transactionRecord.shouldBeSerialized()) {
++serializedCount;
}
}
this.serializedTransactionRecords = new TransactionRecord[serializedCount];
this.nonSerializedTransactionRecords = new TransactionRecord[transactionRecords.length - serializedCount];
int serializedIndex = 0;
int nonSerializedIndex = 0;
for(TransactionRecord transactionRecord : transactionRecords) {
if (transactionRecord.shouldBeSerialized()) {
this.serializedTransactionRecords[serializedIndex++] = transactionRecord;
} else {
this.nonSerializedTransactionRecords[nonSerializedIndex++] = transactionRecord;
}
}
return transactionRecords;
}
}
}
public void complete(@Nonnull Objective objective, @Nullable ComponentAccessor<EntityStore> componentAccessor) {
if (!this.complete) {
if (componentAccessor != null) {
objective.forEachParticipant((participantReference, message) -> {
Player playerComponent = (Player)componentAccessor.getComponent(participantReference, Player.getComponentType());
if (playerComponent != null) {
playerComponent.sendMessage(message);
}
}, Message.translation("server.modules.objective.task.completed").insert(this.getInfoMessage(objective)));
}
this.markers.clear();
this.complete = true;
this.completeTransactionRecords();
}
}
private void registerTaskRef() {
ObjectivePlugin.get().getObjectiveDataStore().addTaskRef(this.taskRef);
}
private void unregisterTaskRef() {
ObjectivePlugin.get().getObjectiveDataStore().removeTaskRef(this.taskRef);
}
public void completeTransactionRecords() {
TransactionUtil.completeAll(this.serializedTransactionRecords);
this.serializedTransactionRecords = null;
TransactionUtil.completeAll(this.nonSerializedTransactionRecords);
this.nonSerializedTransactionRecords = null;
this.shutdownEventRegistry();
this.unregisterTaskRef();
}
public void revertTransactionRecords() {
TransactionUtil.revertAll(this.serializedTransactionRecords);
this.serializedTransactionRecords = null;
TransactionUtil.revertAll(this.nonSerializedTransactionRecords);
this.nonSerializedTransactionRecords = null;
this.shutdownEventRegistry();
this.unregisterTaskRef();
}
public void unloadTransactionRecords() {
TransactionUtil.unloadAll(this.serializedTransactionRecords);
this.serializedTransactionRecords = null;
TransactionUtil.unloadAll(this.nonSerializedTransactionRecords);
this.nonSerializedTransactionRecords = null;
this.shutdownEventRegistry();
this.unregisterTaskRef();
}
private void shutdownEventRegistry() {
if (this.eventRegistry != null) {
this.eventRegistry.shutdown();
this.eventRegistry = null;
}
}
public void assetChanged(@Nonnull Objective objective) {
if (!this.complete) {
if (this.checkCompletion()) {
this.consumeTaskConditions((ComponentAccessor)null, (Ref)null, objective.getActivePlayerUUIDs());
this.complete(objective, (ComponentAccessor)null);
}
}
}
public void sendUpdateObjectiveTaskPacket(@Nonnull Objective objective) {
UpdateObjectiveTask updateObjectiveTaskPacket = new UpdateObjectiveTask(objective.getObjectiveUUID(), this.taskIndex, (com.hypixel.hytale.protocol.ObjectiveTask)this.toPacket(objective));
Universe universe = Universe.get();
for(UUID playerUUID : objective.getActivePlayerUUIDs()) {
PlayerRef player = universe.getPlayer(playerUUID);
if (player != null) {
player.getPacketHandler().writeNoCache(updateObjectiveTaskPacket);
}
}
}
public boolean areTaskConditionsFulfilled(@Nullable ComponentAccessor<EntityStore> componentAccessor, @Nullable Ref<EntityStore> ref, @Nullable Set<UUID> objectivePlayers) {
TaskConditionAsset[] taskConditions = this.asset.getTaskConditions();
if (taskConditions == null) {
return true;
} else {
for(TaskConditionAsset taskCondition : taskConditions) {
if (!taskCondition.isConditionFulfilled(componentAccessor, ref, objectivePlayers)) {
return false;
}
}
return true;
}
}
public void consumeTaskConditions(@Nullable ComponentAccessor<EntityStore> componentAccessor, @Nullable Ref<EntityStore> ref, @Nonnull Set<UUID> objectivePlayers) {
TaskConditionAsset[] taskConditions = this.asset.getTaskConditions();
if (taskConditions != null) {
for(TaskConditionAsset taskCondition : taskConditions) {
taskCondition.consumeCondition(componentAccessor, ref, objectivePlayers);
}
}
}
@Nonnull
public String toString() {
String var10000 = String.valueOf(this.asset);
return "ObjectiveTask{asset=" + var10000 + ", complete=" + this.complete + ", eventRegistry=" + String.valueOf(this.eventRegistry) + ", serializedTransactionRecords=" + Arrays.toString(this.serializedTransactionRecords) + ", nonSerializedTransactionRecords=" + Arrays.toString(this.nonSerializedTransactionRecords) + ", taskIndex=" + this.taskIndex + ", markers=" + String.valueOf(this.markers) + ", taskSetIndex=" + this.taskSetIndex + "}";
}
static {
BASE_CODEC = ((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)BuilderCodec.abstractBuilder(ObjectiveTask.class).append(new KeyedCodec("Task", ObjectiveTaskAsset.CODEC), (aObjectiveTask, objectiveTaskAsset) -> aObjectiveTask.asset = objectiveTaskAsset, (aObjectiveTask) -> aObjectiveTask.asset).add()).append(new KeyedCodec("Complete", Codec.BOOLEAN), (aObjectiveTask, aBoolean) -> aObjectiveTask.complete = aBoolean, (aObjectiveTask) -> aObjectiveTask.complete).add()).append(new KeyedCodec("TransactionRecords", new ArrayCodec(TransactionRecord.CODEC, (x$0) -> new TransactionRecord[x$0])), (objectiveTask, transactionRecords) -> objectiveTask.serializedTransactionRecords = transactionRecords, (objectiveTask) -> objectiveTask.serializedTransactionRecords).add()).append(new KeyedCodec("TaskIndex", Codec.INTEGER), (objectiveTask, integer) -> objectiveTask.taskIndex = integer, (objectiveTask) -> objectiveTask.taskIndex).add()).append(new KeyedCodec("Markers", ProtocolCodecs.MARKER_ARRAY), (objectiveTask, markers) -> {
objectiveTask.markers.clear();
Collections.addAll(objectiveTask.markers, markers);
}, (objectiveTask) -> (MapMarker[])objectiveTask.markers.toArray((x$0) -> new MapMarker[x$0])).add()).append(new KeyedCodec("TaskSetIndex", Codec.INTEGER), (objectiveTask, integer) -> objectiveTask.taskSetIndex = integer, (objectiveTask) -> objectiveTask.taskSetIndex).add()).build();
}
}