Consume pop capacity + evade AI boiler plate
This commit is contained in:
@@ -123,6 +123,17 @@ void bzBTDestroyRoot(BzObjectPool *nodePool, BzBTNode *node) {
|
|||||||
|
|
||||||
bzObjectPoolRelease(nodePool, node);
|
bzObjectPoolRelease(nodePool, node);
|
||||||
}
|
}
|
||||||
|
void bzBTSubTree(BzBTNode *tree, BzBTNode *parent) {
|
||||||
|
// Subtree must not have siblings
|
||||||
|
BZ_ASSERT(tree->prev == NULL && tree->next == NULL);
|
||||||
|
if (parent && parent->last) {
|
||||||
|
parent->last->next = tree;
|
||||||
|
parent->last = tree;
|
||||||
|
} else if (parent) {
|
||||||
|
parent->first = tree;
|
||||||
|
parent->last = tree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BzBTNode *bzBTCompSelector(BzObjectPool *nodePool, BzBTNode *parent) {
|
BzBTNode *bzBTCompSelector(BzObjectPool *nodePool, BzBTNode *parent) {
|
||||||
return bzBTNodeMake(nodePool, parent, BZ_BT_COMP_SELECTOR);
|
return bzBTNodeMake(nodePool, parent, BZ_BT_COMP_SELECTOR);
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ BzBTNode *bzBTMakeRoot(BzObjectPool *nodePool);
|
|||||||
*/
|
*/
|
||||||
void bzBTDestroyRoot(BzObjectPool *nodePool, BzBTNode *node);
|
void bzBTDestroyRoot(BzObjectPool *nodePool, BzBTNode *node);
|
||||||
|
|
||||||
|
void bzBTSubTree(BzBTNode *tree, BzBTNode *parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute all children in turn until one fails.
|
* @brief Execute all children in turn until one fails.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -42,6 +42,14 @@ BzBTStatus aiResetElapsed(AIBlackboard *data, f32 dt) {
|
|||||||
data->elapsed = 0.0f;
|
data->elapsed = 0.0f;
|
||||||
return BZ_BT_SUCCESS;
|
return BZ_BT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BzBTStatus aiIsEnemyNearby(AIBlackboard *data, f32 dt) {
|
||||||
|
return BZ_BT_FAIL;
|
||||||
|
}
|
||||||
|
BzBTStatus aiEvadeTarget(AIBlackboard *data, f32 dt) {
|
||||||
|
return BZ_BT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
BzBTStatus aiFindNextHarvestable(AIBlackboard *data, f32 dt) {
|
BzBTStatus aiFindNextHarvestable(AIBlackboard *data, f32 dt) {
|
||||||
ecs_entity_t harvestTarget = data->as.worker.harvestTarget;
|
ecs_entity_t harvestTarget = data->as.worker.harvestTarget;
|
||||||
if (ecs_is_alive(ECS, harvestTarget)) {
|
if (ecs_is_alive(ECS, harvestTarget)) {
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ typedef struct AIBlackboard {
|
|||||||
BzBTStatus aiMoveTo(AIBlackboard *data, f32 dt);
|
BzBTStatus aiMoveTo(AIBlackboard *data, f32 dt);
|
||||||
BzBTStatus aiResetElapsed(AIBlackboard *data, f32 dt);
|
BzBTStatus aiResetElapsed(AIBlackboard *data, f32 dt);
|
||||||
|
|
||||||
|
BzBTStatus aiIsEnemyNearby(AIBlackboard *data, f32 dt);
|
||||||
|
BzBTStatus aiEvadeTarget(AIBlackboard *data, f32 dt);
|
||||||
|
|
||||||
// Worker
|
// Worker
|
||||||
|
|
||||||
BzBTStatus aiFindNextHarvestable(AIBlackboard *data, f32 dt);
|
BzBTStatus aiFindNextHarvestable(AIBlackboard *data, f32 dt);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ ECS_TAG_DECLARE(Selectable);
|
|||||||
ECS_TAG_DECLARE(Selected);
|
ECS_TAG_DECLARE(Selected);
|
||||||
|
|
||||||
ECS_COMPONENT_DECLARE(AddPopCapacity);
|
ECS_COMPONENT_DECLARE(AddPopCapacity);
|
||||||
|
ECS_COMPONENT_DECLARE(ConsumePopCapacity);
|
||||||
ECS_COMPONENT_DECLARE(Worker);
|
ECS_COMPONENT_DECLARE(Worker);
|
||||||
ECS_COMPONENT_DECLARE(Building);
|
ECS_COMPONENT_DECLARE(Building);
|
||||||
ECS_COMPONENT_DECLARE(Unit);
|
ECS_COMPONENT_DECLARE(Unit);
|
||||||
@@ -72,6 +73,7 @@ void initComponentIDs(ecs_world_t *ecs) {
|
|||||||
ECS_TAG_DEFINE(ecs, Selected);
|
ECS_TAG_DEFINE(ecs, Selected);
|
||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, AddPopCapacity);
|
ECS_COMPONENT_DEFINE(ecs, AddPopCapacity);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, ConsumePopCapacity);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Worker);
|
ECS_COMPONENT_DEFINE(ecs, Worker);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Building);
|
ECS_COMPONENT_DEFINE(ecs, Building);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Unit);
|
ECS_COMPONENT_DEFINE(ecs, Unit);
|
||||||
|
|||||||
@@ -170,6 +170,10 @@ typedef struct AddPopCapacity {
|
|||||||
i32 amount;
|
i32 amount;
|
||||||
} AddPopCapacity;
|
} AddPopCapacity;
|
||||||
extern ECS_COMPONENT_DECLARE(AddPopCapacity);
|
extern ECS_COMPONENT_DECLARE(AddPopCapacity);
|
||||||
|
typedef struct ConsumePopCapacity {
|
||||||
|
i32 amount;
|
||||||
|
} ConsumePopCapacity;
|
||||||
|
extern ECS_COMPONENT_DECLARE(ConsumePopCapacity);
|
||||||
|
|
||||||
// Worker can:
|
// Worker can:
|
||||||
// - Harvest
|
// - Harvest
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ ecs_entity_t entityCreateBaseUnit(const Position position, Player player,
|
|||||||
getTextureRect(getEntityTile(type))
|
getTextureRect(getEntityTile(type))
|
||||||
};
|
};
|
||||||
const Size size = {10.0f * region.rec.width / 16.0f, 10.0f * region.rec.height / 16.0f};
|
const Size size = {10.0f * region.rec.width / 16.0f, 10.0f * region.rec.height / 16.0f};
|
||||||
bzLogInfo("%.2f %.2f", size.x, size.y);
|
|
||||||
ecs_entity_t e = entityCreateEmpty();
|
ecs_entity_t e = entityCreateEmpty();
|
||||||
ecs_set_ptr(ECS, e, Position, &position);
|
ecs_set_ptr(ECS, e, Position, &position);
|
||||||
ecs_set_ptr(ECS, e, Size, &size);
|
ecs_set_ptr(ECS, e, Size, &size);
|
||||||
@@ -55,6 +54,7 @@ ecs_entity_t entityCreateBaseUnit(const Position position, Player player,
|
|||||||
.deceleration = 0.1f,
|
.deceleration = 0.1f,
|
||||||
.unitType = type
|
.unitType = type
|
||||||
});
|
});
|
||||||
|
ecs_set(ECS, e, ConsumePopCapacity, {1});
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
game/main.c
22
game/main.c
@@ -167,6 +167,23 @@ bool init(void *userData) {
|
|||||||
// Just a single action for now
|
// Just a single action for now
|
||||||
node = bzBTAction(nodePool, root, (BzBTActionFn) aiMoveTo);
|
node = bzBTAction(nodePool, root, (BzBTActionFn) aiMoveTo);
|
||||||
bzBTNodeSetName(node, "moveTo");
|
bzBTNodeSetName(node, "moveTo");
|
||||||
|
}
|
||||||
|
// evade
|
||||||
|
BzBTNode *evade = NULL;
|
||||||
|
{
|
||||||
|
BzBTNode *node = NULL;
|
||||||
|
evade = bzBTMakeRoot(nodePool);
|
||||||
|
|
||||||
|
BzBTNode *evadeSeq = bzBTCompSequence(nodePool, evade);
|
||||||
|
{
|
||||||
|
node = bzBTAction(nodePool, evadeSeq, (BzBTActionFn) aiIsEnemyNearby);
|
||||||
|
bzBTNodeSetName(node, "enemyNearby");
|
||||||
|
|
||||||
|
node = bzBTAction(nodePool, evadeSeq, (BzBTActionFn) aiEvadeTarget);
|
||||||
|
bzBTNodeSetName(node, "evadeTarget");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// worker harvest
|
// worker harvest
|
||||||
{
|
{
|
||||||
@@ -175,9 +192,10 @@ bool init(void *userData) {
|
|||||||
root = bzBTMakeRoot(nodePool);
|
root = bzBTMakeRoot(nodePool);
|
||||||
game->BTs.workerHarvest = root;
|
game->BTs.workerHarvest = root;
|
||||||
|
|
||||||
//node = bzBTDecorUntilFail(nodePool, root);
|
BzBTNode *pSel = bzBTCompPSelector(nodePool, root);
|
||||||
|
bzBTSubTree(evade, pSel);
|
||||||
|
|
||||||
BzBTNode *collectSeq = bzBTCompSequence(nodePool, root);
|
BzBTNode *collectSeq = bzBTCompSequence(nodePool, pSel);
|
||||||
|
|
||||||
BzBTNode *untilFail = bzBTDecorUntilFail(nodePool, collectSeq);
|
BzBTNode *untilFail = bzBTDecorUntilFail(nodePool, collectSeq);
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,26 @@ void buildingRemovePopCapacity(ecs_iter_t *it) {
|
|||||||
res->popCapacity -= addPop[i].amount;
|
res->popCapacity -= addPop[i].amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void entityConsumePopCapacity(ecs_iter_t *it) {
|
||||||
|
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||||
|
ConsumePopCapacity *pop = ecs_field(it, ConsumePopCapacity, 1);
|
||||||
|
Owner *owner = ecs_field(it, Owner, 2);
|
||||||
|
|
||||||
|
for (i32 i = 0; i < it->count; i++) {
|
||||||
|
PlayerResources *res = &game->playerResources[owner[i].player];
|
||||||
|
res->pop += pop[i].amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void entityUnConsumePopCapacity(ecs_iter_t *it) {
|
||||||
|
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||||
|
ConsumePopCapacity *pop = ecs_field(it, ConsumePopCapacity, 1);
|
||||||
|
Owner *owner = ecs_field(it, Owner, 2);
|
||||||
|
|
||||||
|
for (i32 i = 0; i < it->count; i++) {
|
||||||
|
PlayerResources *res = &game->playerResources[owner[i].player];
|
||||||
|
res->pop -= pop[i].amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void entityUpdateSpatialID(ecs_iter_t *it) {
|
void entityUpdateSpatialID(ecs_iter_t *it) {
|
||||||
Game *game = ecs_singleton_get_mut(ECS, Game);
|
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
ecs_entity_t queryEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag);
|
ecs_entity_t queryEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag);
|
||||||
|
|
||||||
bool selectEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag);
|
bool selectEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag, Player player);
|
||||||
void selectUnits(BzSpatialGrid *entityGrid, Rectangle area);
|
void selectUnits(BzSpatialGrid *entityGrid, Rectangle area, Player player);
|
||||||
|
|
||||||
void addEntityToInspected(ecs_entity_t entity, Game *game);
|
void addEntityToInspected(ecs_entity_t entity, Game *game);
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ void inputPrimaryAction(Game *game, InputState *input) {
|
|||||||
end.y = tmp;
|
end.y = tmp;
|
||||||
}
|
}
|
||||||
input->pickArea = (Rectangle) {start.x, start.y, end.x - start.x, end.y - start.y};
|
input->pickArea = (Rectangle) {start.x, start.y, end.x - start.x, end.y - start.y};
|
||||||
selectUnits(game->entityGrid, input->pickArea);
|
selectUnits(game->entityGrid, input->pickArea, game->player);
|
||||||
}
|
}
|
||||||
i32 selectedCount = ecs_query_entity_count(input->queries.selected);
|
i32 selectedCount = ecs_query_entity_count(input->queries.selected);
|
||||||
if (isInputBtnJustDragged(input, primaryBtn) && selectedCount > 0) {
|
if (isInputBtnJustDragged(input, primaryBtn) && selectedCount > 0) {
|
||||||
@@ -55,11 +55,11 @@ void inputPrimaryAction(Game *game, InputState *input) {
|
|||||||
if (entity) addEntityToInspected(entity, game);
|
if (entity) addEntityToInspected(entity, game);
|
||||||
} else if (isInputBtnJustUp(input, primaryBtn)) {
|
} else if (isInputBtnJustUp(input, primaryBtn)) {
|
||||||
InputType type = input->state;
|
InputType type = input->state;
|
||||||
if (selectEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Unit)))
|
if (selectEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Unit), game->player))
|
||||||
type = INPUT_SELECTED_UNITS;
|
type = INPUT_SELECTED_UNITS;
|
||||||
else if (selectEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Harvestable)))
|
else if (selectEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Harvestable), PLAYER_COUNT))
|
||||||
type = INPUT_SELECTED_OBJECT;
|
type = INPUT_SELECTED_OBJECT;
|
||||||
else if (selectEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Building)))
|
else if (selectEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Building), game->player))
|
||||||
type = INPUT_SELECTED_BUILDING;
|
type = INPUT_SELECTED_BUILDING;
|
||||||
selectedCount = ecs_query_entity_count(input->queries.selected);
|
selectedCount = ecs_query_entity_count(input->queries.selected);
|
||||||
if (selectedCount > 0) {
|
if (selectedCount > 0) {
|
||||||
@@ -232,6 +232,10 @@ void updatePlayerInput() {
|
|||||||
const MouseButton primaryBtn = input->mapping.primaryBtn;
|
const MouseButton primaryBtn = input->mapping.primaryBtn;
|
||||||
const MouseButton secondaryBtn = input->mapping.secondaryBtn;
|
const MouseButton secondaryBtn = input->mapping.secondaryBtn;
|
||||||
|
|
||||||
|
i32 count = ecs_query_entity_count(input->queries.selected);
|
||||||
|
if (count > 0)
|
||||||
|
input->state = INPUT_SELECTED_UNITS;
|
||||||
|
|
||||||
switch (input->state) {
|
switch (input->state) {
|
||||||
case INPUT_NONE: {
|
case INPUT_NONE: {
|
||||||
inputPrimaryAction(game, input);
|
inputPrimaryAction(game, input);
|
||||||
@@ -304,9 +308,7 @@ void drawPlayerInputUIGround() {
|
|||||||
Size *size = ecs_field(&it, Size, 2);
|
Size *size = ecs_field(&it, Size, 2);
|
||||||
for (i32 i = 0; i < it.count; i++) {
|
for (i32 i = 0; i < it.count; i++) {
|
||||||
ecs_entity_t entity = it.entities[i];
|
ecs_entity_t entity = it.entities[i];
|
||||||
f32 radius = size[i].x;
|
f32 radius = BZ_MIN(size[i].x, size[i].y);
|
||||||
if (size[i].y > radius)
|
|
||||||
radius = size[i].y;
|
|
||||||
radius *= 0.5f;
|
radius *= 0.5f;
|
||||||
const f32 lineThickness = 1.0f;
|
const f32 lineThickness = 1.0f;
|
||||||
if (ecs_has(ECS, entity, Building)) {
|
if (ecs_has(ECS, entity, Building)) {
|
||||||
@@ -379,21 +381,29 @@ ecs_entity_t queryEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t
|
|||||||
return closest;
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool selectEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag) {
|
bool selectEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag, Player player) {
|
||||||
ecs_remove_all(ECS, Selected);
|
ecs_remove_all(ECS, Selected);
|
||||||
const ecs_entity_t entity = queryEntity(entityGrid, point, tag);
|
const ecs_entity_t entity = queryEntity(entityGrid, point, tag);
|
||||||
if (entity) {
|
if (!entity) return false;
|
||||||
|
if (player != PLAYER_COUNT) {
|
||||||
|
if (!ecs_has(ECS, entity, Owner)) return false;
|
||||||
|
Owner owner = *ecs_get(ECS, entity, Owner);
|
||||||
|
if (player != owner.player) return false;
|
||||||
|
}
|
||||||
ecs_add(ECS, entity, Selected);
|
ecs_add(ECS, entity, Selected);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void selectUnits(BzSpatialGrid *entityGrid, Rectangle area) {
|
void selectUnits(BzSpatialGrid *entityGrid, Rectangle area, Player player) {
|
||||||
ecs_remove_all(ECS, Selected);
|
ecs_remove_all(ECS, Selected);
|
||||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height);
|
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height);
|
||||||
while (bzSpatialGridQueryNext(&it)) {
|
while (bzSpatialGridQueryNext(&it)) {
|
||||||
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
||||||
|
if (player != PLAYER_COUNT) {
|
||||||
|
if (!ecs_has(ECS, entity, Owner)) continue;
|
||||||
|
Owner owner = *ecs_get(ECS, entity, Owner);
|
||||||
|
if (owner.player != player) continue;
|
||||||
|
}
|
||||||
if (!ecs_has_id(ECS, entity, ecs_id(Unit))) continue;
|
if (!ecs_has_id(ECS, entity, ecs_id(Unit))) continue;
|
||||||
Rectangle bounds;
|
Rectangle bounds;
|
||||||
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ void setupSystems() {
|
|||||||
ECS_OBSERVER(ECS, buildingAddPopCapacity, EcsOnSet, AddPopCapacity, Owner);
|
ECS_OBSERVER(ECS, buildingAddPopCapacity, EcsOnSet, AddPopCapacity, Owner);
|
||||||
ECS_OBSERVER(ECS, buildingRemovePopCapacity, EcsOnRemove, AddPopCapacity, Owner);
|
ECS_OBSERVER(ECS, buildingRemovePopCapacity, EcsOnRemove, AddPopCapacity, Owner);
|
||||||
|
|
||||||
|
ECS_OBSERVER(ECS, entityConsumePopCapacity, EcsOnSet, ConsumePopCapacity, Owner);
|
||||||
|
ECS_OBSERVER(ECS, entityUnConsumePopCapacity, EcsOnRemove, ConsumePopCapacity, Owner);
|
||||||
|
|
||||||
ECS_SYSTEM(ECS, entityUpdateSpatialID, EcsOnUpdate, Position, Size, Velocity, SpatialGridID);
|
ECS_SYSTEM(ECS, entityUpdateSpatialID, EcsOnUpdate, Position, Size, Velocity, SpatialGridID);
|
||||||
ECS_SYSTEM(ECS, entityUpdateKinematic, EcsOnUpdate, Position, Velocity, Steering, Unit);
|
ECS_SYSTEM(ECS, entityUpdateKinematic, EcsOnUpdate, Position, Velocity, Steering, Unit);
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,19 @@ void buildingAddPopCapacity(ecs_iter_t *it);
|
|||||||
*/
|
*/
|
||||||
void buildingRemovePopCapacity(ecs_iter_t *it);
|
void buildingRemovePopCapacity(ecs_iter_t *it);
|
||||||
|
|
||||||
|
/* Observer (for consuming pop capacity)
|
||||||
|
* 0: Game (singleton)
|
||||||
|
* 1: ConsumePopCapacity
|
||||||
|
* 2: Owner
|
||||||
|
*/
|
||||||
|
void entityConsumePopCapacity(ecs_iter_t *it);
|
||||||
|
/* Observer (for unconsuming pop capacity)
|
||||||
|
* 0: Game (singleton)
|
||||||
|
* 1: ConsumePopCapacity
|
||||||
|
* 2: Owner
|
||||||
|
*/
|
||||||
|
void entityUnConsumePopCapacity(ecs_iter_t *it);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0: Game (singleton) for entity map
|
* 0: Game (singleton) for entity map
|
||||||
* 1: Position
|
* 1: Position
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ BzUINode *uiPushDivParentPercentage(f32 xPercent, f32 yPercent) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiBaseLabel(const char *txt, Font font, f32 scl) {
|
void uiBaseLabel(const char *txt, Font font, f32 scl, Color color) {
|
||||||
BzUINode *node = bzUINodeMake(UI, bzUIKeyFromString(txt), &(BzUINodeDesc) {
|
BzUINode *node = bzUINodeMake(UI, bzUIKeyFromString(txt), &(BzUINodeDesc) {
|
||||||
.flags = BZ_UI_DRAW_TEXT | BZ_UI_DRAW_TEXT_SHADOW | BZ_UI_ALIGN_CENTER,
|
.flags = BZ_UI_DRAW_TEXT | BZ_UI_DRAW_TEXT_SHADOW | BZ_UI_ALIGN_CENTER,
|
||||||
.semanticSize[BZ_UI_AXIS_X] = {
|
.semanticSize[BZ_UI_AXIS_X] = {
|
||||||
@@ -45,9 +45,9 @@ void uiBaseLabel(const char *txt, Font font, f32 scl) {
|
|||||||
.font = font,
|
.font = font,
|
||||||
.fontSpacing = 2 * uiGetScale() * scl,
|
.fontSpacing = 2 * uiGetScale() * scl,
|
||||||
.fontSize = 62 * uiGetScale() * scl,
|
.fontSize = 62 * uiGetScale() * scl,
|
||||||
.normal = WHITE,
|
.normal = color,
|
||||||
.hover = WHITE,
|
.hover = color,
|
||||||
.active = WHITE,
|
.active = color,
|
||||||
});
|
});
|
||||||
bzUISetTextShadowStyle(UI, node, (BzUITextShadowStyle) {
|
bzUISetTextShadowStyle(UI, node, (BzUITextShadowStyle) {
|
||||||
.offset[BZ_UI_AXIS_X] = 2 * uiGetScale() * scl,
|
.offset[BZ_UI_AXIS_X] = 2 * uiGetScale() * scl,
|
||||||
@@ -158,7 +158,7 @@ void uiBaseSlider(const char *txt, Font font, f32 scl, f32 *value, f32 min, f32
|
|||||||
BZ_UI_FLEX_DIR_ROW | BZ_UI_FLEX_ALIGN_CENTER | BZ_UI_FLEX_JUSTIFY_SPACE_BETWEEN
|
BZ_UI_FLEX_DIR_ROW | BZ_UI_FLEX_ALIGN_CENTER | BZ_UI_FLEX_JUSTIFY_SPACE_BETWEEN
|
||||||
});
|
});
|
||||||
|
|
||||||
uiBaseLabel(txt, font, 0.6 * scl);
|
uiBaseLabel(txt, font, 0.6 * scl, WHITE);
|
||||||
|
|
||||||
bzUIPushDiv(UI, (BzUISize) {BZ_UI_SIZE_CHILD_SUM}, (BzUISize) { BZ_UI_SIZE_CHILD_MAX});
|
bzUIPushDiv(UI, (BzUISize) {BZ_UI_SIZE_CHILD_SUM}, (BzUISize) { BZ_UI_SIZE_CHILD_MAX});
|
||||||
bzUISetParentLayout(UI, (BzUILayout) {
|
bzUISetParentLayout(UI, (BzUILayout) {
|
||||||
@@ -173,7 +173,7 @@ void uiBaseSlider(const char *txt, Font font, f32 scl, f32 *value, f32 min, f32
|
|||||||
*value = BZ_MAX(*value, min);
|
*value = BZ_MAX(*value, min);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%2.0f##%s", *value, txt);
|
snprintf(buf, sizeof(buf), "%2.0f##%s", *value, txt);
|
||||||
uiBaseLabel(buf, font, 0.6 * scl);
|
uiBaseLabel(buf, font, 0.6 * scl, WHITE);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "+##%s", txt);
|
snprintf(buf, sizeof(buf), "+##%s", txt);
|
||||||
if (uiBaseTextButton(buf, font, 0.6 * scl))
|
if (uiBaseTextButton(buf, font, 0.6 * scl))
|
||||||
@@ -185,7 +185,7 @@ void uiBaseSlider(const char *txt, Font font, f32 scl, f32 *value, f32 min, f32
|
|||||||
}
|
}
|
||||||
|
|
||||||
void uiMainMenuLabel(const char *txt) {
|
void uiMainMenuLabel(const char *txt) {
|
||||||
uiBaseLabel(txt, getFont(), 1.8f);
|
uiBaseLabel(txt, getFont(), 1.8f, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uiMainMenuButton(const char *txt) {
|
bool uiMainMenuButton(const char *txt) {
|
||||||
@@ -193,7 +193,7 @@ bool uiMainMenuButton(const char *txt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void uiSettingsLabel(const char *txt) {
|
void uiSettingsLabel(const char *txt) {
|
||||||
uiBaseLabel(txt, getFont(), 0.8f);
|
uiBaseLabel(txt, getFont(), 0.8f, WHITE);
|
||||||
}
|
}
|
||||||
bool uiSettingsButton(const char *txt) {
|
bool uiSettingsButton(const char *txt) {
|
||||||
return uiBaseTextButton(txt, getFont(), 0.7f);
|
return uiBaseTextButton(txt, getFont(), 0.7f);
|
||||||
@@ -219,7 +219,10 @@ void uiGameResCount(i32 amount, i32 capacity, Rectangle icon, Texture2D texture)
|
|||||||
else
|
else
|
||||||
snprintf(buf, sizeof(buf), "%d/%d##%d", amount, capacity, id);
|
snprintf(buf, sizeof(buf), "%d/%d##%d", amount, capacity, id);
|
||||||
const f32 scl = 0.4f;
|
const f32 scl = 0.4f;
|
||||||
uiBaseLabel(buf, getFont(), scl);
|
Color color = WHITE;
|
||||||
|
if (capacity != -1 && amount >= capacity)
|
||||||
|
color = RED;
|
||||||
|
uiBaseLabel(buf, getFont(), scl, color);
|
||||||
|
|
||||||
BzUINode *iconNode = bzUINodeMake(UI, id, &(BzUINodeDesc) {
|
BzUINode *iconNode = bzUINodeMake(UI, id, &(BzUINodeDesc) {
|
||||||
.flags = BZ_UI_DRAW_SPRITE | BZ_UI_ALIGN_CENTER,
|
.flags = BZ_UI_DRAW_SPRITE | BZ_UI_ALIGN_CENTER,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ f32 uiGetScale();
|
|||||||
BzUINode *uiPushDivParentPercentage(f32 xPercent, f32 yPercent);
|
BzUINode *uiPushDivParentPercentage(f32 xPercent, f32 yPercent);
|
||||||
|
|
||||||
// Template stuff
|
// Template stuff
|
||||||
void uiBaseLabel(const char *txt, Font font, f32 scl);
|
void uiBaseLabel(const char *txt, Font font, f32 scl, Color color);
|
||||||
bool uiBaseTextButton(const char *txt, Font font, f32 scl);
|
bool uiBaseTextButton(const char *txt, Font font, f32 scl);
|
||||||
void uiBaseCheckbox(const char *txt, Font font, f32 scl, bool *check);
|
void uiBaseCheckbox(const char *txt, Font font, f32 scl, bool *check);
|
||||||
void uiBaseSlider(const char *txt, Font font, f32 scl, f32 *value, f32 min, f32 max);
|
void uiBaseSlider(const char *txt, Font font, f32 scl, f32 *value, f32 min, f32 max);
|
||||||
|
|||||||
Reference in New Issue
Block a user