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;
}
}
}