Update
This commit is contained in:
@@ -67,6 +67,7 @@ void registerClasses()
|
||||
// base thing
|
||||
GetLuaState().GetGlobals().RegisterDirect("load_script", &luaLoadScript);
|
||||
GetLuaState().DoString("g_factory = {}");
|
||||
GetLuaState().DoString("g_entities = {}");
|
||||
|
||||
registerEngine();
|
||||
}
|
||||
@@ -196,11 +197,8 @@ void Game::LoadLevelXML(const char* mapname)
|
||||
}
|
||||
}
|
||||
|
||||
IEntityBase* entity = Lua_CreateEntity(classname.as_string());
|
||||
|
||||
// this is pure C++ entity :)
|
||||
if (!entity)
|
||||
entity = g_entityManager->CreateEntity(classname.as_string());
|
||||
// Create entity and expose it to the engine
|
||||
Entity* entity = static_cast<Entity*>(Lua_CreateEntity(classname.as_string()));
|
||||
|
||||
pugi::xml_node position = entitynode.child("Position");
|
||||
if (position)
|
||||
@@ -212,6 +210,22 @@ void Game::LoadLevelXML(const char* mapname)
|
||||
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 physics = entitynode.child("Physics");
|
||||
if (physics)
|
||||
{
|
||||
bool value = physics.attribute("value").as_bool();
|
||||
if (value)
|
||||
entity->CreateTestBody();
|
||||
}
|
||||
|
||||
//IEntityBase* entity = g_entityManager->CreateEntity(classname.as_string());
|
||||
g_world->AddEntity(entity);
|
||||
}
|
||||
@@ -221,13 +235,62 @@ IEntityBase* Game::Lua_CreateEntity(const char* classname)
|
||||
{
|
||||
using namespace LuaPlus;
|
||||
|
||||
//if (!classname)
|
||||
// classname = "Entity";
|
||||
|
||||
SDL_assert_always(classname);
|
||||
|
||||
LuaPrototype* pluaprototype = nullptr;
|
||||
// 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("m_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();
|
||||
@@ -235,42 +298,9 @@ IEntityBase* Game::Lua_CreateEntity(const char* classname)
|
||||
{
|
||||
if (strcmp((*it).m_luaname.c_str(), classname) == 0)
|
||||
{
|
||||
pluaprototype = &(*it);
|
||||
break;
|
||||
return &(*it);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -278,3 +308,37 @@ IEntityBase* Game::Lua_CreateEntity(const char* classname)
|
||||
void Game::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define GAME_H
|
||||
|
||||
class IEntityBase;
|
||||
struct LuaPrototype;
|
||||
|
||||
class Game
|
||||
{
|
||||
@@ -13,6 +14,8 @@ public:
|
||||
|
||||
IEntityBase* Lua_CreateEntity(const char* classname);
|
||||
|
||||
LuaPrototype* Lua_FindPrototype(const char* classname);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
};
|
||||
|
||||
@@ -66,7 +66,10 @@ void ActorBase_ActivateCamera(LuaPlus::LuaState* state)
|
||||
REGISTER_ENTITY(Entity);
|
||||
|
||||
Entity::Entity() :
|
||||
m_model(nullptr)
|
||||
m_model(nullptr),
|
||||
m_shape(nullptr),
|
||||
m_rigidBody(nullptr),
|
||||
m_bodyDirty(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -84,15 +87,20 @@ Entity::~Entity()
|
||||
if (name.IsString())
|
||||
{
|
||||
LuaPlus::LuaObject factory = GetLuaState().GetGlobal("g_factory");
|
||||
factory.SetNil(m_luaObject);
|
||||
factory.SetNil(name.GetString());
|
||||
}
|
||||
|
||||
LuaPlus::LuaObject lookup = GetLuaState().GetGlobal("g_entities");
|
||||
lookup.SetNil(GetID());
|
||||
|
||||
m_luaObject.AssignNil();
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::Update(float dt)
|
||||
{
|
||||
UpdateBody();
|
||||
|
||||
if ( m_onUpdateFunction.IsFunction())
|
||||
{
|
||||
LuaPlus::LuaFunctionVoid function = m_onUpdateFunction;
|
||||
@@ -113,6 +121,21 @@ void Entity::Render()
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::OnCollide(IEntityBase* other)
|
||||
{
|
||||
if (!m_onCollideFunction.IsFunction())
|
||||
return;
|
||||
|
||||
// find entity
|
||||
LuaPlus::LuaObject lookup = GetLuaState().GetGlobal("g_entities");
|
||||
LuaPlus::LuaObject otherTable = lookup.GetByIndex(other->GetID());
|
||||
if (!otherTable.IsNil())
|
||||
{
|
||||
LuaPlus:: LuaFunctionVoid function = m_onCollideFunction;
|
||||
function(m_luaObject, otherTable);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& Entity::GetName()
|
||||
{
|
||||
return m_name;
|
||||
@@ -148,9 +171,10 @@ void Entity::InitFromTable(LuaPlus::LuaObject& _object)
|
||||
m_onInitFunction = m_luaObject.GetByName("on_init");
|
||||
m_onShutdownFunction = m_luaObject.GetByName("on_shutdown");
|
||||
m_onUpdateFunction = m_luaObject.GetByName("on_update");
|
||||
m_onCollideFunction = m_luaObject.GetByName("on_collide");
|
||||
|
||||
// check
|
||||
SDL_assert_always(m_onInitFunction.IsFunction() || m_onShutdownFunction.IsFunction() || m_onUpdateFunction.IsFunction());
|
||||
//SDL_assert_always(m_onInitFunction.IsFunction() || m_onShutdownFunction.IsFunction() || m_onUpdateFunction.IsFunction());
|
||||
|
||||
// register base entity functions
|
||||
RegisterBaseFunctions();
|
||||
@@ -162,8 +186,11 @@ void Entity::InitFromTable(LuaPlus::LuaObject& _object)
|
||||
m_luaObject.SetLightUserdata("__object", this);
|
||||
|
||||
// call init
|
||||
LuaPlus::LuaFunctionVoid onInitFunction = m_onInitFunction;
|
||||
onInitFunction(m_luaObject);
|
||||
if (m_onInitFunction.IsFunction())
|
||||
{
|
||||
LuaPlus::LuaFunctionVoid onInitFunction = m_onInitFunction;
|
||||
onInitFunction(m_luaObject);
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::RegisterBaseFunctions()
|
||||
@@ -171,6 +198,7 @@ void Entity::RegisterBaseFunctions()
|
||||
m_luaObject.Register("load_model", *this, &Entity::Lua_LoadModel);
|
||||
m_luaObject.Register("translate", *this, &Entity::Lua_Translate);
|
||||
m_luaObject.Register("set_position", *this, &Entity::Lua_SetPosition);
|
||||
m_luaObject.Register("get_classname", *this, &Entity::Lua_GetClassname);
|
||||
|
||||
// m_luaObject.RegisterDirect("load_model", &Entity_LoadModel);
|
||||
//m_luaObject.RegisterDirect("set_visible", &Entity_SetVisible);
|
||||
@@ -237,17 +265,69 @@ int Entity::Lua_SetPosition(LuaPlus::LuaState* state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Entity::Lua_GetClassname(LuaPlus::LuaState* state)
|
||||
{
|
||||
state->PushString(GetClassname());
|
||||
return 1;
|
||||
}
|
||||
|
||||
const LuaPlus::LuaObject& Entity::GetLuaObject()
|
||||
{
|
||||
return m_luaObject;
|
||||
}
|
||||
|
||||
void Entity::CreateTestBody()
|
||||
{
|
||||
m_shape = new btBoxShape(btVector3(0.2f, 0.2f, 0.2f));
|
||||
|
||||
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::UpdateBody()
|
||||
{
|
||||
m_position = btVectorToGlm(m_ph_motion_state.m_transform.getOrigin());
|
||||
m_ph_motion_state.m_transform.getRotation().getEulerZYX(m_rotation.z, m_rotation.y, m_rotation.x);
|
||||
m_rotation = glm::degrees(m_rotation);
|
||||
}
|
||||
|
||||
void Entity::UpdateBodyDirty()
|
||||
{
|
||||
if (m_bodyDirty)
|
||||
{
|
||||
btTransform xform;
|
||||
xform.setIdentity();
|
||||
xform.setOrigin(glmVectorToBt(m_position));
|
||||
m_rigidBody->setWorldTransform(xform);
|
||||
|
||||
m_bodyDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_ENTITY(ActorBase);
|
||||
|
||||
ActorBase::ActorBase() :
|
||||
m_shape(nullptr),
|
||||
m_rigidBody(nullptr),
|
||||
m_bodyDirty(false)
|
||||
ActorBase::ActorBase()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -273,7 +353,7 @@ void ActorBase::Update(float dt)
|
||||
static bool s_test = true;
|
||||
|
||||
if (s_test) {
|
||||
UpdateBody();
|
||||
UpdateBodyDirty();
|
||||
Entity::Update(dt);
|
||||
AfterEngineStep();
|
||||
} else {
|
||||
@@ -340,14 +420,27 @@ void ActorBase::UpdateBodyMovement(float dt)
|
||||
if (movementDir & EMovementDir_Right)
|
||||
dir += glm::normalize(glm::cross(camFront, m_camera.GetUp()));
|
||||
|
||||
btVector3 currentvel = m_rigidBody->getLinearVelocity();
|
||||
glm::vec3 velocity = dir * speed;
|
||||
|
||||
if (glm::length(velocity) > 0.1f && OnGround() && !(movementDir & EMovementDir_Jump))
|
||||
if (OnGround()) {
|
||||
m_rigidBody->setLinearVelocity(btVector3(velocity.x, currentvel.y(), velocity.z));
|
||||
if (movementDir & EMovementDir_Jump) {
|
||||
m_rigidBody->setLinearVelocity(btVector3(currentvel.x(), PLAYER_PHYS_JUMPSPEEDY, currentvel.z()));
|
||||
}
|
||||
} else {
|
||||
float airControl = 0.2f;
|
||||
btVector3 airvel = currentvel + glmVectorToBt(dir * speed * airControl * dt);
|
||||
m_rigidBody->setLinearVelocity(btVector3(airvel.x(), currentvel.y(), airvel.z()));
|
||||
}
|
||||
|
||||
/*if (glm::length(velocity) > 0.1f && OnGround() && !(movementDir & EMovementDir_Jump))
|
||||
m_rigidBody->setLinearVelocity(glmVectorToBt(velocity));
|
||||
|
||||
if ((movementDir & EMovementDir_Jump) && OnGround()) {
|
||||
m_rigidBody->applyCentralImpulse(btVector3(0.0f, PLAYER_PHYS_JUMPSPEEDY*25, 0.0f));
|
||||
}
|
||||
m_rigidBody->applyCentralImpulse(btVector3(0.0f, PLAYER_PHYS_JUMPSPEEDY, 0.0f));
|
||||
movementDir &= ~EMovementDir_Jump;
|
||||
}*/
|
||||
}
|
||||
|
||||
void ActorBase::UpdateCameraLook()
|
||||
@@ -371,19 +464,6 @@ void ActorBase::UpdateCameraLook()
|
||||
m_camera.SetYawPitch(yaw, pitch);
|
||||
}
|
||||
|
||||
void ActorBase::UpdateBody()
|
||||
{
|
||||
if (m_bodyDirty)
|
||||
{
|
||||
btTransform xform;
|
||||
xform.setIdentity();
|
||||
xform.setOrigin(glmVectorToBt(m_position));
|
||||
m_rigidBody->setWorldTransform(xform);
|
||||
|
||||
m_bodyDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ActorBase::ActivateCamera()
|
||||
{
|
||||
g_inputManager.SetRelativeMouseMode(true);
|
||||
@@ -391,7 +471,7 @@ void ActorBase::ActivateCamera()
|
||||
g_cameraManager.SetActiveCamera(&m_camera);
|
||||
}
|
||||
|
||||
void ActorBase::CreateBody()
|
||||
void ActorBase::CreatePlayerBody()
|
||||
{
|
||||
|
||||
m_shape = new btCapsuleShape(PLAYER_PHYS_RADIUS, PLAYER_PHYS_HEIGHT - PLAYER_PHYS_RADIUS * 2.0);
|
||||
@@ -417,7 +497,14 @@ void ActorBase::CreateBody()
|
||||
|
||||
// ACTOR STUFF
|
||||
m_rigidBody->setAngularFactor(btVector3(0.0f, 0.0f, 0.0f));
|
||||
m_rigidBody->setFriction(2.5f);
|
||||
|
||||
|
||||
//m_rigidBody->setFriction(2.5f);
|
||||
|
||||
m_rigidBody->setFriction(0.0f);
|
||||
m_rigidBody->setAnisotropicFriction(btVector3(0.0f, 0.0f, 0.0f));
|
||||
m_rigidBody->setDamping(0.1f, 0.0f);
|
||||
|
||||
m_rigidBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
|
||||
// #TODO: body filter and mask
|
||||
@@ -492,7 +579,7 @@ int ActorBase::Lua_ActivateCamera(LuaPlus::LuaState* state)
|
||||
|
||||
int ActorBase::Lua_CreateBody(LuaPlus::LuaState* state)
|
||||
{
|
||||
CreateBody();
|
||||
CreatePlayerBody();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -523,16 +610,20 @@ uint32_t ActorBase::GenMovementDir()
|
||||
return movementDir;
|
||||
}
|
||||
|
||||
REGISTER_ENTITY(Weapon);
|
||||
REGISTER_ENTITY(WeaponBase);
|
||||
|
||||
Weapon::Weapon()
|
||||
WeaponBase::WeaponBase()
|
||||
{
|
||||
}
|
||||
|
||||
Weapon::~Weapon()
|
||||
WeaponBase::~WeaponBase()
|
||||
{
|
||||
}
|
||||
|
||||
void Weapon::Update(float dt)
|
||||
void WeaponBase::Update(float dt)
|
||||
{
|
||||
}
|
||||
|
||||
void WeaponBase::Fire(const glm::vec3& direction, float damage)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
|
||||
virtual void Update(float dt);
|
||||
virtual void Render();
|
||||
virtual void OnCollide(IEntityBase* other);
|
||||
|
||||
// Game entity extensions
|
||||
const std::string& GetName();
|
||||
@@ -76,6 +77,11 @@ public:
|
||||
void SetVisible(bool visible);
|
||||
bool GetVisible();
|
||||
|
||||
// Game entity physics
|
||||
void CreateTestBody();
|
||||
void UpdateBody();
|
||||
void UpdateBodyDirty();
|
||||
|
||||
// Game entity lua bindings
|
||||
|
||||
void InitFromTable(LuaPlus::LuaObject& _object);
|
||||
@@ -89,6 +95,7 @@ public:
|
||||
int Lua_LoadModel(LuaPlus::LuaState* state);
|
||||
int Lua_Translate(LuaPlus::LuaState* state);
|
||||
int Lua_SetPosition(LuaPlus::LuaState* state);
|
||||
int Lua_GetClassname(LuaPlus::LuaState* state);
|
||||
|
||||
const LuaPlus::LuaObject& GetLuaObject();
|
||||
|
||||
@@ -101,6 +108,14 @@ protected:
|
||||
LuaPlus::LuaObject m_onInitFunction;
|
||||
LuaPlus::LuaObject m_onShutdownFunction;
|
||||
LuaPlus::LuaObject m_onUpdateFunction;
|
||||
LuaPlus::LuaObject m_onCollideFunction;
|
||||
|
||||
protected:
|
||||
btCollisionShape* m_shape;
|
||||
btRigidBody* m_rigidBody;
|
||||
ph_motion_state m_ph_motion_state;
|
||||
float m_mass;
|
||||
bool m_bodyDirty;
|
||||
};
|
||||
|
||||
class ActorBase : public Entity
|
||||
@@ -119,11 +134,9 @@ public:
|
||||
|
||||
void UpdateCameraLook();
|
||||
|
||||
void UpdateBody();
|
||||
|
||||
void ActivateCamera();
|
||||
|
||||
void CreateBody();
|
||||
void CreatePlayerBody();
|
||||
|
||||
bool OnGround();
|
||||
|
||||
@@ -143,21 +156,18 @@ private:
|
||||
private:
|
||||
Camera m_camera;
|
||||
|
||||
private:
|
||||
btCollisionShape* m_shape;
|
||||
btRigidBody* m_rigidBody;
|
||||
ph_motion_state m_ph_motion_state;
|
||||
float m_mass;
|
||||
bool m_bodyDirty;
|
||||
|
||||
};
|
||||
|
||||
class Weapon : public Entity
|
||||
class WeaponBase : public Entity
|
||||
{
|
||||
public:
|
||||
Weapon();
|
||||
~Weapon();
|
||||
WeaponBase();
|
||||
~WeaponBase();
|
||||
|
||||
virtual void Update(float dt);
|
||||
|
||||
void Fire(const glm::vec3& direction, float damage);
|
||||
};
|
||||
|
||||
#endif // !GAME_OBJECT_H
|
||||
|
||||
Reference in New Issue
Block a user