package com.hypixel.hytale.builtin.deployables.config;
import com.hypixel.hytale.builtin.deployables.DeployablesUtils;
import com.hypixel.hytale.builtin.deployables.component.DeployableComponent;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import com.hypixel.hytale.codec.validation.Validators;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageCause;
import com.hypixel.hytale.server.core.modules.time.TimeResource;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import javax.annotation.Nonnull;
public class DeployableTrapSpawnerConfig extends DeployableTrapConfig {
public static final BuilderCodec<DeployableTrapSpawnerConfig> CODEC;
private String[] deployableSpawnerIds;
private DeployableSpawner[] deployableSpawners;
public DeployableTrapSpawnerConfig() {
}
public void tick(@Nonnull DeployableComponent deployableComponent, float dt, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
Ref<EntityStore> entityRef = archetypeChunk.getReferenceTo(index);
switch (deployableComponent.getFlag(DeployableComponent.DeployableFlag.STATE)) {
case 0 -> this.tickDeploymentState(store, deployableComponent, entityRef);
case 1 -> this.tickDeployAnimationState(store, deployableComponent, entityRef);
case 2 -> this.tickFuzeState(store, deployableComponent);
case 3 -> this.tickLiveState(store, deployableComponent, entityRef, commandBuffer, dt);
case 4 -> this.tickTriggeredState(commandBuffer, store, deployableComponent, entityRef);
case 5 -> this.tickDespawnState(deployableComponent, entityRef, store);
}
}
private void tickDeploymentState(@Nonnull Store<EntityStore> store, @Nonnull DeployableComponent component, @Nonnull Ref<EntityStore> entityRef) {
component.setFlag(DeployableComponent.DeployableFlag.STATE, 1);
playAnimation(store, entityRef, this, "Deploy");
}
private void tickDeployAnimationState(Store<EntityStore> store, DeployableComponent component, Ref<EntityStore> entityRef) {
component.setFlag(DeployableComponent.DeployableFlag.STATE, 2);
playAnimation(store, entityRef, this, "Deploy");
}
private void tickFuzeState(@Nonnull Store<EntityStore> store, @Nonnull DeployableComponent component) {
Instant now = ((TimeResource)store.getResource(TimeResource.getResourceType())).getNow();
Instant readyTime = component.getSpawnInstant().plus((long)this.fuzeDuration, ChronoUnit.SECONDS);
if (now.isAfter(readyTime)) {
component.setFlag(DeployableComponent.DeployableFlag.STATE, 3);
}
}
private void tickLiveState(@Nonnull Store<EntityStore> store, @Nonnull DeployableComponent component, @Nonnull Ref<EntityStore> entityRef, CommandBuffer<EntityStore> commandBuffer, float dt) {
Vector3d position = ((TransformComponent)store.getComponent(entityRef, TransformComponent.getComponentType())).getPosition();
float radius = this.getRadius(store, component.getSpawnInstant());
component.setTimeSinceLastAttack(component.getTimeSinceLastAttack() + dt);
if (component.getTimeSinceLastAttack() > this.damageInterval && this.isLive(store, component)) {
component.setTimeSinceLastAttack(0.0F);
this.handleDetection(store, commandBuffer, entityRef, component, position, radius, DamageCause.PHYSICAL);
}
}
private void tickTriggeredState(CommandBuffer<EntityStore> commandBuffer, @Nonnull Store<EntityStore> store, @Nonnull DeployableComponent component, @Nonnull Ref<EntityStore> entityRef) {
component.setFlag(DeployableComponent.DeployableFlag.STATE, 5);
Vector3d parentPosition = ((TransformComponent)store.getComponent(entityRef, TransformComponent.getComponentType())).getPosition();
Ref<EntityStore> parentOwner = ((DeployableComponent)store.getComponent(entityRef, DeployableComponent.getComponentType())).getOwner();
World world = ((EntityStore)store.getExternalData()).getWorld();
if (this.deployableSpawners != null) {
for(DeployableSpawner spawner : this.deployableSpawners) {
if (spawner != null) {
DeployableConfig config = spawner.getConfig();
Vector3d[] positionOffsets = spawner.getPositionOffsets();
for(Vector3d offset : positionOffsets) {
Vector3f childPosition = Vector3d.add(parentPosition, offset).toVector3f();
world.execute(() -> DeployablesUtils.spawnDeployable(commandBuffer, store, config, parentOwner, childPosition, new Vector3f(), "UP"));
}
}
}
}
}
private void tickDespawnState(@Nonnull DeployableComponent component, @Nonnull Ref<EntityStore> entityRef, @Nonnull Store<EntityStore> store) {
component.setFlag(DeployableComponent.DeployableFlag.STATE, 6);
super.onTriggered(store, entityRef);
}
protected void onTriggered(@Nonnull Store<EntityStore> store, @Nonnull Ref<EntityStore> ref) {
((DeployableComponent)store.getComponent(ref, DeployableComponent.getComponentType())).setFlag(DeployableComponent.DeployableFlag.STATE, 4);
}
static {
CODEC = ((BuilderCodec.Builder)((BuilderCodec.Builder)BuilderCodec.builder(DeployableTrapSpawnerConfig.class, DeployableTrapSpawnerConfig::new, DeployableTrapConfig.CODEC).appendInherited(new KeyedCodec("DeployableConfig", new ArrayCodec(Codec.STRING, (x$0) -> new String[x$0])), (o, i) -> o.deployableSpawnerIds = i, (o) -> o.deployableSpawnerIds, (o, p) -> o.deployableSpawnerIds = p.deployableSpawnerIds).addValidator(Validators.nonNull()).add()).afterDecode((config) -> {
if (config.deployableSpawnerIds != null) {
int length = config.deployableSpawnerIds.length;
config.deployableSpawners = new DeployableSpawner[length];
for(int i = 0; i < length; ++i) {
String key = config.deployableSpawnerIds[i];
config.deployableSpawners[i] = (DeployableSpawner)DeployableSpawner.getAssetMap().getAsset(key);
}
}
})).build();
}
}