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
|
#pragma once
|
||||||
#include "script/module/entity/modulecomponent.h"
|
#include "script/module/entity/modulecomponent.h"
|
||||||
#include "camera/modulecamera.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 "physics/modulephysics.h"
|
||||||
|
#include "player/moduleplayer.h"
|
||||||
#include "position/moduleposition.h"
|
#include "position/moduleposition.h"
|
||||||
#include "renderable/modulerenderable.h"
|
#include "renderable/modulerenderable.h"
|
||||||
#include "trigger/moduletrigger.h"
|
#include "trigger/moduletrigger.h"
|
||||||
@@ -24,8 +29,18 @@ static jerry_value_t moduleComponentListCreateInstance(
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case COMPONENT_TYPE_CAMERA:
|
case COMPONENT_TYPE_CAMERA:
|
||||||
return scriptProtoCreateValue(&MODULE_CAMERA_PROTO, comp);
|
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:
|
case COMPONENT_TYPE_PHYSICS:
|
||||||
return scriptProtoCreateValue(&MODULE_PHYSICS_PROTO, comp);
|
return scriptProtoCreateValue(&MODULE_PHYSICS_PROTO, comp);
|
||||||
|
case COMPONENT_TYPE_PLAYER:
|
||||||
|
return scriptProtoCreateValue(&MODULE_PLAYER_PROTO, comp);
|
||||||
case COMPONENT_TYPE_POSITION:
|
case COMPONENT_TYPE_POSITION:
|
||||||
return scriptProtoCreateValue(&MODULE_POSITION_PROTO, comp);
|
return scriptProtoCreateValue(&MODULE_POSITION_PROTO, comp);
|
||||||
case COMPONENT_TYPE_RENDERABLE:
|
case COMPONENT_TYPE_RENDERABLE:
|
||||||
@@ -39,7 +54,12 @@ static jerry_value_t moduleComponentListCreateInstance(
|
|||||||
|
|
||||||
static void moduleComponentListInit(void) {
|
static void moduleComponentListInit(void) {
|
||||||
moduleCameraInit();
|
moduleCameraInit();
|
||||||
|
moduleInteractableInit();
|
||||||
|
moduleOverworldInit();
|
||||||
|
moduleOverworldCameraInit();
|
||||||
|
moduleOverworldTriggerInit();
|
||||||
modulePhysicsInit();
|
modulePhysicsInit();
|
||||||
|
modulePlayerInit();
|
||||||
modulePositionInit();
|
modulePositionInit();
|
||||||
moduleRenderableInit();
|
moduleRenderableInit();
|
||||||
moduleTriggerInit();
|
moduleTriggerInit();
|
||||||
@@ -49,6 +69,11 @@ static void moduleComponentListDispose(void) {
|
|||||||
moduleTriggerDispose();
|
moduleTriggerDispose();
|
||||||
moduleRenderableDispose();
|
moduleRenderableDispose();
|
||||||
modulePositionDispose();
|
modulePositionDispose();
|
||||||
|
modulePlayerDispose();
|
||||||
modulePhysicsDispose();
|
modulePhysicsDispose();
|
||||||
|
moduleOverworldTriggerDispose();
|
||||||
|
moduleOverworldCameraDispose();
|
||||||
|
moduleOverworldDispose();
|
||||||
|
moduleInteractableDispose();
|
||||||
moduleCameraDispose();
|
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
|
// entity / components
|
||||||
/// <reference path="./entity/component.d.ts" />
|
/// <reference path="./entity/component.d.ts" />
|
||||||
/// <reference path="./entity/component/camera.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/physics.d.ts" />
|
||||||
|
/// <reference path="./entity/component/player.d.ts" />
|
||||||
/// <reference path="./entity/component/position.d.ts" />
|
/// <reference path="./entity/component/position.d.ts" />
|
||||||
/// <reference path="./entity/component/renderable.d.ts" />
|
/// <reference path="./entity/component/renderable.d.ts" />
|
||||||
/// <reference path="./entity/component/trigger.d.ts" />
|
/// <reference path="./entity/component/trigger.d.ts" />
|
||||||
|
|||||||
Reference in New Issue
Block a user