nuke unused overworld code

This commit is contained in:
2026-06-02 13:23:11 -05:00
parent 82c300b077
commit 241a52b94a
35 changed files with 5 additions and 2208 deletions
-2
View File
@@ -4,7 +4,5 @@
# https://opensource.org/licenses/MIT
add_subdirectory(display)
add_subdirectory(overworld)
add_subdirectory(physics)
add_subdirectory(script)
add_subdirectory(trigger)
@@ -1,13 +0,0 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
entityinteractable.c
entityoverworld.c
entityoverworldcamera.c
entityoverworldtrigger.c
entityplayer.c
)
@@ -1,49 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entityinteractable.h"
#include "entity/entitymanager.h"
void entityInteractableInit(
const entityid_t entityId,
const componentid_t componentId
) {
entityinteractable_t *inter = entityInteractableGet(entityId, componentId);
inter->onInteract = NULL;
inter->user = NULL;
}
entityinteractable_t * entityInteractableGet(
const entityid_t entityId,
const componentid_t componentId
) {
return componentGetData(entityId, componentId, COMPONENT_TYPE_INTERACTABLE);
}
void entityInteractableSetCallback(
const entityid_t entityId,
const componentid_t componentId,
void (*onInteract)(
const entityid_t entityId,
const componentid_t componentId,
void *user
),
void *user
) {
entityinteractable_t *inter = entityInteractableGet(entityId, componentId);
inter->onInteract = onInteract;
inter->user = user;
}
void entityInteractableTrigger(
const entityid_t entityId,
const componentid_t componentId
) {
entityinteractable_t *inter = entityInteractableGet(entityId, componentId);
if(inter->onInteract == NULL) return;
inter->onInteract(entityId, componentId, inter->user);
}
@@ -1,71 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity/entitybase.h"
typedef struct {
void (*onInteract)(
const entityid_t entityId,
const componentid_t componentId,
void *user
);
void *user;
} entityinteractable_t;
/**
* Initializes the interactable component, clearing the callback and user pointer.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
*/
void entityInteractableInit(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Returns a pointer to the interactable component data.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @return Pointer to the entityinteractable_t data.
*/
entityinteractable_t * entityInteractableGet(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Sets the callback invoked when this interactable is triggered.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @param onInteract Function called on interaction, or NULL to clear.
* @param user Arbitrary pointer forwarded to the callback.
*/
void entityInteractableSetCallback(
const entityid_t entityId,
const componentid_t componentId,
void (*onInteract)(
const entityid_t entityId,
const componentid_t componentId,
void *user
),
void *user
);
/**
* Fires the interactable's callback if one is set.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
*/
void entityInteractableTrigger(
const entityid_t entityId,
const componentid_t componentId
);
@@ -1,55 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entityoverworld.h"
#include "entity/entitymanager.h"
#include "entity/component/display/entityrenderable.h"
#include "display/shader/shaderunlit.h"
#include "display/mesh/cube.h"
void entityOverworldInit(
const entityid_t entityId,
const componentid_t componentId
) {
entityoverworld_t *ow = entityOverworldGet(entityId, componentId);
ow->type = OVERWORLD_ENTITY_TYPE_NPC;
ow->facing = FACING_DIR_DOWN;
ow->renderCompId = entityGetComponent(entityId, COMPONENT_TYPE_RENDERABLE);
if(ow->renderCompId != COMPONENT_ID_INVALID) {
entityRenderableSetDraw(entityId, ow->renderCompId, entityOverworldDraw, NULL);
}
ow->physCompId = entityGetComponent(entityId, COMPONENT_TYPE_PHYSICS);
}
entityoverworld_t * entityOverworldGet(
const entityid_t entityId,
const componentid_t componentId
) {
return componentGetData(entityId, componentId, COMPONENT_TYPE_OVERWORLD);
}
void entityOverworldSetType(
const entityid_t entityId,
const componentid_t componentId,
const entityoverworldtype_t type
) {
entityOverworldGet(entityId, componentId)->type = type;
}
errorret_t entityOverworldDraw(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
componentid_t owCompId = entityGetComponent(entityId, COMPONENT_TYPE_OVERWORLD);
entityoverworld_t *ow = entityOverworldGet(entityId, owCompId);
color_t col = ow->type == OVERWORLD_ENTITY_TYPE_PLAYER ? COLOR_WHITE : COLOR_BLUE;
errorChain(shaderSetColor(&SHADER_UNLIT, SHADER_UNLIT_COLOR, col));
errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, NULL));
return meshDraw(&CUBE_MESH_SIMPLE, 0, -1);
}
@@ -1,74 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include "entity/entitybase.h"
#include "overworld/facingdir.h"
typedef enum {
OVERWORLD_ENTITY_TYPE_PLAYER = 0,
OVERWORLD_ENTITY_TYPE_NPC = 1,
} entityoverworldtype_t;
typedef struct {
entityoverworldtype_t type;
facingdir_t facing;
componentid_t renderCompId;
componentid_t physCompId;
} entityoverworld_t;
/**
* Initializes the overworld component, wiring up the draw callback if a
* renderable component is already present on the entity.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
*/
void entityOverworldInit(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Returns a pointer to the overworld component data.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @return Pointer to the entityoverworld_t data.
*/
entityoverworld_t * entityOverworldGet(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Sets the overworld entity type.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @param type The type to assign.
*/
void entityOverworldSetType(
const entityid_t entityId,
const componentid_t componentId,
const entityoverworldtype_t type
);
/**
* Draw callback registered on the renderable component.
*
* @param entityId The owning entity.
* @param componentId The renderable component's ID.
* @param user Unused.
* @return Error result.
*/
errorret_t entityOverworldDraw(
const entityid_t entityId,
const componentid_t componentId,
void *user
);
@@ -1,66 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entityoverworldcamera.h"
#include "entity/entitymanager.h"
#include "entity/component/display/entityposition.h"
#include "entity/component/display/entitycamera.h"
void entityOverworldCameraInit(
const entityid_t entityId,
const componentid_t componentId
) {
entityoverworldcamera_t *cam = entityOverworldCameraGet(entityId, componentId);
cam->targetEntityId = ENTITY_ID_INVALID;
cam->targetPosCompId = COMPONENT_ID_INVALID;
glm_vec3_zero(cam->targetOffset);
glm_vec3_zero(cam->eyeOffset);
cam->scale = 1.0f;
}
entityoverworldcamera_t * entityOverworldCameraGet(
const entityid_t entityId,
const componentid_t componentId
) {
return componentGetData(entityId, componentId, COMPONENT_TYPE_OVERWORLD_CAMERA);
}
void entityOverworldCameraSetTarget(
const entityid_t entityId,
const componentid_t componentId,
const entityid_t targetEntityId,
const componentid_t targetPosCompId
) {
entityoverworldcamera_t *cam = entityOverworldCameraGet(entityId, componentId);
cam->targetEntityId = targetEntityId;
cam->targetPosCompId = targetPosCompId;
}
errorret_t entityOverworldCameraRender(
const entityid_t entityId,
const componentid_t componentId
) {
entityoverworldcamera_t *cam = entityOverworldCameraGet(entityId, componentId);
vec3 targetPos;
entityPositionGetWorldPosition(
cam->targetEntityId, cam->targetPosCompId, targetPos
);
vec3 center = {
targetPos[0] + cam->targetOffset[0],
targetPos[1] + cam->targetOffset[1],
targetPos[2] + cam->targetOffset[2]
};
componentid_t posComp = entityGetComponent(entityId, COMPONENT_TYPE_POSITION);
componentid_t camComp = entityGetComponent(entityId, COMPONENT_TYPE_CAMERA);
entityCameraLookAtPixelPerfect(
entityId, posComp, camComp, center, cam->eyeOffset, cam->scale
);
errorOk();
}
@@ -1,69 +0,0 @@
/**
* 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 "error/error.h"
typedef struct {
entityid_t targetEntityId;
componentid_t targetPosCompId;
vec3 targetOffset;
vec3 eyeOffset;
float_t scale;
} entityoverworldcamera_t;
/**
* Initializes the overworld camera component.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
*/
void entityOverworldCameraInit(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Returns a pointer to the overworld camera component data.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @return Pointer to the entityoverworldcamera_t data.
*/
entityoverworldcamera_t * entityOverworldCameraGet(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Sets the entity and position component the camera will follow.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @param targetEntityId Entity to follow.
* @param targetPosCompId Position component on the target entity.
*/
void entityOverworldCameraSetTarget(
const entityid_t entityId,
const componentid_t componentId,
const entityid_t targetEntityId,
const componentid_t targetPosCompId
);
/**
* Render callback: updates the camera position to track the target entity.
* Called automatically each frame via componentRenderAll.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @return Error state.
*/
errorret_t entityOverworldCameraRender(
const entityid_t entityId,
const componentid_t componentId
);
@@ -1,83 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entityoverworldtrigger.h"
#include "entity/entitymanager.h"
#include "entity/component/display/entityposition.h"
static void entityOverworldTriggerUpdate(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
entityoverworldtrigger_t *t = entityOverworldTriggerGet(entityId, componentId);
// Find the player position.
vec3 playerPos;
bool_t playerFound = false;
for(entityid_t i = 0; i < ENTITY_COUNT_MAX; i++) {
if((ENTITY_MANAGER.entities[i].state & ENTITY_STATE_ACTIVE) == 0) continue;
if(entityGetComponent(i, COMPONENT_TYPE_PLAYER) == COMPONENT_ID_INVALID) continue;
componentid_t posComp = entityGetComponent(i, COMPONENT_TYPE_POSITION);
if(posComp == COMPONENT_ID_INVALID) continue;
entityPositionGetWorldPosition(i, posComp, playerPos);
playerFound = true;
break;
}
bool_t wasInside = t->playerInside;
bool_t nowInside = playerFound && (
playerPos[0] >= t->min[0] && playerPos[0] <= t->max[0] &&
playerPos[1] >= t->min[1] && playerPos[1] <= t->max[1] &&
playerPos[2] >= t->min[2] && playerPos[2] <= t->max[2]
);
t->playerInside = nowInside;
if(nowInside) {
if(!wasInside && t->onEnter) t->onEnter(entityId, componentId, t->user);
if(t->onStay) t->onStay(entityId, componentId, t->user);
} else {
if(wasInside && t->onExit) t->onExit(entityId, componentId, t->user);
if(t->onOutside) t->onOutside(entityId, componentId, t->user);
}
}
void entityOverworldTriggerInit(
const entityid_t entityId,
const componentid_t componentId
) {
entityoverworldtrigger_t *t = entityOverworldTriggerGet(entityId, componentId);
glm_vec3_zero(t->min);
glm_vec3_zero(t->max);
t->playerInside = false;
t->onEnter = NULL;
t->onExit = NULL;
t->onStay = NULL;
t->onOutside = NULL;
t->user = NULL;
entityUpdateAdd(entityId, entityOverworldTriggerUpdate, componentId, NULL);
}
entityoverworldtrigger_t * entityOverworldTriggerGet(
const entityid_t entityId,
const componentid_t componentId
) {
return componentGetData(
entityId, componentId, COMPONENT_TYPE_OVERWORLD_TRIGGER
);
}
void entityOverworldTriggerSetBounds(
const entityid_t entityId,
const componentid_t componentId,
const vec3 min,
const vec3 max
) {
entityoverworldtrigger_t *t = entityOverworldTriggerGet(entityId, componentId);
glm_vec3_copy((float_t*)min, t->min);
glm_vec3_copy((float_t*)max, t->max);
}
@@ -1,54 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity/entitybase.h"
typedef void (*entityoverworldtriggercallback_t)(
const entityid_t entityId,
const componentid_t componentId,
void *user
);
typedef struct {
vec3 min;
vec3 max;
bool_t playerInside;
entityoverworldtriggercallback_t onEnter;
entityoverworldtriggercallback_t onExit;
entityoverworldtriggercallback_t onStay;
entityoverworldtriggercallback_t onOutside;
void *user;
} entityoverworldtrigger_t;
/**
* Initializes the overworld trigger component and registers its update
* callback with the entity manager. The trigger is entirely self-contained
* after init — no scene-level wiring required.
*/
void entityOverworldTriggerInit(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Returns a pointer to the overworld trigger component data.
*/
entityoverworldtrigger_t * entityOverworldTriggerGet(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Sets the trigger AABB bounds.
*/
void entityOverworldTriggerSetBounds(
const entityid_t entityId,
const componentid_t componentId,
const vec3 min,
const vec3 max
);
@@ -1,103 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entityplayer.h"
#include "entity/entitymanager.h"
#include "entity/component/display/entityposition.h"
#include "entity/component/physics/entityphysics.h"
#include "entity/component/overworld/entityoverworld.h"
#include "entity/component/overworld/entityinteractable.h"
#include "input/input.h"
void entityPlayerInit(
const entityid_t entityId,
const componentid_t componentId
) {
entityplayer_t *player = entityPlayerGet(entityId, componentId);
player->speed = ENTITY_PLAYER_SPEED;
player->runSpeed = ENTITY_PLAYER_RUN_SPEED;
}
entityplayer_t * entityPlayerGet(
const entityid_t entityId,
const componentid_t componentId
) {
return componentGetData(entityId, componentId, COMPONENT_TYPE_PLAYER);
}
void entityPlayerUpdate(
const entityid_t entityId,
const componentid_t componentId
) {
entityplayer_t *player = entityPlayerGet(entityId, componentId);
vec2 dir;
inputAngle2D(
INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT,
INPUT_ACTION_UP, INPUT_ACTION_DOWN,
dir
);
float_t speed = (
inputIsDown(INPUT_ACTION_CANCEL) ? player->runSpeed : player->speed
);
componentid_t owCompId = entityGetComponent(entityId, COMPONENT_TYPE_OVERWORLD);
entityoverworld_t *ow = entityOverworldGet(entityId, owCompId);
if(ow && glm_vec2_norm(dir) > 0.0f) {
if(fabsf(dir[0]) >= fabsf(dir[1])) {
ow->facing = dir[0] > 0.0f ? FACING_DIR_RIGHT : FACING_DIR_LEFT;
} else {
ow->facing = dir[1] > 0.0f ? FACING_DIR_DOWN : FACING_DIR_UP;
}
}
vec3 vel;
entityPhysicsGetVelocity(entityId, ow->physCompId, vel);
vel[0] = dir[0] * speed;
vel[2] = dir[1] * speed;
entityPhysicsSetVelocity(entityId, ow->physCompId, vel);
if(!inputPressed(INPUT_ACTION_ACCEPT)) return;
vec3 playerPos;
componentid_t playerPosCompId = entityGetComponent(entityId, COMPONENT_TYPE_POSITION);
if(playerPosCompId == COMPONENT_ID_INVALID) return;
entityPositionGetWorldPosition(entityId, playerPosCompId, playerPos);
vec2 facingDir;
facingDirToVec2(ow ? ow->facing : FACING_DIR_DOWN, facingDir);
for(entityid_t i = 0; i < ENTITY_COUNT_MAX; i++) {
if((ENTITY_MANAGER.entities[i].state & ENTITY_STATE_ACTIVE) == 0) continue;
if(i == entityId) continue;
componentid_t interComp = entityGetComponent(i, COMPONENT_TYPE_INTERACTABLE);
if(interComp == COMPONENT_ID_INVALID) continue;
componentid_t posComp = entityGetComponent(i, COMPONENT_TYPE_POSITION);
if(posComp == COMPONENT_ID_INVALID) continue;
vec3 targetPos;
entityPositionGetWorldPosition(i, posComp, targetPos);
vec2 toTarget = {
targetPos[0] - playerPos[0],
targetPos[2] - playerPos[2],
};
float_t forward = glm_vec2_dot(facingDir, toTarget);
if(forward <= 0.0f || forward > ENTITY_PLAYER_INTERACT_RANGE) continue;
float_t lateral = fabsf(
facingDir[0] * toTarget[1] - facingDir[1] * toTarget[0]
);
if(lateral > ENTITY_PLAYER_INTERACT_LATERAL) continue;
entityInteractableTrigger(i, interComp);
}
}
@@ -1,52 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include "entity/entitybase.h"
#define ENTITY_PLAYER_SPEED 4.0f
#define ENTITY_PLAYER_RUN_SPEED 8.0f
#define ENTITY_PLAYER_INTERACT_RANGE 1.5f
#define ENTITY_PLAYER_INTERACT_LATERAL 0.6f
typedef struct {
float_t speed;
float_t runSpeed;
} entityplayer_t;
/**
* Initializes the player component.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
*/
void entityPlayerInit(const entityid_t entityId, const componentid_t componentId);
/**
* Returns a pointer to the player component data.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @return Pointer to the entityplayer_t data.
*/
entityplayer_t * entityPlayerGet(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Reads input, moves the player, updates facing direction, and checks for
* interactable entities in front of the player when accept is pressed.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
*/
void entityPlayerUpdate(
const entityid_t entityId,
const componentid_t componentId
);
@@ -1,7 +0,0 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
-10
View File
@@ -10,11 +10,6 @@
#include "entity/component/display/entityrenderable.h"
#include "entity/component/physics/entityphysics.h"
#include "entity/component/trigger/entitytrigger.h"
#include "entity/component/overworld/entityoverworld.h"
#include "entity/component/overworld/entityoverworldtrigger.h"
#include "entity/component/overworld/entityplayer.h"
#include "entity/component/overworld/entityinteractable.h"
#include "entity/component/overworld/entityoverworldcamera.h"
// Name (Uppercase)
// Structure
@@ -28,8 +23,3 @@ X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL, NULL)
X(RENDERABLE, entityrenderable_t, renderable, entityRenderableInit, entityRenderableDispose, NULL)
X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose, NULL)
X(TRIGGER, entitytrigger_t, trigger, entityTriggerInit, NULL, NULL)
X(OVERWORLD, entityoverworld_t, overworld, entityOverworldInit, NULL, NULL)
X(PLAYER, entityplayer_t, player, entityPlayerInit, NULL, NULL)
X(INTERACTABLE, entityinteractable_t, interactable, entityInteractableInit, NULL, NULL)
X(OVERWORLD_CAMERA, entityoverworldcamera_t, overworldCamera, entityOverworldCameraInit, NULL, entityOverworldCameraRender)
X(OVERWORLD_TRIGGER, entityoverworldtrigger_t, overworldTrigger, entityOverworldTriggerInit, NULL, NULL)
+1 -2
View File
@@ -12,5 +12,4 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
# Subdirectories
add_subdirectory(initial)
add_subdirectory(test)
add_subdirectory(overworld)
add_subdirectory(test)
-12
View File
@@ -1,12 +0,0 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
overworldground.c
overworldnpc.c
overworldplayer.c
overworldscene.c
)
@@ -1,49 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "overworldground.h"
#include "entity/entitymanager.h"
#include "entity/component/physics/entityphysics.h"
#define OVERWORLD_GROUND_SIZE 20.0f
void overworldGroundAdd(overworldground_t *ground) {
ground->entityId = entityManagerAdd();
ground->posCompId = entityAddComponent(
ground->entityId, COMPONENT_TYPE_POSITION
);
entityAddComponent(ground->entityId, COMPONENT_TYPE_RENDERABLE);
vec3 pos = { -OVERWORLD_GROUND_SIZE, 0.0f, -OVERWORLD_GROUND_SIZE };
vec3 scale = { OVERWORLD_GROUND_SIZE * 2.0f, 1.0f, OVERWORLD_GROUND_SIZE * 2.0f };
entityPositionSetLocalPosition(ground->entityId, ground->posCompId, pos);
entityPositionSetLocalScale(ground->entityId, ground->posCompId, scale);
// Separate physics entity centered on the finite ground area.
// The visual entity's position is its corner {-size, 0, -size}, not its
// center, so a box collider on it would be misplaced. This entity sits at
// the true center {0, -0.5, 0} with halfExtents matching the visual extent.
ground->floorEntityId = entityManagerAdd();
componentid_t floorPosComp = entityAddComponent(
ground->floorEntityId, COMPONENT_TYPE_POSITION
);
componentid_t floorPhysComp = entityAddComponent(
ground->floorEntityId, COMPONENT_TYPE_PHYSICS
);
vec3 floorPos = { 0.0f, -0.5f, 0.0f };
entityPositionSetLocalPosition(ground->floorEntityId, floorPosComp, floorPos);
entityPhysicsSetBodyType(ground->floorEntityId, floorPhysComp, PHYSICS_BODY_STATIC);
physicsshape_t shape = {
.type = PHYSICS_SHAPE_CUBE,
.data.cube = { .halfExtents = {
OVERWORLD_GROUND_SIZE,
0.5f,
OVERWORLD_GROUND_SIZE
}}
};
entityPhysicsSetShape(ground->floorEntityId, floorPhysComp, shape);
}
@@ -1,22 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity/entitybase.h"
typedef struct {
entityid_t entityId;
componentid_t posCompId;
entityid_t floorEntityId;
} overworldground_t;
/**
* Creates the ground entity and adds it to the world.
*
* @param ground The ground state to initialize.
*/
void overworldGroundAdd(overworldground_t *ground);
-47
View File
@@ -1,47 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "overworldnpc.h"
#include "entity/entitymanager.h"
#include "entity/component/physics/entityphysics.h"
#include "entity/component/trigger/entitytrigger.h"
#include "entity/component/overworld/entityoverworld.h"
#include "entity/component/overworld/entityinteractable.h"
void overworldNpcAdd(overworldnpc_t *npc, vec3 position) {
npc->entityId = entityManagerAdd();
npc->posCompId = entityAddComponent(npc->entityId, COMPONENT_TYPE_POSITION);
entityAddComponent(npc->entityId, COMPONENT_TYPE_RENDERABLE);
entityAddComponent(npc->entityId, COMPONENT_TYPE_PHYSICS);
npc->overworldCompId = entityAddComponent(npc->entityId, COMPONENT_TYPE_OVERWORLD);
npc->triggerCompId = entityAddComponent(npc->entityId, COMPONENT_TYPE_TRIGGER);
npc->interactableCompId = entityAddComponent(
npc->entityId, COMPONENT_TYPE_INTERACTABLE
);
entityPositionSetLocalPosition(npc->entityId, npc->posCompId, position);
componentid_t physCompId = entityOverworldGet(npc->entityId, npc->overworldCompId)->physCompId;
entityPhysicsSetBodyType(npc->entityId, physCompId, PHYSICS_BODY_STATIC);
physicsshape_t shape = {
.type = PHYSICS_SHAPE_CAPSULE,
.data.capsule = { .radius = 0.4f, .halfHeight = 0.1f }
};
entityPhysicsSetShape(npc->entityId, physCompId, shape);
vec3 min = {
position[0] - OVERWORLD_NPC_INTERACT_RANGE,
position[1] - OVERWORLD_NPC_INTERACT_RANGE,
position[2] - OVERWORLD_NPC_INTERACT_RANGE
};
vec3 max = {
position[0] + OVERWORLD_NPC_INTERACT_RANGE,
position[1] + OVERWORLD_NPC_INTERACT_RANGE,
position[2] + OVERWORLD_NPC_INTERACT_RANGE
};
entityTriggerSetBounds(npc->entityId, npc->triggerCompId, min, max);
}
-27
View File
@@ -1,27 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity/entitybase.h"
#define OVERWORLD_NPC_INTERACT_RANGE 1.5f
typedef struct {
entityid_t entityId;
componentid_t posCompId;
componentid_t overworldCompId;
componentid_t triggerCompId;
componentid_t interactableCompId;
} overworldnpc_t;
/**
* Creates the NPC entity at the given world position.
*
* @param npc The NPC state to initialize.
* @param position World-space position to spawn the NPC at.
*/
void overworldNpcAdd(overworldnpc_t *npc, vec3 position);
@@ -1,38 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "overworldplayer.h"
#include "entity/entitymanager.h"
#include "entity/component/physics/entityphysics.h"
#include "entity/component/overworld/entityoverworld.h"
#include "entity/component/overworld/entityplayer.h"
void overworldPlayerAdd(overworldplayer_t *player) {
player->entityId = entityManagerAdd();
player->posCompId = entityAddComponent(player->entityId, COMPONENT_TYPE_POSITION);
entityAddComponent(player->entityId, COMPONENT_TYPE_RENDERABLE);
entityAddComponent(player->entityId, COMPONENT_TYPE_PHYSICS);
componentid_t owCompId = entityAddComponent(player->entityId, COMPONENT_TYPE_OVERWORLD);
entityOverworldSetType(player->entityId, owCompId, OVERWORLD_ENTITY_TYPE_PLAYER);
player->playerCompId = entityAddComponent(player->entityId, COMPONENT_TYPE_PLAYER);
vec3 pos = { 0.0f, 0.5f, 0.0f };
entityPositionSetLocalPosition(player->entityId, player->posCompId, pos);
componentid_t physCompId = entityOverworldGet(player->entityId, owCompId)->physCompId;
entityPhysicsSetBodyType(player->entityId, physCompId, PHYSICS_BODY_DYNAMIC);
physicsshape_t shape = {
.type = PHYSICS_SHAPE_CAPSULE,
.data.capsule = { .radius = 0.4f, .halfHeight = 0.1f }
};
entityPhysicsSetShape(player->entityId, physCompId, shape);
entityPhysicsGet(player->entityId, physCompId)->gravityScale = 1.0f;
}
void overworldPlayerUpdate(overworldplayer_t *player) {
entityPlayerUpdate(player->entityId, player->playerCompId);
}
@@ -1,29 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity/entitybase.h"
typedef struct {
entityid_t entityId;
componentid_t posCompId;
componentid_t playerCompId;
} overworldplayer_t;
/**
* Creates the player entity and adds it to the world.
*
* @param player The player state to initialize.
*/
void overworldPlayerAdd(overworldplayer_t *player);
/**
* Updates the player entity, reading input and moving on the XZ plane.
*
* @param player The player state to update.
*/
void overworldPlayerUpdate(overworldplayer_t *player);
-173
View File
@@ -1,173 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "overworldscene.h"
#include "overworldplayer.h"
#include "overworldground.h"
#include "overworldnpc.h"
#include "console/console.h"
#include "entity/entitymanager.h"
#include "entity/component/display/entityrenderable.h"
#include "display/shader/shaderlist.h"
#include "entity/component/overworld/entityinteractable.h"
#include "entity/component/overworld/entityoverworldcamera.h"
#include "entity/component/overworld/entityoverworldtrigger.h"
#include "display/mesh/cube.h"
#include "display/mesh/plane.h"
#include "display/displaystate.h"
#include "scene/scene.h"
#include "assert/assert.h"
#define OVERWORLD (SCENE.data.overworld)
static void overworldSceneTestTriggerEnter(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
consolePrint("Test trigger: player entered");
}
static void overworldSceneTestTriggerExit(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
consolePrint("Test trigger: player exited");
}
static void overworldSceneNpcInteract(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
consolePrint("NPC interacted with!");
}
void overworldSceneConfigureShaderMaterial(
const entityid_t entityId,
const color_t color,
mesh_t *mesh
) {
assertNotNull(mesh, "Mesh cannot be null");
componentid_t renderComp = entityGetComponent(
entityId, COMPONENT_TYPE_RENDERABLE
);
entityRenderableSetType(entityId, renderComp, ENTITY_RENDERABLE_TYPE_SHADER_MATERIAL);
entityrenderable_t *r = componentGetData(
entityId, renderComp, COMPONENT_TYPE_RENDERABLE
);
r->data.material.shaderType = SHADER_LIST_SHADER_UNLIT;
r->data.material.material.unlit.color = color;
r->data.material.material.unlit.texture = NULL;
r->data.material.state.flags = DISPLAY_STATE_FLAG_DEPTH_TEST;
r->data.material.meshes[0] = mesh;
r->data.material.meshOffsets[0] = 0;
r->data.material.meshCounts[0] = -1;
r->data.material.meshCount = 1;
}
void overworldSceneConfigureSprite(
const entityid_t entityId,
const color_t color,
texture_t *texture
) {
componentid_t renderComp = entityGetComponent(
entityId, COMPONENT_TYPE_RENDERABLE
);
entityRenderableSetType(entityId, renderComp, ENTITY_RENDERABLE_TYPE_SPRITEBATCH);
entityrenderable_t *r = componentGetData(
entityId, renderComp, COMPONENT_TYPE_RENDERABLE
);
r->data.spritebatch.texture = texture;
r->data.spritebatch.spriteCount = 1;
r->data.spritebatch.sprites[0].min[0] = -0.5f;
r->data.spritebatch.sprites[0].min[1] = -0.0f;
r->data.spritebatch.sprites[0].min[2] = -0.5f;
r->data.spritebatch.sprites[0].max[0] = 0.5f;
r->data.spritebatch.sprites[0].max[1] = 0.0f;
r->data.spritebatch.sprites[0].max[2] = 0.5f;
r->data.spritebatch.sprites[0].uvMin[0] = 0.0f;
r->data.spritebatch.sprites[0].uvMin[1] = 0.0f;
r->data.spritebatch.sprites[0].uvMax[0] = 1.0f;
r->data.spritebatch.sprites[0].uvMax[1] = 1.0f;
}
void overworldSceneInit(void) {
consolePrint("Overworld scene initialized");
overworldGroundAdd(&OVERWORLD.ground);
overworldSceneConfigureShaderMaterial(
OVERWORLD.ground.entityId, COLOR_MAGENTA, &PLANE_MESH_SIMPLE
);
overworldPlayerAdd(&OVERWORLD.player);
overworldSceneConfigureSprite(OVERWORLD.player.entityId, COLOR_GREEN, NULL);
vec3 npcPos = { 3.0f, 0.5f, 3.0f };
overworldNpcAdd(&OVERWORLD.npc, npcPos);
overworldSceneConfigureSprite(OVERWORLD.npc.entityId, COLOR_BLUE, NULL);
OVERWORLD.cameraEntityId = entityManagerAdd();
entityAddComponent(OVERWORLD.cameraEntityId, COMPONENT_TYPE_POSITION);
entityAddComponent(OVERWORLD.cameraEntityId, COMPONENT_TYPE_CAMERA);
OVERWORLD.cameraOverworldCompId = entityAddComponent(
OVERWORLD.cameraEntityId, COMPONENT_TYPE_OVERWORLD_CAMERA
);
entityOverworldCameraSetTarget(
OVERWORLD.cameraEntityId, OVERWORLD.cameraOverworldCompId,
OVERWORLD.player.entityId, OVERWORLD.player.posCompId
);
entityoverworldcamera_t *camData = entityOverworldCameraGet(
OVERWORLD.cameraEntityId, OVERWORLD.cameraOverworldCompId
);
glm_vec3_zero(camData->targetOffset);
glm_vec3_copy((vec3){ 0.0f, 0.0f, 5.0f }, camData->eyeOffset);
camData->scale = 32.0f;
entityInteractableSetCallback(
OVERWORLD.npc.entityId, OVERWORLD.npc.interactableCompId,
overworldSceneNpcInteract, NULL
);
OVERWORLD.testTriggerId = entityManagerAdd();
OVERWORLD.testTriggerCompId = entityAddComponent(
OVERWORLD.testTriggerId, COMPONENT_TYPE_OVERWORLD_TRIGGER
);
entityOverworldTriggerSetBounds(
OVERWORLD.testTriggerId, OVERWORLD.testTriggerCompId,
(vec3){ -2.0f, -1.0f, -2.0f },
(vec3){ 2.0f, 1.0f, 2.0f }
);
entityoverworldtrigger_t *testTrigger = entityOverworldTriggerGet(
OVERWORLD.testTriggerId, OVERWORLD.testTriggerCompId
);
testTrigger->onEnter = overworldSceneTestTriggerEnter;
testTrigger->onExit = overworldSceneTestTriggerExit;
}
errorret_t overworldSceneUpdate(void) {
overworldPlayerUpdate(&OVERWORLD.player);
errorOk();
}
void overworldSceneDispose(void) {
OVERWORLD.cameraEntityId = ENTITY_ID_INVALID;
OVERWORLD.cameraOverworldCompId = COMPONENT_ID_INVALID;
OVERWORLD.ground.entityId = ENTITY_ID_INVALID;
OVERWORLD.ground.posCompId = COMPONENT_ID_INVALID;
OVERWORLD.ground.floorEntityId = ENTITY_ID_INVALID;
OVERWORLD.player.entityId = ENTITY_ID_INVALID;
OVERWORLD.player.posCompId = COMPONENT_ID_INVALID;
OVERWORLD.npc.entityId = ENTITY_ID_INVALID;
OVERWORLD.npc.posCompId = COMPONENT_ID_INVALID;
OVERWORLD.npc.overworldCompId = COMPONENT_ID_INVALID;
OVERWORLD.npc.triggerCompId = COMPONENT_ID_INVALID;
OVERWORLD.npc.interactableCompId = COMPONENT_ID_INVALID;
}
-72
View File
@@ -1,72 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include "entity/entitybase.h"
#include "display/color.h"
#include "display/mesh/mesh.h"
#include "display/texture/texture.h"
#include "scene/overworld/overworldplayer.h"
#include "scene/overworld/overworldground.h"
#include "scene/overworld/overworldnpc.h"
typedef struct {
entityid_t cameraEntityId;
componentid_t cameraOverworldCompId;
overworldplayer_t player;
overworldground_t ground;
overworldnpc_t npc;
entityid_t testTriggerId;
componentid_t testTriggerCompId;
} overworldscene_t;
/**
* Configures a SHADER_MATERIAL renderable on an entity with the unlit shader,
* depth testing enabled, no blending, and a single mesh.
*
* @param entityId The entity to configure.
* @param color Unlit diffuse color.
* @param mesh Mesh to render.
*/
void overworldSceneConfigureShaderMaterial(
const entityid_t entityId,
const color_t color,
mesh_t *mesh
);
/**
* Configures a SPRITEBATCH renderable on an entity as a single 1x1 billboard
* sprite centered at the entity's origin.
*
* @param entityId The entity to configure.
* @param color Per-vertex sprite tint color.
* @param texture Texture to use, or NULL for untextured.
*/
void overworldSceneConfigureSprite(
const entityid_t entityId,
const color_t color,
texture_t *texture
);
/**
* Initializes the overworld scene, spawning all entities and configuring
* the camera, player, ground, and NPC.
*/
void overworldSceneInit(void);
/**
* Updates the overworld scene each frame.
*
* @return Error state.
*/
errorret_t overworldSceneUpdate(void);
/**
* Disposes the overworld scene, invalidating all entity and component IDs.
*/
void overworldSceneDispose(void);
-1
View File
@@ -9,7 +9,6 @@
#include "asset/assetfile.h"
#include "scene/initial/initialscene.h"
#include "scene/test/testscene.h"
#include "scene/overworld/overworldscene.h"
#define SCENE_EVENT_UPDATE_MAX 16
+1 -2
View File
@@ -11,5 +11,4 @@
#endif
X(initialscene_t, initial, INITIAL, initialSceneInit, initialSceneUpdate, initialSceneDispose)
X(testscene_t, test, TEST, testSceneInit, testSceneUpdate, testSceneDispose)
X(overworldscene_t, overworld, OVERWORLD, overworldSceneInit, overworldSceneUpdate, overworldSceneDispose)
X(testscene_t, test, TEST, testSceneInit, testSceneUpdate, testSceneDispose)
@@ -1,145 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#include "script/scriptproto.h"
#include "script/module/entity/modulecomponent.h"
#include "entity/component/overworld/entityinteractable.h"
#include <stdlib.h>
static scriptproto_t MODULE_INTERACTABLE_PROTO;
moduleBaseFunction(moduleInteractableCtor) {
(void)callInfo; (void)args; (void)argc;
return moduleBaseThrow("Interactable cannot be instantiated with new");
}
static inline jscomponent_t *moduleInteractableSelf(
const jerry_call_info_t *callInfo
) {
return (jscomponent_t *)scriptProtoGetValue(
&MODULE_INTERACTABLE_PROTO, callInfo->this_value
);
}
static void moduleInteractableCb(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
(void)entityId; (void)componentId;
jerry_value_t fn = *((jerry_value_t *)user);
jerry_value_t ret = jerry_call(fn, jerry_undefined(), NULL, 0);
jerry_value_free(ret);
}
moduleBaseFunction(moduleInteractableGetEntity) {
jscomponent_t *c = moduleInteractableSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->entityId);
}
moduleBaseFunction(moduleInteractableGetId) {
jscomponent_t *c = moduleInteractableSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->componentId);
}
/*
* onInteract getter — reads back the pinned JS function stored on this._cb.
*/
moduleBaseFunction(moduleInteractableGetOnInteract) {
(void)args; (void)argc;
jerry_value_t key = jerry_string_sz("_cb");
jerry_value_t val = jerry_object_get(callInfo->this_value, key);
jerry_value_free(key);
return val;
}
/*
* onInteract setter — pins the JS function on this._cb for GC safety, and
* registers a C trampoline that calls it when the player interacts.
* Passing null/undefined clears the callback.
*/
moduleBaseFunction(moduleInteractableSetOnInteract) {
jscomponent_t *c = moduleInteractableSelf(callInfo);
if(!c) return jerry_undefined();
entityinteractable_t *d = entityInteractableGet(c->entityId, c->componentId);
if(!d) return jerry_undefined();
/* Free previously stored JS reference */
if(d->user) {
jerry_value_free(*((jerry_value_t *)d->user));
free(d->user);
d->user = NULL;
}
jerry_value_t pin = (argc > 0) ? args[0] : jerry_undefined();
jerry_value_t pinKey = jerry_string_sz("_cb");
if(jerry_value_is_function(pin)) {
jerry_value_t *stored = (jerry_value_t *)malloc(sizeof(jerry_value_t));
*stored = jerry_value_copy(pin);
entityInteractableSetCallback(
c->entityId, c->componentId, moduleInteractableCb, stored
);
jerry_object_set(callInfo->this_value, pinKey, pin);
} else {
entityInteractableSetCallback(c->entityId, c->componentId, NULL, NULL);
jerry_value_t undef = jerry_undefined();
jerry_object_set(callInfo->this_value, pinKey, undef);
jerry_value_free(undef);
}
jerry_value_free(pinKey);
return jerry_undefined();
}
moduleBaseFunction(moduleInteractableTrigger) {
(void)args; (void)argc;
jscomponent_t *c = moduleInteractableSelf(callInfo);
if(!c) return jerry_undefined();
entityInteractableTrigger(c->entityId, c->componentId);
return jerry_undefined();
}
moduleBaseFunction(moduleInteractableToString) {
jscomponent_t *c = moduleInteractableSelf(callInfo);
if(!c) return jerry_string_sz("Interactable:invalid");
char_t buf[32];
snprintf(buf, sizeof(buf), "Interactable(%u)", (unsigned)c->componentId);
return jerry_string_sz(buf);
}
static void moduleInteractableInit(void) {
scriptProtoInit(
&MODULE_INTERACTABLE_PROTO, "Interactable",
sizeof(jscomponent_t), moduleInteractableCtor
);
scriptProtoDefineProp(
&MODULE_INTERACTABLE_PROTO, "entity", moduleInteractableGetEntity, NULL
);
scriptProtoDefineProp(
&MODULE_INTERACTABLE_PROTO, "id", moduleInteractableGetId, NULL
);
scriptProtoDefineProp(
&MODULE_INTERACTABLE_PROTO, "onInteract",
moduleInteractableGetOnInteract, moduleInteractableSetOnInteract
);
scriptProtoDefineFunc(
&MODULE_INTERACTABLE_PROTO, "trigger", moduleInteractableTrigger
);
scriptProtoDefineToString(
&MODULE_INTERACTABLE_PROTO, moduleInteractableToString
);
}
static void moduleInteractableDispose(void) {
scriptProtoDispose(&MODULE_INTERACTABLE_PROTO);
}
@@ -7,15 +7,10 @@
#pragma once
#include "script/module/entity/modulecomponent.h"
#include "camera/modulecamera.h"
#include "interactable/moduleinteractable.h"
#include "overworld/moduleoverworld.h"
#include "overworldcamera/moduleoverworldcamera.h"
#include "overworldtrigger/moduleoverworldtrigger.h"
#include "display/modulecamera.h"
#include "display/moduleposition.h"
#include "display/modulerenderable.h"
#include "physics/modulephysics.h"
#include "player/moduleplayer.h"
#include "position/moduleposition.h"
#include "renderable/modulerenderable.h"
#include "trigger/moduletrigger.h"
/**
@@ -29,18 +24,8 @@ static jerry_value_t moduleComponentListCreateInstance(
switch(type) {
case COMPONENT_TYPE_CAMERA:
return scriptProtoCreateValue(&MODULE_CAMERA_PROTO, comp);
case COMPONENT_TYPE_INTERACTABLE:
return scriptProtoCreateValue(&MODULE_INTERACTABLE_PROTO, comp);
case COMPONENT_TYPE_OVERWORLD:
return scriptProtoCreateValue(&MODULE_OVERWORLD_PROTO, comp);
case COMPONENT_TYPE_OVERWORLD_CAMERA:
return scriptProtoCreateValue(&MODULE_OVERWORLD_CAMERA_PROTO, comp);
case COMPONENT_TYPE_OVERWORLD_TRIGGER:
return scriptProtoCreateValue(&MODULE_OVERWORLD_TRIGGER_PROTO, comp);
case COMPONENT_TYPE_PHYSICS:
return scriptProtoCreateValue(&MODULE_PHYSICS_PROTO, comp);
case COMPONENT_TYPE_PLAYER:
return scriptProtoCreateValue(&MODULE_PLAYER_PROTO, comp);
case COMPONENT_TYPE_POSITION:
return scriptProtoCreateValue(&MODULE_POSITION_PROTO, comp);
case COMPONENT_TYPE_RENDERABLE:
@@ -54,12 +39,7 @@ static jerry_value_t moduleComponentListCreateInstance(
static void moduleComponentListInit(void) {
moduleCameraInit();
moduleInteractableInit();
moduleOverworldInit();
moduleOverworldCameraInit();
moduleOverworldTriggerInit();
modulePhysicsInit();
modulePlayerInit();
modulePositionInit();
moduleRenderableInit();
moduleTriggerInit();
@@ -69,11 +49,6 @@ static void moduleComponentListDispose(void) {
moduleTriggerDispose();
moduleRenderableDispose();
modulePositionDispose();
modulePlayerDispose();
modulePhysicsDispose();
moduleOverworldTriggerDispose();
moduleOverworldCameraDispose();
moduleOverworldDispose();
moduleInteractableDispose();
moduleCameraDispose();
}
@@ -1,168 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#include "script/scriptproto.h"
#include "script/module/entity/modulecomponent.h"
#include "entity/component/overworld/entityoverworld.h"
#include "overworld/facingdir.h"
static scriptproto_t MODULE_OVERWORLD_PROTO;
moduleBaseFunction(moduleOverworldCtor) {
(void)callInfo; (void)args; (void)argc;
return moduleBaseThrow("Overworld cannot be instantiated with new");
}
static inline jscomponent_t *moduleOverworldSelf(
const jerry_call_info_t *callInfo
) {
return (jscomponent_t *)scriptProtoGetValue(
&MODULE_OVERWORLD_PROTO, callInfo->this_value
);
}
moduleBaseFunction(moduleOverworldGetEntity) {
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->entityId);
}
moduleBaseFunction(moduleOverworldGetId) {
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->componentId);
}
moduleBaseFunction(moduleOverworldGetType) {
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworld_t *o = entityOverworldGet(c->entityId, c->componentId);
if(!o) return jerry_undefined();
return jerry_number((double)o->type);
}
moduleBaseFunction(moduleOverworldSetType) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
entityOverworldSetType(
c->entityId, c->componentId,
(entityoverworldtype_t)moduleBaseArgInt(0)
);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldGetFacing) {
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworld_t *o = entityOverworldGet(c->entityId, c->componentId);
if(!o) return jerry_undefined();
return jerry_number((double)o->facing);
}
moduleBaseFunction(moduleOverworldSetFacing) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworld_t *o = entityOverworldGet(c->entityId, c->componentId);
if(!o) return jerry_undefined();
o->facing = (facingdir_t)moduleBaseArgInt(0);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldGetRenderCompId) {
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworld_t *o = entityOverworldGet(c->entityId, c->componentId);
if(!o) return jerry_undefined();
return jerry_number((double)o->renderCompId);
}
moduleBaseFunction(moduleOverworldGetPhysCompId) {
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworld_t *o = entityOverworldGet(c->entityId, c->componentId);
if(!o) return jerry_undefined();
return jerry_number((double)o->physCompId);
}
moduleBaseFunction(moduleOverworldToString) {
jscomponent_t *c = moduleOverworldSelf(callInfo);
if(!c) return jerry_string_sz("Overworld:invalid");
char_t buf[32];
snprintf(buf, sizeof(buf), "Overworld(%u)", (unsigned)c->componentId);
return jerry_string_sz(buf);
}
static void moduleOverworldInit(void) {
scriptProtoInit(
&MODULE_OVERWORLD_PROTO, "Overworld",
sizeof(jscomponent_t), moduleOverworldCtor
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_PROTO, "entity", moduleOverworldGetEntity, NULL
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_PROTO, "id", moduleOverworldGetId, NULL
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_PROTO, "type",
moduleOverworldGetType, moduleOverworldSetType
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_PROTO, "facing",
moduleOverworldGetFacing, moduleOverworldSetFacing
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_PROTO, "renderComponentId",
moduleOverworldGetRenderCompId, NULL
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_PROTO, "physicsComponentId",
moduleOverworldGetPhysCompId, NULL
);
scriptProtoDefineToString(&MODULE_OVERWORLD_PROTO, moduleOverworldToString);
jerry_value_t ctor = MODULE_OVERWORLD_PROTO.constructor;
struct { const char_t *name; int val; } types[] = {
{ "PLAYER", OVERWORLD_ENTITY_TYPE_PLAYER },
{ "NPC", OVERWORLD_ENTITY_TYPE_NPC },
};
for(int i = 0; i < 2; i++) {
jerry_value_t k = jerry_string_sz(types[i].name);
jerry_value_t v = jerry_number((double)types[i].val);
jerry_object_set(ctor, k, v);
jerry_value_free(v);
jerry_value_free(k);
}
struct { const char_t *name; int val; } dirs[] = {
{ "FACING_DOWN", FACING_DIR_DOWN },
{ "FACING_UP", FACING_DIR_UP },
{ "FACING_LEFT", FACING_DIR_LEFT },
{ "FACING_RIGHT", FACING_DIR_RIGHT },
{ "FACING_SOUTH", FACING_DIR_SOUTH },
{ "FACING_NORTH", FACING_DIR_NORTH },
{ "FACING_WEST", FACING_DIR_WEST },
{ "FACING_EAST", FACING_DIR_EAST },
};
for(int i = 0; i < 8; i++) {
jerry_value_t k = jerry_string_sz(dirs[i].name);
jerry_value_t v = jerry_number((double)dirs[i].val);
jerry_object_set(ctor, k, v);
jerry_value_free(v);
jerry_value_free(k);
}
}
static void moduleOverworldDispose(void) {
scriptProtoDispose(&MODULE_OVERWORLD_PROTO);
}
@@ -1,201 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#include "script/scriptproto.h"
#include "script/module/math/modulevec3.h"
#include "script/module/entity/modulecomponent.h"
#include "entity/component/overworld/entityoverworldcamera.h"
static scriptproto_t MODULE_OVERWORLD_CAMERA_PROTO;
moduleBaseFunction(moduleOverworldCameraCtor) {
(void)callInfo; (void)args; (void)argc;
return moduleBaseThrow("OverworldCamera cannot be instantiated with new");
}
static inline jscomponent_t *moduleOverworldCameraSelf(
const jerry_call_info_t *callInfo
) {
return (jscomponent_t *)scriptProtoGetValue(
&MODULE_OVERWORLD_CAMERA_PROTO, callInfo->this_value
);
}
moduleBaseFunction(moduleOverworldCameraGetEntity) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->entityId);
}
moduleBaseFunction(moduleOverworldCameraGetId) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->componentId);
}
moduleBaseFunction(moduleOverworldCameraGetTargetEntity) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
return jerry_number((double)cam->targetEntityId);
}
moduleBaseFunction(moduleOverworldCameraSetTargetEntity) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
cam->targetEntityId = (entityid_t)moduleBaseArgInt(0);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldCameraGetTargetPosComp) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
return jerry_number((double)cam->targetPosCompId);
}
moduleBaseFunction(moduleOverworldCameraSetTargetPosComp) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
cam->targetPosCompId = (componentid_t)moduleBaseArgInt(0);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldCameraGetTargetOffset) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
return moduleVec3Push(cam->targetOffset);
}
moduleBaseFunction(moduleOverworldCameraSetTargetOffset) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
float_t *v = moduleVec3From(args[0]);
if(!v) return moduleBaseThrow("OverworldCamera.targetOffset: expected Vec3");
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
glm_vec3_copy(v, cam->targetOffset);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldCameraGetEyeOffset) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
return moduleVec3Push(cam->eyeOffset);
}
moduleBaseFunction(moduleOverworldCameraSetEyeOffset) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
float_t *v = moduleVec3From(args[0]);
if(!v) return moduleBaseThrow("OverworldCamera.eyeOffset: expected Vec3");
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
glm_vec3_copy(v, cam->eyeOffset);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldCameraGetScale) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
return jerry_number((double)cam->scale);
}
moduleBaseFunction(moduleOverworldCameraSetScale) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldcamera_t *cam = entityOverworldCameraGet(c->entityId, c->componentId);
if(!cam) return jerry_undefined();
cam->scale = moduleBaseArgFloat(0);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldCameraSetTarget) {
moduleBaseRequireArgs(2);
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_undefined();
entityOverworldCameraSetTarget(
c->entityId, c->componentId,
(entityid_t)moduleBaseArgInt(0),
(componentid_t)moduleBaseArgInt(1)
);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldCameraToString) {
jscomponent_t *c = moduleOverworldCameraSelf(callInfo);
if(!c) return jerry_string_sz("OverworldCamera:invalid");
char_t buf[32];
snprintf(buf, sizeof(buf), "OverworldCamera(%u)", (unsigned)c->componentId);
return jerry_string_sz(buf);
}
static void moduleOverworldCameraInit(void) {
scriptProtoInit(
&MODULE_OVERWORLD_CAMERA_PROTO, "OverworldCamera",
sizeof(jscomponent_t), moduleOverworldCameraCtor
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_CAMERA_PROTO, "entity",
moduleOverworldCameraGetEntity, NULL
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_CAMERA_PROTO, "id",
moduleOverworldCameraGetId, NULL
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_CAMERA_PROTO, "targetEntity",
moduleOverworldCameraGetTargetEntity, moduleOverworldCameraSetTargetEntity
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_CAMERA_PROTO, "targetPositionComponent",
moduleOverworldCameraGetTargetPosComp, moduleOverworldCameraSetTargetPosComp
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_CAMERA_PROTO, "targetOffset",
moduleOverworldCameraGetTargetOffset, moduleOverworldCameraSetTargetOffset
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_CAMERA_PROTO, "eyeOffset",
moduleOverworldCameraGetEyeOffset, moduleOverworldCameraSetEyeOffset
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_CAMERA_PROTO, "scale",
moduleOverworldCameraGetScale, moduleOverworldCameraSetScale
);
scriptProtoDefineFunc(
&MODULE_OVERWORLD_CAMERA_PROTO, "setTarget",
moduleOverworldCameraSetTarget
);
scriptProtoDefineToString(
&MODULE_OVERWORLD_CAMERA_PROTO, moduleOverworldCameraToString
);
}
static void moduleOverworldCameraDispose(void) {
scriptProtoDispose(&MODULE_OVERWORLD_CAMERA_PROTO);
}
@@ -1,374 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#include "script/scriptproto.h"
#include "script/module/math/modulevec3.h"
#include "script/module/entity/modulecomponent.h"
#include "entity/component/overworld/entityoverworldtrigger.h"
#include <stdlib.h>
static scriptproto_t MODULE_OVERWORLD_TRIGGER_PROTO;
/**
* Heap-allocated struct stored in entityoverworldtrigger_t.user.
* Holds jerry_value_t copies of the four JS callback functions.
*/
typedef struct {
jerry_value_t onEnter;
jerry_value_t onExit;
jerry_value_t onStay;
jerry_value_t onOutside;
} jsoverworldtriggercbs_t;
moduleBaseFunction(moduleOverworldTriggerCtor) {
(void)callInfo; (void)args; (void)argc;
return moduleBaseThrow("OverworldTrigger cannot be instantiated with new");
}
static inline jscomponent_t *moduleOverworldTriggerSelf(
const jerry_call_info_t *callInfo
) {
return (jscomponent_t *)scriptProtoGetValue(
&MODULE_OVERWORLD_TRIGGER_PROTO, callInfo->this_value
);
}
/** Lazily allocates the callback struct and stores it in the trigger's user. */
static jsoverworldtriggercbs_t *moduleOverworldTriggerGetCbs(
entityoverworldtrigger_t *t
) {
if(t->user) return (jsoverworldtriggercbs_t *)t->user;
jsoverworldtriggercbs_t *cbs = (jsoverworldtriggercbs_t *)malloc(
sizeof(jsoverworldtriggercbs_t)
);
cbs->onEnter = jerry_undefined();
cbs->onExit = jerry_undefined();
cbs->onStay = jerry_undefined();
cbs->onOutside = jerry_undefined();
t->user = (void *)cbs;
return cbs;
}
static void moduleOverworldTriggerOnEnterCb(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
(void)entityId; (void)componentId;
jsoverworldtriggercbs_t *cbs = (jsoverworldtriggercbs_t *)user;
if(!jerry_value_is_function(cbs->onEnter)) return;
jerry_value_t ret = jerry_call(cbs->onEnter, jerry_undefined(), NULL, 0);
jerry_value_free(ret);
}
static void moduleOverworldTriggerOnExitCb(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
(void)entityId; (void)componentId;
jsoverworldtriggercbs_t *cbs = (jsoverworldtriggercbs_t *)user;
if(!jerry_value_is_function(cbs->onExit)) return;
jerry_value_t ret = jerry_call(cbs->onExit, jerry_undefined(), NULL, 0);
jerry_value_free(ret);
}
static void moduleOverworldTriggerOnStayCb(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
(void)entityId; (void)componentId;
jsoverworldtriggercbs_t *cbs = (jsoverworldtriggercbs_t *)user;
if(!jerry_value_is_function(cbs->onStay)) return;
jerry_value_t ret = jerry_call(cbs->onStay, jerry_undefined(), NULL, 0);
jerry_value_free(ret);
}
static void moduleOverworldTriggerOnOutsideCb(
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
(void)entityId; (void)componentId;
jsoverworldtriggercbs_t *cbs = (jsoverworldtriggercbs_t *)user;
if(!jerry_value_is_function(cbs->onOutside)) return;
jerry_value_t ret = jerry_call(cbs->onOutside, jerry_undefined(), NULL, 0);
jerry_value_free(ret);
}
// ---- entity / id ----
moduleBaseFunction(moduleOverworldTriggerGetEntity) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->entityId);
}
moduleBaseFunction(moduleOverworldTriggerGetId) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->componentId);
}
// ---- min / max ----
moduleBaseFunction(moduleOverworldTriggerGetMin) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
return moduleVec3Push(t->min);
}
moduleBaseFunction(moduleOverworldTriggerSetMin) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
float_t *v = moduleVec3From(args[0]);
if(!v) return moduleBaseThrow("OverworldTrigger.min: expected Vec3");
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
glm_vec3_copy(v, t->min);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldTriggerGetMax) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
return moduleVec3Push(t->max);
}
moduleBaseFunction(moduleOverworldTriggerSetMax) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
float_t *v = moduleVec3From(args[0]);
if(!v) return moduleBaseThrow("OverworldTrigger.max: expected Vec3");
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
glm_vec3_copy(v, t->max);
return jerry_undefined();
}
// ---- playerInside ----
moduleBaseFunction(moduleOverworldTriggerGetPlayerInside) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
return jerry_boolean(t->playerInside);
}
// ---- setBounds ----
moduleBaseFunction(moduleOverworldTriggerSetBounds) {
moduleBaseRequireArgs(2);
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
float_t *minV = moduleVec3From(args[0]);
float_t *maxV = moduleVec3From(args[1]);
if(!minV) return moduleBaseThrow("OverworldTrigger.setBounds: expected Vec3 for min");
if(!maxV) return moduleBaseThrow("OverworldTrigger.setBounds: expected Vec3 for max");
entityOverworldTriggerSetBounds(c->entityId, c->componentId, minV, maxV);
return jerry_undefined();
}
// ---- callback helpers ----
/*
* Pins the JS function on this._onXxx for GC safety, stores a copied
* jerry_value_t reference in the cbs struct for the C trampoline, and
* wires up the C callback pointer. Passing null/undefined clears it.
*/
static void moduleOverworldTriggerSetCb(
const jerry_call_info_t *callInfo,
const jerry_value_t *newArgs,
const jerry_length_t newArgc,
jerry_value_t *slot,
entityoverworldtriggercallback_t *cslot,
entityoverworldtriggercallback_t trampolineFn,
const char_t *pinKey
) {
jerry_value_free(*slot);
jerry_value_t pin = (newArgc > 0) ? newArgs[0] : jerry_undefined();
jerry_value_t keyVal = jerry_string_sz(pinKey);
if(jerry_value_is_function(pin)) {
*slot = jerry_value_copy(pin);
*cslot = trampolineFn;
jerry_object_set(callInfo->this_value, keyVal, pin);
} else {
*slot = jerry_undefined();
*cslot = NULL;
jerry_value_t undef = jerry_undefined();
jerry_object_set(callInfo->this_value, keyVal, undef);
jerry_value_free(undef);
}
jerry_value_free(keyVal);
}
static jerry_value_t moduleOverworldTriggerGetPinnedCb(
const jerry_call_info_t *callInfo,
const char_t *pinKey
) {
jerry_value_t key = jerry_string_sz(pinKey);
jerry_value_t val = jerry_object_get(callInfo->this_value, key);
jerry_value_free(key);
return val;
}
// ---- onEnter ----
moduleBaseFunction(moduleOverworldTriggerGetOnEnter) {
(void)args; (void)argc;
return moduleOverworldTriggerGetPinnedCb(callInfo, "_onEnter");
}
moduleBaseFunction(moduleOverworldTriggerSetOnEnter) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
jsoverworldtriggercbs_t *cbs = moduleOverworldTriggerGetCbs(t);
moduleOverworldTriggerSetCb(
callInfo, args, argc,
&cbs->onEnter, &t->onEnter,
moduleOverworldTriggerOnEnterCb, "_onEnter"
);
return jerry_undefined();
}
// ---- onExit ----
moduleBaseFunction(moduleOverworldTriggerGetOnExit) {
(void)args; (void)argc;
return moduleOverworldTriggerGetPinnedCb(callInfo, "_onExit");
}
moduleBaseFunction(moduleOverworldTriggerSetOnExit) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
jsoverworldtriggercbs_t *cbs = moduleOverworldTriggerGetCbs(t);
moduleOverworldTriggerSetCb(
callInfo, args, argc,
&cbs->onExit, &t->onExit,
moduleOverworldTriggerOnExitCb, "_onExit"
);
return jerry_undefined();
}
// ---- onStay ----
moduleBaseFunction(moduleOverworldTriggerGetOnStay) {
(void)args; (void)argc;
return moduleOverworldTriggerGetPinnedCb(callInfo, "_onStay");
}
moduleBaseFunction(moduleOverworldTriggerSetOnStay) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
jsoverworldtriggercbs_t *cbs = moduleOverworldTriggerGetCbs(t);
moduleOverworldTriggerSetCb(
callInfo, args, argc,
&cbs->onStay, &t->onStay,
moduleOverworldTriggerOnStayCb, "_onStay"
);
return jerry_undefined();
}
// ---- onOutside ----
moduleBaseFunction(moduleOverworldTriggerGetOnOutside) {
(void)args; (void)argc;
return moduleOverworldTriggerGetPinnedCb(callInfo, "_onOutside");
}
moduleBaseFunction(moduleOverworldTriggerSetOnOutside) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_undefined();
entityoverworldtrigger_t *t = entityOverworldTriggerGet(c->entityId, c->componentId);
if(!t) return jerry_undefined();
jsoverworldtriggercbs_t *cbs = moduleOverworldTriggerGetCbs(t);
moduleOverworldTriggerSetCb(
callInfo, args, argc,
&cbs->onOutside, &t->onOutside,
moduleOverworldTriggerOnOutsideCb, "_onOutside"
);
return jerry_undefined();
}
moduleBaseFunction(moduleOverworldTriggerToString) {
jscomponent_t *c = moduleOverworldTriggerSelf(callInfo);
if(!c) return jerry_string_sz("OverworldTrigger:invalid");
char_t buf[32];
snprintf(buf, sizeof(buf), "OverworldTrigger(%u)", (unsigned)c->componentId);
return jerry_string_sz(buf);
}
static void moduleOverworldTriggerInit(void) {
scriptProtoInit(
&MODULE_OVERWORLD_TRIGGER_PROTO, "OverworldTrigger",
sizeof(jscomponent_t), moduleOverworldTriggerCtor
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "entity",
moduleOverworldTriggerGetEntity, NULL
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "id",
moduleOverworldTriggerGetId, NULL
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "min",
moduleOverworldTriggerGetMin, moduleOverworldTriggerSetMin
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "max",
moduleOverworldTriggerGetMax, moduleOverworldTriggerSetMax
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "playerInside",
moduleOverworldTriggerGetPlayerInside, NULL
);
scriptProtoDefineFunc(
&MODULE_OVERWORLD_TRIGGER_PROTO, "setBounds",
moduleOverworldTriggerSetBounds
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "onEnter",
moduleOverworldTriggerGetOnEnter, moduleOverworldTriggerSetOnEnter
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "onExit",
moduleOverworldTriggerGetOnExit, moduleOverworldTriggerSetOnExit
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "onStay",
moduleOverworldTriggerGetOnStay, moduleOverworldTriggerSetOnStay
);
scriptProtoDefineProp(
&MODULE_OVERWORLD_TRIGGER_PROTO, "onOutside",
moduleOverworldTriggerGetOnOutside, moduleOverworldTriggerSetOnOutside
);
scriptProtoDefineToString(
&MODULE_OVERWORLD_TRIGGER_PROTO, moduleOverworldTriggerToString
);
}
static void moduleOverworldTriggerDispose(void) {
scriptProtoDispose(&MODULE_OVERWORLD_TRIGGER_PROTO);
}
@@ -1,110 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#include "script/scriptproto.h"
#include "script/module/entity/modulecomponent.h"
#include "entity/component/overworld/entityplayer.h"
static scriptproto_t MODULE_PLAYER_PROTO;
moduleBaseFunction(modulePlayerCtor) {
(void)callInfo; (void)args; (void)argc;
return moduleBaseThrow("Player cannot be instantiated with new");
}
static inline jscomponent_t *modulePlayerSelf(
const jerry_call_info_t *callInfo
) {
return (jscomponent_t *)scriptProtoGetValue(
&MODULE_PLAYER_PROTO, callInfo->this_value
);
}
moduleBaseFunction(modulePlayerGetEntity) {
jscomponent_t *c = modulePlayerSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->entityId);
}
moduleBaseFunction(modulePlayerGetId) {
jscomponent_t *c = modulePlayerSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->componentId);
}
moduleBaseFunction(modulePlayerGetSpeed) {
jscomponent_t *c = modulePlayerSelf(callInfo);
if(!c) return jerry_undefined();
entityplayer_t *p = entityPlayerGet(c->entityId, c->componentId);
if(!p) return jerry_undefined();
return jerry_number((double)p->speed);
}
moduleBaseFunction(modulePlayerSetSpeed) {
moduleBaseRequireArgs(1);
jscomponent_t *c = modulePlayerSelf(callInfo);
if(!c) return jerry_undefined();
entityplayer_t *p = entityPlayerGet(c->entityId, c->componentId);
if(!p) return jerry_undefined();
p->speed = moduleBaseArgFloat(0);
return jerry_undefined();
}
moduleBaseFunction(modulePlayerGetRunSpeed) {
jscomponent_t *c = modulePlayerSelf(callInfo);
if(!c) return jerry_undefined();
entityplayer_t *p = entityPlayerGet(c->entityId, c->componentId);
if(!p) return jerry_undefined();
return jerry_number((double)p->runSpeed);
}
moduleBaseFunction(modulePlayerSetRunSpeed) {
moduleBaseRequireArgs(1);
jscomponent_t *c = modulePlayerSelf(callInfo);
if(!c) return jerry_undefined();
entityplayer_t *p = entityPlayerGet(c->entityId, c->componentId);
if(!p) return jerry_undefined();
p->runSpeed = moduleBaseArgFloat(0);
return jerry_undefined();
}
moduleBaseFunction(modulePlayerToString) {
jscomponent_t *c = modulePlayerSelf(callInfo);
if(!c) return jerry_string_sz("Player:invalid");
char_t buf[32];
snprintf(buf, sizeof(buf), "Player(%u)", (unsigned)c->componentId);
return jerry_string_sz(buf);
}
static void modulePlayerInit(void) {
scriptProtoInit(
&MODULE_PLAYER_PROTO, "Player",
sizeof(jscomponent_t), modulePlayerCtor
);
scriptProtoDefineProp(
&MODULE_PLAYER_PROTO, "entity", modulePlayerGetEntity, NULL
);
scriptProtoDefineProp(
&MODULE_PLAYER_PROTO, "id", modulePlayerGetId, NULL
);
scriptProtoDefineProp(
&MODULE_PLAYER_PROTO, "speed",
modulePlayerGetSpeed, modulePlayerSetSpeed
);
scriptProtoDefineProp(
&MODULE_PLAYER_PROTO, "runSpeed",
modulePlayerGetRunSpeed, modulePlayerSetRunSpeed
);
scriptProtoDefineToString(&MODULE_PLAYER_PROTO, modulePlayerToString);
}
static void modulePlayerDispose(void) {
scriptProtoDispose(&MODULE_PLAYER_PROTO);
}