AbilityType enum

Пакет: com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator.combatactions

Файл: com/hypixel/hytale/builtin/npccombatactionevaluator/evaluator/combatactions/AbilityCombatAction.java

Поля (1)

МодификаторыТипИмя
private final InteractionType interactionType

Методы (1)

МодификаторыВозвратСигнатура
abstract Secondary Secondary(InteractionType.Secondary)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator.combatactions;

class="kw">import com.hypixel.hytale.builtin.npccombatactionevaluator.Positioning;
class="kw">import com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator.CombatActionEvaluator;
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.EnumCodec;
class="kw">import com.hypixel.hytale.codec.codecs.map.MapCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.component.ArchetypeChunk;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
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.InteractionChain;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionContext;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionManager;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.InteractionModule;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.physics.util.PhysicsMath;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.npc.entities.NPCEntity;
class="kw">import com.hypixel.hytale.server.npc.instructions.ExecutionSupport;
class="kw">import com.hypixel.hytale.server.npc.interactions.NPCInteractionSimulationHandler;
class="kw">import com.hypixel.hytale.server.npc.util.InventoryHelper;
class="kw">import com.hypixel.hytale.server.npc.valuestore.ValueStore;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import java.util.Arrays;
class="kw">import java.util.Collections;
class="kw">import java.util.Map;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import org.joml.Vector3d;

class="kw">public class AbilityCombatAction class="kw">extends CombatActionOption {
   @Nonnull
   class="kw">public class="kw">static class="kw">final EnumCodec<AbilityCombatAction.AbilityType> MODE_CODEC = new EnumCodec<>(AbilityCombatAction.AbilityType.class)
      .documentKey(AbilityCombatAction.AbilityType.Primary, "Use primary attack.")
      .documentKey(AbilityCombatAction.AbilityType.Secondary, "Use secondary attack.");
   @Nonnull
   class="kw">public class="kw">static class="kw">final EnumCodec<Positioning> POSITIONING_CODEC = new EnumCodec<>(Positioning.class)
      .documentKey(Positioning.Any, "Don't care about positioning.")
      .documentKey(Positioning.Front, "Try to be in front of the target.")
      .documentKey(Positioning.Behind, "Try to be behind the target.")
      .documentKey(Positioning.Flank, "Try to be on the target's flank.");
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<AbilityCombatAction> CODEC = BuilderCodec.builder(
         AbilityCombatAction.class, AbilityCombatAction::new, CombatActionOption.BASE_CODEC
      )
      .documentation("A combat action which executes an attack or ability by triggering an Interaction.")
      .<String>appendInherited(
         new KeyedCodec<>("Ability", RootInteraction.CHILD_ASSET_CODEC),
         (var0, var1) -> var0.ability = var1,
         var0 -> var0.ability,
         (var0, var1) -> var0.ability = var1.ability
      )
      .addValidator(Validators.nonNull())
      .addValidator(RootInteraction.VALIDATOR_CACHE.getValidator())
      .documentation("The interaction (ability) to use.")
      .add()
      .<AbilityCombatAction.AbilityType>appendInherited(
         new KeyedCodec<>("AbilityType", MODE_CODEC),
         (var0, var1) -> var0.abilityType = var1,
         var0 -> var0.abilityType,
         (var0, var1) -> var0.abilityType = var1.abilityType
      )
      .documentation("The ability type.")
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("ChargeFor", Codec.FLOAT),
         (var0, var1) -> var0.chargeFor = var1,
         var0 -> var0.chargeFor,
         (var0, var1) -> var0.chargeFor = var1.chargeFor
      )
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .documentation("How long to charge the ability for before using it.")
      .add()
      .<double[]>appendInherited(new KeyedCodec<>("AttackDistanceRange", Codec.DOUBLE_ARRAY), (var0, var1) -> {
         var0.attackRange = var1;
         var0.maxRangeSquared = var1[1] * var1[1];
      }, var0 -> var0.attackRange, (var0, var1) -> var0.attackRange = var1.attackRange)
      .addValidator(Validators.nonNull())
      .addValidator(Validators.doubleArraySize(2))
      .addValidator(Validators.weaklyMonotonicSequentialDoubleArrayValidator())
      .documentation("The range at which the NPC needs to be from the target to execute the attack.")
      .add()
      .<Integer>appendInherited(
         new KeyedCodec<>("WeaponSlot", Codec.INTEGER),
         (var0, var1) -> var0.weaponSlot = var1,
         var0 -> var0.weaponSlot,
         (var0, var1) -> var0.weaponSlot = var1.weaponSlot
      )
      .documentation("The weapon (hotbar) slot to class="kw">switch to for this attack.")
      .add()
      .<Integer>appendInherited(
         new KeyedCodec<>("OffhandSlot", Codec.INTEGER),
         (var0, var1) -> var0.offhandSlot = var1,
         var0 -> var0.offhandSlot,
         (var0, var1) -> var0.offhandSlot = var1.offhandSlot
      )
      .documentation("The off-hand slot to class="kw">switch to for this attack. -1 set to no off-hand equipped.")
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("FailureTimeout", Codec.FLOAT),
         (var0, var1) -> var0.failureTimeout = var1,
         var0 -> var0.failureTimeout,
         (var0, var1) -> var0.failureTimeout = var1.failureTimeout
      )
      .addValidator(Validators.greaterThan(0.0F))
      .documentation("How long to try and run the action before giving up if it can't be completed in time.")
      .add()
      .<String>appendInherited(
         new KeyedCodec<>("SubState", Codec.STRING), (var0, var1) -> var0.subState = var1, var0 -> var0.subState, (var0, var1) -> var0.subState = var1.subState
      )
      .addValidator(Validators.nonEmptyString())
      .documentation("An optional substate to class="kw">switch to when selecting this combat action to modify motion or other available actions.")
      .add()
      .<Map>appendInherited(
         new KeyedCodec<>("InteractionVars", new MapCodec<>(RootInteraction.CHILD_ASSET_CODEC, Object2ObjectOpenHashMap::new)),
         (var0, var1) -> var0.interactionVars = var1,
         var0 -> var0.interactionVars,
         (var0, var1) -> var0.interactionVars = var1.interactionVars
      )
      .addValidator(RootInteraction.VALIDATOR_CACHE.getMapValueValidator())
      .documentation("Interaction vars to modify the values in the interaction itself.")
      .add()
      .<Boolean>appendInherited(
         new KeyedCodec<>("DamageFriendlies", Codec.BOOLEAN),
         (var0, var1) -> var0.damageFriendlies = var1,
         var0 -> var0.damageFriendlies,
         (var0, var1) -> var0.damageFriendlies = var1.damageFriendlies
      )
      .documentation("Whether or not this ability should be able to damage friendly targets.")
      .add()
      .<Boolean>appendInherited(
         new KeyedCodec<>("RequireAiming", Codec.BOOLEAN),
         (var0, var1) -> var0.requireAiming = var1,
         var0 -> var0.requireAiming,
         (var0, var1) -> var0.requireAiming = var1.requireAiming
      )
      .documentation("Whether or not this ability needs to be aimed at the target.")
      .add()
      .<Positioning>appendInherited(
         new KeyedCodec<>("Positioning", POSITIONING_CODEC),
         (var0, var1) -> var0.positioning = var1,
         var0 -> var0.positioning,
         (var0, var1) -> var0.positioning = var1.positioning
      )
      .documentation("Where the NPC should try to position itself relative to the target's facing direction.")
      .add()
      .<Boolean>appendInherited(
         new KeyedCodec<>("PositionFirst", Codec.BOOLEAN),
         (var0, var1) -> var0.positionFirst = var1,
         var0 -> var0.positionFirst,
         (var0, var1) -> var0.positionFirst = var1.positionFirst
      )
      .documentation("Whether the NPC should try to reach the correct positioning before executing the ability.")
      .add()
      .<Double>appendInherited(
         new KeyedCodec<>("ChargeDistance", Codec.DOUBLE),
         (var0, var1) -> var0.chargeDistance = var1,
         var0 -> var0.chargeDistance,
         (var0, var1) -> var0.chargeDistance = var1.chargeDistance
      )
      .documentation("If this is a charge attack, the distance the charge will cover.")
      .addValidator(Validators.greaterThanOrEqual(0.0))
      .add()
      .build();
   @Nonnull
   class="kw">protected class="kw">static class="kw">final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
   class="kw">protected String ability;
   class="kw">protected AbilityCombatAction.AbilityType abilityType = AbilityCombatAction.AbilityType.Primary;
   class="kw">protected float chargeFor;
   class="kw">protected double[] attackRange;
   class="kw">protected double maxRangeSquared;
   class="kw">protected int weaponSlot;
   class="kw">protected int offhandSlot = -1;
   class="kw">protected float failureTimeout = 10.0F;
   class="kw">protected String subState;
   class="kw">protected Map<String, String> interactionVars = Collections.emptyMap();
   class="kw">protected boolean damageFriendlies;
   class="kw">protected boolean requireAiming = true;
   class="kw">protected Positioning positioning = Positioning.Any;
   class="kw">protected boolean positionFirst;
   class="kw">protected double chargeDistance;

   class="kw">public AbilityCombatAction() {
   }

   class="kw">public String getAbility() {
      class="kw">return this.ability;
   }

   class="kw">public float getChargeFor() {
      class="kw">return this.chargeFor;
   }

   class="kw">public double[] getAttackRange() {
      class="kw">return this.attackRange;
   }

   class="kw">public int getWeaponSlot() {
      class="kw">return this.weaponSlot;
   }

   class="kw">public int getOffhandSlot() {
      class="kw">return this.offhandSlot;
   }

   class="kw">public float getFailureTimeout() {
      class="kw">return this.failureTimeout;
   }

   class="kw">public boolean isDamageFriendlies() {
      class="kw">return this.damageFriendlies;
   }

   class="kw">public boolean isPositionFirst() {
      class="kw">return this.positionFirst;
   }

   @Override
   class="kw">public void execute(
      int var1,
      @Nonnull ArchetypeChunk<EntityStore> var2,
      @Nonnull CommandBuffer<EntityStore> var3,
      @Nonnull ExecutionSupport var4,
      @Nonnull CombatActionEvaluator var5,
      @Nonnull ValueStore var6
   ) {
      NPCEntity var7 = var2.getComponent(var1, NPCEntity.getComponentType());
      assert var7 != null;
      HytaleLogger.Api var8 = CombatActionEvaluator.LOGGER.at(Level.FINEST);
      if (var8.isEnabled()) {
         var8.log("%s: Executing option %s", var2.getReferenceTo(var1), this.getId());
      }

      Ref var9 = var2.getReferenceTo(var1);
      InventoryHelper.setHotbarSlot(var9, (byte)this.weaponSlot, var3);
      InventoryHelper.setOffHandSlot(var9, (byte)this.offhandSlot, var3);
      if (this.subState != null) {
         var4.getStateSupport().setSubState(this.subState);
         var8 = CombatActionEvaluator.LOGGER.at(Level.FINEST);
         if (var8.isEnabled()) {
            var8.log("%s: Set substate to %s", var2.getReferenceTo(var1), this.subState);
         }
      }

      if (this.actionTarget == CombatActionOption.Target.Self) {
         RootInteraction var18 = RootInteraction.getAssetMap().getAsset(this.ability);
         if (var18 == null) {
            throw new IllegalStateException("No such interaction: " + this.ability);
         }

         InteractionManager var19 = var2.getComponent(var1, InteractionModule.get().getInteractionManagerComponent());
         assert var19 != null;
         if (var19.getInteractionSimulationHandler() class="kw">instanceof NPCInteractionSimulationHandler var13) {
            var13.requestChargeTime(this.chargeFor);
         }

         InteractionContext var20 = InteractionContext.forInteraction(var19, var9, this.abilityType.interactionType, var3);
         var20.setInteractionVarsGetter(this::getInteractionVars);
         InteractionChain var14 = var19.initChain(this.abilityType.interactionType, var20, var18, false);
         var19.queueExecuteChain(var14);
         var4.getCombatSupport().setExecutingAttack(var14, false, 2.0);
         var8 = CombatActionEvaluator.LOGGER.at(Level.INFO);
         if (var8.isEnabled()) {
            var8.log("%s: Executed self-targeted ability %s", var2.getReferenceTo(var1), this.ability);
         }

         var5.completeCurrentAction(true, true);
      } else {
         var6.storeDouble(var5.getMinRangeSlot(), this.attackRange[0]);
         var6.storeDouble(var5.getMaxRangeSlot(), this.attackRange[1]);
         if (this.positioning == Positioning.Any) {
            var6.storeDouble(var5.getPositioningAngleSlot(), Double.MAX_VALUE);
         } else {
            float var10 = RandomExtra.randomRange(0.0F, (float) (Math.PI / 2));

            float var11 = PhysicsMath.normalizeTurnAngle(class="kw">switch (this.positioning) {
               case Front -> var10 + (float) (Math.PI / 2) + (float) (Math.PI / 4);
               case Behind -> var10 - (float) (Math.PI / 4);
               case Flank -> var10 + (RandomExtra.randomBoolean() ? (float) (Math.PI / 4) : (float) (-Math.PI * 3.0 / 4.0));
               class="kw">default -> throw new IllegalStateException("Unexpected value: " + this.positioning);
            });
            var6.storeDouble(var5.getPositioningAngleSlot(), var11);
         }

         var5.setCurrentInteraction(
            this.ability,
            this.abilityType.interactionType,
            this.chargeFor,
            this.damageFriendlies,
            this.requireAiming,
            this.positionFirst,
            this.chargeDistance,
            this::getInteractionVars
         );
         var5.setTimeout(this.failureTimeout);
         var8 = CombatActionEvaluator.LOGGER.at(Level.FINEST);
         if (var8.isEnabled()) {
            var8.log("%s: Began executing ability %s", var2.getReferenceTo(var1), this.ability);
         }
      }
   }

   @Override
   class="kw">public boolean isBasicAttackAllowed(
      int var1, @Nonnull ArchetypeChunk<EntityStore> var2, @Nonnull CommandBuffer<EntityStore> var3, @Nonnull CombatActionEvaluator var4
   ) {
      Ref var5 = var4.getPrimaryTarget();
      if (var5 != null && var5.isValid()) {
         TransformComponent var6 = var3.getComponent(var5, TRANSFORM_COMPONENT_TYPE);
         assert var6 != null;
         Vector3d var7 = var6.getPosition();
         TransformComponent var8 = var2.getComponent(var1, TRANSFORM_COMPONENT_TYPE);
         assert var8 != null;
         Vector3d var9 = var8.getPosition();
         double var10 = var9.distanceSquared(var7);
         class="kw">return var10 > this.maxRangeSquared;
      } else {
         class="kw">return true;
      }
   }

   class="kw">private Map<String, String> getInteractionVars(InteractionContext var1) {
      class="kw">return this.interactionVars;
   }

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return "AbilityCombatAction{ability='"
         + this.ability
         + "', abilityType="
         + this.abilityType
         + ", chargeFor="
         + this.chargeFor
         + ", attackRange="
         + Arrays.toString(this.attackRange)
         + ", maxRangeSquared="
         + this.maxRangeSquared
         + ", weaponSlot="
         + this.weaponSlot
         + ", offhandSlot="
         + this.offhandSlot
         + ", failureTimeout="
         + this.failureTimeout
         + ", subState='"
         + this.subState
         + "', interactionVars="
         + this.interactionVars
         + ", damageFriendlies="
         + this.damageFriendlies
         + ", requireAiming="
         + this.requireAiming
         + "}"
         + super.toString();
   }

   class="kw">private enum AbilityType {
      Primary(InteractionType.Primary),
      Secondary(InteractionType.Secondary);

      class="kw">private class="kw">final InteractionType interactionType;

      AbilityType(InteractionType nullxx) {
         this.interactionType = nullxx;
      }
   }
}