This commit is contained in:
saarsena@gmail.com 2026-04-16 21:04:50 -04:00
commit e45f121fb9
89 changed files with 336069 additions and 0 deletions

132
godot/src/grid_to_dict.cpp Normal file
View file

@ -0,0 +1,132 @@
#include "grid_to_dict.h"
#include <godot_cpp/variant/packed_byte_array.hpp>
#include <godot_cpp/variant/packed_int32_array.hpp>
#include <godot_cpp/variant/array.hpp>
#include <godot_cpp/variant/typed_array.hpp>
using namespace godot;
static void build_rooms_and_machines(grid_t g, Array &rooms, Array &machines) {
/* Bucket cells by room_id and machine_id. room_id and machine_id are 1..255. */
struct Bucket { TypedArray<Vector2i> cells; Vector2i gate = Vector2i(-1, -1); };
Bucket rbuckets[256];
Bucket mbuckets[256];
/* Also collect marker-per-cell for each machine. */
Dictionary mmarkers[256];
for (int y = 0; y < DROWS; y++) {
for (int x = 0; x < DCOLS; x++) {
const cell_t *c = &g[y][x];
Vector2i p(x, y);
if (c->room_id > 0) {
rbuckets[c->room_id].cells.push_back(p);
}
if (c->machine_id > 0) {
mbuckets[c->machine_id].cells.push_back(p);
if (c->flags & F_MACHINE_GATE) {
mbuckets[c->machine_id].gate = p;
}
if (c->surface != MK_NONE) {
Dictionary &mk = mmarkers[c->machine_id];
int key = (int)c->surface;
TypedArray<Vector2i> list;
if (mk.has(key)) {
list = (TypedArray<Vector2i>)(Variant)mk[key];
}
list.push_back(p);
mk[key] = list;
}
}
}
}
for (int i = 1; i < 256; i++) {
if (rbuckets[i].cells.size() == 0) continue;
Dictionary d;
d["id"] = i;
d["cells"] = rbuckets[i].cells;
rooms.push_back(d);
}
for (int i = 1; i < 256; i++) {
if (mbuckets[i].cells.size() == 0) continue;
Dictionary d;
d["id"] = i;
d["interior_cells"] = mbuckets[i].cells;
d["gate"] = mbuckets[i].gate;
d["markers"] = mmarkers[i];
machines.push_back(d);
}
}
Dictionary godot::grid_to_dictionary(grid_t g, int seed, int depth, bool add_metadata) {
const int N = DCOLS * DROWS;
PackedByteArray terrain; terrain.resize(N);
PackedByteArray liquid; liquid.resize(N);
PackedByteArray room_id; room_id.resize(N);
PackedByteArray machine_id; machine_id.resize(N);
PackedByteArray surface; surface.resize(N);
PackedInt32Array flags; flags.resize(N);
uint8_t *t = terrain.ptrw();
uint8_t *lq = liquid.ptrw();
uint8_t *ri = room_id.ptrw();
uint8_t *mi = machine_id.ptrw();
uint8_t *sf = surface.ptrw();
int32_t *fl = flags.ptrw();
Vector2i stairs_up(-1, -1), stairs_down(-1, -1);
int i = 0;
for (int y = 0; y < DROWS; y++) {
for (int x = 0; x < DCOLS; x++, i++) {
const cell_t *c = &g[y][x];
t[i] = c->terrain;
lq[i] = c->liquid;
ri[i] = c->room_id;
mi[i] = c->machine_id;
sf[i] = c->surface;
fl[i] = (int32_t)c->flags;
if (c->terrain == T_STAIRS_UP) stairs_up = Vector2i(x, y);
if (c->terrain == T_STAIRS_DOWN) stairs_down = Vector2i(x, y);
}
}
Dictionary d;
d["seed"] = seed;
d["depth"] = depth;
d["width"] = DCOLS;
d["height"] = DROWS;
d["terrain"] = terrain;
d["liquid"] = liquid;
d["flags"] = flags;
d["room_id"] = room_id;
d["machine_id"] = machine_id;
d["surface"] = surface;
d["stairs_up"] = stairs_up;
d["stairs_down"] = stairs_down;
if (add_metadata) {
Array rooms;
Array machines;
build_rooms_and_machines(g, rooms, machines);
d["rooms"] = rooms;
d["machines"] = machines;
}
return d;
}
Dictionary godot::cell_to_dictionary(grid_t g, int x, int y) {
Dictionary d;
if (!grid_in_bounds(x, y)) return d;
const cell_t *c = &g[y][x];
d["x"] = x;
d["y"] = y;
d["terrain"] = (int)c->terrain;
d["liquid"] = (int)c->liquid;
d["surface"] = (int)c->surface;
d["flags"] = (int)c->flags;
d["room_id"] = (int)c->room_id;
d["machine_id"] = (int)c->machine_id;
return d;
}