RunOption class
Пакет: com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator
Файл: com/hypixel/hytale/builtin/npccombatactionevaluator/evaluator/CombatActionEvaluator.java
extends: Option
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator;
class="kw">import com.hypixel.hytale.builtin.npccombatactionevaluator.CombatActionEvaluatorSystems;
class="kw">import com.hypixel.hytale.builtin.npccombatactionevaluator.NPCCombatActionEvaluatorPlugin;
class="kw">import com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator.combatactions.CombatActionOption;
class="kw">import com.hypixel.hytale.builtin.npccombatactionevaluator.memory.TargetMemory;
class="kw">import com.hypixel.hytale.component.ArchetypeChunk;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.Component;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.math.random.RandomExtra;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionContext;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.npc.asset.builder.StateMappingHelper;
class="kw">import com.hypixel.hytale.server.npc.decisionmaker.core.EvaluationContext;
class="kw">import com.hypixel.hytale.server.npc.decisionmaker.core.Evaluator;
class="kw">import com.hypixel.hytale.server.npc.decisionmaker.core.Option;
class="kw">import com.hypixel.hytale.server.npc.instructions.ExecutionSupport;
class="kw">import com.hypixel.hytale.server.npc.role.support.StateSupport;
class="kw">import com.hypixel.hytale.server.npc.valuestore.ValueStore;
class="kw">import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
class="kw">import it.unimi.dsi.fastutil.doubles.DoubleList;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import java.util.Comparator;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.function.Function;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">public class CombatActionEvaluator class="kw">extends Evaluator<CombatActionOption> class="kw">implements Component<EntityStore> {
class="kw">protected class="kw">static class="kw">final float NO_TIMEOUT = Float.MAX_VALUE;
class="kw">protected CombatActionEvaluator.RunOption runOption;
class="kw">protected double minRunUtility;
class="kw">protected long lastRunNanos = NOT_USED;
class="kw">protected int runInState;
class="kw">protected float predictability;
class="kw">protected double minActionUtility;
@Nonnull
class="kw">protected class="kw">final Int2ObjectMap<List<Evaluator<CombatActionOption>.OptionHolder>> optionsBySubState = new Int2ObjectOpenHashMap();
@Nonnull
class="kw">protected class="kw">final Int2ObjectMap<CombatActionEvaluatorConfig.BasicAttacks> basicAttacksBySubState = new Int2ObjectOpenHashMap();
class="kw">protected int currentBasicAttackSubState = Integer.MIN_VALUE;
class="kw">protected CombatActionEvaluatorConfig.BasicAttacks currentBasicAttackSet;
@Nullable
class="kw">protected String currentBasicAttack;
class="kw">protected Function<InteractionContext, Map<String, String>> currentBasicAttacksInteractionVarsGetter;
class="kw">protected boolean currentBasicAttackDamageFriendlies;
class="kw">protected int nextBasicAttackIndex;
class="kw">protected double basicAttackCooldown;
@Nullable
class="kw">protected Ref<EntityStore> basicAttackTarget;
class="kw">protected double basicAttackTimeout;
@Nullable
class="kw">protected Ref<EntityStore> primaryTarget;
@Nullable
class="kw">protected Ref<EntityStore> previousTarget;
@Nullable
class="kw">protected CombatActionEvaluator.CombatOptionHolder currentAction;
@Nullable
class="kw">protected double[] postExecutionDistanceRange;
class="kw">protected int markedTargetSlot;
class="kw">protected int minRangeSlot;
class="kw">protected int maxRangeSlot;
class="kw">protected int positioningAngleSlot;
@Nullable
class="kw">protected String currentInteraction;
class="kw">protected Function<InteractionContext, Map<String, String>> currentInteractionVarsGetter;
class="kw">protected InteractionType currentInteractionType;
class="kw">protected float chargeFor;
class="kw">protected boolean currentDamageFriendlies;
class="kw">protected boolean requireAiming;
class="kw">protected boolean positionFirst;
class="kw">protected double chargeDistance;
class="kw">protected float timeout;
@Nonnull
class="kw">protected class="kw">final EvaluationContext evaluationContext = new EvaluationContext();
class="kw">public class="kw">static ComponentType<EntityStore, CombatActionEvaluator> getComponentType() {
class="kw">return NPCCombatActionEvaluatorPlugin.get().getCombatActionEvaluatorComponentType();
}
class="kw">public CombatActionEvaluator(
@Nonnull StateSupport var1, @Nonnull CombatActionEvaluatorConfig var2, @Nonnull CombatActionEvaluatorSystems.CombatConstructionData var3
) {
this.runOption = new CombatActionEvaluator.RunOption(var2.getRunConditions());
this.runOption.sortConditions();
this.minRunUtility = var2.getMinRunUtility();
this.minActionUtility = var2.getMinActionUtility();
this.predictability = (float)RandomExtra.randomRange(var2.getPredictabilityRange());
StateMappingHelper var4 = var1.getStateHelper();
String var5 = var3.getCombatState();
this.runInState = var4.getStateIndex(var5);
this.markedTargetSlot = var3.getMarkedTargetSlot();
this.minRangeSlot = var3.getMinRangeSlot();
this.maxRangeSlot = var3.getMaxRangeSlot();
this.positioningAngleSlot = var3.getPositioningAngleSlot();
Map var6 = var2.getAvailableActions();
Map var7 = new Object2ObjectOpenHashMap();
for (Entry var9 : var6.entrySet()) {
CombatActionOption var10 = CombatActionOption.getAssetMap().getAsset(var9.getValue());
if (var10 == null) {
throw new IllegalStateException(String.format("Option %s does not exist!", var9.getValue()));
}
var10.sortConditions();
CombatActionEvaluator.CombatOptionHolder var11 = class="kw">switch (var10.getActionTarget()) {
case Self -> new CombatActionEvaluator.SelfCombatOptionHolder(var10);
case Hostile, Friendly -> new CombatActionEvaluator.MultipleTargetCombatOptionHolder(var10);
};
var7.put(var9.getKey(), var11);
}
Map var20 = var2.getActionSets();
for (Entry var23 : var20.entrySet()) {
int var25 = var4.getSubStateIndex(this.runInState, var23.getKey());
if (var25 == Integer.MIN_VALUE) {
throw new IllegalStateException(String.format("No such state for combat evaluator: %s.%s", var5, var23.getKey()));
}
CombatActionEvaluatorConfig.ActionSet var12 = var23.getValue();
this.basicAttacksBySubState.put(var25, var12.getBasicAttacks());
List var13 = (List<Evaluator<CombatActionOption>.OptionHolder>)this.optionsBySubState.computeIfAbsent(var25, var0 -> new ObjectArrayList());
String[] var14 = var12.getCombatActions();
for (String var18 : var14) {
Evaluator.OptionHolder var19 = var7.get(var18);
if (var19 == null) {
throw new IllegalStateException(String.format("No action with name '%s' defined in AvailableActions!", var18));
}
var13.add(var19);
}
}
ObjectIterator var22 = this.optionsBySubState.values().iterator();
while (var22.hasNext()) {
List var24 = (List<Evaluator<CombatActionOption>.OptionHolder>)var22.next();
var24.sort(Comparator.comparingDouble(Evaluator.OptionHolder::getWeightCoefficient).reversed());
}
}
class="kw">protected CombatActionEvaluator() {
}
class="kw">public CombatActionEvaluator.RunOption getRunOption() {
class="kw">return this.runOption;
}
class="kw">public double getMinRunUtility() {
class="kw">return this.minRunUtility;
}
@Nonnull
class="kw">public EvaluationContext getEvaluationContext() {
class="kw">return this.evaluationContext;
}
class="kw">public long getLastRunNanos() {
class="kw">return this.lastRunNanos;
}
class="kw">public void setLastRunNanos(long var1) {
this.lastRunNanos = var1;
}
class="kw">public int getRunInState() {
class="kw">return this.runInState;
}
@Nonnull
class="kw">public Int2ObjectMap<List<Evaluator<CombatActionOption>.OptionHolder>> getOptionsBySubState() {
class="kw">return this.optionsBySubState;
}
class="kw">public CombatActionEvaluatorConfig.BasicAttacks getBasicAttacks(int var1) {
class="kw">return (CombatActionEvaluatorConfig.BasicAttacks)this.basicAttacksBySubState.get(var1);
}
class="kw">public void setCurrentBasicAttackSet(int var1, CombatActionEvaluatorConfig.BasicAttacks var2) {
if (var1 != this.currentBasicAttackSubState) {
this.nextBasicAttackIndex = 0;
this.currentBasicAttackSubState = var1;
this.currentBasicAttackSet = var2;
}
}
@Nullable
class="kw">public String getCurrentBasicAttack() {
class="kw">return this.currentBasicAttack;
}
class="kw">public CombatActionEvaluatorConfig.BasicAttacks getCurrentBasicAttackSet() {
class="kw">return this.currentBasicAttackSet;
}
class="kw">public void setCurrentBasicAttack(String var1, boolean var2, Function<InteractionContext, Map<String, String>> var3) {
this.currentBasicAttack = var1;
this.currentBasicAttacksInteractionVarsGetter = var3;
this.currentBasicAttackDamageFriendlies = var2;
}
class="kw">public int getNextBasicAttackIndex() {
class="kw">return this.nextBasicAttackIndex;
}
class="kw">public void setNextBasicAttackIndex(int var1) {
this.nextBasicAttackIndex = var1;
}
class="kw">public boolean canUseBasicAttack(int var1, ArchetypeChunk<EntityStore> var2, CommandBuffer<EntityStore> var3) {
class="kw">return this.basicAttackCooldown > 0.0
? false
: this.currentAction == null || ((CombatActionOption)this.currentAction.getOption()).isBasicAttackAllowed(var1, var2, var3, this);
}
class="kw">public void tickBasicAttackCoolDown(float var1) {
if (this.basicAttackCooldown > 0.0) {
this.basicAttackCooldown -= var1;
}
}
@Nullable
class="kw">public Ref<EntityStore> getBasicAttackTarget() {
class="kw">return this.basicAttackTarget;
}
class="kw">public void setBasicAttackTarget(Ref<EntityStore> var1) {
this.basicAttackTarget = var1;
}
class="kw">public boolean tickBasicAttackTimeout(float var1) {
class="kw">return (this.basicAttackTimeout -= var1) <= 0.0;
}
class="kw">public void setBasicAttackTimeout(double var1) {
this.basicAttackTimeout = var1;
}
@Nullable
class="kw">public Ref<EntityStore> getPrimaryTarget() {
class="kw">return this.primaryTarget;
}
class="kw">public void clearPrimaryTarget() {
this.primaryTarget = null;
}
class="kw">public void setActiveOptions(List<Evaluator<CombatActionOption>.OptionHolder> var1) {
this.options = var1;
}
class="kw">public int getMarkedTargetSlot() {
class="kw">return this.markedTargetSlot;
}
class="kw">public int getMaxRangeSlot() {
class="kw">return this.maxRangeSlot;
}
class="kw">public int getMinRangeSlot() {
class="kw">return this.minRangeSlot;
}
class="kw">public int getPositioningAngleSlot() {
class="kw">return this.positioningAngleSlot;
}
@Nullable
class="kw">public String getCurrentAttack() {
class="kw">return this.currentBasicAttack != null ? this.currentBasicAttack : this.currentInteraction;
}
class="kw">public float getChargeFor() {
class="kw">return this.currentBasicAttack != null ? 0.0F : this.chargeFor;
}
class="kw">public InteractionType getCurrentInteractionType() {
class="kw">return this.currentBasicAttack != null ? InteractionType.Primary : this.currentInteractionType;
}
class="kw">public Function<InteractionContext, Map<String, String>> getCurrentInteractionVarsGetter() {
class="kw">return this.currentBasicAttack != null ? this.currentBasicAttacksInteractionVarsGetter : this.currentInteractionVarsGetter;
}
class="kw">public boolean shouldDamageFriendlies() {
class="kw">return this.currentBasicAttack != null ? this.currentBasicAttackDamageFriendlies : this.currentDamageFriendlies;
}
class="kw">public boolean requiresAiming() {
class="kw">return this.currentBasicAttack != null ? true : this.requireAiming;
}
class="kw">public boolean shouldPositionFirst() {
class="kw">return this.currentBasicAttack != null ? false : this.positionFirst;
}
class="kw">public double getChargeDistance() {
class="kw">return this.currentBasicAttack != null ? 0.0 : this.chargeDistance;
}
class="kw">public void setCurrentInteraction(
String var1,
InteractionType var2,
float var3,
boolean var4,
boolean var5,
boolean var6,
double var7,
Function<InteractionContext, Map<String, String>> var9
) {
this.currentInteraction = var1;
this.currentInteractionType = var2;
this.chargeFor = var3;
this.currentDamageFriendlies = var4;
this.requireAiming = var5;
this.positionFirst = var6;
this.currentInteractionVarsGetter = var9;
this.chargeDistance = var7;
}
@Nullable
class="kw">public CombatActionEvaluator.CombatOptionHolder getCurrentAction() {
class="kw">return this.currentAction;
}
class="kw">public double[] consumePostExecutionDistanceRange() {
double[] var1 = this.postExecutionDistanceRange;
this.postExecutionDistanceRange = null;
class="kw">return var1;
}
class="kw">public void setTimeout(float var1) {
this.timeout = var1;
}
class="kw">public void clearTimeout() {
this.timeout = Float.MAX_VALUE;
}
class="kw">public boolean hasTimedOut(float var1) {
class="kw">return this.timeout != Float.MAX_VALUE && (this.timeout -= var1) <= 0.0F;
}
class="kw">public void selectNextCombatAction(
int var1, @Nonnull ArchetypeChunk<EntityStore> var2, CommandBuffer<EntityStore> var3, @Nonnull ExecutionSupport var4, ValueStore var5
) {
this.evaluationContext.setPredictability(this.predictability);
this.evaluationContext.setMinimumUtility(this.minActionUtility);
CombatActionEvaluator.CombatOptionHolder var6 = (CombatActionEvaluator.CombatOptionHolder)this.evaluate(var1, var2, var3, this.evaluationContext);
if (var6 != null) {
Ref var7 = var6.getOptionTarget();
if (var7 != null && var7.isValid()) {
if (((CombatActionOption)var6.getOption()).getActionTarget() == CombatActionOption.Target.Friendly) {
this.previousTarget = this.primaryTarget;
}
this.primaryTarget = var7;
var4.getMarkedEntitySupport().setMarkedEntity(this.markedTargetSlot, this.primaryTarget);
}
this.currentAction = var6;
((CombatActionOption)this.currentAction.getOption()).execute(var1, var2, var3, var4, this, var5);
if (((CombatActionOption)var6.getOption()).cancelBasicAttackOnSelect()) {
this.clearCurrentBasicAttack();
}
}
}
class="kw">public void completeCurrentAction(boolean var1, boolean var2) {
if (var1 || this.currentBasicAttack == null) {
this.terminateCurrentAction();
this.lastRunNanos = System.nanoTime();
}
if (var2) {
this.clearCurrentBasicAttack();
}
}
class="kw">public void terminateCurrentAction() {
this.currentInteraction = null;
this.chargeFor = 0.0F;
if (this.currentAction != null) {
this.currentAction.setLastUsedNanos(System.nanoTime());
CombatActionOption var1 = (CombatActionOption)this.currentAction.getOption();
if (var1.getActionTarget() == CombatActionOption.Target.Friendly) {
this.primaryTarget = this.previousTarget;
this.previousTarget = null;
}
this.postExecutionDistanceRange = var1.getPostExecuteDistanceRange();
this.currentAction = null;
}
}
class="kw">public void clearCurrentBasicAttack() {
if (this.currentBasicAttackSet != null) {
this.basicAttackCooldown = RandomExtra.randomRange(this.currentBasicAttackSet.getCooldownRange());
}
this.currentBasicAttack = null;
this.basicAttackTarget = null;
}
@Override
class="kw">public void setupNPC(ExecutionSupport var1) {
ObjectIterator var2 = this.optionsBySubState.values().iterator();
while (var2.hasNext()) {
List var3 = (List<Evaluator<CombatActionOption>.OptionHolder>)var2.next();
for (Evaluator.OptionHolder var5 : var3) {
CombatActionOption var6 = (CombatActionOption)var5.getOption();
var6.setupNPC(var1);
}
}
}
@Override
class="kw">public void setupNPC(Holder<EntityStore> var1) {
ObjectIterator var2 = this.optionsBySubState.values().iterator();
while (var2.hasNext()) {
List var3 = (List<Evaluator<CombatActionOption>.OptionHolder>)var2.next();
for (Evaluator.OptionHolder var5 : var3) {
CombatActionOption var6 = (CombatActionOption)var5.getOption();
var6.setupNPC(var1);
}
}
}
@Nonnull
@Override
class="kw">public Component<EntityStore> clone() {
CombatActionEvaluator var1 = new CombatActionEvaluator();
var1.options = this.options;
var1.runOption = this.runOption;
var1.minRunUtility = this.minRunUtility;
var1.minActionUtility = this.minActionUtility;
var1.predictability = this.predictability;
var1.runInState = this.runInState;
var1.optionsBySubState.putAll(this.optionsBySubState);
var1.lastRunNanos = this.lastRunNanos;
var1.markedTargetSlot = this.markedTargetSlot;
var1.minRangeSlot = this.minRangeSlot;
var1.maxRangeSlot = this.maxRangeSlot;
var1.positioningAngleSlot = this.positioningAngleSlot;
var1.primaryTarget = this.primaryTarget;
var1.previousTarget = this.previousTarget;
var1.currentAction = this.currentAction;
var1.currentInteraction = this.currentInteraction;
var1.chargeFor = this.chargeFor;
var1.timeout = this.timeout;
var1.basicAttacksBySubState.putAll(this.basicAttacksBySubState);
var1.nextBasicAttackIndex = this.nextBasicAttackIndex;
var1.basicAttackCooldown = this.basicAttackCooldown;
var1.currentBasicAttackSet = this.currentBasicAttackSet;
var1.currentBasicAttack = this.currentBasicAttack;
var1.basicAttackTimeout = this.basicAttackTimeout;
var1.basicAttackTarget = this.basicAttackTarget;
var1.currentBasicAttackSubState = this.currentBasicAttackSubState;
var1.currentInteractionType = this.currentInteractionType;
var1.currentBasicAttacksInteractionVarsGetter = this.currentBasicAttacksInteractionVarsGetter;
var1.currentBasicAttackDamageFriendlies = this.currentBasicAttackDamageFriendlies;
var1.currentDamageFriendlies = this.currentDamageFriendlies;
var1.requireAiming = this.requireAiming;
var1.positionFirst = this.positionFirst;
var1.chargeDistance = this.chargeDistance;
var1.currentInteractionVarsGetter = this.currentInteractionVarsGetter;
var1.postExecutionDistanceRange = this.postExecutionDistanceRange;
class="kw">return var1;
}
class="kw">public class="kw">abstract class CombatOptionHolder class="kw">extends Evaluator<CombatActionOption>.OptionHolder {
class="kw">protected CombatOptionHolder(CombatActionOption nullx) {
super(nullx);
}
@Nullable
class="kw">public Ref<EntityStore> getOptionTarget() {
class="kw">return null;
}
}
class="kw">public class MultipleTargetCombatOptionHolder class="kw">extends CombatActionEvaluator.CombatOptionHolder {
class="kw">protected List<Ref<EntityStore>> targets;
@Nonnull
class="kw">protected class="kw">final DoubleList targetUtilities = new DoubleArrayList();
@Nullable
class="kw">protected Ref<EntityStore> pickedTarget;
class="kw">protected MultipleTargetCombatOptionHolder(CombatActionOption nullx) {
super(nullx);
}
@Override
class="kw">public double calculateUtility(int var1, @Nonnull ArchetypeChunk<EntityStore> var2, CommandBuffer<EntityStore> var3, @Nonnull EvaluationContext var4) {
var4.setLastUsedNanos(this.lastUsedNanos);
TargetMemory var5 = var2.getComponent(var1, TargetMemory.getComponentType());
this.targets = class="kw">switch (((CombatActionOption)this.option).getActionTarget()) {
case Self -> throw new IllegalStateException("Self option should not be wrapped in a MultipleTargetCombatOptionHolder!");
case Hostile -> var5.getKnownHostilesList();
case Friendly -> var5.getKnownFriendliesList();
};
this.targetUtilities.clear();
this.pickedTarget = null;
this.utility = 0.0;
for (int var6 = 0; var6 < this.targets.size(); var6++) {
double var7 = ((CombatActionOption)this.option).calculateUtility(var1, var2, this.targets.get(var6), var3, var4);
this.targetUtilities.add(var6, var7);
if (var7 > this.utility) {
this.utility = var7;
this.pickedTarget = this.targets.get(var6);
}
}
class="kw">return this.utility;
}
@Override
class="kw">public double getTotalUtility(double var1) {
double var3 = 0.0;
for (int var5 = 0; var5 < this.targets.size(); var5++) {
double var6 = this.targetUtilities.getDouble(var5);
if (var6 >= var1) {
var3 += var6;
}
}
class="kw">return var3;
}
@Override
class="kw">public double tryPick(double var1, double var3) {
for (int var5 = 0; var5 < this.targets.size(); var5++) {
double var6 = this.targetUtilities.getDouble(var5);
if (!(var6 < var3)) {
var1 -= var6;
if (var1 <= 0.0) {
this.pickedTarget = this.targets.get(var5);
break;
}
}
}
class="kw">return var1;
}
@Override
class="kw">public Ref<EntityStore> getOptionTarget() {
class="kw">return this.pickedTarget;
}
}
class="kw">public class="kw">static class RunOption class="kw">extends Option {
class="kw">protected RunOption(String[] var1) {
this.conditions = var1;
}
}
class="kw">public class SelfCombatOptionHolder class="kw">extends CombatActionEvaluator.CombatOptionHolder {
class="kw">protected SelfCombatOptionHolder(CombatActionOption nullx) {
super(nullx);
}
@Override
class="kw">public double calculateUtility(int var1, @Nonnull ArchetypeChunk<EntityStore> var2, CommandBuffer<EntityStore> var3, @Nonnull EvaluationContext var4) {
var4.setLastUsedNanos(this.lastUsedNanos);
class="kw">return this.utility = ((CombatActionOption)this.option).calculateUtility(var1, var2, CombatActionEvaluator.this.primaryTarget, var3, var4);
}
}
}