AbilityCombatAction class

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

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

extends: CombatActionOption

Поля (19)

МодификаторыТипИмя
private final InteractionType interactionType
float var10
double var10
float var11
InteractionChain var14
RootInteraction var18
InteractionManager var19
InteractionContext var20
Ref var5
TransformComponent var6
NPCEntity var7
Vector3d var7
HytaleLogger.Api var8
var8
var8
var8
TransformComponent var8
Ref var9
Vector3d var9

Методы (16)

МодификаторыВозвратСигнатура
AbilityType AbilityType(InteractionType nullxx)
abstract throw new IllegalStateExceptionthrow new IllegalStateException("No such interaction: " + this.ability)
abstract Secondary Secondary(InteractionType.Secondary)
public String getAbilityString getAbility()
public double[] getAttackRangedouble[] getAttackRange()
public float getChargeForfloat getChargeFor()
public float getFailureTimeoutfloat getFailureTimeout()
private Map<String, String> getInteractionVarsMap<String, String> getInteractionVars(InteractionContext var1)
public int getOffhandSlotint getOffhandSlot()
public int getWeaponSlotint getWeaponSlot()
if if(this.subState != null)
if if(this.actionTarget == CombatActionOption.Target.Self)
if if(var18 == null)
if if(this.positioning == Positioning.Any)
public boolean isDamageFriendliesboolean isDamageFriendlies()
public boolean isPositionFirstboolean isPositionFirst()

Исходный код

Показать/скрыть
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;
      }
   }
}