package com.hypixel.hytale.server.core.modules.entity;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.DisableProcessingAssert;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.HolderSystem;
import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.math.shape.Box;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.core.asset.type.projectile.config.Projectile;
import com.hypixel.hytale.server.core.entity.entities.ProjectileComponent;
import com.hypixel.hytale.server.core.modules.entity.component.BoundingBox;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
import com.hypixel.hytale.server.core.modules.physics.component.Velocity;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.util.logging.Level;
import javax.annotation.Nonnull;
public class LegacyProjectileSystems {
@Nonnull
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
public LegacyProjectileSystems() {
}
public static class OnAddRefSystem extends RefSystem<EntityStore> {
@Nonnull
private static final ComponentType<EntityStore, ProjectileComponent> PROJECTILE_COMPONENT_TYPE = ProjectileComponent.getComponentType();
public OnAddRefSystem() {
}
public Query<EntityStore> getQuery() {
return PROJECTILE_COMPONENT_TYPE;
}
public void onEntityAdded(@Nonnull Ref<EntityStore> ref, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
ProjectileComponent projectileComponent = (ProjectileComponent)commandBuffer.getComponent(ref, PROJECTILE_COMPONENT_TYPE);
assert projectileComponent != null;
if (projectileComponent.getProjectile() == null) {
LegacyProjectileSystems.LOGGER.at(Level.WARNING).log("Removing projectile entity %s as it failed to initialize correctly!", ref);
commandBuffer.removeEntity(ref, RemoveReason.REMOVE);
}
}
public void onEntityRemove(@Nonnull Ref<EntityStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
}
}
public static class OnAddHolderSystem extends HolderSystem<EntityStore> {
@Nonnull
private static final ComponentType<EntityStore, ProjectileComponent> PROJECTILE_COMPONENT_TYPE = ProjectileComponent.getComponentType();
public OnAddHolderSystem() {
}
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
if (!holder.getArchetype().contains(NetworkId.getComponentType())) {
holder.addComponent(NetworkId.getComponentType(), new NetworkId(((EntityStore)store.getExternalData()).takeNextNetworkId()));
}
ProjectileComponent projectileComponent = (ProjectileComponent)holder.getComponent(PROJECTILE_COMPONENT_TYPE);
assert projectileComponent != null;
projectileComponent.initialize();
ModelAsset modelAsset = (ModelAsset)ModelAsset.getAssetMap().getAsset(projectileComponent.getAppearance());
BoundingBox boundingBox;
if (modelAsset != null) {
Model model = Model.createUnitScaleModel(modelAsset);
holder.putComponent(ModelComponent.getComponentType(), new ModelComponent(model));
holder.putComponent(PersistentModel.getComponentType(), new PersistentModel(model.toReference()));
boundingBox = new BoundingBox(model.getBoundingBox());
} else {
Projectile projectileAsset = projectileComponent.getProjectile();
if (projectileAsset != null) {
boundingBox = new BoundingBox(Box.horizontallyCentered(projectileAsset.getRadius(), projectileAsset.getHeight(), projectileAsset.getRadius()));
} else {
boundingBox = new BoundingBox(Box.horizontallyCentered(0.25, 0.25, 0.25));
}
}
holder.putComponent(BoundingBox.getComponentType(), boundingBox);
projectileComponent.initializePhysics(boundingBox);
}
public void onEntityRemoved(@Nonnull Holder<EntityStore> holder, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store) {
}
public Query<EntityStore> getQuery() {
return PROJECTILE_COMPONENT_TYPE;
}
}
public static class TickingSystem extends EntityTickingSystem<EntityStore> implements DisableProcessingAssert {
@Nonnull
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
@Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull
private final ComponentType<EntityStore, Velocity> velocityComponentType;
@Nonnull
private final ComponentType<EntityStore, BoundingBox> boundingBoxComponentType;
@Nonnull
private final ComponentType<EntityStore, ProjectileComponent> projectileComponentType;
@Nonnull
private final Archetype<EntityStore> archetype;
public TickingSystem(@Nonnull ComponentType<EntityStore, ProjectileComponent> projectileComponentType, @Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType, @Nonnull ComponentType<EntityStore, Velocity> velocityComponentType, @Nonnull ComponentType<EntityStore, BoundingBox> boundingBoxComponentType) {
this.projectileComponentType = projectileComponentType;
this.velocityComponentType = velocityComponentType;
this.boundingBoxComponentType = boundingBoxComponentType;
this.transformComponentType = transformComponentType;
this.archetype = Archetype.of(projectileComponentType, transformComponentType, velocityComponentType, boundingBoxComponentType);
}
public Query<EntityStore> getQuery() {
return this.archetype;
}
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, this.transformComponentType);
assert transformComponent != null;
ProjectileComponent projectileComponent = (ProjectileComponent)archetypeChunk.getComponent(index, this.projectileComponentType);
assert projectileComponent != null;
Velocity velocityComponent = (Velocity)archetypeChunk.getComponent(index, this.velocityComponentType);
assert velocityComponent != null;
BoundingBox boundingBox = (BoundingBox)archetypeChunk.getComponent(index, this.boundingBoxComponentType);
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
try {
if (projectileComponent.consumeDeadTimer(dt)) {
projectileComponent.onProjectileDeath(ref, transformComponent.getPosition(), commandBuffer);
commandBuffer.removeEntity(ref, RemoveReason.REMOVE);
return;
}
World world = ((EntityStore)commandBuffer.getExternalData()).getWorld();
projectileComponent.getSimplePhysicsProvider().tick((double)dt, velocityComponent, world, transformComponent, ref, commandBuffer);
} catch (Throwable throwable) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(throwable)).log("Exception while ticking entity! Removing!! %s", projectileComponent);
commandBuffer.removeEntity(ref, RemoveReason.REMOVE);
}
}
}
}