cursor logic for blocks
Some checks reported errors
studiorailgun/Renderer/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
austin 2025-04-26 17:27:31 -04:00
parent 52454e753c
commit df72d51ea2
4 changed files with 69 additions and 0 deletions

View File

@ -1551,6 +1551,7 @@ Interaction target tooltip shows entity target, voxel targets
Fix bug where inventory items aren't destroying physics on server
Align voxel lookups for movement audio and interaction targeting
Align block lookups for interaction targeting
Cursor logic around blocks

View File

@ -18,6 +18,7 @@ import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.controls.cursor.CursorState;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
@ -223,6 +224,9 @@ public class ClientInteractionEngine {
*/
public static void updateInteractionTargetLabel(){
if(Globals.playerEntity != null && Globals.playerCamera != null){
//clear block cursor
Globals.cursorState.hintClearBlockCursor();
boolean set = false;
Entity camera = Globals.playerCamera;
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera));
@ -274,6 +278,8 @@ public class ClientInteractionEngine {
short type = blockChunkData.getType(blockPos.x, blockPos.y, blockPos.z);
String text = Globals.gameConfigCurrent.getBlockData().getTypeFromId(type).getName();
InteractionTargetMenu.setInteractionTargetString(text);
CursorState.makeBlockVisible();
Globals.cursorState.hintClampToExistingBlock();
set = true;
}
}

View File

@ -17,7 +17,9 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.game.data.block.BlockFab;
import electrosphere.game.data.item.Item;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.meshgen.BlockMeshgen;
@ -73,6 +75,12 @@ public class CursorState {
*/
private AreaSelection areaCursorSelection = null;
/**
* Clamps the position of the block cursor to the existing block if true
* Clamps to the closest empty block space if false
*/
private boolean clampToExistingBlock = false;
/**
* The fab cursor
*/
@ -138,6 +146,9 @@ public class CursorState {
EntityUtils.getPosition(Globals.playerCursor).set(cursorPos);
//clamp block cursor to nearest voxel
if(clampToExistingBlock){
cursorPos = cursorPos.add(new Vector3d(eyePos).normalize().mul(-BlockChunkData.BLOCK_SIZE_MULTIPLIER));
}
cursorPos.set(this.clampPositionToNearestBlock(cursorPos));
EntityUtils.getPosition(Globals.playerBlockCursor).set(cursorPos);
EntityUtils.getPosition(CursorState.playerFabCursor).set(cursorPos);
@ -173,6 +184,7 @@ public class CursorState {
*/
public static void makeFabVisible(){
CursorState.hide();
Globals.cursorState.setClampToExistingBlock(false);
Globals.clientSceneWrapper.getScene().registerEntityToTag(CursorState.playerFabCursor, EntityTags.DRAWABLE);
}
@ -319,5 +331,53 @@ public class CursorState {
public AreaSelection getAreaSelection(){
return this.areaCursorSelection;
}
/**
* Sets whether the block cursor should clamp to the existing block or not
* @param clampToExisting true to clamp to existing block, false to clamp to nearest empty block space
*/
public void setClampToExistingBlock(boolean clampToExisting){
this.clampToExistingBlock = clampToExisting;
}
/**
* Hints to clamp the cursor to existing blocks
*/
public void hintClampToExistingBlock(){
Globals.cursorState.setClampToExistingBlock(true);
if(Globals.playerEntity != null && ClientToolbarState.hasClientToolbarState(Globals.playerEntity)){
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
if(clientToolbarState.getCurrentPrimaryItem() != null){
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(clientToolbarState.getCurrentPrimaryItem());
if(Globals.playerCursor != null && Globals.playerBlockCursor != null){
if(itemData.getTokens().contains(CursorState.CURSOR_BLOCK_TOKEN)) {
Globals.cursorState.setClampToExistingBlock(false);
}
}
}
}
}
/**
* Hints to clear the cursor state
*/
public void hintClearBlockCursor(){
Globals.cursorState.setClampToExistingBlock(false);
if(Globals.playerEntity != null && ClientToolbarState.hasClientToolbarState(Globals.playerEntity)){
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
boolean clearBlockCursor = true;
if(clientToolbarState.getCurrentPrimaryItem() != null){
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(clientToolbarState.getCurrentPrimaryItem());
if(Globals.playerCursor != null && Globals.playerBlockCursor != null){
if(itemData.getTokens().contains(CursorState.CURSOR_BLOCK_TOKEN)) {
clearBlockCursor = false;
}
}
}
if(clearBlockCursor){
CursorState.hide();
}
}
}
}

View File

@ -178,9 +178,11 @@ public class ClientToolbarState implements BehaviorTree {
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(toEquip);
if(Globals.playerCursor != null && Globals.playerBlockCursor != null){
CursorState.hide();
Globals.cursorState.setClampToExistingBlock(false);
if(itemData.getTokens().contains(CursorState.CURSOR_TOKEN)){
CursorState.makeRealVisible();
} else if(itemData.getTokens().contains(CursorState.CURSOR_BLOCK_TOKEN)) {
Globals.cursorState.setClampToExistingBlock(true);
CursorState.makeBlockVisible();
}
}