mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-04-26 16:46:31 +00:00
Add pausing of models and behaviors
This commit is contained in:
parent
5d061c0274
commit
0dc4be65a0
@ -15,6 +15,8 @@
|
|||||||
ModelComponent::ModelComponent(Entity* parent) : Component(parent) {
|
ModelComponent::ModelComponent(Entity* parent) : Component(parent) {
|
||||||
m_OriginalPosition = m_Parent->GetDefaultPosition();
|
m_OriginalPosition = m_Parent->GetDefaultPosition();
|
||||||
m_OriginalRotation = m_Parent->GetDefaultRotation();
|
m_OriginalRotation = m_Parent->GetDefaultRotation();
|
||||||
|
m_IsPaused = false;
|
||||||
|
m_IsPickable = false;
|
||||||
|
|
||||||
m_userModelID = m_Parent->GetVarAs<LWOOBJID>(u"userModelID");
|
m_userModelID = m_Parent->GetVarAs<LWOOBJID>(u"userModelID");
|
||||||
RegisterMsg(MessageType::Game::REQUEST_USE, this, &ModelComponent::OnRequestUse);
|
RegisterMsg(MessageType::Game::REQUEST_USE, this, &ModelComponent::OnRequestUse);
|
||||||
@ -27,6 +29,8 @@ bool ModelComponent::OnRequestUse(GameMessages::GameMsg& msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModelComponent::Update(float deltaTime) {
|
void ModelComponent::Update(float deltaTime) {
|
||||||
|
if (m_IsPaused) return;
|
||||||
|
|
||||||
for (auto& behavior : m_Behaviors) {
|
for (auto& behavior : m_Behaviors) {
|
||||||
behavior.Update(deltaTime, *this);
|
behavior.Update(deltaTime, *this);
|
||||||
}
|
}
|
||||||
@ -59,6 +63,11 @@ void ModelComponent::LoadBehaviors() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelComponent::Resume() {
|
||||||
|
m_Dirty = true;
|
||||||
|
m_IsPaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
void ModelComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
void ModelComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||||
// ItemComponent Serialization. Pets do not get this serialization.
|
// ItemComponent Serialization. Pets do not get this serialization.
|
||||||
if (!m_Parent->HasComponent(eReplicaComponentType::PET)) {
|
if (!m_Parent->HasComponent(eReplicaComponentType::PET)) {
|
||||||
@ -70,14 +79,14 @@ void ModelComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialU
|
|||||||
|
|
||||||
//actual model component:
|
//actual model component:
|
||||||
outBitStream.Write1(); // Yes we are writing model info
|
outBitStream.Write1(); // Yes we are writing model info
|
||||||
outBitStream.Write1(); // Is pickable
|
outBitStream.Write(m_IsPickable); // Is pickable
|
||||||
outBitStream.Write<uint32_t>(2); // Physics type
|
outBitStream.Write<uint32_t>(2); // Physics type
|
||||||
outBitStream.Write(m_OriginalPosition); // Original position
|
outBitStream.Write(m_OriginalPosition); // Original position
|
||||||
outBitStream.Write(m_OriginalRotation); // Original rotation
|
outBitStream.Write(m_OriginalRotation); // Original rotation
|
||||||
|
|
||||||
outBitStream.Write1(); // We are writing behavior info
|
outBitStream.Write1(); // We are writing behavior info
|
||||||
outBitStream.Write<uint32_t>(m_Behaviors.size()); // Number of behaviors
|
outBitStream.Write<uint32_t>(m_Behaviors.size()); // Number of behaviors
|
||||||
outBitStream.Write0(); // Is this model paused
|
outBitStream.Write(m_IsPaused); // Is this model paused
|
||||||
if (bIsInitialUpdate) outBitStream.Write0(); // We are not writing model editing info
|
if (bIsInitialUpdate) outBitStream.Write0(); // We are not writing model editing info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Main gateway for all behavior messages to be passed to their respective behaviors.
|
* Main gateway for all behavior messages to be passed to their respective behaviors.
|
||||||
*
|
*
|
||||||
* @tparam Msg The message type to pass
|
* @tparam Msg The message type to pass
|
||||||
* @param args the arguments of the message to be deserialized
|
* @param args the arguments of the message to be deserialized
|
||||||
*/
|
*/
|
||||||
@ -71,7 +71,7 @@ public:
|
|||||||
static_assert(std::is_base_of_v<BehaviorMessageBase, Msg>, "Msg must be a BehaviorMessageBase");
|
static_assert(std::is_base_of_v<BehaviorMessageBase, Msg>, "Msg must be a BehaviorMessageBase");
|
||||||
Msg msg{ args };
|
Msg msg{ args };
|
||||||
for (auto&& behavior : m_Behaviors) {
|
for (auto&& behavior : m_Behaviors) {
|
||||||
if (behavior.GetBehaviorId() == msg.GetBehaviorId()) {
|
if (behavior.GetBehaviorId() == msg.GetBehaviorId()) {
|
||||||
behavior.HandleMsg(msg);
|
behavior.HandleMsg(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -112,14 +112,24 @@ public:
|
|||||||
void SendBehaviorListToClient(AMFArrayValue& args) const;
|
void SendBehaviorListToClient(AMFArrayValue& args) const;
|
||||||
|
|
||||||
void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const;
|
void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const;
|
||||||
|
|
||||||
void VerifyBehaviors();
|
void VerifyBehaviors();
|
||||||
|
|
||||||
std::array<std::pair<int32_t, std::string>, 5> GetBehaviorsForSave() const;
|
std::array<std::pair<int32_t, std::string>, 5> GetBehaviorsForSave() const;
|
||||||
|
|
||||||
const std::vector<PropertyBehavior>& GetBehaviors() const { return m_Behaviors; };
|
const std::vector<PropertyBehavior>& GetBehaviors() const { return m_Behaviors; };
|
||||||
|
|
||||||
|
void SetIsPickable(bool pickable) { m_Dirty = m_IsPickable == pickable; m_IsPickable = pickable; }
|
||||||
|
|
||||||
|
void Pause() { m_Dirty = true; m_IsPaused = true; }
|
||||||
|
|
||||||
|
void Resume();
|
||||||
private:
|
private:
|
||||||
|
bool m_Dirty{};
|
||||||
|
|
||||||
|
bool m_IsPickable{};
|
||||||
|
|
||||||
|
bool m_IsPaused{};
|
||||||
/**
|
/**
|
||||||
* The behaviors of the model
|
* The behaviors of the model
|
||||||
* Note: This is a vector because the order of the behaviors matters when serializing to the client.
|
* Note: This is a vector because the order of the behaviors matters when serializing to the client.
|
||||||
|
@ -221,6 +221,8 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PropertyManagementComponent::OnStartBuilding() {
|
void PropertyManagementComponent::OnStartBuilding() {
|
||||||
|
m_IsBuilding = true;
|
||||||
|
|
||||||
auto* ownerEntity = GetOwner();
|
auto* ownerEntity = GetOwner();
|
||||||
|
|
||||||
if (ownerEntity == nullptr) return;
|
if (ownerEntity == nullptr) return;
|
||||||
@ -253,9 +255,20 @@ void PropertyManagementComponent::OnStartBuilding() {
|
|||||||
|
|
||||||
// Push equipped items
|
// Push equipped items
|
||||||
if (inventoryComponent) inventoryComponent->PushEquippedItems();
|
if (inventoryComponent) inventoryComponent->PushEquippedItems();
|
||||||
|
|
||||||
|
for (auto modelID : models | std::views::keys) {
|
||||||
|
auto* model = Game::entityManager->GetEntity(modelID);
|
||||||
|
if (model) {
|
||||||
|
auto* modelComponent = model->GetComponent<ModelComponent>();
|
||||||
|
if (modelComponent) modelComponent->Pause();
|
||||||
|
Game::entityManager->SerializeEntity(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyManagementComponent::OnFinishBuilding() {
|
void PropertyManagementComponent::OnFinishBuilding() {
|
||||||
|
m_IsBuilding = false;
|
||||||
|
|
||||||
auto* ownerEntity = GetOwner();
|
auto* ownerEntity = GetOwner();
|
||||||
|
|
||||||
if (ownerEntity == nullptr) return;
|
if (ownerEntity == nullptr) return;
|
||||||
@ -265,6 +278,15 @@ void PropertyManagementComponent::OnFinishBuilding() {
|
|||||||
UpdateApprovedStatus(false);
|
UpdateApprovedStatus(false);
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
|
|
||||||
|
for (auto modelID : models | std::views::keys) {
|
||||||
|
auto* model = Game::entityManager->GetEntity(modelID);
|
||||||
|
if (model) {
|
||||||
|
auto* modelComponent = model->GetComponent<ModelComponent>();
|
||||||
|
if (modelComponent) modelComponent->Resume();
|
||||||
|
Game::entityManager->SerializeEntity(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const NiPoint3 position, NiQuaternion rotation) {
|
void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const NiPoint3 position, NiQuaternion rotation) {
|
||||||
@ -316,6 +338,8 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
|
|||||||
Entity* newEntity = Game::entityManager->CreateEntity(info);
|
Entity* newEntity = Game::entityManager->CreateEntity(info);
|
||||||
if (newEntity != nullptr) {
|
if (newEntity != nullptr) {
|
||||||
Game::entityManager->ConstructEntity(newEntity);
|
Game::entityManager->ConstructEntity(newEntity);
|
||||||
|
auto* modelComponent = newEntity->GetComponent<ModelComponent>();
|
||||||
|
if (modelComponent) modelComponent->Pause();
|
||||||
|
|
||||||
// Make sure the propMgmt doesn't delete our model after the server dies
|
// Make sure the propMgmt doesn't delete our model after the server dies
|
||||||
// Trying to do this after the entity is constructed. Shouldn't really change anything but
|
// Trying to do this after the entity is constructed. Shouldn't really change anything but
|
||||||
@ -361,6 +385,8 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
|
|||||||
info.nodes[0]->config.push_back(new LDFData<int>(u"componentWhitelist", 1));
|
info.nodes[0]->config.push_back(new LDFData<int>(u"componentWhitelist", 1));
|
||||||
|
|
||||||
auto* model = spawner->Spawn();
|
auto* model = spawner->Spawn();
|
||||||
|
auto* modelComponent = model->GetComponent<ModelComponent>();
|
||||||
|
if (modelComponent) modelComponent->Pause();
|
||||||
|
|
||||||
models.insert_or_assign(model->GetObjectID(), spawnerId);
|
models.insert_or_assign(model->GetObjectID(), spawnerId);
|
||||||
|
|
||||||
|
@ -239,4 +239,6 @@ private:
|
|||||||
* The privacy setting before it was changed, saved to set back after a player finishes building
|
* The privacy setting before it was changed, saved to set back after a player finishes building
|
||||||
*/
|
*/
|
||||||
PropertyPrivacyOption originalPrivacyOption = PropertyPrivacyOption::Private;
|
PropertyPrivacyOption originalPrivacyOption = PropertyPrivacyOption::Private;
|
||||||
|
|
||||||
|
bool m_IsBuilding{};
|
||||||
};
|
};
|
||||||
|
@ -107,15 +107,11 @@ void Strip::SpawnDrop(LOT dropLOT, Entity& entity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Strip::Update(float deltaTime, ModelComponent& modelComponent) {
|
void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) {
|
||||||
m_PausedTime -= deltaTime;
|
|
||||||
if (m_PausedTime > 0.0f) return;
|
|
||||||
m_PausedTime = 0.0f;
|
|
||||||
auto& entity = *modelComponent.GetParent();
|
auto& entity = *modelComponent.GetParent();
|
||||||
auto& nextAction = GetNextAction();
|
auto& nextAction = GetNextAction();
|
||||||
auto number = nextAction.GetValueParameterDouble();
|
auto number = nextAction.GetValueParameterDouble();
|
||||||
auto numberAsInt = static_cast<int32_t>(number);
|
auto numberAsInt = static_cast<int32_t>(number);
|
||||||
|
|
||||||
if (GetNextAction().GetType() == "SpawnStromling") {
|
if (GetNextAction().GetType() == "SpawnStromling") {
|
||||||
Spawn(10495, entity);
|
Spawn(10495, entity);
|
||||||
} else if (GetNextAction().GetType() == "SpawnPirate") {
|
} else if (GetNextAction().GetType() == "SpawnPirate") {
|
||||||
@ -142,12 +138,30 @@ void Strip::Update(float deltaTime, ModelComponent& modelComponent) {
|
|||||||
} else if (nextAction.GetType() == "Wait") {
|
} else if (nextAction.GetType() == "Wait") {
|
||||||
m_PausedTime = number;
|
m_PausedTime = number;
|
||||||
} else {
|
} else {
|
||||||
|
LOG("Tried to play action (%s) which is not supported.", nextAction.GetType().data());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IncrementAction();
|
IncrementAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Strip::Update(float deltaTime, ModelComponent& modelComponent) {
|
||||||
|
m_PausedTime -= deltaTime;
|
||||||
|
if (m_PausedTime > 0.0f) return;
|
||||||
|
|
||||||
|
m_PausedTime = 0.0f;
|
||||||
|
auto& entity = *modelComponent.GetParent();
|
||||||
|
auto& nextAction = GetNextAction();
|
||||||
|
|
||||||
|
// Check for starting blocks and if not a starting block proc this blocks action
|
||||||
|
if (nextAction.GetType() == "OnInteract") {
|
||||||
|
modelComponent.SetIsPickable(true);
|
||||||
|
Game::entityManager->SerializeEntity(entity);
|
||||||
|
} else { // should be a normal block
|
||||||
|
ProcNormalAction(deltaTime, modelComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) const {
|
void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) const {
|
||||||
m_Position.SendBehaviorBlocksToClient(args);
|
m_Position.SendBehaviorBlocksToClient(args);
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ public:
|
|||||||
void Spawn(LOT object, Entity& entity);
|
void Spawn(LOT object, Entity& entity);
|
||||||
void Update(float deltaTime, ModelComponent& modelComponent);
|
void Update(float deltaTime, ModelComponent& modelComponent);
|
||||||
void SpawnDrop(LOT dropLOT, Entity& entity);
|
void SpawnDrop(LOT dropLOT, Entity& entity);
|
||||||
|
void ProcNormalAction(float deltaTime, ModelComponent& modelComponent);
|
||||||
private:
|
private:
|
||||||
float m_PausedTime{ 0.0f };
|
float m_PausedTime{ 0.0f };
|
||||||
size_t m_NextActionIndex{ 0 };
|
size_t m_NextActionIndex{ 0 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user