From 79898c42d652a345dcf4fea4ce67fe389a40d42d Mon Sep 17 00:00:00 2001 From: ugozapad Date: Sat, 7 Mar 2026 17:25:11 +0300 Subject: [PATCH] Big big update --- data/levels/cemetery/cemetery.xml | 5 + data/levels/zavod/zavod.xml | 7 +- data/scripts/game_hud.lua | 19 ++- data/scripts/game_init.lua | 22 ++- data/scripts/triggers/trigger_deleter.lua | 24 +++ data/scripts/weapons/weapon_base.lua | 7 +- data/scripts/weapons/weapon_ump.lua | 6 +- src/engine/engine.cpp | 15 ++ src/engine/world.h | 1 - src/game/actor_base.cpp | 6 + src/game/game.cpp | 39 ++++- src/game/game.h | 2 + src/game/game_lua_help.cpp | 15 ++ src/game/game_lua_help.h | 1 + src/game/game_object.cpp | 175 ++++++++++++++++++++-- src/game/game_object.h | 18 +++ src/game/game_world_objects.cpp | 59 +++++++- src/game/game_world_objects.h | 7 + src/render/model.cpp | 2 +- src/render/scenemanager.cpp | 26 +++- src/render/scenemanager.h | 10 +- src/sound/soundsystem.cpp | 4 + 22 files changed, 423 insertions(+), 47 deletions(-) create mode 100644 data/scripts/triggers/trigger_deleter.lua diff --git a/data/levels/cemetery/cemetery.xml b/data/levels/cemetery/cemetery.xml index 2dd0d07..09c7ed7 100644 --- a/data/levels/cemetery/cemetery.xml +++ b/data/levels/cemetery/cemetery.xml @@ -25,5 +25,10 @@ --> + + + + + \ No newline at end of file diff --git a/data/levels/zavod/zavod.xml b/data/levels/zavod/zavod.xml index ab13be4..6ea36ec 100644 --- a/data/levels/zavod/zavod.xml +++ b/data/levels/zavod/zavod.xml @@ -2,6 +2,7 @@ + @@ -22,7 +23,7 @@ - + @@ -38,14 +39,14 @@ - + - + diff --git a/data/scripts/game_hud.lua b/data/scripts/game_hud.lua index e874379..5391acc 100644 --- a/data/scripts/game_hud.lua +++ b/data/scripts/game_hud.lua @@ -4,7 +4,8 @@ local BLUE_COLOR = { 0.0, 0.0, 1.0, 1.0 } local BLACK_COLOR = { 0.0, 0.0, 0.0, 1.0 } local WHITE_COLOR = { 1.0, 1.0, 1.0, 1.0 } -local draw_test_hud = false +local draw_test_hud = true +local draw_example_test_hud = true local draw_debug_string = false local debug_string_text = "" local debug_string_time = 0.0 @@ -15,14 +16,16 @@ function game_hud_draw( ) return end - -- example of color - local color = { 0.5, 0.5, 0.1, 1.0 } + if draw_example_test_hud then + -- example of color + local color = { 0.5, 0.5, 0.1, 1.0 } + + -- example of drawing + ui.draw_rect(100.0, 100.0, 400.0, 400.0, BLUE_COLOR) + ui.draw_image("data/textures/koshka1.jpg", 110.0, 110.0, 390.0, 390.0, WHITE_COLOR) + ui.draw_text("Hello, world!", 200.0, 200.0, GREEN_COLOR) + end - -- example of drawing - ui.draw_rect(150.0, 150.0, 350.0, 350.0, BLUE_COLOR) - ui.draw_image("data/textures/koshka1.jpg", 160.0, 160.0, 340.0, 340.0, WHITE_COLOR) - ui.draw_text("Hello, world!", 200.0, 200.0, GREEN_COLOR) - if g_player then game_player_hud_draw() end diff --git a/data/scripts/game_init.lua b/data/scripts/game_init.lua index 28f0755..84c5e88 100644 --- a/data/scripts/game_init.lua +++ b/data/scripts/game_init.lua @@ -7,13 +7,13 @@ load_script("game_object.lua") load_script("test_object.lua") load_script("weapons/weapon_base.lua") - load_script("weapons/weapon_ump.lua") load_script("actors/actor_base.lua") - load_script("actors/actor_player.lua") +load_script("triggers/trigger_deleter.lua") + -- глобальные переменные g_player = nil @@ -22,18 +22,24 @@ g_entity_table = { -- Lua class -- CPP class -- Description -- Actors - - { "actor_player", "ActorBase", "Player entity" }, + { "actor_player", "ActorBase", "Player entity" }, -- Weapons - { "weapon_ump", "WeaponBase", "Weapon UMP" }, + { "weapon_ump", "WeaponBase", "Weapon UMP" }, + + -- Triggers + { "trigger_deleter", "TriggerBase", "Example trigger" }, -- Simple entity - { "test_object", "Entity", "Test entity" }, - - + { "test_object", "Entity", "Test entity" }, } function sv_game_init( ) console.print("--- Game initialization ---") end + +function sv_on_game_start( ) + console.print("Welcome to our Engine") + + +end diff --git a/data/scripts/triggers/trigger_deleter.lua b/data/scripts/triggers/trigger_deleter.lua new file mode 100644 index 0000000..b5cc961 --- /dev/null +++ b/data/scripts/triggers/trigger_deleter.lua @@ -0,0 +1,24 @@ +-- тестовый класс +trigger_deleter = inherit_table(game_object) + +function trigger_deleter:on_init() + game_object.on_init(self) + + self:create_box_body(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, true, false) +end + +function trigger_deleter:on_shutdown() + game_object.on_shutdown(self) +end + +function trigger_deleter:on_update(dt) + game_object.on_shutdown(self, dt) +end + +function trigger_deleter:on_collide(other) + console.print(string.format("trigger_deleter:on_collide: %s", other:get_classname())) + put_debug_string_to_screen(string.format("trigger_deleter:on_collide: %s", other:get_classname()), 4) + + -- FOR TEST + other:mark_for_delete() +end \ No newline at end of file diff --git a/data/scripts/weapons/weapon_base.lua b/data/scripts/weapons/weapon_base.lua index a856c8a..15bc625 100644 --- a/data/scripts/weapons/weapon_base.lua +++ b/data/scripts/weapons/weapon_base.lua @@ -45,7 +45,8 @@ function weapon_base:on_fsm_state_update(dt) -- проверка на стрельбу if (self.m_state == WEAPON_FSM_STATE_ATTACK or - self.m_state == WEAPON_FSM_STATE_ATTACK2) and + self.m_state == WEAPON_FSM_STATE_ATTACK2 or + self.m_state == WEAPON_FSM_STATE_RELOAD) and self.m_state_time >= self.m_end_state_time then -- переходим в ожидание @@ -113,6 +114,10 @@ function weapon_base:on_state_switch(state) local anim_id = self:find_animation(fsm_state.anim) self:play_animation(anim_id, fsm_state.anim_playback) + + if fsm_state.anim_sound then + engine.play_sound(fsm_state.anim_sound) + end end function weapon_base:set_relative_position_to_camera( ent ) diff --git a/data/scripts/weapons/weapon_ump.lua b/data/scripts/weapons/weapon_ump.lua index 5c22485..3f73031 100644 --- a/data/scripts/weapons/weapon_ump.lua +++ b/data/scripts/weapons/weapon_ump.lua @@ -17,14 +17,16 @@ weapon_ump.m_fsm[WEAPON_FSM_STATE_IDLE] = { weapon_ump.m_fsm[WEAPON_FSM_STATE_ATTACK] = { anim = "shoot1", -- имя анимации anim_playback = ANIM_PLAYBACK_NONE, - anim_speed = 1.0 -- обычная скорость анимации + anim_speed = 1.0, -- обычная скорость анимации + anim_sound = "data/sounds/weapons/ump45_shoot.wav" } -- перезарядка weapon_ump.m_fsm[WEAPON_FSM_STATE_RELOAD] = { anim = "reload", -- имя анимации anim_playback = ANIM_PLAYBACK_NONE, - anim_speed = 1.0 -- обычная скорость анимации + anim_speed = 1.0, -- обычная скорость анимации + anim_sound = "data/sounds/weapons/ump45_reload.wav" } function weapon_ump:on_init() diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 826e826..f8d3a3d 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -113,6 +113,7 @@ struct ExampleAppConsole Commands.push_back("r_entity_debug_draw"); Commands.push_back("r_light_debug_draw"); Commands.push_back("noclip"); + Commands.push_back("print_pos"); Commands.push_back("map"); Commands.push_back("quit"); AutoScroll = true; @@ -359,6 +360,20 @@ struct ExampleAppConsole { toggleNoclip(); } + else if (Stricmp(command_line, "PRINT_POS") == 0) + { + Camera* camera = g_cameraManager.GetActiveCamera(); + if (camera) + { + Logger::Msg("pos: %f %f %f", camera->GetPosition().x, camera->GetPosition().y, camera->GetPosition().z); + Logger::Msg("", camera->GetPosition().x, camera->GetPosition().y, camera->GetPosition().z); + Logger::Msg("local x, y, z = %.2f, %.2f, %.2f", camera->GetPosition().x, camera->GetPosition().y, camera->GetPosition().z); + } + else + { + Logger::Msg("print_pos: no active camera!"); + } + } else if (Stricmp(command_line, "MAP") == 0) { GetEngine()->NewGame(full_command_line + 4); diff --git a/src/engine/world.h b/src/engine/world.h index d307889..4692c74 100644 --- a/src/engine/world.h +++ b/src/engine/world.h @@ -21,7 +21,6 @@ public: void DeleteEntity(int index); int GetNumEntities(); - IEntityBase* GetEntity(int index); int FindEntityId(IEntityBase* pEntity); diff --git a/src/game/actor_base.cpp b/src/game/actor_base.cpp index 3dd3b00..c7546e1 100644 --- a/src/game/actor_base.cpp +++ b/src/game/actor_base.cpp @@ -100,6 +100,10 @@ void ActorBase::UpdateBodyMovement(float dt) m_rigidBody->setLinearVelocity(btVector3(airvel.x(), currentvel.y(), airvel.z())); } + if (m_noclip && movementDir == EMouseButton_None) { + m_rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); + } + /*if (glm::length(velocity) > 0.1f && OnGround() && !(movementDir & EMovementDir_Jump)) m_rigidBody->setLinearVelocity(glmVectorToBt(velocity)); @@ -387,6 +391,8 @@ int ActorBase::GenAction() action = 1; else if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_R)) action = 2; + else if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_E)) + action = 3; return action; } diff --git a/src/game/game.cpp b/src/game/game.cpp index b94d364..d4f21bd 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -127,6 +127,19 @@ LuaPlus::LuaObject engineGetEntityFromID(lua_Integer id) return entityTable; } +LuaPlus::LuaObject engineFindEntityByName(const char* name) +{ + Entity* entity = (Entity*)g_game->FindEntityByName(name); + if (!entity) + { + LuaPlus::LuaObject table; + table.AssignNil(GetLuaState()); + return table; + } + + return entity->GetLuaObject(); +} + void engineAddEntityToWorld(LuaPlus::LuaObject& object) { LuaPlus::LuaObject cppclass = object["__object"]; @@ -184,6 +197,7 @@ void registerEngine() engineTable.RegisterDirect("create_entity", &engineCreateEntity); engineTable.RegisterDirect("add_entity_to_world", &engineAddEntityToWorld); engineTable.RegisterDirect("get_entity_from_id", &engineGetEntityFromID); + engineTable.RegisterDirect("find_entity_by_name", &engineFindEntityByName); engineTable.RegisterDirect("play_sound", &enginePlaySound); engineTable.RegisterDirect("play_sound_3d", &enginePlaySound3D); engineTable.RegisterDirect("get_delta", &engineGetDelta); @@ -469,11 +483,15 @@ void Game::Init() { initializeLua(); initializeEntitiesTable(); + + luaCallFunction("sv_game_init"); } void Game::InitForNewMap(const char* mapname) { LoadLevelXML(mapname); + + luaCallFunction("sv_on_game_start"); } void Game::LoadLevelXML(const char* mapname) @@ -519,6 +537,9 @@ void Game::LoadLevelXML(const char* mapname) // Create entity and expose it to the engine Entity* entity = static_cast(Lua_CreateEntity(classname.as_string())); + if (!entityname.empty()) + entity->SetName(entityname.as_string()); + pugi::xml_node position = entitynode.child("Position"); if (position) { @@ -603,7 +624,7 @@ IEntityBase* Game::Lua_CreateEntity(const char* classname) // create an table LuaObject entityTable = GetLuaState().CreateTable(); - entityTable.SetString("m_name", entityname); + entityTable.SetString("__private_name", entityname); entityTable.SetInteger("m_id", entity->GetID()); // assign prototype @@ -640,6 +661,22 @@ LuaPrototype* Game::Lua_FindPrototype(const char* classname) return nullptr; } +IEntityBase* Game::FindEntityByName(const char* name) +{ + if (!g_world) + return nullptr; + + int numEntities = g_world->GetNumEntities(); + for (int i = 0; i < numEntities; i++) + { + Entity* entity = dynamic_cast(g_world->GetEntity(i)); + if (entity && entity->GetName() == name) + return entity; + } + + return nullptr; +} + void Game::Shutdown() { } diff --git a/src/game/game.h b/src/game/game.h index 725fdcd..12f069a 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -16,6 +16,8 @@ public: LuaPrototype* Lua_FindPrototype(const char* classname); + IEntityBase* FindEntityByName(const char* name); + void Shutdown(); void Render2D(); diff --git a/src/game/game_lua_help.cpp b/src/game/game_lua_help.cpp index 252a094..6dd8f03 100644 --- a/src/game/game_lua_help.cpp +++ b/src/game/game_lua_help.cpp @@ -1,5 +1,6 @@ #include #include "core.h" +#include "log.h" #include "game_lua_help.h" class LuaStateWrapper @@ -84,6 +85,20 @@ void luaDoString(const char* str) } } +void luaCallFunction(const char* name) +{ + LuaPlus::LuaObject onGameStart = GetLuaState().GetGlobal(name); + if (onGameStart.IsFunction()) + { + LuaPlus::LuaFunctionVoid function = onGameStart; + function(); + } + else + { + Msg("missing function '%s'", name); + } +} + glm::mat4 getMatrixFromLua(LuaPlus::LuaObject& matrix) { glm::mat4 return_matrix = glm::identity(); diff --git a/src/game/game_lua_help.h b/src/game/game_lua_help.h index f1247a0..9156796 100644 --- a/src/game/game_lua_help.h +++ b/src/game/game_lua_help.h @@ -11,6 +11,7 @@ LuaPlus::LuaState& GetLuaState(); void luaLoadScript(const char* filename); void luaDoString(const char* str); +void luaCallFunction(const char* name); glm::mat4 getMatrixFromLua(LuaPlus::LuaObject& matrix); diff --git a/src/game/game_object.cpp b/src/game/game_object.cpp index 96c5093..138b730 100644 --- a/src/game/game_object.cpp +++ b/src/game/game_object.cpp @@ -1,5 +1,6 @@ #include "core.h" #include "inputmanager.h" +#include "log.h" #include "debugrender.h" #include "game_object.h" #include @@ -185,6 +186,8 @@ void Entity::InitFromTable(LuaPlus::LuaObject& _object) // register entity functions RegisterFunctions(); + m_luaObject.SetString("m_name", m_name.c_str()); + // assign C++ object m_luaObject.SetLightUserdata("__object", this); } @@ -210,11 +213,15 @@ void Entity::RegisterBaseFunctions() m_luaObject.Register("get_classname", *this, &Entity::Lua_GetClassname); m_luaObject.Register("get_id", *this, &Entity::Lua_GetID); m_luaObject.Register("mark_for_delete", *this, &Entity::Lua_MarkForDelete); + m_luaObject.Register("set_name", *this, &Entity::Lua_SetName); + m_luaObject.Register("get_name", *this, &Entity::Lua_GetName); // physics m_luaObject.Register("set_velocity", *this, &Entity::Lua_SetVelocity); m_luaObject.Register("get_velocity", *this, &Entity::Lua_GetVelocity); m_luaObject.Register("has_rigid_body", *this, &Entity::Lua_HasRigidBody); + m_luaObject.Register("create_box_body", *this, &Entity::Lua_CreateBoxBody); + m_luaObject.Register("create_sphere_body", *this, &Entity::Lua_CreateSphereBody); // animation m_luaObject.Register("find_animation", *this, &Entity::Lua_FindAnimation); @@ -357,20 +364,9 @@ int Entity::Lua_SetRotationFromVectors(LuaPlus::LuaState* state) { LuaPlus::LuaStack stack(state); - glm::vec3 front( - stack[2].GetNumber(), - stack[3].GetNumber(), - stack[4].GetNumber()); - - glm::vec3 right( - stack[5].GetNumber(), - stack[6].GetNumber(), - stack[7].GetNumber()); - - glm::vec3 up( - stack[8].GetNumber(), - stack[9].GetNumber(), - stack[10].GetNumber()); + glm::vec3 front = glm::vec3(stack[2].GetNumber(), stack[3].GetNumber(), stack[4].GetNumber()); + glm::vec3 right = glm::vec3(stack[5].GetNumber(), stack[6].GetNumber(), stack[7].GetNumber()); + glm::vec3 up = glm::vec3(stack[8].GetNumber(), stack[9].GetNumber(), stack[10].GetNumber()); Help_SetRotationFromVectors(front, right, up); @@ -403,6 +399,22 @@ int Entity::Lua_MarkForDelete(LuaPlus::LuaState* state) return 0; } +int Entity::Lua_SetName(LuaPlus::LuaState* state) +{ + LuaPlus::LuaStack stack(state); + const char* name = stack[2].GetString(); + + SetName(name); + + return 0; +} + +int Entity::Lua_GetName(LuaPlus::LuaState* state) +{ + state->PushString(m_name.c_str()); + return 1; +} + int Entity::Lua_SetVelocity(LuaPlus::LuaState* state) { LuaPlus::LuaStack stack(state); @@ -437,6 +449,44 @@ int Entity::Lua_HasRigidBody(LuaPlus::LuaState* state) return 1; } +int Entity::Lua_CreateBoxBody(LuaPlus::LuaState* state) +{ + LuaPlus::LuaStack stack(state); + + glm::vec3 size; + size.x = stack[2].GetNumber(); + size.y = stack[3].GetNumber(); + size.z = stack[4].GetNumber(); + + float mass = stack[5].GetNumber(); + float friction = stack[6].GetNumber(); + float damping = stack[7].GetNumber(); + + bool is_trigger = stack[8].GetBoolean(); + bool use_parameters = stack[9].GetBoolean(); + + CreateBoxBody(size, mass, friction, damping, is_trigger, use_parameters); + + return 0; +} + +int Entity::Lua_CreateSphereBody(LuaPlus::LuaState* state) +{ + LuaPlus::LuaStack stack(state); + + float radius = stack[2].GetNumber(); + float mass = stack[3].GetNumber(); + float friction = stack[4].GetNumber(); + float damping = stack[5].GetNumber(); + + bool is_trigger = stack[6].GetBoolean(); + bool use_parameters = stack[7].GetBoolean(); + + CreateSphereBody(radius, mass, friction, damping, is_trigger, use_parameters); + + return 0; +} + int Entity::Lua_FindAnimation(LuaPlus::LuaState* state) { LuaPlus::LuaStack stack(state); @@ -444,7 +494,7 @@ int Entity::Lua_FindAnimation(LuaPlus::LuaState* state) if (!stack[2].IsString()) { - Core::Warning("load_model: first argument is not an string"); + Core::Warning("find_animation: first argument is not an string"); return 0; } @@ -525,7 +575,59 @@ void Entity::CreateTestBody() { m_shape = new btBoxShape(btVector3(0.2f, 0.2f, 0.2f)); - m_mass = 80.0f; + CreateBodyPrivate(80.0f, 0.0, 0.0f, false, false); + + //m_mass = 80.0f; + //btVector3 local_inertia(0.0f, 0.0f, 0.0f); + //if (m_mass > 0.f) { + // m_shape->calculateLocalInertia(m_mass, local_inertia); + //} + + //btRigidBody::btRigidBodyConstructionInfo rigid_body_ci(m_mass, nullptr, m_shape, local_inertia); + + //m_rigidBody = new btRigidBody(rigid_body_ci); + //m_rigidBody->setUserPointer(this); + //m_rigidBody->setMotionState(&m_ph_motion_state); + //m_ph_motion_state.setBody(m_rigidBody); + + //// I'm sure that position is valid + //btTransform xform; + //xform.setIdentity(); + //xform.setOrigin(glmVectorToBt(m_position)); + //m_rigidBody->setWorldTransform(xform); + + //// #TODO: body filter and mask + //g_PhysicsWorld->GetWorld()->addRigidBody(m_rigidBody); + + //m_bodyDirty = true; +} + +void Entity::CreateBoxBody(const glm::vec3& size, float mass, float friction, float damping, bool is_trigger, bool use_parameters) +{ + m_shape = (btCollisionShape*)new btBoxShape(glmVectorToBt(size)); + + CreateBodyPrivate(mass, friction, damping, is_trigger, use_parameters); +} + +void Entity::CreateSphereBody(float radius, float mass, float friction, float damping, bool is_trigger, bool use_parameters) +{ + m_shape = (btCollisionShape*)new btSphereShape(radius); + + CreateBodyPrivate(mass, friction, damping, is_trigger, use_parameters); +} + +void Entity::CreateBodyPrivate(float mass, float friction, float damping, bool is_trigger, bool use_parameters) +{ + SDL_assert_always(m_shape); + + m_mass = mass; + + if (is_trigger && m_mass > 0.f) + { + Msg("WARNING! Entity '%s' trying to create body with mass %f and trigger flag, setting to zero.", m_name.c_str(), mass); + m_mass = 0.0f; + } + btVector3 local_inertia(0.0f, 0.0f, 0.0f); if (m_mass > 0.f) { m_shape->calculateLocalInertia(m_mass, local_inertia); @@ -544,6 +646,26 @@ void Entity::CreateTestBody() xform.setOrigin(glmVectorToBt(m_position)); m_rigidBody->setWorldTransform(xform); + // body parameters + if (use_parameters) + { + m_rigidBody->setFriction(friction); + m_rigidBody->setAnisotropicFriction(btVector3(0.0f, 0.0f, 0.0f)); + m_rigidBody->setDamping(damping, 0.0f); + } + + int bodyCollisionFlags = m_rigidBody->getCollisionFlags(); + + if (is_trigger) + bodyCollisionFlags |= btRigidBody::CF_NO_CONTACT_RESPONSE; + else + bodyCollisionFlags &= ~btRigidBody::CF_NO_CONTACT_RESPONSE; + + m_rigidBody->setCollisionFlags(bodyCollisionFlags); + + if (is_trigger) + m_rigidBody->setCustomDebugColor(btVector3(1.0f, 0.5f, 0.0f)); + // #TODO: body filter and mask g_PhysicsWorld->GetWorld()->addRigidBody(m_rigidBody); @@ -637,3 +759,24 @@ void WeaponBase::Fire(const glm::vec3& direction, float damage) // ActorBase* entity = (ActorBase*)stack[1].GetByName("__object").GetLightUserdata(); // entity->ActivateCamera(); //} + +REGISTER_ENTITY(TriggerBase); + +TriggerBase::TriggerBase() +{ +} + +TriggerBase::~TriggerBase() +{ +} + +void TriggerBase::Render() +{ + if (m_rigidBody && g_debugEntityDraw) + { + BoundingBox bbox; + bbox.m_min = btVectorToGlm(m_rigidBody->getBroadphaseHandle()->m_aabbMin); + bbox.m_max = btVectorToGlm(m_rigidBody->getBroadphaseHandle()->m_aabbMax); + g_debugRender->DrawBoundingBox(bbox, glm::vec3(1.0f, 0.5f, 0.0f)); + } +} diff --git a/src/game/game_object.h b/src/game/game_object.h index 595da10..6998c8e 100644 --- a/src/game/game_object.h +++ b/src/game/game_object.h @@ -84,6 +84,11 @@ public: // Game entity physics void CreateTestBody(); + + void CreateBoxBody(const glm::vec3& size, float mass, float friction, float damping, bool is_trigger, bool use_parameters); + void CreateSphereBody(float radius, float mass, float friction, float damping, bool is_trigger, bool use_parameters); + void CreateBodyPrivate(float mass, float friction, float damping, bool is_trigger, bool use_parameters); + void UpdateBody(); void UpdateBodyDirty(); @@ -112,10 +117,14 @@ public: int Lua_GetID(LuaPlus::LuaState* state); int Lua_UpdateTransform(LuaPlus::LuaState* state); int Lua_MarkForDelete(LuaPlus::LuaState* state); + int Lua_SetName(LuaPlus::LuaState* state); + int Lua_GetName(LuaPlus::LuaState* state); int Lua_SetVelocity(LuaPlus::LuaState* state); int Lua_GetVelocity(LuaPlus::LuaState* state); int Lua_HasRigidBody(LuaPlus::LuaState* state); + int Lua_CreateBoxBody(LuaPlus::LuaState* state); + int Lua_CreateSphereBody(LuaPlus::LuaState* state); int Lua_FindAnimation(LuaPlus::LuaState* state); int Lua_PlayAnimation(LuaPlus::LuaState* state); @@ -157,4 +166,13 @@ public: void Fire(const glm::vec3& direction, float damage); }; +class TriggerBase : public Entity +{ +public: + TriggerBase(); + ~TriggerBase(); + + virtual void Render(); +}; + #endif // !GAME_OBJECT_H diff --git a/src/game/game_world_objects.cpp b/src/game/game_world_objects.cpp index 4e7f672..f71f233 100644 --- a/src/game/game_world_objects.cpp +++ b/src/game/game_world_objects.cpp @@ -9,7 +9,8 @@ REGISTER_ENTITY(Light); Light::Light() { - m_dlight = nullptr; + //m_dlight = nullptr; + m_dlight = DLightManager::GetInstance()->AllocLight(); } Light::~Light() @@ -25,13 +26,23 @@ void Light::Render() if (g_debugDrawLights) { + g_debugRender->DrawAxis(m_dlight->position); g_debugRender->DrawSphere(m_dlight->position, m_dlight->radius, m_dlight->color); } } +void Light::RegisterFunctions() +{ + m_luaObject.Register("set_color", *this, &Light::Lua_SetColor); + m_luaObject.Register("get_color", *this, &Light::Lua_GetColor); + + m_luaObject.Register("set_radius", *this, &Light::Lua_SetRadius); + m_luaObject.Register("get_radius", *this, &Light::Lua_GetRadius); +} + void Light::InitFromXML(const pugi::xml_node& node) { - m_dlight = DLightManager::GetInstance()->AllocLight(); + //m_dlight = DLightManager::GetInstance()->AllocLight(); SDL_assert_always(m_dlight); m_dlight->position = m_position; @@ -48,4 +59,46 @@ void Light::InitFromXML(const pugi::xml_node& node) { m_dlight->radius = radius.attribute("value").as_float(); } -} \ No newline at end of file +} + +int Light::Lua_SetColor(LuaPlus::LuaState* state) +{ + SDL_assert_always(m_dlight); + + LuaPlus::LuaStack stack(state); + m_dlight->color.r = stack[2].GetFloat(); + m_dlight->color.g = stack[3].GetFloat(); + m_dlight->color.b = stack[4].GetFloat(); + + return 0; +} + +int Light::Lua_GetColor(LuaPlus::LuaState* state) +{ + SDL_assert_always(m_dlight); + + state->PushNumber(m_dlight->color.r); + state->PushNumber(m_dlight->color.g); + state->PushNumber(m_dlight->color.b); + + return 3; +} + +int Light::Lua_SetRadius(LuaPlus::LuaState* state) +{ + SDL_assert_always(m_dlight); + + LuaPlus::LuaStack stack(state); + m_dlight->radius = stack[2].GetFloat(); + + return 0; +} + +int Light::Lua_GetRadius(LuaPlus::LuaState* state) +{ + SDL_assert_always(m_dlight); + + state->PushNumber(m_dlight->radius); + + return 1; +} diff --git a/src/game/game_world_objects.h b/src/game/game_world_objects.h index 7ae9a72..b3b369b 100644 --- a/src/game/game_world_objects.h +++ b/src/game/game_world_objects.h @@ -16,9 +16,16 @@ public: ~Light(); void Render() override; + void RegisterFunctions() override; void InitFromXML(const pugi::xml_node& node); +private: + int Lua_SetColor(LuaPlus::LuaState* state); + int Lua_GetColor(LuaPlus::LuaState* state); + int Lua_SetRadius(LuaPlus::LuaState* state); + int Lua_GetRadius(LuaPlus::LuaState* state); + private: DLight* m_dlight; }; diff --git a/src/render/model.cpp b/src/render/model.cpp index 2e0d292..57edfad 100644 --- a/src/render/model.cpp +++ b/src/render/model.cpp @@ -692,7 +692,7 @@ void Model::Draw(const glm::mat4& model, SkeletonInstance* instance /*= nullptr* if (shader->HasUniform(UNIFORM_SUN_AMBIENT)) { - glm::vec4 lightColor = glm::vec4(0.1f); + glm::vec4 lightColor = glm::vec4(g_sceneManager->getAmbientColor(), 1.0f); g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_AMBIENT, &lightColor); } diff --git a/src/render/scenemanager.cpp b/src/render/scenemanager.cpp index c995a71..058ce02 100644 --- a/src/render/scenemanager.cpp +++ b/src/render/scenemanager.cpp @@ -20,6 +20,7 @@ extern int g_NumModels; static bool g_debugRenderScene = false; +glm::vec3 g_ambientColor = glm::vec3(0.0f); static std::string getFileExtension(const std::string& filename) { @@ -218,6 +219,9 @@ void SceneManager::loadScene(const char* filename) { unloadIfScenePresent(); + // Reset ambient color + setAmbientColor(glm::vec3(0.0f)); + char filenameBuffer[kMaxPathLength]; snprintf(filenameBuffer, kMaxPathLength, "data/levels/%s/%s.xml", filename, filename); @@ -243,6 +247,16 @@ void SceneManager::loadScene(const char* filename) pugi::xml_node root = doc.document_element(); const char* scenefilename = root.child("LevelDescription").child("SceneFile").attribute("filename").value(); + pugi::xml_node ambientnode = root.child("LevelDescription").child("AmbientColor"); + if (ambientnode) + { + glm::vec3 color = glm::vec3(0.0f); + color.r = ambientnode.attribute("r").as_float(); + color.g = ambientnode.attribute("g").as_float(); + color.b = ambientnode.attribute("b").as_float(); + setAmbientColor(color); + } + m_sceneName = getFileNameWithoutExtension(scenefilename); sprintf(filenameBuffer, "data/levels/%s/%s", filename, scenefilename); @@ -497,6 +511,16 @@ void SceneManager::toggleDebugRender() g_debugRenderScene = !g_debugRenderScene; } +void SceneManager::setAmbientColor(const glm::vec3& color) +{ + g_ambientColor = color; +} + +const glm::vec3& SceneManager::getAmbientColor() +{ + return g_ambientColor; +} + // SceneStaticMesh SceneStaticMesh::SceneStaticMesh() : @@ -856,7 +880,7 @@ void R_SceneStaticMesh_BindShader(const glm::mat4& worldMatrix, Texture2D* albed if (shader->HasUniform(UNIFORM_SUN_AMBIENT)) { - glm::vec4 lightColor = glm::vec4(0.1f); + glm::vec4 lightColor = glm::vec4(g_sceneManager->getAmbientColor(), 1.0f); g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_AMBIENT, &lightColor); } diff --git a/src/render/scenemanager.h b/src/render/scenemanager.h index 797ff48..b182a4b 100644 --- a/src/render/scenemanager.h +++ b/src/render/scenemanager.h @@ -56,15 +56,21 @@ public: SceneManager(); ~SceneManager(); - // \brief Load an static scene. + // \brief Load a static scene. void loadScene(const char*); // \brief Get current scene name. const char* getSceneName(); - // \brief Toggle an debug rendering. + // \brief Toggle a debug rendering. void toggleDebugRender(); + // \brief Set an ambient color. + void setAmbientColor(const glm::vec3& color); + + // \brief Get an ambient color. + const glm::vec3& getAmbientColor(); + private: void LoadSceneXML(const char* filename); void loadSkybox(const char*); diff --git a/src/sound/soundsystem.cpp b/src/sound/soundsystem.cpp index 6f4aa62..9d5e184 100644 --- a/src/sound/soundsystem.cpp +++ b/src/sound/soundsystem.cpp @@ -89,6 +89,7 @@ void SoundSystem::Play(SoundHandle handle, bool bLoop) assert(handle <= -1 || handle <= m_dwSoundsNum); ma_sound_start(&m_sounds[handle]); + ma_sound_set_spatialization_enabled(&m_sounds[handle], false); if ( bLoop ) ma_sound_set_looping(&m_sounds[handle], true); @@ -100,6 +101,9 @@ void SoundSystem::Play3D(SoundHandle handle, float x, float y, float z, bool bLo return; Play(handle, bLoop); + + // enable 3d + ma_sound_set_spatialization_enabled(&m_sounds[handle], true); ma_sound_set_position(&m_sounds[handle], x, y, z); }