package com.hypixel.hytale.builtin.beds.sleep.systems.world;
import com.hypixel.hytale.builtin.beds.sleep.components.PlayerSleep;
import com.hypixel.hytale.builtin.beds.sleep.components.PlayerSomnolence;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSleep;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSlumber;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.system.tick.TickingSystem;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.Iterator;
import javax.annotation.Nonnull;
public class UpdateWorldSlumberSystem extends TickingSystem<EntityStore> {
public UpdateWorldSlumberSystem() {
}
public void tick(float dt, int systemIndex, @Nonnull Store<EntityStore> store) {
World world = ((EntityStore)store.getExternalData()).getWorld();
WorldSomnolence worldSomnolence = (WorldSomnolence)store.getResource(WorldSomnolence.getResourceType());
WorldSleep worldSleep = worldSomnolence.getState();
if (worldSleep instanceof WorldSlumber slumber) {
slumber.incProgressSeconds(dt);
boolean sleepingIsOver = slumber.getProgressSeconds() >= slumber.getIrlDurationSeconds() || isSomeoneAwake(store);
if (sleepingIsOver) {
worldSomnolence.setState(WorldSleep.Awake.INSTANCE);
WorldTimeResource timeResource = (WorldTimeResource)store.getResource(WorldTimeResource.getResourceType());
Instant wakeUpTime = computeWakeupTime(slumber);
timeResource.setGameTime(wakeUpTime, world, store);
store.forEachEntityParallel(PlayerSomnolence.getComponentType(), (index, archetypeChunk, commandBuffer) -> {
PlayerSomnolence somnolenceComponent = (PlayerSomnolence)archetypeChunk.getComponent(index, PlayerSomnolence.getComponentType());
assert somnolenceComponent != null;
if (somnolenceComponent.getSleepState() instanceof PlayerSleep.Slumber) {
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
commandBuffer.putComponent(ref, PlayerSomnolence.getComponentType(), PlayerSleep.MorningWakeUp.createComponent(timeResource));
}
});
}
}
}
private static Instant computeWakeupTime(@Nonnull WorldSlumber slumber) {
float progress = slumber.getProgressSeconds() / slumber.getIrlDurationSeconds();
long totalNanos = Duration.between(slumber.getStartInstant(), slumber.getTargetInstant()).toNanos();
long progressNanos = (long)((float)totalNanos * progress);
return slumber.getStartInstant().plusNanos(progressNanos);
}
private static boolean isSomeoneAwake(@Nonnull ComponentAccessor<EntityStore> store) {
World world = ((EntityStore)store.getExternalData()).getWorld();
Collection<PlayerRef> playerRefs = world.getPlayerRefs();
if (playerRefs.isEmpty()) {
return false;
} else {
Iterator var3 = playerRefs.iterator();
if (var3.hasNext()) {
PlayerRef playerRef = (PlayerRef)var3.next();
PlayerSomnolence somnolenceComponent = (PlayerSomnolence)store.getComponent(playerRef.getReference(), PlayerSomnolence.getComponentType());
if (somnolenceComponent == null) {
return true;
} else {
PlayerSleep sleepState = somnolenceComponent.getSleepState();
return sleepState instanceof PlayerSleep.FullyAwake;
}
} else {
return false;
}
}
}
}