package com.hypixel.hytale.builtin.deployables.system;
import com.hypixel.hytale.builtin.deployables.component.DeployableComponent;
import com.hypixel.hytale.builtin.deployables.component.DeployableOwnerComponent;
import com.hypixel.hytale.builtin.deployables.config.DeployableConfig;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer;
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.spatial.SpatialResource;
import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.protocol.Direction;
import com.hypixel.hytale.protocol.Vector3f;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelParticle;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
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.asset.DefaultEntityStatTypes;
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.storage.EntityStore;
import it.unimi.dsi.fastutil.objects.ObjectList;
import javax.annotation.Nonnull;
public class DeployablesSystem {
public DeployablesSystem() {
}
private static void spawnParticleEffect(Ref<EntityStore> sourceRef, CommandBuffer<EntityStore> commandBuffer, Vector3d position, ModelParticle particle) {
Vector3f particlePositionOffset = particle.getPositionOffset();
Direction particleRotationOffset = particle.getRotationOffset();
Vector3d particlePosition = new Vector3d(position.x, position.y, position.z);
Vector3f particleRotation = new Vector3f(0.0F, 0.0F, 0.0F);
if (particlePositionOffset != null) {
particlePosition.add((double)particlePositionOffset.x, (double)particlePositionOffset.y, (double)particlePositionOffset.z);
}
if (particleRotationOffset != null) {
particleRotation = new Vector3f(particleRotationOffset.yaw, particleRotationOffset.pitch, particleRotationOffset.roll);
}
SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = (SpatialResource)commandBuffer.getResource(EntityModule.get().getPlayerSpatialResourceType());
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
playerSpatialResource.getSpatialStructure().collect(particlePosition, 75.0, results);
ParticleUtil.spawnParticleEffect(particle.getSystemId(), particlePosition.x, particlePosition.y, particlePosition.z, particleRotation.x, particleRotation.y, particleRotation.z, sourceRef, results, commandBuffer);
}
public static class DeployableTicker extends EntityTickingSystem<EntityStore> {
public DeployableTicker() {
}
public Query<EntityStore> getQuery() {
return Query.<EntityStore>and(DeployableComponent.getComponentType());
}
public void tick(float dt, int index, ArchetypeChunk<EntityStore> archetypeChunk, Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer) {
DeployableComponent comp = (DeployableComponent)archetypeChunk.getComponent(index, DeployableComponent.getComponentType());
comp.tick(dt, index, archetypeChunk, store, commandBuffer);
}
}
public static class DeployableRegisterer extends RefSystem<EntityStore> {
public DeployableRegisterer() {
}
private static void deregisterOwner(@Nonnull Ref<EntityStore> ref, @Nonnull DeployableComponent deployableComponent, @Nonnull DeployableConfig deployableConfig) {
Ref<EntityStore> ownerRef = deployableComponent.getOwner();
if (ownerRef != null && ownerRef.isValid()) {
DeployableOwnerComponent deployableOwnerComponent = (DeployableOwnerComponent)ownerRef.getStore().getComponent(ownerRef, DeployableOwnerComponent.getComponentType());
deployableOwnerComponent.deRegisterDeployable(deployableConfig.getId(), ref);
}
}
public Query<EntityStore> getQuery() {
return Query.<EntityStore>and(DeployableComponent.getComponentType());
}
public void onEntityAdded(@Nonnull Ref<EntityStore> ref, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
DeployableComponent deployableComponent = (DeployableComponent)store.getComponent(ref, DeployableComponent.getComponentType());
DeployableConfig deployableConfig = deployableComponent.getConfig();
Vector3d position = ((TransformComponent)store.getComponent(ref, TransformComponent.getComponentType())).getPosition();
Ref<EntityStore> ownerRef = deployableComponent.getOwner();
int soundIndex = deployableConfig.getDeploySoundEventIndex();
SoundUtil.playSoundEvent3d((Ref)null, soundIndex, position, commandBuffer);
ModelParticle[] particles = deployableConfig.getSpawnParticles();
if (particles != null) {
for(ModelParticle particle : particles) {
DeployablesSystem.spawnParticleEffect(ref, commandBuffer, position, particle);
}
}
if (ownerRef.isValid()) {
DeployableOwnerComponent deployableOwnerComponent = (DeployableOwnerComponent)ownerRef.getStore().getComponent(ownerRef, DeployableOwnerComponent.getComponentType());
assert deployableOwnerComponent != null;
deployableOwnerComponent.registerDeployable(ownerRef, deployableComponent, deployableConfig.getId(), ref, store);
}
}
public void onEntityRemove(@Nonnull Ref<EntityStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
DeployableComponent deployableComponent = (DeployableComponent)store.getComponent(ref, DeployableComponent.getComponentType());
DeployableConfig deployableConfig = deployableComponent.getConfig();
Vector3d position = ((TransformComponent)store.getComponent(ref, TransformComponent.getComponentType())).getPosition();
int despawnSoundIndex = deployableConfig.getDespawnSoundEventIndex();
int dieSoundIndex = deployableConfig.getDieSoundEventIndex();
if (dieSoundIndex != 0) {
EntityStatMap statMap = (EntityStatMap)store.getComponent(ref, EntityStatMap.getComponentType());
if (statMap != null) {
EntityStatValue healthStat = statMap.get(DefaultEntityStatTypes.getHealth());
int removeSound = healthStat != null && healthStat.get() <= 0.0F ? dieSoundIndex : despawnSoundIndex;
SoundUtil.playSoundEvent3d((Ref)null, removeSound, position, commandBuffer);
}
} else {
SoundUtil.playSoundEvent3d((Ref)null, despawnSoundIndex, position, commandBuffer);
}
ModelParticle[] particles = deployableConfig.getDespawnParticles();
if (particles != null) {
for(ModelParticle particle : particles) {
DeployablesSystem.spawnParticleEffect(ref, commandBuffer, position, particle);
}
}
deregisterOwner(ref, deployableComponent, deployableConfig);
}
}
public static class DeployableOwnerTicker extends EntityTickingSystem<EntityStore> {
public DeployableOwnerTicker() {
}
public Query<EntityStore> getQuery() {
return Query.<EntityStore>and(DeployableOwnerComponent.getComponentType());
}
public void tick(float dt, int index, ArchetypeChunk<EntityStore> archetypeChunk, Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer) {
DeployableOwnerComponent deployableOwnerComponent = (DeployableOwnerComponent)archetypeChunk.getComponent(index, DeployableOwnerComponent.getComponentType());
deployableOwnerComponent.tick(commandBuffer);
}
}
}