Compare commits
2 Commits
playertest
...
module
| Author | SHA1 | Date | |
|---|---|---|---|
| ca6cbf41c1 | |||
| 2a9667feca |
@@ -0,0 +1,14 @@
|
||||
module('entity')
|
||||
module('entityposition')
|
||||
module('entitymaterial')
|
||||
module('glm')
|
||||
module('color')
|
||||
|
||||
-- Position
|
||||
local posComp = entityAddComponent(ENTITY_ID, COMPONENT_TYPE_POSITION)
|
||||
entityPositionSetPosition(ENTITY_ID, posComp, vec3(1, 2, 3))
|
||||
|
||||
-- Material
|
||||
local matComp = entityAddComponent(ENTITY_ID, COMPONENT_TYPE_MATERIAL)
|
||||
local material = entityMaterialGetShaderMaterial(ENTITY_ID, matComp)
|
||||
material.unlit.color = colorBlue()
|
||||
@@ -81,19 +81,14 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
|
||||
floorPhysData->shape.data.plane.normal[2] = 0.0f;
|
||||
floorPhysData->shape.data.plane.distance = 0.0f;
|
||||
|
||||
/* ---- Dynamic box ---- */
|
||||
// Test Box
|
||||
phBoxEnt = entityManagerAdd();
|
||||
componentid_t boxPos = entityAddComponent(phBoxEnt, COMPONENT_TYPE_POSITION);
|
||||
componentid_t boxMesh = entityAddComponent(phBoxEnt, COMPONENT_TYPE_MESH);
|
||||
componentid_t boxMat = entityAddComponent(phBoxEnt, COMPONENT_TYPE_MATERIAL);
|
||||
phBoxPhys = entityAddComponent(phBoxEnt, COMPONENT_TYPE_PHYSICS);
|
||||
|
||||
// componentid_t boxMat = entityAddComponent(phBoxEnt, COMPONENT_TYPE_MATERIAL);
|
||||
entityMeshSetMesh(phBoxEnt, boxMesh, &CUBE_MESH_SIMPLE);
|
||||
entityMaterialGetShaderMaterial(phBoxEnt, boxMat)->unlit.color = COLOR_RED;
|
||||
|
||||
/* Physics position lives in the POSITION component. CUBE_MESH_SIMPLE is
|
||||
* centred at origin (-0.5..0.5), so entity position == physics centre. */
|
||||
entityPositionSetPosition(phBoxEnt, boxPos, (vec3){ 0.0f, 4.0f, 0.0f });
|
||||
// entityMaterialGetShaderMaterial(phBoxEnt, boxMat)->unlit.color = COLOR_RED;
|
||||
componentid_t boxScript = entityAddComponent(phBoxEnt, COMPONENT_TYPE_SCRIPT);
|
||||
errorChain(entityScriptExecAsset(phBoxEnt, boxScript, "entity/test.lua"));
|
||||
|
||||
/* Run the init script. */
|
||||
scriptcontext_t ctx;
|
||||
@@ -111,13 +106,6 @@ errorret_t engineUpdate(void) {
|
||||
uiUpdate();
|
||||
errorChain(sceneUpdate());
|
||||
|
||||
/* Reset the box to its start position on demand. */
|
||||
if(inputIsDown(INPUT_ACTION_ACCEPT)) {
|
||||
componentid_t posComp = entityGetComponent(phBoxEnt, COMPONENT_TYPE_POSITION);
|
||||
entityPositionSetPosition(phBoxEnt, posComp, (vec3){ 0.0f, 4.0f, 0.0f });
|
||||
entityPhysicsSetVelocity(phBoxEnt, phBoxPhys, (vec3){ 0.0f, 0.0f, 0.0f });
|
||||
}
|
||||
|
||||
/* Step physics: positions are updated directly on POSITION components. */
|
||||
physicsManagerUpdate();
|
||||
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(physics)
|
||||
add_subdirectory(physics)
|
||||
add_subdirectory(script)
|
||||
@@ -55,6 +55,65 @@ void entityCameraSetZFar(
|
||||
cam->farClip = zFar;
|
||||
}
|
||||
|
||||
entitycameraprojectiontype_t entityCameraGetProjType(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp
|
||||
) {
|
||||
entitycamera_t *cam = (entitycamera_t *)componentGetData(
|
||||
ent, comp, COMPONENT_TYPE_CAMERA
|
||||
);
|
||||
return cam->projType;
|
||||
}
|
||||
|
||||
void entityCameraSetProjType(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
const entitycameraprojectiontype_t type
|
||||
) {
|
||||
entitycamera_t *cam = (entitycamera_t *)componentGetData(
|
||||
ent, comp, COMPONENT_TYPE_CAMERA
|
||||
);
|
||||
cam->projType = type;
|
||||
}
|
||||
|
||||
float_t entityCameraGetFov(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp
|
||||
) {
|
||||
entitycamera_t *cam = (entitycamera_t *)componentGetData(
|
||||
ent, comp, COMPONENT_TYPE_CAMERA
|
||||
);
|
||||
return cam->perspective.fov;
|
||||
}
|
||||
|
||||
void entityCameraSetFov(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
const float_t fov
|
||||
) {
|
||||
entitycamera_t *cam = (entitycamera_t *)componentGetData(
|
||||
ent, comp, COMPONENT_TYPE_CAMERA
|
||||
);
|
||||
cam->perspective.fov = fov;
|
||||
}
|
||||
|
||||
void entityCameraSetOrthographic(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
const float_t left,
|
||||
const float_t right,
|
||||
const float_t top,
|
||||
const float_t bottom
|
||||
) {
|
||||
entitycamera_t *cam = (entitycamera_t *)componentGetData(
|
||||
ent, comp, COMPONENT_TYPE_CAMERA
|
||||
);
|
||||
cam->orthographic.left = left;
|
||||
cam->orthographic.right = right;
|
||||
cam->orthographic.top = top;
|
||||
cam->orthographic.bottom = bottom;
|
||||
}
|
||||
|
||||
void entityCameraGetProjection(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
|
||||
@@ -96,4 +96,73 @@ void entityCameraSetZFar(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
const float_t zFar
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets the projection type of a camera.
|
||||
*
|
||||
* @param ent The entity ID.
|
||||
* @param comp The component ID.
|
||||
* @return The projection type.
|
||||
*/
|
||||
entitycameraprojectiontype_t entityCameraGetProjType(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the projection type of a camera.
|
||||
*
|
||||
* @param ent The entity ID.
|
||||
* @param comp The component ID.
|
||||
* @param type The projection type.
|
||||
*/
|
||||
void entityCameraSetProjType(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
const entitycameraprojectiontype_t type
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets the field of view (in radians) of a perspective camera.
|
||||
*
|
||||
* @param ent The entity ID.
|
||||
* @param comp The component ID.
|
||||
* @return The field of view in radians.
|
||||
*/
|
||||
float_t entityCameraGetFov(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the field of view (in radians) of a perspective camera.
|
||||
*
|
||||
* @param ent The entity ID.
|
||||
* @param comp The component ID.
|
||||
* @param fov The field of view in radians.
|
||||
*/
|
||||
void entityCameraSetFov(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
const float_t fov
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the orthographic projection bounds of a camera.
|
||||
*
|
||||
* @param ent The entity ID.
|
||||
* @param comp The component ID.
|
||||
* @param left Left bound.
|
||||
* @param right Right bound.
|
||||
* @param top Top bound.
|
||||
* @param bottom Bottom bound.
|
||||
*/
|
||||
void entityCameraSetOrthographic(
|
||||
const entityid_t ent,
|
||||
const componentid_t comp,
|
||||
const float_t left,
|
||||
const float_t right,
|
||||
const float_t top,
|
||||
const float_t bottom
|
||||
);
|
||||
@@ -100,6 +100,44 @@ bool_t entityPhysicsIsOnGround(
|
||||
return phys->onGround;
|
||||
}
|
||||
|
||||
physicsbodytype_t entityPhysicsGetBodyType(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
) {
|
||||
entityphysics_t *phys = entityPhysicsGet(entityId, componentId);
|
||||
assertNotNull(phys, "Failed to get physics component data");
|
||||
return phys->type;
|
||||
}
|
||||
|
||||
void entityPhysicsSetBodyType(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const physicsbodytype_t type
|
||||
) {
|
||||
entityphysics_t *phys = entityPhysicsGet(entityId, componentId);
|
||||
assertNotNull(phys, "Failed to get physics component data");
|
||||
phys->type = type;
|
||||
}
|
||||
|
||||
float_t entityPhysicsGetGravityScale(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
) {
|
||||
entityphysics_t *phys = entityPhysicsGet(entityId, componentId);
|
||||
assertNotNull(phys, "Failed to get physics component data");
|
||||
return phys->gravityScale;
|
||||
}
|
||||
|
||||
void entityPhysicsSetGravityScale(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const float_t scale
|
||||
) {
|
||||
entityphysics_t *phys = entityPhysicsGet(entityId, componentId);
|
||||
assertNotNull(phys, "Failed to get physics component data");
|
||||
phys->gravityScale = scale;
|
||||
}
|
||||
|
||||
void entityPhysicsDispose(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
|
||||
@@ -122,6 +122,56 @@ bool_t entityPhysicsIsOnGround(
|
||||
const componentid_t componentId
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets the body type of the entity's physics body.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
* @return The body type (static, dynamic, kinematic).
|
||||
*/
|
||||
physicsbodytype_t entityPhysicsGetBodyType(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the body type of the entity's physics body.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
* @param type The new body type.
|
||||
*/
|
||||
void entityPhysicsSetBodyType(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const physicsbodytype_t type
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets the gravity scale of the entity's physics body.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
* @return The gravity scale factor.
|
||||
*/
|
||||
float_t entityPhysicsGetGravityScale(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the gravity scale of the entity's physics body.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
* @param scale The new gravity scale factor.
|
||||
*/
|
||||
void entityPhysicsSetGravityScale(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const float_t scale
|
||||
);
|
||||
|
||||
/**
|
||||
* Releases the body slot back to PHYSICS_WORLD. Called automatically when
|
||||
* the component is disposed via the component system.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
entityscript.c
|
||||
)
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "entityscript.h"
|
||||
#include "entity/component.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void entityScriptInit(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
) {
|
||||
entityscript_t *script = (entityscript_t*)componentGetData(
|
||||
entityId, componentId, COMPONENT_TYPE_SCRIPT
|
||||
);
|
||||
scriptContextInit(&script->scriptContext);
|
||||
|
||||
// Define script globals.
|
||||
char_t strScript[64];
|
||||
snprintf(strScript, sizeof(strScript), "ENTITY_ID = %d\n", entityId);
|
||||
errorret_t ret = scriptContextExec(&script->scriptContext, strScript);
|
||||
if(ret.code != ERROR_OK) {
|
||||
errorCatch(errorPrint(ret));
|
||||
assertUnreachable("Failed to set up script globals");
|
||||
}
|
||||
}
|
||||
|
||||
errorret_t entityScriptExec(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const char_t *script
|
||||
) {
|
||||
entityscript_t *entityScript = (entityscript_t*)componentGetData(
|
||||
entityId, componentId, COMPONENT_TYPE_SCRIPT
|
||||
);
|
||||
return scriptContextExec(&entityScript->scriptContext, script);
|
||||
}
|
||||
|
||||
errorret_t entityScriptExecAsset(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const char_t *assetName
|
||||
) {
|
||||
entityscript_t *entityScript = (entityscript_t*)componentGetData(
|
||||
entityId, componentId, COMPONENT_TYPE_SCRIPT
|
||||
);
|
||||
return scriptContextExecFile(&entityScript->scriptContext, assetName);
|
||||
}
|
||||
|
||||
void entityScriptDispose(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
) {
|
||||
entityscript_t *script = (entityscript_t*)componentGetData(
|
||||
entityId, componentId, COMPONENT_TYPE_SCRIPT
|
||||
);
|
||||
scriptContextDispose(&script->scriptContext);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "entity/entitybase.h"
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
typedef struct {
|
||||
scriptcontext_t scriptContext;
|
||||
} entityscript_t;
|
||||
|
||||
/**
|
||||
* Initializes the script entity component.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
*/
|
||||
void entityScriptInit(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
);
|
||||
|
||||
/**
|
||||
* Executes a script on the entity's script component.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
* @param script The script to execute.
|
||||
* @return The error return value.
|
||||
*/
|
||||
errorret_t entityScriptExec(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const char_t *script
|
||||
);
|
||||
|
||||
/**
|
||||
* Executes a script from an asset on the entity's script component.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
* @param assetName The name of the script asset to execute.
|
||||
* @return The error return value.
|
||||
*/
|
||||
errorret_t entityScriptExecAsset(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId,
|
||||
const char_t *assetName
|
||||
);
|
||||
|
||||
/**
|
||||
* Disposes of the script entity component.
|
||||
*
|
||||
* @param entityId The entity ID.
|
||||
* @param componentId The component ID.
|
||||
*/
|
||||
void entityScriptDispose(
|
||||
const entityid_t entityId,
|
||||
const componentid_t componentId
|
||||
);
|
||||
@@ -10,9 +10,11 @@
|
||||
#include "entity/component/display/entitymesh.h"
|
||||
#include "entity/component/display/entitymaterial.h"
|
||||
#include "entity/component/physics/entityphysics.h"
|
||||
#include "entity/component/script/entityscript.h"
|
||||
|
||||
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
|
||||
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
|
||||
X(MESH, entitymesh_t, mesh, entityMeshInit, NULL)
|
||||
X(MATERIAL, entitymaterial_t, material, entityMaterialInit, NULL)
|
||||
X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose)
|
||||
X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose)
|
||||
X(SCRIPT, entityscript_t, script, entityScriptInit, entityScriptDispose)
|
||||
@@ -11,4 +11,5 @@ add_subdirectory(locale)
|
||||
add_subdirectory(system)
|
||||
add_subdirectory(scene)
|
||||
add_subdirectory(time)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(entity)
|
||||
@@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
moduleentity.c
|
||||
moduleentityposition.c
|
||||
moduleentitycamera.c
|
||||
moduleentitymesh.c
|
||||
moduleentitymaterial.c
|
||||
moduleentityphysics.c
|
||||
moduleentityscript.c
|
||||
)
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "moduleentity.h"
|
||||
#include "assert/assert.h"
|
||||
#include "entity/entitymanager.h"
|
||||
#include "entity/entity.h"
|
||||
#include "entity/component.h"
|
||||
|
||||
void moduleEntity(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
lua_State *l = ctx->luaState;
|
||||
|
||||
// Component type constants
|
||||
lua_pushnumber(l, COMPONENT_TYPE_POSITION);
|
||||
lua_setglobal(l, "COMPONENT_TYPE_POSITION");
|
||||
|
||||
lua_pushnumber(l, COMPONENT_TYPE_CAMERA);
|
||||
lua_setglobal(l, "COMPONENT_TYPE_CAMERA");
|
||||
|
||||
lua_pushnumber(l, COMPONENT_TYPE_MESH);
|
||||
lua_setglobal(l, "COMPONENT_TYPE_MESH");
|
||||
|
||||
lua_pushnumber(l, COMPONENT_TYPE_MATERIAL);
|
||||
lua_setglobal(l, "COMPONENT_TYPE_MATERIAL");
|
||||
|
||||
lua_pushnumber(l, COMPONENT_TYPE_PHYSICS);
|
||||
lua_setglobal(l, "COMPONENT_TYPE_PHYSICS");
|
||||
|
||||
lua_pushnumber(l, COMPONENT_TYPE_SCRIPT);
|
||||
lua_setglobal(l, "COMPONENT_TYPE_SCRIPT");
|
||||
|
||||
// Entity functions
|
||||
lua_register(l, "entityCreate", moduleEntityCreate);
|
||||
lua_register(l, "entityAddComponent", moduleEntityAddComponent);
|
||||
lua_register(l, "entityGetComponent", moduleEntityGetComponent);
|
||||
lua_register(l, "entityDispose", moduleEntityDispose);
|
||||
}
|
||||
|
||||
int moduleEntityCreate(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
entityid_t id = entityManagerAdd();
|
||||
entityInit(id);
|
||||
lua_pushnumber(L, id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityAddComponent(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityAddComponent: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityAddComponent: componentType must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t entityId = (entityid_t)lua_tonumber(L, 1);
|
||||
componenttype_t type = (componenttype_t)lua_tonumber(L, 2);
|
||||
componentid_t compId = entityAddComponent(entityId, type);
|
||||
lua_pushnumber(L, compId);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityGetComponent(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityGetComponent: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityGetComponent: componentType must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t entityId = (entityid_t)lua_tonumber(L, 1);
|
||||
componenttype_t type = (componenttype_t)lua_tonumber(L, 2);
|
||||
componentid_t compId = entityGetComponent(entityId, type);
|
||||
|
||||
if(compId == 0xFF) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
lua_pushnumber(L, compId);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityDispose(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityDispose: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t entityId = (entityid_t)lua_tonumber(L, 1);
|
||||
entityDispose(entityId);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
/**
|
||||
* Registers the entity module within the given script context.
|
||||
* Provides: entityCreate, entityAddComponent, entityGetComponent, entityDispose
|
||||
* and all COMPONENT_TYPE_* constants.
|
||||
*
|
||||
* @param ctx The script context to register the module in.
|
||||
*/
|
||||
void moduleEntity(scriptcontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Lua binding: reserves and initializes a new entity.
|
||||
* Returns: entityId (integer)
|
||||
*/
|
||||
int moduleEntityCreate(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: adds a component of the given type to an entity.
|
||||
* Args: entityId (integer), componentType (integer)
|
||||
* Returns: componentId (integer)
|
||||
*/
|
||||
int moduleEntityAddComponent(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: gets the component ID for the given type on an entity.
|
||||
* Args: entityId (integer), componentType (integer)
|
||||
* Returns: componentId (integer), or nil if the entity lacks the component
|
||||
*/
|
||||
int moduleEntityGetComponent(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: disposes of the entity with the given ID.
|
||||
* Args: entityId (integer)
|
||||
*/
|
||||
int moduleEntityDispose(lua_State *L);
|
||||
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "moduleentitycamera.h"
|
||||
#include "assert/assert.h"
|
||||
#include "entity/component/display/entitycamera.h"
|
||||
|
||||
void moduleEntityCamera(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
lua_State *l = ctx->luaState;
|
||||
|
||||
// Projection type constants
|
||||
lua_pushnumber(l, ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE);
|
||||
lua_setglobal(l, "ENTITY_CAMERA_PROJECTION_PERSPECTIVE");
|
||||
|
||||
lua_pushnumber(l, ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED);
|
||||
lua_setglobal(l, "ENTITY_CAMERA_PROJECTION_PERSPECTIVE_FLIPPED");
|
||||
|
||||
lua_pushnumber(l, ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC);
|
||||
lua_setglobal(l, "ENTITY_CAMERA_PROJECTION_ORTHOGRAPHIC");
|
||||
|
||||
// Camera functions
|
||||
lua_register(l, "entityCameraGetZNear", moduleEntityCameraGetZNear);
|
||||
lua_register(l, "entityCameraSetZNear", moduleEntityCameraSetZNear);
|
||||
lua_register(l, "entityCameraGetZFar", moduleEntityCameraGetZFar);
|
||||
lua_register(l, "entityCameraSetZFar", moduleEntityCameraSetZFar);
|
||||
lua_register(l, "entityCameraGetProjType", moduleEntityCameraGetProjType);
|
||||
lua_register(l, "entityCameraSetProjType", moduleEntityCameraSetProjType);
|
||||
lua_register(l, "entityCameraGetFov", moduleEntityCameraGetFov);
|
||||
lua_register(l, "entityCameraSetFov", moduleEntityCameraSetFov);
|
||||
lua_register(l, "entityCameraSetOrthographic", moduleEntityCameraSetOrthographic);
|
||||
}
|
||||
|
||||
int moduleEntityCameraGetZNear(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraGetZNear: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraGetZNear: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
lua_pushnumber(L, entityCameraGetZNear(eid, cid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityCameraSetZNear(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraSetZNear: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraSetZNear: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
luaL_error(L, "entityCameraSetZNear: zNear must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
float_t zNear = (float_t)lua_tonumber(L, 3);
|
||||
entityCameraSetZNear(eid, cid, zNear);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityCameraGetZFar(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraGetZFar: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraGetZFar: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
lua_pushnumber(L, entityCameraGetZFar(eid, cid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityCameraSetZFar(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraSetZFar: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraSetZFar: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
luaL_error(L, "entityCameraSetZFar: zFar must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
float_t zFar = (float_t)lua_tonumber(L, 3);
|
||||
entityCameraSetZFar(eid, cid, zFar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityCameraGetProjType(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraGetProjType: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraGetProjType: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
lua_pushnumber(L, entityCameraGetProjType(eid, cid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityCameraSetProjType(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraSetProjType: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraSetProjType: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
luaL_error(L, "entityCameraSetProjType: projType must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
entitycameraprojectiontype_t type = (entitycameraprojectiontype_t)lua_tonumber(L, 3);
|
||||
entityCameraSetProjType(eid, cid, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityCameraGetFov(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraGetFov: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraGetFov: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
lua_pushnumber(L, entityCameraGetFov(eid, cid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityCameraSetFov(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraSetFov: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraSetFov: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
luaL_error(L, "entityCameraSetFov: fov must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
float_t fov = (float_t)lua_tonumber(L, 3);
|
||||
entityCameraSetFov(eid, cid, fov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityCameraSetOrthographic(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityCameraSetOrthographic: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityCameraSetOrthographic: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3) || !lua_isnumber(L, 4) ||
|
||||
!lua_isnumber(L, 5) || !lua_isnumber(L, 6)) {
|
||||
luaL_error(L, "entityCameraSetOrthographic: left/right/top/bottom must be numbers");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
float_t left = (float_t)lua_tonumber(L, 3);
|
||||
float_t right = (float_t)lua_tonumber(L, 4);
|
||||
float_t top = (float_t)lua_tonumber(L, 5);
|
||||
float_t bottom = (float_t)lua_tonumber(L, 6);
|
||||
entityCameraSetOrthographic(eid, cid, left, right, top, bottom);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
/**
|
||||
* Registers the entitycamera module within the given script context.
|
||||
* Provides get/set functions for znear, zfar, and projection type constants.
|
||||
*
|
||||
* @param ctx The script context to register the module in.
|
||||
*/
|
||||
void moduleEntityCamera(scriptcontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraGetZNear(entityId, componentId) -> number
|
||||
*/
|
||||
int moduleEntityCameraGetZNear(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraSetZNear(entityId, componentId, number)
|
||||
*/
|
||||
int moduleEntityCameraSetZNear(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraGetZFar(entityId, componentId) -> number
|
||||
*/
|
||||
int moduleEntityCameraGetZFar(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraSetZFar(entityId, componentId, number)
|
||||
*/
|
||||
int moduleEntityCameraSetZFar(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraGetProjType(entityId, componentId) -> number
|
||||
*/
|
||||
int moduleEntityCameraGetProjType(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraSetProjType(entityId, componentId, number)
|
||||
*/
|
||||
int moduleEntityCameraSetProjType(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraGetFov(entityId, componentId) -> number (radians)
|
||||
*/
|
||||
int moduleEntityCameraGetFov(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraSetFov(entityId, componentId, number)
|
||||
*/
|
||||
int moduleEntityCameraSetFov(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityCameraSetOrthographic(entityId, componentId, left, right, top, bottom)
|
||||
*/
|
||||
int moduleEntityCameraSetOrthographic(lua_State *L);
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "moduleentitymaterial.h"
|
||||
#include "assert/assert.h"
|
||||
#include "entity/component/display/entitymaterial.h"
|
||||
#include "display/shader/shaderunlit.h"
|
||||
#include "util/string.h"
|
||||
|
||||
void moduleEntityMaterial(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
lua_State *l = ctx->luaState;
|
||||
|
||||
// shadermaterial_mt: wraps shadermaterial_t* pointer
|
||||
if(luaL_newmetatable(l, "shadermaterial_mt")) {
|
||||
lua_pushcfunction(l, moduleEntityMaterialShaderMaterialIndex);
|
||||
lua_setfield(l, -2, "__index");
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
// shaderunlitmaterial_mt: wraps shaderunlitmaterial_t* pointer
|
||||
if(luaL_newmetatable(l, "shaderunlitmaterial_mt")) {
|
||||
lua_pushcfunction(l, moduleEntityMaterialUnlitIndex);
|
||||
lua_setfield(l, -2, "__index");
|
||||
lua_pushcfunction(l, moduleEntityMaterialUnlitNewIndex);
|
||||
lua_setfield(l, -2, "__newindex");
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
lua_register(l, "entityMaterialGetShader", moduleEntityMaterialGetShader);
|
||||
lua_register(l, "entityMaterialSetShader", moduleEntityMaterialSetShader);
|
||||
lua_register(l, "entityMaterialGetShaderMaterial", moduleEntityMaterialGetShaderMaterial);
|
||||
}
|
||||
|
||||
int moduleEntityMaterialGetShader(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "Entity ID must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "Component ID must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
shader_t *shader = entityMaterialGetShader(eid, cid);
|
||||
|
||||
if(shader == NULL) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
lua_pushlightuserdata(L, shader);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityMaterialSetShader(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "Entity ID must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "Component ID must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
|
||||
shader_t *shader = NULL;
|
||||
if(!lua_isnil(L, 3)) {
|
||||
if(!lua_isuserdata(L, 3)) {
|
||||
luaL_error(L, "Shader must be a userdata or nil");
|
||||
return 0;
|
||||
}
|
||||
shader = (shader_t *)lua_touserdata(L, 3);
|
||||
}
|
||||
|
||||
entityMaterialSetShader(eid, cid, shader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityMaterialGetShaderMaterial(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityMaterialGetShaderMaterial: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityMaterialGetShaderMaterial: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
shadermaterial_t *mat = entityMaterialGetShaderMaterial(eid, cid);
|
||||
|
||||
if(mat == NULL) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
shadermaterial_t **pmat = (shadermaterial_t **)lua_newuserdata(
|
||||
L, sizeof(shadermaterial_t *)
|
||||
);
|
||||
*pmat = mat;
|
||||
luaL_getmetatable(L, "shadermaterial_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityMaterialShaderMaterialIndex(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
shadermaterial_t *mat = *(shadermaterial_t **)luaL_checkudata(
|
||||
L, 1, "shadermaterial_mt"
|
||||
);
|
||||
assertNotNull(mat, "Shader material pointer cannot be NULL");
|
||||
|
||||
const char_t *key = lua_tostring(L, 2);
|
||||
if(key != NULL && stringCompare(key, "unlit") == 0) {
|
||||
shaderunlitmaterial_t **punlit = (shaderunlitmaterial_t **)lua_newuserdata(
|
||||
L, sizeof(shaderunlitmaterial_t *)
|
||||
);
|
||||
*punlit = &(mat->unlit);
|
||||
luaL_getmetatable(L, "shaderunlitmaterial_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityMaterialUnlitIndex(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
shaderunlitmaterial_t *unlit = *(shaderunlitmaterial_t **)luaL_checkudata(
|
||||
L, 1, "shaderunlitmaterial_mt"
|
||||
);
|
||||
assertNotNull(unlit, "Unlit material pointer cannot be NULL");
|
||||
|
||||
const char_t *key = lua_tostring(L, 2);
|
||||
if(key == NULL) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(stringCompare(key, "color") == 0) {
|
||||
color_t *color = (color_t *)lua_newuserdata(L, sizeof(color_t));
|
||||
*color = unlit->color;
|
||||
luaL_getmetatable(L, "color_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(stringCompare(key, "texture") == 0) {
|
||||
if(unlit->texture == NULL) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
lua_pushlightuserdata(L, unlit->texture);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityMaterialUnlitNewIndex(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
shaderunlitmaterial_t *unlit = *(shaderunlitmaterial_t **)luaL_checkudata(
|
||||
L, 1, "shaderunlitmaterial_mt"
|
||||
);
|
||||
assertNotNull(unlit, "Unlit material pointer cannot be NULL");
|
||||
|
||||
const char_t *key = lua_tostring(L, 2);
|
||||
if(key == NULL) return 0;
|
||||
|
||||
if(stringCompare(key, "color") == 0) {
|
||||
color_t *color = (color_t *)luaL_checkudata(L, 3, "color_mt");
|
||||
unlit->color = *color;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(stringCompare(key, "texture") == 0) {
|
||||
if(lua_isnil(L, 3)) {
|
||||
unlit->texture = NULL;
|
||||
} else if(lua_isuserdata(L, 3)) {
|
||||
unlit->texture = (texture_t *)lua_touserdata(L, 3);
|
||||
} else {
|
||||
luaL_error(L, "shaderunlitmaterial texture must be a userdata or nil");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
/**
|
||||
* Registers the entitymaterial module within the given script context.
|
||||
* Provides get/set functions for the shader pointer (lightuserdata).
|
||||
*
|
||||
* @param ctx The script context to register the module in.
|
||||
*/
|
||||
void moduleEntityMaterial(scriptcontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Lua binding: entityMaterialGetShader(entityId, componentId) -> lightuserdata or nil
|
||||
*/
|
||||
int moduleEntityMaterialGetShader(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityMaterialSetShader(entityId, componentId, shader_lightuserdata|nil)
|
||||
*/
|
||||
int moduleEntityMaterialSetShader(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityMaterialGetShaderMaterial(entityId, componentId)
|
||||
* Returns a shadermaterial userdata (shadermaterial_mt) holding a pointer
|
||||
* into the entity's material component, or nil on failure.
|
||||
*/
|
||||
int moduleEntityMaterialGetShaderMaterial(lua_State *L);
|
||||
|
||||
/**
|
||||
* __index metamethod for shadermaterial_mt userdata.
|
||||
* Supports field: "unlit" -> shaderunlitmaterial_mt userdata.
|
||||
*/
|
||||
int moduleEntityMaterialShaderMaterialIndex(lua_State *L);
|
||||
|
||||
/**
|
||||
* __index metamethod for shaderunlitmaterial_mt userdata.
|
||||
* Supports fields: "color" -> color_mt copy, "texture" -> lightuserdata or nil.
|
||||
*/
|
||||
int moduleEntityMaterialUnlitIndex(lua_State *L);
|
||||
|
||||
/**
|
||||
* __newindex metamethod for shaderunlitmaterial_mt userdata.
|
||||
* Supports fields: "color" <- color_mt, "texture" <- lightuserdata or nil.
|
||||
*/
|
||||
int moduleEntityMaterialUnlitNewIndex(lua_State *L);
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "moduleentitymesh.h"
|
||||
#include "assert/assert.h"
|
||||
#include "entity/component/display/entitymesh.h"
|
||||
|
||||
void moduleEntityMesh(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
lua_State *l = ctx->luaState;
|
||||
lua_register(l, "entityMeshGetMesh", moduleEntityMeshGetMesh);
|
||||
lua_register(l, "entityMeshSetMesh", moduleEntityMeshSetMesh);
|
||||
}
|
||||
|
||||
int moduleEntityMeshGetMesh(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityMeshGetMesh: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityMeshGetMesh: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
mesh_t *mesh = entityMeshGetMesh(eid, cid);
|
||||
|
||||
if(mesh == NULL) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
lua_pushlightuserdata(L, mesh);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityMeshSetMesh(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityMeshSetMesh: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityMeshSetMesh: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
|
||||
mesh_t *mesh = NULL;
|
||||
if(!lua_isnil(L, 3)) {
|
||||
if(!lua_isuserdata(L, 3)) {
|
||||
luaL_error(L, "entityMeshSetMesh: mesh must be a userdata or nil");
|
||||
return 0;
|
||||
}
|
||||
mesh = (mesh_t *)lua_touserdata(L, 3);
|
||||
}
|
||||
|
||||
entityMeshSetMesh(eid, cid, mesh);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
/**
|
||||
* Registers the entitymesh module within the given script context.
|
||||
* Provides get/set functions for the mesh pointer (lightuserdata).
|
||||
*
|
||||
* @param ctx The script context to register the module in.
|
||||
*/
|
||||
void moduleEntityMesh(scriptcontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Lua binding: entityMeshGetMesh(entityId, componentId) -> lightuserdata or nil
|
||||
*/
|
||||
int moduleEntityMeshGetMesh(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityMeshSetMesh(entityId, componentId, mesh_lightuserdata|nil)
|
||||
*/
|
||||
int moduleEntityMeshSetMesh(lua_State *L);
|
||||
@@ -0,0 +1,383 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "moduleentityphysics.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include "entity/component/physics/entityphysics.h"
|
||||
|
||||
void moduleEntityPhysics(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
lua_State *l = ctx->luaState;
|
||||
|
||||
// Body type constants
|
||||
lua_pushnumber(l, PHYSICS_BODY_STATIC);
|
||||
lua_setglobal(l, "PHYSICS_BODY_STATIC");
|
||||
|
||||
lua_pushnumber(l, PHYSICS_BODY_DYNAMIC);
|
||||
lua_setglobal(l, "PHYSICS_BODY_DYNAMIC");
|
||||
|
||||
lua_pushnumber(l, PHYSICS_BODY_KINEMATIC);
|
||||
lua_setglobal(l, "PHYSICS_BODY_KINEMATIC");
|
||||
|
||||
// Shape type constants
|
||||
lua_pushnumber(l, PHYSICS_SHAPE_CUBE);
|
||||
lua_setglobal(l, "PHYSICS_SHAPE_CUBE");
|
||||
|
||||
lua_pushnumber(l, PHYSICS_SHAPE_SPHERE);
|
||||
lua_setglobal(l, "PHYSICS_SHAPE_SPHERE");
|
||||
|
||||
lua_pushnumber(l, PHYSICS_SHAPE_CAPSULE);
|
||||
lua_setglobal(l, "PHYSICS_SHAPE_CAPSULE");
|
||||
|
||||
lua_pushnumber(l, PHYSICS_SHAPE_PLANE);
|
||||
lua_setglobal(l, "PHYSICS_SHAPE_PLANE");
|
||||
|
||||
// Physics shape metatable
|
||||
if(luaL_newmetatable(l, "physicsshape_mt")) {
|
||||
lua_pushcfunction(l, moduleEntityPhysicsShapeToString);
|
||||
lua_setfield(l, -2, "__tostring");
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
// Shape constructors
|
||||
lua_register(l, "physicsShapeCube", modulePhysicsShapeCube);
|
||||
lua_register(l, "physicsShapeSphere", modulePhysicsShapeSphere);
|
||||
lua_register(l, "physicsShapeCapsule", modulePhysicsShapeCapsule);
|
||||
lua_register(l, "physicsShapePlane", modulePhysicsShapePlane);
|
||||
|
||||
// Entity physics functions
|
||||
lua_register(l, "entityPhysicsGetVelocity", moduleEntityPhysicsGetVelocity);
|
||||
lua_register(l, "entityPhysicsSetVelocity", moduleEntityPhysicsSetVelocity);
|
||||
lua_register(l, "entityPhysicsApplyImpulse", moduleEntityPhysicsApplyImpulse);
|
||||
lua_register(l, "entityPhysicsIsOnGround", moduleEntityPhysicsIsOnGround);
|
||||
lua_register(l, "entityPhysicsGetShape", moduleEntityPhysicsGetShape);
|
||||
lua_register(l, "entityPhysicsSetShape", moduleEntityPhysicsSetShape);
|
||||
lua_register(l, "entityPhysicsGetBodyType", moduleEntityPhysicsGetBodyType);
|
||||
lua_register(l, "entityPhysicsSetBodyType", moduleEntityPhysicsSetBodyType);
|
||||
lua_register(l, "entityPhysicsGetGravityScale", moduleEntityPhysicsGetGravityScale);
|
||||
lua_register(l, "entityPhysicsSetGravityScale", moduleEntityPhysicsSetGravityScale);
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsShapeToString(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
physicsshape_t *shape = (physicsshape_t *)luaL_checkudata(L, 1, "physicsshape_mt");
|
||||
assertNotNull(shape, "Physics shape pointer cannot be NULL");
|
||||
|
||||
const char_t *typeName = "unknown";
|
||||
switch(shape->type) {
|
||||
case PHYSICS_SHAPE_CUBE: typeName = "cube"; break;
|
||||
case PHYSICS_SHAPE_SPHERE: typeName = "sphere"; break;
|
||||
case PHYSICS_SHAPE_CAPSULE: typeName = "capsule"; break;
|
||||
case PHYSICS_SHAPE_PLANE: typeName = "plane"; break;
|
||||
}
|
||||
lua_pushfstring(L, "physicsshape(%s)", typeName);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsGetVelocity(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsGetVelocity: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsGetVelocity: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
|
||||
vec3 *v = (vec3 *)lua_newuserdata(L, sizeof(vec3));
|
||||
memoryZero(v, sizeof(vec3));
|
||||
entityPhysicsGetVelocity(eid, cid, *v);
|
||||
luaL_getmetatable(L, "vec3_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsSetVelocity(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsSetVelocity: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsSetVelocity: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
vec3 *v = (vec3 *)luaL_checkudata(L, 3, "vec3_mt");
|
||||
entityPhysicsSetVelocity(eid, cid, *v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsApplyImpulse(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsApplyImpulse: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsApplyImpulse: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
vec3 *v = (vec3 *)luaL_checkudata(L, 3, "vec3_mt");
|
||||
entityPhysicsApplyImpulse(eid, cid, *v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsIsOnGround(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsIsOnGround: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsIsOnGround: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
lua_pushboolean(L, entityPhysicsIsOnGround(eid, cid) ? 1 : 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsSetShape(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsSetShape: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsSetShape: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
physicsshape_t *shape = (physicsshape_t *)luaL_checkudata(L, 3, "physicsshape_mt");
|
||||
entityPhysicsSetShape(eid, cid, *shape);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsGetShape(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsGetShape: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsGetShape: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
|
||||
physicsshape_t *shape = (physicsshape_t *)lua_newuserdata(L, sizeof(physicsshape_t));
|
||||
*shape = entityPhysicsGetShape(eid, cid);
|
||||
luaL_getmetatable(L, "physicsshape_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsGetBodyType(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsGetBodyType: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsGetBodyType: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
lua_pushnumber(L, entityPhysicsGetBodyType(eid, cid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsSetBodyType(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsSetBodyType: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsSetBodyType: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
luaL_error(L, "entityPhysicsSetBodyType: bodyType must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
physicsbodytype_t type = (physicsbodytype_t)lua_tonumber(L, 3);
|
||||
entityPhysicsSetBodyType(eid, cid, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsGetGravityScale(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsGetGravityScale: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsGetGravityScale: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
lua_pushnumber(L, entityPhysicsGetGravityScale(eid, cid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPhysicsSetGravityScale(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPhysicsSetGravityScale: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPhysicsSetGravityScale: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
luaL_error(L, "entityPhysicsSetGravityScale: scale must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
float_t scale = (float_t)lua_tonumber(L, 3);
|
||||
entityPhysicsSetGravityScale(eid, cid, scale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int modulePhysicsShapeCube(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
float_t hx = lua_isnumber(L, 1) ? (float_t)lua_tonumber(L, 1) : 0.5f;
|
||||
float_t hy = lua_isnumber(L, 2) ? (float_t)lua_tonumber(L, 2) : 0.5f;
|
||||
float_t hz = lua_isnumber(L, 3) ? (float_t)lua_tonumber(L, 3) : 0.5f;
|
||||
|
||||
physicsshape_t *shape = (physicsshape_t *)lua_newuserdata(L, sizeof(physicsshape_t));
|
||||
memoryZero(shape, sizeof(physicsshape_t));
|
||||
shape->type = PHYSICS_SHAPE_CUBE;
|
||||
shape->data.cube.halfExtents[0] = hx;
|
||||
shape->data.cube.halfExtents[1] = hy;
|
||||
shape->data.cube.halfExtents[2] = hz;
|
||||
luaL_getmetatable(L, "physicsshape_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int modulePhysicsShapeSphere(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "physicsShapeSphere: radius must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
float_t radius = (float_t)lua_tonumber(L, 1);
|
||||
|
||||
physicsshape_t *shape = (physicsshape_t *)lua_newuserdata(L, sizeof(physicsshape_t));
|
||||
memoryZero(shape, sizeof(physicsshape_t));
|
||||
shape->type = PHYSICS_SHAPE_SPHERE;
|
||||
shape->data.sphere.radius = radius;
|
||||
luaL_getmetatable(L, "physicsshape_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int modulePhysicsShapeCapsule(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "physicsShapeCapsule: radius must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "physicsShapeCapsule: halfHeight must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
float_t radius = (float_t)lua_tonumber(L, 1);
|
||||
float_t halfHeight = (float_t)lua_tonumber(L, 2);
|
||||
|
||||
physicsshape_t *shape = (physicsshape_t *)lua_newuserdata(L, sizeof(physicsshape_t));
|
||||
memoryZero(shape, sizeof(physicsshape_t));
|
||||
shape->type = PHYSICS_SHAPE_CAPSULE;
|
||||
shape->data.capsule.radius = radius;
|
||||
shape->data.capsule.halfHeight = halfHeight;
|
||||
luaL_getmetatable(L, "physicsshape_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int modulePhysicsShapePlane(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "physicsShapePlane: normalX must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "physicsShapePlane: normalY must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
luaL_error(L, "physicsShapePlane: normalZ must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 4)) {
|
||||
luaL_error(L, "physicsShapePlane: distance must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
float_t nx = (float_t)lua_tonumber(L, 1);
|
||||
float_t ny = (float_t)lua_tonumber(L, 2);
|
||||
float_t nz = (float_t)lua_tonumber(L, 3);
|
||||
float_t distance = (float_t)lua_tonumber(L, 4);
|
||||
|
||||
physicsshape_t *shape = (physicsshape_t *)lua_newuserdata(L, sizeof(physicsshape_t));
|
||||
memoryZero(shape, sizeof(physicsshape_t));
|
||||
shape->type = PHYSICS_SHAPE_PLANE;
|
||||
shape->data.plane.normal[0] = nx;
|
||||
shape->data.plane.normal[1] = ny;
|
||||
shape->data.plane.normal[2] = nz;
|
||||
shape->data.plane.distance = distance;
|
||||
luaL_getmetatable(L, "physicsshape_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
/**
|
||||
* Registers the entityphysics module within the given script context.
|
||||
* Provides velocity, impulse, onGround, and shape functions, plus body type
|
||||
* and shape type constants. Shape constructors: physicsShapeCube,
|
||||
* physicsShapeSphere, physicsShapeCapsule, physicsShapePlane.
|
||||
*
|
||||
* @param ctx The script context to register the module in.
|
||||
*/
|
||||
void moduleEntityPhysics(scriptcontext_t *ctx);
|
||||
|
||||
/** Lua binding: entityPhysicsGetVelocity(entityId, componentId) -> vec3 */
|
||||
int moduleEntityPhysicsGetVelocity(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsSetVelocity(entityId, componentId, vec3) */
|
||||
int moduleEntityPhysicsSetVelocity(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsApplyImpulse(entityId, componentId, vec3) */
|
||||
int moduleEntityPhysicsApplyImpulse(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsIsOnGround(entityId, componentId) -> boolean */
|
||||
int moduleEntityPhysicsIsOnGround(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsSetShape(entityId, componentId, physicsshape) */
|
||||
int moduleEntityPhysicsSetShape(lua_State *L);
|
||||
|
||||
/** Lua binding: physicsShapeCube(halfX, halfY, halfZ) -> physicsshape */
|
||||
int modulePhysicsShapeCube(lua_State *L);
|
||||
|
||||
/** Lua binding: physicsShapeSphere(radius) -> physicsshape */
|
||||
int modulePhysicsShapeSphere(lua_State *L);
|
||||
|
||||
/** Lua binding: physicsShapeCapsule(radius, halfHeight) -> physicsshape */
|
||||
int modulePhysicsShapeCapsule(lua_State *L);
|
||||
|
||||
/** Lua binding: physicsShapePlane(normalX, normalY, normalZ, distance) -> physicsshape */
|
||||
int modulePhysicsShapePlane(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsGetShape(entityId, componentId) -> physicsshape */
|
||||
int moduleEntityPhysicsGetShape(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsGetBodyType(entityId, componentId) -> number */
|
||||
int moduleEntityPhysicsGetBodyType(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsSetBodyType(entityId, componentId, number) */
|
||||
int moduleEntityPhysicsSetBodyType(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsGetGravityScale(entityId, componentId) -> number */
|
||||
int moduleEntityPhysicsGetGravityScale(lua_State *L);
|
||||
|
||||
/** Lua binding: entityPhysicsSetGravityScale(entityId, componentId, number) */
|
||||
int moduleEntityPhysicsSetGravityScale(lua_State *L);
|
||||
|
||||
/** Metatable __tostring for physicsshape userdata */
|
||||
int moduleEntityPhysicsShapeToString(lua_State *L);
|
||||
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "moduleentityposition.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include "entity/component/display/entityposition.h"
|
||||
|
||||
void moduleEntityPosition(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
lua_State *l = ctx->luaState;
|
||||
|
||||
lua_register(l, "entityPositionGetPosition", moduleEntityPositionGetPosition);
|
||||
lua_register(l, "entityPositionSetPosition", moduleEntityPositionSetPosition);
|
||||
lua_register(l, "entityPositionGetRotation", moduleEntityPositionGetRotation);
|
||||
lua_register(l, "entityPositionSetRotation", moduleEntityPositionSetRotation);
|
||||
lua_register(l, "entityPositionGetScale", moduleEntityPositionGetScale);
|
||||
lua_register(l, "entityPositionSetScale", moduleEntityPositionSetScale);
|
||||
lua_register(l, "entityPositionLookAt", moduleEntityPositionLookAt);
|
||||
}
|
||||
|
||||
int moduleEntityPositionGetPosition(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPositionGetPosition: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPositionGetPosition: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
|
||||
vec3 *v = (vec3 *)lua_newuserdata(L, sizeof(vec3));
|
||||
memoryZero(v, sizeof(vec3));
|
||||
entityPositionGetPosition(eid, cid, *v);
|
||||
luaL_getmetatable(L, "vec3_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPositionSetPosition(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPositionSetPosition: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPositionSetPosition: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
vec3 *v = (vec3 *)luaL_checkudata(L, 3, "vec3_mt");
|
||||
entityPositionSetPosition(eid, cid, *v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityPositionGetRotation(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPositionGetRotation: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPositionGetRotation: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
|
||||
vec3 *v = (vec3 *)lua_newuserdata(L, sizeof(vec3));
|
||||
memoryZero(v, sizeof(vec3));
|
||||
entityPositionGetRotation(eid, cid, *v);
|
||||
luaL_getmetatable(L, "vec3_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPositionSetRotation(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPositionSetRotation: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPositionSetRotation: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
vec3 *v = (vec3 *)luaL_checkudata(L, 3, "vec3_mt");
|
||||
entityPositionSetRotation(eid, cid, *v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityPositionGetScale(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPositionGetScale: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPositionGetScale: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
|
||||
vec3 *v = (vec3 *)lua_newuserdata(L, sizeof(vec3));
|
||||
memoryZero(v, sizeof(vec3));
|
||||
entityPositionGetScale(eid, cid, *v);
|
||||
luaL_getmetatable(L, "vec3_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int moduleEntityPositionSetScale(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPositionSetScale: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPositionSetScale: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
vec3 *v = (vec3 *)luaL_checkudata(L, 3, "vec3_mt");
|
||||
entityPositionSetScale(eid, cid, *v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityPositionLookAt(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityPositionLookAt: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityPositionLookAt: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
vec3 *target = (vec3 *)luaL_checkudata(L, 3, "vec3_mt");
|
||||
vec3 *up = (vec3 *)luaL_checkudata(L, 4, "vec3_mt");
|
||||
vec3 *eye = (vec3 *)luaL_checkudata(L, 5, "vec3_mt");
|
||||
entityPositionLookAt(eid, cid, *target, *up, *eye);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
/**
|
||||
* Registers the entityposition module within the given script context.
|
||||
* Provides get/set functions for position, rotation, scale, and lookAt.
|
||||
*
|
||||
* @param ctx The script context to register the module in.
|
||||
*/
|
||||
void moduleEntityPosition(scriptcontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Lua binding: entityPositionGetPosition(entityId, componentId) -> vec3
|
||||
*/
|
||||
int moduleEntityPositionGetPosition(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityPositionSetPosition(entityId, componentId, vec3)
|
||||
*/
|
||||
int moduleEntityPositionSetPosition(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityPositionGetRotation(entityId, componentId) -> vec3 (radians)
|
||||
*/
|
||||
int moduleEntityPositionGetRotation(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityPositionSetRotation(entityId, componentId, vec3) (radians)
|
||||
*/
|
||||
int moduleEntityPositionSetRotation(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityPositionGetScale(entityId, componentId) -> vec3
|
||||
*/
|
||||
int moduleEntityPositionGetScale(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityPositionSetScale(entityId, componentId, vec3)
|
||||
*/
|
||||
int moduleEntityPositionSetScale(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityPositionLookAt(entityId, componentId, target, up, eye)
|
||||
* All vec3 arguments.
|
||||
*/
|
||||
int moduleEntityPositionLookAt(lua_State *L);
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "moduleentityscript.h"
|
||||
#include "assert/assert.h"
|
||||
#include "error/error.h"
|
||||
#include "entity/component/script/entityscript.h"
|
||||
|
||||
void moduleEntityScript(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
lua_State *l = ctx->luaState;
|
||||
lua_register(l, "entityScriptExec", moduleEntityScriptExec);
|
||||
lua_register(l, "entityScriptExecAsset", moduleEntityScriptExecAsset);
|
||||
}
|
||||
|
||||
int moduleEntityScriptExec(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityScriptExec: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityScriptExec: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isstring(L, 3)) {
|
||||
luaL_error(L, "entityScriptExec: script must be a string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
const char_t *script = lua_tostring(L, 3);
|
||||
|
||||
errorret_t ret = entityScriptExec(eid, cid, script);
|
||||
if(ret.code != ERROR_OK) {
|
||||
errorCatch(errorPrint(ret));
|
||||
luaL_error(L, "entityScriptExec failed");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleEntityScriptExecAsset(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "entityScriptExecAsset: entityId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "entityScriptExecAsset: componentId must be a number");
|
||||
return 0;
|
||||
}
|
||||
if(!lua_isstring(L, 3)) {
|
||||
luaL_error(L, "entityScriptExecAsset: assetName must be a string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entityid_t eid = (entityid_t)lua_tonumber(L, 1);
|
||||
componentid_t cid = (componentid_t)lua_tonumber(L, 2);
|
||||
const char_t *assetName = lua_tostring(L, 3);
|
||||
|
||||
errorret_t ret = entityScriptExecAsset(eid, cid, assetName);
|
||||
if(ret.code != ERROR_OK) {
|
||||
errorCatch(errorPrint(ret));
|
||||
luaL_error(L, "entityScriptExecAsset failed");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
/**
|
||||
* Registers the entityscript module within the given script context.
|
||||
* Provides functions to execute Lua code on another entity's script component.
|
||||
*
|
||||
* @param ctx The script context to register the module in.
|
||||
*/
|
||||
void moduleEntityScript(scriptcontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Lua binding: entityScriptExec(entityId, componentId, scriptString)
|
||||
* Executes an inline Lua string on the target entity's script component.
|
||||
*/
|
||||
int moduleEntityScriptExec(lua_State *L);
|
||||
|
||||
/**
|
||||
* Lua binding: entityScriptExecAsset(entityId, componentId, assetName)
|
||||
* Executes a Lua script file from assets on the target entity's script component.
|
||||
*/
|
||||
int moduleEntityScriptExecAsset(lua_State *L);
|
||||
@@ -22,6 +22,13 @@
|
||||
#include "script/module/display/modulescreen.h"
|
||||
#include "script/module/display/moduletexture.h"
|
||||
#include "script/module/display/moduletileset.h"
|
||||
#include "script/module/entity/moduleentity.h"
|
||||
#include "script/module/entity/moduleentityposition.h"
|
||||
#include "script/module/entity/moduleentitycamera.h"
|
||||
#include "script/module/entity/moduleentitymesh.h"
|
||||
#include "script/module/entity/moduleentitymaterial.h"
|
||||
#include "script/module/entity/moduleentityphysics.h"
|
||||
#include "script/module/entity/moduleentityscript.h"
|
||||
#include "script/scriptgame.h"
|
||||
#include "util/string.h"
|
||||
|
||||
@@ -42,6 +49,13 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = {
|
||||
{ .name = "texture", .callback = moduleTexture },
|
||||
{ .name = "tileset", .callback = moduleTileset },
|
||||
{ .name = "shader", .callback = moduleShader },
|
||||
{ .name = "entity", .callback = moduleEntity },
|
||||
{ .name = "entityposition", .callback = moduleEntityPosition },
|
||||
{ .name = "entitycamera", .callback = moduleEntityCamera },
|
||||
{ .name = "entitymesh", .callback = moduleEntityMesh },
|
||||
{ .name = "entitymaterial", .callback = moduleEntityMaterial },
|
||||
{ .name = "entityphysics", .callback = moduleEntityPhysics },
|
||||
{ .name = "entityscript", .callback = moduleEntityScript },
|
||||
|
||||
#ifdef SCRIPT_GAME_LIST
|
||||
SCRIPT_GAME_LIST
|
||||
|
||||
Reference in New Issue
Block a user