mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-05 18:24:12 +00:00
feat: Dragonmaw (#1562)
* rigid as heck * abstract physics creation to separate function * loading Update FvRacePillarDServer.cpp consolidate abcd pillar logic modularization Update SimplePhysicsComponent.cpp Update EntityManager.cpp Update MovingPlatformComponent.cpp still need another pass * geiser works * columns working finally * consolidate logic * constiness * Update PhantomPhysicsComponent.cpp * Update PhysicsComponent.cpp * revert testing code * add versions info --------- Co-authored-by: Aaron Kimbre <aronwk.aaron@gmail.com>
This commit is contained in:
@@ -1840,6 +1840,12 @@ const NiPoint3& Entity::GetPosition() const {
|
||||
return vehicel->GetPosition();
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
return rigidBodyPhantomPhysicsComponent->GetPosition();
|
||||
}
|
||||
|
||||
return NiPoint3Constant::ZERO;
|
||||
}
|
||||
|
||||
@@ -1868,6 +1874,12 @@ const NiQuaternion& Entity::GetRotation() const {
|
||||
return vehicel->GetRotation();
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
return rigidBodyPhantomPhysicsComponent->GetRotation();
|
||||
}
|
||||
|
||||
return NiQuaternionConstant::IDENTITY;
|
||||
}
|
||||
|
||||
@@ -1896,6 +1908,12 @@ void Entity::SetPosition(const NiPoint3& position) {
|
||||
vehicel->SetPosition(position);
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
rigidBodyPhantomPhysicsComponent->SetPosition(position);
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(this);
|
||||
}
|
||||
|
||||
@@ -1924,6 +1942,12 @@ void Entity::SetRotation(const NiQuaternion& rotation) {
|
||||
vehicel->SetRotation(rotation);
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
rigidBodyPhantomPhysicsComponent->SetRotation(rotation);
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(this);
|
||||
}
|
||||
|
||||
|
@@ -47,7 +47,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
|
||||
m_Direction = NiPoint3(); // * m_DirectionalMultiplier
|
||||
|
||||
if (m_Parent->GetVar<bool>(u"create_physics")) {
|
||||
CreatePhysics();
|
||||
m_dpEntity = CreatePhysicsLnv(m_Scale, ComponentType);
|
||||
}
|
||||
|
||||
if (m_Parent->GetVar<bool>(u"respawnVol")) {
|
||||
@@ -89,105 +89,9 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
|
||||
m_RespawnRot = m_Rotation;
|
||||
}
|
||||
|
||||
/*
|
||||
for (LDFBaseData* data : settings) {
|
||||
if (data) {
|
||||
if (data->GetKey() == u"create_physics") {
|
||||
if (bool(std::stoi(data->GetValueAsString()))) {
|
||||
CreatePhysics(settings);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->GetKey() == u"respawnVol") {
|
||||
if (bool(std::stoi(data->GetValueAsString()))) {
|
||||
m_IsRespawnVolume = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IsRespawnVolume) {
|
||||
if (data->GetKey() == u"rspPos") {
|
||||
//Joy, we get to split strings!
|
||||
std::stringstream test(data->GetValueAsString());
|
||||
std::string segment;
|
||||
std::vector<std::string> seglist;
|
||||
|
||||
while (std::getline(test, segment, '\x1f')) {
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
|
||||
m_RespawnPos = NiPoint3(std::stof(seglist[0]), std::stof(seglist[1]), std::stof(seglist[2]));
|
||||
}
|
||||
|
||||
if (data->GetKey() == u"rspRot") {
|
||||
//Joy, we get to split strings!
|
||||
std::stringstream test(data->GetValueAsString());
|
||||
std::string segment;
|
||||
std::vector<std::string> seglist;
|
||||
|
||||
while (std::getline(test, segment, '\x1f')) {
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
|
||||
m_RespawnRot = NiQuaternion(std::stof(seglist[0]), std::stof(seglist[1]), std::stof(seglist[2]), std::stof(seglist[3]));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Parent->GetLOT() == 4945) // HF - RespawnPoints
|
||||
{
|
||||
m_IsRespawnVolume = true;
|
||||
m_RespawnPos = m_Position;
|
||||
m_RespawnRot = m_Rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (!m_HasCreatedPhysics) {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return;
|
||||
|
||||
auto* info = physComp->GetByID(componentID);
|
||||
if (info == nullptr || info->physicsAsset == "" || info->physicsAsset == "NO_PHYSICS") return;
|
||||
|
||||
//temp test
|
||||
if (info->physicsAsset == "miscellaneous\\misc_phys_10x1x5.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 5.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") {
|
||||
// TODO Fix physics simulation to do simulation at high velocities due to bullet through paper problem...
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1638.4f, 13.521004f * 2.0f, 1638.4f);
|
||||
|
||||
// Move this down by 13.521004 units so it is still effectively at the same height as before
|
||||
m_Position = m_Position - NiPoint3Constant::UNIT_Y * 13.521004f;
|
||||
} else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f);
|
||||
} else if (info->physicsAsset == "env\\POI_trigger_wall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 7.5f;
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 6.0f;
|
||||
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
|
||||
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 4.5f);
|
||||
} else if (info->physicsAsset == "env\\env_won_fv_gas-blocking-volume.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 390.496826f, 111.467964f, 600.821534f, true);
|
||||
m_Position.y -= (111.467964f * m_Scale) / 2;
|
||||
} else {
|
||||
// LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str());
|
||||
|
||||
//add fallback cube:
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 2.0f, 2.0f, 2.0f);
|
||||
}
|
||||
|
||||
if (!m_dpEntity) {
|
||||
m_dpEntity = CreatePhysicsEntity(ComponentType);
|
||||
if (!m_dpEntity) return;
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
@@ -201,69 +105,6 @@ PhantomPhysicsComponent::~PhantomPhysicsComponent() {
|
||||
}
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::CreatePhysics() {
|
||||
unsigned char alpha;
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
int type = -1;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float width = 0.0f; //aka "radius"
|
||||
float height = 0.0f;
|
||||
|
||||
if (m_Parent->HasVar(u"primitiveModelType")) {
|
||||
type = m_Parent->GetVar<int32_t>(u"primitiveModelType");
|
||||
x = m_Parent->GetVar<float>(u"primitiveModelValueX");
|
||||
y = m_Parent->GetVar<float>(u"primitiveModelValueY");
|
||||
z = m_Parent->GetVar<float>(u"primitiveModelValueZ");
|
||||
} else {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return;
|
||||
|
||||
auto info = physComp->GetByID(componentID);
|
||||
|
||||
if (info == nullptr) return;
|
||||
|
||||
type = info->pcShapeType;
|
||||
width = info->playerRadius;
|
||||
height = info->playerHeight;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 1: { //Make a new box shape
|
||||
NiPoint3 boxSize(x, y, z);
|
||||
if (x == 0.0f) {
|
||||
//LU has some weird values, so I think it's best to scale them down a bit
|
||||
if (height < 0.5f) height = 2.0f;
|
||||
if (width < 0.5f) width = 2.0f;
|
||||
|
||||
//Scale them:
|
||||
width = width * m_Scale;
|
||||
height = height * m_Scale;
|
||||
|
||||
boxSize = NiPoint3(width, height, width);
|
||||
}
|
||||
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), boxSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
m_dpEntity->SetPosition({ m_Position.x, m_Position.y - (height / 2), m_Position.z });
|
||||
|
||||
dpWorld::AddEntity(m_dpEntity);
|
||||
|
||||
m_HasCreatedPhysics = true;
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
|
||||
@@ -308,8 +149,9 @@ void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effec
|
||||
controllablePhysicsComponent->SetGravityScale(effectScale);
|
||||
GameMessages::SendSetGravityScale(target, effectScale, targetEntity->GetSystemAddress());
|
||||
}
|
||||
break;
|
||||
}
|
||||
// The other types are not handled by the server
|
||||
|
||||
case ePhysicsEffectType::ATTRACT:
|
||||
case ePhysicsEffectType::FRICTION:
|
||||
case ePhysicsEffectType::PUSH:
|
||||
@@ -317,6 +159,7 @@ void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effec
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// The other types are not handled by the server and are here to handle all cases of the enum.
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::Update(float deltaTime) {
|
||||
@@ -356,24 +199,12 @@ void PhantomPhysicsComponent::SetDirection(const NiPoint3& pos) {
|
||||
m_IsDirectional = true;
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::SpawnVertices() {
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
LOG("%llu", m_Parent->GetObjectID());
|
||||
auto box = static_cast<dpShapeBox*>(m_dpEntity->GetShape());
|
||||
for (auto vert : box->GetVertices()) {
|
||||
LOG("%f, %f, %f", vert.x, vert.y, vert.z);
|
||||
|
||||
EntityInfo info;
|
||||
info.lot = 33;
|
||||
info.pos = vert;
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
info.spawnerNodeID = 0;
|
||||
|
||||
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
void PhantomPhysicsComponent::SpawnVertices() const {
|
||||
if (!m_dpEntity) {
|
||||
LOG("No dpEntity to spawn vertices for %llu:%i", m_Parent->GetObjectID(), m_Parent->GetLOT());
|
||||
return;
|
||||
}
|
||||
PhysicsComponent::SpawnVertices(m_dpEntity);
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::SetDirectionalMultiplier(float mul) {
|
||||
|
@@ -18,6 +18,7 @@ class LDFBaseData;
|
||||
class Entity;
|
||||
class dpEntity;
|
||||
enum class ePhysicsEffectType : uint32_t ;
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
|
||||
/**
|
||||
* Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be
|
||||
@@ -34,11 +35,6 @@ public:
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Creates the physics shape for this entity based on LDF data
|
||||
*/
|
||||
void CreatePhysics();
|
||||
|
||||
/**
|
||||
* Sets the direction this physics object is pointed at
|
||||
* @param pos the direction to set
|
||||
@@ -109,7 +105,7 @@ public:
|
||||
/**
|
||||
* Spawns an object at each of the vertices for debugging purposes
|
||||
*/
|
||||
void SpawnVertices();
|
||||
void SpawnVertices() const;
|
||||
|
||||
/**
|
||||
* Legacy stuff no clue what this does
|
||||
@@ -166,11 +162,6 @@ private:
|
||||
*/
|
||||
dpEntity* m_dpEntity;
|
||||
|
||||
/**
|
||||
* Whether or not the physics object has been created yet
|
||||
*/
|
||||
bool m_HasCreatedPhysics = false;
|
||||
|
||||
/**
|
||||
* Whether or not this physics object represents an object that updates the respawn pos of an entity that crosses it
|
||||
*/
|
||||
|
@@ -1,5 +1,19 @@
|
||||
#include "PhysicsComponent.h"
|
||||
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
|
||||
#include "dpEntity.h"
|
||||
#include "dpWorld.h"
|
||||
#include "dpShapeBox.h"
|
||||
#include "dpShapeSphere.h"
|
||||
|
||||
#include "EntityInfo.h"
|
||||
|
||||
PhysicsComponent::PhysicsComponent(Entity* parent) : Component(parent) {
|
||||
m_Position = NiPoint3Constant::ZERO;
|
||||
m_Rotation = NiQuaternionConstant::IDENTITY;
|
||||
@@ -19,3 +33,190 @@ void PhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitia
|
||||
if (!bIsInitialUpdate) m_DirtyPosition = false;
|
||||
}
|
||||
}
|
||||
|
||||
dpEntity* PhysicsComponent::CreatePhysicsEntity(eReplicaComponentType type) {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), type);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return nullptr;
|
||||
|
||||
auto* info = physComp->GetByID(componentID);
|
||||
if (info == nullptr || info->physicsAsset == "" || info->physicsAsset == "NO_PHYSICS") return nullptr;
|
||||
|
||||
dpEntity* toReturn;
|
||||
if (info->physicsAsset == "miscellaneous\\misc_phys_10x1x5.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 10.0f, 5.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") {
|
||||
// TODO Fix physics simulation to do simulation at high velocities due to bullet through paper problem...
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1638.4f, 13.521004f * 2.0f, 1638.4f);
|
||||
|
||||
// Move this down by 13.521004 units so it is still effectively at the same height as before
|
||||
m_Position = m_Position - NiPoint3Constant::UNIT_Y * 13.521004f;
|
||||
} else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f);
|
||||
} else if (info->physicsAsset == "env\\POI_trigger_wall.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 7.5f;
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 6.0f;
|
||||
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
|
||||
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 4.5f);
|
||||
} else if (info->physicsAsset == "env\\env_won_fv_gas-blocking-volume.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 390.496826f, 111.467964f, 600.821534f, true);
|
||||
m_Position.y -= (111.467964f * m_Parent->GetDefaultScale()) / 2;
|
||||
} else {
|
||||
// LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str());
|
||||
|
||||
//add fallback cube:
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 2.0f, 2.0f, 2.0f);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
dpEntity* PhysicsComponent::CreatePhysicsLnv(const float scale, const eReplicaComponentType type) const {
|
||||
int pcShapeType = -1;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float width = 0.0f; //aka "radius"
|
||||
float height = 0.0f;
|
||||
dpEntity* toReturn = nullptr;
|
||||
|
||||
if (m_Parent->HasVar(u"primitiveModelType")) {
|
||||
pcShapeType = m_Parent->GetVar<int32_t>(u"primitiveModelType");
|
||||
x = m_Parent->GetVar<float>(u"primitiveModelValueX");
|
||||
y = m_Parent->GetVar<float>(u"primitiveModelValueY");
|
||||
z = m_Parent->GetVar<float>(u"primitiveModelValueZ");
|
||||
} else {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), type);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return nullptr;
|
||||
|
||||
auto info = physComp->GetByID(componentID);
|
||||
|
||||
if (info == nullptr) return nullptr;
|
||||
|
||||
pcShapeType = info->pcShapeType;
|
||||
width = info->playerRadius;
|
||||
height = info->playerHeight;
|
||||
}
|
||||
|
||||
switch (pcShapeType) {
|
||||
case 0: { // HKX type
|
||||
break;
|
||||
}
|
||||
case 1: { //Make a new box shape
|
||||
NiPoint3 boxSize(x, y, z);
|
||||
if (x == 0.0f) {
|
||||
//LU has some weird values, so I think it's best to scale them down a bit
|
||||
if (height < 0.5f) height = 2.0f;
|
||||
if (width < 0.5f) width = 2.0f;
|
||||
|
||||
//Scale them:
|
||||
width = width * scale;
|
||||
height = height * scale;
|
||||
|
||||
boxSize = NiPoint3(width, height, width);
|
||||
}
|
||||
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), boxSize);
|
||||
|
||||
toReturn->SetPosition({ m_Position.x, m_Position.y - (height / 2), m_Position.z });
|
||||
break;
|
||||
}
|
||||
case 2: { //Make a new cylinder shape
|
||||
break;
|
||||
}
|
||||
case 3: { //Make a new sphere shape
|
||||
auto [x, y, z] = m_Position;
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), width);
|
||||
toReturn->SetPosition({ x, y, z });
|
||||
break;
|
||||
}
|
||||
case 4: { //Make a new capsule shape
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (toReturn) dpWorld::AddEntity(toReturn);
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void PhysicsComponent::SpawnVertices(dpEntity* entity) const {
|
||||
if (!entity) return;
|
||||
|
||||
LOG("Spawning vertices for %llu", m_Parent->GetObjectID());
|
||||
EntityInfo info;
|
||||
info.lot = 33;
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
info.spawnerNodeID = 0;
|
||||
|
||||
// These don't use overloaded methods as dPhysics does not link with dGame at the moment.
|
||||
auto box = dynamic_cast<dpShapeBox*>(entity->GetShape());
|
||||
if (box) {
|
||||
for (auto vert : box->GetVertices()) {
|
||||
LOG("Vertex at %f, %f, %f", vert.x, vert.y, vert.z);
|
||||
|
||||
info.pos = vert;
|
||||
Entity* newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
}
|
||||
}
|
||||
auto sphere = dynamic_cast<dpShapeSphere*>(entity->GetShape());
|
||||
if (sphere) {
|
||||
auto [x, y, z] = entity->GetPosition(); // Use shapes position instead of the parent's position in case it's different
|
||||
float plusX = x + sphere->GetRadius();
|
||||
float minusX = x - sphere->GetRadius();
|
||||
float plusY = y + sphere->GetRadius();
|
||||
float minusY = y - sphere->GetRadius();
|
||||
float plusZ = z + sphere->GetRadius();
|
||||
float minusZ = z - sphere->GetRadius();
|
||||
|
||||
auto radius = sphere->GetRadius();
|
||||
LOG("Radius: %f", radius);
|
||||
LOG("Plus Vertices %f %f %f", plusX, plusY, plusZ);
|
||||
LOG("Minus Vertices %f %f %f", minusX, minusY, minusZ);
|
||||
|
||||
info.pos = NiPoint3{ x, plusY, z };
|
||||
Entity* newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, minusY, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ plusX, y, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ minusX, y, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, y, plusZ };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, y, minusZ };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, y, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,10 @@ namespace Raknet {
|
||||
class BitStream;
|
||||
};
|
||||
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
|
||||
class dpEntity;
|
||||
|
||||
class PhysicsComponent : public Component {
|
||||
public:
|
||||
PhysicsComponent(Entity* parent);
|
||||
@@ -22,6 +26,12 @@ public:
|
||||
const NiQuaternion& GetRotation() const { return m_Rotation; }
|
||||
virtual void SetRotation(const NiQuaternion& rot) { if (m_Rotation == rot) return; m_Rotation = rot; m_DirtyPosition = true; }
|
||||
protected:
|
||||
dpEntity* CreatePhysicsEntity(eReplicaComponentType type);
|
||||
|
||||
dpEntity* CreatePhysicsLnv(const float scale, const eReplicaComponentType type) const;
|
||||
|
||||
void SpawnVertices(dpEntity* entity) const;
|
||||
|
||||
NiPoint3 m_Position;
|
||||
|
||||
NiQuaternion m_Rotation;
|
||||
|
@@ -817,8 +817,10 @@ void RacingControlComponent::Update(float deltaTime) {
|
||||
|
||||
// Some offset up to make they don't fall through the terrain on a
|
||||
// respawn, seems to fix itself to the track anyhow
|
||||
player.respawnPosition = position + NiPoint3Constant::UNIT_Y * 5;
|
||||
player.respawnRotation = vehicle->GetRotation();
|
||||
if (waypoint.racing.isResetNode) {
|
||||
player.respawnPosition = position + NiPoint3Constant::UNIT_Y * 5;
|
||||
player.respawnRotation = vehicle->GetRotation();
|
||||
}
|
||||
player.respawnIndex = respawnIndex;
|
||||
|
||||
// Reached the start point, lapped
|
||||
|
@@ -1,16 +1,57 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2023
|
||||
*/
|
||||
// Darkflame Universe
|
||||
// Copyright 2024
|
||||
|
||||
#include "RigidbodyPhantomPhysicsComponent.h"
|
||||
#include "Entity.h"
|
||||
|
||||
#include "dpEntity.h"
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
#include "dpWorld.h"
|
||||
#include "dpShapeBox.h"
|
||||
#include "dpShapeSphere.h"
|
||||
#include"EntityInfo.h"
|
||||
|
||||
RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* parent) : PhysicsComponent(parent) {
|
||||
m_Position = m_Parent->GetDefaultPosition();
|
||||
m_Rotation = m_Parent->GetDefaultRotation();
|
||||
m_Scale = m_Parent->GetDefaultScale();
|
||||
|
||||
if (m_Parent->GetVar<bool>(u"create_physics")) {
|
||||
m_dpEntity = CreatePhysicsLnv(m_Scale, ComponentType);
|
||||
if (!m_dpEntity) {
|
||||
m_dpEntity = CreatePhysicsEntity(ComponentType);
|
||||
if (!m_dpEntity) return;
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::AddEntity(m_dpEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Update(const float deltaTime) {
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
//Process enter events
|
||||
for (const auto id : m_dpEntity->GetNewObjects()) {
|
||||
m_Parent->OnCollisionPhantom(id);
|
||||
}
|
||||
|
||||
//Process exit events
|
||||
for (const auto id : m_dpEntity->GetRemovedObjects()) {
|
||||
m_Parent->OnCollisionLeavePhantom(id);
|
||||
}
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::SpawnVertices() const {
|
||||
if (!m_dpEntity) {
|
||||
LOG("No dpEntity to spawn vertices for %llu:%i", m_Parent->GetObjectID(), m_Parent->GetLOT());
|
||||
return;
|
||||
}
|
||||
PhysicsComponent::SpawnVertices(m_dpEntity);
|
||||
}
|
||||
|
@@ -1,10 +1,8 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2023
|
||||
*/
|
||||
// Darkflame Universe
|
||||
// Copyright 2024
|
||||
|
||||
#ifndef __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
#define __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
#ifndef RIGIDBODYPHANTOMPHYSICS_H
|
||||
#define RIGIDBODYPHANTOMPHYSICS_H
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "dCommonVars.h"
|
||||
@@ -13,6 +11,8 @@
|
||||
#include "PhysicsComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
class dpEntity;
|
||||
|
||||
/**
|
||||
* Component that handles rigid bodies that can be interacted with, mostly client-side rendered. An example is the
|
||||
* bananas that fall from trees in GF.
|
||||
@@ -23,7 +23,15 @@ public:
|
||||
|
||||
RigidbodyPhantomPhysicsComponent(Entity* parent);
|
||||
|
||||
void Update(const float deltaTime) override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
void SpawnVertices() const;
|
||||
private:
|
||||
float m_Scale{};
|
||||
|
||||
dpEntity* m_dpEntity{};
|
||||
};
|
||||
|
||||
#endif // __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
#endif // RIGIDBODYPHANTOMPHYSICS_H
|
||||
|
@@ -369,8 +369,8 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd
|
||||
|
||||
const auto lot = entity->GetLOT();
|
||||
|
||||
if (lot == 12341 || lot == 5027 || lot == 5028 || lot == 14335 || lot == 14447 || lot == 14449) {
|
||||
iDesiredWaypointIndex = 0;
|
||||
if (lot == 12341 || lot == 5027 || lot == 5028 || lot == 14335 || lot == 14447 || lot == 14449 || lot == 11306 || lot == 11308) {
|
||||
iDesiredWaypointIndex = (lot == 11306 || lot == 11308) ? 1 : 0;
|
||||
iIndex = 0;
|
||||
nextIndex = 0;
|
||||
bStopAtDesiredWaypoint = true;
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "ScriptedActivityComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "TriggerComponent.h"
|
||||
#include "RigidbodyPhantomPhysicsComponent.h"
|
||||
|
||||
// Enums
|
||||
#include "eGameMasterLevel.h"
|
||||
@@ -1129,8 +1130,13 @@ namespace DEVGMCommands {
|
||||
void SpawnPhysicsVerts(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||
//Go tell physics to spawn all the vertices:
|
||||
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS);
|
||||
for (auto en : entities) {
|
||||
auto phys = static_cast<PhantomPhysicsComponent*>(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS));
|
||||
for (const auto* en : entities) {
|
||||
const auto* phys = static_cast<PhantomPhysicsComponent*>(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS));
|
||||
if (phys)
|
||||
phys->SpawnVertices();
|
||||
}
|
||||
for (const auto* en : Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS)) {
|
||||
const auto* phys = en->GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
if (phys)
|
||||
phys->SpawnVertices();
|
||||
}
|
||||
|
Reference in New Issue
Block a user