732 lines
18 KiB
C++
732 lines
18 KiB
C++
#include "ifilesystem.h"
|
|
#include "core.h"
|
|
#include "log.h"
|
|
#include "engine.h"
|
|
#include "game.h"
|
|
#include "game_lua_help.h"
|
|
#include "game_ui.h"
|
|
#include "inputmanager.h"
|
|
#include "ientity.h"
|
|
#include "entitymanager.h"
|
|
#include "world.h"
|
|
#include "game_object.h"
|
|
#include "soundsystem.h"
|
|
#include "animation.h"
|
|
#include "scenemanager.h"
|
|
#include "game_world_objects.h"
|
|
#include "actor_base.h"
|
|
#include "physics/physicsworld.h"
|
|
|
|
#include <pugixml.hpp>
|
|
|
|
#include <map>
|
|
#include <string>
|
|
|
|
static Game s_game;
|
|
Game* g_game = &s_game;
|
|
|
|
class GameSoundSystem
|
|
{
|
|
public:
|
|
static GameSoundSystem& GetInstance();
|
|
|
|
public:
|
|
void PlaySound2D(const std::string& filename);
|
|
void PlaySound3D(const std::string& filename, const glm::vec3& pos);
|
|
void CacheSound(const std::string& filename);
|
|
|
|
private:
|
|
std::map<std::string, SoundHandle> m_sounds;
|
|
};
|
|
|
|
GameSoundSystem& GameSoundSystem::GetInstance()
|
|
{
|
|
static GameSoundSystem inst;
|
|
return inst;
|
|
}
|
|
|
|
void GameSoundSystem::PlaySound2D(const std::string& filename)
|
|
{
|
|
auto it = m_sounds.find(filename);
|
|
if (it == m_sounds.end())
|
|
{
|
|
CacheSound(filename);
|
|
it = m_sounds.find(filename);
|
|
}
|
|
|
|
SDL_assert(it != m_sounds.end());
|
|
|
|
// .hack due unimplemented sound sources^
|
|
if (g_soundSystem.IsPlaying(it->second))
|
|
g_soundSystem.Stop(it->second);
|
|
|
|
g_soundSystem.Play(it->second, false);
|
|
}
|
|
|
|
void GameSoundSystem::PlaySound3D(const std::string& filename, const glm::vec3& pos)
|
|
{
|
|
auto it = m_sounds.find(filename);
|
|
if (it == m_sounds.end())
|
|
{
|
|
CacheSound(filename);
|
|
it = m_sounds.find(filename);
|
|
}
|
|
|
|
SDL_assert(it != m_sounds.end());
|
|
|
|
// .hack due unimplemented sound sources^
|
|
if (g_soundSystem.IsPlaying(it->second))
|
|
g_soundSystem.Stop(it->second);
|
|
|
|
g_soundSystem.Play3D(it->second, pos.x, pos.y, pos.z, true);
|
|
}
|
|
|
|
void GameSoundSystem::CacheSound(const std::string& filename)
|
|
{
|
|
m_sounds.emplace(filename, g_soundSystem.LoadSound(filename.c_str()));
|
|
}
|
|
|
|
void consoleMsg(const char* msg)
|
|
{
|
|
Logger::Msg("%s", msg);
|
|
}
|
|
|
|
void engineError(const char* msg)
|
|
{
|
|
Core::Error("%s", msg);
|
|
}
|
|
|
|
void engineWarning(const char* msg)
|
|
{
|
|
Core::Warning("%s", msg);
|
|
}
|
|
|
|
void enginePlaySound(const char* filename)
|
|
{
|
|
GameSoundSystem::GetInstance().PlaySound2D(filename);
|
|
}
|
|
|
|
void enginePlaySound3D(const char* filename, float x, float y, float z)
|
|
{
|
|
GameSoundSystem::GetInstance().PlaySound3D(filename, glm::vec3(x, y, z));
|
|
}
|
|
|
|
LuaPlus::LuaObject engineCreateEntity(const char* classname)
|
|
{
|
|
Entity* entity = static_cast<Entity*>(g_game->Lua_CreateEntity(classname));
|
|
SDL_assert_always(entity);
|
|
|
|
entity->Init();
|
|
|
|
return entity->GetLuaObject();
|
|
}
|
|
|
|
LuaPlus::LuaObject engineGetEntityFromID(lua_Integer id)
|
|
{
|
|
LuaPlus::LuaObject lookup = GetLuaState().GetGlobal("g_entities");
|
|
LuaPlus::LuaObject entityTable = lookup.GetByIndex(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"];
|
|
SDL_assert_always(cppclass.IsLightUserdata());
|
|
|
|
Entity* entity = static_cast<Entity*>(cppclass.GetLightUserdata());
|
|
g_world->AddEntity(entity);
|
|
}
|
|
|
|
LuaPlus::LuaObject engineTraceRay(float rayBeginX, float rayBeginY, float rayBeginZ,
|
|
float rayEndX, float rayEndY, float rayEndZ, const LuaPlus::LuaObject& ignoreTable)
|
|
{
|
|
IEntityBase* pIgnoreEntity = nullptr;
|
|
if (ignoreTable.IsTable())
|
|
{
|
|
LuaPlus::LuaObject ignoreEntityTable = ignoreTable.GetByName("__object");
|
|
if (ignoreEntityTable.IsLightUserdata())
|
|
pIgnoreEntity = (IEntityBase*)ignoreEntityTable.GetLightUserdata();
|
|
}
|
|
|
|
TraceRayResult result = {};
|
|
glm::vec3 rayBegin = glm::vec3(rayBeginX, rayBeginY, rayBeginZ);
|
|
glm::vec3 rayEnd = glm::vec3(rayEndX, rayEndY, rayEndZ);
|
|
|
|
if (g_PhysicsWorld)
|
|
g_PhysicsWorld->TraceRay(result, rayBegin, rayEnd, pIgnoreEntity);
|
|
else
|
|
Logger::Msg("engine.trace_ray(): no server started or game loaded!");
|
|
|
|
LuaPlus::LuaObject resultTable = GetLuaState().CreateTable();
|
|
resultTable.SetNumber("pos_x", result.position.x);
|
|
resultTable.SetNumber("pos_y", result.position.y);
|
|
resultTable.SetNumber("pos_z", result.position.z);
|
|
resultTable.SetNumber("normal_x", result.normal.x);
|
|
resultTable.SetNumber("normal_y", result.normal.y);
|
|
resultTable.SetNumber("normal_z", result.normal.z);
|
|
resultTable.SetInteger("entity_id", result.pEntity ? result.pEntity->GetID() : -1);
|
|
resultTable.SetInteger("hit", result.hit);
|
|
return resultTable;
|
|
}
|
|
|
|
float engineGetDelta()
|
|
{
|
|
return GetEngine()->GetDelta();
|
|
}
|
|
|
|
void registerEngine()
|
|
{
|
|
using namespace LuaPlus;
|
|
|
|
// register engine functions
|
|
LuaObject engineTable = GetLuaState().GetGlobals().CreateTable("engine");
|
|
engineTable.RegisterDirect("error", &engineError);
|
|
engineTable.RegisterDirect("warning", &engineWarning);
|
|
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);
|
|
engineTable.RegisterDirect("trace_ray", &engineTraceRay);
|
|
|
|
LuaObject consoleTable = GetLuaState().GetGlobals().CreateTable("console");
|
|
consoleTable.RegisterDirect("print", &consoleMsg);
|
|
|
|
registerCamera();
|
|
|
|
registerInput();
|
|
|
|
registerEngineUI();
|
|
|
|
// action globals
|
|
GetLuaState().DoString("ACTION_FIRE = 0");
|
|
GetLuaState().DoString("ACTION_ALT_FIRE = 1");
|
|
GetLuaState().DoString("ACTION_RELOAD = 2");
|
|
GetLuaState().DoString("ACTION_USE = 3");
|
|
|
|
// animations globals
|
|
GetLuaState().DoString("ANIM_PLAYBACK_NONE = 0");
|
|
GetLuaState().DoString("ANIM_PLAYBACK_REPEAT = 1");
|
|
|
|
|
|
char buffer[64];
|
|
|
|
#define REGISTER_CONSTANT(constant) \
|
|
snprintf(buffer, sizeof(buffer), #constant" = %d", constant); \
|
|
GetLuaState().DoString(buffer)
|
|
|
|
REGISTER_CONSTANT(EMovementDir_None);
|
|
REGISTER_CONSTANT(EMovementDir_Forward);
|
|
REGISTER_CONSTANT(EMovementDir_Backward);
|
|
REGISTER_CONSTANT(EMovementDir_Left);
|
|
REGISTER_CONSTANT(EMovementDir_Right);
|
|
REGISTER_CONSTANT(EMovementDir_Jump);
|
|
|
|
// Physics
|
|
REGISTER_CONSTANT(PhysicsFilter_None);
|
|
REGISTER_CONSTANT(PhysicsFilter_Player);
|
|
REGISTER_CONSTANT(PhysicsFilter_Triggers);
|
|
REGISTER_CONSTANT(PhysicsFilter_Usable);
|
|
REGISTER_CONSTANT(PhysicsFilter_NPC);
|
|
REGISTER_CONSTANT(PhysicsFilter_Obstacle);
|
|
REGISTER_CONSTANT(kPhysicsFilter_AllAux);
|
|
|
|
#undef REGISTER_CONSTANT
|
|
}
|
|
|
|
int inputGetMousePos(LuaPlus::LuaState* state)
|
|
{
|
|
const glm::vec2& pos = g_inputManager.GetMousePos();
|
|
state->PushNumber(pos.x);
|
|
state->PushNumber(pos.y);
|
|
return 2;
|
|
}
|
|
|
|
int inputGetDeltaMousePos(LuaPlus::LuaState* state)
|
|
{
|
|
const glm::vec2& pos = g_inputManager.GetMouseDeltaPos();
|
|
state->PushNumber(pos.x);
|
|
state->PushNumber(pos.y);
|
|
return 2;
|
|
}
|
|
|
|
void inputLock(bool value)
|
|
{
|
|
g_inputManager.SetRelativeMouseMode(value);
|
|
}
|
|
|
|
bool inputGetLock()
|
|
{
|
|
return g_inputManager.GetRelativeMouseMode();
|
|
}
|
|
|
|
void registerInput()
|
|
{
|
|
LuaPlus::LuaObject inputTable = GetLuaState().GetGlobals().CreateTable("input");
|
|
inputTable.Register("get_mouse_pos", &inputGetMousePos);
|
|
inputTable.Register("get_delta_mouse_pos", &inputGetDeltaMousePos);
|
|
inputTable.RegisterDirect("lock_mouse", &inputLock);
|
|
inputTable.RegisterDirect("get_lock_mouse", &inputGetLock);
|
|
}
|
|
|
|
void toggleNoclip()
|
|
{
|
|
static bool s_noclip = false;
|
|
|
|
s_noclip = !s_noclip;
|
|
|
|
LuaPlus::LuaObject player = GetLuaState().GetGlobal("g_player");
|
|
if (player.IsTable())
|
|
{
|
|
ActorBase* actor = (ActorBase*)player["__object"].GetLightUserdata();
|
|
actor->SetNoclip(s_noclip);
|
|
}
|
|
}
|
|
|
|
int cameraGetPos(LuaPlus::LuaState* state)
|
|
{
|
|
glm::vec3 v = glm::vec3(0.0f);
|
|
|
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
|
if (camera)
|
|
v = camera->GetPosition();
|
|
|
|
state->PushNumber(v.x);
|
|
state->PushNumber(v.y);
|
|
state->PushNumber(v.z);
|
|
|
|
return 3;
|
|
}
|
|
|
|
int cameraGetFront(LuaPlus::LuaState* state)
|
|
{
|
|
glm::vec3 v = glm::vec3(0.0f);
|
|
|
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
|
if (camera)
|
|
v = camera->GetFront();
|
|
|
|
state->PushNumber(v.x);
|
|
state->PushNumber(v.y);
|
|
state->PushNumber(v.z);
|
|
|
|
return 3;
|
|
}
|
|
|
|
int cameraGetRight(LuaPlus::LuaState* state)
|
|
{
|
|
glm::vec3 v = glm::vec3(0.0f);
|
|
|
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
|
if (camera)
|
|
v = camera->GetRight();
|
|
|
|
state->PushNumber(v.x);
|
|
state->PushNumber(v.y);
|
|
state->PushNumber(v.z);
|
|
|
|
return 3;
|
|
}
|
|
|
|
int cameraGetUp(LuaPlus::LuaState* state)
|
|
{
|
|
glm::vec3 v = glm::vec3(0.0f);
|
|
|
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
|
if (camera)
|
|
v = camera->GetUp();
|
|
|
|
state->PushNumber(v.x);
|
|
state->PushNumber(v.y);
|
|
state->PushNumber(v.z);
|
|
|
|
return 3;
|
|
}
|
|
|
|
int cameraGetYaw(LuaPlus::LuaState* state)
|
|
{
|
|
float v = 0.0f;
|
|
|
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
|
if (camera)
|
|
v = camera->GetYaw();
|
|
|
|
state->PushNumber(v);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cameraGetPitch(LuaPlus::LuaState* state)
|
|
{
|
|
float v = 0.0f;
|
|
|
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
|
if (camera)
|
|
v = camera->GetPitch();
|
|
|
|
state->PushNumber(v);
|
|
|
|
return 1;
|
|
}
|
|
|
|
void cameraSetYawPitch(float yaw, float pitch)
|
|
{
|
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
|
if (camera)
|
|
camera->SetYawPitch(yaw, pitch);
|
|
}
|
|
|
|
void registerCamera()
|
|
{
|
|
LuaPlus::LuaObject cameraTable = GetLuaState().GetGlobals().CreateTable("camera");
|
|
cameraTable.Register("get_position", &cameraGetPos);
|
|
cameraTable.Register("get_front", &cameraGetFront);
|
|
cameraTable.Register("get_right", &cameraGetRight);
|
|
cameraTable.Register("get_up", &cameraGetUp);
|
|
cameraTable.Register("get_yaw", &cameraGetYaw);
|
|
cameraTable.Register("get_pitch", &cameraGetPitch);
|
|
cameraTable.RegisterDirect("set_yaw_pitch", &cameraSetYawPitch);
|
|
}
|
|
|
|
void registerClasses()
|
|
{
|
|
using namespace LuaPlus;
|
|
|
|
// base thing
|
|
GetLuaState().GetGlobals().RegisterDirect("load_script", &luaLoadScript);
|
|
GetLuaState().DoString("g_factory = {}");
|
|
GetLuaState().DoString("g_entities = {}");
|
|
|
|
registerEngine();
|
|
}
|
|
|
|
struct LuaPrototype
|
|
{
|
|
std::string m_luaname;
|
|
std::string m_enginename;
|
|
std::string m_description;
|
|
};
|
|
|
|
std::vector<LuaPrototype> g_prototypes;
|
|
|
|
void initializeEntityPrototypesFromLua()
|
|
{
|
|
using namespace LuaPlus;
|
|
LuaObject entitiesTable = GetLuaState().GetGlobal("g_entity_table");
|
|
|
|
for (LuaTableIterator it(entitiesTable); it; it.Next()) {
|
|
LuaObject entityTable = it.GetValue();
|
|
assert(entityTable.IsTable());
|
|
|
|
if (entityTable.GetTableCount() < 3)
|
|
{
|
|
Core::Error("Entry in entity prototype table is bad, missing argument");
|
|
}
|
|
|
|
LuaObject luaname = entityTable[1];
|
|
LuaObject classname = entityTable[2];
|
|
LuaObject description = entityTable[3];
|
|
|
|
Logger::Msg("lua ent: name: %s classname: %s description: %s", luaname.ToString(), classname.ToString(), description.ToString());
|
|
|
|
LuaPrototype prototype;
|
|
prototype.m_luaname = luaname.ToString();
|
|
prototype.m_enginename = classname.ToString();
|
|
prototype.m_description = description.ToString();
|
|
g_prototypes.push_back(prototype);
|
|
|
|
// get a prototype
|
|
LuaObject prototypeTable = GetLuaState().GetGlobal(luaname.ToString());
|
|
SDL_assert_always(!prototypeTable.IsNil());
|
|
prototypeTable.SetObject("__index", prototypeTable);
|
|
|
|
|
|
/*for (LuaTableIterator it2(entityTable); it2; it2.Next()) {
|
|
Logger::Msg("%s", it2.GetValue().ToString());
|
|
}*/
|
|
}
|
|
}
|
|
|
|
void initializeEntitiesTable()
|
|
{
|
|
using namespace LuaPlus;
|
|
|
|
LuaObject entitiesTable = GetLuaState().GetGlobal("g_entity_table");
|
|
if (entitiesTable.IsNil()) {
|
|
Core::Error("initializeEntitiesTable: failed initialize the entity table! g_entity_table is nil");
|
|
}
|
|
|
|
if (!entitiesTable.IsTable()) {
|
|
Core::Error("initializeEntitiesTable: failed initialize the entity table! g_entity_table is not a table");
|
|
}
|
|
|
|
initializeEntityPrototypesFromLua();
|
|
}
|
|
|
|
void initializeLua()
|
|
{
|
|
using namespace LuaPlus;
|
|
|
|
// register base classes
|
|
registerClasses();
|
|
|
|
// load game base script
|
|
luaLoadScript("game_init.lua");
|
|
}
|
|
|
|
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)
|
|
{
|
|
// Load XML file of the level
|
|
char buffer[kMaxPathLength];
|
|
snprintf(buffer, kMaxPathLength, "data/levels/%s/%s.xml", mapname, mapname);
|
|
|
|
FileHandle_t file = GetFileSystem()->OpenFile(buffer, "rb");
|
|
SDL_assert_always(file != kInvalidFileHandleValue);
|
|
|
|
size_t length = GetFileSystem()->GetFileLength(file);
|
|
|
|
char* filedata = new char[length + 1];
|
|
GetFileSystem()->ReadFile(file, filedata, length);
|
|
filedata[length] = '\0';
|
|
|
|
GetFileSystem()->CloseFile(file);
|
|
|
|
pugi::xml_document doc;
|
|
pugi::xml_parse_result result = doc.load_buffer(filedata, length);
|
|
delete[] filedata;
|
|
if (!result) {
|
|
Core::Error("Game::LoadLevelXML: Error while reading level description file '%s'\nError: %s:%i",
|
|
buffer, result.description(), result.offset);
|
|
}
|
|
|
|
// std::map<std::string, std::string> properties;
|
|
|
|
for (pugi::xml_node entitynode : doc.child("Level").child("Entities").children("Entity")) {
|
|
pugi::xml_attribute entityname = entitynode.attribute("name");
|
|
pugi::xml_attribute classname = entitynode.attribute("classname");
|
|
|
|
if (classname.empty()) {
|
|
if (!entityname.empty()) {
|
|
Core::Error(" Game::LoadLevelXML: Classname is not specified for entity '%s'", entityname.as_string());
|
|
}
|
|
else {
|
|
Core::Error(" Game::LoadLevelXML: Classname is not specified for entity");
|
|
}
|
|
}
|
|
|
|
// Create entity and expose it to the engine
|
|
Entity* entity = static_cast<Entity*>(Lua_CreateEntity(classname.as_string()));
|
|
|
|
if (!entityname.empty())
|
|
entity->SetName(entityname.as_string());
|
|
|
|
pugi::xml_node position = entitynode.child("Position");
|
|
if (position)
|
|
{
|
|
float x = position.attribute("x").as_float();
|
|
float y = position.attribute("y").as_float();
|
|
float z = position.attribute("z").as_float();
|
|
|
|
entity->SetPosition(glm::vec3(x, y, z));
|
|
}
|
|
|
|
pugi::xml_node model = entitynode.child("Model");
|
|
if (model)
|
|
{
|
|
const char* filename = model.attribute("filename").as_string();
|
|
if (filename)
|
|
entity->LoadModel(filename);
|
|
}
|
|
|
|
pugi::xml_node animation = entitynode.child("Animation");
|
|
if (animation)
|
|
{
|
|
const char* name = animation.attribute("name").as_string();
|
|
int mode = animation.attribute("mode").as_int();
|
|
SkeletonInstance* skeleton = entity->GetSkeletonInstance();
|
|
if (skeleton)
|
|
skeleton->PlayAnimation(skeleton->FindAnimation(name), mode);
|
|
}
|
|
|
|
pugi::xml_node physics = entitynode.child("Physics");
|
|
if (physics)
|
|
{
|
|
bool value = physics.attribute("value").as_bool();
|
|
if (value)
|
|
entity->CreateTestBody();
|
|
}
|
|
|
|
Light* light = dynamic_cast<Light*>(entity); // BAD!!!
|
|
if (light)
|
|
light->InitFromXML(entitynode);
|
|
|
|
entity->Init();
|
|
|
|
//IEntityBase* entity = g_entityManager->CreateEntity(classname.as_string());
|
|
g_world->AddEntity(entity);
|
|
}
|
|
}
|
|
|
|
IEntityBase* Game::Lua_CreateEntity(const char* classname)
|
|
{
|
|
using namespace LuaPlus;
|
|
|
|
SDL_assert_always(classname);
|
|
|
|
// find prototype
|
|
LuaPrototype* luaprototype = Lua_FindPrototype(classname);
|
|
|
|
// create an entity
|
|
Entity* entity = nullptr;
|
|
if (luaprototype)
|
|
{
|
|
entity = static_cast<Entity*>(g_entityManager->CreateEntity(luaprototype->m_enginename.c_str()));
|
|
|
|
// override classname because of entity system is so dumb
|
|
entity->SetClassname(luaprototype->m_luaname.c_str());
|
|
}
|
|
else
|
|
{
|
|
entity = static_cast<Entity*>(g_entityManager->CreateEntity(classname));
|
|
}
|
|
|
|
SDL_assert_always(entity);
|
|
|
|
// get the factrory
|
|
LuaObject factory = GetLuaState().GetGlobal("g_factory");
|
|
|
|
// and the lookup table
|
|
LuaObject lookup = GetLuaState().GetGlobal("g_entities");
|
|
|
|
// generate name
|
|
char entityname[256];
|
|
snprintf(entityname, sizeof(entityname), "%s_%d", classname, factory.GetTableCount());
|
|
|
|
// create an table
|
|
LuaObject entityTable = GetLuaState().CreateTable();
|
|
entityTable.SetString("__private_name", entityname);
|
|
entityTable.SetInteger("m_id", entity->GetID());
|
|
|
|
// assign prototype
|
|
if (luaprototype)
|
|
{
|
|
LuaObject prototype = GetLuaState().GetGlobal(luaprototype->m_luaname.c_str());
|
|
SDL_assert_always(!prototype.IsNil());
|
|
entityTable.SetMetatable(prototype);
|
|
}
|
|
|
|
// link to the entity
|
|
entity->InitFromTable(entityTable);
|
|
|
|
// push in to the factory
|
|
factory.SetObject(entityname, entityTable);
|
|
lookup.SetObject(entity->GetID(), entityTable);
|
|
|
|
return entity;
|
|
}
|
|
|
|
LuaPrototype* Game::Lua_FindPrototype(const char* classname)
|
|
{
|
|
// find a prototype
|
|
for (std::vector<LuaPrototype>::iterator it = g_prototypes.begin();
|
|
it != g_prototypes.end();
|
|
++it)
|
|
{
|
|
if (strcmp((*it).m_luaname.c_str(), classname) == 0)
|
|
{
|
|
return &(*it);
|
|
}
|
|
}
|
|
|
|
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<Entity*>(g_world->GetEntity(i));
|
|
if (entity && entity->GetName() == name)
|
|
return entity;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void Game::Shutdown()
|
|
{
|
|
}
|
|
|
|
void Game::Render2D()
|
|
{
|
|
gameRenderUI();
|
|
}
|
|
|
|
//LuaPrototype* pluaprototype = Lua_FindPrototype(classname);
|
|
//
|
|
//if (pluaprototype)
|
|
//{
|
|
// Entity* entity = static_cast<Entity*>(g_entityManager->CreateEntity(pluaprototype->m_enginename.c_str()));
|
|
// SDL_assert_always(entity);
|
|
|
|
// // get a prototype
|
|
// LuaObject prototype = GetLuaState().GetGlobal(pluaprototype->m_luaname.c_str());
|
|
// SDL_assert_always(!prototype.IsNil());
|
|
// //prototype.SetObject("__index", prototype);
|
|
|
|
// // generate table
|
|
// LuaObject factory = GetLuaState().GetGlobal("g_factory");
|
|
|
|
// // generate name
|
|
// std::string entityname = pluaprototype->m_luaname + "_" + std::to_string(factory.GetTableCount());
|
|
//
|
|
// // create an table
|
|
// LuaObject entityTable = GetLuaState().GetGlobals().CreateTable(entityname.c_str());
|
|
// entityTable.SetMetatable(prototype);
|
|
// entityTable.SetString("m_name", entityname.c_str());
|
|
//
|
|
// // push in to the factory
|
|
// factory.SetObject(entityname.c_str(), entityTable);
|
|
|
|
// // link to the entity
|
|
// entity->InitFromTable(entityTable);
|
|
|
|
// return entity;
|
|
//}
|
|
|
|
//IEntityBase* entity = g_entityManager->CreateEntity(classname);
|