Files
Patryk Gensch 198d9cf477 Finished automatically generated docs
Time to correct it by itself
2026-05-20 22:49:46 +02:00

439 lines
9.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MATRIX
A rectangular grid of cells with a small built-in stone-falling physics system and primitive enemy pathfinding. Designed around a single use case — the digging minigame (Kretes sections in *Reksio i Ufo*: the wall on Indor and the prison-tunnel on Kuran).
Grid data lives in a one-dimensional array of integers — a cell's address is computed as `index = y * width + x`. Hence the family of methods that converts between linear index and 2D position.
## Field codes
Values used by [`GET`](#get), [`GETCELLSNO`](#getcellsno), [`SET`](#set), [`SETROW`](#setrow) and the internal physics system:
| Code | Meaning |
| --- | --- |
| `0` | empty cell |
| `1` | ground |
| `2` | stone |
| `3` | dynamite stick |
| `4` | weak (destructible) wall |
| `5` | enemy |
| `6` | strong (indestructible) wall |
| `7` | lit dynamite stick |
| `8` | cell within blast radius |
| `9` | exit |
| `99` | Kretes' position |
## Movement direction codes
Values used by [`TICK`](#tick), [`NEXT`](#next), and [`CALCENEMYMOVEDIR`](#calcenemymovedir):
| Code | Direction |
| --- | --- |
| `0` | left |
| `1` | up |
| `2` | right |
| `3` | down |
The physics system uses additional codes returned by [`TICK`](#tick) and consumed by [`NEXT`](#next):
| Code | Operation |
| --- | --- |
| `1` | stone falls down |
| `2` | stone slides diagonally to the left |
| `3` | stone slides diagonally to the right |
| `4` | stone collides with an enemy and explodes |
## Fields
### BASEPOS
```
INTEGER, INTEGER BASEPOS
```
Pixel position of the grid's top-left corner on screen (`X,Y`).
### CELLHEIGHT
```
INTEGER CELLHEIGHT
```
Height of a single cell in pixels.
### CELLWIDTH
```
INTEGER CELLWIDTH
```
Width of a single cell in pixels.
### SIZE
```
INTEGER, INTEGER SIZE
```
Grid dimensions in cells (`width,height`). The value also dictates the size of the internal field-code array.
## Methods
### CALCENEMYMOVEDEST
```
INTEGER CALCENEMYMOVEDEST(INTEGER oldCell, INTEGER direction)
```
Computes the destination cell for an enemy moving from `oldCell` in the given `direction`. If the target cell is out of bounds or not empty, `oldCell` is returned unchanged.
**Parameters**
- `oldCell` — the enemy's current cell index.
- `direction` — movement direction (`0``3`, see [Movement direction codes](#movement-direction-codes)).
**Returns**: [`INTEGER`](INTEGER.md) — destination cell index.
**Examples**
```
MAT^CALCENEMYMOVEDEST(IENOLDCELL,IENNEWDIR);
```
### CALCENEMYMOVEDIR
```
INTEGER CALCENEMYMOVEDIR(INTEGER oldCell, INTEGER oldDir)
```
Computes the next movement direction for an enemy. The algorithm prefers turning left: it first checks `(oldDir+3) MOD 4`, then `oldDir`, then right, and finally backwards. The first direction whose target cell is empty is returned; if none is available, the leftward direction is returned anyway.
**Parameters**
- `oldCell` — the enemy's current cell index.
- `oldDir` — the previous-step movement direction.
**Returns**: [`INTEGER`](INTEGER.md) — the new movement direction.
**Examples**
```
MAT^CALCENEMYMOVEDIR(IENOLDCELL,IENOLDDIR);
```
### CANHEROGOTO
```
BOOL CANHEROGOTO(INTEGER cellNo)
```
Checks whether the protagonist can step onto the given cell. A cell is walkable if it does not contain a weak wall, strong wall, enemy or stone, and is not part of a gate area set with [`SETGATE`](#setgate).
**Parameters**
- `cellNo` — index of the cell to check.
**Returns**: [`BOOL`](BOOL.md) — `TRUE` if the cell is walkable.
**Examples**
```
MAT^CANHEROGOTO(I_0);
```
### GET
```
INTEGER GET(INTEGER cellNo)
```
Returns the field code of the cell at the given index. For out-of-range indices returns `0`.
**Parameters**
- `cellNo` — cell index.
**Returns**: [`INTEGER`](INTEGER.md) — field code (see [Field codes](#field-codes)).
**Examples**
```
MAT^GET(I_ITERATOR);
MAT^GET(I_MOLE_FIELD_CURR);
```
### GETCELLOFFSET
```
INTEGER GETCELLOFFSET(INTEGER x, INTEGER y)
```
Returns the cell index for the given `(x, y)` grid coordinates. Returns `-1` if the coordinates fall outside the grid.
**Parameters**
- `x`, `y` — grid coordinates.
**Returns**: [`INTEGER`](INTEGER.md) — the cell index or `-1`.
**Examples**
```
MAT^GETCELLOFFSET(ISSRCX,ISSRCY);
MAT^GETCELLOFFSET(ISTRGX,ISTRGY);
```
### GETCELLPOSX
```
INTEGER GETCELLPOSX(INTEGER cellNo)
```
Returns the cell's X position in pixels (`BASEPOS.X + col * CELLWIDTH`).
**Parameters**
- `cellNo` — cell index.
**Returns**: [`INTEGER`](INTEGER.md) — X coordinate in pixels.
### GETCELLPOSY
```
INTEGER GETCELLPOSY(INTEGER cellNo)
```
Returns the cell's Y position in pixels (`BASEPOS.Y + row * CELLHEIGHT`).
**Parameters**
- `cellNo` — cell index.
**Returns**: [`INTEGER`](INTEGER.md) — Y coordinate in pixels.
### GETCELLSNO
```
INTEGER GETCELLSNO(INTEGER cellCode)
```
Returns the number of cells with the given field code.
**Parameters**
- `cellCode` — the field code to count.
**Returns**: [`INTEGER`](INTEGER.md) — number of matching cells.
**Examples**
```
MAT^GETCELLSNO(IC_FIELD_CODE_EXIT);
MAT^GETCELLSNO(IC_FIELD_CODE_ENEMY);
```
### GETFIELDPOSX
```
INTEGER GETFIELDPOSX(INTEGER cellNo)
```
Alias of [`GETCELLPOSX`](#getcellposx), used in *Reksio i Ufo* with the Piklib 7.1 engine. Piklib 8 no longer ships this method — calling it crashes the engine.
**Parameters**
- `cellNo` — cell index.
**Returns**: [`INTEGER`](INTEGER.md) — X coordinate in pixels.
### GETFIELDPOSY
```
INTEGER GETFIELDPOSY(INTEGER cellNo)
```
Alias of [`GETCELLPOSY`](#getcellposy), used in *Reksio i Ufo* with the Piklib 7.1 engine. Piklib 8 no longer ships this method — calling it crashes the engine.
**Parameters**
- `cellNo` — cell index.
**Returns**: [`INTEGER`](INTEGER.md) — Y coordinate in pixels.
### GETOFFSET
```
INTEGER GETOFFSET(INTEGER x, INTEGER y)
```
Alias of [`GETCELLOFFSET`](#getcelloffset), used in *Reksio i Ufo* with the Piklib 7.1 engine. Piklib 8 replaces it with `GETCELLOFFSET`.
**Parameters**
- `x`, `y` — grid coordinates.
**Returns**: [`INTEGER`](INTEGER.md) — cell index or `-1`.
### ISGATEEMPTY
```
BOOL ISGATEEMPTY()
```
Checks whether all cells in the gate area set with [`SETGATE`](#setgate) have field code `0` (empty). Returns `FALSE` if no gate has been set.
**Returns**: [`BOOL`](BOOL.md) — `TRUE` if all gate cells are empty.
**Examples**
```
MAT^ISGATEEMPTY();
```
### ISINGATE
```
BOOL ISINGATE(INTEGER cellNo)
```
Checks whether the cell at the given index belongs to the gate area set with [`SETGATE`](#setgate).
**Parameters**
- `cellNo` — cell index.
**Returns**: [`BOOL`](BOOL.md) — `TRUE` if the cell is inside the gate area.
### MOVE
```
void MOVE(INTEGER oldCell, INTEGER newCell)
```
Moves the contents of the source cell to the destination cell; the source cell becomes empty (code `0`).
**Parameters**
- `oldCell` — source cell index.
- `newCell` — destination cell index.
**Examples**
```
MAT^MOVE(I_0,I_1);
```
### NEXT
```
INTEGER NEXT()
```
Executes the next queued move generated by [`TICK`](#tick). The source cell is cleared and the destination cell receives the stone code. After the move the [`ONNEXT`](#onnext) signal is emitted for every move except the last one in the queue, which fires [`ONLATEST`](#onlatest) instead.
**Returns**: [`INTEGER`](INTEGER.md) — `0` if the queue is empty; `1` for an ordinary stone move; `2` if the stone has come to rest two cells above Kretes (collision).
**Examples**
```
MAT^NEXT();
```
### SET
```
void SET(INTEGER cellNo, INTEGER cellCode)
void SET(INTEGER x, INTEGER y, INTEGER cellCode)
```
Sets a cell's field code. Two forms are accepted: the first takes a precomputed cell index, the second takes `(x, y)` coordinates.
**Parameters**
- `cellNo` — cell index **(form 1)**.
- `x`, `y` — cell coordinates **(form 2)**.
- `cellCode` — new field code (see [Field codes](#field-codes)).
**Examples**
```
MAT^SET(I_MOLE_FIELD_CURR,IC_FIELD_CODE_EMPTY);
MAT^SET([I_FIELD_INDEX%I_LEVEL_WIDTH],[I_FIELD_INDEX@I_LEVEL_WIDTH],IC_FIELD_CODE_EMPTY);
```
### SETGATE
```
void SETGATE(INTEGER startX, INTEGER startY, INTEGER endX, INTEGER endY)
```
Defines a rectangular gate area, inclusive of both corners. The gate affects [`CANHEROGOTO`](#canherogoto), [`ISGATEEMPTY`](#isgateempty), and [`ISINGATE`](#isingate).
**Parameters**
- `startX`, `startY` — coordinates of the gate's top-left corner.
- `endX`, `endY` — coordinates of the gate's bottom-right corner.
**Examples**
```
MAT^SETGATE(3,1,16,4);
```
### SETROW
```
void SETROW(INTEGER row, INTEGER cellCode1, [INTEGER cellCode2, ...])
```
Sets field codes for all cells in the given row, starting from column `0`. Excess arguments (beyond the grid's width) are ignored.
**Parameters**
- `row` — row index.
- `cellCode1`, `cellCode2`, … — field codes for successive cells in the row.
**Examples**
```
MAT^SETROW(0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6);
MAT^SETROW(1,6,6,6,2,2,2,2,2,2,2,2,2,2,2,2,2,2,6,6,6);
```
### TICK
```
void TICK()
```
Executes one physics tick. The grid is scanned bottom-to-top, left-to-right. For each stone the following cases are checked in order:
1. Is the cell directly below empty — schedule a downward move.
2. Is the cell below an enemy — schedule an explosion.
3. Are the diagonally adjacent cells (and the lateral neighbour) empty — schedule a diagonal slide.
Scheduled moves are appended to an internal queue and executed one-by-one by [`NEXT`](#next). Each entry records the source cell's X and Y, plus the operation code.
**Examples**
```
MAT^TICK();
```
## Signals
### ONINIT
Fired when the object is initialised.
### ONNEXT
Fired by [`NEXT`](#next) after a move that was not the last in the current queue. Signal arguments are the source cell's X (`$1`), Y (`$2`) and operation code (`$3`).
### ONLATEST
Fired by [`NEXT`](#next) after the last queued move. Arguments are identical to [`ONNEXT`](#onnext).
### ONSIGNAL
Fired when a signal arrives (see [Events and signals](../engine/events.md#onsignal)).