#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 T& Scripting::getContextEntityComponent(EntityHandle handle) { asIScriptContext* context = asGetActiveContext(); ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData(); return environmentData->world->entityEnvironment->getEntity(handle.entityId).getComponent(); } EntityHandle Scripting::entity_getSelf(EntityHandle& handle) { return handle; } std::string Scripting::entity_getName(EntityHandle& handle) { return getContextEntity(handle).getComponent().tag; } int Scripting::entity_getId(EntityHandle& handle) { return handle.entityId; } void Scripting::entity_setName(std::string& name, EntityHandle& handle) { getContextEntity(handle).getComponent().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(handle).networkBehaviour; } void Scripting::entity_setNetworkBehaviour(int value, EntityHandle& handle) { getContextEntityComponent(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"); CScriptArray* array = CScriptArray::Create(arrayStringType); RelationshipComponent& relationship = entity.getComponent(); 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().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(); #ifdef DEER_RENDER } else if (componentName == "MeshComponent") { self_entity.addComponent(); } else if (componentName == "CameraComponent") { self_entity.addComponent(); #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(); #ifdef DEER_RENDER } else if (componentName == "MeshComponent") { self_entity.removeComponent(); } else if (componentName == "CameraComponent") { self_entity.removeComponent(); #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()); #ifdef DEER_RENDER } else if (componentName == "MeshComponent") { generic->SetReturnByte(self_entity.hasComponent()); } else if (componentName == "CameraComponent") { generic->SetReturnByte(self_entity.hasComponent()); #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(handle); return transformComponent.position; } glm::vec3 Scripting::transform_getScale(EntityHandle& handle) { TransformComponent& transformComponent = getContextEntityComponent(handle); return transformComponent.scale; } glm::vec3 Scripting::transform_getRotation(EntityHandle& handle) { TransformComponent& transformComponent = getContextEntityComponent(handle); return transformComponent.getEulerAngles(); } void Scripting::transform_setPosition(glm::vec3 position, EntityHandle& handle) { TransformComponent& transformComponent = getContextEntityComponent(handle); transformComponent.position = position; } void Scripting::transform_setScale(glm::vec3 scale, EntityHandle& handle) { TransformComponent& transformComponent = getContextEntityComponent(handle); transformComponent.scale = scale; } void Scripting::transform_setRotation(glm::vec3 rotation, EntityHandle& handle) { TransformComponent& transformComponent = getContextEntityComponent(handle); transformComponent.setEulerAngles(rotation); } void Scripting::constructEntityStruct(void* memory) { new (memory) EntityHandle(); } void Scripting::destructEntityStruct(void* memory) {} } // namespace Deer