feat: implemented dice rolling
This commit is contained in:
parent
ddf9936f58
commit
ae334c395a
|
|
@ -1,15 +1,22 @@
|
||||||
#include "dice_data.h"
|
#include "dice_data.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace active_dice {
|
namespace active_dice {
|
||||||
|
struct DieState {
|
||||||
|
Die type;
|
||||||
|
uint8_t value;
|
||||||
|
};
|
||||||
constexpr size_t maxActiveDice{16};
|
constexpr size_t maxActiveDice{16};
|
||||||
Die activeDice[maxActiveDice];
|
DieState activeDice[maxActiveDice];
|
||||||
size_t numActiveDice{0};
|
size_t numActiveDice{0};
|
||||||
|
|
||||||
void Add(Die die) {
|
void Add(Die die) {
|
||||||
if(numActiveDice < maxActiveDice) {
|
if(numActiveDice < maxActiveDice) {
|
||||||
activeDice[numActiveDice] = die;
|
activeDice[numActiveDice].type = die;
|
||||||
|
activeDice[numActiveDice].value = RollDie(die);
|
||||||
++numActiveDice;
|
++numActiveDice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,18 +26,37 @@ void Remove(size_t at) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(at < numActiveDice - 1) {
|
if(at < numActiveDice - 1) {
|
||||||
std::memmove(activeDice + at, activeDice + at + 1, numActiveDice - at);
|
std::memmove(activeDice + at, activeDice + at + 1, sizeof(DieState) * (numActiveDice - at));
|
||||||
}
|
}
|
||||||
--numActiveDice;
|
--numActiveDice;
|
||||||
}
|
}
|
||||||
|
|
||||||
Die Get(size_t at) {
|
Die Get(size_t at) {
|
||||||
if(at < numActiveDice) {
|
if(at < numActiveDice) {
|
||||||
return activeDice[at];
|
return activeDice[at].type;
|
||||||
} else return D_COIN;
|
} else return D_COIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t GetValue(size_t at) {
|
||||||
|
if(at < numActiveDice) {
|
||||||
|
return activeDice[at].value;
|
||||||
|
} else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t Count() {
|
size_t Count() {
|
||||||
return numActiveDice;
|
return numActiveDice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReRoll() {
|
||||||
|
for(size_t i{0}; i < numActiveDice; ++i) {
|
||||||
|
activeDice[i].value = RollDie(activeDice[i].type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t RollDie(Die die) {
|
||||||
|
if(die == D_COIN) {
|
||||||
|
return std::rand() % 2;
|
||||||
|
}
|
||||||
|
return 1 + std::rand() % (die-1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
enum Die {
|
enum Die {
|
||||||
D_COIN = 2,
|
D_COIN = 2,
|
||||||
|
|
@ -42,5 +43,9 @@ namespace active_dice {
|
||||||
void Add(Die die);
|
void Add(Die die);
|
||||||
void Remove(size_t at);
|
void Remove(size_t at);
|
||||||
Die Get(size_t at);
|
Die Get(size_t at);
|
||||||
|
uint8_t GetValue(size_t at);
|
||||||
size_t Count();
|
size_t Count();
|
||||||
|
void ReRoll();
|
||||||
} // namespace active_dice
|
} // namespace active_dice
|
||||||
|
|
||||||
|
uint8_t RollDie(Die die);
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@
|
||||||
#include "SDL3/SDL_render.h"
|
#include "SDL3/SDL_render.h"
|
||||||
#include "ceramic/style.h"
|
#include "ceramic/style.h"
|
||||||
#include "dice_data.h"
|
#include "dice_data.h"
|
||||||
|
#include "renderer/ui_data.h"
|
||||||
#include <ceramic/elements.h>
|
#include <ceramic/elements.h>
|
||||||
#include <ceramic/resources.h>
|
#include <ceramic/resources.h>
|
||||||
#include <clay/clay.h>
|
#include <clay/clay.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
extern SDL_Renderer *renderer;
|
extern SDL_Renderer *renderer;
|
||||||
|
|
||||||
|
|
@ -30,6 +32,16 @@ char const *dieImagePaths[8]{
|
||||||
"assets/icons/d20.svg",
|
"assets/icons/d20.svg",
|
||||||
"assets/icons/d10.svg",
|
"assets/icons/d10.svg",
|
||||||
};
|
};
|
||||||
|
Clay_String const dieUiStrings[8] {
|
||||||
|
CLAY_STRING("C"),
|
||||||
|
CLAY_STRING("4"),
|
||||||
|
CLAY_STRING("6"),
|
||||||
|
CLAY_STRING("8"),
|
||||||
|
CLAY_STRING("10"),
|
||||||
|
CLAY_STRING("12"),
|
||||||
|
CLAY_STRING("20"),
|
||||||
|
CLAY_STRING("100")
|
||||||
|
};
|
||||||
|
|
||||||
static void LoadDieImagesIfNeeded() {
|
static void LoadDieImagesIfNeeded() {
|
||||||
static bool diceImagesLoaded{false};
|
static bool diceImagesLoaded{false};
|
||||||
|
|
@ -47,22 +59,89 @@ static void LoadDieImagesIfNeeded() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnDieButtonHovered(Clay_ElementId element, Clay_PointerData pointer, intptr_t data) {
|
|
||||||
|
static void DieButton(Die die, int32_t showNumber, Clay_Sizing size, cera::OnHoveredFn onHover, intptr_t data) {
|
||||||
|
size_t const index{DieToIndex(die)};
|
||||||
|
char resultStr[6]="";
|
||||||
|
int32_t len = SDL_snprintf(resultStr, 6, "%d", showNumber);
|
||||||
|
Clay_String string = UiData_StoreString(resultStr, len);
|
||||||
|
CLAY_AUTO_ID({
|
||||||
|
.layout = {
|
||||||
|
.sizing = {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)},
|
||||||
|
.childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}
|
||||||
|
},
|
||||||
|
.image = {.imageData = Clay_Hovered() ? hoveredDieImages[index] : dieImages[index]}
|
||||||
|
}) {
|
||||||
|
Clay_OnHover(onHover, data);
|
||||||
|
cera::Header(string, 2, {
|
||||||
|
.textColor = cera::color::white
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddDieButtonHovered(Clay_ElementId element, Clay_PointerData pointer, intptr_t data) {
|
||||||
if(pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
|
if(pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
|
||||||
active_dice::Add((Die)data);
|
active_dice::Add((Die)data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ActiveDieButtonHovered(Clay_ElementId element, Clay_PointerData pointer, intptr_t data) {
|
||||||
|
if(pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
|
||||||
|
active_dice::Remove((size_t)data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DiceContainer() {
|
void DiceContainer() {
|
||||||
LoadDieImagesIfNeeded();
|
LoadDieImagesIfNeeded();
|
||||||
CLAY(CLAY_ID("DiceSelector"), {}) {
|
|
||||||
cera::ImageTextButton(dieImages[0], CLAY_STRING("C"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D_COIN);
|
Clay_Sizing const addDieButtonSize{CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)};
|
||||||
cera::ImageTextButton(dieImages[1], CLAY_STRING("4"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D4);
|
CLAY(CLAY_ID("DiceSelector"), cera::PanelContainer({
|
||||||
cera::ImageTextButton(dieImages[2], CLAY_STRING("6"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D6);
|
.layout={
|
||||||
cera::ImageTextButton(dieImages[3], CLAY_STRING("8"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D8);
|
.sizing={CLAY_SIZING_FIT(), CLAY_SIZING_GROW()},
|
||||||
cera::ImageTextButton(dieImages[4], CLAY_STRING("10"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D10);
|
.childAlignment{CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}
|
||||||
cera::ImageTextButton(dieImages[5], CLAY_STRING("12"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D12);
|
},
|
||||||
cera::ImageTextButton(dieImages[6], CLAY_STRING("20"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D20);
|
})) {
|
||||||
cera::ImageTextButton(dieImages[7], CLAY_STRING("100"), {CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100)}, &OnDieButtonHovered, (intptr_t)D100);
|
CLAY_AUTO_ID({
|
||||||
|
.layout = {
|
||||||
|
.sizing = {CLAY_SIZING_FIT(), CLAY_SIZING_FIT()},
|
||||||
|
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||||
|
},
|
||||||
|
.clip = {
|
||||||
|
.horizontal = false,
|
||||||
|
.vertical = true,
|
||||||
|
.childOffset = Clay_GetScrollOffset(),
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
DieButton(D4, D4, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D4);
|
||||||
|
DieButton(D6, D6, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D6);
|
||||||
|
DieButton(D8, D8, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D8);
|
||||||
|
DieButton(D10, D10, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D10);
|
||||||
|
DieButton(D12, D12, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D12);
|
||||||
|
DieButton(D20, D20, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D20);
|
||||||
|
DieButton(D100, D100, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D100);
|
||||||
|
DieButton(D_COIN, D_COIN, addDieButtonSize, &AddDieButtonHovered, (intptr_t)D_COIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Clay_Sizing const activeDieButtonSize{CLAY_SIZING_FIXED(200), CLAY_SIZING_FIXED(200)};
|
||||||
|
CLAY(CLAY_ID("DiceActive"), cera::PanelContainer({
|
||||||
|
.layout={
|
||||||
|
.sizing={CLAY_SIZING_GROW(), CLAY_SIZING_GROW()},
|
||||||
|
.childAlignment={CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}
|
||||||
|
}
|
||||||
|
})) {
|
||||||
|
CLAY_AUTO_ID({
|
||||||
|
.layout = {
|
||||||
|
.sizing = {CLAY_SIZING_FIT(), CLAY_SIZING_FIT()},
|
||||||
|
},
|
||||||
|
.clip = {
|
||||||
|
.horizontal = true,
|
||||||
|
.vertical = false,
|
||||||
|
.childOffset = Clay_GetScrollOffset(),
|
||||||
|
},
|
||||||
|
}) {
|
||||||
|
for(size_t i{0}; i < active_dice::Count(); ++i) {
|
||||||
|
DieButton(active_dice::Get(i), active_dice::GetValue(i), activeDieButtonSize, &ActiveDieButtonHovered, (intptr_t)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
vendor/ceramic
vendored
2
vendor/ceramic
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit 762d165cd14f0d4423c2de6f7f1659f7b36a4fd3
|
Subproject commit 2dcdcd394c5b0c7e4875f965dfe789d3c71ad217
|
||||||
Loading…
Reference in a new issue