// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.builtin.deployables.system;

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.modules.entitystats.EntityStatMap;
import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.builtin.deployables.component.DeployableOwnerComponent;
import com.hypixel.hytale.builtin.deployables.config.DeployableConfig;
import javax.annotation.Nonnull;
import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.builtin.deployables.component.DeployableComponent;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
import it.unimi.dsi.fastutil.objects.ObjectList;
import com.hypixel.hytale.protocol.Direction;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.universe.world.ParticleUtil;
import java.util.List;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.component.spatial.SpatialResource;
import com.hypixel.hytale.protocol.Vector3f;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelParticle;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;

public class DeployablesSystem
{
    private static void spawnParticleEffect(final Ref<EntityStore> sourceRef, final CommandBuffer<EntityStore> commandBuffer, final Vector3d position, final ModelParticle particle) {
        final Vector3f particlePositionOffset = particle.getPositionOffset();
        final Direction particleRotationOffset = particle.getRotationOffset();
        final 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(particlePositionOffset.x, particlePositionOffset.y, particlePositionOffset.z);
        }
        if (particleRotationOffset != null) {
            particleRotation = new Vector3f(particleRotationOffset.yaw, particleRotationOffset.pitch, particleRotationOffset.roll);
        }
        final SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = commandBuffer.getResource(EntityModule.get().getPlayerSpatialResourceType());
        final 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>
    {
        @Override
        public Query<EntityStore> getQuery() {
            return (Query<EntityStore>)Query.and(DeployableComponent.getComponentType());
        }
        
        @Override
        public void tick(final float dt, final int index, final ArchetypeChunk<EntityStore> archetypeChunk, final Store<EntityStore> store, final CommandBuffer<EntityStore> commandBuffer) {
            final DeployableComponent comp = archetypeChunk.getComponent(index, DeployableComponent.getComponentType());
            comp.tick(dt, index, archetypeChunk, store, commandBuffer);
        }
    }
    
    public static class DeployableRegisterer extends RefSystem<EntityStore>
    {
        private static void deregisterOwner(@Nonnull final Ref<EntityStore> ref, @Nonnull final DeployableComponent deployableComponent, @Nonnull final DeployableConfig deployableConfig) {
            final Ref<EntityStore> ownerRef = deployableComponent.getOwner();
            if (ownerRef != null && ownerRef.isValid()) {
                final DeployableOwnerComponent deployableOwnerComponent = ownerRef.getStore().getComponent(ownerRef, DeployableOwnerComponent.getComponentType());
                deployableOwnerComponent.deRegisterDeployable(deployableConfig.getId(), ref);
            }
        }
        
        @Override
        public Query<EntityStore> getQuery() {
            return (Query<EntityStore>)Query.and(DeployableComponent.getComponentType());
        }
        
        @Override
        public void onEntityAdded(@Nonnull final Ref<EntityStore> ref, @Nonnull final AddReason reason, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final DeployableComponent deployableComponent = store.getComponent(ref, DeployableComponent.getComponentType());
            final DeployableConfig deployableConfig = deployableComponent.getConfig();
            final Vector3d position = store.getComponent(ref, TransformComponent.getComponentType()).getPosition();
            final Ref<EntityStore> ownerRef = deployableComponent.getOwner();
            final int soundIndex = deployableConfig.getDeploySoundEventIndex();
            SoundUtil.playSoundEvent3d(null, soundIndex, position, commandBuffer);
            final ModelParticle[] particles = deployableConfig.getSpawnParticles();
            if (particles != null) {
                for (final ModelParticle particle : particles) {
                    DeployablesSystem.spawnParticleEffect(ref, commandBuffer, position, particle);
                }
            }
            if (!ownerRef.isValid()) {
                return;
            }
            final DeployableOwnerComponent deployableOwnerComponent = ownerRef.getStore().getComponent(ownerRef, DeployableOwnerComponent.getComponentType());
            assert deployableOwnerComponent != null;
            deployableOwnerComponent.registerDeployable(ownerRef, deployableComponent, deployableConfig.getId(), ref, store);
        }
        
        @Override
        public void onEntityRemove(@Nonnull final Ref<EntityStore> ref, @Nonnull final RemoveReason reason, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final DeployableComponent deployableComponent = store.getComponent(ref, DeployableComponent.getComponentType());
            final DeployableConfig deployableConfig = deployableComponent.getConfig();
            final Vector3d position = store.getComponent(ref, TransformComponent.getComponentType()).getPosition();
            final int despawnSoundIndex = deployableConfig.getDespawnSoundEventIndex();
            final int dieSoundIndex = deployableConfig.getDieSoundEventIndex();
            if (dieSoundIndex != 0) {
                final EntityStatMap statMap = store.getComponent(ref, EntityStatMap.getComponentType());
                if (statMap != null) {
                    final EntityStatValue healthStat = statMap.get(DefaultEntityStatTypes.getHealth());
                    final int removeSound = (healthStat != null && healthStat.get() <= 0.0f) ? dieSoundIndex : despawnSoundIndex;
                    SoundUtil.playSoundEvent3d(null, removeSound, position, commandBuffer);
                }
            }
            else {
                SoundUtil.playSoundEvent3d(null, despawnSoundIndex, position, commandBuffer);
            }
            final ModelParticle[] particles = deployableConfig.getDespawnParticles();
            if (particles != null) {
                for (final ModelParticle particle : particles) {
                    DeployablesSystem.spawnParticleEffect(ref, commandBuffer, position, particle);
                }
            }
            deregisterOwner(ref, deployableComponent, deployableConfig);
        }
    }
    
    public static class DeployableOwnerTicker extends EntityTickingSystem<EntityStore>
    {
        @Override
        public Query<EntityStore> getQuery() {
            return (Query<EntityStore>)Query.and(DeployableOwnerComponent.getComponentType());
        }
        
        @Override
        public void tick(final float dt, final int index, final ArchetypeChunk<EntityStore> archetypeChunk, final Store<EntityStore> store, final CommandBuffer<EntityStore> commandBuffer) {
            final DeployableOwnerComponent deployableOwnerComponent = archetypeChunk.getComponent(index, DeployableOwnerComponent.getComponentType());
            deployableOwnerComponent.tick(commandBuffer);
        }
    }
}
