diff --git a/game/input.h b/game/input.h index 8da5a00..65e82f3 100644 --- a/game/input.h +++ b/game/input.h @@ -34,6 +34,11 @@ typedef struct InputMapping { MouseButton moveDown; } InputMapping; +typedef struct ToolTipCost { + bool active; + i32 costs[RES_COUNT]; +} ToolTipCost; + typedef struct InputState { InputType state; InputMapping mapping; @@ -66,6 +71,7 @@ typedef struct InputState { // SELECTED_BUILDING // Other + ToolTipCost toolTipCost; struct { /* Selected units * 1: Position diff --git a/game/systems/s_ui.c b/game/systems/s_ui.c index 8247df4..2198773 100644 --- a/game/systems/s_ui.c +++ b/game/systems/s_ui.c @@ -152,7 +152,14 @@ void drawGameUI(Game *game, f32 dt) { bool selected = input->building == buildingOrder[i]; PlayerResources *res = &game->playerResources[game->player]; bool canAfford = canAffordBuilding(buildingType, *res); - uiGameBuild(buildingNames[i], rec, tex, canAfford, &selected); + bool hovered = false; + uiGameBuild(buildingNames[i], rec, tex, canAfford, &selected, &hovered); + if (hovered) { + input->toolTipCost.active = true; + i32 costs[RES_COUNT] = {0}; + getBuildingCost(buildingType, costs); + bzMemCpy(input->toolTipCost.costs, costs, sizeof(costs)); + } if (!canAfford) selected = false; if (selected) { @@ -243,11 +250,16 @@ void drawGameUI(Game *game, f32 dt) { canAfford &= playerRes->pop < playerRes->popCapacity; f32 progress = slot->elapsed / slot->recruitTime; if (slot->numRecruiting <= 0) progress = -1.0f; + bool hovered = false; uiGameRecruit(label, rec, tex, slot->numRecruiting, progress, - canAfford, &selected); + canAfford, &selected, &hovered); + i32 res[RES_COUNT] = {0,}; + getEntityCost(slot->entityType, res); + if (hovered) { + input->toolTipCost.active = true; + bzMemCpy(input->toolTipCost.costs, res, sizeof(res)); + } if (selected) { - i32 res[RES_COUNT] = {0,}; - getEntityCost(slot->entityType, res); playerRes->pop++; playerRes->food -= res[RES_FOOD]; playerRes->wood -= res[RES_WOOD]; @@ -287,6 +299,12 @@ void drawGameUI(Game *game, f32 dt) { } bzUIEnd(UI); + + if (input->toolTipCost.active) { + uiGameTooltipCost(input->mouse, input->toolTipCost.costs, tex); + input->toolTipCost.active = false; + } + } void drawGameOverUI(Game *game, f32 dt) { diff --git a/game/ui_widgets.c b/game/ui_widgets.c index a99fb8e..6044416 100644 --- a/game/ui_widgets.c +++ b/game/ui_widgets.c @@ -1,6 +1,7 @@ #include "ui_widgets.h" #include "game_state.h" +#include "components.h" #include @@ -248,7 +249,7 @@ void uiGameResCount(i32 amount, i32 capacity, Rectangle icon, Texture2D texture) } void uiGameRecruit(const char *label, Rectangle rec, Texture2D tex, i32 numRecruiting, - f32 progress, bool canAfford, bool *selected) { + f32 progress, bool canAfford, bool *selected, bool *hovered) { f32 scl = uiGetScale(); BzUINode *btn = bzUINodeMake(UI, bzUIKeyFromString(label), &(BzUINodeDesc) { .flags = BZ_UI_CLICKABLE | BZ_UI_ALIGN_CENTER | BZ_UI_DRAW_BORDER, @@ -269,6 +270,8 @@ void uiGameRecruit(const char *label, Rectangle rec, Texture2D tex, i32 numRecru bgColor = canAfford ? BROWN : RED; if (inter.clicked && canAfford) *selected = true; + if (hovered) + *hovered = inter.hovering; bzUISetBackgroundStyle(UI, btn, (BzUIBackgroundStyle) { .roundness = 0.2f, @@ -345,7 +348,7 @@ void uiGameRecruit(const char *label, Rectangle rec, Texture2D tex, i32 numRecru bzUIPopParent(UI); } -void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford, bool *selected) { +void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford, bool *selected, bool *hovered) { f32 scl = uiGetScale(); BzUINode *btn = bzUINodeMake(UI, bzUIKeyFromString(label), &(BzUINodeDesc) { .flags = BZ_UI_CLICKABLE | BZ_UI_ALIGN_CENTER | BZ_UI_DRAW_BORDER, @@ -366,6 +369,8 @@ void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford bgColor = canAfford ? BROWN : RED; if (inter.clicked && canAfford) *selected = true; + if (hovered) + *hovered = inter.hovering; bzUISetBackgroundStyle(UI, btn, (BzUIBackgroundStyle) { .roundness = 0.2f, @@ -424,7 +429,7 @@ void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford } bool uiGameTrade(const char *label, Rectangle rec, Texture2D tex, bool canAfford) { bool selected = false; - uiGameBuild(label, rec, tex, canAfford, &selected); + uiGameBuild(label, rec, tex, canAfford, &selected, NULL); return selected; } bool uiGameUnit(const char *label, i32 count, Rectangle rec, Texture2D tex) { @@ -505,3 +510,43 @@ bool uiGameUnit(const char *label, i32 count, Rectangle rec, Texture2D tex) { bzUIPopParent(UI); return inter.clicked; } + +void uiGameTooltipCost(Vector2 pos, i32 costs[RES_COUNT], Texture2D tex) { + char text[RES_COUNT][32]; + for (i32 i = 0; i < RES_COUNT; i++) { + snprintf(text[i], sizeof(text[i]), "%d", BZ_ABS(costs[i])); + } + + Vector2 offset = pos; + const f32 fontSize = 32 * uiGetScale(); + const f32 margin = 10 * uiGetScale(); + offset.x += margin * 0.5f; + offset.y -= margin; + for (i32 i = 0; i < RES_COUNT; i++) { + EntityType entity = ENTITY_NONE; + switch (i) { + case RES_FOOD: + entity = ENTITY_APPLE; + break; + case RES_WOOD: + entity = ENTITY_WOOD; + break; + case RES_GOLD: + entity = ENTITY_GOLD; + break; + } + if (entity == ENTITY_NONE) continue; + if (costs[i] == 0) continue; + + Vector2 size = MeasureTextEx(getFont(), text[i], fontSize, 1.0f); + Rectangle rec = getTextureRect(getEntityTile(entity)); + DrawText(text[i], offset.x, offset.y, fontSize, WHITE); + const f32 texSize = size.y; + offset.x += size.x + margin * 0.8f; + DrawTexturePro(tex, rec, (Rectangle) { + offset.x, offset.y, + texSize, texSize + }, (Vector2) { 0, 0 }, 0.0f, WHITE); + offset.x += texSize + margin; + } +} diff --git a/game/ui_widgets.h b/game/ui_widgets.h index 80808a2..2b9f592 100644 --- a/game/ui_widgets.h +++ b/game/ui_widgets.h @@ -3,6 +3,7 @@ #include #include +#include "components.h"d extern BzUI *UI; // defined in main.c @@ -28,9 +29,11 @@ void uiSettingsSlider(const char *txt, f32 *value); void uiGameResCount(i32 amount, i32 capacity, Rectangle icon, Texture2D texture); void uiGameRecruit(const char *label, Rectangle rec, Texture2D tex, i32 numRecruiting, - f32 progress, bool canAfford, bool *selected); -void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford, bool *selected); + f32 progress, bool canAfford, bool *selected, bool *hovered); +void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford, bool *selected, bool *hovered); bool uiGameTrade(const char *label, Rectangle rec, Texture2D tex, bool canAfford); bool uiGameUnit(const char *label, i32 count, Rectangle rec, Texture2D tex); +void uiGameTooltipCost(Vector2 pos, i32 costs[RES_COUNT], Texture2D tex); + #endif //PIXELDEFENSE_UI_WIDGETS_H