Add some script modules
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -8,7 +8,12 @@
|
||||
#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 "physics/modulephysics.h"
|
||||
#include "player/moduleplayer.h"
|
||||
#include "position/moduleposition.h"
|
||||
#include "renderable/modulerenderable.h"
|
||||
#include "trigger/moduletrigger.h"
|
||||
@@ -24,8 +29,18 @@ 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:
|
||||
@@ -39,7 +54,12 @@ static jerry_value_t moduleComponentListCreateInstance(
|
||||
|
||||
static void moduleComponentListInit(void) {
|
||||
moduleCameraInit();
|
||||
moduleInteractableInit();
|
||||
moduleOverworldInit();
|
||||
moduleOverworldCameraInit();
|
||||
moduleOverworldTriggerInit();
|
||||
modulePhysicsInit();
|
||||
modulePlayerInit();
|
||||
modulePositionInit();
|
||||
moduleRenderableInit();
|
||||
moduleTriggerInit();
|
||||
@@ -49,6 +69,11 @@ static void moduleComponentListDispose(void) {
|
||||
moduleTriggerDispose();
|
||||
moduleRenderableDispose();
|
||||
modulePositionDispose();
|
||||
modulePlayerDispose();
|
||||
modulePhysicsDispose();
|
||||
moduleOverworldTriggerDispose();
|
||||
moduleOverworldCameraDispose();
|
||||
moduleOverworldDispose();
|
||||
moduleInteractableDispose();
|
||||
moduleCameraDispose();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interactable component. Fires a callback when the player activates it.
|
||||
*
|
||||
* Assign a JS function to `onInteract` to handle the event from script.
|
||||
* Call `trigger()` to fire the callback imperatively from C or JS.
|
||||
*/
|
||||
interface Interactable extends Component {
|
||||
/** Called when the player interacts with this entity. Set to null to clear. */
|
||||
onInteract: (() => void) | null;
|
||||
/** Fires the registered callback immediately (no-op if none is set). */
|
||||
trigger(): void;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
interface InteractableConstructor {
|
||||
new(): never;
|
||||
}
|
||||
|
||||
declare var Interactable: InteractableConstructor;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/** Overworld character component (player or NPC). */
|
||||
interface Overworld extends Component {
|
||||
/**
|
||||
* Entity type — `Overworld.PLAYER` or `Overworld.NPC`.
|
||||
*/
|
||||
type: number;
|
||||
/**
|
||||
* Facing direction — one of the `Overworld.FACING_*` constants.
|
||||
*/
|
||||
facing: number;
|
||||
/** Component ID of the linked Renderable, or INVALID if none. */
|
||||
readonly renderComponentId: number;
|
||||
/** Component ID of the linked Physics body, or INVALID if none. */
|
||||
readonly physicsComponentId: number;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
interface OverworldConstructor {
|
||||
readonly PLAYER: number;
|
||||
readonly NPC: number;
|
||||
|
||||
readonly FACING_DOWN: number;
|
||||
readonly FACING_UP: number;
|
||||
readonly FACING_LEFT: number;
|
||||
readonly FACING_RIGHT: number;
|
||||
readonly FACING_SOUTH: number;
|
||||
readonly FACING_NORTH: number;
|
||||
readonly FACING_WEST: number;
|
||||
readonly FACING_EAST: number;
|
||||
|
||||
new(): never;
|
||||
}
|
||||
|
||||
declare var Overworld: OverworldConstructor;
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Overworld follow-camera component.
|
||||
* Smoothly tracks a target entity's Position each frame.
|
||||
*/
|
||||
interface OverworldCamera extends Component {
|
||||
/** Entity ID to follow. */
|
||||
targetEntity: number;
|
||||
/** Position component ID on the target entity. */
|
||||
targetPositionComponent: number;
|
||||
/** World-space offset added to the target's position before placing the camera. */
|
||||
targetOffset: Vec3;
|
||||
/** Eye-space offset applied on top of targetOffset. */
|
||||
eyeOffset: Vec3;
|
||||
/** Orthographic scale factor (larger = wider view). */
|
||||
scale: number;
|
||||
/**
|
||||
* Convenience setter — equivalent to assigning `targetEntity` and
|
||||
* `targetPositionComponent` individually.
|
||||
*/
|
||||
setTarget(targetEntityId: number, targetPositionComponentId: number): void;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
interface OverworldCameraConstructor {
|
||||
new(): never;
|
||||
}
|
||||
|
||||
declare var OverworldCamera: OverworldCameraConstructor;
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Overworld AABB trigger. Fires callbacks as the player enters, stays inside,
|
||||
* exits, or remains outside the defined bounding box each frame.
|
||||
*/
|
||||
interface OverworldTrigger extends Component {
|
||||
/** Minimum corner of the trigger AABB. */
|
||||
min: Vec3;
|
||||
/** Maximum corner of the trigger AABB. */
|
||||
max: Vec3;
|
||||
/** `true` while the player is inside the trigger bounds. */
|
||||
readonly playerInside: boolean;
|
||||
|
||||
/** Fired once when the player first enters the bounds. */
|
||||
onEnter: (() => void) | null;
|
||||
/** Fired once when the player leaves the bounds. */
|
||||
onExit: (() => void) | null;
|
||||
/** Fired every frame while the player remains inside the bounds. */
|
||||
onStay: (() => void) | null;
|
||||
/** Fired every frame while the player remains outside the bounds. */
|
||||
onOutside: (() => void) | null;
|
||||
|
||||
/** Convenience setter for both corners at once. */
|
||||
setBounds(min: Vec3, max: Vec3): void;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
interface OverworldTriggerConstructor {
|
||||
new(): never;
|
||||
}
|
||||
|
||||
declare var OverworldTrigger: OverworldTriggerConstructor;
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/** Player movement component. Controls walk and run speeds. */
|
||||
interface Player extends Component {
|
||||
/** Walk speed in world units per second. */
|
||||
speed: number;
|
||||
/** Run speed in world units per second. */
|
||||
runSpeed: number;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
interface PlayerConstructor {
|
||||
new(): never;
|
||||
}
|
||||
|
||||
declare var Player: PlayerConstructor;
|
||||
Vendored
+5
@@ -36,7 +36,12 @@
|
||||
// entity / components
|
||||
/// <reference path="./entity/component.d.ts" />
|
||||
/// <reference path="./entity/component/camera.d.ts" />
|
||||
/// <reference path="./entity/component/interactable.d.ts" />
|
||||
/// <reference path="./entity/component/overworld.d.ts" />
|
||||
/// <reference path="./entity/component/overworldcamera.d.ts" />
|
||||
/// <reference path="./entity/component/overworldtrigger.d.ts" />
|
||||
/// <reference path="./entity/component/physics.d.ts" />
|
||||
/// <reference path="./entity/component/player.d.ts" />
|
||||
/// <reference path="./entity/component/position.d.ts" />
|
||||
/// <reference path="./entity/component/renderable.d.ts" />
|
||||
/// <reference path="./entity/component/trigger.d.ts" />
|
||||
|
||||
Reference in New Issue
Block a user