126 lines
3.5 KiB
C
126 lines
3.5 KiB
C
#define BZ_ENTRYPOINT
|
|
#include <breeze.h>
|
|
|
|
BzObjectPool *nodePool = NULL;
|
|
BzObjectPool *nodeStatePool = NULL;
|
|
|
|
BzAIBTNode *printBT = NULL;
|
|
BzAIBTState agentState;
|
|
|
|
BzAIBTStatus printAction(void *data) {
|
|
bzLogInfo("Hello, world!");
|
|
return BZ_AIBT_SUCCESS;
|
|
}
|
|
|
|
bool init(int *game) {
|
|
rlImGuiSetup(true);
|
|
nodePool = bzObjectPoolCreate(&(BzObjectPoolDesc) {
|
|
.objectSize = bzAIBTGetNodeSize(),
|
|
});
|
|
nodeStatePool = bzObjectPoolCreate(&(BzObjectPoolDesc) {
|
|
.objectSize = bzAIBTGetNodeStateSize()
|
|
});
|
|
|
|
// for 1..5:
|
|
// seq
|
|
// delay 1s
|
|
// print "Hello, world!"
|
|
printBT = bzAIBTMakeRoot(nodePool);
|
|
BzAIBTNode *node = bzAIBTDecorRepeat(nodePool, printBT, 5);
|
|
|
|
BzAIBTNode *seq = bzAIBTCompSequence(nodePool, node, false);
|
|
|
|
bzAIBTDecorDelay(nodePool, seq, 1.0f);
|
|
bzAIBTAction(nodePool, seq, printAction, "printAction");
|
|
|
|
agentState = bzAIBTCreateState(&(BzAIBTStateDesc) {
|
|
.root = printBT,
|
|
.pool = nodeStatePool,
|
|
.userData = NULL
|
|
});
|
|
|
|
return true;
|
|
}
|
|
void deinit(int *game) {
|
|
|
|
bzObjectPoolDestroy(nodePool);
|
|
bzObjectPoolDestroy(nodeStatePool);
|
|
}
|
|
|
|
void igRenderBTNode(const BzAIBTNode *node, const BzAIBTNodeState *state, i32 depth) {
|
|
const BzAIBTNode *child = bzAIBTNodeChild(node);
|
|
BzAIBTNodeType type = bzAIBTGetNodeType(node);
|
|
char extraInfo[128];
|
|
extraInfo[0] = '\0';
|
|
|
|
bool hasState = bzAIBTNodeMatchesState(node, state);
|
|
|
|
switch (type) {
|
|
case BZ_AIBT_DECOR_REPEAT:
|
|
if (hasState) {
|
|
snprintf(extraInfo, sizeof(extraInfo), "(%d < %d)",
|
|
bzAIBTRepeatStateGetIter(state),
|
|
bzAIBTDecorGetRepeat(node));
|
|
} else {
|
|
snprintf(extraInfo, sizeof(extraInfo), "(%d)", bzAIBTDecorGetRepeat(node));
|
|
}
|
|
break;
|
|
case BZ_AIBT_DECOR_DELAY:
|
|
if (hasState) {
|
|
snprintf(extraInfo, sizeof(extraInfo), "(%.2f < %.2fms)",
|
|
bzAIBTDelayStateGetElapsed(state),
|
|
bzAIBTDecorGetDelay(node));
|
|
} else {
|
|
snprintf(extraInfo, sizeof(extraInfo), "(%.2fms)", bzAIBTDecorGetDelay(node));
|
|
}
|
|
break;
|
|
case BZ_AIBT_ACTION:
|
|
snprintf(extraInfo, sizeof(extraInfo), "(%s:%p)",
|
|
bzAIBTActionGetName(node),
|
|
bzAIBTActionGetFn(node));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (hasState)
|
|
state = bzAIBTNodeStateNext(state);
|
|
|
|
ImVec4 color = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
if (hasState)
|
|
color = (ImVec4) {1.0f, 1.0f, 0.5f, 1.0f};
|
|
|
|
igTextColored(color, "%*s%s %s", depth * 2, "",
|
|
bzAIBTNodeTypeToStr(type), extraInfo);
|
|
while (child) {
|
|
igRenderBTNode(child, state, depth + 1);
|
|
child = bzAIBTNodeNext(child);
|
|
}
|
|
}
|
|
|
|
void igRenderBT(BzAIBTState *state) {
|
|
const BzAIBTNode *root = state->root;
|
|
if (igBegin("BehaviourTree", NULL, 0)) {
|
|
igRenderBTNode(root, state->first, 0);
|
|
}
|
|
igEnd();
|
|
}
|
|
|
|
void render(float dt, int *game) {
|
|
ClearBackground(WHITE);
|
|
|
|
BzAIBTStatus status = bzAIBTExecute(&agentState, dt);
|
|
|
|
rlImGuiBegin();
|
|
igRenderBT(&agentState);
|
|
igShowDemoWindow(NULL);
|
|
rlImGuiEnd();
|
|
}
|
|
|
|
bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) {
|
|
appDesc->init = (BzAppInitFunc) init;
|
|
appDesc->deinit = (BzAppDeinitFunc ) deinit;
|
|
appDesc->render = (BzAppRenderFunc) render;
|
|
|
|
return true;
|
|
}
|