package com.hypixel.hytale.server.core.modules.entity.damage;
import com.hypixel.hytale.assetstore.AssetRegistry;
import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.SystemGroup;
import com.hypixel.hytale.component.dependency.Dependency;
import com.hypixel.hytale.component.dependency.Order;
import com.hypixel.hytale.component.dependency.SystemDependency;
import com.hypixel.hytale.component.dependency.SystemGroupDependency;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.spatial.SpatialResource;
import com.hypixel.hytale.component.spatial.SpatialStructure;
import com.hypixel.hytale.component.system.tick.DelayedEntitySystem;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
import com.hypixel.hytale.math.random.RandomExtra;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.math.util.TrigMathUtil;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.math.vector.Vector4d;
import com.hypixel.hytale.protocol.AnimationSlot;
import com.hypixel.hytale.protocol.BlockMaterial;
import com.hypixel.hytale.protocol.BlockPosition;
import com.hypixel.hytale.protocol.CombatTextUpdate;
import com.hypixel.hytale.protocol.ComponentUpdate;
import com.hypixel.hytale.protocol.ComponentUpdateType;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.protocol.MovementStates;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.protocol.packets.entities.SpawnModelParticles;
import com.hypixel.hytale.protocol.packets.player.DamageInfo;
import com.hypixel.hytale.protocol.packets.player.ReticleEvent;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.EntityEffect;
import com.hypixel.hytale.server.core.asset.type.gameplay.BrokenPenalties;
import com.hypixel.hytale.server.core.asset.type.gameplay.GameplayConfig;
import com.hypixel.hytale.server.core.asset.type.gameplay.PlayerConfig;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemArmor;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelParticle;
import com.hypixel.hytale.server.core.asset.type.particle.config.WorldParticle;
import com.hypixel.hytale.server.core.entity.AnimationUtils;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.server.core.entity.EntityUtils;
import com.hypixel.hytale.server.core.entity.InteractionChain;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.server.core.entity.InteractionManager;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.entity.damage.DamageDataComponent;
import com.hypixel.hytale.server.core.entity.effect.EffectControllerComponent;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.movement.MovementConfig;
import com.hypixel.hytale.server.core.entity.knockback.KnockbackComponent;
import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.meta.DynamicMetaStore;
import com.hypixel.hytale.server.core.modules.entity.AllLegacyLivingEntityTypesQuery;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.component.Intangible;
import com.hypixel.hytale.server.core.modules.entity.component.Invulnerable;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerInput;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSystems;
import com.hypixel.hytale.server.core.modules.entity.tracker.EntityTrackerSystems;
import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatMap;
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatValue;
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatsSystems;
import com.hypixel.hytale.server.core.modules.entitystats.asset.DefaultEntityStatTypes;
import com.hypixel.hytale.server.core.modules.entitystats.modifier.StaticModifier;
import com.hypixel.hytale.server.core.modules.entityui.EntityUIModule;
import com.hypixel.hytale.server.core.modules.entityui.UIComponentList;
import com.hypixel.hytale.server.core.modules.interaction.InteractionModule;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.client.WieldingInteraction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.server.combat.DamageEffects;
import com.hypixel.hytale.server.core.modules.physics.component.Velocity;
import com.hypixel.hytale.server.core.modules.splitvelocity.SplitVelocity;
import com.hypixel.hytale.server.core.modules.time.TimeResource;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.ParticleUtil;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.ints.Int2DoubleMap;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectList;
import it.unimi.dsi.fastutil.shorts.ShortArrayList;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bouncycastle.util.Arrays;
public class DamageSystems {
public static final float DEFAULT_DAMAGE_DELAY = 1.0F;
private static final Query<EntityStore> NPCS_QUERY;
public DamageSystems() {
}
public static void executeDamage(@Nonnull Ref<EntityStore> ref, @Nonnull ComponentAccessor<EntityStore> componentAccessor, @Nonnull Damage damage) {
componentAccessor.invoke(ref, damage);
}
public static void executeDamage(int index, @Nonnull ArchetypeChunk<EntityStore> chunk, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
commandBuffer.invoke(chunk.getReferenceTo(index), damage);
}
public static void executeDamage(@Nonnull Ref<EntityStore> ref, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
commandBuffer.invoke(ref, damage);
}
static {
NPCS_QUERY = Query.<EntityStore>and(AllLegacyLivingEntityTypesQuery.INSTANCE, EntityStatMap.getComponentType(), MovementStatesComponent.getComponentType(), Query.not(EntityModule.get().getPlayerComponentType()));
}
public static class FilterUnkillable extends DamageEventSystem {
public static boolean CAUSE_DESYNC;
@Nonnull
private static final Query<EntityStore> QUERY;
public FilterUnkillable() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
EffectControllerComponent entityEffectControllerComponent = (EffectControllerComponent)archetypeChunk.getComponent(index, EffectControllerComponent.getComponentType());
if (entityEffectControllerComponent != null && entityEffectControllerComponent.isInvulnerable()) {
damage.setCancelled(true);
}
Archetype<EntityStore> archetype = archetypeChunk.getArchetype();
boolean dead = archetype.contains(DeathComponent.getComponentType());
boolean invulnerable = archetype.contains(Invulnerable.getComponentType());
boolean intangible = archetype.contains(Intangible.getComponentType());
if (dead || invulnerable || intangible || CAUSE_DESYNC) {
damage.setCancelled(true);
}
}
static {
QUERY = AllLegacyLivingEntityTypesQuery.INSTANCE;
}
}
public static class FilterPlayerWorldConfig extends DamageEventSystem {
private static final Query<EntityStore> QUERY;
public FilterPlayerWorldConfig() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nullable
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage event) {
World world = ((EntityStore)store.getExternalData()).getWorld();
GameplayConfig gameplayConfig = world.getGameplayConfig();
if (gameplayConfig.getCombatConfig().isPlayerIncomingDamageDisabled()) {
event.setCancelled(true);
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
commandBuffer.tryRemoveComponent(ref, KnockbackComponent.getComponentType());
}
}
static {
QUERY = Query.<EntityStore>and(AllLegacyLivingEntityTypesQuery.INSTANCE, Player.getComponentType());
}
}
public static class FilterNPCWorldConfig extends DamageEventSystem {
public FilterNPCWorldConfig() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nullable
public Query<EntityStore> getQuery() {
return DamageSystems.NPCS_QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage event) {
World world = ((EntityStore)store.getExternalData()).getWorld();
GameplayConfig gameplayConfig = world.getGameplayConfig();
if (gameplayConfig.getCombatConfig().isNpcIncomingDamageDisabled()) {
event.setCancelled(true);
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
commandBuffer.tryRemoveComponent(ref, KnockbackComponent.getComponentType());
}
}
}
public static class ApplyParticles extends DamageEventSystem {
@Nonnull
private static final ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> PLAYER_SPATIAL_RESOURCE_TYPE = EntityModule.get().getPlayerSpatialResourceType();
@Nonnull
private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
@Nonnull
private static final Query<EntityStore> QUERY;
public ApplyParticles() {
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
TransformComponent transformComponent = (TransformComponent)archetypeChunk.getComponent(index, TRANSFORM_COMPONENT_TYPE);
assert transformComponent != null;
NetworkId networkIdComponent = (NetworkId)archetypeChunk.getComponent(index, NetworkId.getComponentType());
assert networkIdComponent != null;
int targetNetworkId = networkIdComponent.getId();
Damage.Particles particles = (Damage.Particles)damage.getIfPresentMetaObject(Damage.IMPACT_PARTICLES);
if (particles != null) {
Damage.Source var11 = damage.getSource();
if (var11 instanceof Damage.EntitySource) {
Damage.EntitySource sourceEntity = (Damage.EntitySource)var11;
Ref<EntityStore> sourceRef = sourceEntity.getRef();
if (sourceRef.isValid()) {
Vector4d hitLocation = (Vector4d)damage.getIfPresentMetaObject(Damage.HIT_LOCATION);
Vector3d targetPosition = hitLocation == null ? transformComponent.getPosition() : new Vector3d(hitLocation.x, hitLocation.y, hitLocation.z);
boolean damageCanBePredicted = (Boolean)damage.getMetaStore().getMetaObject(Damage.CAN_BE_PREDICTED);
double particlesViewDistance = particles.getViewDistance();
WorldParticle[] worldParticles = particles.getWorldParticles();
if (!Arrays.isNullOrEmpty((Object[])worldParticles)) {
TransformComponent sourceTransformComponent = (TransformComponent)commandBuffer.getComponent(sourceRef, TransformComponent.getComponentType());
assert sourceTransformComponent != null;
float angleBetween = TrigMathUtil.atan2(sourceTransformComponent.getPosition().x - targetPosition.x, sourceTransformComponent.getPosition().z - targetPosition.z);
SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = (SpatialResource)commandBuffer.getResource(EntityModule.get().getPlayerSpatialResourceType());
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
playerSpatialResource.getSpatialStructure().collect(targetPosition, particlesViewDistance, results);
Ref<EntityStore> particleSource = damageCanBePredicted ? sourceRef : null;
for(WorldParticle particle : worldParticles) {
ParticleUtil.spawnParticleEffect((WorldParticle)particle, targetPosition, angleBetween, 0.0F, 0.0F, particleSource, results, commandBuffer);
}
}
ModelParticle[] modelParticles = particles.getModelParticles();
if (!Arrays.isNullOrEmpty((Object[])modelParticles)) {
com.hypixel.hytale.protocol.ModelParticle[] modelParticlesProtocol = new com.hypixel.hytale.protocol.ModelParticle[modelParticles.length];
for(int j = 0; j < modelParticles.length; ++j) {
modelParticlesProtocol[j] = modelParticles[j].toPacket();
}
SpawnModelParticles packet = new SpawnModelParticles(targetNetworkId, modelParticlesProtocol);
SpatialResource<Ref<EntityStore>, EntityStore> spatialResource = (SpatialResource)store.getResource(PLAYER_SPATIAL_RESOURCE_TYPE);
SpatialStructure<Ref<EntityStore>> spatialStructure = spatialResource.getSpatialStructure();
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
spatialStructure.ordered(targetPosition, particlesViewDistance, results);
for(Ref<EntityStore> targetRef : results) {
if (damageCanBePredicted && targetRef.equals(sourceRef)) {
return;
}
PlayerRef playerRefComponent = (PlayerRef)commandBuffer.getComponent(targetRef, PlayerRef.getComponentType());
assert playerRefComponent != null;
playerRefComponent.getPacketHandler().write((Packet)packet);
}
}
}
}
}
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
static {
QUERY = TRANSFORM_COMPONENT_TYPE;
}
}
public static class ApplySoundEffects extends DamageEventSystem {
@Nonnull
private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
@Nonnull
private static final ComponentType<EntityStore, Player> PLAYER_COMPONENT_TYPE = Player.getComponentType();
@Nonnull
private static final Query<EntityStore> QUERY;
public ApplySoundEffects() {
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
}
public void handleInternal(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
TransformComponent transformComponent = (TransformComponent)archetypeChunk.getComponent(index, TRANSFORM_COMPONENT_TYPE);
assert transformComponent != null;
Player playerComponent = (Player)archetypeChunk.getComponent(index, PLAYER_COMPONENT_TYPE);
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
Damage.SoundEffect soundEffect = (Damage.SoundEffect)damage.getIfPresentMetaObject(Damage.IMPACT_SOUND_EFFECT);
Damage.SoundEffect playerSoundEffect = (Damage.SoundEffect)damage.getIfPresentMetaObject(Damage.PLAYER_IMPACT_SOUND_EFFECT);
if (soundEffect != null || playerSoundEffect != null) {
Damage.Source var13 = damage.getSource();
Ref<EntityStore> sourceRef;
if (var13 instanceof Damage.EntitySource) {
Damage.EntitySource source = (Damage.EntitySource)var13;
sourceRef = source.getRef().isValid() ? source.getRef() : null;
} else {
sourceRef = null;
}
Vector4d hitLocation = (Vector4d)damage.getIfPresentMetaObject(Damage.HIT_LOCATION);
Vector3d targetPosition = hitLocation == null ? transformComponent.getPosition() : new Vector3d(hitLocation.x, hitLocation.y, hitLocation.z);
if (soundEffect != null && soundEffect.getSoundEventIndex() != 0) {
Predicate<Ref<EntityStore>> filter = sourceRef != null ? (p) -> !p.equals(sourceRef) : (p) -> true;
SoundUtil.playSoundEvent3d(soundEffect.getSoundEventIndex(), targetPosition.x, targetPosition.y, targetPosition.z, filter, commandBuffer);
}
if (playerComponent != null && playerSoundEffect != null && playerSoundEffect.getSoundEventIndex() != 0) {
SoundUtil.playSoundEvent3dToPlayer(ref, playerSoundEffect.getSoundEventIndex(), SoundCategory.SFX, targetPosition.x, targetPosition.y, targetPosition.z, commandBuffer);
}
}
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
static {
QUERY = TRANSFORM_COMPONENT_TYPE;
}
}
public static class RecordLastCombat extends DamageEventSystem {
@Nonnull
private static final ComponentType<EntityStore, DamageDataComponent> DAMAGE_DATA_COMPONENT_TYPE = DamageDataComponent.getComponentType();
@Nonnull
private static final ResourceType<EntityStore, TimeResource> TIME_RESOURCE_TYPE = TimeResource.getResourceType();
@Nonnull
private static final Query<EntityStore> QUERY;
public RecordLastCombat() {
}
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
DamageDataComponent damageDataComponent = (DamageDataComponent)archetypeChunk.getComponent(index, DAMAGE_DATA_COMPONENT_TYPE);
assert damageDataComponent != null;
Instant timestamp = ((TimeResource)store.getResource(TIME_RESOURCE_TYPE)).getNow();
damageDataComponent.setLastCombatAction(timestamp);
Damage.Source var9 = damage.getSource();
if (var9 instanceof Damage.EntitySource) {
Damage.EntitySource entitySource = (Damage.EntitySource)var9;
Ref<EntityStore> sourceRef = entitySource.getRef();
if (!sourceRef.isValid()) {
return;
}
DamageDataComponent sourceDamageDataComponent = (DamageDataComponent)store.getComponent(sourceRef, DAMAGE_DATA_COMPONENT_TYPE);
if (sourceDamageDataComponent != null) {
sourceDamageDataComponent.setLastCombatAction(timestamp);
}
}
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
static {
QUERY = DAMAGE_DATA_COMPONENT_TYPE;
}
}
public static class ApplyDamage extends DamageEventSystem implements EntityStatsSystems.StatModifyingSystem {
@Nonnull
private static final Query<EntityStore> QUERY = EntityStatMap.getComponentType();
@Nonnull
private static final Set<Dependency<EntityStore>> DEPENDENCIES;
public ApplyDamage() {
}
public Query<EntityStore> getQuery() {
return QUERY;
}
@Nonnull
public Set<Dependency<EntityStore>> getDependencies() {
return DEPENDENCIES;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
EntityStatMap entityStatMapComponent = (EntityStatMap)archetypeChunk.getComponent(index, EntityStatMap.getComponentType());
assert entityStatMapComponent != null;
int healthStat = DefaultEntityStatTypes.getHealth();
EntityStatValue healthValue = entityStatMapComponent.get(healthStat);
Objects.requireNonNull(healthValue);
boolean isDead = archetypeChunk.getArchetype().contains(DeathComponent.getComponentType());
if (isDead) {
damage.setCancelled(true);
} else {
damage.setAmount((float)Math.round(damage.getAmount()));
float newValue = entityStatMapComponent.subtractStatValue(healthStat, damage.getAmount());
if (newValue <= healthValue.getMin()) {
DeathComponent.tryAddComponent(commandBuffer, archetypeChunk.getReferenceTo(index), damage);
}
}
}
static {
DEPENDENCIES = Set.of(new SystemGroupDependency(Order.AFTER, DamageModule.get().getGatherDamageGroup()), new SystemGroupDependency(Order.AFTER, DamageModule.get().getFilterDamageGroup()), new SystemGroupDependency(Order.BEFORE, DamageModule.get().getInspectDamageGroup()));
}
}
public static class CanBreathe extends DelayedEntitySystem<EntityStore> {
private static final float DAMAGE_AMOUNT_DROWNING = 10.0F;
private static final float DAMAGE_AMOUNT_SUFFOCATION = 20.0F;
@Nonnull
private static final ComponentType<EntityStore, ModelComponent> MODEL_COMPONENT_TYPE = ModelComponent.getComponentType();
@Nonnull
private static final Query<EntityStore> QUERY;
public CanBreathe() {
super(1.0F);
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getGatherDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void tick(float dt, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
LivingEntity entity = (LivingEntity)EntityUtils.getEntity(index, archetypeChunk);
assert entity != null;
EntityStatMap statMapComponent = (EntityStatMap)archetypeChunk.getComponent(index, EntityStatMap.getComponentType());
assert statMapComponent != null;
EntityStatValue oxygenStatValue = statMapComponent.get(DefaultEntityStatTypes.getOxygen());
if (oxygenStatValue != null) {
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
long packed = LivingEntity.getPackedMaterialAndFluidAtBreathingHeight(ref, commandBuffer);
BlockMaterial material = BlockMaterial.VALUES[MathUtil.unpackLeft(packed)];
int fluidId = MathUtil.unpackRight(packed);
if (!entity.canBreathe(ref, material, fluidId, commandBuffer) && oxygenStatValue.get() <= oxygenStatValue.getMin()) {
Damage damage;
if (fluidId != 0) {
assert DamageCause.DROWNING != null;
damage = new Damage(Damage.NULL_SOURCE, DamageCause.DROWNING, 10.0F);
} else {
assert DamageCause.SUFFOCATION != null;
damage = new Damage(Damage.NULL_SOURCE, DamageCause.SUFFOCATION, 20.0F);
}
DamageSystems.executeDamage(index, archetypeChunk, commandBuffer, damage);
}
}
}
public boolean isParallel(int archetypeChunkSize, int taskCount) {
return false;
}
static {
QUERY = Query.<EntityStore>and(AllLegacyLivingEntityTypesQuery.INSTANCE, EntityStatMap.getComponentType(), TransformComponent.getComponentType(), MODEL_COMPONENT_TYPE);
}
}
public static class OutOfWorldDamage extends DelayedEntitySystem<EntityStore> {
@Nonnull
private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
public OutOfWorldDamage() {
super(1.0F);
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getGatherDamageGroup();
}
public Query<EntityStore> getQuery() {
return TRANSFORM_COMPONENT_TYPE;
}
public void tick(float dt, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
TransformComponent transformComponent = (TransformComponent)archetypeChunk.getComponent(index, TRANSFORM_COMPONENT_TYPE);
assert transformComponent != null;
double posY = transformComponent.getPosition().getY();
if (!(posY >= 0.0)) {
boolean belowMinimum = posY < -32.0;
Damage damage = new Damage(Damage.NULL_SOURCE, DamageCause.OUT_OF_WORLD, belowMinimum ? 2.1474836E9F : 50.0F);
if (belowMinimum) {
DeathComponent.tryAddComponent(commandBuffer, archetypeChunk.getReferenceTo(index), damage);
} else {
DamageSystems.executeDamage(index, archetypeChunk, commandBuffer, damage);
}
}
}
public boolean isParallel(int archetypeChunkSize, int taskCount) {
return EntityTickingSystem.maybeUseParallel(archetypeChunkSize, taskCount);
}
}
public static class FallDamagePlayers extends EntityTickingSystem<EntityStore> {
static final float CURVE_MODIFIER = 0.58F;
static final float CURVE_MULTIPLIER = 2.0F;
public static final double MIN_DAMAGE = 10.0;
@Nonnull
private static final Query<EntityStore> QUERY = Query.<EntityStore>and(EntityStatMap.getComponentType(), MovementStatesComponent.getComponentType(), EntityModule.get().getPlayerComponentType(), PlayerInput.getComponentType());
@Nonnull
private static final Set<Dependency<EntityStore>> DEPENDENCIES;
public FallDamagePlayers() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getGatherDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
@Nonnull
public Set<Dependency<EntityStore>> getDependencies() {
return DEPENDENCIES;
}
public void tick(float dt, int systemIndex, @Nonnull Store<EntityStore> store) {
World world = ((EntityStore)store.getExternalData()).getWorld();
if (world.getWorldConfig().isFallDamageEnabled()) {
super.tick(dt, systemIndex, store);
}
}
public void tick(float dt, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
PlayerInput playerInputComponent = (PlayerInput)archetypeChunk.getComponent(index, PlayerInput.getComponentType());
assert playerInputComponent != null;
Velocity velocityComponent = (Velocity)archetypeChunk.getComponent(index, Velocity.getComponentType());
assert velocityComponent != null;
double yVelocity = Math.abs(velocityComponent.getClientVelocity().getY());
World world = ((EntityStore)commandBuffer.getExternalData()).getWorld();
PlayerConfig worldPlayerConfig = world.getGameplayConfig().getPlayerConfig();
List<PlayerInput.InputUpdate> queue = playerInputComponent.getMovementUpdateQueue();
for(int i = 0; i < queue.size(); ++i) {
PlayerInput.InputUpdate queueEntry = (PlayerInput.InputUpdate)queue.get(i);
Objects.requireNonNull(queueEntry);
byte var16 = 0;
switch (queueEntry.typeSwitch<invokedynamic>(queueEntry, var16)) {
case 0:
PlayerInput.SetClientVelocity velocityEntry = (PlayerInput.SetClientVelocity)queueEntry;
yVelocity = Math.abs(velocityEntry.getVelocity().y);
break;
case 1:
PlayerInput.SetMovementStates movementStatesEntry = (PlayerInput.SetMovementStates)queueEntry;
Player playerComponent = (Player)archetypeChunk.getComponent(index, Player.getComponentType());
assert playerComponent != null;
if (movementStatesEntry.movementStates().onGround && playerComponent.getCurrentFallDistance() > 0.0) {
int movementConfigIndex = worldPlayerConfig.getMovementConfigIndex();
MovementConfig movementConfig = (MovementConfig)MovementConfig.getAssetMap().getAsset(movementConfigIndex);
float minFallSpeedToEngageRoll = movementConfig.getMinFallSpeedToEngageRoll();
if (yVelocity > (double)minFallSpeedToEngageRoll && !movementStatesEntry.movementStates().inFluid) {
EntityStatMap entityStatMapComponent = (EntityStatMap)archetypeChunk.getComponent(index, EntityStatMap.getComponentType());
assert entityStatMapComponent != null;
double damagePercentage = Math.pow(0.5799999833106995 * (yVelocity - (double)minFallSpeedToEngageRoll), 2.0) + 10.0;
EntityStatValue healthStatValue = entityStatMapComponent.get(DefaultEntityStatTypes.getHealth());
assert healthStatValue != null;
float maxHealth = healthStatValue.getMax();
double healthModifier = (double)maxHealth / 100.0;
int damageInt = (int)Math.floor(healthModifier * damagePercentage);
if (movementStatesEntry.movementStates().rolling) {
if (yVelocity <= (double)movementConfig.getMaxFallSpeedRollFullMitigation()) {
damageInt = 0;
} else if (yVelocity <= (double)movementConfig.getMaxFallSpeedToEngageRoll()) {
damageInt = (int)((double)damageInt * (1.0 - (double)movementConfig.getFallDamagePartialMitigationPercent() / 100.0));
}
}
if (damageInt > 0) {
assert DamageCause.FALL != null;
Damage damage = new Damage(Damage.NULL_SOURCE, DamageCause.FALL, (float)damageInt);
DamageSystems.executeDamage(index, archetypeChunk, commandBuffer, damage);
}
}
playerComponent.setCurrentFallDistance(0.0);
}
}
}
}
public boolean isParallel(int archetypeChunkSize, int taskCount) {
return EntityTickingSystem.maybeUseParallel(archetypeChunkSize, taskCount);
}
static {
DEPENDENCIES = Set.of(new SystemDependency(Order.BEFORE, PlayerSystems.ProcessPlayerInput.class));
}
}
public static class FallDamageNPCs extends EntityTickingSystem<EntityStore> {
static final float CURVE_MODIFIER = 0.58F;
static final float CURVE_MULTIPLIER = 2.0F;
public static final double MIN_DAMAGE = 10.0;
public FallDamageNPCs() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getGatherDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return DamageSystems.NPCS_QUERY;
}
public void tick(float dt, int systemIndex, @Nonnull Store<EntityStore> store) {
World world = ((EntityStore)store.getExternalData()).getWorld();
if (world.getWorldConfig().isFallDamageEnabled()) {
super.tick(dt, systemIndex, store);
}
}
public void tick(float dt, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
LivingEntity entity = (LivingEntity)EntityUtils.getEntity(index, archetypeChunk);
assert entity != null;
MovementStatesComponent movementStatesComponent = (MovementStatesComponent)archetypeChunk.getComponent(index, MovementStatesComponent.getComponentType());
assert movementStatesComponent != null;
MovementStates movementStates = movementStatesComponent.getMovementStates();
if (movementStates.onGround && entity.getCurrentFallDistance() > 0.0) {
Velocity velocityComponent = (Velocity)archetypeChunk.getComponent(index, Velocity.getComponentType());
assert velocityComponent != null;
double yVelocity = Math.abs(velocityComponent.getVelocity().getY());
World world = ((EntityStore)commandBuffer.getExternalData()).getWorld();
int movementConfigIndex = world.getGameplayConfig().getPlayerConfig().getMovementConfigIndex();
MovementConfig movementConfig = (MovementConfig)MovementConfig.getAssetMap().getAsset(movementConfigIndex);
float minFallSpeedToEngageRoll = movementConfig.getMinFallSpeedToEngageRoll();
if (yVelocity > (double)minFallSpeedToEngageRoll && !movementStates.inFluid) {
EntityStatMap entityStatMapComponent = (EntityStatMap)archetypeChunk.getComponent(index, EntityStatMap.getComponentType());
assert entityStatMapComponent != null;
double damagePercentage = Math.pow(0.5799999833106995 * (yVelocity - (double)minFallSpeedToEngageRoll), 2.0) + 10.0;
EntityStatValue healthStatValue = entityStatMapComponent.get(DefaultEntityStatTypes.getHealth());
assert healthStatValue != null;
float maxHealth = healthStatValue.getMax();
double healthModifier = (double)maxHealth / 100.0;
int damageInt = (int)Math.floor(healthModifier * damagePercentage);
if (movementStates.rolling) {
if (yVelocity <= (double)movementConfig.getMaxFallSpeedRollFullMitigation()) {
damageInt = 0;
} else if (yVelocity <= (double)movementConfig.getMaxFallSpeedToEngageRoll()) {
damageInt = (int)((double)damageInt * (1.0 - (double)movementConfig.getFallDamagePartialMitigationPercent() / 100.0));
}
}
if (damageInt > 0) {
assert DamageCause.FALL != null;
Damage damage = new Damage(Damage.NULL_SOURCE, DamageCause.FALL, (float)damageInt);
DamageSystems.executeDamage(index, archetypeChunk, commandBuffer, damage);
}
}
entity.setCurrentFallDistance(0.0);
}
}
public boolean isParallel(int archetypeChunkSize, int taskCount) {
return EntityTickingSystem.maybeUseParallel(archetypeChunkSize, taskCount);
}
}
public static class HitAnimation extends DamageEventSystem {
@Nonnull
private static final Query<EntityStore> QUERY = Query.<EntityStore>and(Query.not(DeathComponent.getComponentType()), MovementStatesComponent.getComponentType());
public HitAnimation() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
ModelComponent modelComponent = (ModelComponent)archetypeChunk.getComponent(index, ModelComponent.getComponentType());
Model model = modelComponent != null ? modelComponent.getModel() : null;
MovementStatesComponent movementStatesComponent = (MovementStatesComponent)archetypeChunk.getComponent(index, MovementStatesComponent.getComponentType());
assert movementStatesComponent != null;
MovementStates movementStates = movementStatesComponent.getMovementStates();
if (!(damage.getAmount() <= 0.0F)) {
String[] animationIds = Entity.DefaultAnimations.getHurtAnimationIds(movementStates, damage.getCause());
if (model != null) {
String selectedAnimationId = model.getFirstBoundAnimationId(animationIds);
if (selectedAnimationId != null) {
AnimationUtils.playAnimation(archetypeChunk.getReferenceTo(index), AnimationSlot.Status, selectedAnimationId, true, commandBuffer);
}
}
}
}
}
public static class PlayerDamageFilterSystem extends DamageEventSystem {
@Nonnull
private static final Query<EntityStore> QUERY = Player.getComponentType();
public PlayerDamageFilterSystem() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
World world = ((EntityStore)store.getExternalData()).getWorld();
Player playerComponent = (Player)archetypeChunk.getComponent(index, Player.getComponentType());
assert playerComponent != null;
if (playerComponent.hasSpawnProtection()) {
damage.setCancelled(true);
} else {
if (!world.getWorldConfig().isPvpEnabled()) {
Damage.Source var9 = damage.getSource();
if (var9 instanceof Damage.EntitySource) {
Damage.EntitySource entitySource = (Damage.EntitySource)var9;
Ref<EntityStore> sourceRef = entitySource.getRef();
if (sourceRef.isValid() && commandBuffer.getComponent(sourceRef, Player.getComponentType()) != null) {
damage.setCancelled(true);
return;
}
}
}
}
}
}
public static class TrackLastDamage extends DamageEventSystem {
@Nonnull
private static final Query<EntityStore> QUERY;
public TrackLastDamage() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
TimeResource timeResource = (TimeResource)commandBuffer.getResource(TimeResource.getResourceType());
DamageDataComponent damageDataComponent = (DamageDataComponent)archetypeChunk.getComponent(index, DamageDataComponent.getComponentType());
assert damageDataComponent != null;
damageDataComponent.setLastDamageTime(timeResource.getNow());
}
static {
QUERY = AllLegacyLivingEntityTypesQuery.INSTANCE;
}
}
public static class DamageArmor extends DamageEventSystem {
@Nonnull
private static final Query<EntityStore> QUERY;
public DamageArmor() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
LivingEntity entity = (LivingEntity)EntityUtils.getEntity(index, archetypeChunk);
assert entity != null;
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
DamageCause damageCause = damage.getCause();
if (damageCause.isDurabilityLoss()) {
ItemContainer armor = entity.getInventory().getArmor();
ShortArrayList armorPartIndexes = new ShortArrayList();
armor.forEachWithMeta((slotx, itemStack, _armorPartIndexes) -> {
if (!itemStack.isBroken()) {
_armorPartIndexes.add(slotx);
}
}, armorPartIndexes);
if (!armorPartIndexes.isEmpty()) {
int slot = armorPartIndexes.getShort(RandomExtra.randomRange(armorPartIndexes.size()));
entity.decreaseItemStackDurability(ref, armor.getItemStack((short)slot), -3, slot, commandBuffer);
}
}
}
static {
QUERY = AllLegacyLivingEntityTypesQuery.INSTANCE;
}
}
public static class DamageStamina extends DamageEventSystem implements EntityStatsSystems.StatModifyingSystem {
@Nonnull
private static final Query<EntityStore> QUERY = Query.<EntityStore>and(DamageDataComponent.getComponentType(), EntityStatMap.getComponentType());
public DamageStamina() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage event) {
}
public void handleInternal(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
EntityStatMap entityStatMapComponent = (EntityStatMap)archetypeChunk.getComponent(index, EntityStatMap.getComponentType());
assert entityStatMapComponent != null;
DamageDataComponent damageDataComponent = (DamageDataComponent)archetypeChunk.getComponent(index, DamageDataComponent.getComponentType());
assert damageDataComponent != null;
if (damageDataComponent.getCurrentWielding() != null) {
WieldingInteraction.StaminaCost staminaCost = damageDataComponent.getCurrentWielding().getStaminaCost();
if (staminaCost != null) {
Boolean isBlocked = (Boolean)damage.getMetaStore().getIfPresentMetaObject(Damage.BLOCKED);
if (isBlocked != null && isBlocked) {
float staminaToConsume = staminaCost.computeStaminaAmountToConsume(damage.getInitialAmount(), entityStatMapComponent);
Float multiplier = (Float)damage.getIfPresentMetaObject(Damage.STAMINA_DRAIN_MULTIPLIER);
if (multiplier != null) {
staminaToConsume *= multiplier;
}
entityStatMapComponent.subtractStatValue(DefaultEntityStatTypes.getStamina(), staminaToConsume);
}
}
}
}
}
public static class DamageAttackerTool extends DamageEventSystem {
@Nonnull
private static final Query<EntityStore> QUERY;
public DamageAttackerTool() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
if (damage.getCause().isDurabilityLoss() && damage.getSource() instanceof Damage.EntitySource) {
Ref<EntityStore> attackerRef = ((Damage.EntitySource)damage.getSource()).getRef();
if (attackerRef.isValid()) {
Entity attackerEntity = EntityUtils.getEntity(attackerRef, commandBuffer);
if (attackerEntity instanceof LivingEntity) {
LivingEntity attackerLivingEntity = (LivingEntity)attackerEntity;
Inventory attackerInventory = attackerLivingEntity.getInventory();
byte activeHotbarSlot = attackerInventory.getActiveHotbarSlot();
if (activeHotbarSlot != -1) {
attackerLivingEntity.decreaseItemStackDurability(attackerRef, attackerInventory.getItemInHand(), -1, attackerInventory.getActiveHotbarSlot(), commandBuffer);
}
}
}
}
}
static {
QUERY = AllLegacyLivingEntityTypesQuery.INSTANCE;
}
}
public static class PlayerHitIndicators extends DamageEventSystem {
@Nonnull
private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
@Nonnull
private static final Query<EntityStore> QUERY = PlayerRef.getComponentType();
public PlayerHitIndicators() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
PlayerRef playerRefComponent = (PlayerRef)archetypeChunk.getComponent(index, PlayerRef.getComponentType());
assert playerRefComponent != null;
if (damage.getSource() instanceof Damage.EntitySource) {
Ref<EntityStore> attackerRef = ((Damage.EntitySource)damage.getSource()).getRef();
if (attackerRef.isValid()) {
DamageCause damageCause = damage.getCause();
if (damageCause != null) {
TransformComponent attackerTransform = (TransformComponent)commandBuffer.getComponent(attackerRef, TRANSFORM_COMPONENT_TYPE);
if (attackerTransform != null) {
Vector3d position = attackerTransform.getPosition();
playerRefComponent.getPacketHandler().writeNoCache(new DamageInfo(new com.hypixel.hytale.protocol.Vector3d(position.getX(), position.getY(), position.getZ()), damage.getAmount(), damageCause.toPacket()));
}
}
}
}
}
}
public static class ReticleEvents extends DamageEventSystem {
private static final int EVENT_ON_HIT_TAG_INDEX = AssetRegistry.getOrCreateTagIndex("OnHit");
private static final int EVENT_ON_KILL_TAG_INDEX = AssetRegistry.getOrCreateTagIndex("OnKill");
private static final ReticleEvent ON_HIT;
private static final ReticleEvent ON_KILL;
public ReticleEvents() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return Archetype.<EntityStore>empty();
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
boolean isDead = archetypeChunk.getArchetype().contains(DeathComponent.getComponentType());
if (!(damage.getAmount() <= 0.0F)) {
if (damage.getSource() instanceof Damage.EntitySource) {
Ref<EntityStore> attackerRef = ((Damage.EntitySource)damage.getSource()).getRef();
if (attackerRef.isValid()) {
PlayerRef playerRef = (PlayerRef)commandBuffer.getComponent(attackerRef, PlayerRef.getComponentType());
if (playerRef != null && playerRef.isValid()) {
playerRef.getPacketHandler().writeNoCache(isDead ? ON_KILL : ON_HIT);
}
}
}
}
}
static {
ON_HIT = new ReticleEvent(EVENT_ON_HIT_TAG_INDEX);
ON_KILL = new ReticleEvent(EVENT_ON_KILL_TAG_INDEX);
}
}
public static class EntityUIEvents extends DamageEventSystem {
@Nonnull
private final ComponentType<EntityStore, EntityTrackerSystems.Visible> visibleComponentType = EntityModule.get().getVisibleComponentType();
@Nonnull
private final ComponentType<EntityStore, UIComponentList> uiComponentListComponentType = EntityUIModule.get().getUIComponentListType();
@Nonnull
private final Query<EntityStore> query;
public EntityUIEvents() {
this.query = Query.<EntityStore>and(this.visibleComponentType, this.uiComponentListComponentType);
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return this.query;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
if (!(damage.getAmount() <= 0.0F)) {
if (damage.getSource() instanceof Damage.EntitySource) {
Ref<EntityStore> attackerRef = ((Damage.EntitySource)damage.getSource()).getRef();
if (attackerRef.isValid()) {
PlayerRef playerRef = (PlayerRef)commandBuffer.getComponent(attackerRef, PlayerRef.getComponentType());
if (playerRef != null && playerRef.isValid()) {
EntityTrackerSystems.EntityViewer entityViewer = (EntityTrackerSystems.EntityViewer)commandBuffer.getComponent(attackerRef, EntityTrackerSystems.EntityViewer.getComponentType());
assert entityViewer != null;
Float hitAngleDeg = (Float)damage.getIfPresentMetaObject(Damage.HIT_ANGLE);
queueUpdateFor(archetypeChunk.getReferenceTo(index), damage.getAmount(), hitAngleDeg, entityViewer);
}
}
}
}
}
private static void queueUpdateFor(@Nonnull Ref<EntityStore> ref, float damageAmount, @Nullable Float hitAngleDeg, @Nonnull EntityTrackerSystems.EntityViewer viewer) {
ComponentUpdate update = new ComponentUpdate();
update.type = ComponentUpdateType.CombatText;
CombatTextUpdate combatTextUpdate = new CombatTextUpdate();
combatTextUpdate.hitAngleDeg = hitAngleDeg == null ? 0.0F : hitAngleDeg;
combatTextUpdate.text = Integer.toString((int)Math.floor((double)damageAmount));
update.combatTextUpdate = combatTextUpdate;
viewer.queueUpdate(ref, update);
}
}
@Deprecated
public static class WieldingDamageReduction extends DamageEventSystem {
@Nonnull
private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
@Nonnull
private static final Query<EntityStore> QUERY;
public WieldingDamageReduction() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
DamageDataComponent damageDataComponent = (DamageDataComponent)archetypeChunk.getComponent(index, DamageDataComponent.getComponentType());
assert damageDataComponent != null;
InteractionManager interactionManager = (InteractionManager)archetypeChunk.getComponent(index, InteractionModule.get().getInteractionManagerComponent());
assert interactionManager != null;
WieldingInteraction wielding = damageDataComponent.getCurrentWielding();
if (wielding != null) {
WieldingInteraction.AngledWielding angledWielding = wielding.getAngledWielding();
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
TransformComponent transformComponent = (TransformComponent)archetypeChunk.getComponent(index, TRANSFORM_COMPONENT_TYPE);
assert transformComponent != null;
Vector3d targetPosition = transformComponent.getPosition();
Vector3f targetRotation = transformComponent.getRotation();
Damage.Source var15 = damage.getSource();
if (var15 instanceof Damage.EntitySource) {
Damage.EntitySource source = (Damage.EntitySource)var15;
Ref<EntityStore> attackerRef = source.getRef();
if (attackerRef.isValid()) {
TransformComponent attackerTransformComponent = (TransformComponent)commandBuffer.getComponent(attackerRef, TRANSFORM_COMPONENT_TYPE);
assert attackerTransformComponent != null;
int damageCauseIndex = damage.getDamageCauseIndex();
float wieldingModifier = 1.0F;
float angledWieldingModifier = 1.0F;
String blockedInteractions = null;
Int2FloatMap wieldingDamageModifiers = wielding.getDamageModifiers();
if (!wieldingDamageModifiers.isEmpty()) {
wieldingModifier = wieldingDamageModifiers.getOrDefault(damageCauseIndex, 1.0F);
DamageEffects wieldingBlockedEffects = wielding.getBlockedEffects();
if (wieldingBlockedEffects != null) {
wieldingBlockedEffects.addToDamage(damage);
}
String wieldingBlockedInteractions = wielding.getBlockedInteractions();
if (wieldingBlockedInteractions != null) {
blockedInteractions = wieldingBlockedInteractions;
}
damage.putMetaObject(Damage.BLOCKED, Boolean.TRUE);
}
if (angledWielding != null) {
Int2FloatMap angledWieldingDamageModifiers = angledWielding.getDamageModifiers();
if (angledWieldingDamageModifiers.containsKey(damageCauseIndex)) {
Vector3d attackerPosition = attackerTransformComponent.getPosition();
float angleBetween = TrigMathUtil.atan2(attackerPosition.x - targetPosition.x, attackerPosition.z - targetPosition.z);
angleBetween = MathUtil.wrapAngle(angleBetween + 3.1415927F - targetRotation.getYaw());
if (Math.abs(MathUtil.compareAngle((double)angleBetween, angledWielding.getAngleRad())) < angledWielding.getAngleDistanceRad()) {
angledWieldingModifier = angledWieldingDamageModifiers.getOrDefault(damageCauseIndex, 1.0F);
DamageEffects wieldingBlockedEffects = wielding.getBlockedEffects();
if (wieldingBlockedEffects != null) {
wieldingBlockedEffects.addToDamage(damage);
}
String wieldingBlockedInteractions = wielding.getBlockedInteractions();
if (wieldingBlockedInteractions != null) {
blockedInteractions = wieldingBlockedInteractions;
}
damage.putMetaObject(Damage.BLOCKED, Boolean.TRUE);
}
}
}
damage.setAmount(damage.getAmount() * wieldingModifier * angledWieldingModifier);
if (blockedInteractions != null) {
InteractionContext context = InteractionContext.forInteraction(interactionManager, ref, InteractionType.Wielding, commandBuffer);
DynamicMetaStore<InteractionContext> contextMetaStore = context.getMetaStore();
contextMetaStore.putMetaObject(Interaction.TARGET_ENTITY, attackerRef);
contextMetaStore.putMetaObject(Interaction.DAMAGE, damage);
NetworkId attackerNetworkIdComponent = (NetworkId)commandBuffer.getComponent(attackerRef, NetworkId.getComponentType());
assert attackerNetworkIdComponent != null;
int networkId = attackerNetworkIdComponent.getId();
InteractionChain chain = interactionManager.initChain(InteractionType.Wielding, context, RootInteraction.getRootInteractionOrUnknown(blockedInteractions), networkId, (BlockPosition)null, false);
interactionManager.queueExecuteChain(chain);
}
}
}
}
}
static {
QUERY = Query.<EntityStore>and(AllLegacyLivingEntityTypesQuery.INSTANCE, DamageDataComponent.getComponentType(), InteractionModule.get().getInteractionManagerComponent(), TRANSFORM_COMPONENT_TYPE);
}
}
@Deprecated
public static class WieldingKnockbackReduction extends DamageEventSystem {
@Nonnull
private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
@Nonnull
private static final Query<EntityStore> QUERY;
public WieldingKnockbackReduction() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage event) {
}
public void handleInternal(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
DamageDataComponent damageDataComponent = (DamageDataComponent)archetypeChunk.getComponent(index, DamageDataComponent.getComponentType());
assert damageDataComponent != null;
TransformComponent transformComponent = (TransformComponent)archetypeChunk.getComponent(index, TRANSFORM_COMPONENT_TYPE);
assert transformComponent != null;
WieldingInteraction wielding = damageDataComponent.getCurrentWielding();
if (wielding != null) {
Int2DoubleMap knockbackModifiers = wielding.getKnockbackModifiers();
WieldingInteraction.AngledWielding angledWielding = wielding.getAngledWielding();
KnockbackComponent knockbackComponent = (KnockbackComponent)damage.getIfPresentMetaObject(Damage.KNOCKBACK_COMPONENT);
if (knockbackComponent != null) {
Damage.Source var13 = damage.getSource();
if (var13 instanceof Damage.EntitySource) {
Damage.EntitySource source = (Damage.EntitySource)var13;
Ref<EntityStore> attackerRef = source.getRef();
if (attackerRef.isValid()) {
TransformComponent attackerTransformComponent = (TransformComponent)commandBuffer.getComponent(attackerRef, TRANSFORM_COMPONENT_TYPE);
assert attackerTransformComponent != null;
int damageCauseIndex = damage.getDamageCauseIndex();
double angledWieldingModifier = 1.0;
double wieldingModifier = knockbackModifiers.getOrDefault(damageCauseIndex, 1.0);
if (angledWielding != null) {
Int2DoubleMap angledWieldingKnockbackModifiers = angledWielding.getKnockbackModifiers();
if (angledWieldingKnockbackModifiers.containsKey(damageCauseIndex)) {
Vector3d targetPos = transformComponent.getPosition();
Vector3d attackerPos = attackerTransformComponent.getPosition();
float angleBetween = TrigMathUtil.atan2(attackerPos.x - targetPos.x, attackerPos.z - targetPos.z);
angleBetween = MathUtil.wrapAngle(angleBetween + 3.1415927F - transformComponent.getRotation().getYaw());
if (Math.abs(MathUtil.compareAngle((double)angleBetween, angledWielding.getAngleRad())) < angledWielding.getAngleDistanceRad()) {
angledWieldingModifier = angledWieldingKnockbackModifiers.getOrDefault(damageCauseIndex, 1.0);
}
}
}
knockbackComponent.addModifier(wieldingModifier);
knockbackComponent.addModifier(angledWieldingModifier);
}
}
}
}
}
static {
QUERY = Query.<EntityStore>and(AllLegacyLivingEntityTypesQuery.INSTANCE, DamageDataComponent.getComponentType(), TRANSFORM_COMPONENT_TYPE);
}
}
@Deprecated
public static class ArmorKnockbackReduction extends DamageEventSystem {
@Nonnull
private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
@Nonnull
private static final Query<EntityStore> QUERY;
public ArmorKnockbackReduction() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage event) {
}
public void handleInternal(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
LivingEntity entity = (LivingEntity)EntityUtils.getEntity(index, archetypeChunk);
assert entity != null;
Inventory inventory = entity.getInventory();
if (inventory != null) {
ItemContainer armorContainer = inventory.getArmor();
if (armorContainer != null) {
KnockbackComponent knockbackComponent = (KnockbackComponent)damage.getIfPresentMetaObject(Damage.KNOCKBACK_COMPONENT);
if (knockbackComponent != null) {
float knockbackResistanceModifier = 0.0F;
for(short i = 0; i < armorContainer.getCapacity(); ++i) {
ItemStack itemStack = armorContainer.getItemStack(i);
if (itemStack != null && !itemStack.isEmpty()) {
Item item = itemStack.getItem();
ItemArmor itemArmor = item.getArmor();
if (itemArmor != null) {
Map<DamageCause, Float> knockbackResistances = itemArmor.getKnockbackResistances();
if (knockbackResistances != null) {
DamageCause damageCause = damage.getCause();
knockbackResistanceModifier += (Float)knockbackResistances.get(damageCause);
}
}
}
}
knockbackComponent.addModifier((double)Math.max(1.0F - knockbackResistanceModifier, 0.0F));
}
}
}
}
static {
QUERY = Query.<EntityStore>and(AllLegacyLivingEntityTypesQuery.INSTANCE, DamageDataComponent.getComponentType(), TRANSFORM_COMPONENT_TYPE);
}
}
@Deprecated
public static class ArmorDamageReduction extends DamageEventSystem {
@Nonnull
private static final Query<EntityStore> QUERY;
public ArmorDamageReduction() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
LivingEntity entity = (LivingEntity)EntityUtils.getEntity(index, archetypeChunk);
assert entity != null;
World world = ((EntityStore)commandBuffer.getExternalData()).getWorld();
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
Map<DamageCause, ArmorResistanceModifiers> resistances = getResistanceModifiers(world, entity.getInventory().getArmor(), entity.canApplyItemStackPenalties(ref, commandBuffer), (EffectControllerComponent)archetypeChunk.getComponent(index, EffectControllerComponent.getComponentType()));
if (!damage.getCause().doesBypassResistances() && !resistances.isEmpty()) {
ArmorResistanceModifiers damageModEntry = (ArmorResistanceModifiers)resistances.get(damage.getCause());
if (damageModEntry == null) {
return;
}
float amount = Math.max(0.0F, damage.getAmount() - (float)damageModEntry.flatModifier);
for(amount *= Math.max(0.0F, 1.0F - damageModEntry.multiplierModifier); damageModEntry.inheritedParentId != null; amount *= Math.max(0.0F, 1.0F - damageModEntry.multiplierModifier)) {
damageModEntry = (ArmorResistanceModifiers)resistances.get(damageModEntry.inheritedParentId);
if (damageModEntry == null) {
break;
}
amount = Math.max(0.0F, damage.getAmount() - (float)damageModEntry.flatModifier);
}
damage.setAmount(amount);
}
}
@Nonnull
public static Map<DamageCause, ArmorResistanceModifiers> getResistanceModifiers(@Nonnull World world, @Nonnull ItemContainer inventory, boolean canApplyItemStackPenalties, @Nullable EffectControllerComponent effectControllerComponent) {
Map<DamageCause, ArmorResistanceModifiers> result = new Object2ObjectOpenHashMap<DamageCause, ArmorResistanceModifiers>();
for(short index = 0; index < inventory.getCapacity(); ++index) {
ItemStack itemStack = inventory.getItemStack(index);
if (itemStack != null && !itemStack.isEmpty()) {
Item item = itemStack.getItem();
ItemArmor itemArmor = item.getArmor();
if (itemArmor != null) {
Map<DamageCause, StaticModifier[]> resistances = itemArmor.getDamageResistanceValues();
double flatResistance = itemArmor.getBaseDamageResistance();
if (resistances != null) {
for(Map.Entry<DamageCause, StaticModifier[]> entry : resistances.entrySet()) {
if (entry.getValue() != null) {
calculateResistanceEntryModifications(entry, world, result, canApplyItemStackPenalties, itemStack.isBroken(), flatResistance);
}
}
}
}
}
}
addResistanceModifiersFromEntityEffects(result, effectControllerComponent);
return result;
}
private static void calculateResistanceEntryModifications(@Nonnull Map.Entry<DamageCause, StaticModifier[]> entry, @Nonnull World world, @Nonnull Map<DamageCause, ArmorResistanceModifiers> result, boolean canApplyItemStackPenalties, boolean itemStackIsBroken, double flatResistance) {
ArmorResistanceModifiers mods = (ArmorResistanceModifiers)result.computeIfAbsent((DamageCause)entry.getKey(), (key) -> new ArmorResistanceModifiers());
StaticModifier[] valueArray = (StaticModifier[])entry.getValue();
for(int x = 0; x < valueArray.length; ++x) {
StaticModifier entryValue = valueArray[x];
if (entryValue.getCalculationType() == StaticModifier.CalculationType.ADDITIVE) {
mods.flatModifier = (int)((float)mods.flatModifier + entryValue.getAmount());
} else {
mods.multiplierModifier += entryValue.getAmount();
}
}
mods.flatModifier = (int)((double)mods.flatModifier + flatResistance);
DamageCause damageCause = (DamageCause)entry.getKey();
if (damageCause != null && damageCause.getInherits() != null) {
mods.inheritedParentId = (DamageCause)DamageCause.getAssetMap().getAsset(damageCause.getInherits());
}
if (canApplyItemStackPenalties && itemStackIsBroken) {
BrokenPenalties brokenPenalties = world.getGameplayConfig().getItemDurabilityConfig().getBrokenPenalties();
double penalty = brokenPenalties.getWeapon(0.0);
mods.flatModifier = (int)((double)mods.flatModifier * (1.0 - penalty));
mods.multiplierModifier = (float)((double)mods.multiplierModifier * (1.0 - penalty));
}
}
private static void addResistanceModifiersFromEntityEffects(Map<DamageCause, ArmorResistanceModifiers> resistanceModifiers, EffectControllerComponent effectControllerComponent) {
if (effectControllerComponent != null) {
IntIterator var2 = effectControllerComponent.getActiveEffects().keySet().iterator();
while(var2.hasNext()) {
int entityEffectIndex = (Integer)var2.next();
EntityEffect entityEffectData = (EntityEffect)EntityEffect.getAssetMap().getAsset(entityEffectIndex);
if (entityEffectData != null) {
Map<DamageCause, StaticModifier[]> damageResistanceValues = entityEffectData.getDamageResistanceValues();
if (damageResistanceValues != null && !damageResistanceValues.isEmpty()) {
for(Map.Entry<DamageCause, StaticModifier[]> entry : damageResistanceValues.entrySet()) {
ArmorResistanceModifiers modifier = (ArmorResistanceModifiers)resistanceModifiers.computeIfAbsent((DamageCause)entry.getKey(), (damageCause) -> new ArmorResistanceModifiers());
for(StaticModifier staticModifier : (StaticModifier[])entry.getValue()) {
if (staticModifier.getCalculationType() == StaticModifier.CalculationType.ADDITIVE) {
modifier.flatModifier = (int)((float)modifier.flatModifier + staticModifier.getAmount());
} else if (staticModifier.getCalculationType() == StaticModifier.CalculationType.MULTIPLICATIVE) {
modifier.multiplierModifier += staticModifier.getAmount();
}
}
}
}
}
}
}
}
static {
QUERY = AllLegacyLivingEntityTypesQuery.INSTANCE;
}
public static class ArmorResistanceModifiers {
public int flatModifier;
public float multiplierModifier;
@Nullable
public DamageCause inheritedParentId;
public ArmorResistanceModifiers() {
}
}
}
@Deprecated
public static class HackKnockbackValues extends EntityTickingSystem<EntityStore> {
public static float PLAYER_KNOCKBACK_SCALE = 25.0F;
private static final Query<EntityStore> QUERY;
public HackKnockbackValues() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getFilterDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return QUERY;
}
public void tick(float dt, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
KnockbackComponent knockbackComponent = (KnockbackComponent)archetypeChunk.getComponent(index, KnockbackComponent.getComponentType());
assert knockbackComponent != null;
if (knockbackComponent.getVelocityConfig() == null || SplitVelocity.SHOULD_MODIFY_VELOCITY) {
Vector3d vector = knockbackComponent.getVelocity();
vector.x *= (double)PLAYER_KNOCKBACK_SCALE;
vector.z *= (double)PLAYER_KNOCKBACK_SCALE;
knockbackComponent.setVelocity(vector);
}
}
public boolean isParallel(int archetypeChunkSize, int taskCount) {
return EntityTickingSystem.maybeUseParallel(archetypeChunkSize, taskCount);
}
static {
QUERY = Query.<EntityStore>and(AllLegacyLivingEntityTypesQuery.INSTANCE, KnockbackComponent.getComponentType());
}
}
}