add entities.raycast & update docs structure

This commit is contained in:
MihailRis
2024-07-15 05:42:09 +03:00
parent 23cfe4a4cf
commit 9cdf3e29cc
9 changed files with 389 additions and 348 deletions
+3 -3
View File
@@ -82,12 +82,12 @@ Block is not a physical obstacle if **false**
An array of 6 numbers describing an offset an size of a block hitbox. An array of 6 numbers describing an offset an size of a block hitbox.
Array *\[0.25, 0.0, 0.5, 0.75, 0.4, 0.3\]* describes hitbox width: Array *\[0.25, 0.0, 0.5, 0.75, 0.4, 0.3\]* describes hitbox width:
- 0.75m width (from east to west)
- 0.4m height
- 0.3m length (from south to north)
- offset 0.25m east - offset 0.25m east
- offset 0.0m up - offset 0.0m up
- offset 0.5m north - offset 0.5m north
- 0.75m width (from east to west)
- 0.4m height
- 0.3m length (from south to north)
### *grounded* ### *grounded*
+2 -161
View File
@@ -9,6 +9,8 @@ Subsections:
- [UI properties and methods](scripting/ui.md) - [UI properties and methods](scripting/ui.md)
- [Entities and components](scripting/ecs.md) - [Entities and components](scripting/ecs.md)
- [Libraries](#) - [Libraries](#)
- [block](scripting/builtins/libblock.md)
- [entities](scripting/builtins/libentities.md)
- [mat4](scripting/builtins/libmat4.md) - [mat4](scripting/builtins/libmat4.md)
- [Module core:bit_converter](scripting/modules/core_bit_converter.md) - [Module core:bit_converter](scripting/modules/core_bit_converter.md)
- [Module core:data_buffer](scripting/modules/core_data_buffer.md) - [Module core:data_buffer](scripting/modules/core_data_buffer.md)
@@ -337,167 +339,6 @@ inventory.move(invA: int, slotA: int, invB: int, slotB: int)
Move item from slotA of invA to slotB of invB. invA may be the same as invB. Move item from slotA of invA to slotB of invB. invA may be the same as invB.
If slotB will be chosen automaticly if argument is not specified. If slotB will be chosen automaticly if argument is not specified.
## *block* library
```python
block.name(blockid: int) -> str
```
Returns block string ID (name) by index.
```python
block.index(name: str) -> int
```
Returns block integer ID (index) by name.
```python
block.material(blockid: int) -> str
```
Returns the id of the block material.
```python
block.caption(blockid: int) -> str
```
Returns the block name displayed in the interface.
```python
block.get(x: int, y: int, z: int) -> int
```
Returns integer ID by block position
```python
block.get_states(x: int, y: int, z: int) -> int
```
Returns block state (rotation + additional information) as an integer.
```python
block.set(x: int, y: int, z: int, id: int, states: int)
```
Set block with specified integer ID and state (default - 0) at specified position.
> [!WARNING]
> `block.set` does not trigger on_placed.
```python
block.is_solid_at(x: int, y: int, z: int) -> bool
```
Check if block at the specified position is solid.
```python
block.is_replaceable_at(x: int, y: int, z: int) -> bool
```
Check if block may be placed at specified position. (Examples: air, water, grass, flower)
```python
block.defs_count() -> int
```
Returns count of available block IDs.
Following three functions return direction vectors based on block rotation.
```python
block.get_X(x: int, y: int, z: int) -> int, int, int
```
Returns X: integer direction vector of the block at specified coordinates.
Example: no rotation: 1, 0, 0
```python
block.get_Y(x: int, y: int, z: int) -> int, int, int
```
Returns Y: integer direction vector of the block at specified coordinates.
Example: no rotation: 0, 1, 0
```python
block.get_Z(x: int, y: int, z: int) -> int, int, int
```
Returns Z: integer direction vector of the block at specified coordinates.
Example: no rotation: 0, 0, 1
```python
block.get_rotation(x: int, y: int, z: int) -> int
```
Returns block rotation index based on used profile.
```python
block.set_rotation(x: int, y: int, z: int, rotation: int)
```
Set block rotation by index.
### Extended blocks
Extended blocks are blocks with size greather than 1x1x1
```python
block.is_extended(id: int) -> bool
```
Checks whether the block is extended.
```python
block.get_size(id: int) -> int, int, int
```
Returns the block size.
```python
block.is_segment(x: int, y: int, z: int) -> bool
```
Checks whether the block is a non-origin segment of an extended block.
```python
block.seek_origin(x: int, y: int, z: int) -> int, int, int
```
Returns the position of the main segment of an extended block or the original position,
if the block is not extended.
### User bits
Part of a voxel data used for scripting. Size: 8 bit.
```python
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
```
Get specified bits as an unsigned integer.
```python
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
```
Set specified bits.
```lua
block.raycast(start: vec3, dir: vec3, max_distance: number, [optional] dest: table) -> {
block: int, -- block id
endpoint: vec3, -- point of the ray hit point
iendpoint: vec3, -- position of the block hit by the ray
length: number, -- ray length
normal: vec3 -- normal vector of the surface hit by the ray
} or nil
```
Casts a ray from the start point in the direction of *dir*. Max_distance specifies the maximum ray length.
The function returns a table with the results or nil if the ray does not hit any block.
The result will use the destination table instead of creating a new one if the optional argument specified.
## *item* library ## *item* library
```python ```python
+115
View File
@@ -0,0 +1,115 @@
# *block* library
```lua
-- Returns block string ID (name) by index.
block.name(blockid: int) -> str
-- Returns block integer ID (index) by name.
block.index(name: str) -> int
-- Returns the id of the block material.
block.material(blockid: int) -> str
-- Returns the block name displayed in the UI.
block.caption(blockid: int) -> str
-- Returns integer ID by block position
block.get(x: int, y: int, z: int) -> int
-- Returns block state (rotation + additional information) as an integer.
-- Used to save complete block information.
block.get_states(x: int, y: int, z: int) -> int
-- Set block with specified integer ID and state (default - 0) at specified position.
block.set(x: int, y: int, z: int, id: int, states: int)
```
> [!WARNING]
> `block.set` does not trigger on_placed.
```lua
-- Check if block at the specified position is solid.
block.is_solid_at(x: int, y: int, z: int) -> bool
-- Check if block may be placed at specified position.
-- (Examples: air, water, grass, flower)
block.is_replaceable_at(x: int, y: int, z: int) -> bool
-- Returns count of available block IDs.
block.defs_count() -> int
```
## Rotation
Following three functions return direction vectors based on block rotation.
```lua
-- Returns X: integer direction vector of the block at specified coordinates.
-- Example: no rotation: 1, 0, 0.
block.get_X(x: int, y: int, z: int) -> int, int, int
-- Same for axis Y. Default: 0, 1, 0.
block.get_Y(x: int, y: int, z: int) -> int, int, int
-- Same for axis Z. Default: 0, 0, 1.
block.get_Z(x: int, y: int, z: int) -> int, int, int
-- Returns block rotation index based on used profile.
block.get_rotation(x: int, y: int, z: int) -> int
-- Set block rotation by index.
block.set_rotation(x: int, y: int, z: int, rotation: int)
```
## Extended blocks
Extended blocks are blocks with size greather than 1x1x1
```lua
-- Checks whether the block is extended.
block.is_extended(id: int) -> bool
-- Returns the block size.
block.get_size(id: int) -> int, int, int
-- Checks whether the block is a non-origin segment of an extended block.
block.is_segment(x: int, y: int, z: int) -> bool
-- Returns the position of the main segment of an extended block
-- or the original position, if the block is not extended.
block.seek_origin(x: int, y: int, z: int) -> int, int, int
```
## User bits
Part of a voxel data used for scripting. Size: 8 bit.
```python
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
```
Get specified bits as an unsigned integer.
```python
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
```
Set specified bits.
## Raycast
```lua
block.raycast(start: vec3, dir: vec3, max_distance: number, [optional] dest: table) -> {
block: int, -- block id
endpoint: vec3, -- point of the ray hit point
iendpoint: vec3, -- position of the block hit by the ray
length: number, -- ray length
normal: vec3 -- normal vector of the surface hit by the ray
} or nil
```
Casts a ray from the start point in the direction of *dir*. Max_distance specifies the maximum ray length.
The function returns a table with the results or nil if the ray does not hit any block.
The result will use the destination table instead of creating a new one if the optional argument specified.
+26
View File
@@ -0,0 +1,26 @@
# Library *entities*
The library is designed to work with a registry of entities.
```lua
-- Returns an entity by unique identifier
-- The table returned is the same one available in the entity components.
entities.get(uid: int) -> table
-- Creates the specified entity.
-- args - table of component parameter tables (ARGS variable)
-- args is optional
entities.spawn(name: str, pos: vec3, [optional] args: table)
-- Checks the existence of an entity by a unique identifier.
entities.exists(uid: int) -> bool
```
```lua
entities.raycast(start: vec3, dir: vec3, max_distance: number,
ignore: int, [optional] destination: table) -> table or nil
```
The function is an extended version of [block.raycast](libblock.md#raycast). Returns a table with the results if the ray touches a block or entity.
Accordingly, this will affect the presence of the *entity* and *block* fields.
+3 -3
View File
@@ -87,12 +87,12 @@
Числа указываются в диапазоне [0.0, 1.0] - т.е в пределах блока. Числа указываются в диапазоне [0.0, 1.0] - т.е в пределах блока.
Массив `[0.25, 0.0, 0.5, 0.75, 0.4, 0.3]` описывает хитбокс: Массив `[0.25, 0.0, 0.5, 0.75, 0.4, 0.3]` описывает хитбокс:
- шириной (с востока на запад) 0.75 м
- высотой 0.4 м
- длиной (с юга на север) 0.3 м
- смещен на 0.25 м на запад - смещен на 0.25 м на запад
- смещен на 0.0 м вверх - смещен на 0.0 м вверх
- смещен на 0.5 м на север - смещен на 0.5 м на север
- шириной (с востока на запад) 0.75 м
- высотой 0.4 м
- длиной (с юга на север) 0.3 м
### Приземленность - *grounded* ### Приземленность - *grounded*
+3 -180
View File
@@ -9,7 +9,10 @@
- [Свойства и методы UI элементов](scripting/ui.md) - [Свойства и методы UI элементов](scripting/ui.md)
- [Сущности и компоненты](scripting/ecs.md) - [Сущности и компоненты](scripting/ecs.md)
- [Библиотеки](#) - [Библиотеки](#)
- [block](scripting/builtins/libblock.md)
- [entities](scripting/builtins/libentities.md)
- [mat4](scripting/builtins/libmat4.md) - [mat4](scripting/builtins/libmat4.md)
- [vec2, vec3, vec4](scripting/builtins/libvecn.md)
- [Модуль core:bit_converter](scripting/modules/core_bit_converter.md) - [Модуль core:bit_converter](scripting/modules/core_bit_converter.md)
- [Модуль core:data_buffer](scripting/modules/core_data_buffer.md) - [Модуль core:data_buffer](scripting/modules/core_data_buffer.md)
- [Модули core:vector2, core:vector3](scripting/modules/core_vector2_vector3.md) - [Модули core:vector2, core:vector3](scripting/modules/core_vector2_vector3.md)
@@ -332,186 +335,6 @@ inventory.move(invA: int, slotA: int, invB: int, slotB: int)
invA и invB могут указывать на один инвентарь. invA и invB могут указывать на один инвентарь.
slotB будет выбран автоматически, если не указывать явно. slotB будет выбран автоматически, если не указывать явно.
## Библиотека *block*
```python
block.name(blockid: int) -> str
```
Возвращает строковый id блока по его числовому id.
```python
block.index(name: str) -> int
```
Возвращает числовой id блока, принимая в качестве агрумента строковый.
```python
block.material(blockid: int) -> str
```
Возвращает id материала блока.
```python
block.caption(blockid: int) -> str
```
Возвращает название блока, отображаемое в интерфейсе.
```python
block.get(x: int, y: int, z: int) -> int
```
Возвращает числовой id блока на указанных координатах. Если чанк на указанных координатах не загружен, возвращает -1.
```python
block.get_states(x: int, y: int, z: int) -> int
```
Возвращает состояние (поворот + доп. информация) в виде целого числа
```python
block.set(x: int, y: int, z: int, id: int, states: int)
```
Устанавливает блок с заданным числовым id и состоянием (0 - по-умолчанию) на заданных координатах.
> [!WARNING]
> `block.set` не вызывает событие on_placed.
```python
block.is_solid_at(x: int, y: int, z: int) -> bool
```
Проверяет, является ли блок на указанных координатах полным
```python
block.is_replaceable_at(x: int, y: int, z: int) -> bool
```
Проверяет, можно ли на заданных координатах поставить блок (примеры: воздух, трава, цветы, вода)
```python
block.defs_count() -> int
```
Возвращает количество id доступных в движке блоков
```python
block.get_picking_item(id: int) -> int
```
Возвращает числовой id предмета, указанного в свойстве *picking-item*.
```lua
block.raycast(start: vec3, dir: vec3, max_distance: number, [опционально] dest: table) -> {
block: int, -- id блока
endpoint: vec3, -- точка касания луча
iendpoint: vec3, -- позиция блока, которого касается луч
length: number, -- длина луча
normal: vec3 -- вектор нормали поверхности, которой касается луч
} или nil
```
Бросает луч из точки start в направлении dir. Max_distance указывает максимальную длину луча.
Функция возвращает таблицу с результатами или nil, если луч не касается блока.
Для результата будет использоваться целевая (dest) таблица вместо создания новой, если указан опциональный аргумент.
### Вращение
Следующие функции используется для учёта вращения блока при обращении к соседним блокам или других целей, где направление блока имеет решающее значение.
```lua
-- Возвращает целочисленный единичный вектор X блока на указанных координатах с учётом его вращения (три целых числа).
-- Если поворот отсутствует, возвращает 1, 0, 0
block.get_X(x: int, y: int, z: int) -> int, int, int
-- То же, но для оси Y (по-умолчанию 0, 1, 0)
block.get_Y(x: int, y: int, z: int) -> int, int, int
-- То же, но для оси Z (по-умолчанию 0, 0, 1)
block.get_Z(x: int, y: int, z: int) -> int, int, int
-- Возвращает индекс поворота блока в его профиле вращения (не превышает 7).
block.get_rotation(x: int, y: int, z: int) -> int
-- Устанавливает вращение блока по индексу в его профиле вращения.
block.set_rotation(x: int, y: int, z: int, rotation: int)
-- Возвращает имя профиля вращения (none/pane/pipe)
block.get_rotation_profile(id: int) -> str
```
### Расширенные блоки
Расширенные блоки - те, размер которых превышает 1x1x1
```python
block.is_extended(id: int) -> bool
```
Проверяет, является ли блок расширенным.
```python
block.get_size(id: int) -> int, int, int
```
Возвращает размер блока.
```python
block.is_segment(x: int, y: int, z: int) -> bool
```
Проверяет является ли блок сегментом расширенного блока, не являющимся главным.
```python
block.seek_origin(x: int, y: int, z: int) -> int, int, int
```
Возвращает позицию главного сегмента расширенного блока или исходную позицию,
если блок не являющийся расширенным.
### Пользовательские биты
Выделенная под использования в скриптах часть поля `voxel.states` хранящего доп-информацию о вокселе, такую как вращение блока. На данный момент выделенная часть составляет 8 бит.
```python
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
```
Возвращает выбранное число бит с указанного смещения в виде целого беззнакового числа
```python
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
```
Записывает указанное число бит значения value в user bits по выбранному смещению
### Физика
Информация свойствах блока, используемых физическим движком.
```lua
-- Возвращает массив из двух векторов (массивов из 3 чисел):
-- 1. Минимальная точка хитбокса
-- 2. Размер хитбокса
-- rotation_index - индекс поворота блока
block.get_hitbox(id: int, rotation_index: int) -> {vec3, vec3}
```
### Модель
Информация о модели блока.
```lua
-- возвращает тип модели блока (block/aabb/custom/...)
block.get_model(id: int) -> str
-- возвращает массив из 6 текстур, назначенных на стороны блока
block.get_textures(id: int) -> таблица строк
```
## Библиотека item ## Библиотека item
```python ```python
+143
View File
@@ -0,0 +1,143 @@
# Библиотека *block*
```lua
-- Возвращает строковый id блока по его числовому id.
block.name(blockid: int) -> str
-- Возвращает числовой id блока, принимая в качестве агрумента строковый
block.index(name: str) -> int
-- Возвращает id материала блока.
block.material(blockid: int) -> str
-- Возвращает название блока, отображаемое в интерфейсе.
block.caption(blockid: int) -> str
-- Возвращает числовой id блока на указанных координатах.
-- Если чанк на указанных координатах не загружен, возвращает -1.
block.get(x: int, y: int, z: int) -> int
-- Возвращает состояние (поворот + доп. информация) в виде целого числа
block.get_states(x: int, y: int, z: int) -> int
-- Устанавливает блок с заданным числовым id и состоянием (0 - по-умолчанию) на заданных координатах.
block.set(x: int, y: int, z: int, id: int, states: int)
```
> [!WARNING]
> `block.set` не вызывает событие on_placed.
```lua
-- Проверяет, является ли блок на указанных координатах полным
block.is_solid_at(x: int, y: int, z: int) -> bool
-- Проверяет, можно ли на заданных координатах поставить блок
-- (примеры: воздух, трава, цветы, вода)
block.is_replaceable_at(x: int, y: int, z: int) -> bool
-- Возвращает количество id доступных в загруженном контенте блоков
block.defs_count() -> int
-- Возвращает числовой id предмета, указанного в свойстве *picking-item*.
block.get_picking_item(id: int) -> int
```
### Raycast
```lua
block.raycast(start: vec3, dir: vec3, max_distance: number, [опционально] dest: table) -> {
block: int, -- id блока
endpoint: vec3, -- точка касания луча
iendpoint: vec3, -- позиция блока, которого касается луч
length: number, -- длина луча
normal: vec3 -- вектор нормали поверхности, которой касается луч
} или nil
```
Бросает луч из точки start в направлении dir. Max_distance указывает максимальную длину луча.
Функция возвращает таблицу с результатами или nil, если луч не касается блока.
Для результата будет использоваться целевая (dest) таблица вместо создания новой, если указан опциональный аргумент.
## Вращение
Следующие функции используется для учёта вращения блока при обращении к соседним блокам или других целей, где направление блока имеет решающее значение.
```lua
-- Возвращает целочисленный единичный вектор X блока на указанных координатах с учётом его вращения (три целых числа).
-- Если поворот отсутствует, возвращает 1, 0, 0
block.get_X(x: int, y: int, z: int) -> int, int, int
-- То же, но для оси Y (по-умолчанию 0, 1, 0)
block.get_Y(x: int, y: int, z: int) -> int, int, int
-- То же, но для оси Z (по-умолчанию 0, 0, 1)
block.get_Z(x: int, y: int, z: int) -> int, int, int
-- Возвращает индекс поворота блока в его профиле вращения (не превышает 7).
block.get_rotation(x: int, y: int, z: int) -> int
-- Устанавливает вращение блока по индексу в его профиле вращения.
block.set_rotation(x: int, y: int, z: int, rotation: int)
-- Возвращает имя профиля вращения (none/pane/pipe)
block.get_rotation_profile(id: int) -> str
```
## Расширенные блоки
Расширенные блоки - те, размер которых превышает 1x1x1
```lua
-- Проверяет, является ли блок расширенным.
block.is_extended(id: int) -> bool
-- Возвращает размер блока.
block.get_size(id: int) -> int, int, int
-- Проверяет является ли блок сегментом расширенного блока, не являющимся главным.
block.is_segment(x: int, y: int, z: int) -> bool
-- Возвращает позицию главного сегмента расширенного блока или исходную позицию,
-- если блок не является расширенным.
block.seek_origin(x: int, y: int, z: int) -> int, int, int
```
## Пользовательские биты
Выделенная под использования в скриптах часть поля `voxel.states` хранящего доп-информацию о вокселе, такую как вращение блока. На данный момент выделенная часть составляет 8 бит.
```lua
-- Возвращает выбранное число бит с указанного смещения в виде целого беззнакового числа
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
-- Записывает указанное число бит значения value в user bits по выбранному смещению
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
```
## Физика
Информация свойствах блока, используемых физическим движком.
```lua
-- Возвращает массив из двух векторов (массивов из 3 чисел):
-- 1. Минимальная точка хитбокса
-- 2. Размер хитбокса
-- rotation_index - индекс поворота блока
block.get_hitbox(id: int, rotation_index: int) -> {vec3, vec3}
```
## Модель
Информация о модели блока.
```lua
-- возвращает тип модели блока (block/aabb/custom/...)
block.get_model(id: int) -> str
-- возвращает массив из 6 текстур, назначенных на стороны блока
block.get_textures(id: int) -> таблица строк
```
+26
View File
@@ -0,0 +1,26 @@
# Библиотека *entities*
Библиотека предназначена для работы с реестром сущностей.
```lua
-- Возвращает сущность по уникальному идентификатору
-- Возвращаемая таблица - та же, что доступна в компонентах сущности.
entities.get(uid: int) -> table
-- Создает указанную сущность.
-- args - таблица таблиц параметров компонентов (переменная ARGS)
-- args не является обязательным
entities.spawn(name: str, pos: vec3, [optional] args: table)
-- Проверяет наличие сущности по уникальному идентификатору.
entities.exists(uid: int) -> bool
```
```lua
entities.raycast(start: vec3, dir: vec3, max_distance: number,
ignore: int, [optional] destination: table) -> table или nil
```
Функция является расширенным вариантом [block.raycast](libblock.md#raycast). Возвращает таблицу с результатами если луч касается блока, либо сущности.
Соответственно это повлияет на наличие полей *entity* и *block*.
+67
View File
@@ -6,6 +6,7 @@
#include "../../../physics/Hitbox.hpp" #include "../../../physics/Hitbox.hpp"
#include "../../../window/Camera.hpp" #include "../../../window/Camera.hpp"
#include "../../../content/Content.hpp" #include "../../../content/Content.hpp"
#include "../../../voxels/Chunks.hpp"
#include "../../../engine.hpp" #include "../../../engine.hpp"
using namespace scripting; using namespace scripting;
@@ -53,11 +54,77 @@ static int l_set_skeleton(lua::State* L) {
return 0; return 0;
} }
static int l_raycast(lua::State* L) {
auto start = lua::tovec<3>(L, 1);
auto dir = lua::tovec<3>(L, 2);
auto maxDistance = lua::tonumber(L, 3);
auto ignore = lua::tointeger(L, 4);
glm::vec3 end;
glm::ivec3 normal;
glm::ivec3 iend;
blockid_t block = BLOCK_VOID;
if (auto voxel = level->chunks->rayCast(start, dir, maxDistance, end, normal, iend)) {
maxDistance = glm::distance(start, end);
block = voxel->id;
}
if (auto ray = level->entities->rayCast(start, dir, maxDistance, ignore)) {
if (lua::gettop(L) >= 5) {
lua::pushvalue(L, 5);
} else {
lua::createtable(L, 0, 6);
}
lua::pushvec3_arr(L, start + dir * ray->distance);
lua::setfield(L, "endpoint");
lua::pushvec3_arr(L, ray->normal);
lua::setfield(L, "normal");
lua::pushnumber(L, glm::distance(start, end));
lua::setfield(L, "length");
lua::pushvec3_arr(L, iend);
lua::setfield(L, "iendpoint");
lua::pushinteger(L, block);
lua::setfield(L, "block");
lua::pushinteger(L, ray->entity);
lua::setfield(L, "entity");
return 1;
} else if (block != BLOCK_VOID) {
if (lua::gettop(L) >= 5) {
lua::pushvalue(L, 5);
} else {
lua::createtable(L, 0, 5);
}
lua::pushvec3_arr(L, end);
lua::setfield(L, "endpoint");
lua::pushvec3_arr(L, normal);
lua::setfield(L, "normal");
lua::pushnumber(L, glm::distance(start, end));
lua::setfield(L, "length");
lua::pushvec3_arr(L, iend);
lua::setfield(L, "iendpoint");
lua::pushinteger(L, block);
lua::setfield(L, "block");
return 1;
}
return 0;
}
const luaL_Reg entitylib [] = { const luaL_Reg entitylib [] = {
{"exists", lua::wrap<l_exists>}, {"exists", lua::wrap<l_exists>},
{"spawn", lua::wrap<l_spawn>}, {"spawn", lua::wrap<l_spawn>},
{"despawn", lua::wrap<l_despawn>}, {"despawn", lua::wrap<l_despawn>},
{"get_skeleton", lua::wrap<l_get_skeleton>}, {"get_skeleton", lua::wrap<l_get_skeleton>},
{"set_skeleton", lua::wrap<l_set_skeleton>}, {"set_skeleton", lua::wrap<l_set_skeleton>},
{"raycast", lua::wrap<l_raycast>},
{NULL, NULL} {NULL, NULL}
}; };