152 lines
5.8 KiB
C
152 lines
5.8 KiB
C
|
|
#pragma once
|
||
|
|
#include "Common.h"
|
||
|
|
#include "Python.h"
|
||
|
|
#include "UIBase.h" // For PyUIGridObject typedef
|
||
|
|
#include <libtcod.h>
|
||
|
|
#include <SFML/System/Vector2.hpp>
|
||
|
|
#include <vector>
|
||
|
|
#include <memory>
|
||
|
|
#include <map>
|
||
|
|
|
||
|
|
// Forward declarations
|
||
|
|
class UIGrid;
|
||
|
|
|
||
|
|
//=============================================================================
|
||
|
|
// AStarPath - A computed A* path result, consumed like an iterator
|
||
|
|
//=============================================================================
|
||
|
|
|
||
|
|
struct PyAStarPathObject {
|
||
|
|
PyObject_HEAD
|
||
|
|
std::vector<sf::Vector2i> path; // Pre-computed path positions
|
||
|
|
size_t current_index; // Next step to return
|
||
|
|
sf::Vector2i origin; // Fixed at creation
|
||
|
|
sf::Vector2i destination; // Fixed at creation
|
||
|
|
};
|
||
|
|
|
||
|
|
//=============================================================================
|
||
|
|
// DijkstraMap - A Dijkstra distance field from a fixed root
|
||
|
|
//=============================================================================
|
||
|
|
|
||
|
|
class DijkstraMap {
|
||
|
|
public:
|
||
|
|
DijkstraMap(TCODMap* map, int root_x, int root_y, float diagonal_cost);
|
||
|
|
~DijkstraMap();
|
||
|
|
|
||
|
|
// Non-copyable (owns TCODDijkstra)
|
||
|
|
DijkstraMap(const DijkstraMap&) = delete;
|
||
|
|
DijkstraMap& operator=(const DijkstraMap&) = delete;
|
||
|
|
|
||
|
|
// Queries
|
||
|
|
float getDistance(int x, int y) const;
|
||
|
|
std::vector<sf::Vector2i> getPathFrom(int x, int y) const;
|
||
|
|
sf::Vector2i stepFrom(int x, int y, bool* valid = nullptr) const;
|
||
|
|
|
||
|
|
// Accessors
|
||
|
|
sf::Vector2i getRoot() const { return root; }
|
||
|
|
float getDiagonalCost() const { return diagonal_cost; }
|
||
|
|
|
||
|
|
private:
|
||
|
|
TCODDijkstra* tcod_dijkstra; // Owned by this object
|
||
|
|
TCODMap* tcod_map; // Borrowed from Grid
|
||
|
|
sf::Vector2i root;
|
||
|
|
float diagonal_cost;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct PyDijkstraMapObject {
|
||
|
|
PyObject_HEAD
|
||
|
|
std::shared_ptr<DijkstraMap> data; // Shared with Grid's collection
|
||
|
|
};
|
||
|
|
|
||
|
|
//=============================================================================
|
||
|
|
// Helper Functions
|
||
|
|
//=============================================================================
|
||
|
|
|
||
|
|
namespace UIGridPathfinding {
|
||
|
|
// Extract grid position from Vector, Entity, or tuple
|
||
|
|
// Sets Python error and returns false on failure
|
||
|
|
// If expected_grid is provided and obj is Entity, validates grid membership
|
||
|
|
bool ExtractPosition(PyObject* obj, int* x, int* y,
|
||
|
|
UIGrid* expected_grid = nullptr,
|
||
|
|
const char* arg_name = "position");
|
||
|
|
|
||
|
|
//=========================================================================
|
||
|
|
// AStarPath Python Type Methods
|
||
|
|
//=========================================================================
|
||
|
|
|
||
|
|
PyObject* AStarPath_new(PyTypeObject* type, PyObject* args, PyObject* kwds);
|
||
|
|
int AStarPath_init(PyAStarPathObject* self, PyObject* args, PyObject* kwds);
|
||
|
|
void AStarPath_dealloc(PyAStarPathObject* self);
|
||
|
|
PyObject* AStarPath_repr(PyAStarPathObject* self);
|
||
|
|
|
||
|
|
// Methods
|
||
|
|
PyObject* AStarPath_walk(PyAStarPathObject* self, PyObject* args);
|
||
|
|
PyObject* AStarPath_peek(PyAStarPathObject* self, PyObject* args);
|
||
|
|
|
||
|
|
// Properties
|
||
|
|
PyObject* AStarPath_get_origin(PyAStarPathObject* self, void* closure);
|
||
|
|
PyObject* AStarPath_get_destination(PyAStarPathObject* self, void* closure);
|
||
|
|
PyObject* AStarPath_get_remaining(PyAStarPathObject* self, void* closure);
|
||
|
|
|
||
|
|
// Sequence protocol
|
||
|
|
Py_ssize_t AStarPath_len(PyAStarPathObject* self);
|
||
|
|
int AStarPath_bool(PyObject* self);
|
||
|
|
PyObject* AStarPath_iter(PyAStarPathObject* self);
|
||
|
|
PyObject* AStarPath_iternext(PyAStarPathObject* self);
|
||
|
|
|
||
|
|
//=========================================================================
|
||
|
|
// DijkstraMap Python Type Methods
|
||
|
|
//=========================================================================
|
||
|
|
|
||
|
|
PyObject* DijkstraMap_new(PyTypeObject* type, PyObject* args, PyObject* kwds);
|
||
|
|
int DijkstraMap_init(PyDijkstraMapObject* self, PyObject* args, PyObject* kwds);
|
||
|
|
void DijkstraMap_dealloc(PyDijkstraMapObject* self);
|
||
|
|
PyObject* DijkstraMap_repr(PyDijkstraMapObject* self);
|
||
|
|
|
||
|
|
// Methods
|
||
|
|
PyObject* DijkstraMap_distance(PyDijkstraMapObject* self, PyObject* args, PyObject* kwds);
|
||
|
|
PyObject* DijkstraMap_path_from(PyDijkstraMapObject* self, PyObject* args, PyObject* kwds);
|
||
|
|
PyObject* DijkstraMap_step_from(PyDijkstraMapObject* self, PyObject* args, PyObject* kwds);
|
||
|
|
|
||
|
|
// Properties
|
||
|
|
PyObject* DijkstraMap_get_root(PyDijkstraMapObject* self, void* closure);
|
||
|
|
|
||
|
|
//=========================================================================
|
||
|
|
// Grid Factory Methods (called from UIGrid Python bindings)
|
||
|
|
//=========================================================================
|
||
|
|
|
||
|
|
// Grid.find_path() -> AStarPath | None
|
||
|
|
PyObject* Grid_find_path(PyUIGridObject* self, PyObject* args, PyObject* kwds);
|
||
|
|
|
||
|
|
// Grid.get_dijkstra_map() -> DijkstraMap
|
||
|
|
PyObject* Grid_get_dijkstra_map(PyUIGridObject* self, PyObject* args, PyObject* kwds);
|
||
|
|
|
||
|
|
// Grid.clear_dijkstra_maps() -> None
|
||
|
|
PyObject* Grid_clear_dijkstra_maps(PyUIGridObject* self, PyObject* args);
|
||
|
|
}
|
||
|
|
|
||
|
|
//=============================================================================
|
||
|
|
// Python Type Definitions
|
||
|
|
//=============================================================================
|
||
|
|
|
||
|
|
namespace mcrfpydef {
|
||
|
|
|
||
|
|
// AStarPath iterator type
|
||
|
|
struct PyAStarPathIterObject {
|
||
|
|
PyObject_HEAD
|
||
|
|
PyAStarPathObject* path; // Reference to path being iterated
|
||
|
|
size_t iter_index; // Current iteration position
|
||
|
|
};
|
||
|
|
|
||
|
|
extern PyNumberMethods PyAStarPath_as_number;
|
||
|
|
extern PySequenceMethods PyAStarPath_as_sequence;
|
||
|
|
extern PyMethodDef PyAStarPath_methods[];
|
||
|
|
extern PyGetSetDef PyAStarPath_getsetters[];
|
||
|
|
|
||
|
|
extern PyTypeObject PyAStarPathType;
|
||
|
|
extern PyTypeObject PyAStarPathIterType;
|
||
|
|
|
||
|
|
extern PyMethodDef PyDijkstraMap_methods[];
|
||
|
|
extern PyGetSetDef PyDijkstraMap_getsetters[];
|
||
|
|
|
||
|
|
extern PyTypeObject PyDijkstraMapType;
|
||
|
|
}
|