2026-03-01 17:48:56 +01:00

257 lines
9.1 KiB
C++

#include "DeerCore/Scripting/InternalAPI/Entity.h"
#include "DeerCore/Scripting/ScriptEnvironmentContextData.h"
#include "DeerCore/EntityEnviroment.h"
#include "angelscript.h"
#include "scriptarray.h"
#ifdef DEER_RENDER
#include "DeerRender/Mesh.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Texture.h"
#include "DeerRender/World.h"
#endif
namespace Deer {
namespace Scripting {
extern asIScriptEngine* scriptEngine;
}
Entity& Scripting::getContextEntity(EntityHandle handle) {
asIScriptContext* context = asGetActiveContext();
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
return environmentData->world->entityEnvironment->getEntity(handle.entityId);
}
EntityEnvironment& Scripting::getContextEntityEnvironment(EntityHandle handle) {
asIScriptContext* context = asGetActiveContext();
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
return *environmentData->world->entityEnvironment.get();
}
template <typename T>
T& Scripting::getContextEntityComponent(EntityHandle handle) {
asIScriptContext* context = asGetActiveContext();
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
return environmentData->world->entityEnvironment->getEntity(handle.entityId).getComponent<T>();
}
EntityHandle Scripting::entity_getSelf(EntityHandle& handle) {
return handle;
}
std::string Scripting::entity_getName(EntityHandle& handle) {
return getContextEntity(handle).getComponent<TagComponent>().tag;
}
int Scripting::entity_getId(EntityHandle& handle) {
return handle.entityId;
}
void Scripting::entity_setName(std::string& name, EntityHandle& handle) {
getContextEntity(handle).getComponent<TagComponent>().tag = name;
}
bool Scripting::entity_exists(EntityHandle& handle) {
return getContextEntityEnvironment(handle).entityExists(handle.entityId);
}
bool Scripting::entity_isRoot(EntityHandle& handle) {
return handle.entityId == 0;
}
void Scripting::entity_destroy(EntityHandle& handle) {
getContextEntity(handle).destroy();
}
glm::mat4 Scripting::entity_getWorldMatrix(EntityHandle& handle) {
Entity& entity = getContextEntity(handle);
return entity.getWorldMatrix();
}
int Scripting::entity_getNetworkBehaviour(EntityHandle& handle) {
return (int)getContextEntityComponent<TagComponent>(handle).networkBehaviour;
}
void Scripting::entity_setNetworkBehaviour(int value, EntityHandle& handle) {
getContextEntityComponent<TagComponent>(handle).networkBehaviour = (EntityNetworkBehaviour)value;
}
int Scripting::entity_getForcedNetworkBehaviour(EntityHandle& handle) {
return (int)getContextEntity(handle).getForcedNetworkBehaviour();
}
bool Scripting::entity_isValidNetworkBehaviour(EntityHandle& handle) {
return getContextEntity(handle).isValidNetworkBehaviour();
}
CScriptArray* Scripting::entity_getChildrens(EntityHandle& handle) {
Entity& entity = getContextEntity(handle);
asITypeInfo* arrayStringType = scriptEngine->GetTypeInfoByDecl("array<Entity>");
CScriptArray* array = CScriptArray::Create(arrayStringType);
RelationshipComponent& relationship = entity.getComponent<RelationshipComponent>();
size_t childCount = relationship.getChildCount();
for (size_t i = 0; i < childCount; i++) {
EntityHandle entity(relationship.getChildId(i));
array->Resize(array->GetSize() + 1);
array->SetValue(array->GetSize() - 1, &entity);
}
return array;
}
EntityHandle Scripting::entity_createChild(std::string& childName, EntityHandle& handle) {
Entity& child = getContextEntityEnvironment(handle).createEntity();
Entity& self = getContextEntity(handle);
child.setParent(self);
child.getComponent<TagComponent>().tag = childName;
return EntityHandle(child.getId());
}
void Scripting::entity_setParent(EntityHandle other_handle, EntityHandle& self_handle) {
Entity& child = getContextEntity(other_handle);
Entity& self = getContextEntity(self_handle);
self.setParent(child);
}
EntityHandle Scripting::entity_getParent(EntityHandle& handle) {
return EntityHandle(getContextEntity(handle).getParentId());
}
bool Scripting::entity_isDescendantOf(EntityHandle other_handle, EntityHandle& self_handle) {
Entity& child = getContextEntity(other_handle);
Entity& self = getContextEntity(self_handle);
return self.isDescendantOf(child);
}
bool Scripting::entity_opEquals(EntityHandle& other, EntityHandle& self_handle) {
return other.entityId == self_handle.entityId;
}
void Scripting::entity_addGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
EntityHandle* return_handle = (EntityHandle*)generic->GetAddressOfReturnLocation();
*return_handle = handle;
if (componentName == "TransformComponent") {
self_entity.addComponent<TransformComponent>();
#ifdef DEER_RENDER
} else if (componentName == "MeshComponent") {
self_entity.addComponent<MeshComponent>();
} else if (componentName == "CameraComponent") {
self_entity.addComponent<CameraComponent>();
#endif
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
void Scripting::entity_removeGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
if (componentName == "TransformComponent") {
self_entity.removeComponent<TransformComponent>();
#ifdef DEER_RENDER
} else if (componentName == "MeshComponent") {
self_entity.removeComponent<MeshComponent>();
} else if (componentName == "CameraComponent") {
self_entity.removeComponent<CameraComponent>();
#endif
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
void Scripting::entity_getGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
EntityHandle* return_handle = (EntityHandle*)generic->GetAddressOfReturnLocation();
*return_handle = handle;
if (componentName == "TransformComponent") {
// Some checks
} else if (componentName == "MeshComponent") {
// Some checks
} else if (componentName == "CameraComponent") {
// Some checks
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
void Scripting::entity_hasGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
if (componentName == "TransformComponent") {
generic->SetReturnByte(self_entity.hasComponent<TransformComponent>());
#ifdef DEER_RENDER
} else if (componentName == "MeshComponent") {
generic->SetReturnByte(self_entity.hasComponent<MeshComponent>());
} else if (componentName == "CameraComponent") {
generic->SetReturnByte(self_entity.hasComponent<CameraComponent>());
#endif
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
// SPECIFIC TRANSFORM SECTION
glm::vec3 Scripting::transform_getPosition(EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
return transformComponent.position;
}
glm::vec3 Scripting::transform_getScale(EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
return transformComponent.scale;
}
glm::vec3 Scripting::transform_getRotation(EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
return transformComponent.getEulerAngles();
}
void Scripting::transform_setPosition(glm::vec3 position, EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
transformComponent.position = position;
}
void Scripting::transform_setScale(glm::vec3 scale, EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
transformComponent.scale = scale;
}
void Scripting::transform_setRotation(glm::vec3 rotation, EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
transformComponent.setEulerAngles(rotation);
}
void Scripting::constructEntityStruct(void* memory) {
new (memory) EntityHandle();
}
void Scripting::destructEntityStruct(void* memory) {}
} // namespace Deer