Files
Nuake-custom/Nuake/src/Scripting/Modules/SceneModule.h
2024-09-15 21:34:37 +01:00

461 lines
15 KiB
C++

#pragma once
#include "wren.h"
#include <string>
#include <src/Core/Logger.h>
#include "ScriptModule.h"
#include <iostream>
#include <wren.h>
#include "Engine.h"
#include "src/Physics/PhysicsManager.h"
#include "../Scene/Entities/Entity.h"
#include <src/Scene/Components/TransformComponent.h>
#include <src/Scene/Components/LightComponent.h>
#include <src/Scene/Components/QuakeMap.h>
#include <src/Scene/Components/CameraComponent.h>
#include <src/Scene/Components/RigidbodyComponent.h>
#include <src/Scene/Components/CharacterControllerComponent.h>
#include <src/Scene/Components/WrenScriptComponent.h>
#include <src/Scene/Components/BSPBrushComponent.h>
#include <src/Scene/Components/PrefabComponent.h>
#include <src/Scene/Components/AudioEmitterComponent.h>
namespace Nuake
{
namespace ScriptAPI
{
class SceneModule : public ScriptModule
{
std::string GetModuleName() override
{
return "Scene";
}
void RegisterModule(WrenVM* vm) override
{
RegisterMethod("CreateEntity(_)", (void*)CreateEntity);
RegisterMethod("AddPrefab(_)", (void*)AddPrefab);
RegisterMethod("GetEntityID(_)", (void*)GetEntity);
RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent);
RegisterMethod("GetTranslation_(_)", (void*)GetTranslation);
RegisterMethod("GetLocalTranslation_(_)", (void*)GetLocalTranslation);
RegisterMethod("SetTranslation_(_,_,_,_)", (void*)SetTranslation);
RegisterMethod("GetRotation_(_)", (void*)GetRotation);
RegisterMethod("SetRotation_(_,_,_,_)", (void*)SetRotation);
RegisterMethod("SetLookAt_(_,_,_,_)", (void*)SetLookAt);
RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity);
RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity);
RegisterMethod("GetScript_(_)", (void*)GetScript);
RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection);
RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection);
RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight);
RegisterMethod("SetAudioEmitterPlaying_(_,_)", (void*)SetAudioEmitterPlaying);
RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide);
RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround);
RegisterMethod("RayCast_(_,_,_,_,_,_)", (void*)Raycast);
RegisterMethod("AddForce_(_,_,_,_)", (void*)AddForce);
RegisterMethod("TriggerGetOverlappingBodyCount_(_)", (void*)TriggerGetOverlappingBodyCount);
RegisterMethod("TriggerGetOverlappingBodies_(_)", (void*)TriggerGetOverlappingBodies);
RegisterMethod("BrushGetTargets_(_)", (void*)BrushGetTargets);
RegisterMethod("BrushGetTargetsCount_(_)", (void*)BrushGetTargetsCount);
}
static void CreateEntity(WrenVM* vm)
{
const std::string name = wrenGetSlotString(vm, 1);
const int entity = Engine::GetCurrentScene()->CreateEntity(name).GetHandle();
wrenSetSlotDouble(vm, 0, entity);
}
static void GetEntity(WrenVM* vm)
{
std::string name = wrenGetSlotString(vm, 1);
int handle = Engine::GetCurrentScene()->GetEntity(name).GetHandle();
wrenSetSlotDouble(vm, 0, handle);
}
static void AddPrefab(WrenVM* vm)
{
const std::string& prefabPath = wrenGetSlotString(vm, 1);
if (prefabPath.empty())
{
Logger::Log("Cannot add prefab with an empty path.", "script", CRITICAL);
wrenSetSlotDouble(vm, 0, -1); // -1 is an empty entity.
return;
}
const std::string& prefabName = wrenGetSlotString(vm, 1);
if (prefabName.empty())
{
Logger::Log("Cannot add prefab with an empty name.", "script", CRITICAL);
wrenSetSlotDouble(vm, 0, -1); // -1 is an empty entity.
return;
}
if (!FileSystem::FileExists(prefabPath))
{
Logger::Log("Cannot add prefab. File not found: " + prefabPath, "script", CRITICAL);
return;
}
const auto& prefab = Prefab::New(prefabPath);
wrenSetSlotDouble(vm, 0, prefab->Root.GetHandle());
}
static void EntityHasComponent(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
std::string name = wrenGetSlotString(vm, 2);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
bool result = false;
if (handle == -1)
{
wrenSetSlotBool(vm, 0, result);
return;
}
if (name == "Transform") result = ent.HasComponent<TransformComponent>();
if (name == "Light") result = ent.HasComponent<LightComponent>();
if (name == "QuakeMap") result = ent.HasComponent<QuakeMapComponent>();
if (name == "RigidBody") result = ent.HasComponent<RigidBodyComponent>();
if (name == "CharacterController")
{
result = ent.HasComponent<CharacterControllerComponent>();
}
if (name == "Camera")
{
result = ent.HasComponent<CameraComponent>();
}
if (name == "Script")
{
result = ent.HasComponent<WrenScriptComponent>();
}
if (name == "Rigidbody")
{
result = ent.HasComponent<RigidBodyComponent>();
}
if (name == "Script") {
result = ent.HasComponent<WrenScriptComponent>();
}
if (name == "Brush") {
result = ent.HasComponent<BSPBrushComponent>();
}
if (name == "AudioEmitter") {
result = ent.HasComponent<AudioEmitterComponent>();
}
wrenSetSlotBool(vm, 0, result);
}
static void GetScript(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
if (ent.HasComponent<WrenScriptComponent>())
{
wrenSetSlotHandle(vm, 0, ent.GetComponent<WrenScriptComponent>().mWrenScript->GetWrenInstanceHandle());
}
}
static void SetLightIntensity(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
double intensity = wrenGetSlotDouble(vm, 2);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& light = ent.GetComponent<LightComponent>();
light.Strength = static_cast<float>(intensity);
}
static void GetLightIntensity(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
double intensity = wrenGetSlotDouble(vm, 2);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& light = ent.GetComponent<LightComponent>();
wrenSetSlotDouble(vm, 0, light.Strength);
}
static void SetCameraDirection(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
double x = wrenGetSlotDouble(vm, 2);
double y = wrenGetSlotDouble(vm, 3);
double z = wrenGetSlotDouble(vm, 4);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& cam = ent.GetComponent<CameraComponent>();
cam.CameraInstance->SetDirection(Vector3(x, y, z));
}
static void GetCameraDirection(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& cam = ent.GetComponent<CameraComponent>();
Vector3 dir = cam.CameraInstance->GetDirection();
wrenEnsureSlots(vm, 4);
// set the slots
// Fill the list
wrenSetSlotNewList(vm, 0);
wrenSetSlotDouble(vm, 1, dir.x);
wrenSetSlotDouble(vm, 2, dir.y);
wrenSetSlotDouble(vm, 3, dir.z);
wrenInsertInList(vm, 0, -1, 1);
wrenInsertInList(vm, 0, -1, 2);
wrenInsertInList(vm, 0, -1, 3);
}
static void GetCameraRight(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& cam = ent.GetComponent<CameraComponent>();
Vector3 right = cam.CameraInstance->GetRight();
// set the slots
wrenSetSlotDouble(vm, 1, right.x);
wrenSetSlotDouble(vm, 2, right.y);
wrenSetSlotDouble(vm, 3, right.z);
// Fill the list
wrenSetSlotNewList(vm, 0);
wrenInsertInList(vm, 0, 0, 1);
wrenInsertInList(vm, 0, 1, 2);
wrenInsertInList(vm, 0, 2, 3);
}
static void SetAudioEmitterPlaying(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& audioEmitter = ent.GetComponent<AudioEmitterComponent>();
bool isPlaying = wrenGetSlotBool(vm, 2);
audioEmitter.IsPlaying = isPlaying;
}
static void IsCharacterControllerOnGround(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& characterController = ent.GetComponent<CharacterControllerComponent>();
bool result = PhysicsManager::Get().GetWorld()->IsCharacterGrounded(ent);
wrenSetSlotBool(vm, 0, result);
}
static void Raycast(WrenVM* vm)
{
const double& fromX = wrenGetSlotDouble(vm, 1);
const double& fromY = wrenGetSlotDouble(vm, 2);
const double& fromZ = wrenGetSlotDouble(vm, 3);
const auto& from = Vector3(fromX, fromY, fromZ);
const double& toX = wrenGetSlotDouble(vm, 4);
const double& toY = wrenGetSlotDouble(vm, 5);
const double& toZ = wrenGetSlotDouble(vm, 6);
const auto& to = Vector3(toX, toY, toZ);
const auto& result = PhysicsManager::Get().GetWorld()->Raycast(from, to);
}
static void MoveAndSlide(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
double x = wrenGetSlotDouble(vm, 2);
double y = wrenGetSlotDouble(vm, 3);
double z = wrenGetSlotDouble(vm, 4);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& characterController = ent.GetComponent<CharacterControllerComponent>();
characterController.GetCharacterController()->MoveAndSlide(Vector3(x, y, z));
}
static void AddForce(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
double x = wrenGetSlotDouble(vm, 2);
double y = wrenGetSlotDouble(vm, 3);
double z = wrenGetSlotDouble(vm, 4);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& rigidBodyComponent = ent.GetComponent<RigidBodyComponent>();
rigidBodyComponent.QueuedForce += Vector3(x, y, z);
}
static void GetTranslation(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
Vector3 position = transform.GetGlobalPosition();
wrenSetSlotDouble(vm, 1, position.x);
wrenSetSlotDouble(vm, 2, position.y);
wrenSetSlotDouble(vm, 3, position.z);
// Fill the list
wrenSetSlotNewList(vm, 0);
wrenInsertInList(vm, 0, 0, 1);
wrenInsertInList(vm, 0, 1, 2);
wrenInsertInList(vm, 0, 2, 3);
}
static void GetLocalTranslation(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
Vector3 position = transform.GetLocalPosition();
wrenSetSlotDouble(vm, 1, position.x);
wrenSetSlotDouble(vm, 2, position.y);
wrenSetSlotDouble(vm, 3, position.z);
// Fill the list
wrenSetSlotNewList(vm, 0);
wrenInsertInList(vm, 0, 0, 1);
wrenInsertInList(vm, 0, 1, 2);
wrenInsertInList(vm, 0, 2, 3);
}
static void GetRotation(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
wrenSetSlotDouble(vm, 1, transform.Rotation.x);
wrenSetSlotDouble(vm, 2, transform.Rotation.y);
wrenSetSlotDouble(vm, 3, transform.Rotation.z);
// Fill the list
wrenSetSlotNewList(vm, 0);
wrenInsertInList(vm, 0, 0, 1);
wrenInsertInList(vm, 0, 1, 2);
wrenInsertInList(vm, 0, 2, 3);
}
static void SetRotation(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
float x = (float)wrenGetSlotDouble(vm, 2);
float y = (float)wrenGetSlotDouble(vm, 3);
float z = (float)wrenGetSlotDouble(vm, 4);
transform.SetLocalRotation(QuatFromEuler(x, y, z));
}
static void SetLookAt(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
float x = (float)wrenGetSlotDouble(vm, 2);
float y = (float)wrenGetSlotDouble(vm, 3);
float z = (float)wrenGetSlotDouble(vm, 4);
Vector3 targetPosition = Vector3(x, y, z);
Quat rotation = LookAt(transform.GetGlobalPosition(), transform.GetGlobalPosition() + targetPosition);
transform.SetLocalRotation(rotation);
}
static void SetTranslation(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
double x = wrenGetSlotDouble(vm, 2);
double y = wrenGetSlotDouble(vm, 3);
double z = wrenGetSlotDouble(vm, 4);
transform.SetLocalPosition(Vector3(x, y, z));
}
static void TriggerGetOverlappingBodyCount(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
int count = 0;
wrenSetSlotDouble(vm, 0, count);
}
static void TriggerGetOverlappingBodies(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
std::vector<Entity> entities = {};
wrenEnsureSlots(vm, static_cast<int>(entities.size()));
wrenSetSlotNewList(vm, 0);
int idx = 1;
for (auto& e : entities)
{
wrenSetSlotDouble(vm, idx, e.GetHandle());
wrenInsertInList(vm, 0, -1, idx);
idx++;
}
}
static void BrushGetTargets(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
BSPBrushComponent& brush = ent.GetComponent<BSPBrushComponent>();
wrenEnsureSlots(vm, static_cast<int>(brush.Targets.size()));
wrenSetSlotNewList(vm, 0);
int idx = 1;
for (auto& e : brush.Targets)
{
wrenSetSlotDouble(vm, idx, e.GetHandle());
wrenInsertInList(vm, 0, -1, idx);
idx++;
}
}
static void BrushGetTargetsCount(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
BSPBrushComponent& brush = ent.GetComponent<BSPBrushComponent>();
wrenSetSlotDouble(vm, 0, static_cast<int>(brush.Targets.size()));
}
};
}
}