feat: Migrate Grid to user-driven layer rendering (closes #150)

- Add `layers` dict parameter to Grid constructor for explicit layer definitions
  - `layers={"ground": "color", "terrain": "tile"}` creates named layers
  - `layers={}` creates empty grid (entities + pathfinding only)
  - Default creates single TileLayer named "tilesprite" for backward compat

- Implement dynamic GridPoint property access via layer names
  - `grid.at(x,y).layer_name = value` routes to corresponding layer
  - Protected names (walkable, transparent, etc.) still use GridPoint

- Remove base layer rendering from UIGrid::render()
  - Layers are now the sole source of grid rendering
  - Old chunk_manager remains for GridPoint data access
  - FOV overlay unchanged

- Update test to use explicit `layers={}` parameter

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
John McCardle 2025-11-28 23:04:09 -05:00
commit a258613faa
6 changed files with 200 additions and 87 deletions

View file

@ -52,6 +52,10 @@ public:
static PyObject* get_bool_member(PyUIGridPointObject* self, void* closure);
static int set_color(PyUIGridPointObject* self, PyObject* value, void* closure);
static PyObject* repr(PyUIGridPointObject* self);
// #150 - Dynamic property access for named layers
static PyObject* getattro(PyUIGridPointObject* self, PyObject* name);
static int setattro(PyUIGridPointObject* self, PyObject* name, PyObject* value);
};
// UIGridPointState - entity-specific info for each cell
@ -73,6 +77,9 @@ namespace mcrfpydef {
.tp_basicsize = sizeof(PyUIGridPointObject),
.tp_itemsize = 0,
.tp_repr = (reprfunc)UIGridPoint::repr,
// #150 - Dynamic attribute access for named layers
.tp_getattro = (getattrofunc)UIGridPoint::getattro,
.tp_setattro = (setattrofunc)UIGridPoint::setattro,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = "UIGridPoint object",
.tp_getset = UIGridPoint::getsetters,