From 12d7ab9034f148ea53407160c13606dc2c0602bf Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 6 Jun 2023 22:48:41 -0700 Subject: [PATCH 1/8] Remove null check in GetPosition (#1109) Get ready for null pointer errors --- dGame/Entity.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 6de6ba6..907e8e6 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1827,8 +1827,6 @@ bool Entity::IsSleeping() const { const NiPoint3& Entity::GetPosition() const { - if (!this) return NiPoint3::ZERO; - auto* controllable = GetComponent(); if (controllable != nullptr) { From 2a0f63c0a1ad7bef842bddbbbf647d934362791f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 14 Jun 2023 15:44:22 -0700 Subject: [PATCH 2/8] Fix all smashables not playing animations (#1112) Fixes an issue where most smashables did not explode into bricks upon death. This included anything that was spawned or didnt have the flag is_smashable set. Tested that in races, all objects smash into bricks Tested that the player properly explodes in their car if they crash Tested that Shooting Gallery plays the special smash animation when a ship is smashed Tested that all spawned objects play smash animations * Fix warning, Fix modular assembly not smashing * Rename variable to correct name --- dGame/Entity.cpp | 4 ++-- dGame/dComponents/DestroyableComponent.cpp | 4 ++-- dGame/dComponents/DestroyableComponent.h | 4 ++-- dGame/dComponents/InventoryComponent.cpp | 1 - dScripts/EquipmentScripts/BuccaneerValiantShip.cpp | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 907e8e6..bac0771 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -386,8 +386,8 @@ void Entity::Initialize() { comp->SetMaxCoins(currencyValues[0].maxvalue); } - // extraInfo overrides - comp->SetIsSmashable(GetVarAs(u"is_smashable") != 0); + // extraInfo overrides. Client ORs the database smashable and the luz smashable. + comp->SetIsSmashable(comp->GetIsSmashable() | (GetVarAs(u"is_smashable") != 0)); } } else { comp->SetHealth(1); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 01ebf5c..db8a201 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -51,7 +51,7 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_IsGMImmune = false; m_IsShielded = false; m_DamageToAbsorb = 0; - m_HasBricks = false; + m_IsModuleAssembly = m_Parent->HasComponent(eReplicaComponentType::MODULE_ASSEMBLY); m_DirtyThreatList = false; m_HasThreats = false; m_ExplodeFactor = 1.0f; @@ -163,7 +163,7 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_IsSmashed); if (m_IsSmashable) { - outBitStream->Write(m_HasBricks); + outBitStream->Write(m_IsModuleAssembly); outBitStream->Write(m_ExplodeFactor != 1.0f); if (m_ExplodeFactor != 1.0f) outBitStream->Write(m_ExplodeFactor); } diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 66c8374..5e5133b 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -239,7 +239,7 @@ public: * Returns whether or not this entity has bricks flying out when smashed * @return whether or not this entity has bricks flying out when smashed */ - bool GetHasBricks() const { return m_HasBricks; } + bool GetHasBricks() const { return m_IsModuleAssembly; } /** * Sets the multiplier for the explosion that's visible when the bricks fly out when this entity is smashed @@ -546,7 +546,7 @@ private: /** * Whether this entity has bricks flying out when smashed (causes the client to look up the files) */ - bool m_HasBricks; + bool m_IsModuleAssembly; /** * The rate at which bricks fly out when smashed diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 907356c..618e93b 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1002,7 +1002,6 @@ void InventoryComponent::HandlePossession(Item* item) { // Setup the destroyable stats auto* destroyableComponent = mount->GetComponent(); if (destroyableComponent) { - destroyableComponent->SetIsSmashable(false); destroyableComponent->SetIsImmune(true); } diff --git a/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp b/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp index 3db214b..1595462 100644 --- a/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp +++ b/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp @@ -11,7 +11,7 @@ void BuccaneerValiantShip::OnStartup(Entity* self) { // Kill self if missed self->AddCallbackTimer(1.1F, [self]() { - self->Kill(); + self->Smash(); }); } }); From 1a74c028c2eff7661d6ec3bcebadc777aed369ec Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 16 Jun 2023 16:09:46 -0500 Subject: [PATCH 3/8] fix: make vanity npc's use default equipment if none is specified (#1116) --- dGame/dUtilities/VanityUtilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 7fabfbc..ed425fe 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -163,7 +163,7 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin auto* inventoryComponent = entity->GetComponent(); - if (inventoryComponent != nullptr) { + if (inventoryComponent && !inventory.empty()) { inventoryComponent->SetNPCItems(inventory); } From 0d6bd33f9e592e3a4ef016dc3fc4b8f29cf8e7f1 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 16 Jun 2023 21:30:28 -0700 Subject: [PATCH 4/8] Remove unused problematic code (#1115) --- dZoneManager/Level.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dZoneManager/Level.h b/dZoneManager/Level.h index 83daeed..0f8fa72 100644 --- a/dZoneManager/Level.h +++ b/dZoneManager/Level.h @@ -30,12 +30,6 @@ public: struct SceneObjectDataChunk { std::map objects; - SceneObject& GetObject(LWOOBJID id) { - for (std::map::iterator it = objects.begin(); it != objects.end(); ++it) { - if (it->first == id) return it->second; - } - } - const void PrintAllObjects() { for (std::map::iterator it = objects.begin(); it != objects.end(); ++it) { std::cout << "\t ID: " << it->first << " LOT: " << it->second.lot << std::endl; From f46bc33dd48e82a757f1e043180ffb759b61df3b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 17 Jun 2023 17:20:05 -0700 Subject: [PATCH 5/8] Fix prereq bug (#1118) --- dGame/dComponents/InventoryComponent.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 618e93b..626c7ee 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -38,7 +38,7 @@ #include "CDObjectSkillsTable.h" #include "CDSkillBehaviorTable.h" -InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) { +InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) { this->m_Dirty = true; this->m_Equipped = {}; this->m_Pushed = {}; @@ -830,14 +830,22 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { const auto position = m_Parent->GetPosition(); - for (auto* lauchPad : rocketLauchPads) { - if (Vector3::DistanceSquared(lauchPad->GetPosition(), position) > 13 * 13) continue; + for (auto* launchPad : rocketLauchPads) { + if (!launchPad) continue; + + auto prereq = launchPad->GetVarAsString(u"rocketLaunchPreCondition"); + if (!prereq.empty()) { + PreconditionExpression expression(prereq); + if (!expression.Check(m_Parent)) continue; + } + + if (Vector3::DistanceSquared(launchPad->GetPosition(), position) > 13 * 13) continue; auto* characterComponent = m_Parent->GetComponent(); if (characterComponent != nullptr) characterComponent->SetLastRocketItemID(item->GetId()); - lauchPad->OnUse(m_Parent); + launchPad->OnUse(m_Parent); break; } From 2d31b7e4bb913a6df9d3bab988ca9b652a2e8238 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 18 Jun 2023 00:00:36 -0700 Subject: [PATCH 6/8] Fix incorrect serialization of SendTeleport (#1121) * Fix incorrect serialization of SendTeleport - Fixes all incorrect teleports in the game - remove hacks in mast teleport - ... - ...... Update GameMessages.cpp * Remove stupid argument there got it all out * remove extra true --- dGame/dComponents/RacingControlComponent.cpp | 11 ++++------- dGame/dGameMessages/GameMessages.cpp | 3 +-- dGame/dGameMessages/GameMessages.h | 2 +- dScripts/02_server/Map/GF/MastTeleport.cpp | 10 +--------- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 4a4ead5..c16e99f 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -124,8 +124,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Make sure the player is at the correct position. GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); // Spawn the vehicle entity. @@ -243,11 +242,9 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Make sure everything has the correct position. GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); GameMessages::SendTeleport(carEntity->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); } void RacingControlComponent::OnRacingClientReady(Entity* player) { @@ -634,7 +631,7 @@ void RacingControlComponent::Update(float deltaTime) { GameMessages::SendTeleport( player.playerID, player.respawnPosition, player.respawnRotation, - playerEntity->GetSystemAddress(), true, true); + playerEntity->GetSystemAddress(), true); vehicle->SetPosition(player.respawnPosition); vehicle->SetRotation(player.respawnRotation); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 1646002..0c3207d 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -120,7 +120,7 @@ void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const Syste SEND_PACKET; } -void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation, bool noGravTeleport) { +void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); @@ -141,7 +141,6 @@ void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, c bitStream.Write(pos.y); bitStream.Write(pos.z); bitStream.Write(bUseNavmesh); - bitStream.Write(noGravTeleport); bitStream.Write(rot.w != 1.0f); if (rot.w != 1.0f) bitStream.Write(rot.w); diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 7e7a8f7..94bdd3e 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -40,7 +40,7 @@ enum class eRebuildState : uint32_t; namespace GameMessages { class PropertyDataMessage; void SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender); - void SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation = false, bool noGravTeleport = true); + void SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation = false); void SendPlayAnimation(Entity* entity, const std::u16string& animationName, float fPriority = 0.0f, float fScale = 1.0f); void SendPlayerReady(Entity* entity, const SystemAddress& sysAddr); void SendPlayerAllowedRespawn(LWOOBJID entityID, bool doNotPromptRespawn, const SystemAddress& systemAddress); diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index 311da34..5f8795a 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -43,15 +43,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendTeleport(playerId, position, rotation, player->GetSystemAddress(), true); - // Hacky fix for odd rotations - auto mastName = self->GetVar(u"MastName"); - if (mastName == u"Elephant") { - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 140.0f, player->GetSystemAddress()); - } else if (mastName == u"Jail") { - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 100.0f, player->GetSystemAddress()); - } else if (mastName == u""){ - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 203.0f, player->GetSystemAddress()); - } + GameMessages::SendTeleport(playerId, position, rotation, player->GetSystemAddress(), true); const auto cinematic = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Cinematic")); const auto leanIn = self->GetVar(u"LeanIn"); From 132d31d3aba5df0bf089407a32af39ead259125c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 20 Jun 2023 07:19:21 -0700 Subject: [PATCH 7/8] Fix vehicle serialization during races (#1122) * Fix vehicle serialization during races - Add missing frame stats reading - correct the inversion of rotation - correct serialization order - use proper dirty flags Tested that racers are no longer sideways on certain vertical slopes and stay in sync throughout the whole race. * Update ClientPackets.cpp * Update ClientPackets.cpp * Update VehiclePhysicsComponent.h --- dGame/dComponents/VehiclePhysicsComponent.cpp | 49 +++++++++++++++---- dGame/dComponents/VehiclePhysicsComponent.h | 21 ++++++++ dNet/ClientPackets.cpp | 31 ++++++++++-- 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/dGame/dComponents/VehiclePhysicsComponent.cpp b/dGame/dComponents/VehiclePhysicsComponent.cpp index d981acf..58bf7eb 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.cpp +++ b/dGame/dComponents/VehiclePhysicsComponent.cpp @@ -19,34 +19,47 @@ VehiclePhysicsComponent::~VehiclePhysicsComponent() { } void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) { + if (pos == m_Position) return; + m_DirtyPosition = true; m_Position = pos; } void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) { + if (rot == m_Rotation) return; m_DirtyPosition = true; m_Rotation = rot; } void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) { + if (vel == m_Velocity) return; m_DirtyPosition = true; m_Velocity = vel; } void VehiclePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) { + if (vel == m_AngularVelocity) return; m_DirtyPosition = true; m_AngularVelocity = vel; } void VehiclePhysicsComponent::SetIsOnGround(bool val) { + if (val == m_IsOnGround) return; m_DirtyPosition = true; m_IsOnGround = val; } void VehiclePhysicsComponent::SetIsOnRail(bool val) { + if (val == m_IsOnRail) return; m_DirtyPosition = true; m_IsOnRail = val; } +void VehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) { + if (m_RemoteInputInfo == remoteInputInfo) return; + this->m_RemoteInputInfo = remoteInputInfo; + m_DirtyRemoteInput = true; +} + void VehiclePhysicsComponent::SetDirtyPosition(bool val) { m_DirtyPosition = val; } @@ -63,9 +76,15 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI outBitStream->Write(bIsInitialUpdate || m_DirtyPosition); if (bIsInitialUpdate || m_DirtyPosition) { - outBitStream->Write(m_Position); + m_DirtyPosition = false; + outBitStream->Write(m_Position.x); + outBitStream->Write(m_Position.y); + outBitStream->Write(m_Position.z); - outBitStream->Write(m_Rotation); + outBitStream->Write(m_Rotation.x); + outBitStream->Write(m_Rotation.y); + outBitStream->Write(m_Rotation.z); + outBitStream->Write(m_Rotation.w); outBitStream->Write(m_IsOnGround); outBitStream->Write(m_IsOnRail); @@ -73,20 +92,33 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI outBitStream->Write(bIsInitialUpdate || m_DirtyVelocity); if (bIsInitialUpdate || m_DirtyVelocity) { - outBitStream->Write(m_Velocity); + outBitStream->Write(m_Velocity.x); + outBitStream->Write(m_Velocity.y); + outBitStream->Write(m_Velocity.z); + m_DirtyVelocity = false; } outBitStream->Write(bIsInitialUpdate || m_DirtyAngularVelocity); if (bIsInitialUpdate || m_DirtyAngularVelocity) { - outBitStream->Write(m_AngularVelocity); + outBitStream->Write(m_AngularVelocity.x); + outBitStream->Write(m_AngularVelocity.y); + outBitStream->Write(m_AngularVelocity.z); + m_DirtyAngularVelocity = false; } - outBitStream->Write0(); + outBitStream->Write0(); // local_space_info. TODO: Implement this - outBitStream->Write0(); + outBitStream->Write(m_DirtyRemoteInput || bIsInitialUpdate); // remote_input_info + if (m_DirtyRemoteInput || bIsInitialUpdate) { + outBitStream->Write(m_RemoteInputInfo.m_RemoteInputX); + outBitStream->Write(m_RemoteInputInfo.m_RemoteInputY); + outBitStream->Write(m_RemoteInputInfo.m_IsPowersliding); + outBitStream->Write(m_RemoteInputInfo.m_IsModified); + m_DirtyRemoteInput = false; + } - outBitStream->Write(0.0f); + outBitStream->Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race. if (!bIsInitialUpdate) { outBitStream->Write0(); @@ -95,7 +127,7 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI if (bIsInitialUpdate) { outBitStream->Write(m_EndBehavior); - outBitStream->Write1(); + outBitStream->Write1(); // is input locked? } outBitStream->Write0(); @@ -104,7 +136,6 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI void VehiclePhysicsComponent::Update(float deltaTime) { if (m_SoftUpdate > 5) { EntityManager::Instance()->SerializeEntity(m_Parent); - m_SoftUpdate = 0; } else { m_SoftUpdate += deltaTime; diff --git a/dGame/dComponents/VehiclePhysicsComponent.h b/dGame/dComponents/VehiclePhysicsComponent.h index 64609ed..e314bef 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.h +++ b/dGame/dComponents/VehiclePhysicsComponent.h @@ -5,6 +5,24 @@ #include "Component.h" #include "eReplicaComponentType.h" +struct RemoteInputInfo { + void operator=(const RemoteInputInfo& other) { + m_RemoteInputX = other.m_RemoteInputX; + m_RemoteInputY = other.m_RemoteInputY; + m_IsPowersliding = other.m_IsPowersliding; + m_IsModified = other.m_IsModified; + } + + bool operator==(const RemoteInputInfo& other) { + return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified; + } + + float m_RemoteInputX; + float m_RemoteInputY; + bool m_IsPowersliding; + bool m_IsModified; +}; + /** * Physics component for vehicles. */ @@ -94,6 +112,7 @@ public: void SetDirtyPosition(bool val); void SetDirtyVelocity(bool val); void SetDirtyAngularVelocity(bool val); + void SetRemoteInputInfo(const RemoteInputInfo&); private: bool m_DirtyPosition; @@ -110,4 +129,6 @@ private: float m_SoftUpdate = 0; uint32_t m_EndBehavior; + RemoteInputInfo m_RemoteInputInfo; + bool m_DirtyRemoteInput; }; diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 1c22bdc..313be6b 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -136,6 +136,33 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac inStream.Read(angVelocity.z); } + // TODO figure out how to use these. Ignoring for now, but reading in if they exist. + bool hasLocalSpaceInfo{}; + LWOOBJID objectId{}; + NiPoint3 localSpacePosition{}; + bool hasLinearVelocity{}; + NiPoint3 linearVelocity{}; + if (inStream.Read(hasLocalSpaceInfo) && hasLocalSpaceInfo) { + inStream.Read(objectId); + inStream.Read(localSpacePosition.x); + inStream.Read(localSpacePosition.y); + inStream.Read(localSpacePosition.z); + if (inStream.Read(hasLinearVelocity) && hasLinearVelocity) { + inStream.Read(linearVelocity.x); + inStream.Read(linearVelocity.y); + inStream.Read(linearVelocity.z); + } + } + bool hasRemoteInputInfo{}; + RemoteInputInfo remoteInput{}; + + if (inStream.Read(hasRemoteInputInfo) && hasRemoteInputInfo) { + inStream.Read(remoteInput.m_RemoteInputX); + inStream.Read(remoteInput.m_RemoteInputY); + inStream.Read(remoteInput.m_IsPowersliding); + inStream.Read(remoteInput.m_IsModified); + } + bool updateChar = true; if (possessorComponent != nullptr) { @@ -150,9 +177,6 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac auto* vehiclePhysicsComponent = possassableEntity->GetComponent(); if (vehiclePhysicsComponent != nullptr) { - // This is flipped for whatever reason - rotation = NiQuaternion(rotation.z, rotation.y, rotation.x, rotation.w); - vehiclePhysicsComponent->SetPosition(position); vehiclePhysicsComponent->SetRotation(rotation); vehiclePhysicsComponent->SetIsOnGround(onGround); @@ -161,6 +185,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac vehiclePhysicsComponent->SetDirtyVelocity(velocityFlag); vehiclePhysicsComponent->SetAngularVelocity(angVelocity); vehiclePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag); + vehiclePhysicsComponent->SetRemoteInputInfo(remoteInput); } else { // Need to get the mount's controllable physics auto* controllablePhysicsComponent = possassableEntity->GetComponent(); From fe23c7c5f7543a95c9c327ac9cefab21f0395645 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 20 Jun 2023 08:40:16 -0700 Subject: [PATCH 8/8] Allow default scripts (#1117) Fix an issue where vanity script overwrote always --- dGame/dUtilities/VanityUtilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index ed425fe..703f7d3 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -119,7 +119,7 @@ void VanityUtilities::SpawnVanity() { auto* scriptComponent = npcEntity->GetComponent(); - if (scriptComponent != nullptr) { + if (scriptComponent && !npc.m_Script.empty()) { scriptComponent->SetScript(npc.m_Script); scriptComponent->SetSerialized(false);