Finished automatically generated docs
Time to correct it by itself
This commit is contained in:
438
docs/en/reference/MATRIX.md
Normal file
438
docs/en/reference/MATRIX.md
Normal file
@@ -0,0 +1,438 @@
|
||||
# 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)).
|
||||
Reference in New Issue
Block a user