mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-09 20:24:16 +00:00
rigid as heck
This commit is contained in:
@@ -1,16 +1,244 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2023
|
||||
* Copyright 2018
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "RigidbodyPhantomPhysicsComponent.h"
|
||||
#include "Game.h"
|
||||
#include "LDFFormat.h"
|
||||
#include "Logger.h"
|
||||
#include "Entity.h"
|
||||
#include "EntityManager.h"
|
||||
#include "ControllablePhysicsComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ePhysicsEffectType.h"
|
||||
|
||||
#include "CDClientManager.h"
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
#include "dServer.h"
|
||||
#include "EntityInfo.h"
|
||||
|
||||
#include "dpWorld.h"
|
||||
#include "dpEntity.h"
|
||||
#include "dpShapeBox.h"
|
||||
#include "dpShapeSphere.h"
|
||||
|
||||
RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* parent) : PhysicsComponent(parent) {
|
||||
m_Position = m_Parent->GetDefaultPosition();
|
||||
m_Rotation = m_Parent->GetDefaultRotation();
|
||||
m_Scale = m_Parent->GetDefaultScale();
|
||||
m_dpEntity = nullptr;
|
||||
|
||||
m_EffectInfoDirty = false;
|
||||
|
||||
m_IsPhysicsEffectActive = false;
|
||||
m_EffectType = ePhysicsEffectType::PUSH;
|
||||
m_DirectionalMultiplier = 0.0f;
|
||||
|
||||
m_MinMax = false;
|
||||
m_Min = 0;
|
||||
m_Max = 1;
|
||||
|
||||
m_IsDirectional = false;
|
||||
m_Direction = NiPoint3(); // * m_DirectionalMultiplier
|
||||
|
||||
if (m_Parent->GetVar<bool>(u"create_physics")) {
|
||||
CreatePhysics();
|
||||
}
|
||||
|
||||
if (!m_HasCreatedPhysics) {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::Instance().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);
|
||||
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") {
|
||||
// Move this down by 13.521004 units so it is still effectively at the same height as before
|
||||
m_Position = m_Position - NiPoint3::UNIT_Y * 13.521004f;
|
||||
// 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);
|
||||
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f);
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f);
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} 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
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} 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_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 7.5f);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} 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_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 6.0f);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 4.5f);
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} 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_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_Position.y -= (111.467964f * m_Scale) / 2;
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
} else {
|
||||
//LOG("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);
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::Instance().AddEntity(m_dpEntity);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
RigidbodyPhantomPhysicsComponent::~RigidbodyPhantomPhysicsComponent() {
|
||||
if (m_dpEntity) {
|
||||
dpWorld::Instance().RemoveEntity(m_dpEntity);
|
||||
}
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::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::Instance().GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::Instance().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::Instance().AddEntity(m_dpEntity);
|
||||
|
||||
m_HasCreatedPhysics = true;
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Update(float deltaTime) {
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
//Process enter events
|
||||
for (auto en : m_dpEntity->GetNewObjects()) {
|
||||
if (!en) continue;
|
||||
m_Parent->OnCollisionPhantom(en->GetObjectID());
|
||||
}
|
||||
|
||||
//Process exit events
|
||||
for (auto en : m_dpEntity->GetRemovedObjects()) {
|
||||
if (!en) continue;
|
||||
m_Parent->OnCollisionLeavePhantom(en->GetObjectID());
|
||||
}
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::SetPosition(const NiPoint3& pos) {
|
||||
PhysicsComponent::SetPosition(pos);
|
||||
if (m_dpEntity) m_dpEntity->SetPosition(pos);
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::SetRotation(const NiQuaternion& rot) {
|
||||
PhysicsComponent::SetRotation(rot);
|
||||
if (m_dpEntity) m_dpEntity->SetRotation(rot);
|
||||
}
|
||||
|
@@ -1,29 +1,142 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2023
|
||||
* Copyright 2018
|
||||
*/
|
||||
|
||||
#ifndef __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
#define __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
#pragma once
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
#include "PhysicsComponent.h"
|
||||
#include "BitStream.h"
|
||||
#include <vector>
|
||||
#include "CppScripts.h"
|
||||
#include "InvalidScript.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "PhysicsComponent.h"
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
class LDFBaseData;
|
||||
class Entity;
|
||||
class dpEntity;
|
||||
enum class ePhysicsEffectType : uint32_t ;
|
||||
|
||||
/**
|
||||
* Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be
|
||||
* collided with using various shapes to detect collision on certain points in the map. Generally these are used to
|
||||
* trigger gameplay events, for example the bus in Avant Gardens that moves around when the player touches its physics
|
||||
* body. Optionally this object can also have effects, like the fans in AG.
|
||||
*/
|
||||
class RigidbodyPhantomPhysicsComponent : public PhysicsComponent {
|
||||
public:
|
||||
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS;
|
||||
|
||||
RigidbodyPhantomPhysicsComponent(Entity* parent);
|
||||
|
||||
~RigidbodyPhantomPhysicsComponent() override;
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
};
|
||||
|
||||
#endif // __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
/**
|
||||
* Creates the physics shape for this entity based on LDF data
|
||||
*/
|
||||
void CreatePhysics();
|
||||
|
||||
/**
|
||||
* Sets the position of this physics object
|
||||
* @param pos the position to set
|
||||
*/
|
||||
void SetPosition(const NiPoint3& pos) override;
|
||||
|
||||
/**
|
||||
* Sets the rotation of this physics object
|
||||
* @param rot the rotation to set
|
||||
*/
|
||||
void SetRotation(const NiQuaternion& rot) override;
|
||||
|
||||
/**
|
||||
* Returns the effect that's currently active, defaults to 0
|
||||
* @return the effect that's currently active
|
||||
*/
|
||||
ePhysicsEffectType GetEffectType() const { return m_EffectType; }
|
||||
|
||||
/**
|
||||
* Sets the effect that's currently active
|
||||
* @param type the effect to set
|
||||
*/
|
||||
void SetEffectType(ePhysicsEffectType type);
|
||||
|
||||
/**
|
||||
* Returns the Physics entity for the component
|
||||
* @return Physics entity for the component
|
||||
*/
|
||||
|
||||
dpEntity* GetdpEntity() const { return m_dpEntity; }
|
||||
|
||||
/**
|
||||
* Spawns an object at each of the vertices for debugging purposes
|
||||
*/
|
||||
void SpawnVertices();
|
||||
|
||||
private:
|
||||
/**
|
||||
* A scale to apply to the size of the physics object
|
||||
*/
|
||||
float m_Scale;
|
||||
|
||||
/**
|
||||
* Whether or not the effect has changed and needs to be serialized
|
||||
*/
|
||||
bool m_EffectInfoDirty;
|
||||
|
||||
/**
|
||||
* Whether or not there's currently a physics effect active
|
||||
*/
|
||||
bool m_IsPhysicsEffectActive;
|
||||
|
||||
/**
|
||||
* The physics effect that's currently active, defaults to 0
|
||||
*/
|
||||
ePhysicsEffectType m_EffectType;
|
||||
|
||||
/**
|
||||
* A scaling multiplier to add to the directional vector
|
||||
*/
|
||||
float m_DirectionalMultiplier;
|
||||
|
||||
bool m_MinMax;
|
||||
uint32_t m_Min;
|
||||
uint32_t m_Max;
|
||||
|
||||
/**
|
||||
* Whether or not this physics object is pointed in some direction
|
||||
*/
|
||||
bool m_IsDirectional;
|
||||
|
||||
/**
|
||||
* The direction this physics object is pointed in, if any
|
||||
*/
|
||||
NiPoint3 m_Direction;
|
||||
|
||||
/**
|
||||
* The parent entity of this component
|
||||
*/
|
||||
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
|
||||
*/
|
||||
bool m_IsRespawnVolume = false;
|
||||
|
||||
/**
|
||||
* If this is a respawn volume, the exact position an entity will respawn
|
||||
*/
|
||||
NiPoint3 m_RespawnPos;
|
||||
|
||||
/**
|
||||
* If this is a respawn volume, the exact rotation an entity will respawn
|
||||
*/
|
||||
NiQuaternion m_RespawnRot;
|
||||
};
|
||||
|
Reference in New Issue
Block a user