package com.hypixel.hytale.server.core.command.commands.player.camera;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.event.EventRegistry;
import com.hypixel.hytale.math.iterator.BlockIterator;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.ClientCameraView;
import com.hypixel.hytale.protocol.Direction;
import com.hypixel.hytale.protocol.MouseButtonState;
import com.hypixel.hytale.protocol.MouseButtonType;
import com.hypixel.hytale.protocol.MouseInputType;
import com.hypixel.hytale.protocol.MovementForceRotationType;
import com.hypixel.hytale.protocol.PositionDistanceOffsetType;
import com.hypixel.hytale.protocol.RotationType;
import com.hypixel.hytale.protocol.ServerCameraSettings;
import com.hypixel.hytale.protocol.Vector3f;
import com.hypixel.hytale.protocol.packets.camera.SetServerCamera;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.entity.entities.player.CameraManager;
import com.hypixel.hytale.server.core.event.events.player.PlayerConnectEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerInteractEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerMouseButtonEvent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.Nonnull;
public class CameraDemo {
public static final CameraDemo INSTANCE = new CameraDemo();
private final EventRegistry eventRegistry = new EventRegistry(new CopyOnWriteArrayList(), () -> this.isActive, "CameraDemo is not active!", HytaleServer.get().getEventBus());
private final ServerCameraSettings cameraSettings = createServerCameraSettings();
private boolean isActive;
public CameraDemo() {
}
public void activate() {
if (!this.isActive) {
this.eventRegistry.enable();
this.isActive = true;
this.eventRegistry.register(PlayerConnectEvent.class, (event) -> this.onAddNewPlayer(event.getPlayerRef()));
this.eventRegistry.register(PlayerMouseButtonEvent.class, this::onPlayerMouseButton);
this.eventRegistry.registerGlobal(PlayerInteractEvent.class, (event) -> event.setCancelled(true));
Universe.get().getPlayers().forEach(this::onAddNewPlayer);
}
}
public void deactivate() {
if (this.isActive) {
this.eventRegistry.shutdown();
Universe.get().getPlayers().forEach((p) -> {
CameraManager cameraManager = (CameraManager)p.getComponent(CameraManager.getComponentType());
if (cameraManager != null) {
cameraManager.resetCamera(p);
}
});
this.isActive = false;
}
}
private void onAddNewPlayer(@Nonnull PlayerRef player) {
player.getPacketHandler().writeNoCache(new SetServerCamera(ClientCameraView.Custom, true, this.cameraSettings));
}
private void onPlayerMouseButton(@Nonnull PlayerMouseButtonEvent event) {
if (event.getMouseButton().state == MouseButtonState.Released) {
Ref<EntityStore> ref = event.getPlayerRef();
if (ref.isValid()) {
Store<EntityStore> store = ref.getStore();
World world = ((EntityStore)store.getExternalData()).getWorld();
Vector3i targetBlock = event.getTargetBlock();
CameraManager cameraManagerComponent = (CameraManager)store.getComponent(ref, CameraManager.getComponentType());
assert cameraManagerComponent != null;
Vector3i lastTargetBlock = cameraManagerComponent.getLastMouseButtonPressedPosition(event.getMouseButton().mouseButtonType);
if (event.getMouseButton().mouseButtonType == MouseButtonType.Middle) {
if (event.getItemInHand() != null && event.getItemInHand().hasBlockType() && targetBlock != null) {
String key = event.getItemInHand().getId();
int blockId = BlockType.getAssetMap().getIndex(key);
if (blockId == -2147483648) {
throw new IllegalArgumentException("Unknown key! " + key);
}
if (!lastTargetBlock.equals(targetBlock)) {
BlockIterator.iterateFromTo((Vector3i)lastTargetBlock, (Vector3i)targetBlock, (xx, y, zx, px, py, pz, qx, qy, qz) -> {
world.getChunk(ChunkUtil.indexChunkFromBlock(xx, zx)).setBlock(xx, y, zx, blockId);
return true;
});
} else {
int x = targetBlock.getX();
int z = targetBlock.getZ();
world.getChunk(ChunkUtil.indexChunkFromBlock(x, z)).setBlock(x, targetBlock.getY(), z, blockId);
}
}
} else if (event.getMouseButton().mouseButtonType == MouseButtonType.Right) {
if (!lastTargetBlock.equals(targetBlock)) {
BlockIterator.iterateFromTo((Vector3i)lastTargetBlock, (Vector3i)targetBlock, (xx, y, zx, px, py, pz, qx, qy, qz) -> {
world.getChunk(ChunkUtil.indexChunkFromBlock(xx, zx)).setBlock(xx, y, zx, 0);
return true;
});
} else {
int x = targetBlock.getX();
int z = targetBlock.getZ();
world.getChunk(ChunkUtil.indexChunkFromBlock(x, z)).setBlock(x, targetBlock.getY(), z, 0);
}
} else if (event.getMouseButton().mouseButtonType == MouseButtonType.Left && event.getItemInHand() != null && event.getItemInHand().hasBlockType() && targetBlock != null) {
String key = event.getItemInHand().getId();
int blockId = BlockType.getAssetMap().getIndex(key);
if (blockId == -2147483648) {
throw new IllegalArgumentException("Unknown key! " + key);
}
if (!lastTargetBlock.equals(targetBlock)) {
BlockIterator.iterateFromTo((double)lastTargetBlock.getX(), (double)(lastTargetBlock.getY() + 1), (double)lastTargetBlock.getZ(), (double)targetBlock.getX(), (double)(targetBlock.getY() + 1), (double)targetBlock.getZ(), (xx, y, zx, px, py, pz, qx, qy, qz) -> {
world.getChunk(ChunkUtil.indexChunkFromBlock(xx, zx)).setBlock(xx, y, zx, blockId);
return true;
});
} else {
int x = targetBlock.getX();
int z = targetBlock.getZ();
world.getChunk(ChunkUtil.indexChunkFromBlock(x, z)).setBlock(x, targetBlock.getY() + 1, z, blockId);
}
}
}
}
}
@Nonnull
private static ServerCameraSettings createServerCameraSettings() {
ServerCameraSettings cameraSettings = new ServerCameraSettings();
cameraSettings.positionLerpSpeed = 0.2F;
cameraSettings.rotationLerpSpeed = 0.2F;
cameraSettings.distance = 20.0F;
cameraSettings.displayCursor = true;
cameraSettings.sendMouseMotion = true;
cameraSettings.isFirstPerson = false;
cameraSettings.movementForceRotationType = MovementForceRotationType.Custom;
cameraSettings.eyeOffset = true;
cameraSettings.positionDistanceOffsetType = PositionDistanceOffsetType.DistanceOffset;
cameraSettings.rotationType = RotationType.Custom;
cameraSettings.rotation = new Direction(0.0F, -1.5707964F, 0.0F);
cameraSettings.mouseInputType = MouseInputType.LookAtPlane;
cameraSettings.planeNormal = new Vector3f(0.0F, 1.0F, 0.0F);
return cameraSettings;
}
}