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

package com.hypixel.hytale.server.npc.corecomponents.world;

import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.random.RandomExtra;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.npc.sensorinfo.InfoProvider;
import com.hypixel.hytale.server.npc.role.Role;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.hypixel.hytale.server.npc.corecomponents.builders.BuilderActionBase;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.corecomponents.world.builders.BuilderActionTriggerSpawners;
import javax.annotation.Nullable;
import com.hypixel.hytale.component.Ref;
import java.util.List;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.spawning.spawnmarkers.SpawnMarkerEntity;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.npc.corecomponents.ActionBase;

public class ActionTriggerSpawners extends ActionBase
{
    protected static final ComponentType<EntityStore, SpawnMarkerEntity> SPAWN_MARKER_ENTITY_COMPONENT_TYPE;
    protected static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE;
    protected final String spawner;
    protected final double range;
    protected final double rangeSquared;
    protected final int count;
    @Nullable
    protected final List<Ref<EntityStore>> triggerList;
    protected Ref<EntityStore> parentRef;
    
    public ActionTriggerSpawners(@Nonnull final BuilderActionTriggerSpawners builder, @Nonnull final BuilderSupport support) {
        super(builder);
        this.spawner = builder.getSpawner(support);
        this.range = builder.getRange(support);
        this.rangeSquared = this.range * this.range;
        this.count = builder.getCount(support);
        this.triggerList = ((this.count > 0) ? new ObjectArrayList<Ref<EntityStore>>(this.count) : null);
    }
    
    @Override
    public void registerWithSupport(@Nonnull final Role role) {
        role.getPositionCache().requireSpawnMarkerDistance(this.range);
    }
    
    @Override
    public boolean execute(@Nonnull final Ref<EntityStore> ref, @Nonnull final Role role, final InfoProvider sensorInfo, final double dt, @Nonnull final Store<EntityStore> store) {
        super.execute(ref, role, sensorInfo, dt, store);
        this.parentRef = ref;
        final List<Ref<EntityStore>> spawners = role.getPositionCache().getSpawnMarkerList();
        if (this.count <= 0) {
            for (int i = 0; i < spawners.size(); ++i) {
                final Ref<EntityStore> spawnMarkerRef = this.filterMarker(spawners.get(i), store);
                if (spawnMarkerRef != null) {
                    final SpawnMarkerEntity spawnMarkerEntityComponent = store.getComponent(spawnMarkerRef, ActionTriggerSpawners.SPAWN_MARKER_ENTITY_COMPONENT_TYPE);
                    assert spawnMarkerEntityComponent != null;
                    spawnMarkerEntityComponent.trigger(spawnMarkerRef, store);
                }
            }
            return true;
        }
        RandomExtra.reservoirSample(spawners, (reference, _this, _store) -> _this.filterMarker(reference, _store), this.count, this.triggerList, this, store);
        for (int i = 0; i < this.triggerList.size(); ++i) {
            final Ref<EntityStore> spawnMarkerRef = this.triggerList.get(i);
            final SpawnMarkerEntity spawnMarkerEntityComponent = store.getComponent(spawnMarkerRef, ActionTriggerSpawners.SPAWN_MARKER_ENTITY_COMPONENT_TYPE);
            assert spawnMarkerEntityComponent != null;
            spawnMarkerEntityComponent.trigger(spawnMarkerRef, store);
        }
        this.triggerList.clear();
        return true;
    }
    
    @Nullable
    protected Ref<EntityStore> filterMarker(@Nonnull final Ref<EntityStore> targetRef, @Nonnull final Store<EntityStore> store) {
        if (!targetRef.isValid()) {
            return null;
        }
        final TransformComponent parentTransformComponent = store.getComponent(this.parentRef, ActionTriggerSpawners.TRANSFORM_COMPONENT_TYPE);
        assert parentTransformComponent != null;
        final Vector3d parentPosition = parentTransformComponent.getPosition();
        final TransformComponent targetTransformComponent = store.getComponent(targetRef, ActionTriggerSpawners.TRANSFORM_COMPONENT_TYPE);
        assert targetTransformComponent != null;
        final Vector3d targetPosition = targetTransformComponent.getPosition();
        final SpawnMarkerEntity targetMarkerEntityComponent = store.getComponent(targetRef, ActionTriggerSpawners.SPAWN_MARKER_ENTITY_COMPONENT_TYPE);
        return (targetMarkerEntityComponent != null && targetMarkerEntityComponent.isManualTrigger() && parentPosition.distanceSquaredTo(targetPosition) <= this.rangeSquared && (this.spawner == null || this.spawner.equals(targetMarkerEntityComponent.getSpawnMarkerId()))) ? targetRef : null;
    }
    
    static {
        SPAWN_MARKER_ENTITY_COMPONENT_TYPE = SpawnMarkerEntity.getComponentType();
        TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
    }
}
