Convert UIGrid perspective from index to weak_ptr<UIEntity>

Major refactor of the perspective system to use entity references instead of indices:

- Replaced `int perspective` with `std::weak_ptr<UIEntity> perspective_entity`
- Added `bool perspective_enabled` flag for explicit control
- Direct entity assignment: `grid.perspective = player`
- Automatic cleanup when entity is destroyed (weak_ptr becomes invalid)
- No issues with collection reordering or entity removal
- PythonObjectCache integration preserves Python derived classes

API changes:
- Old: `grid.perspective = 0` (index), `-1` for omniscient
- New: `grid.perspective = entity` (object), `None` to clear
- New: `grid.perspective_enabled` controls rendering mode

Three rendering states:
1. `perspective_enabled = False`: Omniscient view (default)
2. `perspective_enabled = True` with valid entity: Entity's FOV
3. `perspective_enabled = True` with invalid entity: All black

Also includes:
- Part 3: Procedural dungeon generation with libtcod.line()
- Part 4: Field of view with entity perspective switching

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
John McCardle 2025-07-21 23:47:21 -04:00
commit b5eab85e70
4 changed files with 792 additions and 63 deletions

View file

@ -77,8 +77,9 @@ public:
// Background rendering
sf::Color fill_color;
// Perspective system - which entity's view to render (-1 = omniscient/default)
int perspective;
// Perspective system - entity whose view to render
std::weak_ptr<UIEntity> perspective_entity; // Weak reference to perspective entity
bool perspective_enabled; // Whether to use perspective rendering
// Property system for animations
bool setProperty(const std::string& name, float value) override;
@ -103,6 +104,8 @@ public:
static int set_fill_color(PyUIGridObject* self, PyObject* value, void* closure);
static PyObject* get_perspective(PyUIGridObject* self, void* closure);
static int set_perspective(PyUIGridObject* self, PyObject* value, void* closure);
static PyObject* get_perspective_enabled(PyUIGridObject* self, void* closure);
static int set_perspective_enabled(PyUIGridObject* self, PyObject* value, void* closure);
static PyObject* py_at(PyUIGridObject* self, PyObject* args, PyObject* kwds);
static PyObject* py_compute_fov(PyUIGridObject* self, PyObject* args, PyObject* kwds);
static PyObject* py_is_in_fov(PyUIGridObject* self, PyObject* args);