tooltips, recipes, refactoring
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-10-23 10:41:32 -04:00
parent 3b521e3197
commit d10da49140
37 changed files with 690 additions and 28 deletions

View File

@ -390,6 +390,36 @@
"offsetZ" : 0
},
"iconPath" : "Textures/icons/itemIconItemGeneric.png"
},
{
"id" : "entityinspector",
"tokens" : [
"GRAVITY",
"TARGETABLE"
],
"equipData": {
"equipClass" : "tool"
},
"graphicsTemplate": {
"model": {
"path" : "Models/items/weapons/shovel1.glb"
}
},
"clientSideSecondary": "INSPECTOR",
"collidable": {
"type" : "CUBE",
"dimension1" : 0.1,
"dimension2" : 0.1,
"dimension3" : 0.35,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"rotW": 1,
"offsetX" : 0,
"offsetY" : 0.05,
"offsetZ" : 0
},
"iconPath" : "Textures/icons/itemIconItemGeneric.png"
}

View File

@ -0,0 +1,22 @@
{
"recipes": [
{
"id": 0,
"ingredients": [
{
"itemType": "katana2H",
"count": 1
}
],
"products": [
{
"itemType": "katana2H",
"count": 1
}
]
}
],
"files": [
]
}

View File

@ -28,5 +28,11 @@ export const clientHooks: Hook[] = [
callback: (engine: Engine) => {
engine.classes.levelEditorUtils.static.spawnEntity()
}
},
{
signal: "INSPECTOR",
callback: (engine: Engine) => {
engine.classes.levelEditorUtils.static.inspectEntity()
}
}
]

View File

@ -8,4 +8,9 @@ export interface ClientLevelEditorUtils {
*/
readonly spawnEntity: () => void
/**
* Inspects the entity that the player's cursor is hovering over
*/
readonly inspectEntity: () => void
}

View File

@ -23,6 +23,7 @@
+ rearchitecture
+ fix the vibes
Tooltips for items, hover over with cursor, etc
Ticketed randomizer node for BTs to more heavily weight attacking and waiting
+ non-feedback requirements

View File

@ -888,6 +888,15 @@ Fix script spawning NPE
(10/22/2024)
Editor movement system + editor entity
Ability to disable physics
Inspector item
Fix alignment on spawn palette menu
Add padding setters to ui kit
Refactor ui components to be under client folder
Scaffold out recipes data
Initial implementation of tooltips
(10/23/2024)
Tooltip improvements

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.ui.components;
package electrosphere.client.ui.components;
import java.util.stream.Collectors;

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.ui.components;
package electrosphere.client.ui.components;
import java.util.List;

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.ui.components;
package electrosphere.client.ui.components;
import java.util.function.Consumer;

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.ui.components;
package electrosphere.client.ui.components;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.client.ui.menu.WindowStrings;

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.ui.components;
package electrosphere.client.ui.components;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.client.ui.menu.WindowStrings;

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.ui.components;
package electrosphere.client.ui.components;
import java.util.LinkedList;
import java.util.List;
@ -30,11 +30,15 @@ public class SpawnSelectionPanel {
//type selection
static final int SELECTION_SCROLLABLE_WIDTH = 500;
static final int SELECTION_SCROLLABLE_HEIGHT = 500;
static final int SELECTION_SCROLLABLE_HEIGHT = 450;
//single listing
static final int MARGIN_EACH_SIDE = 5;
//margin from top for search input
static final int SEARCH_INPUT_MARGIN = 10;
static final int SEARCH_INPUT_MIN_HEIGHt = 20;
/**
* Creates the spawning menu selection panel
* @return
@ -51,12 +55,17 @@ public class SpawnSelectionPanel {
VirtualScrollable scrollable = new VirtualScrollable(SELECTION_SCROLLABLE_WIDTH, SELECTION_SCROLLABLE_HEIGHT);
scrollable.setFlexDirection(YogaFlexDirection.Column);
scrollable.setAlignItems(YogaAlignment.Start);
scrollable.setMarginBottom(MARGIN_EACH_SIDE);
scrollable.setMarginLeft(MARGIN_EACH_SIDE);
scrollable.setMarginRight(MARGIN_EACH_SIDE);
scrollable.setMarginTop(MARGIN_EACH_SIDE);
//search input
TextInput searchInput = TextInput.createTextInput();
searchInput.setWidth(TEXT_INPUT_WIDTH);
searchInput.setMinWidth(TEXT_INPUT_WIDTH);
searchInput.setMinHeight(20);
searchInput.setMinHeight(SEARCH_INPUT_MIN_HEIGHt);
searchInput.setMarginTop(SEARCH_INPUT_MARGIN);
searchInput.setOnPress(new KeyboardEventCallback() {public boolean execute(KeyboardEvent event){
boolean rVal = searchInput.defaultKeyHandling(event);
fillInEntitySelectors(scrollable, searchInput.getText(), onSelectType);

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.ui.components;
package electrosphere.client.ui.components;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.client.ui.menu.WindowStrings;
@ -18,6 +18,7 @@ import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.ImagePanel;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Tooltip;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.ContainerElement;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
@ -25,14 +26,21 @@ import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.elementtypes.DraggableElement.DragEventCallback;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.HoverableElement.HoverEventCallback;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.DragEvent;
import electrosphere.renderer.ui.events.HoverEvent;
/**
* Toolbar inventory panel
*/
public class ToolbarInventoryPanel {
/**
* The tooltip for the currently hovered item
*/
static Tooltip itemTooltip;
/**
* Creates the toolbar inventory panel
* @param entity The entity who has the inventory
@ -180,6 +188,27 @@ public class ToolbarInventoryPanel {
}
return false;
}});
panel.setOnHoverCallback(new HoverEventCallback() {public boolean execute(HoverEvent event){
if(event.isHovered() && Globals.draggedItem == null){
if(itemTooltip != null){
Tooltip.destroy(itemTooltip);
}
Entity itemEntity = inventory.getItemSlot("" + itemId) ;
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(itemEntity);
Globals.signalSystem.post(SignalType.UI_MODIFICATION,()->{
itemTooltip = Tooltip.create(null,
Div.createCol(Label.createLabel(itemData.getId()))
);
itemTooltip.setPositionX(panel.getAbsoluteX() + panelWidth);
itemTooltip.setPositionY(panel.getAbsoluteY());
});
} else {
if(itemTooltip != null){
Tooltip.destroy(itemTooltip);
}
}
return false;
}});
} else {
int slotId = i;
panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){

View File

@ -3,6 +3,7 @@ package electrosphere.client.ui.menu;
import java.util.List;
import electrosphere.auth.AuthenticationManager;
import electrosphere.client.ui.components.InputMacros;
import electrosphere.client.ui.menu.mainmenu.MenuGeneratorsKeybind;
import electrosphere.client.ui.menu.mainmenu.MenuGeneratorsTitleMenu;
import electrosphere.engine.Globals;
@ -10,7 +11,6 @@ import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.entity.scene.SceneGenerator;
import electrosphere.net.NetUtils;
import electrosphere.renderer.ui.components.InputMacros;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.FormElement;

View File

@ -41,4 +41,9 @@ public class WindowStrings {
//the tutorial popup
public static final String TUTORIAL_POPUP = "tutorialPopup";
/**
* Window for displaying tooltip elements
*/
public static final String TOOLTIP_WINDOW = "tooltipWindow";
}

View File

@ -1,10 +1,10 @@
package electrosphere.client.ui.menu;
import electrosphere.client.ui.components.PlayerInventoryWindow;
import electrosphere.client.ui.menu.ingame.MenuGeneratorsInventory;
import electrosphere.client.ui.menu.mainmenu.MenuGeneratorsTitleMenu;
import electrosphere.engine.Globals;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.renderer.ui.components.PlayerInventoryWindow;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ContainerElement;
@ -173,12 +173,15 @@ public class WindowUtils {
}
/**
* Inits all base windows
*/
public static void initBaseWindows(){
initLoadingWindow();
initItemDropWindow();
initItemDragContainerWindow();
initMainMenuWindow();
initTooltipWindow();
}
static void initLoadingWindow(){
@ -205,6 +208,14 @@ public class WindowUtils {
Globals.elementService.registerWindow(WindowStrings.WINDOW_ITEM_DRAG_CONTAINER, itemDragContainerWindow);
}
/**
* Creates the tooltip window
*/
static void initTooltipWindow(){
Window tooltipWindow = Window.create(Globals.renderingEngine.getOpenGLState(), 0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, false);
Globals.elementService.registerWindow(WindowStrings.TOOLTIP_WINDOW, tooltipWindow);
}
public static void focusWindow(String window){
Element windowEl = Globals.elementService.getWindow(window);
if(windowEl != null){

View File

@ -1,6 +1,7 @@
package electrosphere.client.ui.menu.ingame;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.client.ui.components.PlayerInventoryWindow;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.engine.Globals;
@ -9,7 +10,6 @@ import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.item.type.Item;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.ui.components.PlayerInventoryWindow;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.Element;

View File

@ -3,6 +3,7 @@ package electrosphere.client.ui.menu.ingame;
import java.util.List;
import java.util.function.Consumer;
import electrosphere.client.ui.components.SpawnSelectionPanel;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.controls.ControlHandler.ControlsState;
@ -11,7 +12,6 @@ import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.game.data.common.CommonEntityType;
import electrosphere.game.data.voxel.VoxelData;
import electrosphere.game.data.voxel.VoxelType;
import electrosphere.renderer.ui.components.SpawnSelectionPanel;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.ImagePanel;
@ -52,8 +52,8 @@ public class MenuGeneratorsTerrainEditing {
static final int VOXEL_SCROLLABLE_HEIGHT = VOXEL_BUTTON_HEIGHT * 5;
//width of the side panel
static final int WINDOW_WIDTH = VOXEL_SCROLLABLE_WIDTH;
static final int WINDOW_HEIGHT = VOXEL_SCROLLABLE_HEIGHT + TEXT_INPUT_HEIGHT;
static final int WINDOW_WIDTH = 550;
static final int WINDOW_HEIGHT = 550;
/**
* Creates the level editor side panel window

View File

@ -2,6 +2,7 @@ package electrosphere.client.ui.menu.mainmenu;
import java.util.List;
import electrosphere.client.ui.components.InputMacros;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.client.ui.menu.ingame.MenuGeneratorsTerrainEditing;
import electrosphere.engine.Globals;
@ -10,7 +11,6 @@ import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.entity.scene.SceneFile;
import electrosphere.game.data.voxel.VoxelType;
import electrosphere.renderer.ui.components.InputMacros;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.FormElement;

View File

@ -1,9 +1,9 @@
package electrosphere.client.ui.menu.mainmenu;
import electrosphere.client.ui.components.CharacterCustomizer;
import electrosphere.client.ui.menu.MenuGenerators;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.engine.Globals;
import electrosphere.renderer.ui.components.CharacterCustomizer;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label;

View File

@ -7,6 +7,11 @@ import java.util.List;
import org.joml.Vector3f;
import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.ui.components.CharacterCustomizer;
import electrosphere.client.ui.components.EquipmentInventoryPanel;
import electrosphere.client.ui.components.InputMacros;
import electrosphere.client.ui.components.NaturalInventoryPanel;
import electrosphere.client.ui.components.SpawnSelectionPanel;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.client.ui.menu.ingame.MenuGeneratorsTerrainEditing;
import electrosphere.engine.Globals;
@ -20,11 +25,6 @@ import electrosphere.game.data.common.CommonEntityType;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.game.data.voxel.VoxelType;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.renderer.ui.components.CharacterCustomizer;
import electrosphere.renderer.ui.components.EquipmentInventoryPanel;
import electrosphere.renderer.ui.components.InputMacros;
import electrosphere.renderer.ui.components.NaturalInventoryPanel;
import electrosphere.renderer.ui.components.SpawnSelectionPanel;
import electrosphere.renderer.ui.elements.ActorPanel;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.FormElement;

View File

@ -6,8 +6,10 @@ import org.graalvm.polyglot.HostAccess.Export;
import org.joml.Vector3d;
import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.ui.menu.debug.entity.ImGuiEntityMacros;
import electrosphere.collision.CollisionEngine;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils;
@ -80,4 +82,19 @@ public class ScriptLevelEditorUtils {
}
}
/**
* Inspects the entity that the player's cursor is hovering over
*/
@Export
public static void inspectEntity(){
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
CollisionEngine clientCollisionEngine = Globals.clientSceneWrapper.getCollisionEngine(); //using client collision engine so ray doesn't collide with player entity
Entity target = clientCollisionEngine.rayCast(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
//show detail view here
if(target != null){
ImGuiEntityMacros.showEntity(target);
}
}
}

View File

@ -78,6 +78,7 @@ import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.entity.crosshair.Crosshair;
import electrosphere.client.item.ItemActions;
import electrosphere.client.terrain.editing.TerrainEditing;
import electrosphere.client.ui.components.PlayerInventoryWindow;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.client.ui.menu.debug.ImGuiWindowMacros;
@ -103,7 +104,6 @@ import electrosphere.entity.state.movement.sprint.ClientSprintTree;
import electrosphere.entity.state.movement.walk.ClientWalkTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.ui.components.PlayerInventoryWindow;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.KeyboardEvent;
@ -1245,6 +1245,7 @@ public class ControlHandler {
controls.get(DATA_STRING_INPUT_CODE_MENU_INCREMENT).setRepeatTimeout(0.5f * Main.targetFrameRate);
//moving the mouse
inventoryControlList.add(controls.get(MENU_MOUSE_MOVE));
menuNavigationControlList.add(controls.get(MENU_MOUSE_MOVE));
controls.get(MENU_MOUSE_MOVE).setOnMove(new Control.MouseCallback(){public void execute(MouseEvent mouseEvent){
Globals.elementService.updateHover(mouseEvent.getCurrentX(), mouseEvent.getCurrentY());

View File

@ -179,6 +179,7 @@ public class LoadingUtils {
}
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
//set player character template
serverPlayerConnection.setCreatureTemplate(template);
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage());

View File

@ -7,6 +7,7 @@ import electrosphere.game.data.audio.SurfaceAudioCollection;
import electrosphere.game.data.common.CommonEntityLoader;
import electrosphere.game.data.common.CommonEntityMap;
import electrosphere.game.data.common.CommonEntityType;
import electrosphere.game.data.crafting.RecipeDataMap;
import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.CreatureTypeLoader;
import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
@ -51,6 +52,11 @@ public class Config {
*/
UnitLoader unitLoader;
/**
* The crafting recipe map
*/
RecipeDataMap recipeMap;
/**
* Loads the default data
* @return The config
@ -69,6 +75,7 @@ public class Config {
config.surfaceAudioCollection = FileUtils.loadObjectFromAssetPath("Data/audio/surface.json", SurfaceAudioCollection.class);
config.projectileTypeHolder.init();
config.unitLoader = UnitLoader.create(FileUtils.loadObjectFromAssetPath("Data/game/units/units.json", UnitDefinitionFile.class));
config.recipeMap = RecipeDataMap.loadRecipeFiles("Data/game/recipes.json");
//validate
ConfigValidator.valdiate(config);
@ -246,4 +253,12 @@ public class Config {
return unitLoader;
}
/**
* Gets the recipe map
* @return The recipe map
*/
public RecipeDataMap getRecipeMap(){
return recipeMap;
}
}

View File

@ -0,0 +1,77 @@
package electrosphere.game.data.crafting;
import java.util.List;
/**
* Data on a crafting recipe
*/
public class RecipeData {
/**
* The id of the recipe
*/
int id;
/**
* The ingredients required for the recipe
*/
List<RecipeIngredientData> ingredients;
/**
* The products produced by the recipe
*/
List<RecipeIngredientData> products;
/**
* Gets the ingredients required for the recipe
* @return The ingredients required for the recipe
*/
public List<RecipeIngredientData> getIngredients() {
return ingredients;
}
/**
* Sets the ingredients required for the recipe
* @param ingredients The ingredients required for the recipe
*/
public void setIngredients(List<RecipeIngredientData> ingredients) {
this.ingredients = ingredients;
}
/**
* Gets the products produced by the recipe
* @return The products produced by the recipe
*/
public List<RecipeIngredientData> getProducts() {
return products;
}
/**
* Sets the products produced by the recipe
* @param products The products produced by the recipe
*/
public void setProducts(List<RecipeIngredientData> products) {
this.products = products;
}
/**
* Gets the id of the recipe
* @return The id of the recipe
*/
public int getId() {
return id;
}
/**
* Sets the id of the recipe
* @param id The id of the recipe
*/
public void setId(int id) {
this.id = id;
}
}

View File

@ -0,0 +1,54 @@
package electrosphere.game.data.crafting;
import java.util.List;
/**
* A file containing crafting recipe data
*/
public class RecipeDataFile {
/**
* The recipe data in this file
*/
List<RecipeData> recipes;
/**
* All child files of this one
*/
List<String> files;
/**
* Gets the recipe data in this file
* @return The recipe data in this file
*/
public List<RecipeData> getRecipes() {
return recipes;
}
/**
* Sets the recipe data in this file
* @param recipes The recipe data in this file
*/
public void setRecipes(List<RecipeData> recipes) {
this.recipes = recipes;
}
/**
* Gets all child files of this one
* @return All child files of this one
*/
public List<String> getFiles() {
return files;
}
/**
* Sets all child files of this one
* @param files All child files of this one
*/
public void setFiles(List<String> files) {
this.files = files;
}
}

View File

@ -0,0 +1,92 @@
package electrosphere.game.data.crafting;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import electrosphere.util.FileUtils;
/**
* A structure for efficiently looking up recipes
*/
public class RecipeDataMap {
/**
* The map of recipe id -> recipe data
*/
Map<Integer,RecipeData> idRecipeMap = new HashMap<Integer,RecipeData>();
/**
* Adds recipe data to the loader
* @param name The id of the recipe
* @param type The recipe data
*/
public void putType(int id, RecipeData type){
idRecipeMap.put(id,type);
}
/**
* Gets recipe data from the id of the recipe
* @param id The id of the recipe
* @return The recipe data if it exists, null otherwise
*/
public RecipeData getType(int id){
return idRecipeMap.get(id);
}
/**
* Gets the collection of all recipe data
* @return the collection of all recipe data
*/
public Collection<RecipeData> getTypes(){
return idRecipeMap.values();
}
/**
* Gets the set of all recipe data id's stored in the loader
* @return the set of all recipe data ids
*/
public Set<Integer> getTypeIds(){
return idRecipeMap.keySet();
}
/**
* Reads a child recipe defintion file
* @param filename The filename
* @return The list of recipes in the file
*/
static List<RecipeData> recursiveReadRecipeLoader(String filename){
List<RecipeData> typeList = new LinkedList<RecipeData>();
RecipeDataFile loaderFile = FileUtils.loadObjectFromAssetPath(filename, RecipeDataFile.class);
//push the types from this file
for(RecipeData type : loaderFile.getRecipes()){
typeList.add(type);
}
//push types from any other files
for(String filepath : loaderFile.getFiles()){
List<RecipeData> parsedTypeList = recursiveReadRecipeLoader(filepath);
for(RecipeData type : parsedTypeList){
typeList.add(type);
}
}
return typeList;
}
/**
* Loads all recipe definition files recursively
* @param initialPath The initial path to recurse from
* @return The recipe defintion interface
*/
public static RecipeDataMap loadRecipeFiles(String initialPath) {
RecipeDataMap rVal = new RecipeDataMap();
List<RecipeData> typeList = recursiveReadRecipeLoader(initialPath);
for(RecipeData type : typeList){
rVal.putType(type.getId(), type);
}
return rVal;
}
}

View File

@ -0,0 +1,52 @@
package electrosphere.game.data.crafting;
/**
* An ingredient in a recipe
*/
public class RecipeIngredientData {
/**
* The type of item for the recipe
*/
String itemType;
/**
* The count of the item required for the recipe
*/
int count;
/**
* Gets the type of item for the recipe
* @return The type of item for the recipe
*/
public String getItemType() {
return itemType;
}
/**
* Sets the type of item for the recipe
* @param itemType The type of item for the recipe
*/
public void setItemType(String itemType) {
this.itemType = itemType;
}
/**
* Gets the count of the item required for the recipe
* @return The count of the item required for the recipe
*/
public int getCount() {
return count;
}
/**
* Sets the count of the item required for the recipe
* @param count The count of the item required for the recipe
*/
public void setCount(int count) {
this.count = count;
}
}

View File

@ -2,6 +2,7 @@ package electrosphere.renderer.pipelines;
import org.lwjgl.opengl.GL40;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.engine.Globals;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
@ -9,6 +10,7 @@ import electrosphere.renderer.RenderingEngine;
import electrosphere.renderer.debug.DebugRendering;
import electrosphere.renderer.texture.Texture;
import electrosphere.renderer.ui.UIUtils;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.DrawableElement;
import electrosphere.renderer.ui.elementtypes.Element;
@ -77,6 +79,11 @@ public class UIPipeline implements RenderPipeline {
}
}
}
if(Globals.elementService.getWindow(WindowStrings.TOOLTIP_WINDOW) != null){
Window tooltipWindow = (Window)Globals.elementService.getWindow(WindowStrings.TOOLTIP_WINDOW);
tooltipWindow.draw(renderPipelineState, openGLState, Globals.renderingEngine.defaultFramebuffer, 0, 0);
}
}
if(DebugRendering.RENDER_DEBUG_UI_TREE){

View File

@ -500,10 +500,10 @@ public class ElementService extends SignalServiceImpl {
Element newHoverableElement = resolveFirstHoverable(currentX,currentY);
if(currentHoveredElement != newHoverableElement){
if(currentHoveredElement != null){
currentHoveredElement.handleEvent(new HoverEvent(false));
currentHoveredElement.handleEvent(new HoverEvent(false,currentX,currentY));
}
if(newHoverableElement != null){
newHoverableElement.handleEvent(new HoverEvent(true));
newHoverableElement.handleEvent(new HoverEvent(true,currentX,currentY));
}
currentHoveredElement = (HoverableElement)newHoverableElement;
}

View File

@ -12,15 +12,17 @@ import electrosphere.renderer.model.Model;
import electrosphere.renderer.texture.Texture;
import electrosphere.renderer.ui.elementtypes.DraggableElement;
import electrosphere.renderer.ui.elementtypes.DrawableElement;
import electrosphere.renderer.ui.elementtypes.HoverableElement;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.events.DragEvent;
import electrosphere.renderer.ui.events.DragEvent.DragEventType;
import electrosphere.renderer.ui.events.Event;
import electrosphere.renderer.ui.events.HoverEvent;
/**
* A UI element that is a single, uninteractable image
*/
public class ImagePanel extends StandardElement implements DrawableElement, DraggableElement {
public class ImagePanel extends StandardElement implements DrawableElement, DraggableElement, HoverableElement {
Vector3f color = new Vector3f(1.0f);
@ -47,6 +49,7 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag
DragEventCallback onDragStart;
DragEventCallback onDrag;
DragEventCallback onDragRelease;
HoverEventCallback onHover;
static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,0.5f,1.0f);
@ -192,6 +195,13 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag
}
}
}
if(event instanceof HoverEvent){
if(onHover != null){
if(!onHover.execute((HoverEvent)event)){
propagate = false;
}
}
}
return propagate;
}
@ -210,4 +220,9 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag
onDragRelease = callback;
}
@Override
public void setOnHoverCallback(HoverEventCallback callback) {
onHover = callback;
}
}

View File

@ -264,4 +264,24 @@ public class StandardElement implements Element {
Yoga.YGNodeStyleSetDisplay(this.yogaNode, value);
}
@Override
public void setPaddingTop(int paddingTop) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeTop, paddingTop);
}
@Override
public void setPaddingRight(int paddingRight) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeRight, paddingRight);
}
@Override
public void setPaddingBottom(int paddingBottom) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeBottom, paddingBottom);
}
@Override
public void setPaddingLeft(int paddingLeft) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeLeft, paddingLeft);
}
}

View File

@ -0,0 +1,132 @@
package electrosphere.renderer.ui.elements;
import java.util.function.Consumer;
import org.joml.Vector3f;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.engine.Globals;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.model.Material;
import electrosphere.renderer.model.Model;
import electrosphere.renderer.texture.Texture;
import electrosphere.renderer.ui.elementtypes.DrawableElement;
import electrosphere.renderer.ui.elementtypes.Element;
/**
* A tooltip
*/
public class Tooltip extends StandardDrawableContainerElement {
//color of the decorations for the tooltip popout
Vector3f backgroundColor = new Vector3f(0.2f,0.2f,0.2f);
Vector3f boxPosition = new Vector3f();
Vector3f boxDimensions = new Vector3f();
Vector3f texPosition = new Vector3f(0,0,0);
Vector3f texScale = new Vector3f(1,1,0);
Material customMat = new Material();
/**
* Optional callback for aligning the tooltip to a given location
*/
Consumer<Tooltip> alignmentCallback;
/**
* Creates a tooltip
* @param alignmentCallback The logic for aligning the tooltip positionally
* @param children The children of the tooltip
* @return The tooltip
*/
public static Tooltip create(Consumer<Tooltip> alignmentCallback, Element ... children){
Tooltip tooltip = new Tooltip();
tooltip.setAbsolutePosition(true);
tooltip.setPositionX(0);
tooltip.setPositionY(0);
tooltip.alignmentCallback = alignmentCallback;
for(Element child : children){
tooltip.addChild(child);
}
Element windowElement = Globals.elementService.getWindow(WindowStrings.TOOLTIP_WINDOW);
if(windowElement instanceof Window){
Window windowView = (Window)windowElement;
windowView.addChild(tooltip);
Globals.signalSystem.post(SignalType.YOGA_APPLY,windowView);
}
return tooltip;
}
@Override
public void draw(
RenderPipelineState renderPipelineState,
OpenGLState openGLState,
Framebuffer framebuffer,
int framebufferPosX,
int framebufferPosY
) {
//calculate alignment
if(this.alignmentCallback != null){
this.alignmentCallback.accept(this);
}
//
//Draw decorations
float ndcWidth = (float)getWidth()/framebuffer.getWidth();
float ndcHeight = (float)getHeight()/framebuffer.getHeight();
float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth();
float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight();
boxPosition = new Vector3f(ndcX,ndcY,0);
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID);
Texture windowFrame = null;
windowFrame = Globals.assetManager.fetchTexture("Textures/b1.png");
//this call binds the screen as the "texture" we're rendering to
//have to call before actually rendering
framebuffer.bind(openGLState);
openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight());
//error if assets are null
if(planeModel == null || windowFrame == null){
LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model or window frame!!", new Exception());
}
//render background of window
if(planeModel != null && windowFrame != null){
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
planeModel.pushUniformToMesh("plane", "tDimension", texScale);
planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", backgroundColor);
customMat.setTexturePointer(windowFrame.getTexturePointer());
planeModel.getMeshes().get(0).setMaterial(customMat);
planeModel.drawUI();
}
//
//Draw children elements
for(Element child : childList){
((DrawableElement)child).draw(renderPipelineState, openGLState, framebuffer, framebufferPosX, framebufferPosY);
}
}
/**
* Destroys the tooltip
* @param target The tooltip to destroy
*/
public static void destroy(Tooltip target){
Globals.signalSystem.post(SignalType.UI_MODIFICATION,()->{
Window tooltipWindow = (Window)Globals.elementService.getWindow(WindowStrings.TOOLTIP_WINDOW);
tooltipWindow.removeChild(target);
Globals.signalSystem.post(SignalType.YOGA_DESTROY, target);
});
}
}

View File

@ -816,4 +816,24 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
Yoga.YGNodeStyleSetPosition(this.yogaNode, Yoga.YGEdgeTop, positionY);
}
@Override
public void setPaddingTop(int paddingTop) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeTop, paddingTop);
}
@Override
public void setPaddingRight(int paddingRight) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeRight, paddingRight);
}
@Override
public void setPaddingBottom(int paddingBottom) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeBottom, paddingBottom);
}
@Override
public void setPaddingLeft(int paddingLeft) {
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeLeft, paddingLeft);
}
}

View File

@ -45,6 +45,12 @@ public interface Element {
public void setMarginBottom(int marginBottom);
public void setMarginLeft(int marginLeft);
//padding
public void setPaddingTop(int paddingTop);
public void setPaddingRight(int paddingRight);
public void setPaddingBottom(int paddingBottom);
public void setPaddingLeft(int paddingLeft);
/**
* Sets the self alignment
* @param alignment the alignment style

View File

@ -8,12 +8,20 @@ public class HoverEvent implements Event {
//if true, this element is hovered over, false otherwise
boolean isHovered;
/**
* The mouse position of the event
*/
int currentX;
int currentY;
/**
* Creates the hover event
* @param isHovered true if hovered over, false otherwise
*/
public HoverEvent(boolean isHovered){
public HoverEvent(boolean isHovered, int currentX, int currentY){
this.isHovered = isHovered;
this.currentX = currentX;
this.currentY = currentY;
}
/**
@ -24,4 +32,22 @@ public class HoverEvent implements Event {
return isHovered;
}
/**
* Gets the x position of the mouse
* @return The x position
*/
public int getCurrentX() {
return currentX;
}
/**
* Gets the y position of the mouse
* @return The y position
*/
public int getCurrentY() {
return currentY;
}
}