F15: convert frozen binding docstrings to MCRF_* macros (#314)

Convert 289 raw PyMethodDef/PyGetSetDef docstring slots to MCRF_METHOD /
MCRF_PROPERTY across the 20 frozen (non-3D) binding files, bringing the
frozen surface to 100% macro compliance (check_frozen_docstrings.sh PASS).
Done via a one-agent-per-file workflow gated by validate_file_docstrings.sh
and per-wave build/doc-rebuild checks.

- Adds #include "McRFPy_Doc.h" where missing; fills the lone genuine doc
  gap (UIGrid.at, which was MISSING a doc field in two arrays).
- McRFPy_Doc.h: comment documenting the MCRF_METHOD_DOC comma rule (the
  trap that broke the GridLayers conversion mid-run).
- Rebaseline api_surface golden: property types now resolve to real types
  instead of "Any" (e.g. grid_pos: Vector, on_cell_click: Callable | None),
  and 11 properties correctly flip rw->ro now that their docstrings carry
  "read-only" (collections, grid_size, hovered_cell, texture, view — all
  verified against NULL setter slots).
- Regenerate docs/stubs/man page from the new docstrings.

Module-level functions use MCRF_METHOD(<name>, ...) (expands identically to
the intended MCRF_FUNCTION; the audit's compliance set is METHOD/PROPERTY).
Experimental 3D/Voxel bindings (src/3d/) remain exempt from the freeze.

Pre-existing failures unrelated to this change: test_animation_*,
test_constructor_comprehensive (reference the removed mcrfpy.Animation and
old constructor arity).

Refs #314

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
John McCardle 2026-06-21 01:20:55 -04:00
commit 5725a4f035
26 changed files with 2762 additions and 2085 deletions

View file

@ -1,6 +1,6 @@
# McRogueFace API Reference # McRogueFace API Reference
*Generated on 2026-06-10 20:23:39* *Generated on 2026-06-21 01:18:30*
*This documentation was dynamically generated from the compiled module.* *This documentation was dynamically generated from the compiled module.*
@ -229,19 +229,19 @@ Example:
#### `peek() -> Vector` #### `peek() -> Vector`
See next step without consuming it. See the next step without consuming it.
**Returns:** Next position as Vector. **Returns:** Next position as Vector
**Raises:** IndexError: If path is exhausted. **Raises:** IndexError: If the path is exhausted
#### `walk() -> Vector` #### `walk() -> Vector`
Get and consume next step in the path. Get and consume the next step in the path.
**Returns:** Next position as Vector. **Returns:** Next position as Vector
**Raises:** IndexError: If path is exhausted. **Raises:** IndexError: If the path is exhausted
### Alignment ### Alignment
@ -403,17 +403,17 @@ Attributes:
**Properties:** **Properties:**
- `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning. - `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.
- `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). - `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
- `center`: Center position of the arc - `center`: Center position of the arc (Vector).
- `color`: Arc color - `color`: Arc fill color (Color).
- `end_angle`: Ending angle in degrees - `end_angle`: Ending angle in degrees (float).
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_pos`: Position in grid tile coordinates (only when parent is Grid) - `grid_pos`: Position in grid tile coordinates (Vector, only when parent is Grid).
- `grid_size`: Size in grid tile coordinates (only when parent is Grid) - `grid_size`: Size in grid tile coordinates (Vector, only when parent is Grid).
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
- `name`: Name for finding this element. - `name`: Name for finding this element (str).
- `on_click`: Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str). - `on_click`: Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str).
- `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. - `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
- `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. - `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
@ -422,14 +422,14 @@ Attributes:
- `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. - `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
- `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. - `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
- `pos`: Position as a Vector (same as center). - `pos`: Position as a Vector (same as center).
- `radius`: Arc radius in pixels - `radius`: Arc radius in pixels (float).
- `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents. - `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.
- `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property. - `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property.
- `start_angle`: Starting angle in degrees - `start_angle`: Starting angle in degrees (float).
- `thickness`: Line thickness - `thickness`: Line thickness in pixels (float).
- `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). - `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
- `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable. - `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable.
- `z_index`: Z-order for rendering (lower values rendered first). - `z_index`: Z-order for rendering (int, lower values rendered first).
**Methods:** **Methods:**
@ -868,38 +868,38 @@ Attributes:
**Properties:** **Properties:**
- `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning. - `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.
- `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). - `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
- `fill_color`: Fill color of the text. Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc. - `fill_color`: Fill color of the text (Color). Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc.
- `font_size`: Font size (integer) in points - `font_size`: Font size in points (int). Clamped to the range [0, 65535].
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_pos`: Position in grid tile coordinates (only when parent is Grid) - `grid_pos`: Position in grid tile coordinates (Vector). Only valid when parent is a Grid.
- `grid_size`: Size in grid tile coordinates (only when parent is Grid) - `grid_size`: Size in grid tile coordinates (Vector). Only valid when parent is a Grid.
- `h` *(read-only)*: Text height in pixels (read-only) - `h` *(read-only)*: Text height in pixels (float, read-only).
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
- `name`: Name for finding elements - `name`: Name for finding elements (str).
- `on_click`: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str). - `on_click`: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).
- `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. - `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
- `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. - `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
- `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast. - `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.
- `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. - `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
- `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. - `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
- `outline`: Thickness of the border - `outline`: Thickness of the text outline border (float). Clamped to non-negative values.
- `outline_color`: Outline color of the text. Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', etc. - `outline_color`: Outline color of the text (Color). Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', etc.
- `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. - `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
- `pos`: (x, y) vector - `pos`: Position as (x, y) Vector.
- `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents. - `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.
- `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property. - `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property.
- `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. - `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
- `size` *(read-only)*: Text dimensions as Vector (read-only) - `size` *(read-only)*: Text dimensions as Vector (read-only).
- `text`: The text displayed - `text`: The text string displayed by this Caption (str).
- `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding. - `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.
- `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). - `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
- `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable. - `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable.
- `w` *(read-only)*: Text width in pixels (read-only) - `w` *(read-only)*: Text width in pixels (float, read-only).
- `x`: X coordinate of top-left corner - `x`: X coordinate of top-left corner (float).
- `y`: Y coordinate of top-left corner - `y`: Y coordinate of top-left corner (float).
- `z_index`: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed. - `z_index`: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.
**Methods:** **Methods:**
@ -998,32 +998,32 @@ Attributes:
**Properties:** **Properties:**
- `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning. - `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.
- `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). - `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
- `center`: Center position of the circle - `center`: Center position of the circle (Vector).
- `fill_color`: Fill color of the circle - `fill_color`: Fill color of the circle (Color).
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_pos`: Position in grid tile coordinates (only when parent is Grid) - `grid_pos`: Position in grid tile coordinates (Vector). Only meaningful when parent is a Grid.
- `grid_size`: Size in grid tile coordinates (only when parent is Grid) - `grid_size`: Size in grid tile coordinates (Vector). Only meaningful when parent is a Grid.
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
- `name`: Name for finding this element. - `name`: Name for finding this element (str).
- `on_click`: Callable executed when circle is clicked. Function receives (pos: Vector, button: str, action: str). - `on_click`: Callable executed when circle is clicked (Callable | None). Function receives (pos: Vector, button: str, action: str).
- `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. - `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
- `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. - `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
- `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast. - `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.
- `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. - `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
- `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. - `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
- `outline`: Outline thickness (0 for no outline) - `outline`: Outline thickness in pixels (float). Use 0 for no outline.
- `outline_color`: Outline color of the circle - `outline_color`: Outline color of the circle (Color).
- `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. - `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
- `pos`: Position as a Vector (same as center). - `pos`: Position as a Vector (same as center) (Vector).
- `radius`: Circle radius in pixels - `radius`: Circle radius in pixels (float).
- `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents. - `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.
- `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property. - `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property.
- `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). - `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
- `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable. - `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable.
- `z_index`: Z-order for rendering (lower values rendered first). - `z_index`: Z-order for rendering (int). Lower values are rendered first.
**Methods:** **Methods:**
@ -1187,88 +1187,119 @@ Example:
grid.layer('fog').set(5, 5, mcrfpy.Color(255, 0, 0, 128)) grid.layer('fog').set(5, 5, mcrfpy.Color(255, 0, 0, 128))
**Properties:** **Properties:**
- `grid`: Parent Grid or None. Setting manages layer association and handles lazy allocation. - `grid`: Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation.
- `grid_size`: Layer dimensions as (width, height) tuple. - `grid_size` *(read-only)*: Layer dimensions as (width, height) tuple (tuple, read-only).
- `name` *(read-only)*: Layer name (str, read-only). Used for Grid.layer(name) lookup. - `name` *(read-only)*: Layer name (str, read-only). Used for Grid.layer(name) lookup.
- `visible`: Whether the layer is rendered. - `visible`: Whether the layer is rendered (bool).
- `z_index`: Layer z-order. Negative values render below entities. - `z_index`: Layer z-order (int). Negative values render below entities.
**Methods:** **Methods:**
#### `apply_gradient(source, range, color_low, color_high) -> ColorLayer` #### `apply_gradient(source: HeightMap, range: tuple, color_low: Color, color_high: Color) -> ColorLayer`
Interpolate between colors based on HeightMap value within range. Interpolate between two colors based on HeightMap value within a range. Uses the original heightmap value for smooth transitions.
Note:
**Arguments:** **Arguments:**
- `source`: Source heightmap (must match layer dimensions)
- `range`: Value range as (min, max) inclusive
- `color_low`: Color at range minimum - `color_low`: Color at range minimum
- `color_high`: Color at range maximum - `color_high`: Color at range maximum
**Returns:** self for method chaining Uses the original HeightMap value for interpolation, not binary. This allows smooth color transitions within a value range. **Returns:** self for method chaining
#### `apply_perspective(entity, visible=None, discovered=None, unknown=None)` #### `apply_perspective(entity: Entity, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None`
Bind this layer to an entity for automatic FOV updates. Bind this layer to an entity for automatic FOV updates. After binding, call update_perspective() when the entity moves.
#### `apply_ranges(source, ranges) -> ColorLayer` **Arguments:**
- `entity`: The entity whose perspective to track
- `visible`: Color for currently visible cells
- `discovered`: Color for previously seen cells
- `unknown`: Color for never-seen cells
Apply multiple color assignments in a single pass. #### `apply_ranges(source: HeightMap, ranges: list) -> ColorLayer`
Apply multiple color assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping.
Note: Note:
**Returns:** self for method chaining Later ranges override earlier ones if overlapping. Cells not matching any range are left unchanged. **Arguments:**
- `source`: Source heightmap (must match layer dimensions)
- `ranges`: List of range specs: ((min, max), color) for fixed or ((min, max), (color_low, color_high)) for gradient
#### `apply_threshold(source, range, color) -> ColorLayer` **Returns:** self for method chaining Cells not matching any range are left unchanged.
Set fixed color for cells where HeightMap value is within range. #### `apply_threshold(source: HeightMap, range: tuple, color: Color) -> ColorLayer`
Set a fixed color for cells where the HeightMap value falls within a range.
**Arguments:** **Arguments:**
- `source`: Source heightmap (must match layer dimensions)
- `range`: Value range as (min, max) inclusive
- `color`: Color or (r, g, b[, a]) tuple to set for cells in range - `color`: Color or (r, g, b[, a]) tuple to set for cells in range
**Returns:** self for method chaining **Returns:** self for method chaining
#### `at(pos) -> Color` #### `at(pos) or (x: int, y: int) -> Color`
at(x, y) -> Color Get the color at a cell position.
Get the color at cell position.
**Arguments:** **Arguments:**
- `pos`: Position as (x, y) tuple, list, or Vector - `pos`: Position as (x, y) tuple, list, or Vector; or pass x and y separately
#### `clear_perspective()` **Returns:** Color at the specified cell
**Raises:** IndexError: If coordinates are out of bounds
#### `clear_perspective() -> None`
Remove the perspective binding from this layer. Remove the perspective binding from this layer.
#### `draw_fov(source, radius=None, fov=None, visible=None, discovered=None, unknown=None)` #### `draw_fov(source: tuple, radius: int = None, fov: FOV = None, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None`
Paint cells based on field-of-view visibility from source position. Paint cells based on field-of-view visibility from a source position.
Note: Layer must be attached to a grid for FOV calculation. Note:
#### `fill(color)` **Arguments:**
- `source`: FOV origin as (x, y)
- `radius`: FOV radius; defaults to the grid's fov_radius
- `fov`: FOV algorithm; defaults to the grid's fov setting
- `visible`: Color for currently visible cells
- `discovered`: Color for previously seen cells
- `unknown`: Color for never-seen cells
#### `fill(color: Color) -> None`
Fill the entire layer with the specified color. Fill the entire layer with the specified color.
#### `fill_rect(pos, size, color)` **Arguments:**
- `color`: Color object or (r, g, b[, a]) tuple
#### `fill_rect(pos: tuple, size: tuple, color: Color) -> None`
Fill a rectangular region with a color. Fill a rectangular region with a color.
**Arguments:** **Arguments:**
- `pos`: Top-left corner as (x, y)
- `size`: Dimensions as (width, height)
- `color`: Color object or (r, g, b[, a]) tuple - `color`: Color object or (r, g, b[, a]) tuple
#### `set(pos, color)` #### `set(pos, color: Color) -> None`
Set the color at cell position. Set the color at a cell position.
**Arguments:** **Arguments:**
- `pos`: Position as (x, y) tuple, list, or Vector - `pos`: Position as (x, y) tuple, list, or Vector
- `color`: Color object or (r, g, b[, a]) tuple - `color`: Color object or (r, g, b[, a]) tuple
#### `update_perspective()` **Raises:** IndexError: If coordinates are out of bounds
Redraw FOV based on the bound entity's current position. #### `update_perspective() -> None`
Call this after the entity moves to update the visibility layer.
Redraw FOV based on the bound entity's current position. Call this after the entity moves to update the visibility layer.
**Raises:** RuntimeError: If no perspective binding has been set via apply_perspective()
### DijkstraMap ### DijkstraMap
@ -1302,66 +1333,57 @@ Example:
**Methods:** **Methods:**
#### `descent_step(pos) -> Vector | None` #### `descent_step(pos: Vector | tuple) -> Vector | None`
Get the adjacent cell with the lowest distance (steepest descent). Get the adjacent cell with the lowest distance (steepest descent). Unlike step_from, this always returns the best neighbor in a single hop without following a precomputed path.
Unlike step_from (which follows the path set by path_from), descent_step
always returns the best neighbor in a single hop. Useful for AI that
reacts to the current distance field rather than following a fixed path.
**Arguments:** **Arguments:**
- `pos`: Current position as Vector, Entity, or (x, y) tuple. - `pos`: Current position as Vector, Entity, or (x, y) tuple
**Returns:** Next position as Vector, or None if pos is a local minimum or off-grid. **Returns:** Next position as Vector, or None if pos is a local minimum or off-grid
#### `distance(pos) -> float | None` #### `distance(pos: Vector | tuple) -> float | None`
Get distance from position to root. Get distance from position to root.
**Arguments:** **Arguments:**
- `pos`: Position as Vector, Entity, or (x, y) tuple. - `pos`: Position as Vector, Entity, or (x, y) tuple
**Returns:** Float distance, or None if position is unreachable. **Returns:** Float distance, or None if position is unreachable
#### `invert() -> DijkstraMap` #### `invert() -> DijkstraMap`
Return a NEW DijkstraMap whose distance field is the safety field. Return a new DijkstraMap whose distance field is inverted (safety field). Cells near a root become high values; descend to flee from original roots. The original DijkstraMap is unchanged.
Cells near a root become high values and cells far from any root become
low values. Combined with step_from or descent_step, this gives flee
behavior: descend the inverted map to move away from the original roots.
The original DijkstraMap is unchanged.
**Returns:** New DijkstraMap with inverted distances. **Returns:** New DijkstraMap with inverted distances
#### `path_from(pos) -> AStarPath` #### `path_from(pos: Vector | tuple) -> AStarPath`
Get full path from position to root. Get full path from position to root.
**Arguments:** **Arguments:**
- `pos`: Starting position as Vector, Entity, or (x, y) tuple. - `pos`: Starting position as Vector, Entity, or (x, y) tuple
**Returns:** AStarPath from pos toward root. **Returns:** AStarPath from pos toward root
#### `step_from(pos) -> Vector | None` #### `step_from(pos: Vector | tuple) -> Vector | None`
Get single step from position toward root. Get single step from position toward root.
**Arguments:** **Arguments:**
- `pos`: Current position as Vector, Entity, or (x, y) tuple. - `pos`: Current position as Vector, Entity, or (x, y) tuple
**Returns:** Next position as Vector, or None if at root or unreachable. **Returns:** Next position as Vector, or None if at root or unreachable
#### `to_heightmap(size=None, unreachable=-1.0) -> HeightMap` #### `to_heightmap(size=None, unreachable=-1.0) -> HeightMap`
Convert distance field to a HeightMap. Convert distance field to a HeightMap. Each cell's height equals its pathfinding distance from the root, useful for visualization, procedural terrain, or influence mapping.
Each cell's height equals its pathfinding distance from the root.
Useful for visualization, procedural terrain, or influence mapping.
**Arguments:** **Arguments:**
- `size`: Optional (width, height) tuple. Defaults to dijkstra dimensions. - `size`: Optional (width, height) tuple. Defaults to dijkstra dimensions
- `unreachable`: Value for cells that cannot reach root (default -1.0). - `unreachable`: Value for cells that cannot reach root (default -1.0)
**Returns:** HeightMap with distance values as heights. **Returns:** HeightMap with distance values as heights
### DiscreteMap ### DiscreteMap
@ -1787,44 +1809,49 @@ Attributes:
**Properties:** **Properties:**
- `behavior_type` *(read-only)*: Current behavior type (int, read-only). Use set_behavior() to change. - `behavior_type` *(read-only)*: Current behavior type (int, read-only). Use set_behavior() to change.
- `cell_pos`: Integer logical cell position (Vector). Alias for grid_pos (the canonical name). - `cell_pos`: Integer logical cell position (Vector). Alias for grid_pos (the canonical name).
- `cell_x`: Integer X cell coordinate. Alias for grid_x. - `cell_x`: Integer X cell coordinate (int). Alias for grid_x.
- `cell_y`: Integer Y cell coordinate. Alias for grid_y. - `cell_y`: Integer Y cell coordinate (int). Alias for grid_y.
- `default_behavior`: Default behavior type (int, maps to Behavior enum). Entity reverts to this after DONE trigger. Default: 0 (IDLE). - `default_behavior`: Default behavior type (int, maps to Behavior enum). Entity reverts to this after DONE trigger. Default: 0 (IDLE).
- `draw_pos`: Fractional tile position for rendering (Vector). Use for smooth animation between grid cells. - `draw_pos`: Fractional tile position for rendering (Vector). Use for smooth animation between grid cells.
- `grid`: Grid this entity belongs to. Get: Returns the Grid or None. Set: Assign a Grid to move entity, or None to remove from grid. - `grid`: Grid this entity belongs to (Grid or None). Assign a Grid to attach the entity, or None to remove it from its current grid.
- `grid_pos`: Integer logical cell position (Vector). Canonical cell-position property; matches the 'grid_pos' constructor argument. Decoupled from draw_pos. Determines which cell this entity logically occupies for collision, pathfinding, etc. - `grid_pos`: Integer logical cell position (Vector). Canonical cell-position property matching the 'grid_pos' constructor argument. Decoupled from draw_pos. Determines which cell this entity logically occupies for collision and pathfinding.
- `grid_x`: Integer X cell coordinate. Canonical; matches grid_pos. - `grid_x`: Integer X cell coordinate (int). Canonical; matches grid_pos.
- `grid_y`: Integer Y cell coordinate. Canonical; matches grid_pos. - `grid_y`: Integer Y cell coordinate (int). Canonical; matches grid_pos.
- `labels`: Set of string labels for collision/targeting (frozenset). Assign any iterable of strings to replace all labels. - `labels`: String labels for collision and targeting (frozenset). Assign any iterable of strings to replace all labels.
- `move_speed`: Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15. - `move_speed`: Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15.
- `name`: Name for finding elements - `name`: Entity name for lookup (str).
- `opacity`: Opacity (0.0 = transparent, 1.0 = opaque) - `opacity`: Render opacity (float). 0.0 = fully transparent, 1.0 = fully opaque.
- `perspective_map`: Per-entity FOV memory (DiscreteMap, read-write). 3-state values per cell: 0 = unknown (never seen), 1 = discovered (seen before, not currently visible), 2 = visible (in current FOV). Use mcrfpy.Perspective enum for clarity. Lazy-allocated on first access once the entity has a grid; returns None otherwise. The returned DiscreteMap is a live reference -- mutations are visible to subsequent updateVisibility() calls. Assigning a DiscreteMap replaces the entity's memory; the new map's size must match the grid's size or ValueError is raised. Assign None to clear (will be lazy-reallocated on next access). - `perspective_map`: Per-entity FOV memory (DiscreteMap). 3-state values per cell: 0=unknown, 1=discovered, 2=visible. Lazy-allocated on first access once entity has a grid; returns None otherwise. The returned DiscreteMap is a live reference. Assigning a DiscreteMap replaces the entity's memory; size must match the grid or ValueError is raised. Assign None to clear.
- `pos`: Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. Requires entity to be attached to a grid. - `pos`: Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. Requires entity to be attached to a grid.
- `shader`: Shader for GPU visual effects (Shader or None). When set, the entity is rendered through the shader program. Set to None to disable shader effects. - `shader`: GPU shader for visual effects (Shader or None). Set to None to disable shader rendering.
- `sight_radius`: FOV radius for TARGET trigger (int). Default: 10. - `sight_radius`: FOV radius for TARGET trigger (int). Default: 10.
- `sprite_grid`: Per-tile sprite indices for composite multi-tile entities (list of lists or None). Row-major, dimensions must match tile_width x tile_height. Use -1 for empty tiles. When set, each tile renders its own sprite index instead of the single entity sprite. - `sprite_grid`: Per-tile sprite indices for composite multi-tile entities (list of lists or None). Row-major, dimensions must match tile_width x tile_height. Use -1 for empty tiles.
- `sprite_index`: Sprite index on the texture on the display - `sprite_index`: Sprite index into the entity's texture atlas (int).
- `sprite_offset`: Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering. - `sprite_offset`: Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering.
- `sprite_offset_x`: X component of sprite pixel offset. - `sprite_offset_x`: X component of sprite pixel offset (float).
- `sprite_offset_y`: Y component of sprite pixel offset. - `sprite_offset_y`: Y component of sprite pixel offset (float).
- `step`: Step callback for grid.step() turn management. Called with (trigger, data) when behavior triggers fire. Set to None to clear. - `step`: Step callback for grid.step() turn management (Callable or None). Called with (trigger, data) when behavior triggers fire.
- `target_label`: Label to search for with TARGET trigger (str or None). Default: None. - `target_label`: Label to search for with TARGET trigger (str or None). Default: None.
- `texture`: Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture when the entity is constructed without one. Setting preserves sprite_index (the index is not re-validated against the new atlas). The grid's texture only determines cell size; entities draw with their own. - `texture`: Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture at construction. Setting preserves sprite_index (not re-validated against the new atlas).
- `tile_height`: Entity height in tiles (int). Must be >= 1. Default 1. - `tile_height`: Entity height in tiles (int). Must be >= 1. Default 1.
- `tile_size`: Entity size in tiles as (width, height) Vector. Default (1, 1). - `tile_size`: Entity size in tiles as (width, height) (Vector). Default (1, 1).
- `tile_width`: Entity width in tiles (int). Must be >= 1. Default 1. - `tile_width`: Entity width in tiles (int). Must be >= 1. Default 1.
- `turn_order`: Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1. - `turn_order`: Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1.
- `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: entity.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding. - `uniforms` *(read-only)*: Collection of shader uniforms (UniformCollection, read-only). Set values via dict-like syntax: entity.uniforms['name'] = value.
- `visible`: Visibility flag - `visible`: Visibility flag (bool). When False, the entity is not rendered.
- `x`: Pixel X position relative to grid. Requires entity to be attached to a grid. - `x`: Pixel X position relative to grid (float). Requires entity to be attached to a grid.
- `y`: Pixel Y position relative to grid. Requires entity to be attached to a grid. - `y`: Pixel Y position relative to grid (float). Requires entity to be attached to a grid.
**Methods:** **Methods:**
#### `add_label(label: str) -> None` #### `add_label(label: str) -> None`
Add a label to this entity. Idempotent (adding same label twice is safe). Add a label to this entity. Idempotent; adding the same label twice is safe.
**Arguments:**
- `label`: String label to add
**Returns:** None
#### `animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation` #### `animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation`
@ -1846,41 +1873,55 @@ Note:
**Raises:** ValueError: If property name is not valid for Entity (draw_x, draw_y, sprite_scale, sprite_index) Use 'draw_x'/'draw_y' to animate tile coordinates for smooth movement between grid cells. Use list target with loop=True for repeating sprite frame animations. **Raises:** ValueError: If property name is not valid for Entity (draw_x, draw_y, sprite_scale, sprite_index) Use 'draw_x'/'draw_y' to animate tile coordinates for smooth movement between grid cells. Use list target with loop=True for repeating sprite frame animations.
#### `at(x, y) or at(pos) -> GridPoint | None` #### `at(x: int, y: int) -> GridPoint | None`
Return the GridPoint at (x, y) if currently VISIBLE to this entity's Return the GridPoint at (x, y) if currently VISIBLE to this entity's perspective_map, otherwise None.
perspective_map, otherwise None. Equivalent to:
grid.at(x, y) if perspective_map[x, y] == Perspective.VISIBLE else None Note:
To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y]
directly and use grid.at(x, y) for cell data.
**Arguments:** **Arguments:**
- `pos`: Grid coordinates as tuple, list, or Vector - `x`: Grid X coordinate (also accepts a tuple/Vector as first positional arg)
- `y`: Grid Y coordinate (omit when passing a tuple or Vector)
#### `die(...)` **Returns:** GridPoint if visible, None if undiscovered or not currently in FOV To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y] directly.
#### `die() -> None`
Remove this entity from its grid. Remove this entity from its grid.
Warning: Do not call during iteration over grid.entities.
Modifying the collection during iteration raises RuntimeError.
#### `find_path(target, diagonal_cost=1.41, collide=None) -> AStarPath | None` Note:
**Returns:** None Do not call during iteration over grid.entities; modifying the collection during iteration raises RuntimeError.
#### `find_path(target, diagonal_cost: float = 1.41, collide: str = None) -> AStarPath | None`
Find a path from this entity to the target position. Find a path from this entity to the target position.
**Arguments:** **Arguments:**
- `target`: Target as Vector, Entity, or (x, y) tuple. - `target`: Target as Vector, Entity, or (x, y) tuple
- `diagonal_cost`: Cost of diagonal movement (default 1.41). - `diagonal_cost`: Cost of diagonal movement (default 1.41)
- `collide`: Label string. Entities with this label block pathfinding. - `collide`: Label string; entities with this label block pathfinding
**Returns:** AStarPath object, or None if no path exists. **Returns:** AStarPath object, or None if no path exists
**Raises:** ValueError: If entity has no grid or positions are out of bounds
#### `has_label(label: str) -> bool` #### `has_label(label: str) -> bool`
Check if this entity has the given label. Check if this entity has the given label.
#### `index(...)` **Arguments:**
- `label`: String label to check
Return the index of this entity in its grid's entity collection **Returns:** True if the entity has the label, False otherwise
#### `index() -> int`
Return the index of this entity in its grid's entity collection.
**Returns:** Zero-based index of this entity in grid.entities
**Raises:** RuntimeError: If entity is not associated with a grid
#### `move(dx, dy) or (delta) -> None` #### `move(dx, dy) or (delta) -> None`
@ -1893,18 +1934,26 @@ Note:
- `dy`: Vertical offset in pixels (or use delta) - `dy`: Vertical offset in pixels (or use delta)
- `delta`: Offset as tuple, list, or Vector: (dx, dy) - `delta`: Offset as tuple, list, or Vector: (dx, dy)
#### `path_to(x, y) or path_to(target) -> list` #### `path_to(x: int, y: int) -> list`
Find a path to the target position using Dijkstra pathfinding. Find a path to the target position using A* pathfinding.
**Arguments:** **Arguments:**
- `target`: Target coordinates as tuple, list, or Vector - `x`: Target X coordinate (also accepts a tuple/Vector as first positional arg)
- `y`: Target Y coordinate (omit when passing a tuple or Vector)
**Returns:** List of (x, y) tuples representing the path. **Returns:** List of (x, y) tuples representing the path from current position to target
**Raises:** ValueError: If entity has no grid or target is out of bounds
#### `remove_label(label: str) -> None` #### `remove_label(label: str) -> None`
Remove a label from this entity. No-op if label not present. Remove a label from this entity. No-op if label is not present.
**Arguments:**
- `label`: String label to remove
**Returns:** None
#### `resize(width, height) or (size) -> None` #### `resize(width, height) or (size) -> None`
@ -1917,23 +1966,38 @@ Note:
- `height`: New height in pixels (or use size) - `height`: New height in pixels (or use size)
- `size`: Size as tuple, list, or Vector: (width, height) - `size`: Size as tuple, list, or Vector: (width, height)
#### `set_behavior(type, waypoints=None, turns=0, path=None) -> None` #### `set_behavior(type, waypoints=None, turns: int = 0, path=None, pathfinder=None) -> None`
Configure this entity's behavior for grid.step() turn management. Configure this entity's behavior for grid.step() turn management.
**Arguments:**
- `type`: Behavior type (int or Behavior enum, e.g., Behavior.PATROL)
- `waypoints`: List of (x, y) tuples for WAYPOINT/PATROL/LOOP behaviors
- `turns`: Number of turns for SLEEP behavior
- `path`: Pre-computed path as list of (x, y) tuples for PATH behavior
- `pathfinder`: DijkstraMap, AStarPath, or (x, y) target tuple for SEEK behavior
**Returns:** None
#### `update_visibility() -> None` #### `update_visibility() -> None`
Update entity's visibility state based on current FOV. Recompute which cells are visible from this entity's position and update perspective_map.
Recomputes which cells are visible from the entity's position and updates
the entity's perspective_map (see entity.perspective_map and mcrfpy.Perspective).
This is called automatically when the entity moves if it has a grid with
perspective set.
#### `visible_entities(fov=None, radius=None) -> list[Entity]` Note:
**Returns:** None Called automatically when the entity moves if the grid has FOV configured.
#### `visible_entities(fov=None, radius: int = None) -> list[Entity]`
Get list of other entities visible from this entity's position. Get list of other entities visible from this entity's position.
**Returns:** List of Entity objects that are within field of view. Computes FOV from this entity's position and returns all other entities whose positions fall within the visible area. **Arguments:**
- `fov`: FOV algorithm to use (FOV enum or None to use grid.fov)
- `radius`: FOV radius (int or None to use grid.fov_radius)
**Returns:** List of Entity objects within field of view, excluding self
**Raises:** ValueError: If entity is not associated with a grid
### Entity3D ### Entity3D
@ -2229,38 +2293,38 @@ Attributes:
**Properties:** **Properties:**
- `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning. - `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.
- `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). - `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
- `cache_subtree`: #144: Cache subtree rendering to texture for performance - `cache_subtree`: Cache the frame and all children to a render texture for performance (bool). Useful for complex static subtrees.
- `children`: UICollection of objects on top of this one - `children` *(read-only)*: UICollection of child drawable objects rendered on top of this frame (UICollection, read-only).
- `clip_children`: Whether to clip children to frame bounds - `clip_children`: Whether to clip child elements to the frame's bounds (bool). Enables render-texture mode when True.
- `fill_color`: Fill color of the rectangle. Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc. - `fill_color`: Fill color of the rectangle (Color). Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc.
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_pos`: Position in grid tile coordinates (only when parent is Grid) - `grid_pos`: Position in grid tile coordinates (Vector). Only meaningful when this element's parent is a Grid.
- `grid_size`: Size in grid tile coordinates (only when parent is Grid) - `grid_size`: Size in grid tile coordinates (Vector). Only meaningful when this element's parent is a Grid.
- `h`: height of the rectangle - `h`: Height of the rectangle (float).
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
- `name`: Name for finding elements - `name`: Name for finding elements (str).
- `on_click`: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str). - `on_click`: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).
- `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. - `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
- `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. - `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
- `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast. - `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.
- `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. - `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
- `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. - `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
- `outline`: Thickness of the border - `outline`: Thickness of the border in pixels (float).
- `outline_color`: Outline color of the rectangle. Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', etc. - `outline_color`: Outline color of the rectangle (Color). Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', etc.
- `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. - `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
- `pos`: Position as a Vector - `pos`: Position as a Vector (Vector).
- `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents. - `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.
- `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property. - `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property.
- `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. - `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
- `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding. - `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.
- `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). - `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
- `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable. - `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable.
- `w`: width of the rectangle - `w`: Width of the rectangle (float).
- `x`: X coordinate of top-left corner - `x`: X coordinate of the top-left corner (float).
- `y`: Y coordinate of top-left corner - `y`: Y coordinate of the top-left corner (float).
- `z_index`: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed. - `z_index`: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.
**Methods:** **Methods:**
@ -2349,39 +2413,39 @@ Keyword Args:
**Properties:** **Properties:**
- `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning. - `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.
- `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). - `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
- `camera_rotation`: Rotation of grid contents around camera center (degrees). - `camera_rotation`: Rotation of grid contents around camera center in degrees (float).
- `center`: Camera center point in pixel coordinates. - `center`: Camera center point in pixel coordinates (tuple).
- `center_x`: center of the view X-coordinate - `center_x`: Camera center X-coordinate in pixel space (float).
- `center_y`: center of the view Y-coordinate - `center_y`: Camera center Y-coordinate in pixel space (float).
- `fill_color`: Background fill color. - `fill_color`: Background fill color (Color). Drawn behind all tiles and entities.
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_data`: The underlying grid data object (for multi-view scenarios). - `grid_data`: The underlying grid data object (Grid | None). Used for multi-view scenarios where multiple GridViews share one Grid.
- `h`: visible widget height - `h`: Visible widget height (float).
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
- `name`: Name for finding elements - `name`: Name for finding elements (str).
- `on_click`: Callable executed when object is clicked. - `on_click`: Callable executed when object is clicked (Callable | None).
- `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. - `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
- `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. - `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
- `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast. - `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.
- `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. - `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
- `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. - `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
- `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. - `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
- `pos`: Position of the grid as Vector - `pos`: Position of the grid as Vector (Vector).
- `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents. - `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.
- `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property. - `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property.
- `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. - `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
- `texture` *(read-only)*: Texture used for tile rendering (read-only). - `texture` *(read-only)*: Texture used for tile rendering (Texture | None, read-only).
- `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding. - `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.
- `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). - `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
- `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable. - `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable.
- `w`: visible widget width - `w`: Visible widget width (float).
- `x`: top-left corner X-coordinate - `x`: Top-left corner X-coordinate (float).
- `y`: top-left corner Y-coordinate - `y`: Top-left corner Y-coordinate (float).
- `z_index`: Z-order for rendering (lower values rendered first). - `z_index`: Z-order for rendering (int). Lower values are rendered first.
- `zoom`: Zoom level for rendering. - `zoom`: Zoom level for rendering (float). Values greater than 1.0 magnify; less than 1.0 shrink.
**Methods:** **Methods:**
@ -2469,39 +2533,39 @@ Keyword Args:
**Properties:** **Properties:**
- `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning. - `align`: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.
- `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). - `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
- `camera_rotation`: Rotation of grid contents around camera center (degrees). - `camera_rotation`: Rotation of grid contents around camera center in degrees (float).
- `center`: Camera center point in pixel coordinates. - `center`: Camera center point in pixel coordinates (tuple).
- `center_x`: center of the view X-coordinate - `center_x`: Camera center X-coordinate in pixel space (float).
- `center_y`: center of the view Y-coordinate - `center_y`: Camera center Y-coordinate in pixel space (float).
- `fill_color`: Background fill color. - `fill_color`: Background fill color (Color). Drawn behind all tiles and entities.
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_data`: The underlying grid data object (for multi-view scenarios). - `grid_data`: The underlying grid data object (Grid | None). Used for multi-view scenarios where multiple GridViews share one Grid.
- `h`: visible widget height - `h`: Visible widget height (float).
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
- `name`: Name for finding elements - `name`: Name for finding elements (str).
- `on_click`: Callable executed when object is clicked. - `on_click`: Callable executed when object is clicked (Callable | None).
- `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. - `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
- `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. - `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
- `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast. - `on_move`: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.
- `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. - `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
- `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. - `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
- `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. - `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
- `pos`: Position of the grid as Vector - `pos`: Position of the grid as Vector (Vector).
- `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents. - `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.
- `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property. - `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property.
- `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. - `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
- `texture` *(read-only)*: Texture used for tile rendering (read-only). - `texture` *(read-only)*: Texture used for tile rendering (Texture | None, read-only).
- `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding. - `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.
- `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). - `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
- `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable. - `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable.
- `w`: visible widget width - `w`: Visible widget width (float).
- `x`: top-left corner X-coordinate - `x`: Top-left corner X-coordinate (float).
- `y`: top-left corner Y-coordinate - `y`: Top-left corner Y-coordinate (float).
- `z_index`: Z-order for rendering (lower values rendered first). - `z_index`: Z-order for rendering (int). Lower values are rendered first.
- `zoom`: Zoom level for rendering. - `zoom`: Zoom level for rendering (float). Values greater than 1.0 magnify; less than 1.0 shrink.
**Methods:** **Methods:**
@ -3368,8 +3432,8 @@ Attributes:
- `end`: Ending point of the line as a Vector. - `end`: Ending point of the line as a Vector.
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_pos`: Position in grid tile coordinates (only when parent is Grid) - `grid_pos`: Position in grid tile coordinates (Vector, only when parent is Grid).
- `grid_size`: Size in grid tile coordinates (only when parent is Grid) - `grid_size`: Size in grid tile coordinates (Vector, only when parent is Grid).
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
@ -4203,12 +4267,12 @@ Attributes:
- `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). - `bounds`: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
- `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). - `global_bounds`: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
- `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain. - `global_position` *(read-only)*: Global screen position (read-only). Calculates absolute position by walking up the parent chain.
- `grid_pos`: Position in grid tile coordinates (only when parent is Grid) - `grid_pos`: Position in grid tile coordinates (Vector, only when parent is Grid).
- `grid_size`: Size in grid tile coordinates (only when parent is Grid) - `grid_size`: Size in grid tile coordinates (Vector, only when parent is Grid).
- `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). - `horiz_margin`: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
- `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. - `hovered` *(read-only)*: Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
- `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError). - `margin`: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).
- `name`: Name for finding elements - `name`: Name for finding elements (str).
- `on_click`: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str). - `on_click`: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).
- `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. - `on_enter`: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
- `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. - `on_exit`: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
@ -4216,20 +4280,20 @@ Attributes:
- `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. - `opacity`: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
- `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. - `origin`: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
- `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. - `parent`: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
- `pos`: Position as a Vector - `pos`: Position as a Vector (Vector).
- `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents. - `rotate_with_camera`: Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.
- `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property. - `rotation`: Rotation angle in degrees (clockwise around origin). Animatable property.
- `scale`: Uniform size factor - `scale`: Uniform size factor (float). Sets both horizontal and vertical scale to the same value.
- `scale_x`: Horizontal scale factor - `scale_x`: Horizontal scale factor (float).
- `scale_y`: Vertical scale factor - `scale_y`: Vertical scale factor (float).
- `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. - `shader`: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
- `sprite_index`: Which sprite on the texture is shown - `sprite_index`: Which sprite on the texture is shown (int). Index into the texture atlas; must be in range [0, sprite_count).
- `texture`: Texture object - `texture`: Texture object (Texture). The texture atlas from which sprites are drawn.
- `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding. - `uniforms` *(read-only)*: Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.
- `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). - `vert_margin`: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
- `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable. - `visible`: Whether the object is visible (bool). Invisible objects are not rendered or clickable.
- `x`: X coordinate of top-left corner - `x`: X coordinate of top-left corner (float).
- `y`: Y coordinate of top-left corner - `y`: Y coordinate of top-left corner (float).
- `z_index`: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed. - `z_index`: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.
**Methods:** **Methods:**
@ -4412,53 +4476,75 @@ Example:
grid.layer('terrain').set(5, 5, 42) # Place tile 42 at (5, 5) grid.layer('terrain').set(5, 5, 42) # Place tile 42 at (5, 5)
**Properties:** **Properties:**
- `grid`: Parent Grid or None. Setting manages layer association and handles lazy allocation. - `grid`: Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation.
- `grid_size`: Layer dimensions as (width, height) tuple. - `grid_size` *(read-only)*: Layer dimensions as (width, height) tuple (tuple, read-only).
- `name` *(read-only)*: Layer name (str, read-only). Used for Grid.layer(name) lookup. - `name` *(read-only)*: Layer name (str, read-only). Used for Grid.layer(name) lookup.
- `texture`: Texture atlas for tile sprites. - `texture`: Texture atlas for tile sprites (Texture | None).
- `visible`: Whether the layer is rendered. - `visible`: Whether the layer is rendered (bool).
- `z_index`: Layer z-order. Negative values render below entities. - `z_index`: Layer z-order (int). Negative values render below entities.
**Methods:** **Methods:**
#### `apply_ranges(source, ranges) -> TileLayer` #### `apply_ranges(source: HeightMap, ranges: list) -> TileLayer`
Apply multiple tile assignments in a single pass. Apply multiple tile assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping.
Note: Note:
**Returns:** self for method chaining Later ranges override earlier ones if overlapping. Cells not matching any range are left unchanged. **Arguments:**
- `source`: Source heightmap (must match layer dimensions)
- `ranges`: List of ((min, max), tile_index) tuples
#### `apply_threshold(source, range, tile) -> TileLayer` **Returns:** self for method chaining Cells not matching any range are left unchanged.
Set tile index for cells where HeightMap value is within range. #### `apply_threshold(source: HeightMap, range: tuple, tile: int) -> TileLayer`
Set a tile index for cells where the HeightMap value falls within a range.
**Arguments:**
- `source`: Source heightmap (must match layer dimensions)
- `range`: Value range as (min, max) inclusive
- `tile`: Tile index to set for cells in range
**Returns:** self for method chaining **Returns:** self for method chaining
#### `at(pos) -> int` #### `at(pos) or (x: int, y: int) -> int`
at(x, y) -> int Get the tile index at a cell position. Returns -1 if no tile is set.
Get the tile index at cell position. Returns -1 if no tile.
**Arguments:** **Arguments:**
- `pos`: Position as (x, y) tuple, list, or Vector - `pos`: Position as (x, y) tuple, list, or Vector; or pass x and y separately
#### `fill(index)` **Returns:** Tile index at the specified cell, or -1 if empty
**Raises:** IndexError: If coordinates are out of bounds
#### `fill(index: int) -> None`
Fill the entire layer with the specified tile index. Fill the entire layer with the specified tile index.
#### `fill_rect(pos, size, index)` **Arguments:**
- `index`: Tile index to fill with (-1 for no tile)
#### `fill_rect(pos: tuple, size: tuple, index: int) -> None`
Fill a rectangular region with a tile index. Fill a rectangular region with a tile index.
#### `set(pos, index)` **Arguments:**
- `pos`: Top-left corner as (x, y)
- `size`: Dimensions as (width, height)
- `index`: Tile index to fill with (-1 for no tile)
Set the tile index at cell position. Use -1 for no tile. #### `set(pos, index: int) -> None`
Set the tile index at a cell position. Use -1 to clear the tile.
**Arguments:** **Arguments:**
- `pos`: Position as (x, y) tuple, list, or Vector - `pos`: Position as (x, y) tuple, list, or Vector
- `index`: Tile index (-1 for no tile) - `index`: Tile index (-1 for no tile)
**Raises:** IndexError: If coordinates are out of bounds
### TileMapFile ### TileMapFile
TileMapFile(path: str) TileMapFile(path: str)

View file

@ -108,7 +108,7 @@
<body> <body>
<div class="container"> <div class="container">
<h1>McRogueFace API Reference</h1> <h1>McRogueFace API Reference</h1>
<p><em>Generated on 2026-06-10 20:23:39</em></p> <p><em>Generated on 2026-06-21 01:18:30</em></p>
<p><em>This documentation was dynamically generated from the compiled module.</em></p> <p><em>This documentation was dynamically generated from the compiled module.</em></p>
<div class="toc"> <div class="toc">
@ -346,16 +346,16 @@ Example:
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">peek() -> Vector</code></h5> <h5><code class="method-name">peek() -> Vector</code></h5>
<p>See next step without consuming it.</p> <p>See the next step without consuming it.</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If path is exhausted.</p> <p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If the path is exhausted</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">walk() -> Vector</code></h5> <h5><code class="method-name">walk() -> Vector</code></h5>
<p>Get and consume next step in the path.</p> <p>Get and consume the next step in the path.</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If path is exhausted.</p> <p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If the path is exhausted</p>
</div> </div>
</div> </div>
@ -525,17 +525,17 @@ Attributes:
<ul> <ul>
<li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li> <li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li>
<li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>center</span>: Center position of the arc</li> <li><span class='property-name'>center</span>: Center position of the arc (Vector).</li>
<li><span class='property-name'>color</span>: Arc color</li> <li><span class='property-name'>color</span>: Arc fill color (Color).</li>
<li><span class='property-name'>end_angle</span>: Ending angle in degrees</li> <li><span class='property-name'>end_angle</span>: Ending angle in degrees (float).</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (Vector, only when parent is Grid).</li>
<li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (Vector, only when parent is Grid).</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
<li><span class='property-name'>name</span>: Name for finding this element.</li> <li><span class='property-name'>name</span>: Name for finding this element (str).</li>
<li><span class='property-name'>on_click</span>: Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str).</li> <li><span class='property-name'>on_click</span>: Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str).</li>
<li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li> <li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li>
<li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li> <li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li>
@ -544,14 +544,14 @@ Attributes:
<li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li> <li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li>
<li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li> <li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li>
<li><span class='property-name'>pos</span>: Position as a Vector (same as center).</li> <li><span class='property-name'>pos</span>: Position as a Vector (same as center).</li>
<li><span class='property-name'>radius</span>: Arc radius in pixels</li> <li><span class='property-name'>radius</span>: Arc radius in pixels (float).</li>
<li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li> <li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li>
<li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li> <li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li>
<li><span class='property-name'>start_angle</span>: Starting angle in degrees</li> <li><span class='property-name'>start_angle</span>: Starting angle in degrees (float).</li>
<li><span class='property-name'>thickness</span>: Line thickness</li> <li><span class='property-name'>thickness</span>: Line thickness in pixels (float).</li>
<li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li> <li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li>
<li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li> <li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li>
<li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first).</li> <li><span class='property-name'>z_index</span>: Z-order for rendering (int, lower values rendered first).</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
@ -1003,38 +1003,38 @@ Attributes:
<ul> <ul>
<li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li> <li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li>
<li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>fill_color</span>: Fill color of the text. Returns a copy; modifying components requires reassignment. For animation, use &#x27;fill_color.r&#x27;, &#x27;fill_color.g&#x27;, etc.</li> <li><span class='property-name'>fill_color</span>: Fill color of the text (Color). Returns a copy; modifying components requires reassignment. For animation, use &#x27;fill_color.r&#x27;, &#x27;fill_color.g&#x27;, etc.</li>
<li><span class='property-name'>font_size</span>: Font size (integer) in points</li> <li><span class='property-name'>font_size</span>: Font size in points (int). Clamped to the range [0, 65535].</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (Vector). Only valid when parent is a Grid.</li>
<li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (Vector). Only valid when parent is a Grid.</li>
<li><span class='property-name'>h</span> (read-only): Text height in pixels (read-only)</li> <li><span class='property-name'>h</span> (read-only): Text height in pixels (float, read-only).</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
<li><span class='property-name'>name</span>: Name for finding elements</li> <li><span class='property-name'>name</span>: Name for finding elements (str).</li>
<li><span class='property-name'>on_click</span>: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).</li> <li><span class='property-name'>on_click</span>: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).</li>
<li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li> <li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li>
<li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li> <li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li>
<li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li> <li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li>
<li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li> <li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li>
<li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li> <li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li>
<li><span class='property-name'>outline</span>: Thickness of the border</li> <li><span class='property-name'>outline</span>: Thickness of the text outline border (float). Clamped to non-negative values.</li>
<li><span class='property-name'>outline_color</span>: Outline color of the text. Returns a copy; modifying components requires reassignment. For animation, use &#x27;outline_color.r&#x27;, &#x27;outline_color.g&#x27;, etc.</li> <li><span class='property-name'>outline_color</span>: Outline color of the text (Color). Returns a copy; modifying components requires reassignment. For animation, use &#x27;outline_color.r&#x27;, &#x27;outline_color.g&#x27;, etc.</li>
<li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li> <li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li>
<li><span class='property-name'>pos</span>: (x, y) vector</li> <li><span class='property-name'>pos</span>: Position as (x, y) Vector.</li>
<li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li> <li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li>
<li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li> <li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li>
<li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li> <li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li>
<li><span class='property-name'>size</span> (read-only): Text dimensions as Vector (read-only)</li> <li><span class='property-name'>size</span> (read-only): Text dimensions as Vector (read-only).</li>
<li><span class='property-name'>text</span>: The text displayed</li> <li><span class='property-name'>text</span>: The text string displayed by this Caption (str).</li>
<li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li> <li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li>
<li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li> <li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li>
<li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li> <li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li>
<li><span class='property-name'>w</span> (read-only): Text width in pixels (read-only)</li> <li><span class='property-name'>w</span> (read-only): Text width in pixels (float, read-only).</li>
<li><span class='property-name'>x</span>: X coordinate of top-left corner</li> <li><span class='property-name'>x</span>: X coordinate of top-left corner (float).</li>
<li><span class='property-name'>y</span>: Y coordinate of top-left corner</li> <li><span class='property-name'>y</span>: Y coordinate of top-left corner (float).</li>
<li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.</li> <li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
@ -1135,32 +1135,32 @@ Attributes:
<ul> <ul>
<li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li> <li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li>
<li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>center</span>: Center position of the circle</li> <li><span class='property-name'>center</span>: Center position of the circle (Vector).</li>
<li><span class='property-name'>fill_color</span>: Fill color of the circle</li> <li><span class='property-name'>fill_color</span>: Fill color of the circle (Color).</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (Vector). Only meaningful when parent is a Grid.</li>
<li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (Vector). Only meaningful when parent is a Grid.</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
<li><span class='property-name'>name</span>: Name for finding this element.</li> <li><span class='property-name'>name</span>: Name for finding this element (str).</li>
<li><span class='property-name'>on_click</span>: Callable executed when circle is clicked. Function receives (pos: Vector, button: str, action: str).</li> <li><span class='property-name'>on_click</span>: Callable executed when circle is clicked (Callable | None). Function receives (pos: Vector, button: str, action: str).</li>
<li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li> <li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li>
<li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li> <li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li>
<li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li> <li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li>
<li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li> <li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li>
<li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li> <li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li>
<li><span class='property-name'>outline</span>: Outline thickness (0 for no outline)</li> <li><span class='property-name'>outline</span>: Outline thickness in pixels (float). Use 0 for no outline.</li>
<li><span class='property-name'>outline_color</span>: Outline color of the circle</li> <li><span class='property-name'>outline_color</span>: Outline color of the circle (Color).</li>
<li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li> <li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li>
<li><span class='property-name'>pos</span>: Position as a Vector (same as center).</li> <li><span class='property-name'>pos</span>: Position as a Vector (same as center) (Vector).</li>
<li><span class='property-name'>radius</span>: Circle radius in pixels</li> <li><span class='property-name'>radius</span>: Circle radius in pixels (float).</li>
<li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li> <li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li>
<li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li> <li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li>
<li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li> <li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li>
<li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li> <li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li>
<li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first).</li> <li><span class='property-name'>z_index</span>: Z-order for rendering (int). Lower values are rendered first.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
@ -1327,95 +1327,122 @@ Example:
grid.layer(&#x27;fog&#x27;).set(5, 5, mcrfpy.Color(255, 0, 0, 128))</p> grid.layer(&#x27;fog&#x27;).set(5, 5, mcrfpy.Color(255, 0, 0, 128))</p>
<h4>Properties:</h4> <h4>Properties:</h4>
<ul> <ul>
<li><span class='property-name'>grid</span>: Parent Grid or None. Setting manages layer association and handles lazy allocation.</li> <li><span class='property-name'>grid</span>: Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation.</li>
<li><span class='property-name'>grid_size</span>: Layer dimensions as (width, height) tuple.</li> <li><span class='property-name'>grid_size</span> (read-only): Layer dimensions as (width, height) tuple (tuple, read-only).</li>
<li><span class='property-name'>name</span> (read-only): Layer name (str, read-only). Used for Grid.layer(name) lookup.</li> <li><span class='property-name'>name</span> (read-only): Layer name (str, read-only). Used for Grid.layer(name) lookup.</li>
<li><span class='property-name'>visible</span>: Whether the layer is rendered.</li> <li><span class='property-name'>visible</span>: Whether the layer is rendered (bool).</li>
<li><span class='property-name'>z_index</span>: Layer z-order. Negative values render below entities.</li> <li><span class='property-name'>z_index</span>: Layer z-order (int). Negative values render below entities.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">apply_gradient(source, range, color_low, color_high) -> ColorLayer</code></h5> <h5><code class="method-name">apply_gradient(source: HeightMap, range: tuple, color_low: Color, color_high: Color) -> ColorLayer</code></h5>
<p>Interpolate between colors based on HeightMap value within range. <p>Interpolate between two colors based on HeightMap value within a range. Uses the original heightmap value for smooth transitions.</p>
Note:</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>source</span>: Source heightmap (must match layer dimensions)</div>
<div><span class='arg-name'>range</span>: Value range as (min, max) inclusive</div>
<div><span class='arg-name'>color_low</span>: Color at range minimum</div> <div><span class='arg-name'>color_low</span>: Color at range minimum</div>
<div><span class='arg-name'>color_high</span>: Color at range maximum</div> <div><span class='arg-name'>color_high</span>: Color at range maximum</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining Uses the original HeightMap value for interpolation, not binary. This allows smooth color transitions within a value range.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">apply_perspective(entity, visible=None, discovered=None, unknown=None)</code></h5> <h5><code class="method-name">apply_perspective(entity: Entity, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None</code></h5>
<p>Bind this layer to an entity for automatic FOV updates.</p> <p>Bind this layer to an entity for automatic FOV updates. After binding, call update_perspective() when the entity moves.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>entity</span>: The entity whose perspective to track</div>
<div><span class='arg-name'>visible</span>: Color for currently visible cells</div>
<div><span class='arg-name'>discovered</span>: Color for previously seen cells</div>
<div><span class='arg-name'>unknown</span>: Color for never-seen cells</div>
</div>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">apply_ranges(source, ranges) -> ColorLayer</code></h5> <h5><code class="method-name">apply_ranges(source: HeightMap, ranges: list) -> ColorLayer</code></h5>
<p>Apply multiple color assignments in a single pass. <p>Apply multiple color assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping.
Note:</p> Note:</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining Later ranges override earlier ones if overlapping. Cells not matching any range are left unchanged.</p> <div style='margin-left: 20px;'>
<div><span class='arg-name'>source</span>: Source heightmap (must match layer dimensions)</div>
<div><span class='arg-name'>ranges</span>: List of range specs: ((min, max), color) for fixed or ((min, max), (color_low, color_high)) for gradient</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining Cells not matching any range are left unchanged.</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">apply_threshold(source, range, color) -> ColorLayer</code></h5> <h5><code class="method-name">apply_threshold(source: HeightMap, range: tuple, color: Color) -> ColorLayer</code></h5>
<p>Set fixed color for cells where HeightMap value is within range.</p> <p>Set a fixed color for cells where the HeightMap value falls within a range.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>source</span>: Source heightmap (must match layer dimensions)</div>
<div><span class='arg-name'>range</span>: Value range as (min, max) inclusive</div>
<div><span class='arg-name'>color</span>: Color or (r, g, b[, a]) tuple to set for cells in range</div> <div><span class='arg-name'>color</span>: Color or (r, g, b[, a]) tuple to set for cells in range</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">at(pos) -> Color</code></h5> <h5><code class="method-name">at(pos) or (x: int, y: int) -> Color</code></h5>
<p>at(x, y) -&gt; Color <p>Get the color at a cell position.</p>
Get the color at cell position.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector</div> <div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector; or pass x and y separately</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Color at the specified cell</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If coordinates are out of bounds</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">clear_perspective()</code></h5> <h5><code class="method-name">clear_perspective() -> None</code></h5>
<p>Remove the perspective binding from this layer.</p> <p>Remove the perspective binding from this layer.</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">draw_fov(source, radius=None, fov=None, visible=None, discovered=None, unknown=None)</code></h5> <h5><code class="method-name">draw_fov(source: tuple, radius: int = None, fov: FOV = None, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None</code></h5>
<p>Paint cells based on field-of-view visibility from source position. <p>Paint cells based on field-of-view visibility from a source position.
Note: Layer must be attached to a grid for FOV calculation.</p> Note:</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>source</span>: FOV origin as (x, y)</div>
<div><span class='arg-name'>radius</span>: FOV radius; defaults to the grid&#x27;s fov_radius</div>
<div><span class='arg-name'>fov</span>: FOV algorithm; defaults to the grid&#x27;s fov setting</div>
<div><span class='arg-name'>visible</span>: Color for currently visible cells</div>
<div><span class='arg-name'>discovered</span>: Color for previously seen cells</div>
<div><span class='arg-name'>unknown</span>: Color for never-seen cells</div>
</div>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">fill(color)</code></h5> <h5><code class="method-name">fill(color: Color) -> None</code></h5>
<p>Fill the entire layer with the specified color.</p> <p>Fill the entire layer with the specified color.</p>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">fill_rect(pos, size, color)</code></h5>
<p>Fill a rectangular region with a color.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>color</span>: Color object or (r, g, b[, a]) tuple</div> <div><span class='arg-name'>color</span>: Color object or (r, g, b[, a]) tuple</div>
</div> </div>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">set(pos, color)</code></h5> <h5><code class="method-name">fill_rect(pos: tuple, size: tuple, color: Color) -> None</code></h5>
<p>Set the color at cell position.</p> <p>Fill a rectangular region with a color.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Top-left corner as (x, y)</div>
<div><span class='arg-name'>size</span>: Dimensions as (width, height)</div>
<div><span class='arg-name'>color</span>: Color object or (r, g, b[, a]) tuple</div>
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">set(pos, color: Color) -> None</code></h5>
<p>Set the color at a cell position.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector</div> <div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector</div>
<div><span class='arg-name'>color</span>: Color object or (r, g, b[, a]) tuple</div> <div><span class='arg-name'>color</span>: Color object or (r, g, b[, a]) tuple</div>
</div> </div>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If coordinates are out of bounds</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">update_perspective()</code></h5> <h5><code class="method-name">update_perspective() -> None</code></h5>
<p>Redraw FOV based on the bound entity&#x27;s current position. <p>Redraw FOV based on the bound entity&#x27;s current position. Call this after the entity moves to update the visibility layer.</p>
Call this after the entity moves to update the visibility layer.</p> <p style='margin-left: 20px;'><span class='raises'>Raises:</span> RuntimeError: If no perspective binding has been set via apply_perspective()</p>
</div> </div>
</div> </div>
@ -1452,64 +1479,55 @@ Example:
<h4>Methods:</h4> <h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">descent_step(pos) -> Vector | None</code></h5> <h5><code class="method-name">descent_step(pos: Vector | tuple) -> Vector | None</code></h5>
<p>Get the adjacent cell with the lowest distance (steepest descent). <p>Get the adjacent cell with the lowest distance (steepest descent). Unlike step_from, this always returns the best neighbor in a single hop without following a precomputed path.</p>
Unlike step_from (which follows the path set by path_from), descent_step
always returns the best neighbor in a single hop. Useful for AI that
reacts to the current distance field rather than following a fixed path.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Current position as Vector, Entity, or (x, y) tuple.</div> <div><span class='arg-name'>pos</span>: Current position as Vector, Entity, or (x, y) tuple</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector, or None if pos is a local minimum or off-grid.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector, or None if pos is a local minimum or off-grid</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">distance(pos) -> float | None</code></h5> <h5><code class="method-name">distance(pos: Vector | tuple) -> float | None</code></h5>
<p>Get distance from position to root.</p> <p>Get distance from position to root.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Position as Vector, Entity, or (x, y) tuple.</div> <div><span class='arg-name'>pos</span>: Position as Vector, Entity, or (x, y) tuple</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Float distance, or None if position is unreachable.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> Float distance, or None if position is unreachable</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">invert() -> DijkstraMap</code></h5> <h5><code class="method-name">invert() -> DijkstraMap</code></h5>
<p>Return a NEW DijkstraMap whose distance field is the safety field. <p>Return a new DijkstraMap whose distance field is inverted (safety field). Cells near a root become high values; descend to flee from original roots. The original DijkstraMap is unchanged.</p>
Cells near a root become high values and cells far from any root become <p style='margin-left: 20px;'><span class='returns'>Returns:</span> New DijkstraMap with inverted distances</p>
low values. Combined with step_from or descent_step, this gives flee
behavior: descend the inverted map to move away from the original roots.
The original DijkstraMap is unchanged.</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> New DijkstraMap with inverted distances.</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">path_from(pos) -> AStarPath</code></h5> <h5><code class="method-name">path_from(pos: Vector | tuple) -> AStarPath</code></h5>
<p>Get full path from position to root.</p> <p>Get full path from position to root.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Starting position as Vector, Entity, or (x, y) tuple.</div> <div><span class='arg-name'>pos</span>: Starting position as Vector, Entity, or (x, y) tuple</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> AStarPath from pos toward root.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> AStarPath from pos toward root</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">step_from(pos) -> Vector | None</code></h5> <h5><code class="method-name">step_from(pos: Vector | tuple) -> Vector | None</code></h5>
<p>Get single step from position toward root.</p> <p>Get single step from position toward root.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Current position as Vector, Entity, or (x, y) tuple.</div> <div><span class='arg-name'>pos</span>: Current position as Vector, Entity, or (x, y) tuple</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector, or None if at root or unreachable.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> Next position as Vector, or None if at root or unreachable</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">to_heightmap(size=None, unreachable=-1.0) -> HeightMap</code></h5> <h5><code class="method-name">to_heightmap(size=None, unreachable=-1.0) -> HeightMap</code></h5>
<p>Convert distance field to a HeightMap. <p>Convert distance field to a HeightMap. Each cell&#x27;s height equals its pathfinding distance from the root, useful for visualization, procedural terrain, or influence mapping.</p>
Each cell&#x27;s height equals its pathfinding distance from the root.
Useful for visualization, procedural terrain, or influence mapping.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>size</span>: Optional (width, height) tuple. Defaults to dijkstra dimensions.</div> <div><span class='arg-name'>size</span>: Optional (width, height) tuple. Defaults to dijkstra dimensions</div>
<div><span class='arg-name'>unreachable</span>: Value for cells that cannot reach root (default -1.0).</div> <div><span class='arg-name'>unreachable</span>: Value for cells that cannot reach root (default -1.0)</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> HeightMap with distance values as heights.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> HeightMap with distance values as heights</p>
</div> </div>
</div> </div>
@ -1947,44 +1965,48 @@ Attributes:
<ul> <ul>
<li><span class='property-name'>behavior_type</span> (read-only): Current behavior type (int, read-only). Use set_behavior() to change.</li> <li><span class='property-name'>behavior_type</span> (read-only): Current behavior type (int, read-only). Use set_behavior() to change.</li>
<li><span class='property-name'>cell_pos</span>: Integer logical cell position (Vector). Alias for grid_pos (the canonical name).</li> <li><span class='property-name'>cell_pos</span>: Integer logical cell position (Vector). Alias for grid_pos (the canonical name).</li>
<li><span class='property-name'>cell_x</span>: Integer X cell coordinate. Alias for grid_x.</li> <li><span class='property-name'>cell_x</span>: Integer X cell coordinate (int). Alias for grid_x.</li>
<li><span class='property-name'>cell_y</span>: Integer Y cell coordinate. Alias for grid_y.</li> <li><span class='property-name'>cell_y</span>: Integer Y cell coordinate (int). Alias for grid_y.</li>
<li><span class='property-name'>default_behavior</span>: Default behavior type (int, maps to Behavior enum). Entity reverts to this after DONE trigger. Default: 0 (IDLE).</li> <li><span class='property-name'>default_behavior</span>: Default behavior type (int, maps to Behavior enum). Entity reverts to this after DONE trigger. Default: 0 (IDLE).</li>
<li><span class='property-name'>draw_pos</span>: Fractional tile position for rendering (Vector). Use for smooth animation between grid cells.</li> <li><span class='property-name'>draw_pos</span>: Fractional tile position for rendering (Vector). Use for smooth animation between grid cells.</li>
<li><span class='property-name'>grid</span>: Grid this entity belongs to. Get: Returns the Grid or None. Set: Assign a Grid to move entity, or None to remove from grid.</li> <li><span class='property-name'>grid</span>: Grid this entity belongs to (Grid or None). Assign a Grid to attach the entity, or None to remove it from its current grid.</li>
<li><span class='property-name'>grid_pos</span>: Integer logical cell position (Vector). Canonical cell-position property; matches the &#x27;grid_pos&#x27; constructor argument. Decoupled from draw_pos. Determines which cell this entity logically occupies for collision, pathfinding, etc.</li> <li><span class='property-name'>grid_pos</span>: Integer logical cell position (Vector). Canonical cell-position property matching the &#x27;grid_pos&#x27; constructor argument. Decoupled from draw_pos. Determines which cell this entity logically occupies for collision and pathfinding.</li>
<li><span class='property-name'>grid_x</span>: Integer X cell coordinate. Canonical; matches grid_pos.</li> <li><span class='property-name'>grid_x</span>: Integer X cell coordinate (int). Canonical; matches grid_pos.</li>
<li><span class='property-name'>grid_y</span>: Integer Y cell coordinate. Canonical; matches grid_pos.</li> <li><span class='property-name'>grid_y</span>: Integer Y cell coordinate (int). Canonical; matches grid_pos.</li>
<li><span class='property-name'>labels</span>: Set of string labels for collision/targeting (frozenset). Assign any iterable of strings to replace all labels.</li> <li><span class='property-name'>labels</span>: String labels for collision and targeting (frozenset). Assign any iterable of strings to replace all labels.</li>
<li><span class='property-name'>move_speed</span>: Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15.</li> <li><span class='property-name'>move_speed</span>: Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15.</li>
<li><span class='property-name'>name</span>: Name for finding elements</li> <li><span class='property-name'>name</span>: Entity name for lookup (str).</li>
<li><span class='property-name'>opacity</span>: Opacity (0.0 = transparent, 1.0 = opaque)</li> <li><span class='property-name'>opacity</span>: Render opacity (float). 0.0 = fully transparent, 1.0 = fully opaque.</li>
<li><span class='property-name'>perspective_map</span>: Per-entity FOV memory (DiscreteMap, read-write). 3-state values per cell: 0 = unknown (never seen), 1 = discovered (seen before, not currently visible), 2 = visible (in current FOV). Use mcrfpy.Perspective enum for clarity. Lazy-allocated on first access once the entity has a grid; returns None otherwise. The returned DiscreteMap is a live reference -- mutations are visible to subsequent updateVisibility() calls. Assigning a DiscreteMap replaces the entity&#x27;s memory; the new map&#x27;s size must match the grid&#x27;s size or ValueError is raised. Assign None to clear (will be lazy-reallocated on next access).</li> <li><span class='property-name'>perspective_map</span>: Per-entity FOV memory (DiscreteMap). 3-state values per cell: 0=unknown, 1=discovered, 2=visible. Lazy-allocated on first access once entity has a grid; returns None otherwise. The returned DiscreteMap is a live reference. Assigning a DiscreteMap replaces the entity&#x27;s memory; size must match the grid or ValueError is raised. Assign None to clear.</li>
<li><span class='property-name'>pos</span>: Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. Requires entity to be attached to a grid.</li> <li><span class='property-name'>pos</span>: Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. Requires entity to be attached to a grid.</li>
<li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the entity is rendered through the shader program. Set to None to disable shader effects.</li> <li><span class='property-name'>shader</span>: GPU shader for visual effects (Shader or None). Set to None to disable shader rendering.</li>
<li><span class='property-name'>sight_radius</span>: FOV radius for TARGET trigger (int). Default: 10.</li> <li><span class='property-name'>sight_radius</span>: FOV radius for TARGET trigger (int). Default: 10.</li>
<li><span class='property-name'>sprite_grid</span>: Per-tile sprite indices for composite multi-tile entities (list of lists or None). Row-major, dimensions must match tile_width x tile_height. Use -1 for empty tiles. When set, each tile renders its own sprite index instead of the single entity sprite.</li> <li><span class='property-name'>sprite_grid</span>: Per-tile sprite indices for composite multi-tile entities (list of lists or None). Row-major, dimensions must match tile_width x tile_height. Use -1 for empty tiles.</li>
<li><span class='property-name'>sprite_index</span>: Sprite index on the texture on the display</li> <li><span class='property-name'>sprite_index</span>: Sprite index into the entity&#x27;s texture atlas (int).</li>
<li><span class='property-name'>sprite_offset</span>: Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering.</li> <li><span class='property-name'>sprite_offset</span>: Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering.</li>
<li><span class='property-name'>sprite_offset_x</span>: X component of sprite pixel offset.</li> <li><span class='property-name'>sprite_offset_x</span>: X component of sprite pixel offset (float).</li>
<li><span class='property-name'>sprite_offset_y</span>: Y component of sprite pixel offset.</li> <li><span class='property-name'>sprite_offset_y</span>: Y component of sprite pixel offset (float).</li>
<li><span class='property-name'>step</span>: Step callback for grid.step() turn management. Called with (trigger, data) when behavior triggers fire. Set to None to clear.</li> <li><span class='property-name'>step</span>: Step callback for grid.step() turn management (Callable or None). Called with (trigger, data) when behavior triggers fire.</li>
<li><span class='property-name'>target_label</span>: Label to search for with TARGET trigger (str or None). Default: None.</li> <li><span class='property-name'>target_label</span>: Label to search for with TARGET trigger (str or None). Default: None.</li>
<li><span class='property-name'>texture</span>: Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture when the entity is constructed without one. Setting preserves sprite_index (the index is not re-validated against the new atlas). The grid&#x27;s texture only determines cell size; entities draw with their own.</li> <li><span class='property-name'>texture</span>: Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture at construction. Setting preserves sprite_index (not re-validated against the new atlas).</li>
<li><span class='property-name'>tile_height</span>: Entity height in tiles (int). Must be &gt;= 1. Default 1.</li> <li><span class='property-name'>tile_height</span>: Entity height in tiles (int). Must be &gt;= 1. Default 1.</li>
<li><span class='property-name'>tile_size</span>: Entity size in tiles as (width, height) Vector. Default (1, 1).</li> <li><span class='property-name'>tile_size</span>: Entity size in tiles as (width, height) (Vector). Default (1, 1).</li>
<li><span class='property-name'>tile_width</span>: Entity width in tiles (int). Must be &gt;= 1. Default 1.</li> <li><span class='property-name'>tile_width</span>: Entity width in tiles (int). Must be &gt;= 1. Default 1.</li>
<li><span class='property-name'>turn_order</span>: Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1.</li> <li><span class='property-name'>turn_order</span>: Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1.</li>
<li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: entity.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li> <li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (UniformCollection, read-only). Set values via dict-like syntax: entity.uniforms[&#x27;name&#x27;] = value.</li>
<li><span class='property-name'>visible</span>: Visibility flag</li> <li><span class='property-name'>visible</span>: Visibility flag (bool). When False, the entity is not rendered.</li>
<li><span class='property-name'>x</span>: Pixel X position relative to grid. Requires entity to be attached to a grid.</li> <li><span class='property-name'>x</span>: Pixel X position relative to grid (float). Requires entity to be attached to a grid.</li>
<li><span class='property-name'>y</span>: Pixel Y position relative to grid. Requires entity to be attached to a grid.</li> <li><span class='property-name'>y</span>: Pixel Y position relative to grid (float). Requires entity to be attached to a grid.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">add_label(label: str) -> None</code></h5> <h5><code class="method-name">add_label(label: str) -> None</code></h5>
<p>Add a label to this entity. Idempotent (adding same label twice is safe).</p> <p>Add a label to this entity. Idempotent; adding the same label twice is safe.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>label</span>: String label to add</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> None</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
@ -2007,43 +2029,51 @@ Note:</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">at(x, y) or at(pos) -> GridPoint | None</code></h5> <h5><code class="method-name">at(x: int, y: int) -> GridPoint | None</code></h5>
<p>Return the GridPoint at (x, y) if currently VISIBLE to this entity&#x27;s <p>Return the GridPoint at (x, y) if currently VISIBLE to this entity&#x27;s perspective_map, otherwise None.
perspective_map, otherwise None. Equivalent to:
grid.at(x, y) if perspective_map[x, y] == Perspective.VISIBLE else None Note:</p>
To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y]
directly and use grid.at(x, y) for cell data.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Grid coordinates as tuple, list, or Vector</div> <div><span class='arg-name'>x</span>: Grid X coordinate (also accepts a tuple/Vector as first positional arg)</div>
<div><span class='arg-name'>y</span>: Grid Y coordinate (omit when passing a tuple or Vector)</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> GridPoint if visible, None if undiscovered or not currently in FOV To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y] directly.</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">die(...)</code></h5> <h5><code class="method-name">die() -> None</code></h5>
<p>Remove this entity from its grid. <p>Remove this entity from its grid.
Warning: Do not call during iteration over grid.entities.
Modifying the collection during iteration raises RuntimeError.</p> Note:</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> None Do not call during iteration over grid.entities; modifying the collection during iteration raises RuntimeError.</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">find_path(target, diagonal_cost=1.41, collide=None) -> AStarPath | None</code></h5> <h5><code class="method-name">find_path(target, diagonal_cost: float = 1.41, collide: str = None) -> AStarPath | None</code></h5>
<p>Find a path from this entity to the target position.</p> <p>Find a path from this entity to the target position.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>target</span>: Target as Vector, Entity, or (x, y) tuple.</div> <div><span class='arg-name'>target</span>: Target as Vector, Entity, or (x, y) tuple</div>
<div><span class='arg-name'>diagonal_cost</span>: Cost of diagonal movement (default 1.41).</div> <div><span class='arg-name'>diagonal_cost</span>: Cost of diagonal movement (default 1.41)</div>
<div><span class='arg-name'>collide</span>: Label string. Entities with this label block pathfinding.</div> <div><span class='arg-name'>collide</span>: Label string; entities with this label block pathfinding</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> AStarPath object, or None if no path exists.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> AStarPath object, or None if no path exists</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> ValueError: If entity has no grid or positions are out of bounds</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">has_label(label: str) -> bool</code></h5> <h5><code class="method-name">has_label(label: str) -> bool</code></h5>
<p>Check if this entity has the given label.</p> <p>Check if this entity has the given label.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>label</span>: String label to check</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> True if the entity has the label, False otherwise</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">index(...)</code></h5> <h5><code class="method-name">index() -> int</code></h5>
<p>Return the index of this entity in its grid&#x27;s entity collection</p> <p>Return the index of this entity in its grid&#x27;s entity collection.</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Zero-based index of this entity in grid.entities</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> RuntimeError: If entity is not associated with a grid</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
@ -2059,17 +2089,23 @@ Note:</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">path_to(x, y) or path_to(target) -> list</code></h5> <h5><code class="method-name">path_to(x: int, y: int) -> list</code></h5>
<p>Find a path to the target position using Dijkstra pathfinding.</p> <p>Find a path to the target position using A* pathfinding.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>target</span>: Target coordinates as tuple, list, or Vector</div> <div><span class='arg-name'>x</span>: Target X coordinate (also accepts a tuple/Vector as first positional arg)</div>
<div><span class='arg-name'>y</span>: Target Y coordinate (omit when passing a tuple or Vector)</div>
</div> </div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> List of (x, y) tuples representing the path.</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> List of (x, y) tuples representing the path from current position to target</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> ValueError: If entity has no grid or target is out of bounds</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">remove_label(label: str) -> None</code></h5> <h5><code class="method-name">remove_label(label: str) -> None</code></h5>
<p>Remove a label from this entity. No-op if label not present.</p> <p>Remove a label from this entity. No-op if label is not present.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>label</span>: String label to remove</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> None</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
@ -2085,23 +2121,35 @@ Note:</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">set_behavior(type, waypoints=None, turns=0, path=None) -> None</code></h5> <h5><code class="method-name">set_behavior(type, waypoints=None, turns: int = 0, path=None, pathfinder=None) -> None</code></h5>
<p>Configure this entity&#x27;s behavior for grid.step() turn management.</p> <p>Configure this entity&#x27;s behavior for grid.step() turn management.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>type</span>: Behavior type (int or Behavior enum, e.g., Behavior.PATROL)</div>
<div><span class='arg-name'>waypoints</span>: List of (x, y) tuples for WAYPOINT/PATROL/LOOP behaviors</div>
<div><span class='arg-name'>turns</span>: Number of turns for SLEEP behavior</div>
<div><span class='arg-name'>path</span>: Pre-computed path as list of (x, y) tuples for PATH behavior</div>
<div><span class='arg-name'>pathfinder</span>: DijkstraMap, AStarPath, or (x, y) target tuple for SEEK behavior</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> None</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">update_visibility() -> None</code></h5> <h5><code class="method-name">update_visibility() -> None</code></h5>
<p>Update entity&#x27;s visibility state based on current FOV. <p>Recompute which cells are visible from this entity&#x27;s position and update perspective_map.
Recomputes which cells are visible from the entity&#x27;s position and updates
the entity&#x27;s perspective_map (see entity.perspective_map and mcrfpy.Perspective). Note:</p>
This is called automatically when the entity moves if it has a grid with <p style='margin-left: 20px;'><span class='returns'>Returns:</span> None Called automatically when the entity moves if the grid has FOV configured.</p>
perspective set.</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">visible_entities(fov=None, radius=None) -> list[Entity]</code></h5> <h5><code class="method-name">visible_entities(fov=None, radius: int = None) -> list[Entity]</code></h5>
<p>Get list of other entities visible from this entity&#x27;s position.</p> <p>Get list of other entities visible from this entity&#x27;s position.</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> List of Entity objects that are within field of view. Computes FOV from this entity&#x27;s position and returns all other entities whose positions fall within the visible area.</p> <div style='margin-left: 20px;'>
<div><span class='arg-name'>fov</span>: FOV algorithm to use (FOV enum or None to use grid.fov)</div>
<div><span class='arg-name'>radius</span>: FOV radius (int or None to use grid.fov_radius)</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> List of Entity objects within field of view, excluding self</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> ValueError: If entity is not associated with a grid</p>
</div> </div>
</div> </div>
@ -2421,38 +2469,38 @@ Attributes:
<ul> <ul>
<li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li> <li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li>
<li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>cache_subtree</span>: #144: Cache subtree rendering to texture for performance</li> <li><span class='property-name'>cache_subtree</span>: Cache the frame and all children to a render texture for performance (bool). Useful for complex static subtrees.</li>
<li><span class='property-name'>children</span>: UICollection of objects on top of this one</li> <li><span class='property-name'>children</span> (read-only): UICollection of child drawable objects rendered on top of this frame (UICollection, read-only).</li>
<li><span class='property-name'>clip_children</span>: Whether to clip children to frame bounds</li> <li><span class='property-name'>clip_children</span>: Whether to clip child elements to the frame&#x27;s bounds (bool). Enables render-texture mode when True.</li>
<li><span class='property-name'>fill_color</span>: Fill color of the rectangle. Returns a copy; modifying components requires reassignment. For animation, use &#x27;fill_color.r&#x27;, &#x27;fill_color.g&#x27;, etc.</li> <li><span class='property-name'>fill_color</span>: Fill color of the rectangle (Color). Returns a copy; modifying components requires reassignment. For animation, use &#x27;fill_color.r&#x27;, &#x27;fill_color.g&#x27;, etc.</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (Vector). Only meaningful when this element&#x27;s parent is a Grid.</li>
<li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (Vector). Only meaningful when this element&#x27;s parent is a Grid.</li>
<li><span class='property-name'>h</span>: height of the rectangle</li> <li><span class='property-name'>h</span>: Height of the rectangle (float).</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
<li><span class='property-name'>name</span>: Name for finding elements</li> <li><span class='property-name'>name</span>: Name for finding elements (str).</li>
<li><span class='property-name'>on_click</span>: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).</li> <li><span class='property-name'>on_click</span>: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).</li>
<li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li> <li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li>
<li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li> <li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li>
<li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li> <li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li>
<li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li> <li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li>
<li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li> <li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li>
<li><span class='property-name'>outline</span>: Thickness of the border</li> <li><span class='property-name'>outline</span>: Thickness of the border in pixels (float).</li>
<li><span class='property-name'>outline_color</span>: Outline color of the rectangle. Returns a copy; modifying components requires reassignment. For animation, use &#x27;outline_color.r&#x27;, &#x27;outline_color.g&#x27;, etc.</li> <li><span class='property-name'>outline_color</span>: Outline color of the rectangle (Color). Returns a copy; modifying components requires reassignment. For animation, use &#x27;outline_color.r&#x27;, &#x27;outline_color.g&#x27;, etc.</li>
<li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li> <li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li>
<li><span class='property-name'>pos</span>: Position as a Vector</li> <li><span class='property-name'>pos</span>: Position as a Vector (Vector).</li>
<li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li> <li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li>
<li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li> <li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li>
<li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li> <li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li>
<li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li> <li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li>
<li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li> <li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li>
<li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li> <li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li>
<li><span class='property-name'>w</span>: width of the rectangle</li> <li><span class='property-name'>w</span>: Width of the rectangle (float).</li>
<li><span class='property-name'>x</span>: X coordinate of top-left corner</li> <li><span class='property-name'>x</span>: X coordinate of the top-left corner (float).</li>
<li><span class='property-name'>y</span>: Y coordinate of top-left corner</li> <li><span class='property-name'>y</span>: Y coordinate of the top-left corner (float).</li>
<li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.</li> <li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
@ -2543,39 +2591,39 @@ Keyword Args:
<ul> <ul>
<li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li> <li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li>
<li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>camera_rotation</span>: Rotation of grid contents around camera center (degrees).</li> <li><span class='property-name'>camera_rotation</span>: Rotation of grid contents around camera center in degrees (float).</li>
<li><span class='property-name'>center</span>: Camera center point in pixel coordinates.</li> <li><span class='property-name'>center</span>: Camera center point in pixel coordinates (tuple).</li>
<li><span class='property-name'>center_x</span>: center of the view X-coordinate</li> <li><span class='property-name'>center_x</span>: Camera center X-coordinate in pixel space (float).</li>
<li><span class='property-name'>center_y</span>: center of the view Y-coordinate</li> <li><span class='property-name'>center_y</span>: Camera center Y-coordinate in pixel space (float).</li>
<li><span class='property-name'>fill_color</span>: Background fill color.</li> <li><span class='property-name'>fill_color</span>: Background fill color (Color). Drawn behind all tiles and entities.</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_data</span>: The underlying grid data object (for multi-view scenarios).</li> <li><span class='property-name'>grid_data</span>: The underlying grid data object (Grid | None). Used for multi-view scenarios where multiple GridViews share one Grid.</li>
<li><span class='property-name'>h</span>: visible widget height</li> <li><span class='property-name'>h</span>: Visible widget height (float).</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
<li><span class='property-name'>name</span>: Name for finding elements</li> <li><span class='property-name'>name</span>: Name for finding elements (str).</li>
<li><span class='property-name'>on_click</span>: Callable executed when object is clicked.</li> <li><span class='property-name'>on_click</span>: Callable executed when object is clicked (Callable | None).</li>
<li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li> <li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li>
<li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li> <li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li>
<li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li> <li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li>
<li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li> <li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li>
<li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li> <li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li>
<li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li> <li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li>
<li><span class='property-name'>pos</span>: Position of the grid as Vector</li> <li><span class='property-name'>pos</span>: Position of the grid as Vector (Vector).</li>
<li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li> <li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li>
<li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li> <li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li>
<li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li> <li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li>
<li><span class='property-name'>texture</span> (read-only): Texture used for tile rendering (read-only).</li> <li><span class='property-name'>texture</span> (read-only): Texture used for tile rendering (Texture | None, read-only).</li>
<li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li> <li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li>
<li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li> <li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li>
<li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li> <li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li>
<li><span class='property-name'>w</span>: visible widget width</li> <li><span class='property-name'>w</span>: Visible widget width (float).</li>
<li><span class='property-name'>x</span>: top-left corner X-coordinate</li> <li><span class='property-name'>x</span>: Top-left corner X-coordinate (float).</li>
<li><span class='property-name'>y</span>: top-left corner Y-coordinate</li> <li><span class='property-name'>y</span>: Top-left corner Y-coordinate (float).</li>
<li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first).</li> <li><span class='property-name'>z_index</span>: Z-order for rendering (int). Lower values are rendered first.</li>
<li><span class='property-name'>zoom</span>: Zoom level for rendering.</li> <li><span class='property-name'>zoom</span>: Zoom level for rendering (float). Values greater than 1.0 magnify; less than 1.0 shrink.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
@ -2665,39 +2713,39 @@ Keyword Args:
<ul> <ul>
<li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li> <li><span class='property-name'>align</span>: Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None to disable alignment and use manual positioning.</li>
<li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>camera_rotation</span>: Rotation of grid contents around camera center (degrees).</li> <li><span class='property-name'>camera_rotation</span>: Rotation of grid contents around camera center in degrees (float).</li>
<li><span class='property-name'>center</span>: Camera center point in pixel coordinates.</li> <li><span class='property-name'>center</span>: Camera center point in pixel coordinates (tuple).</li>
<li><span class='property-name'>center_x</span>: center of the view X-coordinate</li> <li><span class='property-name'>center_x</span>: Camera center X-coordinate in pixel space (float).</li>
<li><span class='property-name'>center_y</span>: center of the view Y-coordinate</li> <li><span class='property-name'>center_y</span>: Camera center Y-coordinate in pixel space (float).</li>
<li><span class='property-name'>fill_color</span>: Background fill color.</li> <li><span class='property-name'>fill_color</span>: Background fill color (Color). Drawn behind all tiles and entities.</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_data</span>: The underlying grid data object (for multi-view scenarios).</li> <li><span class='property-name'>grid_data</span>: The underlying grid data object (Grid | None). Used for multi-view scenarios where multiple GridViews share one Grid.</li>
<li><span class='property-name'>h</span>: visible widget height</li> <li><span class='property-name'>h</span>: Visible widget height (float).</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
<li><span class='property-name'>name</span>: Name for finding elements</li> <li><span class='property-name'>name</span>: Name for finding elements (str).</li>
<li><span class='property-name'>on_click</span>: Callable executed when object is clicked.</li> <li><span class='property-name'>on_click</span>: Callable executed when object is clicked (Callable | None).</li>
<li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li> <li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li>
<li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li> <li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li>
<li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li> <li><span class='property-name'>on_move</span>: Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called frequently during movement - keep handlers fast.</li>
<li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li> <li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li>
<li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li> <li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li>
<li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li> <li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li>
<li><span class='property-name'>pos</span>: Position of the grid as Vector</li> <li><span class='property-name'>pos</span>: Position of the grid as Vector (Vector).</li>
<li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li> <li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li>
<li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li> <li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li>
<li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li> <li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li>
<li><span class='property-name'>texture</span> (read-only): Texture used for tile rendering (read-only).</li> <li><span class='property-name'>texture</span> (read-only): Texture used for tile rendering (Texture | None, read-only).</li>
<li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li> <li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li>
<li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li> <li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li>
<li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li> <li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li>
<li><span class='property-name'>w</span>: visible widget width</li> <li><span class='property-name'>w</span>: Visible widget width (float).</li>
<li><span class='property-name'>x</span>: top-left corner X-coordinate</li> <li><span class='property-name'>x</span>: Top-left corner X-coordinate (float).</li>
<li><span class='property-name'>y</span>: top-left corner Y-coordinate</li> <li><span class='property-name'>y</span>: Top-left corner Y-coordinate (float).</li>
<li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first).</li> <li><span class='property-name'>z_index</span>: Z-order for rendering (int). Lower values are rendered first.</li>
<li><span class='property-name'>zoom</span>: Zoom level for rendering.</li> <li><span class='property-name'>zoom</span>: Zoom level for rendering (float). Values greater than 1.0 magnify; less than 1.0 shrink.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
@ -3582,8 +3630,8 @@ Attributes:
<li><span class='property-name'>end</span>: Ending point of the line as a Vector.</li> <li><span class='property-name'>end</span>: Ending point of the line as a Vector.</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (Vector, only when parent is Grid).</li>
<li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (Vector, only when parent is Grid).</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
@ -4468,12 +4516,12 @@ Attributes:
<li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>bounds</span>: Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li> <li><span class='property-name'>global_bounds</span>: Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).</li>
<li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li> <li><span class='property-name'>global_position</span> (read-only): Global screen position (read-only). Calculates absolute position by walking up the parent chain.</li>
<li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_pos</span>: Position in grid tile coordinates (Vector, only when parent is Grid).</li>
<li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (only when parent is Grid)</li> <li><span class='property-name'>grid_size</span>: Size in grid tile coordinates (Vector, only when parent is Grid).</li>
<li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li> <li><span class='property-name'>horiz_margin</span>: Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).</li>
<li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li> <li><span class='property-name'>hovered</span> (read-only): Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.</li>
<li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li> <li><span class='property-name'>margin</span>: General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueError).</li>
<li><span class='property-name'>name</span>: Name for finding elements</li> <li><span class='property-name'>name</span>: Name for finding elements (str).</li>
<li><span class='property-name'>on_click</span>: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).</li> <li><span class='property-name'>on_click</span>: Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).</li>
<li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li> <li><span class='property-name'>on_enter</span>: Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element&#x27;s bounds.</li>
<li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li> <li><span class='property-name'>on_exit</span>: Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element&#x27;s bounds.</li>
@ -4481,20 +4529,20 @@ Attributes:
<li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li> <li><span class='property-name'>opacity</span>: Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].</li>
<li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li> <li><span class='property-name'>origin</span>: Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.</li>
<li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li> <li><span class='property-name'>parent</span>: Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.</li>
<li><span class='property-name'>pos</span>: Position as a Vector</li> <li><span class='property-name'>pos</span>: Position as a Vector (Vector).</li>
<li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li> <li><span class='property-name'>rotate_with_camera</span>: Whether to rotate visually with parent Grid&#x27;s camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of UIGrid; ignored for other parents.</li>
<li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li> <li><span class='property-name'>rotation</span>: Rotation angle in degrees (clockwise around origin). Animatable property.</li>
<li><span class='property-name'>scale</span>: Uniform size factor</li> <li><span class='property-name'>scale</span>: Uniform size factor (float). Sets both horizontal and vertical scale to the same value.</li>
<li><span class='property-name'>scale_x</span>: Horizontal scale factor</li> <li><span class='property-name'>scale_x</span>: Horizontal scale factor (float).</li>
<li><span class='property-name'>scale_y</span>: Vertical scale factor</li> <li><span class='property-name'>scale_y</span>: Vertical scale factor (float).</li>
<li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li> <li><span class='property-name'>shader</span>: Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.</li>
<li><span class='property-name'>sprite_index</span>: Which sprite on the texture is shown</li> <li><span class='property-name'>sprite_index</span>: Which sprite on the texture is shown (int). Index into the texture atlas; must be in range [0, sprite_count).</li>
<li><span class='property-name'>texture</span>: Texture object</li> <li><span class='property-name'>texture</span>: Texture object (Texture). The texture atlas from which sprites are drawn.</li>
<li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li> <li><span class='property-name'>uniforms</span> (read-only): Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms[&#x27;name&#x27;] = value. Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.</li>
<li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li> <li><span class='property-name'>vert_margin</span>: Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).</li>
<li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li> <li><span class='property-name'>visible</span>: Whether the object is visible (bool). Invisible objects are not rendered or clickable.</li>
<li><span class='property-name'>x</span>: X coordinate of top-left corner</li> <li><span class='property-name'>x</span>: X coordinate of top-left corner (float).</li>
<li><span class='property-name'>y</span>: Y coordinate of top-left corner</li> <li><span class='property-name'>y</span>: Y coordinate of top-left corner (float).</li>
<li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.</li> <li><span class='property-name'>z_index</span>: Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
@ -4679,55 +4727,74 @@ Example:
grid.layer(&#x27;terrain&#x27;).set(5, 5, 42) # Place tile 42 at (5, 5)</p> grid.layer(&#x27;terrain&#x27;).set(5, 5, 42) # Place tile 42 at (5, 5)</p>
<h4>Properties:</h4> <h4>Properties:</h4>
<ul> <ul>
<li><span class='property-name'>grid</span>: Parent Grid or None. Setting manages layer association and handles lazy allocation.</li> <li><span class='property-name'>grid</span>: Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation.</li>
<li><span class='property-name'>grid_size</span>: Layer dimensions as (width, height) tuple.</li> <li><span class='property-name'>grid_size</span> (read-only): Layer dimensions as (width, height) tuple (tuple, read-only).</li>
<li><span class='property-name'>name</span> (read-only): Layer name (str, read-only). Used for Grid.layer(name) lookup.</li> <li><span class='property-name'>name</span> (read-only): Layer name (str, read-only). Used for Grid.layer(name) lookup.</li>
<li><span class='property-name'>texture</span>: Texture atlas for tile sprites.</li> <li><span class='property-name'>texture</span>: Texture atlas for tile sprites (Texture | None).</li>
<li><span class='property-name'>visible</span>: Whether the layer is rendered.</li> <li><span class='property-name'>visible</span>: Whether the layer is rendered (bool).</li>
<li><span class='property-name'>z_index</span>: Layer z-order. Negative values render below entities.</li> <li><span class='property-name'>z_index</span>: Layer z-order (int). Negative values render below entities.</li>
</ul> </ul>
<h4>Methods:</h4> <h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">apply_ranges(source, ranges) -> TileLayer</code></h5> <h5><code class="method-name">apply_ranges(source: HeightMap, ranges: list) -> TileLayer</code></h5>
<p>Apply multiple tile assignments in a single pass. <p>Apply multiple tile assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping.
Note:</p> Note:</p>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining Later ranges override earlier ones if overlapping. Cells not matching any range are left unchanged.</p> <div style='margin-left: 20px;'>
<div><span class='arg-name'>source</span>: Source heightmap (must match layer dimensions)</div>
<div><span class='arg-name'>ranges</span>: List of ((min, max), tile_index) tuples</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining Cells not matching any range are left unchanged.</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">apply_threshold(source, range, tile) -> TileLayer</code></h5> <h5><code class="method-name">apply_threshold(source: HeightMap, range: tuple, tile: int) -> TileLayer</code></h5>
<p>Set tile index for cells where HeightMap value is within range.</p> <p>Set a tile index for cells where the HeightMap value falls within a range.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>source</span>: Source heightmap (must match layer dimensions)</div>
<div><span class='arg-name'>range</span>: Value range as (min, max) inclusive</div>
<div><span class='arg-name'>tile</span>: Tile index to set for cells in range</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining</p> <p style='margin-left: 20px;'><span class='returns'>Returns:</span> self for method chaining</p>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">at(pos) -> int</code></h5> <h5><code class="method-name">at(pos) or (x: int, y: int) -> int</code></h5>
<p>at(x, y) -&gt; int <p>Get the tile index at a cell position. Returns -1 if no tile is set.</p>
Get the tile index at cell position. Returns -1 if no tile.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector</div> <div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector; or pass x and y separately</div>
</div>
<p style='margin-left: 20px;'><span class='returns'>Returns:</span> Tile index at the specified cell, or -1 if empty</p>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If coordinates are out of bounds</p>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">fill(index: int) -> None</code></h5>
<p>Fill the entire layer with the specified tile index.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>index</span>: Tile index to fill with (-1 for no tile)</div>
</div> </div>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">fill(index)</code></h5> <h5><code class="method-name">fill_rect(pos: tuple, size: tuple, index: int) -> None</code></h5>
<p>Fill the entire layer with the specified tile index.</p>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">fill_rect(pos, size, index)</code></h5>
<p>Fill a rectangular region with a tile index.</p> <p>Fill a rectangular region with a tile index.</p>
<div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Top-left corner as (x, y)</div>
<div><span class='arg-name'>size</span>: Dimensions as (width, height)</div>
<div><span class='arg-name'>index</span>: Tile index to fill with (-1 for no tile)</div>
</div>
</div> </div>
<div style="margin-left: 20px; margin-bottom: 15px;"> <div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method-name">set(pos, index)</code></h5> <h5><code class="method-name">set(pos, index: int) -> None</code></h5>
<p>Set the tile index at cell position. Use -1 for no tile.</p> <p>Set the tile index at a cell position. Use -1 to clear the tile.</p>
<div style='margin-left: 20px;'> <div style='margin-left: 20px;'>
<div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector</div> <div><span class='arg-name'>pos</span>: Position as (x, y) tuple, list, or Vector</div>
<div><span class='arg-name'>index</span>: Tile index (-1 for no tile)</div> <div><span class='arg-name'>index</span>: Tile index (-1 for no tile)</div>
</div> </div>
<p style='margin-left: 20px;'><span class='raises'>Raises:</span> IndexError: If coordinates are out of bounds</p>
</div> </div>
</div> </div>

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
#include "GridLayers.h" #include "GridLayers.h"
#include "McRFPy_Doc.h"
#include "UIGrid.h" #include "UIGrid.h"
#include "UIGridView.h" #include "UIGridView.h"
#include "UIEntity.h" #include "UIEntity.h"
@ -699,117 +700,121 @@ void TileLayer::render(sf::RenderTarget& target,
PyMethodDef PyGridLayerAPI::ColorLayer_methods[] = { PyMethodDef PyGridLayerAPI::ColorLayer_methods[] = {
{"at", (PyCFunction)PyGridLayerAPI::ColorLayer_at, METH_VARARGS | METH_KEYWORDS, {"at", (PyCFunction)PyGridLayerAPI::ColorLayer_at, METH_VARARGS | METH_KEYWORDS,
"at(pos) -> Color\nat(x, y) -> Color\n\n" MCRF_METHOD(ColorLayer, at,
"Get the color at cell position.\n\n" MCRF_SIG("(pos) or (x: int, y: int)", "Color"),
"Args:\n" MCRF_DESC("Get the color at a cell position.")
" pos: Position as (x, y) tuple, list, or Vector\n" MCRF_ARGS_START
" x, y: Position as separate integer arguments"}, MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector; or pass x and y separately")
MCRF_RETURNS("Color at the specified cell")
MCRF_RAISES("IndexError", "If coordinates are out of bounds")
)},
{"set", (PyCFunction)PyGridLayerAPI::ColorLayer_set, METH_VARARGS, {"set", (PyCFunction)PyGridLayerAPI::ColorLayer_set, METH_VARARGS,
"set(pos, color)\n\n" MCRF_METHOD(ColorLayer, set,
"Set the color at cell position.\n\n" MCRF_SIG("(pos, color: Color)", "None"),
"Args:\n" MCRF_DESC("Set the color at a cell position.")
" pos: Position as (x, y) tuple, list, or Vector\n" MCRF_ARGS_START
" color: Color object or (r, g, b[, a]) tuple"}, MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector")
MCRF_ARG("color", "Color object or (r, g, b[, a]) tuple")
MCRF_RAISES("IndexError", "If coordinates are out of bounds")
)},
{"fill", (PyCFunction)PyGridLayerAPI::ColorLayer_fill, METH_VARARGS, {"fill", (PyCFunction)PyGridLayerAPI::ColorLayer_fill, METH_VARARGS,
"fill(color)\n\nFill the entire layer with the specified color."}, MCRF_METHOD(ColorLayer, fill,
MCRF_SIG("(color: Color)", "None"),
MCRF_DESC("Fill the entire layer with the specified color.")
MCRF_ARGS_START
MCRF_ARG("color", "Color object or (r, g, b[, a]) tuple")
)},
{"fill_rect", (PyCFunction)PyGridLayerAPI::ColorLayer_fill_rect, METH_VARARGS | METH_KEYWORDS, {"fill_rect", (PyCFunction)PyGridLayerAPI::ColorLayer_fill_rect, METH_VARARGS | METH_KEYWORDS,
"fill_rect(pos, size, color)\n\n" MCRF_METHOD(ColorLayer, fill_rect,
"Fill a rectangular region with a color.\n\n" MCRF_SIG("(pos: tuple, size: tuple, color: Color)", "None"),
"Args:\n" MCRF_DESC("Fill a rectangular region with a color.")
" pos (tuple): Top-left corner as (x, y)\n" MCRF_ARGS_START
" size (tuple): Dimensions as (width, height)\n" MCRF_ARG("pos", "Top-left corner as (x, y)")
" color: Color object or (r, g, b[, a]) tuple"}, MCRF_ARG("size", "Dimensions as (width, height)")
MCRF_ARG("color", "Color object or (r, g, b[, a]) tuple")
)},
{"draw_fov", (PyCFunction)PyGridLayerAPI::ColorLayer_draw_fov, METH_VARARGS | METH_KEYWORDS, {"draw_fov", (PyCFunction)PyGridLayerAPI::ColorLayer_draw_fov, METH_VARARGS | METH_KEYWORDS,
"draw_fov(source, radius=None, fov=None, visible=None, discovered=None, unknown=None)\n\n" MCRF_METHOD(ColorLayer, draw_fov,
"Paint cells based on field-of-view visibility from source position.\n\n" MCRF_SIG("(source: tuple, radius: int = None, fov: FOV = None, visible: Color = None, discovered: Color = None, unknown: Color = None)", "None"),
"Args:\n" MCRF_DESC("Paint cells based on field-of-view visibility from a source position.")
" source (tuple): FOV origin as (x, y)\n" MCRF_ARGS_START
" radius (int): FOV radius. Default: grid's fov_radius\n" MCRF_ARG("source", "FOV origin as (x, y)")
" fov (FOV): FOV algorithm. Default: grid's fov setting\n" MCRF_ARG("radius", "FOV radius; defaults to the grid's fov_radius")
" visible (Color): Color for currently visible cells\n" MCRF_ARG("fov", "FOV algorithm; defaults to the grid's fov setting")
" discovered (Color): Color for previously seen cells\n" MCRF_ARG("visible", "Color for currently visible cells")
" unknown (Color): Color for never-seen cells\n\n" MCRF_ARG("discovered", "Color for previously seen cells")
"Note: Layer must be attached to a grid for FOV calculation."}, MCRF_ARG("unknown", "Color for never-seen cells")
MCRF_NOTE("Layer must be attached to a grid for FOV calculation.")
)},
{"apply_perspective", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_perspective, METH_VARARGS | METH_KEYWORDS, {"apply_perspective", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_perspective, METH_VARARGS | METH_KEYWORDS,
"apply_perspective(entity, visible=None, discovered=None, unknown=None)\n\n" MCRF_METHOD(ColorLayer, apply_perspective,
"Bind this layer to an entity for automatic FOV updates.\n\n" MCRF_SIG("(entity: Entity, visible: Color = None, discovered: Color = None, unknown: Color = None)", "None"),
"Args:\n" MCRF_DESC("Bind this layer to an entity for automatic FOV updates. After binding, call update_perspective() when the entity moves.")
" entity (Entity): The entity whose perspective to track\n" MCRF_ARGS_START
" visible (Color): Color for currently visible cells\n" MCRF_ARG("entity", "The entity whose perspective to track")
" discovered (Color): Color for previously seen cells\n" MCRF_ARG("visible", "Color for currently visible cells")
" unknown (Color): Color for never-seen cells\n\n" MCRF_ARG("discovered", "Color for previously seen cells")
"After binding, call update_perspective() when the entity moves."}, MCRF_ARG("unknown", "Color for never-seen cells")
)},
{"update_perspective", (PyCFunction)PyGridLayerAPI::ColorLayer_update_perspective, METH_NOARGS, {"update_perspective", (PyCFunction)PyGridLayerAPI::ColorLayer_update_perspective, METH_NOARGS,
"update_perspective()\n\n" MCRF_METHOD(ColorLayer, update_perspective,
"Redraw FOV based on the bound entity's current position.\n\n" MCRF_SIG("()", "None"),
"Call this after the entity moves to update the visibility layer."}, MCRF_DESC("Redraw FOV based on the bound entity's current position. Call this after the entity moves to update the visibility layer.")
MCRF_RAISES("RuntimeError", "If no perspective binding has been set via apply_perspective()")
)},
{"clear_perspective", (PyCFunction)PyGridLayerAPI::ColorLayer_clear_perspective, METH_NOARGS, {"clear_perspective", (PyCFunction)PyGridLayerAPI::ColorLayer_clear_perspective, METH_NOARGS,
"clear_perspective()\n\n" MCRF_METHOD(ColorLayer, clear_perspective,
"Remove the perspective binding from this layer."}, MCRF_SIG("()", "None"),
MCRF_DESC("Remove the perspective binding from this layer.")
)},
{"apply_threshold", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_hmap_threshold, METH_VARARGS | METH_KEYWORDS, {"apply_threshold", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_hmap_threshold, METH_VARARGS | METH_KEYWORDS,
"apply_threshold(source, range, color) -> ColorLayer\n\n" MCRF_METHOD(ColorLayer, apply_threshold,
"Set fixed color for cells where HeightMap value is within range.\n\n" MCRF_SIG("(source: HeightMap, range: tuple, color: Color)", "ColorLayer"),
"Args:\n" MCRF_DESC("Set a fixed color for cells where the HeightMap value falls within a range.")
" source (HeightMap): Source heightmap (must match layer dimensions)\n" MCRF_ARGS_START
" range (tuple): Value range as (min, max) inclusive\n" MCRF_ARG("source", "Source heightmap (must match layer dimensions)")
" color: Color or (r, g, b[, a]) tuple to set for cells in range\n\n" MCRF_ARG("range", "Value range as (min, max) inclusive")
"Returns:\n" MCRF_ARG("color", "Color or (r, g, b[, a]) tuple to set for cells in range")
" self for method chaining\n\n" MCRF_RETURNS("self for method chaining")
"Example:\n" )},
" layer.apply_threshold(terrain, (0.0, 0.3), (0, 0, 180)) # Blue for water"},
{"apply_gradient", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_gradient, METH_VARARGS | METH_KEYWORDS, {"apply_gradient", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_gradient, METH_VARARGS | METH_KEYWORDS,
"apply_gradient(source, range, color_low, color_high) -> ColorLayer\n\n" MCRF_METHOD(ColorLayer, apply_gradient,
"Interpolate between colors based on HeightMap value within range.\n\n" MCRF_SIG("(source: HeightMap, range: tuple, color_low: Color, color_high: Color)", "ColorLayer"),
"Args:\n" MCRF_DESC("Interpolate between two colors based on HeightMap value within a range. Uses the original heightmap value for smooth transitions.")
" source (HeightMap): Source heightmap (must match layer dimensions)\n" MCRF_ARGS_START
" range (tuple): Value range as (min, max) inclusive\n" MCRF_ARG("source", "Source heightmap (must match layer dimensions)")
" color_low: Color at range minimum\n" MCRF_ARG("range", "Value range as (min, max) inclusive")
" color_high: Color at range maximum\n\n" MCRF_ARG("color_low", "Color at range minimum")
"Returns:\n" MCRF_ARG("color_high", "Color at range maximum")
" self for method chaining\n\n" MCRF_RETURNS("self for method chaining")
"Note:\n" )},
" Uses the original HeightMap value for interpolation, not binary.\n"
" This allows smooth color transitions within a value range.\n\n"
"Example:\n"
" layer.apply_gradient(terrain, (0.3, 0.7),\n"
" (50, 120, 50), # Dark green at 0.3\n"
" (100, 200, 100)) # Light green at 0.7"},
{"apply_ranges", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_ranges, METH_VARARGS, {"apply_ranges", (PyCFunction)PyGridLayerAPI::ColorLayer_apply_ranges, METH_VARARGS,
"apply_ranges(source, ranges) -> ColorLayer\n\n" MCRF_METHOD(ColorLayer, apply_ranges,
"Apply multiple color assignments in a single pass.\n\n" MCRF_SIG("(source: HeightMap, ranges: list)", "ColorLayer"),
"Args:\n" MCRF_DESC("Apply multiple color assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping.")
" source (HeightMap): Source heightmap (must match layer dimensions)\n" MCRF_ARGS_START
" ranges (list): List of range specifications. Each entry is:\n" MCRF_ARG("source", "Source heightmap (must match layer dimensions)")
" ((min, max), (r, g, b[, a])) - for fixed color\n" MCRF_ARG("ranges", "List of range specs: ((min, max), color) for fixed or ((min, max), (color_low, color_high)) for gradient")
" ((min, max), ((r1, g1, b1[, a1]), (r2, g2, b2[, a2]))) - for gradient\n\n" MCRF_RETURNS("self for method chaining")
"Returns:\n" MCRF_NOTE("Cells not matching any range are left unchanged.")
" self for method chaining\n\n" )},
"Note:\n"
" Later ranges override earlier ones if overlapping.\n"
" Cells not matching any range are left unchanged.\n\n"
"Example:\n"
" layer.apply_ranges(terrain, [\n"
" ((0.0, 0.3), (0, 0, 180)), # Fixed blue\n"
" ((0.3, 0.7), ((50, 120, 50), (100, 200, 100))), # Gradient\n"
" ((0.7, 1.0), ((100, 100, 100), (255, 255, 255))), # Gradient\n"
" ])"},
{NULL} {NULL}
}; };
PyGetSetDef PyGridLayerAPI::ColorLayer_getsetters[] = { PyGetSetDef PyGridLayerAPI::ColorLayer_getsetters[] = {
{"z_index", (getter)PyGridLayerAPI::ColorLayer_get_z_index, {"z_index", (getter)PyGridLayerAPI::ColorLayer_get_z_index,
(setter)PyGridLayerAPI::ColorLayer_set_z_index, (setter)PyGridLayerAPI::ColorLayer_set_z_index,
"Layer z-order. Negative values render below entities.", NULL}, MCRF_PROPERTY(z_index, "Layer z-order (int). Negative values render below entities."), NULL},
{"visible", (getter)PyGridLayerAPI::ColorLayer_get_visible, {"visible", (getter)PyGridLayerAPI::ColorLayer_get_visible,
(setter)PyGridLayerAPI::ColorLayer_set_visible, (setter)PyGridLayerAPI::ColorLayer_set_visible,
"Whether the layer is rendered.", NULL}, MCRF_PROPERTY(visible, "Whether the layer is rendered (bool)."), NULL},
{"grid_size", (getter)PyGridLayerAPI::ColorLayer_get_grid_size, NULL, {"grid_size", (getter)PyGridLayerAPI::ColorLayer_get_grid_size, NULL,
"Layer dimensions as (width, height) tuple.", NULL}, MCRF_PROPERTY(grid_size, "Layer dimensions as (width, height) tuple (tuple, read-only)."), NULL},
{"name", (getter)PyGridLayerAPI::ColorLayer_get_name, NULL, {"name", (getter)PyGridLayerAPI::ColorLayer_get_name, NULL,
"Layer name (str, read-only). Used for Grid.layer(name) lookup.", NULL}, MCRF_PROPERTY(name, "Layer name (str, read-only). Used for Grid.layer(name) lookup."), NULL},
{"grid", (getter)PyGridLayerAPI::ColorLayer_get_grid, {"grid", (getter)PyGridLayerAPI::ColorLayer_get_grid,
(setter)PyGridLayerAPI::ColorLayer_set_grid, (setter)PyGridLayerAPI::ColorLayer_set_grid,
"Parent Grid or None. Setting manages layer association and handles lazy allocation.", NULL}, MCRF_PROPERTY(grid, "Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation."), NULL},
{NULL} {NULL}
}; };
@ -1875,74 +1880,79 @@ PyObject* PyGridLayerAPI::ColorLayer_repr(PyColorLayerObject* self) {
PyMethodDef PyGridLayerAPI::TileLayer_methods[] = { PyMethodDef PyGridLayerAPI::TileLayer_methods[] = {
{"at", (PyCFunction)PyGridLayerAPI::TileLayer_at, METH_VARARGS | METH_KEYWORDS, {"at", (PyCFunction)PyGridLayerAPI::TileLayer_at, METH_VARARGS | METH_KEYWORDS,
"at(pos) -> int\nat(x, y) -> int\n\n" MCRF_METHOD(TileLayer, at,
"Get the tile index at cell position. Returns -1 if no tile.\n\n" MCRF_SIG("(pos) or (x: int, y: int)", "int"),
"Args:\n" MCRF_DESC("Get the tile index at a cell position. Returns -1 if no tile is set.")
" pos: Position as (x, y) tuple, list, or Vector\n" MCRF_ARGS_START
" x, y: Position as separate integer arguments"}, MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector; or pass x and y separately")
MCRF_RETURNS("Tile index at the specified cell, or -1 if empty")
MCRF_RAISES("IndexError", "If coordinates are out of bounds")
)},
{"set", (PyCFunction)PyGridLayerAPI::TileLayer_set, METH_VARARGS, {"set", (PyCFunction)PyGridLayerAPI::TileLayer_set, METH_VARARGS,
"set(pos, index)\n\n" MCRF_METHOD(TileLayer, set,
"Set the tile index at cell position. Use -1 for no tile.\n\n" MCRF_SIG("(pos, index: int)", "None"),
"Args:\n" MCRF_DESC("Set the tile index at a cell position. Use -1 to clear the tile.")
" pos: Position as (x, y) tuple, list, or Vector\n" MCRF_ARGS_START
" index: Tile index (-1 for no tile)"}, MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector")
MCRF_ARG("index", "Tile index (-1 for no tile)")
MCRF_RAISES("IndexError", "If coordinates are out of bounds")
)},
{"fill", (PyCFunction)PyGridLayerAPI::TileLayer_fill, METH_VARARGS, {"fill", (PyCFunction)PyGridLayerAPI::TileLayer_fill, METH_VARARGS,
"fill(index)\n\nFill the entire layer with the specified tile index."}, MCRF_METHOD(TileLayer, fill,
MCRF_SIG("(index: int)", "None"),
MCRF_DESC("Fill the entire layer with the specified tile index.")
MCRF_ARGS_START
MCRF_ARG("index", "Tile index to fill with (-1 for no tile)")
)},
{"fill_rect", (PyCFunction)PyGridLayerAPI::TileLayer_fill_rect, METH_VARARGS | METH_KEYWORDS, {"fill_rect", (PyCFunction)PyGridLayerAPI::TileLayer_fill_rect, METH_VARARGS | METH_KEYWORDS,
"fill_rect(pos, size, index)\n\n" MCRF_METHOD(TileLayer, fill_rect,
"Fill a rectangular region with a tile index.\n\n" MCRF_SIG("(pos: tuple, size: tuple, index: int)", "None"),
"Args:\n" MCRF_DESC("Fill a rectangular region with a tile index.")
" pos (tuple): Top-left corner as (x, y)\n" MCRF_ARGS_START
" size (tuple): Dimensions as (width, height)\n" MCRF_ARG("pos", "Top-left corner as (x, y)")
" index (int): Tile index to fill with (-1 for no tile)"}, MCRF_ARG("size", "Dimensions as (width, height)")
MCRF_ARG("index", "Tile index to fill with (-1 for no tile)")
)},
{"apply_threshold", (PyCFunction)PyGridLayerAPI::TileLayer_apply_threshold, METH_VARARGS | METH_KEYWORDS, {"apply_threshold", (PyCFunction)PyGridLayerAPI::TileLayer_apply_threshold, METH_VARARGS | METH_KEYWORDS,
"apply_threshold(source, range, tile) -> TileLayer\n\n" MCRF_METHOD(TileLayer, apply_threshold,
"Set tile index for cells where HeightMap value is within range.\n\n" MCRF_SIG("(source: HeightMap, range: tuple, tile: int)", "TileLayer"),
"Args:\n" MCRF_DESC("Set a tile index for cells where the HeightMap value falls within a range.")
" source (HeightMap): Source heightmap (must match layer dimensions)\n" MCRF_ARGS_START
" range (tuple): Value range as (min, max) inclusive\n" MCRF_ARG("source", "Source heightmap (must match layer dimensions)")
" tile (int): Tile index to set for cells in range\n\n" MCRF_ARG("range", "Value range as (min, max) inclusive")
"Returns:\n" MCRF_ARG("tile", "Tile index to set for cells in range")
" self for method chaining\n\n" MCRF_RETURNS("self for method chaining")
"Example:\n" )},
" layer.apply_threshold(terrain, (0.0, 0.3), WATER_TILE)"},
{"apply_ranges", (PyCFunction)PyGridLayerAPI::TileLayer_apply_ranges, METH_VARARGS, {"apply_ranges", (PyCFunction)PyGridLayerAPI::TileLayer_apply_ranges, METH_VARARGS,
"apply_ranges(source, ranges) -> TileLayer\n\n" MCRF_METHOD(TileLayer, apply_ranges,
"Apply multiple tile assignments in a single pass.\n\n" MCRF_SIG("(source: HeightMap, ranges: list)", "TileLayer"),
"Args:\n" MCRF_DESC("Apply multiple tile assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping.")
" source (HeightMap): Source heightmap (must match layer dimensions)\n" MCRF_ARGS_START
" ranges (list): List of ((min, max), tile_index) tuples\n\n" MCRF_ARG("source", "Source heightmap (must match layer dimensions)")
"Returns:\n" MCRF_ARG("ranges", "List of ((min, max), tile_index) tuples")
" self for method chaining\n\n" MCRF_RETURNS("self for method chaining")
"Note:\n" MCRF_NOTE("Cells not matching any range are left unchanged.")
" Later ranges override earlier ones if overlapping.\n" )},
" Cells not matching any range are left unchanged.\n\n"
"Example:\n"
" layer.apply_ranges(terrain, [\n"
" ((0.0, 0.2), DEEP_WATER),\n"
" ((0.2, 0.3), SHALLOW_WATER),\n"
" ((0.3, 0.7), GRASS),\n"
" ])"},
{NULL} {NULL}
}; };
PyGetSetDef PyGridLayerAPI::TileLayer_getsetters[] = { PyGetSetDef PyGridLayerAPI::TileLayer_getsetters[] = {
{"z_index", (getter)PyGridLayerAPI::TileLayer_get_z_index, {"z_index", (getter)PyGridLayerAPI::TileLayer_get_z_index,
(setter)PyGridLayerAPI::TileLayer_set_z_index, (setter)PyGridLayerAPI::TileLayer_set_z_index,
"Layer z-order. Negative values render below entities.", NULL}, MCRF_PROPERTY(z_index, "Layer z-order (int). Negative values render below entities."), NULL},
{"visible", (getter)PyGridLayerAPI::TileLayer_get_visible, {"visible", (getter)PyGridLayerAPI::TileLayer_get_visible,
(setter)PyGridLayerAPI::TileLayer_set_visible, (setter)PyGridLayerAPI::TileLayer_set_visible,
"Whether the layer is rendered.", NULL}, MCRF_PROPERTY(visible, "Whether the layer is rendered (bool)."), NULL},
{"texture", (getter)PyGridLayerAPI::TileLayer_get_texture, {"texture", (getter)PyGridLayerAPI::TileLayer_get_texture,
(setter)PyGridLayerAPI::TileLayer_set_texture, (setter)PyGridLayerAPI::TileLayer_set_texture,
"Texture atlas for tile sprites.", NULL}, MCRF_PROPERTY(texture, "Texture atlas for tile sprites (Texture | None)."), NULL},
{"grid_size", (getter)PyGridLayerAPI::TileLayer_get_grid_size, NULL, {"grid_size", (getter)PyGridLayerAPI::TileLayer_get_grid_size, NULL,
"Layer dimensions as (width, height) tuple.", NULL}, MCRF_PROPERTY(grid_size, "Layer dimensions as (width, height) tuple (tuple, read-only)."), NULL},
{"name", (getter)PyGridLayerAPI::TileLayer_get_name, NULL, {"name", (getter)PyGridLayerAPI::TileLayer_get_name, NULL,
"Layer name (str, read-only). Used for Grid.layer(name) lookup.", NULL}, MCRF_PROPERTY(name, "Layer name (str, read-only). Used for Grid.layer(name) lookup."), NULL},
{"grid", (getter)PyGridLayerAPI::TileLayer_get_grid, {"grid", (getter)PyGridLayerAPI::TileLayer_get_grid,
(setter)PyGridLayerAPI::TileLayer_set_grid, (setter)PyGridLayerAPI::TileLayer_set_grid,
"Parent Grid or None. Setting manages layer association and handles lazy allocation.", NULL}, MCRF_PROPERTY(grid, "Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation."), NULL},
{NULL} {NULL}
}; };

View file

@ -256,7 +256,7 @@ static PyMethodDef mcrfpyMethods[] = {
// Note: setTimer and delTimer removed in #173 - use Timer objects instead // Note: setTimer and delTimer removed in #173 - use Timer objects instead
{"step", McRFPy_API::_step, METH_VARARGS, {"step", McRFPy_API::_step, METH_VARARGS,
MCRF_FUNCTION(step, MCRF_METHOD(mcrfpy, step,
MCRF_SIG("(dt: float = None)", "float"), MCRF_SIG("(dt: float = None)", "float"),
MCRF_DESC("Advance simulation time (headless mode only)."), MCRF_DESC("Advance simulation time (headless mode only)."),
MCRF_ARGS_START MCRF_ARGS_START
@ -265,14 +265,14 @@ static PyMethodDef mcrfpyMethods[] = {
MCRF_NOTE("In windowed mode, this is a no-op and returns 0.0. Use this for deterministic simulation control in headless/testing scenarios.") MCRF_NOTE("In windowed mode, this is a no-op and returns 0.0. Use this for deterministic simulation control in headless/testing scenarios.")
)}, )},
{"exit", McRFPy_API::_exit, METH_NOARGS, {"exit", McRFPy_API::_exit, METH_NOARGS,
MCRF_FUNCTION(exit, MCRF_METHOD(mcrfpy, exit,
MCRF_SIG("()", "None"), MCRF_SIG("()", "None"),
MCRF_DESC("Cleanly shut down the game engine and exit the application."), MCRF_DESC("Cleanly shut down the game engine and exit the application."),
MCRF_RETURNS("None") MCRF_RETURNS("None")
MCRF_NOTE("This immediately closes the window and terminates the program.") MCRF_NOTE("This immediately closes the window and terminates the program.")
)}, )},
{"set_scale", McRFPy_API::_setScale, METH_VARARGS, {"set_scale", McRFPy_API::_setScale, METH_VARARGS,
MCRF_FUNCTION(set_scale, MCRF_METHOD(mcrfpy, set_scale,
MCRF_SIG("(multiplier: float)", "None"), MCRF_SIG("(multiplier: float)", "None"),
MCRF_DESC("Deprecated: use Window.resolution instead. Scale the game window size."), MCRF_DESC("Deprecated: use Window.resolution instead. Scale the game window size."),
MCRF_ARGS_START MCRF_ARGS_START
@ -282,7 +282,7 @@ static PyMethodDef mcrfpyMethods[] = {
)}, )},
{"find", McRFPy_API::_find, METH_VARARGS, {"find", McRFPy_API::_find, METH_VARARGS,
MCRF_FUNCTION(find, MCRF_METHOD(mcrfpy, find,
MCRF_SIG("(name: str, scene: str = None)", "UIDrawable | None"), MCRF_SIG("(name: str, scene: str = None)", "UIDrawable | None"),
MCRF_DESC("Find the first UI element with the specified name."), MCRF_DESC("Find the first UI element with the specified name."),
MCRF_ARGS_START MCRF_ARGS_START
@ -292,7 +292,7 @@ static PyMethodDef mcrfpyMethods[] = {
MCRF_NOTE("Searches scene UI elements and entities within grids.") MCRF_NOTE("Searches scene UI elements and entities within grids.")
)}, )},
{"find_all", McRFPy_API::_findAll, METH_VARARGS, {"find_all", McRFPy_API::_findAll, METH_VARARGS,
MCRF_FUNCTION(find_all, MCRF_METHOD(mcrfpy, find_all,
MCRF_SIG("(pattern: str, scene: str = None)", "list"), MCRF_SIG("(pattern: str, scene: str = None)", "list"),
MCRF_DESC("Find all UI elements matching a name pattern."), MCRF_DESC("Find all UI elements matching a name pattern."),
MCRF_ARGS_START MCRF_ARGS_START
@ -303,14 +303,14 @@ static PyMethodDef mcrfpyMethods[] = {
)}, )},
{"get_metrics", McRFPy_API::_getMetrics, METH_NOARGS, {"get_metrics", McRFPy_API::_getMetrics, METH_NOARGS,
MCRF_FUNCTION(get_metrics, MCRF_METHOD(mcrfpy, get_metrics,
MCRF_SIG("()", "dict"), MCRF_SIG("()", "dict"),
MCRF_DESC("Get current performance metrics."), MCRF_DESC("Get current performance metrics."),
MCRF_RETURNS("dict: Performance data with keys: frame_time (last frame duration in seconds), avg_frame_time (average frame time), fps (frames per second), draw_calls (number of draw calls), ui_elements (total UI element count), visible_elements (visible element count), current_frame (frame counter), runtime (total runtime in seconds)") MCRF_RETURNS("dict: Performance data with keys: frame_time (last frame duration in seconds), avg_frame_time (average frame time), fps (frames per second), draw_calls (number of draw calls), ui_elements (total UI element count), visible_elements (visible element count), current_frame (frame counter), runtime (total runtime in seconds)")
)}, )},
{"set_dev_console", McRFPy_API::_setDevConsole, METH_VARARGS, {"set_dev_console", McRFPy_API::_setDevConsole, METH_VARARGS,
MCRF_FUNCTION(set_dev_console, MCRF_METHOD(mcrfpy, set_dev_console,
MCRF_SIG("(enabled: bool)", "None"), MCRF_SIG("(enabled: bool)", "None"),
MCRF_DESC("Enable or disable the developer console overlay."), MCRF_DESC("Enable or disable the developer console overlay."),
MCRF_ARGS_START MCRF_ARGS_START
@ -320,7 +320,7 @@ static PyMethodDef mcrfpyMethods[] = {
)}, )},
{"start_benchmark", McRFPy_API::_startBenchmark, METH_NOARGS, {"start_benchmark", McRFPy_API::_startBenchmark, METH_NOARGS,
MCRF_FUNCTION(start_benchmark, MCRF_METHOD(mcrfpy, start_benchmark,
MCRF_SIG("()", "None"), MCRF_SIG("()", "None"),
MCRF_DESC("Start capturing benchmark data to a file."), MCRF_DESC("Start capturing benchmark data to a file."),
MCRF_RETURNS("None") MCRF_RETURNS("None")
@ -329,7 +329,7 @@ static PyMethodDef mcrfpyMethods[] = {
)}, )},
{"end_benchmark", McRFPy_API::_endBenchmark, METH_NOARGS, {"end_benchmark", McRFPy_API::_endBenchmark, METH_NOARGS,
MCRF_FUNCTION(end_benchmark, MCRF_METHOD(mcrfpy, end_benchmark,
MCRF_SIG("()", "str"), MCRF_SIG("()", "str"),
MCRF_DESC("Stop benchmark capture and write data to JSON file."), MCRF_DESC("Stop benchmark capture and write data to JSON file."),
MCRF_RETURNS("str: The filename of the written benchmark data") MCRF_RETURNS("str: The filename of the written benchmark data")
@ -338,7 +338,7 @@ static PyMethodDef mcrfpyMethods[] = {
)}, )},
{"log_benchmark", McRFPy_API::_logBenchmark, METH_VARARGS, {"log_benchmark", McRFPy_API::_logBenchmark, METH_VARARGS,
MCRF_FUNCTION(log_benchmark, MCRF_METHOD(mcrfpy, log_benchmark,
MCRF_SIG("(message: str)", "None"), MCRF_SIG("(message: str)", "None"),
MCRF_DESC("Add a log message to the current benchmark frame."), MCRF_DESC("Add a log message to the current benchmark frame."),
MCRF_ARGS_START MCRF_ARGS_START
@ -350,11 +350,14 @@ static PyMethodDef mcrfpyMethods[] = {
// #151: Module-level attribute access for current_scene and scenes // #151: Module-level attribute access for current_scene and scenes
{"__getattr__", mcrfpy_module_getattr, METH_VARARGS, {"__getattr__", mcrfpy_module_getattr, METH_VARARGS,
"Module-level __getattr__ for dynamic properties (current_scene, scenes)"}, MCRF_METHOD(mcrfpy, __getattr__,
MCRF_SIG("(name: str)", "object"),
MCRF_DESC("Module-level attribute access for dynamic properties (current_scene, scenes).")
)},
// #219: Thread synchronization // #219: Thread synchronization
{"lock", PyLock::lock, METH_NOARGS, {"lock", PyLock::lock, METH_NOARGS,
MCRF_FUNCTION(lock, MCRF_METHOD(mcrfpy, lock,
MCRF_SIG("()", "_LockContext"), MCRF_SIG("()", "_LockContext"),
MCRF_DESC("Get a context manager for thread-safe UI updates from background threads."), MCRF_DESC("Get a context manager for thread-safe UI updates from background threads."),
MCRF_RETURNS("_LockContext: A context manager that blocks until safe to modify UI") MCRF_RETURNS("_LockContext: A context manager that blocks until safe to modify UI")
@ -365,7 +368,7 @@ static PyMethodDef mcrfpyMethods[] = {
// #215: Bresenham line algorithm (replaces mcrfpy.libtcod.line) // #215: Bresenham line algorithm (replaces mcrfpy.libtcod.line)
{"bresenham", (PyCFunction)McRFPy_API::_bresenham, METH_VARARGS | METH_KEYWORDS, {"bresenham", (PyCFunction)McRFPy_API::_bresenham, METH_VARARGS | METH_KEYWORDS,
MCRF_FUNCTION(bresenham, MCRF_METHOD(mcrfpy, bresenham,
MCRF_SIG("(start, end, *, include_start=True, include_end=True)", "list[tuple[int, int]]"), MCRF_SIG("(start, end, *, include_start=True, include_end=True)", "list[tuple[int, int]]"),
MCRF_DESC("Compute grid cells along a line using Bresenham's algorithm."), MCRF_DESC("Compute grid cells along a line using Bresenham's algorithm."),
MCRF_ARGS_START MCRF_ARGS_START
@ -379,7 +382,7 @@ static PyMethodDef mcrfpyMethods[] = {
)}, )},
{"_sync_storage", mcrfpy_sync_storage, METH_NOARGS, {"_sync_storage", mcrfpy_sync_storage, METH_NOARGS,
MCRF_FUNCTION(_sync_storage, MCRF_METHOD(mcrfpy, _sync_storage,
MCRF_SIG("()", "None"), MCRF_SIG("()", "None"),
MCRF_DESC("Flush save directory to persistent storage."), MCRF_DESC("Flush save directory to persistent storage."),
MCRF_RETURNS("None") MCRF_RETURNS("None")

View file

@ -3,6 +3,7 @@
#include "GameEngine.h" #include "GameEngine.h"
#include "PyPositionHelper.h" #include "PyPositionHelper.h"
#include "PyVector.h" #include "PyVector.h"
#include "McRFPy_Doc.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -840,49 +841,166 @@ PyObject* McRFPy_Automation::_dragRel(PyObject* self, PyObject* args, PyObject*
// Method definitions for the automation module // Method definitions for the automation module
static PyMethodDef automationMethods[] = { static PyMethodDef automationMethods[] = {
{"screenshot", McRFPy_Automation::_screenshot, METH_VARARGS, {"screenshot", McRFPy_Automation::_screenshot, METH_VARARGS,
"screenshot(filename) - Save a screenshot to the specified file"}, MCRF_METHOD(automation, screenshot,
MCRF_SIG("(filename: str)", "bool"),
MCRF_DESC("Save a screenshot of the current render target to the specified file."),
MCRF_ARGS_START
MCRF_ARG("filename", "Path to the output image file (PNG, JPG, etc.)")
MCRF_RETURNS("True if the file was saved successfully, False otherwise")
MCRF_RAISES("RuntimeError", "If the game engine or render target is not initialized")
)},
{"position", McRFPy_Automation::_position, METH_NOARGS, {"position", McRFPy_Automation::_position, METH_NOARGS,
"position() - Get current mouse position as Vector"}, MCRF_METHOD(automation, position,
MCRF_SIG("()", "Vector"),
MCRF_DESC("Get the current mouse position as a Vector.")
MCRF_RETURNS("Vector: current mouse position in screen coordinates")
)},
{"size", McRFPy_Automation::_size, METH_NOARGS, {"size", McRFPy_Automation::_size, METH_NOARGS,
"size() - Get screen size as Vector"}, MCRF_METHOD(automation, size,
MCRF_SIG("()", "Vector"),
MCRF_DESC("Get the current screen (render target) size as a Vector.")
MCRF_RETURNS("Vector: screen width and height in pixels")
)},
{"onScreen", (PyCFunction)McRFPy_Automation::_onScreen, METH_VARARGS | METH_KEYWORDS, {"onScreen", (PyCFunction)McRFPy_Automation::_onScreen, METH_VARARGS | METH_KEYWORDS,
"onScreen(pos) - Check if position is within screen bounds. Accepts (x,y) tuple, [x,y] list, or Vector."}, MCRF_METHOD(automation, onScreen,
MCRF_SIG("(pos: tuple | list | Vector)", "bool"),
MCRF_DESC("Check if a position is within the screen bounds."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, or Vector")
MCRF_RETURNS("True if the position is on screen, False otherwise")
)},
{"moveTo", (PyCFunction)McRFPy_Automation::_moveTo, METH_VARARGS | METH_KEYWORDS, {"moveTo", (PyCFunction)McRFPy_Automation::_moveTo, METH_VARARGS | METH_KEYWORDS,
"moveTo(pos, duration=0.0) - Move mouse to position. Accepts (x,y) tuple, [x,y] list, or Vector."}, MCRF_METHOD(automation, moveTo,
MCRF_SIG("(pos: tuple | list | Vector, duration: float = 0.0)", "None"),
MCRF_DESC("Move the mouse cursor to the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Target position as (x, y) tuple, [x, y] list, or Vector")
MCRF_ARG("duration", "Time in seconds to take for the movement (default 0.0)")
)},
{"moveRel", (PyCFunction)McRFPy_Automation::_moveRel, METH_VARARGS | METH_KEYWORDS, {"moveRel", (PyCFunction)McRFPy_Automation::_moveRel, METH_VARARGS | METH_KEYWORDS,
"moveRel(offset, duration=0.0) - Move mouse relative to current position. Accepts (x,y) tuple, [x,y] list, or Vector."}, MCRF_METHOD(automation, moveRel,
MCRF_SIG("(offset: tuple | list | Vector, duration: float = 0.0)", "None"),
MCRF_DESC("Move the mouse cursor relative to its current position."),
MCRF_ARGS_START
MCRF_ARG("offset", "Offset as (x, y) tuple, [x, y] list, or Vector")
MCRF_ARG("duration", "Time in seconds to take for the movement (default 0.0)")
)},
{"dragTo", (PyCFunction)McRFPy_Automation::_dragTo, METH_VARARGS | METH_KEYWORDS, {"dragTo", (PyCFunction)McRFPy_Automation::_dragTo, METH_VARARGS | METH_KEYWORDS,
"dragTo(pos, duration=0.0, button='left') - Drag mouse to position. Accepts (x,y) tuple, [x,y] list, or Vector."}, MCRF_METHOD(automation, dragTo,
MCRF_SIG("(pos: tuple | list | Vector, duration: float = 0.0, button: str = 'left')", "None"),
MCRF_DESC("Drag the mouse from the current position to the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Target position as (x, y) tuple, [x, y] list, or Vector")
MCRF_ARG("duration", "Time in seconds for the drag (default 0.0)")
MCRF_ARG("button", "Mouse button to use: 'left', 'right', or 'middle' (default 'left')")
)},
{"dragRel", (PyCFunction)McRFPy_Automation::_dragRel, METH_VARARGS | METH_KEYWORDS, {"dragRel", (PyCFunction)McRFPy_Automation::_dragRel, METH_VARARGS | METH_KEYWORDS,
"dragRel(offset, duration=0.0, button='left') - Drag mouse relative to current position. Accepts (x,y) tuple, [x,y] list, or Vector."}, MCRF_METHOD(automation, dragRel,
MCRF_SIG("(offset: tuple | list | Vector, duration: float = 0.0, button: str = 'left')", "None"),
MCRF_DESC("Drag the mouse relative to its current position."),
MCRF_ARGS_START
MCRF_ARG("offset", "Offset as (x, y) tuple, [x, y] list, or Vector")
MCRF_ARG("duration", "Time in seconds for the drag (default 0.0)")
MCRF_ARG("button", "Mouse button to use: 'left', 'right', or 'middle' (default 'left')")
)},
{"click", (PyCFunction)McRFPy_Automation::_click, METH_VARARGS | METH_KEYWORDS, {"click", (PyCFunction)McRFPy_Automation::_click, METH_VARARGS | METH_KEYWORDS,
"click(pos=None, clicks=1, interval=0.0, button='left') - Click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, click,
MCRF_SIG("(pos: tuple | list | Vector | None = None, clicks: int = 1, interval: float = 0.0, button: str = 'left')", "None"),
MCRF_DESC("Click the mouse at the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
MCRF_ARG("clicks", "Number of clicks to perform (default 1)")
MCRF_ARG("interval", "Seconds between clicks when clicks > 1 (default 0.0)")
MCRF_ARG("button", "Mouse button: 'left', 'right', or 'middle' (default 'left')")
)},
{"rightClick", (PyCFunction)McRFPy_Automation::_rightClick, METH_VARARGS | METH_KEYWORDS, {"rightClick", (PyCFunction)McRFPy_Automation::_rightClick, METH_VARARGS | METH_KEYWORDS,
"rightClick(pos=None) - Right click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, rightClick,
MCRF_SIG("(pos: tuple | list | Vector | None = None)", "None"),
MCRF_DESC("Right-click the mouse at the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
)},
{"middleClick", (PyCFunction)McRFPy_Automation::_middleClick, METH_VARARGS | METH_KEYWORDS, {"middleClick", (PyCFunction)McRFPy_Automation::_middleClick, METH_VARARGS | METH_KEYWORDS,
"middleClick(pos=None) - Middle click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, middleClick,
MCRF_SIG("(pos: tuple | list | Vector | None = None)", "None"),
MCRF_DESC("Middle-click the mouse at the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
)},
{"doubleClick", (PyCFunction)McRFPy_Automation::_doubleClick, METH_VARARGS | METH_KEYWORDS, {"doubleClick", (PyCFunction)McRFPy_Automation::_doubleClick, METH_VARARGS | METH_KEYWORDS,
"doubleClick(pos=None) - Double click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, doubleClick,
MCRF_SIG("(pos: tuple | list | Vector | None = None)", "None"),
MCRF_DESC("Double-click the mouse at the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
)},
{"tripleClick", (PyCFunction)McRFPy_Automation::_tripleClick, METH_VARARGS | METH_KEYWORDS, {"tripleClick", (PyCFunction)McRFPy_Automation::_tripleClick, METH_VARARGS | METH_KEYWORDS,
"tripleClick(pos=None) - Triple click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, tripleClick,
MCRF_SIG("(pos: tuple | list | Vector | None = None)", "None"),
MCRF_DESC("Triple-click the mouse at the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
)},
{"scroll", (PyCFunction)McRFPy_Automation::_scroll, METH_VARARGS | METH_KEYWORDS, {"scroll", (PyCFunction)McRFPy_Automation::_scroll, METH_VARARGS | METH_KEYWORDS,
"scroll(clicks, pos=None) - Scroll wheel at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, scroll,
MCRF_SIG("(clicks: int, pos: tuple | list | Vector | None = None)", "None"),
MCRF_DESC("Scroll the mouse wheel at the specified position."),
MCRF_ARGS_START
MCRF_ARG("clicks", "Number of scroll steps (positive = up, negative = down)")
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
)},
{"mouseDown", (PyCFunction)McRFPy_Automation::_mouseDown, METH_VARARGS | METH_KEYWORDS, {"mouseDown", (PyCFunction)McRFPy_Automation::_mouseDown, METH_VARARGS | METH_KEYWORDS,
"mouseDown(pos=None, button='left') - Press mouse button at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, mouseDown,
MCRF_SIG("(pos: tuple | list | Vector | None = None, button: str = 'left')", "None"),
MCRF_DESC("Press and hold a mouse button at the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
MCRF_ARG("button", "Mouse button: 'left', 'right', or 'middle' (default 'left')")
)},
{"mouseUp", (PyCFunction)McRFPy_Automation::_mouseUp, METH_VARARGS | METH_KEYWORDS, {"mouseUp", (PyCFunction)McRFPy_Automation::_mouseUp, METH_VARARGS | METH_KEYWORDS,
"mouseUp(pos=None, button='left') - Release mouse button at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position."}, MCRF_METHOD(automation, mouseUp,
MCRF_SIG("(pos: tuple | list | Vector | None = None, button: str = 'left')", "None"),
MCRF_DESC("Release a mouse button at the specified position."),
MCRF_ARGS_START
MCRF_ARG("pos", "Position as (x, y) tuple, [x, y] list, Vector, or None for current position")
MCRF_ARG("button", "Mouse button: 'left', 'right', or 'middle' (default 'left')")
)},
{"typewrite", (PyCFunction)McRFPy_Automation::_typewrite, METH_VARARGS | METH_KEYWORDS, {"typewrite", (PyCFunction)McRFPy_Automation::_typewrite, METH_VARARGS | METH_KEYWORDS,
"typewrite(message, interval=0.0) - Type text with optional interval between keystrokes"}, MCRF_METHOD(automation, typewrite,
MCRF_SIG("(message: str, interval: float = 0.0)", "None"),
MCRF_DESC("Type text by injecting keyboard events for each character."),
MCRF_ARGS_START
MCRF_ARG("message", "Text string to type")
MCRF_ARG("interval", "Seconds to wait between keystrokes (default 0.0)")
)},
{"hotkey", McRFPy_Automation::_hotkey, METH_VARARGS, {"hotkey", McRFPy_Automation::_hotkey, METH_VARARGS,
"hotkey(*keys) - Press a hotkey combination (e.g., hotkey('ctrl', 'c'))"}, MCRF_METHOD(automation, hotkey,
MCRF_SIG("(*keys: str)", "None"),
MCRF_DESC("Press a hotkey combination by pressing all keys in order then releasing in reverse."),
MCRF_ARGS_START
MCRF_ARG("*keys", "Key names to press, e.g. 'ctrl', 'c'")
MCRF_RAISES("ValueError", "If any key name is not recognized")
)},
{"keyDown", McRFPy_Automation::_keyDown, METH_VARARGS, {"keyDown", McRFPy_Automation::_keyDown, METH_VARARGS,
"keyDown(key) - Press and hold a key"}, MCRF_METHOD(automation, keyDown,
MCRF_SIG("(key: str)", "None"),
MCRF_DESC("Press and hold a keyboard key."),
MCRF_ARGS_START
MCRF_ARG("key", "Key name string, e.g. 'a', 'enter', 'ctrl', 'f1'")
MCRF_RAISES("ValueError", "If the key name is not recognized")
)},
{"keyUp", McRFPy_Automation::_keyUp, METH_VARARGS, {"keyUp", McRFPy_Automation::_keyUp, METH_VARARGS,
"keyUp(key) - Release a key"}, MCRF_METHOD(automation, keyUp,
MCRF_SIG("(key: str)", "None"),
MCRF_DESC("Release a keyboard key."),
MCRF_ARGS_START
MCRF_ARG("key", "Key name string, e.g. 'a', 'enter', 'ctrl', 'f1'")
MCRF_RAISES("ValueError", "If the key name is not recognized")
)},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -16,6 +16,9 @@
#define MCRF_LINK(ref, text) "\nSee also: " text " (" ref ")\n" #define MCRF_LINK(ref, text) "\nSee also: " text " (" ref ")\n"
// Main documentation macros // Main documentation macros
// name: stringified method name; sig: MCRF_SIG(...); desc: MCRF_DESC(...);
// remaining sections (MCRF_ARGS_START, MCRF_ARG, MCRF_RETURNS, etc.) go in __VA_ARGS__
// as adjacent string literals with NO commas between them.
#define MCRF_METHOD_DOC(name, sig, desc, ...) \ #define MCRF_METHOD_DOC(name, sig, desc, ...) \
name sig desc __VA_ARGS__ name sig desc __VA_ARGS__

View file

@ -1597,7 +1597,11 @@ PySequenceMethods PyBSPAdjacentTiles::sequence_methods = {
PyMethodDef PyBSPAdjacentTiles::methods[] = { PyMethodDef PyBSPAdjacentTiles::methods[] = {
{"keys", (PyCFunction)PyBSPAdjacentTiles::keys, METH_NOARGS, {"keys", (PyCFunction)PyBSPAdjacentTiles::keys, METH_NOARGS,
"Return tuple of adjacent neighbor indices."}, MCRF_METHOD(BSPAdjacentTiles, keys,
MCRF_SIG("()", "tuple[int, ...]"),
MCRF_DESC("Return tuple of adjacent neighbor indices."),
MCRF_RETURNS("tuple of int: indices of all leaf nodes adjacent to this one")
)},
{NULL} {NULL}
}; };

View file

@ -2,6 +2,7 @@
#include "PyLock.h" #include "PyLock.h"
#include "GameEngine.h" #include "GameEngine.h"
#include "Resources.h" #include "Resources.h"
#include "McRFPy_Doc.h"
// Forward declarations // Forward declarations
static PyObject* PyLockContext_enter(PyLockContextObject* self, PyObject* args); static PyObject* PyLockContext_enter(PyLockContextObject* self, PyObject* args);
@ -12,9 +13,18 @@ static PyObject* PyLockContext_new(PyTypeObject* type, PyObject* args, PyObject*
// Context manager methods // Context manager methods
static PyMethodDef PyLockContext_methods[] = { static PyMethodDef PyLockContext_methods[] = {
{"__enter__", (PyCFunction)PyLockContext_enter, METH_NOARGS, {"__enter__", (PyCFunction)PyLockContext_enter, METH_NOARGS,
"Acquire the frame lock, blocking until safe window opens"}, MCRF_METHOD(LockContext, __enter__,
MCRF_SIG("()", "_LockContext"),
MCRF_DESC("Acquire the frame lock, blocking until a safe window opens. No-op on the main thread."),
MCRF_RETURNS("self, for use in a `with` statement")
MCRF_RAISES("RuntimeError", "If the game engine is not initialized")
)},
{"__exit__", (PyCFunction)PyLockContext_exit, METH_VARARGS, {"__exit__", (PyCFunction)PyLockContext_exit, METH_VARARGS,
"Release the frame lock"}, MCRF_METHOD(LockContext, __exit__,
MCRF_SIG("(exc_type, exc_val, exc_tb)", "bool"),
MCRF_DESC("Release the frame lock. Does not suppress exceptions."),
MCRF_RETURNS("False, so any active exception propagates normally")
)},
{NULL} {NULL}
}; };

View file

@ -112,13 +112,28 @@ const UniformEntry* UniformCollection::getEntry(const std::string& name) const {
PyMethodDef PyUniformCollectionType::methods[] = { PyMethodDef PyUniformCollectionType::methods[] = {
{"keys", (PyCFunction)PyUniformCollectionType::keys, METH_NOARGS, {"keys", (PyCFunction)PyUniformCollectionType::keys, METH_NOARGS,
"Return list of uniform names"}, MCRF_METHOD(UniformCollection, keys,
MCRF_SIG("()", "list"),
MCRF_DESC("Return a list of all uniform names in this collection.")
MCRF_RETURNS("list of str: the names of all uniforms currently set")
)},
{"values", (PyCFunction)PyUniformCollectionType::values, METH_NOARGS, {"values", (PyCFunction)PyUniformCollectionType::values, METH_NOARGS,
"Return list of uniform values"}, MCRF_METHOD(UniformCollection, values,
MCRF_SIG("()", "list"),
MCRF_DESC("Return a list of all uniform values in this collection.")
MCRF_RETURNS("list of float or tuple: the values of all uniforms currently set")
)},
{"items", (PyCFunction)PyUniformCollectionType::items, METH_NOARGS, {"items", (PyCFunction)PyUniformCollectionType::items, METH_NOARGS,
"Return list of (name, value) tuples"}, MCRF_METHOD(UniformCollection, items,
MCRF_SIG("()", "list"),
MCRF_DESC("Return a list of (name, value) tuples for all uniforms in this collection.")
MCRF_RETURNS("list of tuple: (str, float | tuple) pairs for each uniform")
)},
{"clear", (PyCFunction)PyUniformCollectionType::clear, METH_NOARGS, {"clear", (PyCFunction)PyUniformCollectionType::clear, METH_NOARGS,
"Remove all uniforms"}, MCRF_METHOD(UniformCollection, clear,
MCRF_SIG("()", "None"),
MCRF_DESC("Remove all uniforms from this collection.")
)},
{NULL} {NULL}
}; };

View file

@ -1,4 +1,5 @@
#include "UIArc.h" #include "UIArc.h"
#include "McRFPy_Doc.h"
#include "McRFPy_API.h" #include "McRFPy_API.h"
#include "PythonObjectCache.h" #include "PythonObjectCache.h"
#include "PyAlignment.h" #include "PyAlignment.h"
@ -493,27 +494,29 @@ typedef PyUIArcObject PyObjectType;
PyGetSetDef UIArc::getsetters[] = { PyGetSetDef UIArc::getsetters[] = {
{"center", (getter)UIArc::get_center, (setter)UIArc::set_center, {"center", (getter)UIArc::get_center, (setter)UIArc::set_center,
"Center position of the arc", NULL}, MCRF_PROPERTY(center, "Center position of the arc (Vector)."), NULL},
{"radius", (getter)UIArc::get_radius, (setter)UIArc::set_radius, {"radius", (getter)UIArc::get_radius, (setter)UIArc::set_radius,
"Arc radius in pixels", NULL}, MCRF_PROPERTY(radius, "Arc radius in pixels (float)."), NULL},
{"start_angle", (getter)UIArc::get_start_angle, (setter)UIArc::set_start_angle, {"start_angle", (getter)UIArc::get_start_angle, (setter)UIArc::set_start_angle,
"Starting angle in degrees", NULL}, MCRF_PROPERTY(start_angle, "Starting angle in degrees (float)."), NULL},
{"end_angle", (getter)UIArc::get_end_angle, (setter)UIArc::set_end_angle, {"end_angle", (getter)UIArc::get_end_angle, (setter)UIArc::set_end_angle,
"Ending angle in degrees", NULL}, MCRF_PROPERTY(end_angle, "Ending angle in degrees (float)."), NULL},
{"color", (getter)UIArc::get_color, (setter)UIArc::set_color, {"color", (getter)UIArc::get_color, (setter)UIArc::set_color,
"Arc color", NULL}, MCRF_PROPERTY(color, "Arc fill color (Color)."), NULL},
{"thickness", (getter)UIArc::get_thickness, (setter)UIArc::set_thickness, {"thickness", (getter)UIArc::get_thickness, (setter)UIArc::set_thickness,
"Line thickness", NULL}, MCRF_PROPERTY(thickness, "Line thickness in pixels (float)."), NULL},
{"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, {"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click,
"Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str).", (void*)PyObjectsEnum::UIARC}, MCRF_PROPERTY(on_click, "Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str)."), (void*)PyObjectsEnum::UIARC},
{"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int, {"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int,
"Z-order for rendering (lower values rendered first).", (void*)PyObjectsEnum::UIARC}, MCRF_PROPERTY(z_index, "Z-order for rendering (int, lower values rendered first)."), (void*)PyObjectsEnum::UIARC},
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, {"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name,
"Name for finding this element.", (void*)PyObjectsEnum::UIARC}, MCRF_PROPERTY(name, "Name for finding this element (str)."), (void*)PyObjectsEnum::UIARC},
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
"Position as a Vector (same as center).", (void*)PyObjectsEnum::UIARC}, MCRF_PROPERTY(pos, "Position as a Vector (same as center)."), (void*)PyObjectsEnum::UIARC},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos, "Position in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UIARC}, {"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos,
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size, "Size in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UIARC}, MCRF_PROPERTY(grid_pos, "Position in grid tile coordinates (Vector, only when parent is Grid)."), (void*)PyObjectsEnum::UIARC},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size,
MCRF_PROPERTY(grid_size, "Size in grid tile coordinates (Vector, only when parent is Grid)."), (void*)PyObjectsEnum::UIARC},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIARC), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIARC),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIARC), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIARC),

View file

@ -11,6 +11,7 @@
#include "UIGrid.h" // parent= kwarg: Grid/GridView parent type #include "UIGrid.h" // parent= kwarg: Grid/GridView parent type
#include "PySceneObject.h" // parent= kwarg: Scene parent type #include "PySceneObject.h" // parent= kwarg: Scene parent type
// UIDrawable methods now in UIBase.h // UIDrawable methods now in UIBase.h
#include "McRFPy_Doc.h"
#include <algorithm> #include <algorithm>
UICaption::UICaption() UICaption::UICaption()
@ -373,24 +374,50 @@ PyObject* UICaption::get_h(PyUICaptionObject* self, void* closure)
} }
PyGetSetDef UICaption::getsetters[] = { PyGetSetDef UICaption::getsetters[] = {
{"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "X coordinate of top-left corner", (void*)((intptr_t)PyObjectsEnum::UICAPTION << 8 | 0)}, {"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "Y coordinate of top-left corner", (void*)((intptr_t)PyObjectsEnum::UICAPTION << 8 | 1)}, MCRF_PROPERTY(x, "X coordinate of top-left corner (float)."),
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, "(x, y) vector", (void*)PyObjectsEnum::UICAPTION}, (void*)((intptr_t)PyObjectsEnum::UICAPTION << 8 | 0)},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos, "Position in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UICAPTION}, {"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size, "Size in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UICAPTION}, MCRF_PROPERTY(y, "Y coordinate of top-left corner (float)."),
{"size", (getter)UICaption::get_size, NULL, "Text dimensions as Vector (read-only)", NULL}, (void*)((intptr_t)PyObjectsEnum::UICAPTION << 8 | 1)},
{"w", (getter)UICaption::get_w, NULL, "Text width in pixels (read-only)", NULL}, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
{"h", (getter)UICaption::get_h, NULL, "Text height in pixels (read-only)", NULL}, MCRF_PROPERTY(pos, "Position as (x, y) Vector."),
{"outline", (getter)UICaption::get_float_member, (setter)UICaption::set_float_member, "Thickness of the border", (void*)4}, (void*)PyObjectsEnum::UICAPTION},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos,
MCRF_PROPERTY(grid_pos, "Position in grid tile coordinates (Vector). Only valid when parent is a Grid."),
(void*)PyObjectsEnum::UICAPTION},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size,
MCRF_PROPERTY(grid_size, "Size in grid tile coordinates (Vector). Only valid when parent is a Grid."),
(void*)PyObjectsEnum::UICAPTION},
{"size", (getter)UICaption::get_size, NULL,
MCRF_PROPERTY(size, "Text dimensions as Vector (read-only)."),
NULL},
{"w", (getter)UICaption::get_w, NULL,
MCRF_PROPERTY(w, "Text width in pixels (float, read-only)."),
NULL},
{"h", (getter)UICaption::get_h, NULL,
MCRF_PROPERTY(h, "Text height in pixels (float, read-only)."),
NULL},
{"outline", (getter)UICaption::get_float_member, (setter)UICaption::set_float_member,
MCRF_PROPERTY(outline, "Thickness of the text outline border (float). Clamped to non-negative values."),
(void*)4},
{"fill_color", (getter)UICaption::get_color_member, (setter)UICaption::set_color_member, {"fill_color", (getter)UICaption::get_color_member, (setter)UICaption::set_color_member,
"Fill color of the text. Returns a copy; modifying components requires reassignment. " MCRF_PROPERTY(fill_color,
"For animation, use 'fill_color.r', 'fill_color.g', etc.", (void*)0}, "Fill color of the text (Color). Returns a copy; modifying components requires reassignment. "
"For animation, use 'fill_color.r', 'fill_color.g', etc."
), (void*)0},
{"outline_color", (getter)UICaption::get_color_member, (setter)UICaption::set_color_member, {"outline_color", (getter)UICaption::get_color_member, (setter)UICaption::set_color_member,
"Outline color of the text. Returns a copy; modifying components requires reassignment. " MCRF_PROPERTY(outline_color,
"For animation, use 'outline_color.r', 'outline_color.g', etc.", (void*)1}, "Outline color of the text (Color). Returns a copy; modifying components requires reassignment. "
"For animation, use 'outline_color.r', 'outline_color.g', etc."
), (void*)1},
//{"children", (getter)PyUIFrame_get_children, NULL, "UICollection of objects on top of this one", NULL}, //{"children", (getter)PyUIFrame_get_children, NULL, "UICollection of objects on top of this one", NULL},
{"text", (getter)UICaption::get_text, (setter)UICaption::set_text, "The text displayed", NULL}, {"text", (getter)UICaption::get_text, (setter)UICaption::set_text,
{"font_size", (getter)UICaption::get_float_member, (setter)UICaption::set_float_member, "Font size (integer) in points", (void*)5}, MCRF_PROPERTY(text, "The text string displayed by this Caption (str)."),
NULL},
{"font_size", (getter)UICaption::get_float_member, (setter)UICaption::set_float_member,
MCRF_PROPERTY(font_size, "Font size in points (int). Clamped to the range [0, 65535]."),
(void*)5},
{"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, {"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click,
MCRF_PROPERTY(on_click, MCRF_PROPERTY(on_click,
"Callable executed when object is clicked. " "Callable executed when object is clicked. "
@ -401,7 +428,9 @@ PyGetSetDef UICaption::getsetters[] = {
"Z-order for rendering (lower values rendered first). " "Z-order for rendering (lower values rendered first). "
"Automatically triggers scene resort when changed." "Automatically triggers scene resort when changed."
), (void*)PyObjectsEnum::UICAPTION}, ), (void*)PyObjectsEnum::UICAPTION},
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, "Name for finding elements", (void*)PyObjectsEnum::UICAPTION}, {"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name,
MCRF_PROPERTY(name, "Name for finding elements (str)."),
(void*)PyObjectsEnum::UICAPTION},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UICAPTION), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UICAPTION),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UICAPTION), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UICAPTION),

View file

@ -1,6 +1,7 @@
#include "UICircle.h" #include "UICircle.h"
#include "GameEngine.h" #include "GameEngine.h"
#include "McRFPy_API.h" #include "McRFPy_API.h"
#include "McRFPy_Doc.h"
#include "PyVector.h" #include "PyVector.h"
#include "PyColor.h" #include "PyColor.h"
#include "PythonObjectCache.h" #include "PythonObjectCache.h"
@ -439,25 +440,27 @@ typedef PyUICircleObject PyObjectType;
PyGetSetDef UICircle::getsetters[] = { PyGetSetDef UICircle::getsetters[] = {
{"radius", (getter)UICircle::get_radius, (setter)UICircle::set_radius, {"radius", (getter)UICircle::get_radius, (setter)UICircle::set_radius,
"Circle radius in pixels", NULL}, MCRF_PROPERTY(radius, "Circle radius in pixels (float)."), NULL},
{"center", (getter)UICircle::get_center, (setter)UICircle::set_center, {"center", (getter)UICircle::get_center, (setter)UICircle::set_center,
"Center position of the circle", NULL}, MCRF_PROPERTY(center, "Center position of the circle (Vector)."), NULL},
{"fill_color", (getter)UICircle::get_fill_color, (setter)UICircle::set_fill_color, {"fill_color", (getter)UICircle::get_fill_color, (setter)UICircle::set_fill_color,
"Fill color of the circle", NULL}, MCRF_PROPERTY(fill_color, "Fill color of the circle (Color)."), NULL},
{"outline_color", (getter)UICircle::get_outline_color, (setter)UICircle::set_outline_color, {"outline_color", (getter)UICircle::get_outline_color, (setter)UICircle::set_outline_color,
"Outline color of the circle", NULL}, MCRF_PROPERTY(outline_color, "Outline color of the circle (Color)."), NULL},
{"outline", (getter)UICircle::get_outline, (setter)UICircle::set_outline, {"outline", (getter)UICircle::get_outline, (setter)UICircle::set_outline,
"Outline thickness (0 for no outline)", NULL}, MCRF_PROPERTY(outline, "Outline thickness in pixels (float). Use 0 for no outline."), NULL},
{"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, {"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click,
"Callable executed when circle is clicked. Function receives (pos: Vector, button: str, action: str).", (void*)PyObjectsEnum::UICIRCLE}, MCRF_PROPERTY(on_click, "Callable executed when circle is clicked (Callable | None). Function receives (pos: Vector, button: str, action: str)."), (void*)PyObjectsEnum::UICIRCLE},
{"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int, {"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int,
"Z-order for rendering (lower values rendered first).", (void*)PyObjectsEnum::UICIRCLE}, MCRF_PROPERTY(z_index, "Z-order for rendering (int). Lower values are rendered first."), (void*)PyObjectsEnum::UICIRCLE},
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, {"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name,
"Name for finding this element.", (void*)PyObjectsEnum::UICIRCLE}, MCRF_PROPERTY(name, "Name for finding this element (str)."), (void*)PyObjectsEnum::UICIRCLE},
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
"Position as a Vector (same as center).", (void*)PyObjectsEnum::UICIRCLE}, MCRF_PROPERTY(pos, "Position as a Vector (same as center) (Vector)."), (void*)PyObjectsEnum::UICIRCLE},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos, "Position in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UICIRCLE}, {"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos,
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size, "Size in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UICIRCLE}, MCRF_PROPERTY(grid_pos, "Position in grid tile coordinates (Vector). Only meaningful when parent is a Grid."), (void*)PyObjectsEnum::UICIRCLE},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size,
MCRF_PROPERTY(grid_size, "Size in grid tile coordinates (Vector). Only meaningful when parent is a Grid."), (void*)PyObjectsEnum::UICIRCLE},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UICIRCLE), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UICIRCLE),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UICIRCLE), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UICIRCLE),

View file

@ -1,4 +1,5 @@
#include "UICollection.h" #include "UICollection.h"
#include "McRFPy_Doc.h"
#include "UIFrame.h" #include "UIFrame.h"
#include "UICaption.h" #include "UICaption.h"
@ -1047,42 +1048,72 @@ PyObject* UICollection::find(PyUICollectionObject* self, PyObject* args, PyObjec
PyMethodDef UICollection::methods[] = { PyMethodDef UICollection::methods[] = {
{"append", (PyCFunction)UICollection::append, METH_O, {"append", (PyCFunction)UICollection::append, METH_O,
"append(element)\n\n" MCRF_METHOD(UICollection, append,
"Add an element to the end of the collection."}, MCRF_SIG("(element: Drawable)", "None"),
MCRF_DESC("Add an element to the end of the collection.")
MCRF_ARGS_START
MCRF_ARG("element", "Drawable object to add")
)},
{"extend", (PyCFunction)UICollection::extend, METH_O, {"extend", (PyCFunction)UICollection::extend, METH_O,
"extend(iterable)\n\n" MCRF_METHOD(UICollection, extend,
"Add all elements from an iterable to the collection."}, MCRF_SIG("(iterable)", "None"),
MCRF_DESC("Add all elements from an iterable to the collection.")
MCRF_ARGS_START
MCRF_ARG("iterable", "Iterable of Drawable objects to add")
)},
{"insert", (PyCFunction)UICollection::insert, METH_VARARGS, {"insert", (PyCFunction)UICollection::insert, METH_VARARGS,
"insert(index, element)\n\n" MCRF_METHOD(UICollection, insert,
"Insert element at index. Like list.insert(), indices past the end append.\n\n" MCRF_SIG("(index: int, element: Drawable)", "None"),
"Note: If using z_index for sorting, insertion order may not persist after\n" MCRF_DESC("Insert element at index. Like list.insert(), indices past the end append.")
"the next render. Use name-based .find() for stable element access."}, MCRF_ARGS_START
MCRF_ARG("index", "Position at which to insert the element")
MCRF_ARG("element", "Drawable object to insert")
MCRF_NOTE("If using z_index for sorting, insertion order may not persist after the next render. Use name-based .find() for stable element access.")
)},
{"remove", (PyCFunction)UICollection::remove, METH_O, {"remove", (PyCFunction)UICollection::remove, METH_O,
"remove(element)\n\n" MCRF_METHOD(UICollection, remove,
"Remove first occurrence of element. Raises ValueError if not found."}, MCRF_SIG("(element: Drawable)", "None"),
MCRF_DESC("Remove first occurrence of element.")
MCRF_ARGS_START
MCRF_ARG("element", "Drawable object to remove")
MCRF_RAISES("ValueError", "If the element is not in the collection")
)},
{"pop", (PyCFunction)UICollection::pop, METH_VARARGS, {"pop", (PyCFunction)UICollection::pop, METH_VARARGS,
"pop([index]) -> element\n\n" MCRF_METHOD(UICollection, pop,
"Remove and return element at index (default: last element).\n\n" MCRF_SIG("(index: int = -1)", "Drawable"),
"Note: If using z_index for sorting, indices may shift after render.\n" MCRF_DESC("Remove and return element at index (default: last element).")
"Use name-based .find() for stable element access."}, MCRF_ARGS_START
MCRF_ARG("index", "Position of element to remove (default -1 = last)")
MCRF_RETURNS("Drawable: the removed element")
MCRF_RAISES("IndexError", "If the collection is empty or index is out of range")
MCRF_NOTE("If using z_index for sorting, indices may shift after render. Use name-based .find() for stable element access.")
)},
{"index", (PyCFunction)UICollection::index_method, METH_O, {"index", (PyCFunction)UICollection::index_method, METH_O,
"index(element) -> int\n\n" MCRF_METHOD(UICollection, index,
"Return index of first occurrence of element. Raises ValueError if not found."}, MCRF_SIG("(element: Drawable)", "int"),
MCRF_DESC("Return index of first occurrence of element.")
MCRF_ARGS_START
MCRF_ARG("element", "Drawable object to search for")
MCRF_RETURNS("int: index of the first occurrence")
MCRF_RAISES("ValueError", "If the element is not in the collection")
)},
{"count", (PyCFunction)UICollection::count, METH_O, {"count", (PyCFunction)UICollection::count, METH_O,
"count(element) -> int\n\n" MCRF_METHOD(UICollection, count,
"Count occurrences of element in the collection."}, MCRF_SIG("(element: Drawable)", "int"),
MCRF_DESC("Count occurrences of element in the collection.")
MCRF_ARGS_START
MCRF_ARG("element", "Drawable object to count")
MCRF_RETURNS("int: number of occurrences")
)},
{"find", (PyCFunction)UICollection::find, METH_VARARGS | METH_KEYWORDS, {"find", (PyCFunction)UICollection::find, METH_VARARGS | METH_KEYWORDS,
"find(name, recursive=False) -> element or list\n\n" MCRF_METHOD(UICollection, find,
"Find elements by name.\n\n" MCRF_SIG("(name: str, recursive: bool = False)", "Drawable | list | None"),
"Args:\n" MCRF_DESC("Find elements by name. Supports wildcard patterns.")
" name (str): Name to search for. Supports wildcards:\n" MCRF_ARGS_START
" - 'exact' for exact match (returns single element or None)\n" MCRF_ARG("name", "Name to search for. Use 'exact' for exact match, 'prefix*', '*suffix', or '*substring*' for wildcard matches")
" - 'prefix*' for starts-with match (returns list)\n" MCRF_ARG("recursive", "If True, search in Frame children recursively")
" - '*suffix' for ends-with match (returns list)\n" MCRF_RETURNS("Single Drawable for exact match, list for wildcard match, None if not found")
" - '*substring*' for contains match (returns list)\n" )},
" recursive (bool): If True, search in Frame children recursively.\n\n"
"Returns:\n"
" Single element if exact match, list if wildcard, None if not found."},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -20,6 +20,7 @@
#include "PyUniformCollection.h" // #106: Uniform collection support #include "PyUniformCollection.h" // #106: Uniform collection support
// UIDrawable methods now in UIBase.h // UIDrawable methods now in UIBase.h
#include "UIEntityPyMethods.h" #include "UIEntityPyMethods.h"
#include "McRFPy_Doc.h"
#include <cassert> #include <cassert>
// #313: UIEntity::grid holds the GridData base, but some Python wrappers // #313: UIEntity::grid holds the GridData base, but some Python wrappers
@ -1340,66 +1341,67 @@ PyObject* UIEntity::visible_entities(PyUIEntityObject* self, PyObject* args, PyO
PyMethodDef UIEntity::methods[] = { PyMethodDef UIEntity::methods[] = {
{"at", (PyCFunction)UIEntity::at, METH_VARARGS | METH_KEYWORDS, {"at", (PyCFunction)UIEntity::at, METH_VARARGS | METH_KEYWORDS,
"at(x, y) or at(pos) -> GridPoint | None\n\n" MCRF_METHOD(Entity, at,
"Return the GridPoint at (x, y) if currently VISIBLE to this entity's\n" MCRF_SIG("(x: int, y: int)", "GridPoint | None"),
"perspective_map, otherwise None. Equivalent to:\n" MCRF_DESC("Return the GridPoint at (x, y) if currently VISIBLE to this entity's perspective_map, otherwise None."),
" grid.at(x, y) if perspective_map[x, y] == Perspective.VISIBLE else None\n\n" MCRF_ARGS_START
"To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y]\n" MCRF_ARG("x", "Grid X coordinate (also accepts a tuple/Vector as first positional arg)")
"directly and use grid.at(x, y) for cell data.\n\n" MCRF_ARG("y", "Grid Y coordinate (omit when passing a tuple or Vector)")
"Args:\n" MCRF_RETURNS("GridPoint if visible, None if undiscovered or not currently in FOV")
" x, y: Grid coordinates as two integers, OR\n" MCRF_NOTE("To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y] directly.")
" pos: Grid coordinates as tuple, list, or Vector\n\n" )},
"Example:\n" {"index", (PyCFunction)UIEntity::index, METH_NOARGS,
" point = entity.at(5, 3)\n" MCRF_METHOD(Entity, index,
" if point is not None and point.walkable: ...\n" MCRF_SIG("()", "int"),
" point = entity.at((5, 3))\n" MCRF_DESC("Return the index of this entity in its grid's entity collection."),
" point = entity.at(pos=(5, 3))"}, MCRF_RETURNS("Zero-based index of this entity in grid.entities")
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"}, MCRF_RAISES("RuntimeError", "If entity is not associated with a grid")
)},
{"die", (PyCFunction)UIEntity::die, METH_NOARGS, {"die", (PyCFunction)UIEntity::die, METH_NOARGS,
"Remove this entity from its grid.\n\n" MCRF_METHOD(Entity, die,
"Warning: Do not call during iteration over grid.entities.\n" MCRF_SIG("()", "None"),
"Modifying the collection during iteration raises RuntimeError."}, MCRF_DESC("Remove this entity from its grid."),
MCRF_RETURNS("None")
MCRF_NOTE("Do not call during iteration over grid.entities; modifying the collection during iteration raises RuntimeError.")
)},
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS, {"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
"path_to(x, y) or path_to(target) -> list\n\n" MCRF_METHOD(Entity, path_to,
"Find a path to the target position using Dijkstra pathfinding.\n\n" MCRF_SIG("(x: int, y: int)", "list"),
"Args:\n" MCRF_DESC("Find a path to the target position using A* pathfinding."),
" x, y: Target coordinates as two integers, OR\n" MCRF_ARGS_START
" target: Target coordinates as tuple, list, or Vector\n\n" MCRF_ARG("x", "Target X coordinate (also accepts a tuple/Vector as first positional arg)")
"Returns:\n" MCRF_ARG("y", "Target Y coordinate (omit when passing a tuple or Vector)")
" List of (x, y) tuples representing the path.\n\n" MCRF_RETURNS("List of (x, y) tuples representing the path from current position to target")
"Example:\n" MCRF_RAISES("ValueError", "If entity has no grid or target is out of bounds")
" path = entity.path_to(10, 5)\n" )},
" path = entity.path_to((10, 5))\n"
" path = entity.path_to(pos=(10, 5))"},
{"find_path", (PyCFunction)UIEntity::find_path, METH_VARARGS | METH_KEYWORDS, {"find_path", (PyCFunction)UIEntity::find_path, METH_VARARGS | METH_KEYWORDS,
"find_path(target, diagonal_cost=1.41, collide=None) -> AStarPath | None\n\n" MCRF_METHOD(Entity, find_path,
"Find a path from this entity to the target position.\n\n" MCRF_SIG("(target, diagonal_cost: float = 1.41, collide: str = None)", "AStarPath | None"),
"Args:\n" MCRF_DESC("Find a path from this entity to the target position."),
" target: Target as Vector, Entity, or (x, y) tuple.\n" MCRF_ARGS_START
" diagonal_cost: Cost of diagonal movement (default 1.41).\n" MCRF_ARG("target", "Target as Vector, Entity, or (x, y) tuple")
" collide: Label string. Entities with this label block pathfinding.\n\n" MCRF_ARG("diagonal_cost", "Cost of diagonal movement (default 1.41)")
"Returns:\n" MCRF_ARG("collide", "Label string; entities with this label block pathfinding")
" AStarPath object, or None if no path exists.\n\n" MCRF_RETURNS("AStarPath object, or None if no path exists")
"Example:\n" MCRF_RAISES("ValueError", "If entity has no grid or positions are out of bounds")
" path = entity.find_path((10, 5))\n" )},
" path = entity.find_path(player, collide='enemy')"},
{"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS, {"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS,
"update_visibility() -> None\n\n" MCRF_METHOD(Entity, update_visibility,
"Update entity's visibility state based on current FOV.\n\n" MCRF_SIG("()", "None"),
"Recomputes which cells are visible from the entity's position and updates\n" MCRF_DESC("Recompute which cells are visible from this entity's position and update perspective_map."),
"the entity's perspective_map (see entity.perspective_map and mcrfpy.Perspective).\n" MCRF_RETURNS("None")
"This is called automatically when the entity moves if it has a grid with\n" MCRF_NOTE("Called automatically when the entity moves if the grid has FOV configured.")
"perspective set."}, )},
{"visible_entities", (PyCFunction)UIEntity::visible_entities, METH_VARARGS | METH_KEYWORDS, {"visible_entities", (PyCFunction)UIEntity::visible_entities, METH_VARARGS | METH_KEYWORDS,
"visible_entities(fov=None, radius=None) -> list[Entity]\n\n" MCRF_METHOD(Entity, visible_entities,
"Get list of other entities visible from this entity's position.\n\n" MCRF_SIG("(fov=None, radius: int = None)", "list[Entity]"),
"Args:\n" MCRF_DESC("Get list of other entities visible from this entity's position."),
" fov (FOV, optional): FOV algorithm to use. Default: grid.fov\n" MCRF_ARGS_START
" radius (int, optional): FOV radius. Default: grid.fov_radius\n\n" MCRF_ARG("fov", "FOV algorithm to use (FOV enum or None to use grid.fov)")
"Returns:\n" MCRF_ARG("radius", "FOV radius (int or None to use grid.fov_radius)")
" List of Entity objects that are within field of view.\n\n" MCRF_RETURNS("List of Entity objects within field of view, excluding self")
"Computes FOV from this entity's position and returns all other entities\n" MCRF_RAISES("ValueError", "If entity is not associated with a grid")
"whose positions fall within the visible area."}, )},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
@ -1747,194 +1749,193 @@ PyMethodDef UIEntity_all_methods[] = {
"Use list target with loop=True for repeating sprite frame animations.") "Use list target with loop=True for repeating sprite frame animations.")
)}, )},
{"at", (PyCFunction)UIEntity::at, METH_VARARGS | METH_KEYWORDS, {"at", (PyCFunction)UIEntity::at, METH_VARARGS | METH_KEYWORDS,
"at(x, y) or at(pos) -> GridPoint | None\n\n" MCRF_METHOD(Entity, at,
"Return the GridPoint at (x, y) if currently VISIBLE to this entity's\n" MCRF_SIG("(x: int, y: int)", "GridPoint | None"),
"perspective_map, otherwise None. Equivalent to:\n" MCRF_DESC("Return the GridPoint at (x, y) if currently VISIBLE to this entity's perspective_map, otherwise None."),
" grid.at(x, y) if perspective_map[x, y] == Perspective.VISIBLE else None\n\n" MCRF_ARGS_START
"To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y]\n" MCRF_ARG("x", "Grid X coordinate (also accepts a tuple/Vector as first positional arg)")
"directly and use grid.at(x, y) for cell data.\n\n" MCRF_ARG("y", "Grid Y coordinate (omit when passing a tuple or Vector)")
"Args:\n" MCRF_RETURNS("GridPoint if visible, None if undiscovered or not currently in FOV")
" x, y: Grid coordinates as two integers, OR\n" MCRF_NOTE("To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y] directly.")
" pos: Grid coordinates as tuple, list, or Vector\n\n" )},
"Example:\n" {"index", (PyCFunction)UIEntity::index, METH_NOARGS,
" point = entity.at(5, 3)\n" MCRF_METHOD(Entity, index,
" if point is not None and point.walkable: ...\n" MCRF_SIG("()", "int"),
" point = entity.at((5, 3))\n" MCRF_DESC("Return the index of this entity in its grid's entity collection."),
" point = entity.at(pos=(5, 3))"}, MCRF_RETURNS("Zero-based index of this entity in grid.entities")
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"}, MCRF_RAISES("RuntimeError", "If entity is not associated with a grid")
)},
{"die", (PyCFunction)UIEntity::die, METH_NOARGS, {"die", (PyCFunction)UIEntity::die, METH_NOARGS,
"Remove this entity from its grid.\n\n" MCRF_METHOD(Entity, die,
"Warning: Do not call during iteration over grid.entities.\n" MCRF_SIG("()", "None"),
"Modifying the collection during iteration raises RuntimeError."}, MCRF_DESC("Remove this entity from its grid."),
MCRF_RETURNS("None")
MCRF_NOTE("Do not call during iteration over grid.entities; modifying the collection during iteration raises RuntimeError.")
)},
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS, {"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
"path_to(x, y) or path_to(target) -> list\n\n" MCRF_METHOD(Entity, path_to,
"Find a path to the target position using Dijkstra pathfinding.\n\n" MCRF_SIG("(x: int, y: int)", "list"),
"Args:\n" MCRF_DESC("Find a path to the target position using A* pathfinding."),
" x, y: Target coordinates as two integers, OR\n" MCRF_ARGS_START
" target: Target coordinates as tuple, list, or Vector\n\n" MCRF_ARG("x", "Target X coordinate (also accepts a tuple/Vector as first positional arg)")
"Returns:\n" MCRF_ARG("y", "Target Y coordinate (omit when passing a tuple or Vector)")
" List of (x, y) tuples representing the path.\n\n" MCRF_RETURNS("List of (x, y) tuples representing the path from current position to target")
"Example:\n" MCRF_RAISES("ValueError", "If entity has no grid or target is out of bounds")
" path = entity.path_to(10, 5)\n" )},
" path = entity.path_to((10, 5))\n"
" path = entity.path_to(pos=(10, 5))"},
{"find_path", (PyCFunction)UIEntity::find_path, METH_VARARGS | METH_KEYWORDS, {"find_path", (PyCFunction)UIEntity::find_path, METH_VARARGS | METH_KEYWORDS,
"find_path(target, diagonal_cost=1.41, collide=None) -> AStarPath | None\n\n" MCRF_METHOD(Entity, find_path,
"Find a path from this entity to the target position.\n\n" MCRF_SIG("(target, diagonal_cost: float = 1.41, collide: str = None)", "AStarPath | None"),
"Args:\n" MCRF_DESC("Find a path from this entity to the target position."),
" target: Target as Vector, Entity, or (x, y) tuple.\n" MCRF_ARGS_START
" diagonal_cost: Cost of diagonal movement (default 1.41).\n" MCRF_ARG("target", "Target as Vector, Entity, or (x, y) tuple")
" collide: Label string. Entities with this label block pathfinding.\n\n" MCRF_ARG("diagonal_cost", "Cost of diagonal movement (default 1.41)")
"Returns:\n" MCRF_ARG("collide", "Label string; entities with this label block pathfinding")
" AStarPath object, or None if no path exists.\n\n" MCRF_RETURNS("AStarPath object, or None if no path exists")
"Example:\n" MCRF_RAISES("ValueError", "If entity has no grid or positions are out of bounds")
" path = entity.find_path((10, 5))\n" )},
" path = entity.find_path(player, collide='enemy')"},
{"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS, {"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS,
"update_visibility() -> None\n\n" MCRF_METHOD(Entity, update_visibility,
"Update entity's visibility state based on current FOV.\n\n" MCRF_SIG("()", "None"),
"Recomputes which cells are visible from the entity's position and updates\n" MCRF_DESC("Recompute which cells are visible from this entity's position and update perspective_map."),
"the entity's perspective_map (see entity.perspective_map and mcrfpy.Perspective).\n" MCRF_RETURNS("None")
"This is called automatically when the entity moves if it has a grid with\n" MCRF_NOTE("Called automatically when the entity moves if the grid has FOV configured.")
"perspective set."}, )},
{"visible_entities", (PyCFunction)UIEntity::visible_entities, METH_VARARGS | METH_KEYWORDS, {"visible_entities", (PyCFunction)UIEntity::visible_entities, METH_VARARGS | METH_KEYWORDS,
"visible_entities(fov=None, radius=None) -> list[Entity]\n\n" MCRF_METHOD(Entity, visible_entities,
"Get list of other entities visible from this entity's position.\n\n" MCRF_SIG("(fov=None, radius: int = None)", "list[Entity]"),
"Args:\n" MCRF_DESC("Get list of other entities visible from this entity's position."),
" fov (FOV, optional): FOV algorithm to use. Default: grid.fov\n" MCRF_ARGS_START
" radius (int, optional): FOV radius. Default: grid.fov_radius\n\n" MCRF_ARG("fov", "FOV algorithm to use (FOV enum or None to use grid.fov)")
"Returns:\n" MCRF_ARG("radius", "FOV radius (int or None to use grid.fov_radius)")
" List of Entity objects that are within field of view.\n\n" MCRF_RETURNS("List of Entity objects within field of view, excluding self")
"Computes FOV from this entity's position and returns all other entities\n" MCRF_RAISES("ValueError", "If entity is not associated with a grid")
"whose positions fall within the visible area."}, )},
// #296 - Label methods // #296 - Label methods
{"add_label", (PyCFunction)UIEntity::py_add_label, METH_O, {"add_label", (PyCFunction)UIEntity::py_add_label, METH_O,
"add_label(label: str) -> None\n\n" MCRF_METHOD(Entity, add_label,
"Add a label to this entity. Idempotent (adding same label twice is safe)."}, MCRF_SIG("(label: str)", "None"),
MCRF_DESC("Add a label to this entity. Idempotent; adding the same label twice is safe."),
MCRF_ARGS_START
MCRF_ARG("label", "String label to add")
MCRF_RETURNS("None")
)},
{"remove_label", (PyCFunction)UIEntity::py_remove_label, METH_O, {"remove_label", (PyCFunction)UIEntity::py_remove_label, METH_O,
"remove_label(label: str) -> None\n\n" MCRF_METHOD(Entity, remove_label,
"Remove a label from this entity. No-op if label not present."}, MCRF_SIG("(label: str)", "None"),
MCRF_DESC("Remove a label from this entity. No-op if label is not present."),
MCRF_ARGS_START
MCRF_ARG("label", "String label to remove")
MCRF_RETURNS("None")
)},
{"has_label", (PyCFunction)UIEntity::py_has_label, METH_O, {"has_label", (PyCFunction)UIEntity::py_has_label, METH_O,
"has_label(label: str) -> bool\n\n" MCRF_METHOD(Entity, has_label,
"Check if this entity has the given label."}, MCRF_SIG("(label: str)", "bool"),
MCRF_DESC("Check if this entity has the given label."),
MCRF_ARGS_START
MCRF_ARG("label", "String label to check")
MCRF_RETURNS("True if the entity has the label, False otherwise")
)},
// #300 - Behavior system // #300 - Behavior system
{"set_behavior", (PyCFunction)UIEntity::py_set_behavior, METH_VARARGS | METH_KEYWORDS, {"set_behavior", (PyCFunction)UIEntity::py_set_behavior, METH_VARARGS | METH_KEYWORDS,
"set_behavior(type, waypoints=None, turns=0, path=None) -> None\n\n" MCRF_METHOD(Entity, set_behavior,
"Configure this entity's behavior for grid.step() turn management.\n\n" MCRF_SIG("(type, waypoints=None, turns: int = 0, path=None, pathfinder=None)", "None"),
"Args:\n" MCRF_DESC("Configure this entity's behavior for grid.step() turn management."),
" type (int/Behavior): Behavior type (e.g., Behavior.PATROL)\n" MCRF_ARGS_START
" waypoints (list): List of (x, y) tuples for WAYPOINT/PATROL/LOOP\n" MCRF_ARG("type", "Behavior type (int or Behavior enum, e.g., Behavior.PATROL)")
" turns (int): Number of turns for SLEEP behavior\n" MCRF_ARG("waypoints", "List of (x, y) tuples for WAYPOINT/PATROL/LOOP behaviors")
" path (list): Pre-computed path as list of (x, y) tuples for PATH behavior"}, MCRF_ARG("turns", "Number of turns for SLEEP behavior")
MCRF_ARG("path", "Pre-computed path as list of (x, y) tuples for PATH behavior")
MCRF_ARG("pathfinder", "DijkstraMap, AStarPath, or (x, y) target tuple for SEEK behavior")
MCRF_RETURNS("None")
)},
{NULL} // Sentinel {NULL} // Sentinel
}; };
PyGetSetDef UIEntity::getsetters[] = { PyGetSetDef UIEntity::getsetters[] = {
// #176 - Pixel coordinates (relative to grid, like UIDrawable.pos) // #176 - Pixel coordinates (relative to grid, like UIDrawable.pos)
{"pos", (getter)UIEntity::get_pixel_pos, (setter)UIEntity::set_pixel_pos, {"pos", (getter)UIEntity::get_pixel_pos, (setter)UIEntity::set_pixel_pos,
"Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. " MCRF_PROPERTY(pos, "Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. Requires entity to be attached to a grid."), NULL},
"Requires entity to be attached to a grid.", NULL},
{"x", (getter)UIEntity::get_pixel_member, (setter)UIEntity::set_pixel_member, {"x", (getter)UIEntity::get_pixel_member, (setter)UIEntity::set_pixel_member,
"Pixel X position relative to grid. Requires entity to be attached to a grid.", (void*)0}, MCRF_PROPERTY(x, "Pixel X position relative to grid (float). Requires entity to be attached to a grid."), (void*)0},
{"y", (getter)UIEntity::get_pixel_member, (setter)UIEntity::set_pixel_member, {"y", (getter)UIEntity::get_pixel_member, (setter)UIEntity::set_pixel_member,
"Pixel Y position relative to grid. Requires entity to be attached to a grid.", (void*)1}, MCRF_PROPERTY(y, "Pixel Y position relative to grid (float). Requires entity to be attached to a grid."), (void*)1},
// #295 - Integer cell position (decoupled from float draw_pos) // #295 - Integer cell position (decoupled from float draw_pos)
// #314 F3: grid_pos is the CANONICAL name (matches the grid_pos= constructor // #314 F3: grid_pos is the CANONICAL name (matches the grid_pos= constructor
// argument); cell_pos/cell_x/cell_y are documented aliases. Both share the // argument); cell_pos/cell_x/cell_y are documented aliases. Both share the
// same getter/setter and remain fully interchangeable. // same getter/setter and remain fully interchangeable.
{"grid_pos", (getter)UIEntity::get_cell_pos, (setter)UIEntity::set_cell_pos, {"grid_pos", (getter)UIEntity::get_cell_pos, (setter)UIEntity::set_cell_pos,
"Integer logical cell position (Vector). Canonical cell-position property; " MCRF_PROPERTY(grid_pos, "Integer logical cell position (Vector). Canonical cell-position property matching the 'grid_pos' constructor argument. Decoupled from draw_pos. Determines which cell this entity logically occupies for collision and pathfinding."), NULL},
"matches the 'grid_pos' constructor argument. Decoupled from draw_pos. "
"Determines which cell this entity logically occupies for collision, pathfinding, etc.", NULL},
{"grid_x", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member, {"grid_x", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member,
"Integer X cell coordinate. Canonical; matches grid_pos.", (void*)0}, MCRF_PROPERTY(grid_x, "Integer X cell coordinate (int). Canonical; matches grid_pos."), (void*)0},
{"grid_y", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member, {"grid_y", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member,
"Integer Y cell coordinate. Canonical; matches grid_pos.", (void*)1}, MCRF_PROPERTY(grid_y, "Integer Y cell coordinate (int). Canonical; matches grid_pos."), (void*)1},
{"cell_pos", (getter)UIEntity::get_cell_pos, (setter)UIEntity::set_cell_pos, {"cell_pos", (getter)UIEntity::get_cell_pos, (setter)UIEntity::set_cell_pos,
"Integer logical cell position (Vector). Alias for grid_pos (the canonical name).", NULL}, MCRF_PROPERTY(cell_pos, "Integer logical cell position (Vector). Alias for grid_pos (the canonical name)."), NULL},
{"cell_x", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member, {"cell_x", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member,
"Integer X cell coordinate. Alias for grid_x.", (void*)0}, MCRF_PROPERTY(cell_x, "Integer X cell coordinate (int). Alias for grid_x."), (void*)0},
{"cell_y", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member, {"cell_y", (getter)UIEntity::get_cell_member, (setter)UIEntity::set_cell_member,
"Integer Y cell coordinate. Alias for grid_y.", (void*)1}, MCRF_PROPERTY(cell_y, "Integer Y cell coordinate (int). Alias for grid_y."), (void*)1},
// Float tile coordinates (for smooth animation between tiles) // Float tile coordinates (for smooth animation between tiles)
{"draw_pos", (getter)UIEntity::get_position, (setter)UIEntity::set_position, {"draw_pos", (getter)UIEntity::get_position, (setter)UIEntity::set_position,
"Fractional tile position for rendering (Vector). Use for smooth animation between grid cells.", (void*)0}, MCRF_PROPERTY(draw_pos, "Fractional tile position for rendering (Vector). Use for smooth animation between grid cells."), (void*)0},
{"perspective_map", (getter)UIEntity::get_perspective_map, (setter)UIEntity::set_perspective_map, {"perspective_map", (getter)UIEntity::get_perspective_map, (setter)UIEntity::set_perspective_map,
"Per-entity FOV memory (DiscreteMap, read-write). 3-state values per cell: " MCRF_PROPERTY(perspective_map, "Per-entity FOV memory (DiscreteMap). 3-state values per cell: 0=unknown, 1=discovered, 2=visible. Lazy-allocated on first access once entity has a grid; returns None otherwise. The returned DiscreteMap is a live reference. Assigning a DiscreteMap replaces the entity's memory; size must match the grid or ValueError is raised. Assign None to clear."),
"0 = unknown (never seen), 1 = discovered (seen before, not currently visible), "
"2 = visible (in current FOV). Use mcrfpy.Perspective enum for clarity. "
"Lazy-allocated on first access once the entity has a grid; returns None otherwise. "
"The returned DiscreteMap is a live reference -- mutations are visible to subsequent "
"updateVisibility() calls. Assigning a DiscreteMap replaces the entity's memory; "
"the new map's size must match the grid's size or ValueError is raised. "
"Assign None to clear (will be lazy-reallocated on next access).",
NULL}, NULL},
{"grid", (getter)UIEntity::get_grid, (setter)UIEntity::set_grid, {"grid", (getter)UIEntity::get_grid, (setter)UIEntity::set_grid,
"Grid this entity belongs to. " MCRF_PROPERTY(grid, "Grid this entity belongs to (Grid or None). Assign a Grid to attach the entity, or None to remove it from its current grid."), NULL},
"Get: Returns the Grid or None. " {"sprite_index", (getter)UIEntity::get_spritenumber, (setter)UIEntity::set_spritenumber,
"Set: Assign a Grid to move entity, or None to remove from grid.", NULL}, MCRF_PROPERTY(sprite_index, "Sprite index into the entity's texture atlas (int)."), NULL},
{"sprite_index", (getter)UIEntity::get_spritenumber, (setter)UIEntity::set_spritenumber, "Sprite index on the texture on the display", NULL},
// #313 - entities render from their OWN texture, not the grid's // #313 - entities render from their OWN texture, not the grid's
{"texture", (getter)UIEntity::get_texture, (setter)UIEntity::set_texture, {"texture", (getter)UIEntity::get_texture, (setter)UIEntity::set_texture,
"Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture when " MCRF_PROPERTY(texture, "Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture at construction. Setting preserves sprite_index (not re-validated against the new atlas)."), NULL},
"the entity is constructed without one. Setting preserves sprite_index " {"visible", (getter)UIEntity_get_visible, (setter)UIEntity_set_visible,
"(the index is not re-validated against the new atlas). The grid's " MCRF_PROPERTY(visible, "Visibility flag (bool). When False, the entity is not rendered."), NULL},
"texture only determines cell size; entities draw with their own.", NULL}, {"opacity", (getter)UIEntity_get_opacity, (setter)UIEntity_set_opacity,
{"visible", (getter)UIEntity_get_visible, (setter)UIEntity_set_visible, "Visibility flag", NULL}, MCRF_PROPERTY(opacity, "Render opacity (float). 0.0 = fully transparent, 1.0 = fully opaque."), NULL},
{"opacity", (getter)UIEntity_get_opacity, (setter)UIEntity_set_opacity, "Opacity (0.0 = transparent, 1.0 = opaque)", NULL}, {"name", (getter)UIEntity_get_name, (setter)UIEntity_set_name,
{"name", (getter)UIEntity_get_name, (setter)UIEntity_set_name, "Name for finding elements", NULL}, MCRF_PROPERTY(name, "Entity name for lookup (str)."), NULL},
{"shader", (getter)UIEntity_get_shader, (setter)UIEntity_set_shader, {"shader", (getter)UIEntity_get_shader, (setter)UIEntity_set_shader,
"Shader for GPU visual effects (Shader or None). " MCRF_PROPERTY(shader, "GPU shader for visual effects (Shader or None). Set to None to disable shader rendering."), NULL},
"When set, the entity is rendered through the shader program. "
"Set to None to disable shader effects.", NULL},
{"uniforms", (getter)UIEntity_get_uniforms, NULL, {"uniforms", (getter)UIEntity_get_uniforms, NULL,
"Collection of shader uniforms (read-only access to collection). " MCRF_PROPERTY(uniforms, "Collection of shader uniforms (UniformCollection, read-only). Set values via dict-like syntax: entity.uniforms['name'] = value."), NULL},
"Set uniforms via dict-like syntax: entity.uniforms['name'] = value. "
"Supports float, vec2/3/4 tuples, PropertyBinding, and CallableBinding.", NULL},
{"sprite_offset", (getter)UIEntity::get_sprite_offset, (setter)UIEntity::set_sprite_offset, {"sprite_offset", (getter)UIEntity::get_sprite_offset, (setter)UIEntity::set_sprite_offset,
"Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering.", NULL}, MCRF_PROPERTY(sprite_offset, "Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering."), NULL},
{"sprite_offset_x", (getter)UIEntity::get_sprite_offset_member, (setter)UIEntity::set_sprite_offset_member, {"sprite_offset_x", (getter)UIEntity::get_sprite_offset_member, (setter)UIEntity::set_sprite_offset_member,
"X component of sprite pixel offset.", (void*)0}, MCRF_PROPERTY(sprite_offset_x, "X component of sprite pixel offset (float)."), (void*)0},
{"sprite_offset_y", (getter)UIEntity::get_sprite_offset_member, (setter)UIEntity::set_sprite_offset_member, {"sprite_offset_y", (getter)UIEntity::get_sprite_offset_member, (setter)UIEntity::set_sprite_offset_member,
"Y component of sprite pixel offset.", (void*)1}, MCRF_PROPERTY(sprite_offset_y, "Y component of sprite pixel offset (float)."), (void*)1},
// #236 - Multi-tile entity size // #236 - Multi-tile entity size
{"tile_size", (getter)UIEntity::get_tile_size, (setter)UIEntity::set_tile_size, {"tile_size", (getter)UIEntity::get_tile_size, (setter)UIEntity::set_tile_size,
"Entity size in tiles as (width, height) Vector. Default (1, 1).", NULL}, MCRF_PROPERTY(tile_size, "Entity size in tiles as (width, height) (Vector). Default (1, 1)."), NULL},
{"tile_width", (getter)UIEntity::get_tile_width, (setter)UIEntity::set_tile_width, {"tile_width", (getter)UIEntity::get_tile_width, (setter)UIEntity::set_tile_width,
"Entity width in tiles (int). Must be >= 1. Default 1.", NULL}, MCRF_PROPERTY(tile_width, "Entity width in tiles (int). Must be >= 1. Default 1."), NULL},
{"tile_height", (getter)UIEntity::get_tile_height, (setter)UIEntity::set_tile_height, {"tile_height", (getter)UIEntity::get_tile_height, (setter)UIEntity::set_tile_height,
"Entity height in tiles (int). Must be >= 1. Default 1.", NULL}, MCRF_PROPERTY(tile_height, "Entity height in tiles (int). Must be >= 1. Default 1."), NULL},
// #237 - Composite sprite grid // #237 - Composite sprite grid
{"sprite_grid", (getter)UIEntity::get_sprite_grid, (setter)UIEntity::set_sprite_grid, {"sprite_grid", (getter)UIEntity::get_sprite_grid, (setter)UIEntity::set_sprite_grid,
"Per-tile sprite indices for composite multi-tile entities (list of lists or None). " MCRF_PROPERTY(sprite_grid, "Per-tile sprite indices for composite multi-tile entities (list of lists or None). Row-major, dimensions must match tile_width x tile_height. Use -1 for empty tiles."), NULL},
"Row-major, dimensions must match tile_width x tile_height. Use -1 for empty tiles. "
"When set, each tile renders its own sprite index instead of the single entity sprite.", NULL},
// #296 - Label system // #296 - Label system
{"labels", (getter)UIEntity::get_labels, (setter)UIEntity::set_labels, {"labels", (getter)UIEntity::get_labels, (setter)UIEntity::set_labels,
"Set of string labels for collision/targeting (frozenset). " MCRF_PROPERTY(labels, "String labels for collision and targeting (frozenset). Assign any iterable of strings to replace all labels."), NULL},
"Assign any iterable of strings to replace all labels.", NULL},
// #299 - Step callback and default behavior // #299 - Step callback and default behavior
{"step", (getter)UIEntity::get_step, (setter)UIEntity::set_step, {"step", (getter)UIEntity::get_step, (setter)UIEntity::set_step,
"Step callback for grid.step() turn management. " MCRF_PROPERTY(step, "Step callback for grid.step() turn management (Callable or None). Called with (trigger, data) when behavior triggers fire."), NULL},
"Called with (trigger, data) when behavior triggers fire. "
"Set to None to clear.", NULL},
{"default_behavior", (getter)UIEntity::get_default_behavior, (setter)UIEntity::set_default_behavior, {"default_behavior", (getter)UIEntity::get_default_behavior, (setter)UIEntity::set_default_behavior,
"Default behavior type (int, maps to Behavior enum). " MCRF_PROPERTY(default_behavior, "Default behavior type (int, maps to Behavior enum). Entity reverts to this after DONE trigger. Default: 0 (IDLE)."), NULL},
"Entity reverts to this after DONE trigger. Default: 0 (IDLE).", NULL},
// #300 - Behavior system // #300 - Behavior system
{"behavior_type", (getter)UIEntity::get_behavior_type, NULL, {"behavior_type", (getter)UIEntity::get_behavior_type, NULL,
"Current behavior type (int, read-only). Use set_behavior() to change.", NULL}, MCRF_PROPERTY(behavior_type, "Current behavior type (int, read-only). Use set_behavior() to change."), NULL},
{"turn_order", (getter)UIEntity::get_turn_order, (setter)UIEntity::set_turn_order, {"turn_order", (getter)UIEntity::get_turn_order, (setter)UIEntity::set_turn_order,
"Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1.", NULL}, MCRF_PROPERTY(turn_order, "Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1."), NULL},
{"move_speed", (getter)UIEntity::get_move_speed, (setter)UIEntity::set_move_speed, {"move_speed", (getter)UIEntity::get_move_speed, (setter)UIEntity::set_move_speed,
"Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15.", NULL}, MCRF_PROPERTY(move_speed, "Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15."), NULL},
{"target_label", (getter)UIEntity::get_target_label, (setter)UIEntity::set_target_label, {"target_label", (getter)UIEntity::get_target_label, (setter)UIEntity::set_target_label,
"Label to search for with TARGET trigger (str or None). Default: None.", NULL}, MCRF_PROPERTY(target_label, "Label to search for with TARGET trigger (str or None). Default: None."), NULL},
{"sight_radius", (getter)UIEntity::get_sight_radius, (setter)UIEntity::set_sight_radius, {"sight_radius", (getter)UIEntity::get_sight_radius, (setter)UIEntity::set_sight_radius,
"FOV radius for TARGET trigger (int). Default: 10.", NULL}, MCRF_PROPERTY(sight_radius, "FOV radius for TARGET trigger (int). Default: 10."), NULL},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };

View file

@ -7,6 +7,7 @@
#include "UIEntity.h" #include "UIEntity.h"
#include "UIGrid.h" #include "UIGrid.h"
#include "McRFPy_API.h" #include "McRFPy_API.h"
#include "McRFPy_Doc.h"
#include "PythonObjectCache.h" #include "PythonObjectCache.h"
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
@ -958,37 +959,74 @@ PyObject* UIEntityCollection::find(PyUIEntityCollectionObject* self, PyObject* a
PyMethodDef UIEntityCollection::methods[] = { PyMethodDef UIEntityCollection::methods[] = {
{"append", (PyCFunction)UIEntityCollection::append, METH_O, {"append", (PyCFunction)UIEntityCollection::append, METH_O,
"append(entity)\n\n" MCRF_METHOD(EntityCollection, append,
"Add an entity to the end of the collection."}, MCRF_SIG("(entity: Entity)", "None"),
MCRF_DESC("Add an entity to the end of the collection."),
MCRF_ARGS_START
MCRF_ARG("entity", "Entity object to append")
MCRF_RETURNS("None")
)},
{"extend", (PyCFunction)UIEntityCollection::extend, METH_O, {"extend", (PyCFunction)UIEntityCollection::extend, METH_O,
"extend(iterable)\n\n" MCRF_METHOD(EntityCollection, extend,
"Add all entities from an iterable to the collection."}, MCRF_SIG("(iterable)", "None"),
MCRF_DESC("Add all entities from an iterable to the collection."),
MCRF_ARGS_START
MCRF_ARG("iterable", "Iterable of Entity objects to add")
MCRF_RETURNS("None")
MCRF_RAISES("TypeError", "If any item is not an Entity object")
)},
{"insert", (PyCFunction)UIEntityCollection::insert, METH_VARARGS, {"insert", (PyCFunction)UIEntityCollection::insert, METH_VARARGS,
"insert(index, entity)\n\n" MCRF_METHOD(EntityCollection, insert,
"Insert entity at index. Like list.insert(), indices past the end append."}, MCRF_SIG("(index: int, entity: Entity)", "None"),
MCRF_DESC("Insert entity at index. Like list.insert(), indices past the end append."),
MCRF_ARGS_START
MCRF_ARG("index", "Position at which to insert the entity")
MCRF_ARG("entity", "Entity object to insert")
MCRF_RETURNS("None")
)},
{"remove", (PyCFunction)UIEntityCollection::remove, METH_O, {"remove", (PyCFunction)UIEntityCollection::remove, METH_O,
"remove(entity)\n\n" MCRF_METHOD(EntityCollection, remove,
"Remove first occurrence of entity. Raises ValueError if not found."}, MCRF_SIG("(entity: Entity)", "None"),
MCRF_DESC("Remove first occurrence of entity from the collection."),
MCRF_ARGS_START
MCRF_ARG("entity", "Entity object to remove")
MCRF_RETURNS("None")
MCRF_RAISES("ValueError", "If the entity is not in the collection")
)},
{"pop", (PyCFunction)UIEntityCollection::pop, METH_VARARGS, {"pop", (PyCFunction)UIEntityCollection::pop, METH_VARARGS,
"pop([index]) -> entity\n\n" MCRF_METHOD(EntityCollection, pop,
"Remove and return entity at index (default: last entity)."}, MCRF_SIG("(index: int = -1)", "Entity"),
MCRF_DESC("Remove and return entity at index (default: last entity)."),
MCRF_ARGS_START
MCRF_ARG("index", "Index of entity to remove; defaults to -1 (last entity)")
MCRF_RETURNS("Entity: the removed entity")
MCRF_RAISES("IndexError", "If the collection is empty or index is out of range")
)},
{"index", (PyCFunction)UIEntityCollection::index_method, METH_O, {"index", (PyCFunction)UIEntityCollection::index_method, METH_O,
"index(entity) -> int\n\n" MCRF_METHOD(EntityCollection, index,
"Return index of first occurrence of entity. Raises ValueError if not found."}, MCRF_SIG("(entity: Entity)", "int"),
MCRF_DESC("Return index of first occurrence of entity in the collection."),
MCRF_ARGS_START
MCRF_ARG("entity", "Entity object to find")
MCRF_RETURNS("int: zero-based index of the entity")
MCRF_RAISES("ValueError", "If the entity is not in the collection")
)},
{"count", (PyCFunction)UIEntityCollection::count, METH_O, {"count", (PyCFunction)UIEntityCollection::count, METH_O,
"count(entity) -> int\n\n" MCRF_METHOD(EntityCollection, count,
"Count occurrences of entity in the collection."}, MCRF_SIG("(entity: Entity)", "int"),
MCRF_DESC("Count occurrences of entity in the collection."),
MCRF_ARGS_START
MCRF_ARG("entity", "Entity object to count")
MCRF_RETURNS("int: number of times entity appears in the collection")
)},
{"find", (PyCFunction)UIEntityCollection::find, METH_VARARGS | METH_KEYWORDS, {"find", (PyCFunction)UIEntityCollection::find, METH_VARARGS | METH_KEYWORDS,
"find(name) -> entity or list\n\n" MCRF_METHOD(EntityCollection, find,
"Find entities by name.\n\n" MCRF_SIG("(name: str)", "Entity | list | None"),
"Args:\n" MCRF_DESC("Find entities by name. Returns a single entity for exact matches or a list for wildcard patterns."),
" name (str): Name to search for. Supports wildcards:\n" MCRF_ARGS_START
" - 'exact' for exact match (returns single entity or None)\n" MCRF_ARG("name", "Name to search for; supports wildcards: 'exact', 'prefix*', '*suffix', '*substring*'")
" - 'prefix*' for starts-with match (returns list)\n" MCRF_RETURNS("Entity if exact match found, list of Entity if wildcard pattern, None if no exact match")
" - '*suffix' for ends-with match (returns list)\n" )},
" - '*substring*' for contains match (returns list)\n\n"
"Returns:\n"
" Single entity if exact match, list if wildcard, None if not found."},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -12,6 +12,7 @@
#include "PyShader.h" // #106: Shader support #include "PyShader.h" // #106: Shader support
#include "PyUniformCollection.h" // #106: Uniform collection #include "PyUniformCollection.h" // #106: Uniform collection
#include <iostream> // #106: for shader error output #include <iostream> // #106: for shader error output
#include "McRFPy_Doc.h"
// UIDrawable methods now in UIBase.h // UIDrawable methods now in UIBase.h
UIDrawable* UIFrame::click_at(sf::Vector2f point) UIDrawable* UIFrame::click_at(sf::Vector2f point)
@ -519,18 +520,36 @@ PyMethodDef UIFrame_methods[] = {
}; };
PyGetSetDef UIFrame::getsetters[] = { PyGetSetDef UIFrame::getsetters[] = {
{"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "X coordinate of top-left corner", (void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 0)}, {"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "Y coordinate of top-left corner", (void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 1)}, MCRF_PROPERTY(x, "X coordinate of the top-left corner (float)."),
{"w", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "width of the rectangle", (void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 2)}, (void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 0)},
{"h", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "height of the rectangle", (void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 3)}, {"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"outline", (getter)UIFrame::get_float_member, (setter)UIFrame::set_float_member, "Thickness of the border", (void*)4}, MCRF_PROPERTY(y, "Y coordinate of the top-left corner (float)."),
(void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 1)},
{"w", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
MCRF_PROPERTY(w, "Width of the rectangle (float)."),
(void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 2)},
{"h", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
MCRF_PROPERTY(h, "Height of the rectangle (float)."),
(void*)((intptr_t)PyObjectsEnum::UIFRAME << 8 | 3)},
{"outline", (getter)UIFrame::get_float_member, (setter)UIFrame::set_float_member,
MCRF_PROPERTY(outline, "Thickness of the border in pixels (float)."),
(void*)4},
{"fill_color", (getter)UIFrame::get_color_member, (setter)UIFrame::set_color_member, {"fill_color", (getter)UIFrame::get_color_member, (setter)UIFrame::set_color_member,
"Fill color of the rectangle. Returns a copy; modifying components requires reassignment. " MCRF_PROPERTY(fill_color,
"For animation, use 'fill_color.r', 'fill_color.g', etc.", (void*)0}, "Fill color of the rectangle (Color). "
"Returns a copy; modifying components requires reassignment. "
"For animation, use 'fill_color.r', 'fill_color.g', etc."
), (void*)0},
{"outline_color", (getter)UIFrame::get_color_member, (setter)UIFrame::set_color_member, {"outline_color", (getter)UIFrame::get_color_member, (setter)UIFrame::set_color_member,
"Outline color of the rectangle. Returns a copy; modifying components requires reassignment. " MCRF_PROPERTY(outline_color,
"For animation, use 'outline_color.r', 'outline_color.g', etc.", (void*)1}, "Outline color of the rectangle (Color). "
{"children", (getter)UIFrame::get_children, NULL, "UICollection of objects on top of this one", NULL}, "Returns a copy; modifying components requires reassignment. "
"For animation, use 'outline_color.r', 'outline_color.g', etc."
), (void*)1},
{"children", (getter)UIFrame::get_children, NULL,
MCRF_PROPERTY(children, "UICollection of child drawable objects rendered on top of this frame (UICollection, read-only)."),
NULL},
{"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, {"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click,
MCRF_PROPERTY(on_click, MCRF_PROPERTY(on_click,
"Callable executed when object is clicked. " "Callable executed when object is clicked. "
@ -541,12 +560,24 @@ PyGetSetDef UIFrame::getsetters[] = {
"Z-order for rendering (lower values rendered first). " "Z-order for rendering (lower values rendered first). "
"Automatically triggers scene resort when changed." "Automatically triggers scene resort when changed."
), (void*)PyObjectsEnum::UIFRAME}, ), (void*)PyObjectsEnum::UIFRAME},
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, "Name for finding elements", (void*)PyObjectsEnum::UIFRAME}, {"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name,
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, "Position as a Vector", (void*)PyObjectsEnum::UIFRAME}, MCRF_PROPERTY(name, "Name for finding elements (str)."),
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos, "Position in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UIFRAME}, (void*)PyObjectsEnum::UIFRAME},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size, "Size in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UIFRAME}, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
{"clip_children", (getter)UIFrame::get_clip_children, (setter)UIFrame::set_clip_children, "Whether to clip children to frame bounds", NULL}, MCRF_PROPERTY(pos, "Position as a Vector (Vector)."),
{"cache_subtree", (getter)UIFrame::get_cache_subtree, (setter)UIFrame::set_cache_subtree, "#144: Cache subtree rendering to texture for performance", NULL}, (void*)PyObjectsEnum::UIFRAME},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos,
MCRF_PROPERTY(grid_pos, "Position in grid tile coordinates (Vector). Only meaningful when this element's parent is a Grid."),
(void*)PyObjectsEnum::UIFRAME},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size,
MCRF_PROPERTY(grid_size, "Size in grid tile coordinates (Vector). Only meaningful when this element's parent is a Grid."),
(void*)PyObjectsEnum::UIFRAME},
{"clip_children", (getter)UIFrame::get_clip_children, (setter)UIFrame::set_clip_children,
MCRF_PROPERTY(clip_children, "Whether to clip child elements to the frame's bounds (bool). Enables render-texture mode when True."),
NULL},
{"cache_subtree", (getter)UIFrame::get_cache_subtree, (setter)UIFrame::set_cache_subtree,
MCRF_PROPERTY(cache_subtree, "Cache the frame and all children to a render texture for performance (bool). Useful for complex static subtrees."),
NULL},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIFRAME), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIFRAME),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIFRAME), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIFRAME),

View file

@ -7,6 +7,7 @@
#include "PyPositionHelper.h" #include "PyPositionHelper.h"
#include "PyHeuristic.h" #include "PyHeuristic.h"
#include "PyDiscreteMap.h" #include "PyDiscreteMap.h"
#include "McRFPy_Doc.h"
//============================================================================= //=============================================================================
// DijkstraMap Implementation // DijkstraMap Implementation
@ -914,20 +915,20 @@ namespace mcrfpydef {
// AStarPath methods // AStarPath methods
PyMethodDef PyAStarPath_methods[] = { PyMethodDef PyAStarPath_methods[] = {
{"walk", (PyCFunction)UIGridPathfinding::AStarPath_walk, METH_NOARGS, {"walk", (PyCFunction)UIGridPathfinding::AStarPath_walk, METH_NOARGS,
"walk() -> Vector\n\n" MCRF_METHOD(AStarPath, walk,
"Get and consume next step in the path.\n\n" MCRF_SIG("()", "Vector"),
"Returns:\n" MCRF_DESC("Get and consume the next step in the path.")
" Next position as Vector.\n\n" MCRF_RETURNS("Next position as Vector")
"Raises:\n" MCRF_RAISES("IndexError", "If the path is exhausted")
" IndexError: If path is exhausted."}, )},
{"peek", (PyCFunction)UIGridPathfinding::AStarPath_peek, METH_NOARGS, {"peek", (PyCFunction)UIGridPathfinding::AStarPath_peek, METH_NOARGS,
"peek() -> Vector\n\n" MCRF_METHOD(AStarPath, peek,
"See next step without consuming it.\n\n" MCRF_SIG("()", "Vector"),
"Returns:\n" MCRF_DESC("See the next step without consuming it.")
" Next position as Vector.\n\n" MCRF_RETURNS("Next position as Vector")
"Raises:\n" MCRF_RAISES("IndexError", "If the path is exhausted")
" IndexError: If path is exhausted."}, )},
{NULL} {NULL}
}; };
@ -935,13 +936,13 @@ PyMethodDef PyAStarPath_methods[] = {
// AStarPath getsetters // AStarPath getsetters
PyGetSetDef PyAStarPath_getsetters[] = { PyGetSetDef PyAStarPath_getsetters[] = {
{"origin", (getter)UIGridPathfinding::AStarPath_get_origin, NULL, {"origin", (getter)UIGridPathfinding::AStarPath_get_origin, NULL,
"Starting position of the path (Vector, read-only).", NULL}, MCRF_PROPERTY(origin, "Starting position of the path (Vector, read-only)."), NULL},
{"destination", (getter)UIGridPathfinding::AStarPath_get_destination, NULL, {"destination", (getter)UIGridPathfinding::AStarPath_get_destination, NULL,
"Ending position of the path (Vector, read-only).", NULL}, MCRF_PROPERTY(destination, "Ending position of the path (Vector, read-only)."), NULL},
{"remaining", (getter)UIGridPathfinding::AStarPath_get_remaining, NULL, {"remaining", (getter)UIGridPathfinding::AStarPath_get_remaining, NULL,
"Number of steps remaining in the path (int, read-only).", NULL}, MCRF_PROPERTY(remaining, "Number of steps remaining in the path (int, read-only)."), NULL},
{NULL} {NULL}
}; };
@ -1005,60 +1006,57 @@ PyTypeObject PyAStarPathIterType = {
// DijkstraMap methods // DijkstraMap methods
PyMethodDef PyDijkstraMap_methods[] = { PyMethodDef PyDijkstraMap_methods[] = {
{"distance", (PyCFunction)UIGridPathfinding::DijkstraMap_distance, METH_VARARGS | METH_KEYWORDS, {"distance", (PyCFunction)UIGridPathfinding::DijkstraMap_distance, METH_VARARGS | METH_KEYWORDS,
"distance(pos) -> float | None\n\n" MCRF_METHOD(DijkstraMap, distance,
"Get distance from position to root.\n\n" MCRF_SIG("(pos: Vector | tuple)", "float | None"),
"Args:\n" MCRF_DESC("Get distance from position to root.")
" pos: Position as Vector, Entity, or (x, y) tuple.\n\n" MCRF_ARGS_START
"Returns:\n" MCRF_ARG("pos", "Position as Vector, Entity, or (x, y) tuple")
" Float distance, or None if position is unreachable."}, MCRF_RETURNS("Float distance, or None if position is unreachable")
)},
{"path_from", (PyCFunction)UIGridPathfinding::DijkstraMap_path_from, METH_VARARGS | METH_KEYWORDS, {"path_from", (PyCFunction)UIGridPathfinding::DijkstraMap_path_from, METH_VARARGS | METH_KEYWORDS,
"path_from(pos) -> AStarPath\n\n" MCRF_METHOD(DijkstraMap, path_from,
"Get full path from position to root.\n\n" MCRF_SIG("(pos: Vector | tuple)", "AStarPath"),
"Args:\n" MCRF_DESC("Get full path from position to root.")
" pos: Starting position as Vector, Entity, or (x, y) tuple.\n\n" MCRF_ARGS_START
"Returns:\n" MCRF_ARG("pos", "Starting position as Vector, Entity, or (x, y) tuple")
" AStarPath from pos toward root."}, MCRF_RETURNS("AStarPath from pos toward root")
)},
{"step_from", (PyCFunction)UIGridPathfinding::DijkstraMap_step_from, METH_VARARGS | METH_KEYWORDS, {"step_from", (PyCFunction)UIGridPathfinding::DijkstraMap_step_from, METH_VARARGS | METH_KEYWORDS,
"step_from(pos) -> Vector | None\n\n" MCRF_METHOD(DijkstraMap, step_from,
"Get single step from position toward root.\n\n" MCRF_SIG("(pos: Vector | tuple)", "Vector | None"),
"Args:\n" MCRF_DESC("Get single step from position toward root.")
" pos: Current position as Vector, Entity, or (x, y) tuple.\n\n" MCRF_ARGS_START
"Returns:\n" MCRF_ARG("pos", "Current position as Vector, Entity, or (x, y) tuple")
" Next position as Vector, or None if at root or unreachable."}, MCRF_RETURNS("Next position as Vector, or None if at root or unreachable")
)},
{"to_heightmap", (PyCFunction)UIGridPathfinding::DijkstraMap_to_heightmap, METH_VARARGS | METH_KEYWORDS, {"to_heightmap", (PyCFunction)UIGridPathfinding::DijkstraMap_to_heightmap, METH_VARARGS | METH_KEYWORDS,
"to_heightmap(size=None, unreachable=-1.0) -> HeightMap\n\n" MCRF_METHOD(DijkstraMap, to_heightmap,
"Convert distance field to a HeightMap.\n\n" MCRF_SIG("(size=None, unreachable=-1.0)", "HeightMap"),
"Each cell's height equals its pathfinding distance from the root.\n" MCRF_DESC("Convert distance field to a HeightMap. Each cell's height equals its pathfinding distance from the root, useful for visualization, procedural terrain, or influence mapping.")
"Useful for visualization, procedural terrain, or influence mapping.\n\n" MCRF_ARGS_START
"Args:\n" MCRF_ARG("size", "Optional (width, height) tuple. Defaults to dijkstra dimensions")
" size: Optional (width, height) tuple. Defaults to dijkstra dimensions.\n" MCRF_ARG("unreachable", "Value for cells that cannot reach root (default -1.0)")
" unreachable: Value for cells that cannot reach root (default -1.0).\n\n" MCRF_RETURNS("HeightMap with distance values as heights")
"Returns:\n" )},
" HeightMap with distance values as heights."},
{"invert", (PyCFunction)UIGridPathfinding::DijkstraMap_invert, METH_NOARGS, {"invert", (PyCFunction)UIGridPathfinding::DijkstraMap_invert, METH_NOARGS,
"invert() -> DijkstraMap\n\n" MCRF_METHOD(DijkstraMap, invert,
"Return a NEW DijkstraMap whose distance field is the safety field.\n\n" MCRF_SIG("()", "DijkstraMap"),
"Cells near a root become high values and cells far from any root become\n" MCRF_DESC("Return a new DijkstraMap whose distance field is inverted (safety field). Cells near a root become high values; descend to flee from original roots. The original DijkstraMap is unchanged.")
"low values. Combined with step_from or descent_step, this gives flee\n" MCRF_RETURNS("New DijkstraMap with inverted distances")
"behavior: descend the inverted map to move away from the original roots.\n\n" )},
"The original DijkstraMap is unchanged.\n\n"
"Returns:\n"
" New DijkstraMap with inverted distances."},
{"descent_step", (PyCFunction)UIGridPathfinding::DijkstraMap_descent_step, METH_VARARGS | METH_KEYWORDS, {"descent_step", (PyCFunction)UIGridPathfinding::DijkstraMap_descent_step, METH_VARARGS | METH_KEYWORDS,
"descent_step(pos) -> Vector | None\n\n" MCRF_METHOD(DijkstraMap, descent_step,
"Get the adjacent cell with the lowest distance (steepest descent).\n\n" MCRF_SIG("(pos: Vector | tuple)", "Vector | None"),
"Unlike step_from (which follows the path set by path_from), descent_step\n" MCRF_DESC("Get the adjacent cell with the lowest distance (steepest descent). Unlike step_from, this always returns the best neighbor in a single hop without following a precomputed path.")
"always returns the best neighbor in a single hop. Useful for AI that\n" MCRF_ARGS_START
"reacts to the current distance field rather than following a fixed path.\n\n" MCRF_ARG("pos", "Current position as Vector, Entity, or (x, y) tuple")
"Args:\n" MCRF_RETURNS("Next position as Vector, or None if pos is a local minimum or off-grid")
" pos: Current position as Vector, Entity, or (x, y) tuple.\n\n" )},
"Returns:\n"
" Next position as Vector, or None if pos is a local minimum or off-grid."},
{NULL} {NULL}
}; };
@ -1066,7 +1064,7 @@ PyMethodDef PyDijkstraMap_methods[] = {
// DijkstraMap getsetters // DijkstraMap getsetters
PyGetSetDef PyDijkstraMap_getsetters[] = { PyGetSetDef PyDijkstraMap_getsetters[] = {
{"root", (getter)UIGridPathfinding::DijkstraMap_get_root, NULL, {"root", (getter)UIGridPathfinding::DijkstraMap_get_root, NULL,
"Root position that distances are measured from (Vector, read-only).", NULL}, MCRF_PROPERTY(root, "Root position that distances are measured from (Vector, read-only)."), NULL},
{NULL} {NULL}
}; };

View file

@ -136,9 +136,12 @@ PyObject* UIGridPoint::get_grid_pos(PyUIGridPointObject* self, void* closure) {
} }
PyGetSetDef UIGridPoint::getsetters[] = { PyGetSetDef UIGridPoint::getsetters[] = {
{"walkable", (getter)UIGridPoint::get_bool_member, (setter)UIGridPoint::set_bool_member, "Is the GridPoint walkable", (void*)0}, {"walkable", (getter)UIGridPoint::get_bool_member, (setter)UIGridPoint::set_bool_member,
{"transparent", (getter)UIGridPoint::get_bool_member, (setter)UIGridPoint::set_bool_member, "Is the GridPoint transparent", (void*)1}, MCRF_PROPERTY(walkable, "Whether this cell can be walked through (bool). Affects pathfinding and TCOD map sync."), (void*)0},
{"entities", (getter)UIGridPoint::get_entities, NULL, "List of entities at this grid cell (read-only)", NULL}, {"transparent", (getter)UIGridPoint::get_bool_member, (setter)UIGridPoint::set_bool_member,
MCRF_PROPERTY(transparent, "Whether this cell allows line-of-sight to pass through (bool). Affects FOV computation and TCOD map sync."), (void*)1},
{"entities", (getter)UIGridPoint::get_entities, NULL,
MCRF_PROPERTY(entities, "List of Entity objects currently occupying this cell (list, read-only)."), NULL},
{"grid_pos", (getter)UIGridPoint::get_grid_pos, NULL, {"grid_pos", (getter)UIGridPoint::get_grid_pos, NULL,
MCRF_PROPERTY(grid_pos, "Grid coordinates as (x, y) tuple (read-only)."), NULL}, MCRF_PROPERTY(grid_pos, "Grid coordinates as (x, y) tuple (read-only)."), NULL},
{NULL} /* Sentinel */ {NULL} /* Sentinel */

View file

@ -15,6 +15,7 @@
#include "PyTrigger.h" #include "PyTrigger.h"
#include "UIBase.h" #include "UIBase.h"
#include "PyFOV.h" #include "PyFOV.h"
#include "McRFPy_Doc.h"
// ========================================================================= // =========================================================================
// Cell access: py_at, subscript, mpmethods // Cell access: py_at, subscript, mpmethods
@ -889,103 +890,124 @@ PyObject* UIGrid::py_step(PyUIGridObject* self, PyObject* args, PyObject* kwds)
// ========================================================================= // =========================================================================
PyMethodDef UIGrid::methods[] = { PyMethodDef UIGrid::methods[] = {
{"at", (PyCFunction)UIGrid::py_at, METH_VARARGS | METH_KEYWORDS}, {"at", (PyCFunction)UIGrid::py_at, METH_VARARGS | METH_KEYWORDS,
MCRF_METHOD(Grid, at,
MCRF_SIG("(x: int, y: int)", "GridPoint"),
MCRF_DESC("Return the GridPoint cell at grid coordinates (x, y)."),
MCRF_ARGS_START
MCRF_ARG("x", "Column index (0-based)")
MCRF_ARG("y", "Row index (0-based)")
MCRF_RETURNS("GridPoint: the cell at the given position")
MCRF_RAISES("IndexError", "If x or y is out of range")
)},
{"compute_fov", (PyCFunction)UIGrid::py_compute_fov, METH_VARARGS | METH_KEYWORDS, {"compute_fov", (PyCFunction)UIGrid::py_compute_fov, METH_VARARGS | METH_KEYWORDS,
"compute_fov(pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None\n\n" MCRF_METHOD(Grid, compute_fov,
"Compute field of view from a position.\n\n" MCRF_SIG("(pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC)", "None"),
"Args:\n" MCRF_DESC("Compute field of view from a position. Updates the internal FOV state; use is_in_fov() to query visibility."),
" pos: Position as (x, y) tuple, list, or Vector\n" MCRF_ARGS_START
" radius: Maximum view distance (0 = unlimited)\n" MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector")
" light_walls: Whether walls are lit when visible\n" MCRF_ARG("radius", "Maximum view distance (0 = unlimited)")
" algorithm: FOV algorithm to use (FOV_BASIC, FOV_DIAMOND, FOV_SHADOW, FOV_PERMISSIVE_0-8)\n\n" MCRF_ARG("light_walls", "Whether walls are lit when visible")
"Updates the internal FOV state. Use is_in_fov(pos) to query visibility."}, MCRF_ARG("algorithm", "FOV algorithm to use (FOV_BASIC, FOV_DIAMOND, FOV_SHADOW, FOV_PERMISSIVE_0-8)")
)},
{"is_in_fov", (PyCFunction)UIGrid::py_is_in_fov, METH_VARARGS | METH_KEYWORDS, {"is_in_fov", (PyCFunction)UIGrid::py_is_in_fov, METH_VARARGS | METH_KEYWORDS,
"is_in_fov(pos) -> bool\n\n" MCRF_METHOD(Grid, is_in_fov,
"Check if a cell is in the field of view.\n\n" MCRF_SIG("(pos)", "bool"),
"Args:\n" MCRF_DESC("Check if a cell is in the field of view. Must call compute_fov() first to calculate visibility."),
" pos: Position as (x, y) tuple, list, or Vector\n\n" MCRF_ARGS_START
"Returns:\n" MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector")
" True if the cell is visible, False otherwise\n\n" MCRF_RETURNS("True if the cell is visible, False otherwise")
"Must call compute_fov() first to calculate visibility."}, )},
{"find_path", (PyCFunction)UIGridPathfinding::Grid_find_path, METH_VARARGS | METH_KEYWORDS, {"find_path", (PyCFunction)UIGridPathfinding::Grid_find_path, METH_VARARGS | METH_KEYWORDS,
"find_path(start, end, diagonal_cost=1.41, collide=None) -> AStarPath | None\n\n" MCRF_METHOD(Grid, find_path,
"Compute A* path between two points.\n\n" MCRF_SIG("(start, end, diagonal_cost: float = 1.41, collide: str = None)", "AStarPath | None"),
"Args:\n" MCRF_DESC("Compute A* path between two points. The returned AStarPath can be iterated or walked step-by-step."),
" start: Starting position as Vector, Entity, or (x, y) tuple\n" MCRF_ARGS_START
" end: Target position as Vector, Entity, or (x, y) tuple\n" MCRF_ARG("start", "Starting position as Vector, Entity, or (x, y) tuple")
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n" MCRF_ARG("end", "Target position as Vector, Entity, or (x, y) tuple")
" collide: Label string. Entities with this label block pathfinding.\n\n" MCRF_ARG("diagonal_cost", "Cost of diagonal movement (default: 1.41)")
"Returns:\n" MCRF_ARG("collide", "Label string. Entities with this label block pathfinding.")
" AStarPath object if path exists, None otherwise.\n\n" MCRF_RETURNS("AStarPath object if path exists, None otherwise")
"The returned AStarPath can be iterated or walked step-by-step."}, )},
{"get_dijkstra_map", (PyCFunction)UIGridPathfinding::Grid_get_dijkstra_map, METH_VARARGS | METH_KEYWORDS, {"get_dijkstra_map", (PyCFunction)UIGridPathfinding::Grid_get_dijkstra_map, METH_VARARGS | METH_KEYWORDS,
"get_dijkstra_map(root, diagonal_cost=1.41, collide=None) -> DijkstraMap\n\n" MCRF_METHOD(Grid, get_dijkstra_map,
"Get or create a Dijkstra distance map for a root position.\n\n" MCRF_SIG("(root, diagonal_cost: float = 1.41, collide: str = None)", "DijkstraMap"),
"Args:\n" MCRF_DESC("Get or create a cached Dijkstra distance map for a root position. Call clear_dijkstra_maps() after changing grid walkability to invalidate."),
" root: Root position as Vector, Entity, or (x, y) tuple\n" MCRF_ARGS_START
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n" MCRF_ARG("root", "Root position as Vector, Entity, or (x, y) tuple")
" collide: Label string. Entities with this label block pathfinding.\n\n" MCRF_ARG("diagonal_cost", "Cost of diagonal movement (default: 1.41)")
"Returns:\n" MCRF_ARG("collide", "Label string. Entities with this label block pathfinding.")
" DijkstraMap object for querying distances and paths.\n\n" MCRF_RETURNS("DijkstraMap object for querying distances and paths")
"Grid caches DijkstraMaps by (root, collide) key. Multiple requests for\n" )},
"the same root and collide label return the same cached map. Call\n"
"clear_dijkstra_maps() after changing grid walkability to invalidate."},
{"clear_dijkstra_maps", (PyCFunction)UIGridPathfinding::Grid_clear_dijkstra_maps, METH_NOARGS, {"clear_dijkstra_maps", (PyCFunction)UIGridPathfinding::Grid_clear_dijkstra_maps, METH_NOARGS,
"clear_dijkstra_maps() -> None\n\n" MCRF_METHOD(Grid, clear_dijkstra_maps,
"Clear all cached Dijkstra maps.\n\n" MCRF_SIG("()", "None"),
"Call this after modifying grid cell walkability to ensure pathfinding\n" MCRF_DESC("Clear all cached Dijkstra maps. Call this after modifying grid cell walkability to ensure pathfinding uses updated walkability data.")
"uses updated walkability data."}, )},
{"add_layer", (PyCFunction)UIGrid::py_add_layer, METH_VARARGS, {"add_layer", (PyCFunction)UIGrid::py_add_layer, METH_VARARGS,
"add_layer(layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer"}, MCRF_METHOD(Grid, add_layer,
MCRF_SIG("(layer: ColorLayer | TileLayer)", "ColorLayer | TileLayer"),
MCRF_DESC("Add a layer to the grid. Layers with size (0, 0) are automatically resized to match the grid."),
MCRF_ARGS_START
MCRF_ARG("layer", "A ColorLayer or TileLayer object. Named layers replace any existing layer with the same name.")
MCRF_RETURNS("The added layer object")
MCRF_RAISES("ValueError", "If layer is already attached to another grid, or if layer size doesn't match grid (and isn't (0,0))")
MCRF_RAISES("TypeError", "If argument is not a ColorLayer or TileLayer")
)},
{"remove_layer", (PyCFunction)UIGrid::py_remove_layer, METH_VARARGS, {"remove_layer", (PyCFunction)UIGrid::py_remove_layer, METH_VARARGS,
"remove_layer(name_or_layer: str | ColorLayer | TileLayer) -> None"}, MCRF_METHOD(Grid, remove_layer,
MCRF_SIG("(name_or_layer: str | ColorLayer | TileLayer)", "None"),
MCRF_DESC("Remove a layer from the grid by name or by object reference."),
MCRF_ARGS_START
MCRF_ARG("name_or_layer", "Either a layer name (str) or the layer object itself")
MCRF_RAISES("KeyError", "If name is provided but no layer with that name exists")
MCRF_RAISES("TypeError", "If argument is not a string, ColorLayer, or TileLayer")
)},
{"layer", (PyCFunction)UIGrid::py_layer, METH_VARARGS, {"layer", (PyCFunction)UIGrid::py_layer, METH_VARARGS,
"layer(name: str) -> ColorLayer | TileLayer | None"}, MCRF_METHOD(Grid, layer,
MCRF_SIG("(name: str)", "ColorLayer | TileLayer | None"),
MCRF_DESC("Get a layer by its name."),
MCRF_ARGS_START
MCRF_ARG("name", "The name of the layer to find")
MCRF_RETURNS("The layer with the specified name, or None if not found")
)},
{"entities_in_radius", (PyCFunction)UIGrid::py_entities_in_radius, METH_VARARGS | METH_KEYWORDS, {"entities_in_radius", (PyCFunction)UIGrid::py_entities_in_radius, METH_VARARGS | METH_KEYWORDS,
"entities_in_radius(pos: tuple|Vector, radius: float) -> list[Entity]\n\n" MCRF_METHOD(Grid, entities_in_radius,
"Query entities within radius using spatial hash (O(k) where k = nearby entities).\n\n" MCRF_SIG("(pos: tuple | Vector, radius: float)", "list"),
"Args:\n" MCRF_DESC("Query entities within radius using spatial hash (O(k) where k = nearby entities)."),
" pos: Center position as (x, y) tuple, Vector, or other 2-element sequence\n" MCRF_ARGS_START
" radius: Search radius\n\n" MCRF_ARG("pos", "Center position as (x, y) tuple, Vector, or other 2-element sequence")
"Returns:\n" MCRF_ARG("radius", "Search radius")
" List of Entity objects within the radius."}, MCRF_RETURNS("List of Entity objects within the radius")
)},
{"center_camera", (PyCFunction)UIGrid::py_center_camera, METH_VARARGS, {"center_camera", (PyCFunction)UIGrid::py_center_camera, METH_VARARGS,
"center_camera(pos: tuple = None) -> None\n\n" MCRF_METHOD(Grid, center_camera,
"Center the camera on a tile coordinate.\n\n" MCRF_SIG("(pos: tuple = None)", "None"),
"Args:\n" MCRF_DESC("Center the camera on a tile coordinate. If pos is None, centers on the grid's middle tile."),
" pos: Optional (tile_x, tile_y) tuple. If None, centers on grid's middle tile.\n\n" MCRF_ARGS_START
"Example:\n" MCRF_ARG("pos", "Optional (tile_x, tile_y) tuple. If None, centers on grid's middle tile.")
" grid.center_camera() # Center on middle of grid\n" )},
" grid.center_camera((5, 10)) # Center on tile (5, 10)\n"
" grid.center_camera((0, 0)) # Center on tile (0, 0)"},
{"apply_threshold", (PyCFunction)UIGrid::py_apply_threshold, METH_VARARGS | METH_KEYWORDS, {"apply_threshold", (PyCFunction)UIGrid::py_apply_threshold, METH_VARARGS | METH_KEYWORDS,
"apply_threshold(source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid\n\n" MCRF_METHOD(Grid, apply_threshold,
"Apply walkable/transparent properties where heightmap values are in range.\n\n" MCRF_SIG("(source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None)", "Grid"),
"Args:\n" MCRF_DESC("Apply walkable/transparent properties to cells where heightmap values fall within range."),
" source: HeightMap with values to check. Must match grid size.\n" MCRF_ARGS_START
" range: Tuple of (min, max) - cells with values in this range are affected.\n" MCRF_ARG("source", "HeightMap with values to check. Must match grid size.")
" walkable: If not None, set walkable to this value for cells in range.\n" MCRF_ARG("range", "Tuple of (min, max) - cells with values in this range are affected")
" transparent: If not None, set transparent to this value for cells in range.\n\n" MCRF_ARG("walkable", "If not None, set walkable to this value for cells in range")
"Returns:\n" MCRF_ARG("transparent", "If not None, set transparent to this value for cells in range")
" Grid: self, for method chaining.\n\n" MCRF_RETURNS("Grid: self, for method chaining")
"Raises:\n" MCRF_RAISES("ValueError", "If HeightMap size doesn't match grid size")
" ValueError: If HeightMap size doesn't match grid size."}, )},
{"apply_ranges", (PyCFunction)UIGrid::py_apply_ranges, METH_VARARGS, {"apply_ranges", (PyCFunction)UIGrid::py_apply_ranges, METH_VARARGS,
"apply_ranges(source: HeightMap, ranges: list) -> Grid\n\n" MCRF_METHOD(Grid, apply_ranges,
"Apply multiple thresholds in a single pass.\n\n" MCRF_SIG("(source: HeightMap, ranges: list)", "Grid"),
"Args:\n" MCRF_DESC("Apply multiple walkability thresholds to the grid in a single pass."),
" source: HeightMap with values to check. Must match grid size.\n" MCRF_ARGS_START
" ranges: List of (range_tuple, properties_dict) tuples.\n" MCRF_ARG("source", "HeightMap with values to check. Must match grid size.")
" range_tuple: (min, max) value range\n" MCRF_ARG("ranges", "List of (range_tuple, properties_dict) tuples where range_tuple=(min,max) and properties_dict has 'walkable'/'transparent' keys")
" properties_dict: {'walkable': bool, 'transparent': bool}\n\n" MCRF_RETURNS("Grid: self, for method chaining")
"Returns:\n" )},
" Grid: self, for method chaining.\n\n"
"Example:\n"
" grid.apply_ranges(terrain, [\n"
" ((0.0, 0.3), {'walkable': False, 'transparent': True}), # Water\n"
" ((0.3, 0.8), {'walkable': True, 'transparent': True}), # Land\n"
" ((0.8, 1.0), {'walkable': False, 'transparent': False}), # Mountains\n"
" ])"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
@ -993,132 +1015,131 @@ typedef PyUIGridObject PyObjectType;
PyMethodDef UIGrid_all_methods[] = { PyMethodDef UIGrid_all_methods[] = {
UIDRAWABLE_METHODS, UIDRAWABLE_METHODS,
{"at", (PyCFunction)UIGrid::py_at, METH_VARARGS | METH_KEYWORDS}, {"at", (PyCFunction)UIGrid::py_at, METH_VARARGS | METH_KEYWORDS,
MCRF_METHOD(Grid, at,
MCRF_SIG("(x: int, y: int)", "GridPoint"),
MCRF_DESC("Return the GridPoint cell at grid coordinates (x, y)."),
MCRF_ARGS_START
MCRF_ARG("x", "Column index (0-based)")
MCRF_ARG("y", "Row index (0-based)")
MCRF_RETURNS("GridPoint: the cell at the given position")
MCRF_RAISES("IndexError", "If x or y is out of range")
)},
{"compute_fov", (PyCFunction)UIGrid::py_compute_fov, METH_VARARGS | METH_KEYWORDS, {"compute_fov", (PyCFunction)UIGrid::py_compute_fov, METH_VARARGS | METH_KEYWORDS,
"compute_fov(pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None\n\n" MCRF_METHOD(Grid, compute_fov,
"Compute field of view from a position.\n\n" MCRF_SIG("(pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC)", "None"),
"Args:\n" MCRF_DESC("Compute field of view from a position. Updates the internal FOV state; use is_in_fov() to query visibility."),
" pos: Position as (x, y) tuple, list, or Vector\n" MCRF_ARGS_START
" radius: Maximum view distance (0 = unlimited)\n" MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector")
" light_walls: Whether walls are lit when visible\n" MCRF_ARG("radius", "Maximum view distance (0 = unlimited)")
" algorithm: FOV algorithm to use (FOV_BASIC, FOV_DIAMOND, FOV_SHADOW, FOV_PERMISSIVE_0-8)\n\n" MCRF_ARG("light_walls", "Whether walls are lit when visible")
"Updates the internal FOV state. Use is_in_fov(pos) to query visibility."}, MCRF_ARG("algorithm", "FOV algorithm to use (FOV_BASIC, FOV_DIAMOND, FOV_SHADOW, FOV_PERMISSIVE_0-8)")
)},
{"is_in_fov", (PyCFunction)UIGrid::py_is_in_fov, METH_VARARGS | METH_KEYWORDS, {"is_in_fov", (PyCFunction)UIGrid::py_is_in_fov, METH_VARARGS | METH_KEYWORDS,
"is_in_fov(pos) -> bool\n\n" MCRF_METHOD(Grid, is_in_fov,
"Check if a cell is in the field of view.\n\n" MCRF_SIG("(pos)", "bool"),
"Args:\n" MCRF_DESC("Check if a cell is in the field of view. Must call compute_fov() first to calculate visibility."),
" pos: Position as (x, y) tuple, list, or Vector\n\n" MCRF_ARGS_START
"Returns:\n" MCRF_ARG("pos", "Position as (x, y) tuple, list, or Vector")
" True if the cell is visible, False otherwise\n\n" MCRF_RETURNS("True if the cell is visible, False otherwise")
"Must call compute_fov() first to calculate visibility."}, )},
{"find_path", (PyCFunction)UIGridPathfinding::Grid_find_path, METH_VARARGS | METH_KEYWORDS, {"find_path", (PyCFunction)UIGridPathfinding::Grid_find_path, METH_VARARGS | METH_KEYWORDS,
"find_path(start, end, diagonal_cost=1.41, collide=None) -> AStarPath | None\n\n" MCRF_METHOD(Grid, find_path,
"Compute A* path between two points.\n\n" MCRF_SIG("(start, end, diagonal_cost: float = 1.41, collide: str = None)", "AStarPath | None"),
"Args:\n" MCRF_DESC("Compute A* path between two points. The returned AStarPath can be iterated or walked step-by-step."),
" start: Starting position as Vector, Entity, or (x, y) tuple\n" MCRF_ARGS_START
" end: Target position as Vector, Entity, or (x, y) tuple\n" MCRF_ARG("start", "Starting position as Vector, Entity, or (x, y) tuple")
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n" MCRF_ARG("end", "Target position as Vector, Entity, or (x, y) tuple")
" collide: Label string. Entities with this label block pathfinding.\n\n" MCRF_ARG("diagonal_cost", "Cost of diagonal movement (default: 1.41)")
"Returns:\n" MCRF_ARG("collide", "Label string. Entities with this label block pathfinding.")
" AStarPath object if path exists, None otherwise.\n\n" MCRF_RETURNS("AStarPath object if path exists, None otherwise")
"The returned AStarPath can be iterated or walked step-by-step."}, )},
{"get_dijkstra_map", (PyCFunction)UIGridPathfinding::Grid_get_dijkstra_map, METH_VARARGS | METH_KEYWORDS, {"get_dijkstra_map", (PyCFunction)UIGridPathfinding::Grid_get_dijkstra_map, METH_VARARGS | METH_KEYWORDS,
"get_dijkstra_map(root, diagonal_cost=1.41, collide=None) -> DijkstraMap\n\n" MCRF_METHOD(Grid, get_dijkstra_map,
"Get or create a Dijkstra distance map for a root position.\n\n" MCRF_SIG("(root, diagonal_cost: float = 1.41, collide: str = None)", "DijkstraMap"),
"Args:\n" MCRF_DESC("Get or create a cached Dijkstra distance map for a root position. Call clear_dijkstra_maps() after changing grid walkability to invalidate."),
" root: Root position as Vector, Entity, or (x, y) tuple\n" MCRF_ARGS_START
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n" MCRF_ARG("root", "Root position as Vector, Entity, or (x, y) tuple")
" collide: Label string. Entities with this label block pathfinding.\n\n" MCRF_ARG("diagonal_cost", "Cost of diagonal movement (default: 1.41)")
"Returns:\n" MCRF_ARG("collide", "Label string. Entities with this label block pathfinding.")
" DijkstraMap object for querying distances and paths.\n\n" MCRF_RETURNS("DijkstraMap object for querying distances and paths")
"Grid caches DijkstraMaps by (root, collide) key. Multiple requests for\n" )},
"the same root and collide label return the same cached map. Call\n"
"clear_dijkstra_maps() after changing grid walkability to invalidate."},
{"clear_dijkstra_maps", (PyCFunction)UIGridPathfinding::Grid_clear_dijkstra_maps, METH_NOARGS, {"clear_dijkstra_maps", (PyCFunction)UIGridPathfinding::Grid_clear_dijkstra_maps, METH_NOARGS,
"clear_dijkstra_maps() -> None\n\n" MCRF_METHOD(Grid, clear_dijkstra_maps,
"Clear all cached Dijkstra maps.\n\n" MCRF_SIG("()", "None"),
"Call this after modifying grid cell walkability to ensure pathfinding\n" MCRF_DESC("Clear all cached Dijkstra maps. Call this after modifying grid cell walkability to ensure pathfinding uses updated walkability data.")
"uses updated walkability data."}, )},
{"add_layer", (PyCFunction)UIGrid::py_add_layer, METH_VARARGS, {"add_layer", (PyCFunction)UIGrid::py_add_layer, METH_VARARGS,
"add_layer(layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer\n\n" MCRF_METHOD(Grid, add_layer,
"Add a layer to the grid.\n\n" MCRF_SIG("(layer: ColorLayer | TileLayer)", "ColorLayer | TileLayer"),
"Args:\n" MCRF_DESC("Add a layer to the grid. Layers with size (0, 0) are automatically resized to match the grid."),
" layer: A ColorLayer or TileLayer object. Layers with size (0, 0) are\n" MCRF_ARGS_START
" automatically resized to match the grid. Named layers replace\n" MCRF_ARG("layer", "A ColorLayer or TileLayer object. Named layers replace any existing layer with the same name.")
" any existing layer with the same name.\n\n" MCRF_RETURNS("The added layer object")
"Returns:\n" MCRF_RAISES("ValueError", "If layer is already attached to another grid, or if layer size doesn't match grid (and isn't (0,0))")
" The added layer object.\n\n" MCRF_RAISES("TypeError", "If argument is not a ColorLayer or TileLayer")
"Raises:\n" )},
" ValueError: If layer is already attached to another grid, or if\n"
" layer size doesn't match grid (and isn't (0,0)).\n"
" TypeError: If argument is not a ColorLayer or TileLayer."},
{"remove_layer", (PyCFunction)UIGrid::py_remove_layer, METH_VARARGS, {"remove_layer", (PyCFunction)UIGrid::py_remove_layer, METH_VARARGS,
"remove_layer(name_or_layer: str | ColorLayer | TileLayer) -> None\n\n" MCRF_METHOD(Grid, remove_layer,
"Remove a layer from the grid.\n\n" MCRF_SIG("(name_or_layer: str | ColorLayer | TileLayer)", "None"),
"Args:\n" MCRF_DESC("Remove a layer from the grid by name or by object reference."),
" name_or_layer: Either a layer name (str) or the layer object itself.\n\n" MCRF_ARGS_START
"Raises:\n" MCRF_ARG("name_or_layer", "Either a layer name (str) or the layer object itself")
" KeyError: If name is provided but no layer with that name exists.\n" MCRF_RAISES("KeyError", "If name is provided but no layer with that name exists")
" TypeError: If argument is not a string, ColorLayer, or TileLayer."}, MCRF_RAISES("TypeError", "If argument is not a string, ColorLayer, or TileLayer")
)},
{"layer", (PyCFunction)UIGrid::py_layer, METH_VARARGS, {"layer", (PyCFunction)UIGrid::py_layer, METH_VARARGS,
"layer(name: str) -> ColorLayer | TileLayer | None\n\n" MCRF_METHOD(Grid, layer,
"Get a layer by its name.\n\n" MCRF_SIG("(name: str)", "ColorLayer | TileLayer | None"),
"Args:\n" MCRF_DESC("Get a layer by its name."),
" name: The name of the layer to find.\n\n" MCRF_ARGS_START
"Returns:\n" MCRF_ARG("name", "The name of the layer to find")
" The layer with the specified name, or None if not found."}, MCRF_RETURNS("The layer with the specified name, or None if not found")
)},
{"entities_in_radius", (PyCFunction)UIGrid::py_entities_in_radius, METH_VARARGS | METH_KEYWORDS, {"entities_in_radius", (PyCFunction)UIGrid::py_entities_in_radius, METH_VARARGS | METH_KEYWORDS,
"entities_in_radius(pos: tuple|Vector, radius: float) -> list[Entity]\n\n" MCRF_METHOD(Grid, entities_in_radius,
"Query entities within radius using spatial hash (O(k) where k = nearby entities).\n\n" MCRF_SIG("(pos: tuple | Vector, radius: float)", "list"),
"Args:\n" MCRF_DESC("Query entities within radius using spatial hash (O(k) where k = nearby entities)."),
" pos: Center position as (x, y) tuple, Vector, or other 2-element sequence\n" MCRF_ARGS_START
" radius: Search radius\n\n" MCRF_ARG("pos", "Center position as (x, y) tuple, Vector, or other 2-element sequence")
"Returns:\n" MCRF_ARG("radius", "Search radius")
" List of Entity objects within the radius."}, MCRF_RETURNS("List of Entity objects within the radius")
)},
{"center_camera", (PyCFunction)UIGrid::py_center_camera, METH_VARARGS, {"center_camera", (PyCFunction)UIGrid::py_center_camera, METH_VARARGS,
"center_camera(pos: tuple = None) -> None\n\n" MCRF_METHOD(Grid, center_camera,
"Center the camera on a tile coordinate.\n\n" MCRF_SIG("(pos: tuple = None)", "None"),
"Args:\n" MCRF_DESC("Center the camera on a tile coordinate. If pos is None, centers on the grid's middle tile."),
" pos: Optional (tile_x, tile_y) tuple. If None, centers on grid's middle tile.\n\n" MCRF_ARGS_START
"Example:\n" MCRF_ARG("pos", "Optional (tile_x, tile_y) tuple. If None, centers on grid's middle tile.")
" grid.center_camera() # Center on middle of grid\n" )},
" grid.center_camera((5, 10)) # Center on tile (5, 10)\n"
" grid.center_camera((0, 0)) # Center on tile (0, 0)"},
{"apply_threshold", (PyCFunction)UIGrid::py_apply_threshold, METH_VARARGS | METH_KEYWORDS, {"apply_threshold", (PyCFunction)UIGrid::py_apply_threshold, METH_VARARGS | METH_KEYWORDS,
"apply_threshold(source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid\n\n" MCRF_METHOD(Grid, apply_threshold,
"Apply walkable/transparent properties where heightmap values are in range.\n\n" MCRF_SIG("(source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None)", "Grid"),
"Args:\n" MCRF_DESC("Apply walkable/transparent properties to cells where heightmap values fall within range."),
" source: HeightMap with values to check. Must match grid size.\n" MCRF_ARGS_START
" range: Tuple of (min, max) - cells with values in this range are affected.\n" MCRF_ARG("source", "HeightMap with values to check. Must match grid size.")
" walkable: If not None, set walkable to this value for cells in range.\n" MCRF_ARG("range", "Tuple of (min, max) - cells with values in this range are affected")
" transparent: If not None, set transparent to this value for cells in range.\n\n" MCRF_ARG("walkable", "If not None, set walkable to this value for cells in range")
"Returns:\n" MCRF_ARG("transparent", "If not None, set transparent to this value for cells in range")
" Grid: self, for method chaining.\n\n" MCRF_RETURNS("Grid: self, for method chaining")
"Raises:\n" MCRF_RAISES("ValueError", "If HeightMap size doesn't match grid size")
" ValueError: If HeightMap size doesn't match grid size."}, )},
{"apply_ranges", (PyCFunction)UIGrid::py_apply_ranges, METH_VARARGS, {"apply_ranges", (PyCFunction)UIGrid::py_apply_ranges, METH_VARARGS,
"apply_ranges(source: HeightMap, ranges: list) -> Grid\n\n" MCRF_METHOD(Grid, apply_ranges,
"Apply multiple thresholds in a single pass.\n\n" MCRF_SIG("(source: HeightMap, ranges: list)", "Grid"),
"Args:\n" MCRF_DESC("Apply multiple walkability thresholds to the grid in a single pass."),
" source: HeightMap with values to check. Must match grid size.\n" MCRF_ARGS_START
" ranges: List of (range_tuple, properties_dict) tuples.\n" MCRF_ARG("source", "HeightMap with values to check. Must match grid size.")
" range_tuple: (min, max) value range\n" MCRF_ARG("ranges", "List of (range_tuple, properties_dict) tuples where range_tuple=(min,max) and properties_dict has 'walkable'/'transparent' keys")
" properties_dict: {'walkable': bool, 'transparent': bool}\n\n" MCRF_RETURNS("Grid: self, for method chaining")
"Returns:\n" )},
" Grid: self, for method chaining.\n\n"
"Example:\n"
" grid.apply_ranges(terrain, [\n"
" ((0.0, 0.3), {'walkable': False, 'transparent': True}), # Water\n"
" ((0.3, 0.8), {'walkable': True, 'transparent': True}), # Land\n"
" ((0.8, 1.0), {'walkable': False, 'transparent': False}), # Mountains\n"
" ])"},
{"step", (PyCFunction)UIGrid::py_step, METH_VARARGS | METH_KEYWORDS, {"step", (PyCFunction)UIGrid::py_step, METH_VARARGS | METH_KEYWORDS,
"step(n=1, turn_order=None) -> None\n\n" MCRF_METHOD(Grid, step,
"Execute n rounds of turn-based entity behavior.\n\n" MCRF_SIG("(n: int = 1, turn_order: int = None)", "None"),
"Args:\n" MCRF_DESC("Execute n rounds of turn-based entity behavior. Each round: entities grouped by turn_order (ascending), behaviors executed, triggers fired (TARGET, DONE, BLOCKED), movement animated."),
" n (int): Number of rounds to execute. Default: 1\n" MCRF_ARGS_START
" turn_order (int, optional): Only process entities with this turn_order value\n\n" MCRF_ARG("n", "Number of rounds to execute (default: 1)")
"Each round: entities grouped by turn_order (ascending), behaviors executed,\n" MCRF_ARG("turn_order", "If provided, only process entities with this turn_order value")
"triggers fired (TARGET, DONE, BLOCKED), movement animated."}, )},
{NULL} {NULL}
}; };

View file

@ -529,26 +529,44 @@ typedef PyUIGridObject PyObjectType;
PyGetSetDef UIGrid::getsetters[] = { PyGetSetDef UIGrid::getsetters[] = {
{"grid_size", (getter)UIGrid::get_grid_size, NULL, "Grid dimensions (grid_w, grid_h)", NULL}, {"grid_size", (getter)UIGrid::get_grid_size, NULL,
{"grid_w", (getter)UIGrid::get_grid_w, NULL, "Grid width in cells", NULL}, MCRF_PROPERTY(grid_size, "Grid dimensions as (grid_w, grid_h) (Vector, read-only)."), NULL},
{"grid_h", (getter)UIGrid::get_grid_h, NULL, "Grid height in cells", NULL}, {"grid_w", (getter)UIGrid::get_grid_w, NULL,
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, "Position of the grid as Vector", (void*)PyObjectsEnum::UIGRID}, MCRF_PROPERTY(grid_w, "Grid width in cells (int, read-only)."), NULL},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos, "Position in parent grid's tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UIGRID}, {"grid_h", (getter)UIGrid::get_grid_h, NULL,
{"size", (getter)UIGrid::get_size, (setter)UIGrid::set_size, "Size of the grid as Vector (width, height)", NULL}, MCRF_PROPERTY(grid_h, "Grid height in cells (int, read-only)."), NULL},
{"center", (getter)UIGrid::get_center, (setter)UIGrid::set_center, "Grid coordinate at the center of the Grid's view (pan)", NULL}, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
MCRF_PROPERTY(pos, "Position of the grid as Vector (Vector)."), (void*)PyObjectsEnum::UIGRID},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos,
MCRF_PROPERTY(grid_pos, "Position in parent grid's tile coordinates (Vector). Only valid when parent is a Grid."), (void*)PyObjectsEnum::UIGRID},
{"size", (getter)UIGrid::get_size, (setter)UIGrid::set_size,
MCRF_PROPERTY(size, "Size of the grid widget as Vector (Vector, width x height in pixels)."), NULL},
{"center", (getter)UIGrid::get_center, (setter)UIGrid::set_center,
MCRF_PROPERTY(center, "Camera center point in pixel coordinates (Vector). Controls which part of the grid world is visible (pan)."), NULL},
{"entities", (getter)UIGrid::get_entities, NULL, "EntityCollection of entities on this grid", NULL}, {"entities", (getter)UIGrid::get_entities, NULL,
{"children", (getter)UIGrid::get_children, NULL, "UICollection of UIDrawable children (speech bubbles, effects, overlays)", NULL}, MCRF_PROPERTY(entities, "EntityCollection of entities on this grid (EntityCollection, read-only)."), NULL},
{"layers", (getter)UIGrid::get_layers, NULL, "List of grid layers (ColorLayer, TileLayer) sorted by z_index", NULL}, {"children", (getter)UIGrid::get_children, NULL,
MCRF_PROPERTY(children, "UICollection of UIDrawable children such as speech bubbles, effects, and overlays (UICollection, read-only)."), NULL},
{"layers", (getter)UIGrid::get_layers, NULL,
MCRF_PROPERTY(layers, "Tuple of grid layers sorted by z_index (tuple, read-only). Contains ColorLayer and TileLayer objects."), NULL},
{"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "top-left corner X-coordinate", (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 0)}, {"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "top-left corner Y-coordinate", (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 1)}, MCRF_PROPERTY(x, "Top-left corner X-coordinate in pixels (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 0)},
{"w", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "visible widget width", (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 2)}, {"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"h", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "visible widget height", (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 3)}, MCRF_PROPERTY(y, "Top-left corner Y-coordinate in pixels (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 1)},
{"center_x", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member, "center of the view X-coordinate", (void*)4}, {"w", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"center_y", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member, "center of the view Y-coordinate", (void*)5}, MCRF_PROPERTY(w, "Visible widget width in pixels (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 2)},
{"zoom", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member, "zoom factor for displaying the Grid", (void*)6}, {"h", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"camera_rotation", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member, "Rotation of grid contents around camera center (degrees). The grid widget stays axis-aligned; only the view into the world rotates.", (void*)7}, MCRF_PROPERTY(h, "Visible widget height in pixels (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRID << 8 | 3)},
{"center_x", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member,
MCRF_PROPERTY(center_x, "Camera center X-coordinate in pixels (float)."), (void*)4},
{"center_y", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member,
MCRF_PROPERTY(center_y, "Camera center Y-coordinate in pixels (float)."), (void*)5},
{"zoom", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member,
MCRF_PROPERTY(zoom, "Zoom factor for rendering the grid (float). Values > 1 zoom in; values < 1 zoom out."), (void*)6},
{"camera_rotation", (getter)UIGrid::get_float_member, (setter)UIGrid::set_float_member,
MCRF_PROPERTY(camera_rotation, "Rotation of grid contents around camera center in degrees (float). The grid widget stays axis-aligned; only the view into the world rotates."), (void*)7},
{"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, {"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click,
MCRF_PROPERTY(on_click, MCRF_PROPERTY(on_click,
@ -556,42 +574,56 @@ PyGetSetDef UIGrid::getsetters[] = {
"Function receives (pos: Vector, button: str, action: str)." "Function receives (pos: Vector, button: str, action: str)."
), (void*)PyObjectsEnum::UIGRID}, ), (void*)PyObjectsEnum::UIGRID},
{"texture", (getter)UIGrid::get_texture, NULL, "Texture of the grid", NULL}, {"texture", (getter)UIGrid::get_texture, NULL,
MCRF_PROPERTY(texture, "Texture used for tile rendering (Texture | None, read-only)."), NULL},
{"fill_color", (getter)UIGrid::get_fill_color, (setter)UIGrid::set_fill_color, {"fill_color", (getter)UIGrid::get_fill_color, (setter)UIGrid::set_fill_color,
"Background fill color of the grid. Returns a copy; modifying components requires reassignment. " MCRF_PROPERTY(fill_color,
"For animation, use 'fill_color.r', 'fill_color.g', etc.", NULL}, "Background fill color of the grid (Color). "
"Returns a copy; modifying components requires reassignment. "
"For animation, use 'fill_color.r', 'fill_color.g', etc."
), NULL},
{"perspective", (getter)UIGrid::get_perspective, (setter)UIGrid::set_perspective, {"perspective", (getter)UIGrid::get_perspective, (setter)UIGrid::set_perspective,
"Entity whose perspective to use for FOV rendering (None for omniscient view). " MCRF_PROPERTY(perspective,
"Setting an entity automatically enables perspective mode.", NULL}, "Entity whose perspective to use for FOV rendering (Entity | None). "
"Setting an entity automatically enables perspective mode. "
"Set to None for omniscient view."
), NULL},
{"perspective_enabled", (getter)UIGrid::get_perspective_enabled, (setter)UIGrid::set_perspective_enabled, {"perspective_enabled", (getter)UIGrid::get_perspective_enabled, (setter)UIGrid::set_perspective_enabled,
"Whether to use perspective-based FOV rendering. When True with no valid entity, " MCRF_PROPERTY(perspective_enabled,
"all cells appear undiscovered.", NULL}, "Whether to use perspective-based FOV rendering (bool). "
"When True with no valid entity, all cells appear undiscovered."
), NULL},
{"fov", (getter)UIGrid::get_fov, (setter)UIGrid::set_fov, {"fov", (getter)UIGrid::get_fov, (setter)UIGrid::set_fov,
"FOV algorithm for this grid (mcrfpy.FOV enum). " MCRF_PROPERTY(fov,
"Used by entity.updateVisibility() and layer methods when fov=None.", NULL}, "FOV algorithm for this grid (FOV enum). "
"Used by entity.updateVisibility() and layer methods when fov=None."
), NULL},
{"fov_radius", (getter)UIGrid::get_fov_radius, (setter)UIGrid::set_fov_radius, {"fov_radius", (getter)UIGrid::get_fov_radius, (setter)UIGrid::set_fov_radius,
"Default FOV radius for this grid. Used when radius not specified.", NULL}, MCRF_PROPERTY(fov_radius, "Default FOV radius for this grid (int). Used when radius is not specified."), NULL},
{"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int, {"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int,
MCRF_PROPERTY(z_index, MCRF_PROPERTY(z_index,
"Z-order for rendering (lower values rendered first). " "Z-order for rendering (lower values rendered first). "
"Automatically triggers scene resort when changed." "Automatically triggers scene resort when changed."
), (void*)PyObjectsEnum::UIGRID}, ), (void*)PyObjectsEnum::UIGRID},
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, "Name for finding elements", (void*)PyObjectsEnum::UIGRID}, {"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name,
MCRF_PROPERTY(name, "Name for finding elements (str)."), (void*)PyObjectsEnum::UIGRID},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIGRID), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIGRID),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIGRID), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIGRID),
UIDRAWABLE_ROTATION_GETSETTERS(PyObjectsEnum::UIGRID), UIDRAWABLE_ROTATION_GETSETTERS(PyObjectsEnum::UIGRID),
{"on_cell_enter", (getter)UIGrid::get_on_cell_enter, (setter)UIGrid::set_on_cell_enter, {"on_cell_enter", (getter)UIGrid::get_on_cell_enter, (setter)UIGrid::set_on_cell_enter,
"Callback when mouse enters a grid cell. Called with (cell_pos: Vector).", NULL}, MCRF_PROPERTY(on_cell_enter, "Callback when mouse enters a grid cell (Callable | None). Called with (cell_pos: Vector)."), NULL},
{"on_cell_exit", (getter)UIGrid::get_on_cell_exit, (setter)UIGrid::set_on_cell_exit, {"on_cell_exit", (getter)UIGrid::get_on_cell_exit, (setter)UIGrid::set_on_cell_exit,
"Callback when mouse exits a grid cell. Called with (cell_pos: Vector).", NULL}, MCRF_PROPERTY(on_cell_exit, "Callback when mouse exits a grid cell (Callable | None). Called with (cell_pos: Vector)."), NULL},
{"on_cell_click", (getter)UIGrid::get_on_cell_click, (setter)UIGrid::set_on_cell_click, {"on_cell_click", (getter)UIGrid::get_on_cell_click, (setter)UIGrid::set_on_cell_click,
"Callback when a grid cell is clicked. Called with (cell_pos: Vector).", NULL}, MCRF_PROPERTY(on_cell_click, "Callback when a grid cell is clicked (Callable | None). Called with (cell_pos: Vector, button: MouseButton, action: InputState)."), NULL},
{"hovered_cell", (getter)UIGrid::get_hovered_cell, NULL, {"hovered_cell", (getter)UIGrid::get_hovered_cell, NULL,
"Currently hovered cell as (x, y) tuple, or None if not hovering.", NULL}, MCRF_PROPERTY(hovered_cell, "Currently hovered cell as (x, y) tuple, or None if not hovering (tuple | None, read-only)."), NULL},
UIDRAWABLE_SHADER_GETSETTERS(PyObjectsEnum::UIGRID), UIDRAWABLE_SHADER_GETSETTERS(PyObjectsEnum::UIGRID),
{"view", (getter)UIGrid::get_view, NULL, {"view", (getter)UIGrid::get_view, NULL,
"Auto-created GridView for rendering (read-only). " MCRF_PROPERTY(view,
"When Grid is appended to a scene, this view is what actually renders.", NULL}, "Auto-created GridView for rendering (GridView | None, read-only). "
"When Grid is appended to a scene, this view is what actually renders."
), NULL},
{NULL} {NULL}
}; };

View file

@ -13,6 +13,7 @@
#include "PyVector.h" #include "PyVector.h"
#include "PythonObjectCache.h" #include "PythonObjectCache.h"
#include "PySceneObject.h" // parent= kwarg: Scene is a valid parent type #include "PySceneObject.h" // parent= kwarg: Scene is a valid parent type
#include "McRFPy_Doc.h"
#include <cmath> #include <cmath>
#include <algorithm> #include <algorithm>
@ -885,38 +886,38 @@ PyMethodDef UIGridView_all_methods[] = {
// Data properties (entities, grid_size, layers, etc.) are accessed via getattro delegation. // Data properties (entities, grid_size, layers, etc.) are accessed via getattro delegation.
PyGetSetDef UIGridView::getsetters[] = { PyGetSetDef UIGridView::getsetters[] = {
{"grid_data", (getter)UIGridView::get_grid, (setter)UIGridView::set_grid, {"grid_data", (getter)UIGridView::get_grid, (setter)UIGridView::set_grid,
"The underlying grid data object (for multi-view scenarios).", NULL}, MCRF_PROPERTY(grid_data, "The underlying grid data object (Grid | None). Used for multi-view scenarios where multiple GridViews share one Grid."), NULL},
{"center", (getter)UIGridView::get_center, (setter)UIGridView::set_center, {"center", (getter)UIGridView::get_center, (setter)UIGridView::set_center,
"Camera center point in pixel coordinates.", NULL}, MCRF_PROPERTY(center, "Camera center point in pixel coordinates (tuple)."), NULL},
{"zoom", (getter)UIGridView::get_zoom, (setter)UIGridView::set_zoom, {"zoom", (getter)UIGridView::get_zoom, (setter)UIGridView::set_zoom,
"Zoom level for rendering.", NULL}, MCRF_PROPERTY(zoom, "Zoom level for rendering (float). Values greater than 1.0 magnify; less than 1.0 shrink."), NULL},
{"fill_color", (getter)UIGridView::get_fill_color, (setter)UIGridView::set_fill_color, {"fill_color", (getter)UIGridView::get_fill_color, (setter)UIGridView::set_fill_color,
"Background fill color.", NULL}, MCRF_PROPERTY(fill_color, "Background fill color (Color). Drawn behind all tiles and entities."), NULL},
{"texture", (getter)UIGridView::get_texture, NULL, {"texture", (getter)UIGridView::get_texture, NULL,
"Texture used for tile rendering (read-only).", NULL}, MCRF_PROPERTY(texture, "Texture used for tile rendering (Texture | None, read-only)."), NULL},
// UIDrawable base properties - applied to GridView (the rendered object) // UIDrawable base properties - applied to GridView (the rendered object)
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
"Position of the grid as Vector", (void*)PyObjectsEnum::UIGRIDVIEW}, MCRF_PROPERTY(pos, "Position of the grid as Vector (Vector)."), (void*)PyObjectsEnum::UIGRIDVIEW},
{"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, {"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
"top-left corner X-coordinate", (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 0)}, MCRF_PROPERTY(x, "Top-left corner X-coordinate (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 0)},
{"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, {"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
"top-left corner Y-coordinate", (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 1)}, MCRF_PROPERTY(y, "Top-left corner Y-coordinate (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 1)},
{"w", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, {"w", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
"visible widget width", (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 2)}, MCRF_PROPERTY(w, "Visible widget width (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 2)},
{"h", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, {"h", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
"visible widget height", (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 3)}, MCRF_PROPERTY(h, "Visible widget height (float)."), (void*)((intptr_t)PyObjectsEnum::UIGRIDVIEW << 8 | 3)},
{"center_x", (getter)UIGridView::get_float_member_gv, (setter)UIGridView::set_float_member_gv, {"center_x", (getter)UIGridView::get_float_member_gv, (setter)UIGridView::set_float_member_gv,
"center of the view X-coordinate", (void*)4}, MCRF_PROPERTY(center_x, "Camera center X-coordinate in pixel space (float)."), (void*)4},
{"center_y", (getter)UIGridView::get_float_member_gv, (setter)UIGridView::set_float_member_gv, {"center_y", (getter)UIGridView::get_float_member_gv, (setter)UIGridView::set_float_member_gv,
"center of the view Y-coordinate", (void*)5}, MCRF_PROPERTY(center_y, "Camera center Y-coordinate in pixel space (float)."), (void*)5},
{"camera_rotation", (getter)UIGridView::get_float_member_gv, (setter)UIGridView::set_float_member_gv, {"camera_rotation", (getter)UIGridView::get_float_member_gv, (setter)UIGridView::set_float_member_gv,
"Rotation of grid contents around camera center (degrees).", (void*)7}, MCRF_PROPERTY(camera_rotation, "Rotation of grid contents around camera center in degrees (float)."), (void*)7},
{"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, {"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click,
"Callable executed when object is clicked.", (void*)PyObjectsEnum::UIGRIDVIEW}, MCRF_PROPERTY(on_click, "Callable executed when object is clicked (Callable | None)."), (void*)PyObjectsEnum::UIGRIDVIEW},
{"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int, {"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int,
"Z-order for rendering (lower values rendered first).", (void*)PyObjectsEnum::UIGRIDVIEW}, MCRF_PROPERTY(z_index, "Z-order for rendering (int). Lower values are rendered first."), (void*)PyObjectsEnum::UIGRIDVIEW},
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, {"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name,
"Name for finding elements", (void*)PyObjectsEnum::UIGRIDVIEW}, MCRF_PROPERTY(name, "Name for finding elements (str)."), (void*)PyObjectsEnum::UIGRIDVIEW},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIGRIDVIEW), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UIGRIDVIEW),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIGRIDVIEW), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UIGRIDVIEW),

View file

@ -1,6 +1,7 @@
#include "UILine.h" #include "UILine.h"
#include "GameEngine.h" #include "GameEngine.h"
#include "McRFPy_API.h" #include "McRFPy_API.h"
#include "McRFPy_Doc.h"
#include "PyVector.h" #include "PyVector.h"
#include "PyColor.h" #include "PyColor.h"
#include "PythonObjectCache.h" #include "PythonObjectCache.h"
@ -527,8 +528,12 @@ PyGetSetDef UILine::getsetters[] = {
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
MCRF_PROPERTY(pos, "Position as a Vector (midpoint of line)."), MCRF_PROPERTY(pos, "Position as a Vector (midpoint of line)."),
(void*)PyObjectsEnum::UILINE}, (void*)PyObjectsEnum::UILINE},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos, "Position in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UILINE}, {"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos,
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size, "Size in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UILINE}, MCRF_PROPERTY(grid_pos, "Position in grid tile coordinates (Vector, only when parent is Grid)."),
(void*)PyObjectsEnum::UILINE},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size,
MCRF_PROPERTY(grid_size, "Size in grid tile coordinates (Vector, only when parent is Grid)."),
(void*)PyObjectsEnum::UILINE},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UILINE), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UILINE),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UILINE), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UILINE),

View file

@ -9,6 +9,7 @@
#include "PyAlignment.h" #include "PyAlignment.h"
#include "PyShader.h" // #106: Shader support #include "PyShader.h" // #106: Shader support
#include "PyUniformCollection.h" // #106: Uniform collection support #include "PyUniformCollection.h" // #106: Uniform collection support
#include "McRFPy_Doc.h"
// UIDrawable methods now in UIBase.h // UIDrawable methods now in UIBase.h
UIDrawable* UISprite::click_at(sf::Vector2f point) UIDrawable* UISprite::click_at(sf::Vector2f point)
@ -416,13 +417,27 @@ PyMethodDef UISprite_methods[] = {
}; };
PyGetSetDef UISprite::getsetters[] = { PyGetSetDef UISprite::getsetters[] = {
{"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "X coordinate of top-left corner", (void*)((intptr_t)PyObjectsEnum::UISPRITE << 8 | 0)}, {"x", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member, "Y coordinate of top-left corner", (void*)((intptr_t)PyObjectsEnum::UISPRITE << 8 | 1)}, MCRF_PROPERTY(x, "X coordinate of top-left corner (float)."),
{"scale", (getter)UISprite::get_float_member, (setter)UISprite::set_float_member, "Uniform size factor", (void*)2}, (void*)((intptr_t)PyObjectsEnum::UISPRITE << 8 | 0)},
{"scale_x", (getter)UISprite::get_float_member, (setter)UISprite::set_float_member, "Horizontal scale factor", (void*)3}, {"y", (getter)UIDrawable::get_float_member, (setter)UIDrawable::set_float_member,
{"scale_y", (getter)UISprite::get_float_member, (setter)UISprite::set_float_member, "Vertical scale factor", (void*)4}, MCRF_PROPERTY(y, "Y coordinate of top-left corner (float)."),
{"sprite_index", (getter)UISprite::get_int_member, (setter)UISprite::set_int_member, "Which sprite on the texture is shown", NULL}, (void*)((intptr_t)PyObjectsEnum::UISPRITE << 8 | 1)},
{"texture", (getter)UISprite::get_texture, (setter)UISprite::set_texture, "Texture object", NULL}, {"scale", (getter)UISprite::get_float_member, (setter)UISprite::set_float_member,
MCRF_PROPERTY(scale, "Uniform size factor (float). Sets both horizontal and vertical scale to the same value."),
(void*)2},
{"scale_x", (getter)UISprite::get_float_member, (setter)UISprite::set_float_member,
MCRF_PROPERTY(scale_x, "Horizontal scale factor (float)."),
(void*)3},
{"scale_y", (getter)UISprite::get_float_member, (setter)UISprite::set_float_member,
MCRF_PROPERTY(scale_y, "Vertical scale factor (float)."),
(void*)4},
{"sprite_index", (getter)UISprite::get_int_member, (setter)UISprite::set_int_member,
MCRF_PROPERTY(sprite_index, "Which sprite on the texture is shown (int). Index into the texture atlas; must be in range [0, sprite_count)."),
NULL},
{"texture", (getter)UISprite::get_texture, (setter)UISprite::set_texture,
MCRF_PROPERTY(texture, "Texture object (Texture). The texture atlas from which sprites are drawn."),
NULL},
{"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, {"on_click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click,
MCRF_PROPERTY(on_click, MCRF_PROPERTY(on_click,
"Callable executed when object is clicked. " "Callable executed when object is clicked. "
@ -433,10 +448,18 @@ PyGetSetDef UISprite::getsetters[] = {
"Z-order for rendering (lower values rendered first). " "Z-order for rendering (lower values rendered first). "
"Automatically triggers scene resort when changed." "Automatically triggers scene resort when changed."
), (void*)PyObjectsEnum::UISPRITE}, ), (void*)PyObjectsEnum::UISPRITE},
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, "Name for finding elements", (void*)PyObjectsEnum::UISPRITE}, {"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name,
{"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos, "Position as a Vector", (void*)PyObjectsEnum::UISPRITE}, MCRF_PROPERTY(name, "Name for finding elements (str)."),
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos, "Position in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UISPRITE}, (void*)PyObjectsEnum::UISPRITE},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size, "Size in grid tile coordinates (only when parent is Grid)", (void*)PyObjectsEnum::UISPRITE}, {"pos", (getter)UIDrawable::get_pos, (setter)UIDrawable::set_pos,
MCRF_PROPERTY(pos, "Position as a Vector (Vector)."),
(void*)PyObjectsEnum::UISPRITE},
{"grid_pos", (getter)UIDrawable::get_grid_pos, (setter)UIDrawable::set_grid_pos,
MCRF_PROPERTY(grid_pos, "Position in grid tile coordinates (Vector, only when parent is Grid)."),
(void*)PyObjectsEnum::UISPRITE},
{"grid_size", (getter)UIDrawable::get_grid_size, (setter)UIDrawable::set_grid_size,
MCRF_PROPERTY(grid_size, "Size in grid tile coordinates (Vector, only when parent is Grid)."),
(void*)PyObjectsEnum::UISPRITE},
UIDRAWABLE_GETSETTERS, UIDRAWABLE_GETSETTERS,
UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UISPRITE), UIDRAWABLE_PARENT_GETSETTERS(PyObjectsEnum::UISPRITE),
UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UISPRITE), UIDRAWABLE_ALIGNMENT_GETSETTERS(PyObjectsEnum::UISPRITE),

View file

@ -257,10 +257,10 @@ class AStarPath:
origin: Vector # Starting position of the path (Vector, read-only). origin: Vector # Starting position of the path (Vector, read-only).
remaining: int # Number of steps remaining in the path (int, read-only). remaining: int # Number of steps remaining in the path (int, read-only).
def peek(self) -> Vector: def peek(self) -> Vector:
"""See next step without consuming it.""" """See the next step without consuming it."""
... ...
def walk(self) -> Vector: def walk(self) -> Vector:
"""Get and consume next step in the path.""" """Get and consume the next step in the path."""
... ...
class Arc: class Arc:
@ -268,17 +268,17 @@ class Arc:
def __init__(self, center=None, radius=0, start_angle=0, end_angle=90, color=None, thickness=1, **kwargs) -> None: ... def __init__(self, center=None, radius=0, start_angle=0, end_angle=90, color=None, thickness=1, **kwargs) -> None: ...
align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ... align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ...
bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
center: Any # Center position of the arc center: Vector # Center position of the arc (Vector).
color: Any # Arc color color: Color # Arc fill color (Color).
end_angle: Any # Ending angle in degrees end_angle: float # Ending angle in degrees (float).
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_pos: Any # Position in grid tile coordinates (only when parent is Grid) grid_pos: Vector # Position in grid tile coordinates (Vector, only when parent is Grid).
grid_size: Any # Size in grid tile coordinates (only when parent is Grid) grid_size: Vector # Size in grid tile coordinates (Vector, only when parent is Grid).
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
name: Any # Name for finding this element. name: str # Name for finding this element (str).
on_click: Any # Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str). on_click: Any # Callable executed when arc is clicked. Function receives (pos: Vector, button: str, action: str).
on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
@ -287,14 +287,14 @@ class Arc:
origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
pos: Any # Position as a Vector (same as center). pos: Any # Position as a Vector (same as center).
radius: Any # Arc radius in pixels radius: float # Arc radius in pixels (float).
rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ... rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ...
rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property. rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property.
start_angle: Any # Starting angle in degrees start_angle: float # Starting angle in degrees (float).
thickness: Any # Line thickness thickness: float # Line thickness in pixels (float).
vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable. visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable.
z_index: Any # Z-order for rendering (lower values rendered first). z_index: int # Z-order for rendering (int, lower values rendered first).
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this drawable's property.""" """Create and start an animation on this drawable's property."""
... ...
@ -385,38 +385,38 @@ class Caption:
def __init__(self, pos=None, font=None, text='', **kwargs) -> None: ... def __init__(self, pos=None, font=None, text='', **kwargs) -> None: ...
align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ... align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ...
bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
fill_color: Any # Fill color of the text. Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc. fill_color: Color # Fill color of the text (Color). Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc.
font_size: Any # Font size (integer) in points font_size: int # Font size in points (int). Clamped to the range [0, 65535].
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_pos: Any # Position in grid tile coordinates (only when parent is Grid) grid_pos: Vector # Position in grid tile coordinates (Vector). Only valid when parent is a Grid.
grid_size: Any # Size in grid tile coordinates (only when parent is Grid) grid_size: Vector # Size in grid tile coordinates (Vector). Only valid when parent is a Grid.
h: Any # Text height in pixels (read-only) h: float # Text height in pixels (float, read-only).
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
name: Any # Name for finding elements name: str # Name for finding elements (str).
on_click: Any # Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str). on_click: Any # Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).
on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called... on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called...
opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
outline: Any # Thickness of the border outline: float # Thickness of the text outline border (float). Clamped to non-negative values.
outline_color: Any # Outline color of the text. Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', etc. outline_color: Color # Outline color of the text (Color). Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', etc.
parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
pos: Any # (x, y) vector pos: Any # Position as (x, y) Vector.
rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ... rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ...
rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property. rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property.
shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
size: Any # Text dimensions as Vector (read-only) size: Any # Text dimensions as Vector (read-only).
text: Any # The text displayed text: str # The text string displayed by this Caption (str).
uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/... uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/...
vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable. visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable.
w: Any # Text width in pixels (read-only) w: float # Text width in pixels (float, read-only).
x: Any # X coordinate of top-left corner x: float # X coordinate of top-left corner (float).
y: Any # Y coordinate of top-left corner y: float # Y coordinate of top-left corner (float).
z_index: Any # Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed. z_index: Any # Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this drawable's property.""" """Create and start an animation on this drawable's property."""
@ -436,32 +436,32 @@ class Circle:
def __init__(self, radius=0, center=None, fill_color=None, outline_color=None, outline=0, **kwargs) -> None: ... def __init__(self, radius=0, center=None, fill_color=None, outline_color=None, outline=0, **kwargs) -> None: ...
align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ... align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ...
bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
center: Any # Center position of the circle center: Vector # Center position of the circle (Vector).
fill_color: Any # Fill color of the circle fill_color: Color # Fill color of the circle (Color).
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_pos: Any # Position in grid tile coordinates (only when parent is Grid) grid_pos: Vector # Position in grid tile coordinates (Vector). Only meaningful when parent is a Grid.
grid_size: Any # Size in grid tile coordinates (only when parent is Grid) grid_size: Vector # Size in grid tile coordinates (Vector). Only meaningful when parent is a Grid.
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
name: Any # Name for finding this element. name: str # Name for finding this element (str).
on_click: Any # Callable executed when circle is clicked. Function receives (pos: Vector, button: str, action: str). on_click: Callable | None # Callable executed when circle is clicked (Callable | None). Function receives (pos: Vector, button: str, action: str).
on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called... on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called...
opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
outline: Any # Outline thickness (0 for no outline) outline: float # Outline thickness in pixels (float). Use 0 for no outline.
outline_color: Any # Outline color of the circle outline_color: Color # Outline color of the circle (Color).
parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
pos: Any # Position as a Vector (same as center). pos: Vector # Position as a Vector (same as center) (Vector).
radius: Any # Circle radius in pixels radius: float # Circle radius in pixels (float).
rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ... rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ...
rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property. rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property.
vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable. visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable.
z_index: Any # Z-order for rendering (lower values rendered first). z_index: int # Z-order for rendering (int). Lower values are rendered first.
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this drawable's property.""" """Create and start an animation on this drawable's property."""
... ...
@ -495,66 +495,66 @@ class Color:
class ColorLayer: class ColorLayer:
"""A grid layer that stores RGBA colors per cell for background/overlay effects.""" """A grid layer that stores RGBA colors per cell for background/overlay effects."""
def __init__(self, z_index=-1, name=None, grid_size=None) -> None: ... def __init__(self, z_index=-1, name=None, grid_size=None) -> None: ...
grid: Any # Parent Grid or None. Setting manages layer association and handles lazy allocation. grid: Grid | None # Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation.
grid_size: Any # Layer dimensions as (width, height) tuple. grid_size: tuple # Layer dimensions as (width, height) tuple (tuple, read-only).
name: str # Layer name (str, read-only). Used for Grid.layer(name) lookup. name: str # Layer name (str, read-only). Used for Grid.layer(name) lookup.
visible: Any # Whether the layer is rendered. visible: bool # Whether the layer is rendered (bool).
z_index: Any # Layer z-order. Negative values render below entities. z_index: int # Layer z-order (int). Negative values render below entities.
def apply_gradient(self, source, range, color_low, color_high) -> ColorLayer: def apply_gradient(self, source: HeightMap, range: tuple, color_low: Color, color_high: Color) -> ColorLayer:
"""Interpolate between colors based on HeightMap value within range.""" """Interpolate between two colors based on HeightMap value within a range. Uses the original heightmap value for smooth transitions."""
... ...
def apply_perspective(self, entity, visible=None, discovered=None, unknown=None) -> Any: def apply_perspective(self, entity: Entity, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None:
"""Bind this layer to an entity for automatic FOV updates.""" """Bind this layer to an entity for automatic FOV updates. After binding, call update_perspective() when the entity moves."""
... ...
def apply_ranges(self, source, ranges) -> ColorLayer: def apply_ranges(self, source: HeightMap, ranges: list) -> ColorLayer:
"""Apply multiple color assignments in a single pass.""" """Apply multiple color assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping."""
... ...
def apply_threshold(self, source, range, color) -> ColorLayer: def apply_threshold(self, source: HeightMap, range: tuple, color: Color) -> ColorLayer:
"""Set fixed color for cells where HeightMap value is within range.""" """Set a fixed color for cells where the HeightMap value falls within a range."""
... ...
def at(self, pos) -> Color: def at(self, *args, **kwargs) -> Any:
"""at(x, y) -> Color""" """at(pos) or (x: int, y: int) -> Color"""
... ...
def clear_perspective(self) -> Any: def clear_perspective(self) -> None:
"""Remove the perspective binding from this layer.""" """Remove the perspective binding from this layer."""
... ...
def draw_fov(self, source, radius=None, fov=None, visible=None, discovered=None, unknown=None) -> Any: def draw_fov(self, source: tuple, radius: int = None, fov: FOV = None, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None:
"""Paint cells based on field-of-view visibility from source position.""" """Paint cells based on field-of-view visibility from a source position."""
... ...
def fill(self, color) -> Any: def fill(self, color: Color) -> None:
"""Fill the entire layer with the specified color.""" """Fill the entire layer with the specified color."""
... ...
def fill_rect(self, pos, size, color) -> Any: def fill_rect(self, pos: tuple, size: tuple, color: Color) -> None:
"""Fill a rectangular region with a color.""" """Fill a rectangular region with a color."""
... ...
def set(self, pos, color) -> Any: def set(self, pos, color: Color) -> None:
"""Set the color at cell position.""" """Set the color at a cell position."""
... ...
def update_perspective(self) -> Any: def update_perspective(self) -> None:
"""Redraw FOV based on the bound entity's current position.""" """Redraw FOV based on the bound entity's current position. Call this after the entity moves to update the visibility layer."""
... ...
class DijkstraMap: class DijkstraMap:
"""A Dijkstra distance map from a fixed root position.""" """A Dijkstra distance map from a fixed root position."""
def __init__(self, *args, **kwargs) -> None: ... def __init__(self, *args, **kwargs) -> None: ...
root: Vector # Root position that distances are measured from (Vector, read-only). root: Vector # Root position that distances are measured from (Vector, read-only).
def descent_step(self, pos) -> Vector | None: def descent_step(self, pos: Vector | tuple) -> Vector | None:
"""Get the adjacent cell with the lowest distance (steepest descent).""" """Get the adjacent cell with the lowest distance (steepest descent). Unlike step_from, this always returns the best neighbor in a single hop without following ..."""
... ...
def distance(self, pos) -> float | None: def distance(self, pos: Vector | tuple) -> float | None:
"""Get distance from position to root.""" """Get distance from position to root."""
... ...
def invert(self) -> DijkstraMap: def invert(self) -> DijkstraMap:
"""Return a NEW DijkstraMap whose distance field is the safety field.""" """Return a new DijkstraMap whose distance field is inverted (safety field). Cells near a root become high values; descend to flee from original roots. The orig..."""
... ...
def path_from(self, pos) -> AStarPath: def path_from(self, pos: Vector | tuple) -> AStarPath:
"""Get full path from position to root.""" """Get full path from position to root."""
... ...
def step_from(self, pos) -> Vector | None: def step_from(self, pos: Vector | tuple) -> Vector | None:
"""Get single step from position toward root.""" """Get single step from position toward root."""
... ...
def to_heightmap(self, size=None, unreachable=-1.0) -> HeightMap: def to_heightmap(self, size=None, unreachable=-1.0) -> HeightMap:
"""Convert distance field to a HeightMap.""" """Convert distance field to a HeightMap. Each cell's height equals its pathfinding distance from the root, useful for visualization, procedural terrain, or inf..."""
... ...
class DiscreteMap: class DiscreteMap:
@ -654,78 +654,78 @@ class Entity:
def __init__(self, grid_pos=None, texture=None, sprite_index=0, **kwargs) -> None: ... def __init__(self, grid_pos=None, texture=None, sprite_index=0, **kwargs) -> None: ...
behavior_type: int # Current behavior type (int, read-only). Use set_behavior() to change. behavior_type: int # Current behavior type (int, read-only). Use set_behavior() to change.
cell_pos: Vector # Integer logical cell position (Vector). Alias for grid_pos (the canonical name). cell_pos: Vector # Integer logical cell position (Vector). Alias for grid_pos (the canonical name).
cell_x: Any # Integer X cell coordinate. Alias for grid_x. cell_x: int # Integer X cell coordinate (int). Alias for grid_x.
cell_y: Any # Integer Y cell coordinate. Alias for grid_y. cell_y: int # Integer Y cell coordinate (int). Alias for grid_y.
default_behavior: int # Default behavior type (int, maps to Behavior enum). Entity reverts to this after DONE trigger. Default: 0 (IDLE). default_behavior: int # Default behavior type (int, maps to Behavior enum). Entity reverts to this after DONE trigger. Default: 0 (IDLE).
draw_pos: Vector # Fractional tile position for rendering (Vector). Use for smooth animation between grid cells. draw_pos: Vector # Fractional tile position for rendering (Vector). Use for smooth animation between grid cells.
grid: Any # Grid this entity belongs to. Get: Returns the Grid or None. Set: Assign a Grid to move entity, or None to remove from grid. grid: Any # Grid this entity belongs to (Grid or None). Assign a Grid to attach the entity, or None to remove it from its current grid.
grid_pos: Vector # Integer logical cell position (Vector). Canonical cell-position property; matches the 'grid_pos' constructor argument. Decoupled from draw_pos. Determines wh... grid_pos: Vector # Integer logical cell position (Vector). Canonical cell-position property matching the 'grid_pos' constructor argument. Decoupled from draw_pos. Determines wh...
grid_x: Any # Integer X cell coordinate. Canonical; matches grid_pos. grid_x: int # Integer X cell coordinate (int). Canonical; matches grid_pos.
grid_y: Any # Integer Y cell coordinate. Canonical; matches grid_pos. grid_y: int # Integer Y cell coordinate (int). Canonical; matches grid_pos.
labels: frozenset # Set of string labels for collision/targeting (frozenset). Assign any iterable of strings to replace all labels. labels: frozenset # String labels for collision and targeting (frozenset). Assign any iterable of strings to replace all labels.
move_speed: float # Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15. move_speed: float # Animation duration for behavior movement in seconds (float). 0 = instant. Default: 0.15.
name: Any # Name for finding elements name: str # Entity name for lookup (str).
opacity: Any # Opacity (0.0 = transparent, 1.0 = opaque) opacity: float # Render opacity (float). 0.0 = fully transparent, 1.0 = fully opaque.
perspective_map: DiscreteMap # Per-entity FOV memory (DiscreteMap, read-write). 3-state values per cell: 0 = unknown (never seen), 1 = discovered (seen before, not currently visible), 2 = ... perspective_map: DiscreteMap # Per-entity FOV memory (DiscreteMap). 3-state values per cell: 0=unknown, 1=discovered, 2=visible. Lazy-allocated on first access once entity has a grid; retu...
pos: Vector # Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. Requires entity to be attached to a grid. pos: Vector # Pixel position relative to grid (Vector). Computed as draw_pos * tile_size. Requires entity to be attached to a grid.
shader: Any # Shader for GPU visual effects (Shader or None). When set, the entity is rendered through the shader program. Set to None to disable shader effects. shader: Any # GPU shader for visual effects (Shader or None). Set to None to disable shader rendering.
sight_radius: int # FOV radius for TARGET trigger (int). Default: 10. sight_radius: int # FOV radius for TARGET trigger (int). Default: 10.
sprite_grid: Any # Per-tile sprite indices for composite multi-tile entities (list of lists or None). Row-major, dimensions must match tile_width x tile_height. Use -1 for empt... sprite_grid: Any # Per-tile sprite indices for composite multi-tile entities (list of lists or None). Row-major, dimensions must match tile_width x tile_height. Use -1 for empt...
sprite_index: Any # Sprite index on the texture on the display sprite_index: int # Sprite index into the entity's texture atlas (int).
sprite_offset: Vector # Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering. sprite_offset: Vector # Pixel offset for oversized sprites (Vector). Applied pre-zoom during grid rendering.
sprite_offset_x: Any # X component of sprite pixel offset. sprite_offset_x: float # X component of sprite pixel offset (float).
sprite_offset_y: Any # Y component of sprite pixel offset. sprite_offset_y: float # Y component of sprite pixel offset (float).
step: Any # Step callback for grid.step() turn management. Called with (trigger, data) when behavior triggers fire. Set to None to clear. step: Any # Step callback for grid.step() turn management (Callable or None). Called with (trigger, data) when behavior triggers fire.
target_label: Any # Label to search for with TARGET trigger (str or None). Default: None. target_label: Any # Label to search for with TARGET trigger (str or None). Default: None.
texture: Texture # Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture when the entity is constructed without one. Setting preserves sprite_index (the index is n... texture: Texture # Sprite texture atlas (Texture). Defaults to mcrfpy.default_texture at construction. Setting preserves sprite_index (not re-validated against the new atlas).
tile_height: int # Entity height in tiles (int). Must be >= 1. Default 1. tile_height: int # Entity height in tiles (int). Must be >= 1. Default 1.
tile_size: Any # Entity size in tiles as (width, height) Vector. Default (1, 1). tile_size: Vector # Entity size in tiles as (width, height) (Vector). Default (1, 1).
tile_width: int # Entity width in tiles (int). Must be >= 1. Default 1. tile_width: int # Entity width in tiles (int). Must be >= 1. Default 1.
turn_order: int # Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1. turn_order: int # Turn order for grid.step() (int). 0 = skip, higher values go later. Default: 1.
uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: entity.uniforms['name'] = value. Supports float, vec2/3/4 ... uniforms: UniformCollection # Collection of shader uniforms (UniformCollection, read-only). Set values via dict-like syntax: entity.uniforms['name'] = value.
visible: Any # Visibility flag visible: bool # Visibility flag (bool). When False, the entity is not rendered.
x: Any # Pixel X position relative to grid. Requires entity to be attached to a grid. x: float # Pixel X position relative to grid (float). Requires entity to be attached to a grid.
y: Any # Pixel Y position relative to grid. Requires entity to be attached to a grid. y: float # Pixel Y position relative to grid (float). Requires entity to be attached to a grid.
def add_label(self, label: str) -> None: def add_label(self, label: str) -> None:
"""Add a label to this entity. Idempotent (adding same label twice is safe).""" """Add a label to this entity. Idempotent; adding the same label twice is safe."""
... ...
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this entity's property.""" """Create and start an animation on this entity's property."""
... ...
def at(self, *args, **kwargs) -> Any: def at(self, x: int, y: int) -> GridPoint | None:
"""at(x, y) or at(pos) -> GridPoint | None""" """Return the GridPoint at (x, y) if currently VISIBLE to this entity's perspective_map, otherwise None."""
... ...
def die(self, *args, **kwargs) -> Any: def die(self) -> None:
"""Remove this entity from its grid.""" """Remove this entity from its grid."""
... ...
def find_path(self, target, diagonal_cost=1.41, collide=None) -> AStarPath | None: def find_path(self, target, diagonal_cost: float = 1.41, collide: str = None) -> AStarPath | None:
"""Find a path from this entity to the target position.""" """Find a path from this entity to the target position."""
... ...
def has_label(self, label: str) -> bool: def has_label(self, label: str) -> bool:
"""Check if this entity has the given label.""" """Check if this entity has the given label."""
... ...
def index(self, *args, **kwargs) -> Any: def index(self) -> int:
"""Return the index of this entity in its grid's entity collection""" """Return the index of this entity in its grid's entity collection."""
... ...
def move(self, *args, **kwargs) -> Any: def move(self, *args, **kwargs) -> Any:
"""move(dx, dy) or (delta) -> None""" """move(dx, dy) or (delta) -> None"""
... ...
def path_to(self, *args, **kwargs) -> Any: def path_to(self, x: int, y: int) -> list:
"""path_to(x, y) or path_to(target) -> list""" """Find a path to the target position using A* pathfinding."""
... ...
def remove_label(self, label: str) -> None: def remove_label(self, label: str) -> None:
"""Remove a label from this entity. No-op if label not present.""" """Remove a label from this entity. No-op if label is not present."""
... ...
def resize(self, *args, **kwargs) -> Any: def resize(self, *args, **kwargs) -> Any:
"""resize(width, height) or (size) -> None""" """resize(width, height) or (size) -> None"""
... ...
def set_behavior(self, type, waypoints=None, turns=0, path=None) -> None: def set_behavior(self, type, waypoints=None, turns: int = 0, path=None, pathfinder=None) -> None:
"""Configure this entity's behavior for grid.step() turn management.""" """Configure this entity's behavior for grid.step() turn management."""
... ...
def update_visibility(self) -> None: def update_visibility(self) -> None:
"""Update entity's visibility state based on current FOV.""" """Recompute which cells are visible from this entity's position and update perspective_map."""
... ...
def visible_entities(self, fov=None, radius=None) -> list[Entity]: def visible_entities(self, fov=None, radius: int = None) -> list[Entity]:
"""Get list of other entities visible from this entity's position.""" """Get list of other entities visible from this entity's position."""
... ...
@ -812,38 +812,38 @@ class Frame:
def __init__(self, pos=None, size=None, **kwargs) -> None: ... def __init__(self, pos=None, size=None, **kwargs) -> None: ...
align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ... align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ...
bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
cache_subtree: Any # #144: Cache subtree rendering to texture for performance cache_subtree: bool # Cache the frame and all children to a render texture for performance (bool). Useful for complex static subtrees.
children: Any # UICollection of objects on top of this one children: UICollection # UICollection of child drawable objects rendered on top of this frame (UICollection, read-only).
clip_children: Any # Whether to clip children to frame bounds clip_children: bool # Whether to clip child elements to the frame's bounds (bool). Enables render-texture mode when True.
fill_color: Any # Fill color of the rectangle. Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc. fill_color: Color # Fill color of the rectangle (Color). Returns a copy; modifying components requires reassignment. For animation, use 'fill_color.r', 'fill_color.g', etc.
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_pos: Any # Position in grid tile coordinates (only when parent is Grid) grid_pos: Vector # Position in grid tile coordinates (Vector). Only meaningful when this element's parent is a Grid.
grid_size: Any # Size in grid tile coordinates (only when parent is Grid) grid_size: Vector # Size in grid tile coordinates (Vector). Only meaningful when this element's parent is a Grid.
h: Any # height of the rectangle h: float # Height of the rectangle (float).
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
name: Any # Name for finding elements name: str # Name for finding elements (str).
on_click: Any # Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str). on_click: Any # Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).
on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called... on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called...
opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
outline: Any # Thickness of the border outline: float # Thickness of the border in pixels (float).
outline_color: Any # Outline color of the rectangle. Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', etc. outline_color: Color # Outline color of the rectangle (Color). Returns a copy; modifying components requires reassignment. For animation, use 'outline_color.r', 'outline_color.g', ...
parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
pos: Any # Position as a Vector pos: Vector # Position as a Vector (Vector).
rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ... rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ...
rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property. rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property.
shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/... uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/...
vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable. visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable.
w: Any # width of the rectangle w: float # Width of the rectangle (float).
x: Any # X coordinate of top-left corner x: float # X coordinate of the top-left corner (float).
y: Any # Y coordinate of top-left corner y: float # Y coordinate of the top-left corner (float).
z_index: Any # Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed. z_index: Any # Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this drawable's property.""" """Create and start an animation on this drawable's property."""
@ -863,89 +863,91 @@ class Grid:
def __init__(self, grid_size=None, pos=None, size=None, texture=None, **kwargs) -> None: ... def __init__(self, grid_size=None, pos=None, size=None, texture=None, **kwargs) -> None: ...
align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ... align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ...
bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
camera_rotation: Any # Rotation of grid contents around camera center (degrees). camera_rotation: float # Rotation of grid contents around camera center in degrees (float).
center: Any # Camera center point in pixel coordinates. center: tuple # Camera center point in pixel coordinates (tuple).
center_x: Any # center of the view X-coordinate center_x: float # Camera center X-coordinate in pixel space (float).
center_y: Any # center of the view Y-coordinate center_y: float # Camera center Y-coordinate in pixel space (float).
children: Any # UICollection of UIDrawable children (speech bubbles, effects, overlays) children: UICollection # UICollection of UIDrawable children such as speech bubbles, effects, and overlays (UICollection, read-only).
entities: Any # EntityCollection of entities on this grid entities: EntityCollection # EntityCollection of entities on this grid (EntityCollection, read-only).
fill_color: Any # Background fill color. fill_color: Color # Background fill color (Color). Drawn behind all tiles and entities.
fov: Any # FOV algorithm for this grid (mcrfpy.FOV enum). Used by entity.updateVisibility() and layer methods when fov=None. fov: Any # FOV algorithm for this grid (FOV enum). Used by entity.updateVisibility() and layer methods when fov=None.
fov_radius: Any # Default FOV radius for this grid. Used when radius not specified. fov_radius: int # Default FOV radius for this grid (int). Used when radius is not specified.
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_data: Any # The underlying grid data object (for multi-view scenarios). grid_data: Grid | None # The underlying grid data object (Grid | None). Used for multi-view scenarios where multiple GridViews share one Grid.
grid_h: Any # Grid height in cells grid_h: int # Grid height in cells (int, read-only).
grid_pos: Any # Position in parent grid's tile coordinates (only when parent is Grid) grid_pos: Vector # Position in parent grid's tile coordinates (Vector). Only valid when parent is a Grid.
grid_size: Any # Grid dimensions (grid_w, grid_h) grid_size: Vector # Grid dimensions as (grid_w, grid_h) (Vector, read-only).
grid_w: Any # Grid width in cells grid_w: int # Grid width in cells (int, read-only).
h: Any # visible widget height h: float # Visible widget height (float).
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
hovered_cell: Any # Currently hovered cell as (x, y) tuple, or None if not hovering. hovered_cell: tuple | None # Currently hovered cell as (x, y) tuple, or None if not hovering (tuple | None, read-only).
layers: ColorLayer # List of grid layers (ColorLayer, TileLayer) sorted by z_index layers: tuple # Tuple of grid layers sorted by z_index (tuple, read-only). Contains ColorLayer and TileLayer objects.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
name: Any # Name for finding elements name: str # Name for finding elements (str).
on_cell_click: Any # Callback when a grid cell is clicked. Called with (cell_pos: Vector). on_cell_click: Callable | None # Callback when a grid cell is clicked (Callable | None). Called with (cell_pos: Vector, button: MouseButton, action: InputState).
on_cell_enter: Any # Callback when mouse enters a grid cell. Called with (cell_pos: Vector). on_cell_enter: Callable | None # Callback when mouse enters a grid cell (Callable | None). Called with (cell_pos: Vector).
on_cell_exit: Any # Callback when mouse exits a grid cell. Called with (cell_pos: Vector). on_cell_exit: Callable | None # Callback when mouse exits a grid cell (Callable | None). Called with (cell_pos: Vector).
on_click: Any # Callable executed when object is clicked. on_click: Callable | None # Callable executed when object is clicked (Callable | None).
on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called... on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called...
opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
perspective: Any # Entity whose perspective to use for FOV rendering (None for omniscient view). Setting an entity automatically enables perspective mode. perspective: Entity | None # Entity whose perspective to use for FOV rendering (Entity | None). Setting an entity automatically enables perspective mode. Set to None for omniscient view.
perspective_enabled: Any # Whether to use perspective-based FOV rendering. When True with no valid entity, all cells appear undiscovered. perspective_enabled: bool # Whether to use perspective-based FOV rendering (bool). When True with no valid entity, all cells appear undiscovered.
pos: Any # Position of the grid as Vector pos: Vector # Position of the grid as Vector (Vector).
rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ... rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ...
rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property. rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property.
shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
size: Any # Size of the grid as Vector (width, height) size: Vector # Size of the grid widget as Vector (Vector, width x height in pixels).
texture: Any # Texture used for tile rendering (read-only). texture: Texture | None # Texture used for tile rendering (Texture | None, read-only).
uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/... uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/...
vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
view: Any # Auto-created GridView for rendering (read-only). When Grid is appended to a scene, this view is what actually renders. view: GridView | None # Auto-created GridView for rendering (GridView | None, read-only). When Grid is appended to a scene, this view is what actually renders.
visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable. visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable.
w: Any # visible widget width w: float # Visible widget width (float).
x: Any # top-left corner X-coordinate x: float # Top-left corner X-coordinate (float).
y: Any # top-left corner Y-coordinate y: float # Top-left corner Y-coordinate (float).
z_index: Any # Z-order for rendering (lower values rendered first). z_index: int # Z-order for rendering (int). Lower values are rendered first.
zoom: Any # Zoom level for rendering. zoom: float # Zoom level for rendering (float). Values greater than 1.0 magnify; less than 1.0 shrink.
def add_layer(self, layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer: def add_layer(self, layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer:
"""Add a layer to the grid.""" """Add a layer to the grid. Layers with size (0, 0) are automatically resized to match the grid."""
... ...
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this drawable's property.""" """Create and start an animation on this drawable's property."""
... ...
def apply_ranges(self, source: HeightMap, ranges: list) -> Grid: def apply_ranges(self, source: HeightMap, ranges: list) -> Grid:
"""Apply multiple thresholds in a single pass.""" """Apply multiple walkability thresholds to the grid in a single pass."""
... ...
def apply_threshold(self, source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid: def apply_threshold(self, source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid:
"""Apply walkable/transparent properties where heightmap values are in range.""" """Apply walkable/transparent properties to cells where heightmap values fall within range."""
...
def at(self, x: int, y: int) -> GridPoint:
"""Return the GridPoint cell at grid coordinates (x, y)."""
... ...
def at(self, *args, **kwargs) -> Any: ...
def center_camera(self, pos: tuple = None) -> None: def center_camera(self, pos: tuple = None) -> None:
"""Center the camera on a tile coordinate.""" """Center the camera on a tile coordinate. If pos is None, centers on the grid's middle tile."""
... ...
def clear_dijkstra_maps(self) -> None: def clear_dijkstra_maps(self) -> None:
"""Clear all cached Dijkstra maps.""" """Clear all cached Dijkstra maps. Call this after modifying grid cell walkability to ensure pathfinding uses updated walkability data."""
... ...
def compute_fov(self, pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None: def compute_fov(self, pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None:
"""Compute field of view from a position.""" """Compute field of view from a position. Updates the internal FOV state; use is_in_fov() to query visibility."""
... ...
def entities_in_radius(self, pos: tuple|Vector, radius: float) -> list[Entity]: def entities_in_radius(self, pos: tuple | Vector, radius: float) -> list:
"""Query entities within radius using spatial hash (O(k) where k = nearby entities).""" """Query entities within radius using spatial hash (O(k) where k = nearby entities)."""
... ...
def find_path(self, start, end, diagonal_cost=1.41, collide=None) -> AStarPath | None: def find_path(self, start, end, diagonal_cost: float = 1.41, collide: str = None) -> AStarPath | None:
"""Compute A* path between two points.""" """Compute A* path between two points. The returned AStarPath can be iterated or walked step-by-step."""
... ...
def get_dijkstra_map(self, root, diagonal_cost=1.41, collide=None) -> DijkstraMap: def get_dijkstra_map(self, root, diagonal_cost: float = 1.41, collide: str = None) -> DijkstraMap:
"""Get or create a Dijkstra distance map for a root position.""" """Get or create a cached Dijkstra distance map for a root position. Call clear_dijkstra_maps() after changing grid walkability to invalidate."""
... ...
def is_in_fov(self, pos) -> bool: def is_in_fov(self, pos) -> bool:
"""Check if a cell is in the field of view.""" """Check if a cell is in the field of view. Must call compute_fov() first to calculate visibility."""
... ...
def layer(self, name: str) -> ColorLayer | TileLayer | None: def layer(self, name: str) -> ColorLayer | TileLayer | None:
"""Get a layer by its name.""" """Get a layer by its name."""
@ -957,13 +959,13 @@ class Grid:
"""Reapply alignment relative to parent, useful for responsive layouts.""" """Reapply alignment relative to parent, useful for responsive layouts."""
... ...
def remove_layer(self, name_or_layer: str | ColorLayer | TileLayer) -> None: def remove_layer(self, name_or_layer: str | ColorLayer | TileLayer) -> None:
"""Remove a layer from the grid.""" """Remove a layer from the grid by name or by object reference."""
... ...
def resize(self, *args, **kwargs) -> Any: def resize(self, *args, **kwargs) -> Any:
"""resize(width, height) or (size) -> None""" """resize(width, height) or (size) -> None"""
... ...
def step(self, n=1, turn_order=None) -> None: def step(self, n: int = 1, turn_order: int = None) -> None:
"""Execute n rounds of turn-based entity behavior.""" """Execute n rounds of turn-based entity behavior. Each round: entities grouped by turn_order (ascending), behaviors executed, triggers fired (TARGET, DONE, BLO..."""
... ...
class GridView: class GridView:
@ -971,89 +973,91 @@ class GridView:
def __init__(self, *args, **kwargs) -> None: ... def __init__(self, *args, **kwargs) -> None: ...
align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ... align: Any # Alignment relative to parent bounds (Alignment enum or None). When set, position is automatically calculated when parent is assigned or resized. Set to None ...
bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
camera_rotation: Any # Rotation of grid contents around camera center (degrees). camera_rotation: float # Rotation of grid contents around camera center in degrees (float).
center: Any # Camera center point in pixel coordinates. center: tuple # Camera center point in pixel coordinates (tuple).
center_x: Any # center of the view X-coordinate center_x: float # Camera center X-coordinate in pixel space (float).
center_y: Any # center of the view Y-coordinate center_y: float # Camera center Y-coordinate in pixel space (float).
children: Any # UICollection of UIDrawable children (speech bubbles, effects, overlays) children: UICollection # UICollection of UIDrawable children such as speech bubbles, effects, and overlays (UICollection, read-only).
entities: Any # EntityCollection of entities on this grid entities: EntityCollection # EntityCollection of entities on this grid (EntityCollection, read-only).
fill_color: Any # Background fill color. fill_color: Color # Background fill color (Color). Drawn behind all tiles and entities.
fov: Any # FOV algorithm for this grid (mcrfpy.FOV enum). Used by entity.updateVisibility() and layer methods when fov=None. fov: Any # FOV algorithm for this grid (FOV enum). Used by entity.updateVisibility() and layer methods when fov=None.
fov_radius: Any # Default FOV radius for this grid. Used when radius not specified. fov_radius: int # Default FOV radius for this grid (int). Used when radius is not specified.
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_data: Any # The underlying grid data object (for multi-view scenarios). grid_data: Grid | None # The underlying grid data object (Grid | None). Used for multi-view scenarios where multiple GridViews share one Grid.
grid_h: Any # Grid height in cells grid_h: int # Grid height in cells (int, read-only).
grid_pos: Any # Position in parent grid's tile coordinates (only when parent is Grid) grid_pos: Vector # Position in parent grid's tile coordinates (Vector). Only valid when parent is a Grid.
grid_size: Any # Grid dimensions (grid_w, grid_h) grid_size: Vector # Grid dimensions as (grid_w, grid_h) (Vector, read-only).
grid_w: Any # Grid width in cells grid_w: int # Grid width in cells (int, read-only).
h: Any # visible widget height h: float # Visible widget height (float).
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
hovered_cell: Any # Currently hovered cell as (x, y) tuple, or None if not hovering. hovered_cell: tuple | None # Currently hovered cell as (x, y) tuple, or None if not hovering (tuple | None, read-only).
layers: ColorLayer # List of grid layers (ColorLayer, TileLayer) sorted by z_index layers: tuple # Tuple of grid layers sorted by z_index (tuple, read-only). Contains ColorLayer and TileLayer objects.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
name: Any # Name for finding elements name: str # Name for finding elements (str).
on_cell_click: Any # Callback when a grid cell is clicked. Called with (cell_pos: Vector). on_cell_click: Callable | None # Callback when a grid cell is clicked (Callable | None). Called with (cell_pos: Vector, button: MouseButton, action: InputState).
on_cell_enter: Any # Callback when mouse enters a grid cell. Called with (cell_pos: Vector). on_cell_enter: Callable | None # Callback when mouse enters a grid cell (Callable | None). Called with (cell_pos: Vector).
on_cell_exit: Any # Callback when mouse exits a grid cell. Called with (cell_pos: Vector). on_cell_exit: Callable | None # Callback when mouse exits a grid cell (Callable | None). Called with (cell_pos: Vector).
on_click: Any # Callable executed when object is clicked. on_click: Callable | None # Callable executed when object is clicked (Callable | None).
on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called... on_move: Any # Callback for mouse movement within bounds. Called with (pos: Vector, button: str, action: str) for each mouse movement while inside. Performance note: Called...
opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
perspective: Any # Entity whose perspective to use for FOV rendering (None for omniscient view). Setting an entity automatically enables perspective mode. perspective: Entity | None # Entity whose perspective to use for FOV rendering (Entity | None). Setting an entity automatically enables perspective mode. Set to None for omniscient view.
perspective_enabled: Any # Whether to use perspective-based FOV rendering. When True with no valid entity, all cells appear undiscovered. perspective_enabled: bool # Whether to use perspective-based FOV rendering (bool). When True with no valid entity, all cells appear undiscovered.
pos: Any # Position of the grid as Vector pos: Vector # Position of the grid as Vector (Vector).
rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ... rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ...
rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property. rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property.
shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
size: Any # Size of the grid as Vector (width, height) size: Vector # Size of the grid widget as Vector (Vector, width x height in pixels).
texture: Any # Texture used for tile rendering (read-only). texture: Texture | None # Texture used for tile rendering (Texture | None, read-only).
uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/... uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/...
vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
view: Any # Auto-created GridView for rendering (read-only). When Grid is appended to a scene, this view is what actually renders. view: GridView | None # Auto-created GridView for rendering (GridView | None, read-only). When Grid is appended to a scene, this view is what actually renders.
visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable. visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable.
w: Any # visible widget width w: float # Visible widget width (float).
x: Any # top-left corner X-coordinate x: float # Top-left corner X-coordinate (float).
y: Any # top-left corner Y-coordinate y: float # Top-left corner Y-coordinate (float).
z_index: Any # Z-order for rendering (lower values rendered first). z_index: int # Z-order for rendering (int). Lower values are rendered first.
zoom: Any # Zoom level for rendering. zoom: float # Zoom level for rendering (float). Values greater than 1.0 magnify; less than 1.0 shrink.
def add_layer(self, layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer: def add_layer(self, layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer:
"""Add a layer to the grid.""" """Add a layer to the grid. Layers with size (0, 0) are automatically resized to match the grid."""
... ...
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this drawable's property.""" """Create and start an animation on this drawable's property."""
... ...
def apply_ranges(self, source: HeightMap, ranges: list) -> Grid: def apply_ranges(self, source: HeightMap, ranges: list) -> Grid:
"""Apply multiple thresholds in a single pass.""" """Apply multiple walkability thresholds to the grid in a single pass."""
... ...
def apply_threshold(self, source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid: def apply_threshold(self, source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid:
"""Apply walkable/transparent properties where heightmap values are in range.""" """Apply walkable/transparent properties to cells where heightmap values fall within range."""
...
def at(self, x: int, y: int) -> GridPoint:
"""Return the GridPoint cell at grid coordinates (x, y)."""
... ...
def at(self, *args, **kwargs) -> Any: ...
def center_camera(self, pos: tuple = None) -> None: def center_camera(self, pos: tuple = None) -> None:
"""Center the camera on a tile coordinate.""" """Center the camera on a tile coordinate. If pos is None, centers on the grid's middle tile."""
... ...
def clear_dijkstra_maps(self) -> None: def clear_dijkstra_maps(self) -> None:
"""Clear all cached Dijkstra maps.""" """Clear all cached Dijkstra maps. Call this after modifying grid cell walkability to ensure pathfinding uses updated walkability data."""
... ...
def compute_fov(self, pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None: def compute_fov(self, pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None:
"""Compute field of view from a position.""" """Compute field of view from a position. Updates the internal FOV state; use is_in_fov() to query visibility."""
... ...
def entities_in_radius(self, pos: tuple|Vector, radius: float) -> list[Entity]: def entities_in_radius(self, pos: tuple | Vector, radius: float) -> list:
"""Query entities within radius using spatial hash (O(k) where k = nearby entities).""" """Query entities within radius using spatial hash (O(k) where k = nearby entities)."""
... ...
def find_path(self, start, end, diagonal_cost=1.41, collide=None) -> AStarPath | None: def find_path(self, start, end, diagonal_cost: float = 1.41, collide: str = None) -> AStarPath | None:
"""Compute A* path between two points.""" """Compute A* path between two points. The returned AStarPath can be iterated or walked step-by-step."""
... ...
def get_dijkstra_map(self, root, diagonal_cost=1.41, collide=None) -> DijkstraMap: def get_dijkstra_map(self, root, diagonal_cost: float = 1.41, collide: str = None) -> DijkstraMap:
"""Get or create a Dijkstra distance map for a root position.""" """Get or create a cached Dijkstra distance map for a root position. Call clear_dijkstra_maps() after changing grid walkability to invalidate."""
... ...
def is_in_fov(self, pos) -> bool: def is_in_fov(self, pos) -> bool:
"""Check if a cell is in the field of view.""" """Check if a cell is in the field of view. Must call compute_fov() first to calculate visibility."""
... ...
def layer(self, name: str) -> ColorLayer | TileLayer | None: def layer(self, name: str) -> ColorLayer | TileLayer | None:
"""Get a layer by its name.""" """Get a layer by its name."""
@ -1065,13 +1069,13 @@ class GridView:
"""Reapply alignment relative to parent, useful for responsive layouts.""" """Reapply alignment relative to parent, useful for responsive layouts."""
... ...
def remove_layer(self, name_or_layer: str | ColorLayer | TileLayer) -> None: def remove_layer(self, name_or_layer: str | ColorLayer | TileLayer) -> None:
"""Remove a layer from the grid.""" """Remove a layer from the grid by name or by object reference."""
... ...
def resize(self, *args, **kwargs) -> Any: def resize(self, *args, **kwargs) -> Any:
"""resize(width, height) or (size) -> None""" """resize(width, height) or (size) -> None"""
... ...
def step(self, n=1, turn_order=None) -> None: def step(self, n: int = 1, turn_order: int = None) -> None:
"""Execute n rounds of turn-based entity behavior.""" """Execute n rounds of turn-based entity behavior. Each round: entities grouped by turn_order (ascending), behaviors executed, triggers fired (TARGET, DONE, BLO..."""
... ...
class HeightMap: class HeightMap:
@ -1219,8 +1223,8 @@ class Line:
end: Any # Ending point of the line as a Vector. end: Any # Ending point of the line as a Vector.
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_pos: Any # Position in grid tile coordinates (only when parent is Grid) grid_pos: Vector # Position in grid tile coordinates (Vector, only when parent is Grid).
grid_size: Any # Size in grid tile coordinates (only when parent is Grid) grid_size: Vector # Size in grid tile coordinates (Vector, only when parent is Grid).
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
@ -1458,12 +1462,12 @@ class Sprite:
bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)). bounds: Any # Bounding box as (pos, size) tuple of Vectors. Returns (Vector(x, y), Vector(width, height)).
global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)). global_bounds: Any # Bounding box as (pos, size) tuple of Vectors in screen coordinates. Returns (Vector(x, y), Vector(width, height)).
global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain. global_position: Any # Global screen position (read-only). Calculates absolute position by walking up the parent chain.
grid_pos: Any # Position in grid tile coordinates (only when parent is Grid) grid_pos: Vector # Position in grid tile coordinates (Vector, only when parent is Grid).
grid_size: Any # Size in grid tile coordinates (only when parent is Grid) grid_size: Vector # Size in grid tile coordinates (Vector, only when parent is Grid).
horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER). horiz_margin: float # Horizontal margin override (float, 0 = use general margin). Invalid for vertically-centered alignments (TOP_CENTER, BOTTOM_CENTER, CENTER).
hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement. hovered: Any # Whether mouse is currently over this element (read-only). Updated automatically by the engine during mouse movement.
margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr... margin: float # General margin from edge when aligned (float). Applied to both horizontal and vertical edges unless overridden. Invalid for CENTER alignment (raises ValueErr...
name: Any # Name for finding elements name: str # Name for finding elements (str).
on_click: Any # Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str). on_click: Any # Callable executed when object is clicked. Function receives (pos: Vector, button: str, action: str).
on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds. on_enter: Any # Callback for mouse enter events. Called with (pos: Vector, button: str, action: str) when mouse enters this element's bounds.
on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds. on_exit: Any # Callback for mouse exit events. Called with (pos: Vector, button: str, action: str) when mouse leaves this element's bounds.
@ -1471,20 +1475,20 @@ class Sprite:
opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0]. opacity: Any # Opacity level (0.0 = transparent, 1.0 = opaque). Automatically clamped to valid range [0.0, 1.0].
origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center. origin: Any # Transform origin as Vector (pivot point for rotation). Default (0,0) is top-left; set to (w/2, h/2) to rotate around center.
parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent. parent: Any # Parent drawable. Get: Returns the parent Frame/Grid if nested, or None if at scene level. Set: Assign a Frame/Grid to reparent, or None to remove from parent.
pos: Any # Position as a Vector pos: Vector # Position as a Vector (Vector).
rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ... rotate_with_camera: bool # Whether to rotate visually with parent Grid's camera_rotation (bool). False (default): stay screen-aligned. True: tilt with camera. Only affects children of ...
rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property. rotation: Any # Rotation angle in degrees (clockwise around origin). Animatable property.
scale: Any # Uniform size factor scale: float # Uniform size factor (float). Sets both horizontal and vertical scale to the same value.
scale_x: Any # Horizontal scale factor scale_x: float # Horizontal scale factor (float).
scale_y: Any # Vertical scale factor scale_y: float # Vertical scale factor (float).
shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects. shader: Any # Shader for GPU visual effects (Shader or None). When set, the drawable is rendered through the shader program. Set to None to disable shader effects.
sprite_index: Any # Which sprite on the texture is shown sprite_index: int # Which sprite on the texture is shown (int). Index into the texture atlas; must be in range [0, sprite_count).
texture: Any # Texture object texture: Texture # Texture object (Texture). The texture atlas from which sprites are drawn.
uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/... uniforms: Any # Collection of shader uniforms (read-only access to collection). Set uniforms via dict-like syntax: drawable.uniforms['name'] = value. Supports float, vec2/3/...
vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER). vert_margin: float # Vertical margin override (float, 0 = use general margin). Invalid for horizontally-centered alignments (CENTER_LEFT, CENTER_RIGHT, CENTER).
visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable. visible: bool # Whether the object is visible (bool). Invisible objects are not rendered or clickable.
x: Any # X coordinate of top-left corner x: float # X coordinate of top-left corner (float).
y: Any # Y coordinate of top-left corner y: float # Y coordinate of top-left corner (float).
z_index: Any # Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed. z_index: Any # Z-order for rendering (lower values rendered first). Automatically triggers scene resort when changed.
def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation: def animate(self, property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation:
"""Create and start an animation on this drawable's property.""" """Create and start an animation on this drawable's property."""
@ -1525,29 +1529,29 @@ class Texture:
class TileLayer: class TileLayer:
"""A grid layer that stores sprite indices per cell for tile-based rendering.""" """A grid layer that stores sprite indices per cell for tile-based rendering."""
def __init__(self, z_index=-1, name=None, texture=None, grid_size=None) -> None: ... def __init__(self, z_index=-1, name=None, texture=None, grid_size=None) -> None: ...
grid: Any # Parent Grid or None. Setting manages layer association and handles lazy allocation. grid: Grid | None # Parent Grid or None (Grid | None). Setting manages layer association and handles lazy allocation.
grid_size: Any # Layer dimensions as (width, height) tuple. grid_size: tuple # Layer dimensions as (width, height) tuple (tuple, read-only).
name: str # Layer name (str, read-only). Used for Grid.layer(name) lookup. name: str # Layer name (str, read-only). Used for Grid.layer(name) lookup.
texture: Any # Texture atlas for tile sprites. texture: Texture | None # Texture atlas for tile sprites (Texture | None).
visible: Any # Whether the layer is rendered. visible: bool # Whether the layer is rendered (bool).
z_index: Any # Layer z-order. Negative values render below entities. z_index: int # Layer z-order (int). Negative values render below entities.
def apply_ranges(self, source, ranges) -> TileLayer: def apply_ranges(self, source: HeightMap, ranges: list) -> TileLayer:
"""Apply multiple tile assignments in a single pass.""" """Apply multiple tile assignments from a HeightMap in a single pass. Later ranges override earlier ones if overlapping."""
... ...
def apply_threshold(self, source, range, tile) -> TileLayer: def apply_threshold(self, source: HeightMap, range: tuple, tile: int) -> TileLayer:
"""Set tile index for cells where HeightMap value is within range.""" """Set a tile index for cells where the HeightMap value falls within a range."""
... ...
def at(self, pos) -> int: def at(self, *args, **kwargs) -> Any:
"""at(x, y) -> int""" """at(pos) or (x: int, y: int) -> int"""
... ...
def fill(self, index) -> Any: def fill(self, index: int) -> None:
"""Fill the entire layer with the specified tile index.""" """Fill the entire layer with the specified tile index."""
... ...
def fill_rect(self, pos, size, index) -> Any: def fill_rect(self, pos: tuple, size: tuple, index: int) -> None:
"""Fill a rectangular region with a tile index.""" """Fill a rectangular region with a tile index."""
... ...
def set(self, pos, index) -> Any: def set(self, pos, index: int) -> None:
"""Set the tile index at cell position. Use -1 for no tile.""" """Set the tile index at a cell position. Use -1 to clear the tile."""
... ...
class TileMapFile: class TileMapFile:
@ -1928,84 +1932,84 @@ class Window:
class _automation_module: class _automation_module:
"""Stub for mcrfpy.automation submodule.""" """Stub for mcrfpy.automation submodule."""
@staticmethod @staticmethod
def click(self, *args, **kwargs) -> Any: def click(pos: tuple | list | Vector | None = None, clicks: int = 1, interval: float = 0.0, button: str = 'left') -> None:
"""click(pos=None, clicks=1, interval=0.0, button='left') - Click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Click the mouse at the specified position."""
... ...
@staticmethod @staticmethod
def doubleClick(self, *args, **kwargs) -> Any: def doubleClick(pos: tuple | list | Vector | None = None) -> None:
"""doubleClick(pos=None) - Double click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Double-click the mouse at the specified position."""
... ...
@staticmethod @staticmethod
def dragRel(self, *args, **kwargs) -> Any: def dragRel(offset: tuple | list | Vector, duration: float = 0.0, button: str = 'left') -> None:
"""dragRel(offset, duration=0.0, button='left') - Drag mouse relative to current position. Accepts (x,y) tuple, [x,y] list, or Vector.""" """Drag the mouse relative to its current position."""
... ...
@staticmethod @staticmethod
def dragTo(self, *args, **kwargs) -> Any: def dragTo(pos: tuple | list | Vector, duration: float = 0.0, button: str = 'left') -> None:
"""dragTo(pos, duration=0.0, button='left') - Drag mouse to position. Accepts (x,y) tuple, [x,y] list, or Vector.""" """Drag the mouse from the current position to the specified position."""
... ...
@staticmethod @staticmethod
def hotkey(self, *args, **kwargs) -> Any: def hotkey(*keys: str) -> None:
"""hotkey(*keys) - Press a hotkey combination (e.g., hotkey('ctrl', 'c'))""" """Press a hotkey combination by pressing all keys in order then releasing in reverse."""
... ...
@staticmethod @staticmethod
def keyDown(self, *args, **kwargs) -> Any: def keyDown(key: str) -> None:
"""keyDown(key) - Press and hold a key""" """Press and hold a keyboard key."""
... ...
@staticmethod @staticmethod
def keyUp(self, *args, **kwargs) -> Any: def keyUp(key: str) -> None:
"""keyUp(key) - Release a key""" """Release a keyboard key."""
... ...
@staticmethod @staticmethod
def middleClick(self, *args, **kwargs) -> Any: def middleClick(pos: tuple | list | Vector | None = None) -> None:
"""middleClick(pos=None) - Middle click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Middle-click the mouse at the specified position."""
... ...
@staticmethod @staticmethod
def mouseDown(self, *args, **kwargs) -> Any: def mouseDown(pos: tuple | list | Vector | None = None, button: str = 'left') -> None:
"""mouseDown(pos=None, button='left') - Press mouse button at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Press and hold a mouse button at the specified position."""
... ...
@staticmethod @staticmethod
def mouseUp(self, *args, **kwargs) -> Any: def mouseUp(pos: tuple | list | Vector | None = None, button: str = 'left') -> None:
"""mouseUp(pos=None, button='left') - Release mouse button at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Release a mouse button at the specified position."""
... ...
@staticmethod @staticmethod
def moveRel(self, *args, **kwargs) -> Any: def moveRel(offset: tuple | list | Vector, duration: float = 0.0) -> None:
"""moveRel(offset, duration=0.0) - Move mouse relative to current position. Accepts (x,y) tuple, [x,y] list, or Vector.""" """Move the mouse cursor relative to its current position."""
... ...
@staticmethod @staticmethod
def moveTo(self, *args, **kwargs) -> Any: def moveTo(pos: tuple | list | Vector, duration: float = 0.0) -> None:
"""moveTo(pos, duration=0.0) - Move mouse to position. Accepts (x,y) tuple, [x,y] list, or Vector.""" """Move the mouse cursor to the specified position."""
... ...
@staticmethod @staticmethod
def onScreen(self, *args, **kwargs) -> Any: def onScreen(pos: tuple | list | Vector) -> bool:
"""onScreen(pos) - Check if position is within screen bounds. Accepts (x,y) tuple, [x,y] list, or Vector.""" """Check if a position is within the screen bounds."""
... ...
@staticmethod @staticmethod
def position(self, *args, **kwargs) -> Any: def position() -> Vector:
"""position() - Get current mouse position as Vector""" """Get the current mouse position as a Vector."""
... ...
@staticmethod @staticmethod
def rightClick(self, *args, **kwargs) -> Any: def rightClick(pos: tuple | list | Vector | None = None) -> None:
"""rightClick(pos=None) - Right click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Right-click the mouse at the specified position."""
... ...
@staticmethod @staticmethod
def screenshot(self, *args, **kwargs) -> Any: def screenshot(filename: str) -> bool:
"""screenshot(filename) - Save a screenshot to the specified file""" """Save a screenshot of the current render target to the specified file."""
... ...
@staticmethod @staticmethod
def scroll(self, *args, **kwargs) -> Any: def scroll(clicks: int, pos: tuple | list | Vector | None = None) -> None:
"""scroll(clicks, pos=None) - Scroll wheel at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Scroll the mouse wheel at the specified position."""
... ...
@staticmethod @staticmethod
def size(self, *args, **kwargs) -> Any: def size() -> Vector:
"""size() - Get screen size as Vector""" """Get the current screen (render target) size as a Vector."""
... ...
@staticmethod @staticmethod
def tripleClick(self, *args, **kwargs) -> Any: def tripleClick(pos: tuple | list | Vector | None = None) -> None:
"""tripleClick(pos=None) - Triple click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position.""" """Triple-click the mouse at the specified position."""
... ...
@staticmethod @staticmethod
def typewrite(self, *args, **kwargs) -> Any: def typewrite(message: str, interval: float = 0.0) -> None:
"""typewrite(message, interval=0.0) - Type text with optional interval between keystrokes""" """Type text by injecting keyboard events for each character."""
... ...
automation: _automation_module automation: _automation_module

View file

@ -254,17 +254,17 @@ submodule automation
[Arc] [Arc]
prop align: Any (rw) prop align: Any (rw)
prop bounds: Any (rw) prop bounds: Any (rw)
prop center: Any (rw) prop center: Vector (rw)
prop color: Any (rw) prop color: Color (rw)
prop end_angle: Any (rw) prop end_angle: float (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_pos: Any (rw) prop grid_pos: Vector (rw)
prop grid_size: Any (rw) prop grid_size: Vector (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_click: Any (rw) prop on_click: Any (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
@ -273,14 +273,14 @@ submodule automation
prop origin: Any (rw) prop origin: Any (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop pos: Any (rw) prop pos: Any (rw)
prop radius: Any (rw) prop radius: float (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop start_angle: Any (rw) prop start_angle: float (rw)
prop thickness: Any (rw) prop thickness: float (rw)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop visible: bool (rw) prop visible: bool (rw)
prop z_index: Any (rw) prop z_index: int (rw)
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
meth realign :: realign() -> None meth realign :: realign() -> None
@ -302,38 +302,38 @@ submodule automation
[Caption] [Caption]
prop align: Any (rw) prop align: Any (rw)
prop bounds: Any (rw) prop bounds: Any (rw)
prop fill_color: Any (rw) prop fill_color: Color (rw)
prop font_size: Any (rw) prop font_size: int (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_pos: Any (rw) prop grid_pos: Vector (rw)
prop grid_size: Any (rw) prop grid_size: Vector (rw)
prop h: Any (ro) prop h: float (ro)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_click: Any (rw) prop on_click: Any (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
prop on_move: Any (rw) prop on_move: Any (rw)
prop opacity: Any (rw) prop opacity: Any (rw)
prop origin: Any (rw) prop origin: Any (rw)
prop outline: Any (rw) prop outline: float (rw)
prop outline_color: Any (rw) prop outline_color: Color (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop pos: Any (rw) prop pos: Any (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop shader: Any (rw) prop shader: Any (rw)
prop size: Any (ro) prop size: Any (ro)
prop text: Any (rw) prop text: str (rw)
prop uniforms: Any (ro) prop uniforms: Any (ro)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop visible: bool (rw) prop visible: bool (rw)
prop w: Any (ro) prop w: float (ro)
prop x: Any (rw) prop x: float (rw)
prop y: Any (rw) prop y: float (rw)
prop z_index: Any (rw) prop z_index: Any (rw)
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
@ -342,32 +342,32 @@ submodule automation
[Circle] [Circle]
prop align: Any (rw) prop align: Any (rw)
prop bounds: Any (rw) prop bounds: Any (rw)
prop center: Any (rw) prop center: Vector (rw)
prop fill_color: Any (rw) prop fill_color: Color (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_pos: Any (rw) prop grid_pos: Vector (rw)
prop grid_size: Any (rw) prop grid_size: Vector (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_click: Any (rw) prop on_click: Callable | None (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
prop on_move: Any (rw) prop on_move: Any (rw)
prop opacity: Any (rw) prop opacity: Any (rw)
prop origin: Any (rw) prop origin: Any (rw)
prop outline: Any (rw) prop outline: float (rw)
prop outline_color: Any (rw) prop outline_color: Color (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop pos: Any (rw) prop pos: Vector (rw)
prop radius: Any (rw) prop radius: float (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop visible: bool (rw) prop visible: bool (rw)
prop z_index: Any (rw) prop z_index: int (rw)
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
meth realign :: realign() -> None meth realign :: realign() -> None
@ -381,29 +381,29 @@ submodule automation
meth lerp :: lerp(other: Color, t: float) -> Color meth lerp :: lerp(other: Color, t: float) -> Color
meth to_hex :: to_hex() -> str meth to_hex :: to_hex() -> str
[ColorLayer] [ColorLayer]
prop grid: Any (rw) prop grid: Grid | None (rw)
prop grid_size: Any (rw) prop grid_size: tuple (ro)
prop name: str (ro) prop name: str (ro)
prop visible: Any (rw) prop visible: bool (rw)
prop z_index: Any (rw) prop z_index: int (rw)
meth apply_gradient :: apply_gradient(source, range, color_low, color_high) -> ColorLayer meth apply_gradient :: apply_gradient(source: HeightMap, range: tuple, color_low: Color, color_high: Color) -> ColorLayer
meth apply_perspective :: apply_perspective(entity, visible=None, discovered=None, unknown=None) meth apply_perspective :: apply_perspective(entity: Entity, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None
meth apply_ranges :: apply_ranges(source, ranges) -> ColorLayer meth apply_ranges :: apply_ranges(source: HeightMap, ranges: list) -> ColorLayer
meth apply_threshold :: apply_threshold(source, range, color) -> ColorLayer meth apply_threshold :: apply_threshold(source: HeightMap, range: tuple, color: Color) -> ColorLayer
meth at :: at(pos) -> Color meth at :: at(pos) or (x: int, y: int) -> Color
meth clear_perspective :: clear_perspective() meth clear_perspective :: clear_perspective() -> None
meth draw_fov :: draw_fov(source, radius=None, fov=None, visible=None, discovered=None, unknown=None) meth draw_fov :: draw_fov(source: tuple, radius: int = None, fov: FOV = None, visible: Color = None, discovered: Color = None, unknown: Color = None) -> None
meth fill :: fill(color) meth fill :: fill(color: Color) -> None
meth fill_rect :: fill_rect(pos, size, color) meth fill_rect :: fill_rect(pos: tuple, size: tuple, color: Color) -> None
meth set :: set(pos, color) meth set :: set(pos, color: Color) -> None
meth update_perspective :: update_perspective() meth update_perspective :: update_perspective() -> None
[DijkstraMap] [DijkstraMap]
prop root: Vector (ro) prop root: Vector (ro)
meth descent_step :: descent_step(pos) -> Vector | None meth descent_step :: descent_step(pos: Vector | tuple) -> Vector | None
meth distance :: distance(pos) -> float | None meth distance :: distance(pos: Vector | tuple) -> float | None
meth invert :: invert() -> DijkstraMap meth invert :: invert() -> DijkstraMap
meth path_from :: path_from(pos) -> AStarPath meth path_from :: path_from(pos: Vector | tuple) -> AStarPath
meth step_from :: step_from(pos) -> Vector | None meth step_from :: step_from(pos: Vector | tuple) -> Vector | None
meth to_heightmap :: to_heightmap(size=None, unreachable=-1.0) -> HeightMap meth to_heightmap :: to_heightmap(size=None, unreachable=-1.0) -> HeightMap
[DiscreteMap] [DiscreteMap]
prop enum_type: Any (rw) prop enum_type: Any (rw)
@ -442,90 +442,90 @@ submodule automation
[Entity] [Entity]
prop behavior_type: int (ro) prop behavior_type: int (ro)
prop cell_pos: Vector (rw) prop cell_pos: Vector (rw)
prop cell_x: Any (rw) prop cell_x: int (rw)
prop cell_y: Any (rw) prop cell_y: int (rw)
prop default_behavior: int (rw) prop default_behavior: int (rw)
prop draw_pos: Vector (rw) prop draw_pos: Vector (rw)
prop grid: Any (rw) prop grid: Any (rw)
prop grid_pos: Vector (rw) prop grid_pos: Vector (rw)
prop grid_x: Any (rw) prop grid_x: int (rw)
prop grid_y: Any (rw) prop grid_y: int (rw)
prop labels: frozenset (rw) prop labels: frozenset (rw)
prop move_speed: float (rw) prop move_speed: float (rw)
prop name: Any (rw) prop name: str (rw)
prop opacity: Any (rw) prop opacity: float (rw)
prop perspective_map: DiscreteMap (rw) prop perspective_map: DiscreteMap (rw)
prop pos: Vector (rw) prop pos: Vector (rw)
prop shader: Any (rw) prop shader: Any (rw)
prop sight_radius: int (rw) prop sight_radius: int (rw)
prop sprite_grid: Any (rw) prop sprite_grid: Any (rw)
prop sprite_index: Any (rw) prop sprite_index: int (rw)
prop sprite_offset: Vector (rw) prop sprite_offset: Vector (rw)
prop sprite_offset_x: Any (rw) prop sprite_offset_x: float (rw)
prop sprite_offset_y: Any (rw) prop sprite_offset_y: float (rw)
prop step: Any (rw) prop step: Any (rw)
prop target_label: Any (rw) prop target_label: Any (rw)
prop texture: Texture (rw) prop texture: Texture (rw)
prop tile_height: int (rw) prop tile_height: int (rw)
prop tile_size: Any (rw) prop tile_size: Vector (rw)
prop tile_width: int (rw) prop tile_width: int (rw)
prop turn_order: int (rw) prop turn_order: int (rw)
prop uniforms: Any (ro) prop uniforms: UniformCollection (ro)
prop visible: Any (rw) prop visible: bool (rw)
prop x: Any (rw) prop x: float (rw)
prop y: Any (rw) prop y: float (rw)
meth add_label :: add_label(label: str) -> None meth add_label :: add_label(label: str) -> None
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth at :: at(x, y) or at(pos) -> GridPoint | None meth at :: at(x: int, y: int) -> GridPoint | None
meth die :: Remove this entity from its grid. meth die :: die() -> None
meth find_path :: find_path(target, diagonal_cost=1.41, collide=None) -> AStarPath | None meth find_path :: find_path(target, diagonal_cost: float = 1.41, collide: str = None) -> AStarPath | None
meth has_label :: has_label(label: str) -> bool meth has_label :: has_label(label: str) -> bool
meth index :: Return the index of this entity in its grid's entity collection meth index :: index() -> int
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
meth path_to :: path_to(x, y) or path_to(target) -> list meth path_to :: path_to(x: int, y: int) -> list
meth remove_label :: remove_label(label: str) -> None meth remove_label :: remove_label(label: str) -> None
meth resize :: resize(width, height) or (size) -> None meth resize :: resize(width, height) or (size) -> None
meth set_behavior :: set_behavior(type, waypoints=None, turns=0, path=None) -> None meth set_behavior :: set_behavior(type, waypoints=None, turns: int = 0, path=None, pathfinder=None) -> None
meth update_visibility :: update_visibility() -> None meth update_visibility :: update_visibility() -> None
meth visible_entities :: visible_entities(fov=None, radius=None) -> list[Entity] meth visible_entities :: visible_entities(fov=None, radius: int = None) -> list[Entity]
[Font] [Font]
prop family: str (ro) prop family: str (ro)
prop source: str (ro) prop source: str (ro)
[Frame] [Frame]
prop align: Any (rw) prop align: Any (rw)
prop bounds: Any (rw) prop bounds: Any (rw)
prop cache_subtree: Any (rw) prop cache_subtree: bool (rw)
prop children: Any (rw) prop children: UICollection (ro)
prop clip_children: Any (rw) prop clip_children: bool (rw)
prop fill_color: Any (rw) prop fill_color: Color (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_pos: Any (rw) prop grid_pos: Vector (rw)
prop grid_size: Any (rw) prop grid_size: Vector (rw)
prop h: Any (rw) prop h: float (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_click: Any (rw) prop on_click: Any (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
prop on_move: Any (rw) prop on_move: Any (rw)
prop opacity: Any (rw) prop opacity: Any (rw)
prop origin: Any (rw) prop origin: Any (rw)
prop outline: Any (rw) prop outline: float (rw)
prop outline_color: Any (rw) prop outline_color: Color (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop pos: Any (rw) prop pos: Vector (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop shader: Any (rw) prop shader: Any (rw)
prop uniforms: Any (ro) prop uniforms: Any (ro)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop visible: bool (rw) prop visible: bool (rw)
prop w: Any (rw) prop w: float (rw)
prop x: Any (rw) prop x: float (rw)
prop y: Any (rw) prop y: float (rw)
prop z_index: Any (rw) prop z_index: Any (rw)
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
@ -534,39 +534,39 @@ submodule automation
[Grid] [Grid]
prop align: Any (rw) prop align: Any (rw)
prop bounds: Any (rw) prop bounds: Any (rw)
prop camera_rotation: Any (rw) prop camera_rotation: float (rw)
prop center: Any (rw) prop center: tuple (rw)
prop center_x: Any (rw) prop center_x: float (rw)
prop center_y: Any (rw) prop center_y: float (rw)
prop fill_color: Any (rw) prop fill_color: Color (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_data: Any (rw) prop grid_data: Grid | None (rw)
prop h: Any (rw) prop h: float (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_click: Any (rw) prop on_click: Callable | None (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
prop on_move: Any (rw) prop on_move: Any (rw)
prop opacity: Any (rw) prop opacity: Any (rw)
prop origin: Any (rw) prop origin: Any (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop pos: Any (rw) prop pos: Vector (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop shader: Any (rw) prop shader: Any (rw)
prop texture: Any (ro) prop texture: Texture | None (ro)
prop uniforms: Any (ro) prop uniforms: Any (ro)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop visible: bool (rw) prop visible: bool (rw)
prop w: Any (rw) prop w: float (rw)
prop x: Any (rw) prop x: float (rw)
prop y: Any (rw) prop y: float (rw)
prop z_index: Any (rw) prop z_index: int (rw)
prop zoom: Any (rw) prop zoom: float (rw)
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
meth realign :: realign() -> None meth realign :: realign() -> None
@ -574,39 +574,39 @@ submodule automation
[GridView] [GridView]
prop align: Any (rw) prop align: Any (rw)
prop bounds: Any (rw) prop bounds: Any (rw)
prop camera_rotation: Any (rw) prop camera_rotation: float (rw)
prop center: Any (rw) prop center: tuple (rw)
prop center_x: Any (rw) prop center_x: float (rw)
prop center_y: Any (rw) prop center_y: float (rw)
prop fill_color: Any (rw) prop fill_color: Color (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_data: Any (rw) prop grid_data: Grid | None (rw)
prop h: Any (rw) prop h: float (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_click: Any (rw) prop on_click: Callable | None (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
prop on_move: Any (rw) prop on_move: Any (rw)
prop opacity: Any (rw) prop opacity: Any (rw)
prop origin: Any (rw) prop origin: Any (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop pos: Any (rw) prop pos: Vector (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop shader: Any (rw) prop shader: Any (rw)
prop texture: Any (ro) prop texture: Texture | None (ro)
prop uniforms: Any (ro) prop uniforms: Any (ro)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop visible: bool (rw) prop visible: bool (rw)
prop w: Any (rw) prop w: float (rw)
prop x: Any (rw) prop x: float (rw)
prop y: Any (rw) prop y: float (rw)
prop z_index: Any (rw) prop z_index: int (rw)
prop zoom: Any (rw) prop zoom: float (rw)
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
meth realign :: realign() -> None meth realign :: realign() -> None
@ -660,8 +660,8 @@ submodule automation
prop end: Any (rw) prop end: Any (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_pos: Any (rw) prop grid_pos: Vector (rw)
prop grid_size: Any (rw) prop grid_size: Vector (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
@ -767,12 +767,12 @@ submodule automation
prop bounds: Any (rw) prop bounds: Any (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_pos: Any (rw) prop grid_pos: Vector (rw)
prop grid_size: Any (rw) prop grid_size: Vector (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_click: Any (rw) prop on_click: Any (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
@ -780,20 +780,20 @@ submodule automation
prop opacity: Any (rw) prop opacity: Any (rw)
prop origin: Any (rw) prop origin: Any (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop pos: Any (rw) prop pos: Vector (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop scale: Any (rw) prop scale: float (rw)
prop scale_x: Any (rw) prop scale_x: float (rw)
prop scale_y: Any (rw) prop scale_y: float (rw)
prop shader: Any (rw) prop shader: Any (rw)
prop sprite_index: Any (rw) prop sprite_index: int (rw)
prop texture: Any (rw) prop texture: Texture (rw)
prop uniforms: Any (ro) prop uniforms: Any (ro)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop visible: bool (rw) prop visible: bool (rw)
prop x: Any (rw) prop x: float (rw)
prop y: Any (rw) prop y: float (rw)
prop z_index: Any (rw) prop z_index: Any (rw)
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
@ -814,18 +814,18 @@ submodule automation
meth from_bytes :: from_bytes(data: bytes, width: int, height: int, sprite_width: int, sprite_height: int, name: str = '<generated>') -> Texture meth from_bytes :: from_bytes(data: bytes, width: int, height: int, sprite_width: int, sprite_height: int, name: str = '<generated>') -> Texture
meth hsl_shift :: hsl_shift(hue_shift: float, sat_shift: float = 0.0, lit_shift: float = 0.0) -> Texture meth hsl_shift :: hsl_shift(hue_shift: float, sat_shift: float = 0.0, lit_shift: float = 0.0) -> Texture
[TileLayer] [TileLayer]
prop grid: Any (rw) prop grid: Grid | None (rw)
prop grid_size: Any (rw) prop grid_size: tuple (ro)
prop name: str (ro) prop name: str (ro)
prop texture: Any (rw) prop texture: Texture | None (rw)
prop visible: Any (rw) prop visible: bool (rw)
prop z_index: Any (rw) prop z_index: int (rw)
meth apply_ranges :: apply_ranges(source, ranges) -> TileLayer meth apply_ranges :: apply_ranges(source: HeightMap, ranges: list) -> TileLayer
meth apply_threshold :: apply_threshold(source, range, tile) -> TileLayer meth apply_threshold :: apply_threshold(source: HeightMap, range: tuple, tile: int) -> TileLayer
meth at :: at(pos) -> int meth at :: at(pos) or (x: int, y: int) -> int
meth fill :: fill(index) meth fill :: fill(index: int) -> None
meth fill_rect :: fill_rect(pos, size, index) meth fill_rect :: fill_rect(pos: tuple, size: tuple, index: int) -> None
meth set :: set(pos, index) meth set :: set(pos, index: int) -> None
[Timer] [Timer]
prop active: bool (rw) prop active: bool (rw)
prop callback: Callable (rw) prop callback: Callable (rw)
@ -1106,31 +1106,31 @@ submodule automation
[_GridData] [_GridData]
prop align: Any (rw) prop align: Any (rw)
prop bounds: Any (rw) prop bounds: Any (rw)
prop camera_rotation: Any (rw) prop camera_rotation: float (rw)
prop center: Any (rw) prop center: Vector (rw)
prop center_x: Any (rw) prop center_x: float (rw)
prop center_y: Any (rw) prop center_y: float (rw)
prop children: Any (rw) prop children: UICollection (ro)
prop entities: Any (rw) prop entities: EntityCollection (ro)
prop fill_color: Any (rw) prop fill_color: Color (rw)
prop fov: Any (rw) prop fov: Any (rw)
prop fov_radius: Any (rw) prop fov_radius: int (rw)
prop global_bounds: Any (rw) prop global_bounds: Any (rw)
prop global_position: Any (ro) prop global_position: Any (ro)
prop grid_h: Any (rw) prop grid_h: int (ro)
prop grid_pos: Any (rw) prop grid_pos: Vector (rw)
prop grid_size: Any (rw) prop grid_size: Vector (ro)
prop grid_w: Any (rw) prop grid_w: int (ro)
prop h: Any (rw) prop h: float (rw)
prop horiz_margin: float (rw) prop horiz_margin: float (rw)
prop hovered: Any (ro) prop hovered: Any (ro)
prop hovered_cell: Any (rw) prop hovered_cell: tuple | None (ro)
prop layers: ColorLayer (rw) prop layers: tuple (ro)
prop margin: float (rw) prop margin: float (rw)
prop name: Any (rw) prop name: str (rw)
prop on_cell_click: Any (rw) prop on_cell_click: Callable | None (rw)
prop on_cell_enter: Any (rw) prop on_cell_enter: Callable | None (rw)
prop on_cell_exit: Any (rw) prop on_cell_exit: Callable | None (rw)
prop on_click: Any (rw) prop on_click: Any (rw)
prop on_enter: Any (rw) prop on_enter: Any (rw)
prop on_exit: Any (rw) prop on_exit: Any (rw)
@ -1138,91 +1138,91 @@ submodule automation
prop opacity: Any (rw) prop opacity: Any (rw)
prop origin: Any (rw) prop origin: Any (rw)
prop parent: Any (rw) prop parent: Any (rw)
prop perspective: Any (rw) prop perspective: Entity | None (rw)
prop perspective_enabled: Any (rw) prop perspective_enabled: bool (rw)
prop pos: Any (rw) prop pos: Vector (rw)
prop rotate_with_camera: bool (rw) prop rotate_with_camera: bool (rw)
prop rotation: Any (rw) prop rotation: Any (rw)
prop shader: Any (rw) prop shader: Any (rw)
prop size: Any (rw) prop size: Vector (rw)
prop texture: Any (rw) prop texture: Texture | None (ro)
prop uniforms: Any (ro) prop uniforms: Any (ro)
prop vert_margin: float (rw) prop vert_margin: float (rw)
prop view: Any (ro) prop view: GridView | None (ro)
prop visible: bool (rw) prop visible: bool (rw)
prop w: Any (rw) prop w: float (rw)
prop x: Any (rw) prop x: float (rw)
prop y: Any (rw) prop y: float (rw)
prop z_index: Any (rw) prop z_index: Any (rw)
prop zoom: Any (rw) prop zoom: float (rw)
meth add_layer :: add_layer(layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer meth add_layer :: add_layer(layer: ColorLayer | TileLayer) -> ColorLayer | TileLayer
meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation meth animate :: animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> Animation
meth apply_ranges :: apply_ranges(source: HeightMap, ranges: list) -> Grid meth apply_ranges :: apply_ranges(source: HeightMap, ranges: list) -> Grid
meth apply_threshold :: apply_threshold(source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid meth apply_threshold :: apply_threshold(source: HeightMap, range: tuple, walkable: bool = None, transparent: bool = None) -> Grid
meth at :: <no-doc> meth at :: at(x: int, y: int) -> GridPoint
meth center_camera :: center_camera(pos: tuple = None) -> None meth center_camera :: center_camera(pos: tuple = None) -> None
meth clear_dijkstra_maps :: clear_dijkstra_maps() -> None meth clear_dijkstra_maps :: clear_dijkstra_maps() -> None
meth compute_fov :: compute_fov(pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None meth compute_fov :: compute_fov(pos, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None
meth entities_in_radius :: entities_in_radius(pos: tuple|Vector, radius: float) -> list[Entity] meth entities_in_radius :: entities_in_radius(pos: tuple | Vector, radius: float) -> list
meth find_path :: find_path(start, end, diagonal_cost=1.41, collide=None) -> AStarPath | None meth find_path :: find_path(start, end, diagonal_cost: float = 1.41, collide: str = None) -> AStarPath | None
meth get_dijkstra_map :: get_dijkstra_map(root, diagonal_cost=1.41, collide=None) -> DijkstraMap meth get_dijkstra_map :: get_dijkstra_map(root, diagonal_cost: float = 1.41, collide: str = None) -> DijkstraMap
meth is_in_fov :: is_in_fov(pos) -> bool meth is_in_fov :: is_in_fov(pos) -> bool
meth layer :: layer(name: str) -> ColorLayer | TileLayer | None meth layer :: layer(name: str) -> ColorLayer | TileLayer | None
meth move :: move(dx, dy) or (delta) -> None meth move :: move(dx, dy) or (delta) -> None
meth realign :: realign() -> None meth realign :: realign() -> None
meth remove_layer :: remove_layer(name_or_layer: str | ColorLayer | TileLayer) -> None meth remove_layer :: remove_layer(name_or_layer: str | ColorLayer | TileLayer) -> None
meth resize :: resize(width, height) or (size) -> None meth resize :: resize(width, height) or (size) -> None
meth step :: step(n=1, turn_order=None) -> None meth step :: step(n: int = 1, turn_order: int = None) -> None
[GridPoint] [GridPoint]
prop entities: Any (ro) prop entities: list (ro)
prop grid_pos: Any (ro) prop grid_pos: Any (ro)
prop transparent: Any (rw) prop transparent: bool (rw)
prop walkable: Any (rw) prop walkable: bool (rw)
[EntityCollection] [EntityCollection]
meth append :: append(entity) meth append :: append(entity: Entity) -> None
meth count :: count(entity) -> int meth count :: count(entity: Entity) -> int
meth extend :: extend(iterable) meth extend :: extend(iterable) -> None
meth find :: find(name) -> entity or list meth find :: find(name: str) -> Entity | list | None
meth index :: index(entity) -> int meth index :: index(entity: Entity) -> int
meth insert :: insert(index, entity) meth insert :: insert(index: int, entity: Entity) -> None
meth pop :: pop([index]) -> entity meth pop :: pop(index: int = -1) -> Entity
meth remove :: remove(entity) meth remove :: remove(entity: Entity) -> None
[UICollection] [UICollection]
meth append :: append(element) meth append :: append(element: Drawable) -> None
meth count :: count(element) -> int meth count :: count(element: Drawable) -> int
meth extend :: extend(iterable) meth extend :: extend(iterable) -> None
meth find :: find(name, recursive=False) -> element or list meth find :: find(name: str, recursive: bool = False) -> Drawable | list | None
meth index :: index(element) -> int meth index :: index(element: Drawable) -> int
meth insert :: insert(index, element) meth insert :: insert(index: int, element: Drawable) -> None
meth pop :: pop([index]) -> element meth pop :: pop(index: int = -1) -> Drawable
meth remove :: remove(element) meth remove :: remove(element: Drawable) -> None
[UniformCollection] [UniformCollection]
meth clear :: Remove all uniforms meth clear :: clear() -> None
meth items :: Return list of (name, value) tuples meth items :: items() -> list
meth keys :: Return list of uniform names meth keys :: keys() -> list
meth values :: Return list of uniform values meth values :: values() -> list
=== AUTOMATION (PyAutoGUI-compat, snake_case-exempt) === === AUTOMATION (PyAutoGUI-compat, snake_case-exempt) ===
func click :: click(pos=None, clicks=1, interval=0.0, button='left') - Click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func click :: click(pos: tuple | list | Vector | None = None, clicks: int = 1, interval: float = 0.0, button: str = 'left') -> None
func doubleClick :: doubleClick(pos=None) - Double click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func doubleClick :: doubleClick(pos: tuple | list | Vector | None = None) -> None
func dragRel :: dragRel(offset, duration=0.0, button='left') - Drag mouse relative to current position. Accepts (x,y) tuple, [x,y] list, or Vector. func dragRel :: dragRel(offset: tuple | list | Vector, duration: float = 0.0, button: str = 'left') -> None
func dragTo :: dragTo(pos, duration=0.0, button='left') - Drag mouse to position. Accepts (x,y) tuple, [x,y] list, or Vector. func dragTo :: dragTo(pos: tuple | list | Vector, duration: float = 0.0, button: str = 'left') -> None
func hotkey :: hotkey(*keys) - Press a hotkey combination (e.g., hotkey('ctrl', 'c')) func hotkey :: hotkey(*keys: str) -> None
func keyDown :: keyDown(key) - Press and hold a key func keyDown :: keyDown(key: str) -> None
func keyUp :: keyUp(key) - Release a key func keyUp :: keyUp(key: str) -> None
func middleClick :: middleClick(pos=None) - Middle click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func middleClick :: middleClick(pos: tuple | list | Vector | None = None) -> None
func mouseDown :: mouseDown(pos=None, button='left') - Press mouse button at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func mouseDown :: mouseDown(pos: tuple | list | Vector | None = None, button: str = 'left') -> None
func mouseUp :: mouseUp(pos=None, button='left') - Release mouse button at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func mouseUp :: mouseUp(pos: tuple | list | Vector | None = None, button: str = 'left') -> None
func moveRel :: moveRel(offset, duration=0.0) - Move mouse relative to current position. Accepts (x,y) tuple, [x,y] list, or Vector. func moveRel :: moveRel(offset: tuple | list | Vector, duration: float = 0.0) -> None
func moveTo :: moveTo(pos, duration=0.0) - Move mouse to position. Accepts (x,y) tuple, [x,y] list, or Vector. func moveTo :: moveTo(pos: tuple | list | Vector, duration: float = 0.0) -> None
func onScreen :: onScreen(pos) - Check if position is within screen bounds. Accepts (x,y) tuple, [x,y] list, or Vector. func onScreen :: onScreen(pos: tuple | list | Vector) -> bool
func position :: position() - Get current mouse position as Vector func position :: position() -> Vector
func rightClick :: rightClick(pos=None) - Right click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func rightClick :: rightClick(pos: tuple | list | Vector | None = None) -> None
func screenshot :: screenshot(filename) - Save a screenshot to the specified file func screenshot :: screenshot(filename: str) -> bool
func scroll :: scroll(clicks, pos=None) - Scroll wheel at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func scroll :: scroll(clicks: int, pos: tuple | list | Vector | None = None) -> None
func size :: size() - Get screen size as Vector func size :: size() -> Vector
func tripleClick :: tripleClick(pos=None) - Triple click at position. Accepts (x,y) tuple, [x,y] list, Vector, or None for current position. func tripleClick :: tripleClick(pos: tuple | list | Vector | None = None) -> None
func typewrite :: typewrite(message, interval=0.0) - Type text with optional interval between keystrokes func typewrite :: typewrite(message: str, interval: float = 0.0) -> None
=== DELEGATION INTEGRITY (Grid instance -> _GridData) === === DELEGATION INTEGRITY (Grid instance -> _GridData) ===
delegated-resolved: 69/69 delegated-resolved: 69/69