From a7eeba03a10285fd78e268e6748857f95220fff0 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 1 May 2022 21:59:17 +0300 Subject: [PATCH] [General] Synchronize origin and orientation for non-magical projectiles --- .../player/ProcessorPlayerAttack.hpp | 11 +++- apps/openmw/mwrender/weaponanimation.cpp | 66 +++++++++++++++++++ components/openmw-mp/Base/BaseStructs.hpp | 1 + .../Packets/Actor/PacketActorAttack.cpp | 8 +++ .../Packets/Player/PacketPlayerAttack.cpp | 8 +++ 5 files changed, 92 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmp/processors/player/ProcessorPlayerAttack.hpp b/apps/openmw/mwmp/processors/player/ProcessorPlayerAttack.hpp index e176b501f..0fbf063bc 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorPlayerAttack.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorPlayerAttack.hpp @@ -17,8 +17,15 @@ namespace mwmp virtual void Do(PlayerPacket &packet, BasePlayer *player) { - if (player != 0) - MechanicsHelper::processAttack(player->attack, static_cast(player)->getPtr()); + if (!isLocal() && player != 0) + { + DedicatedPlayer& dedicatedPlayer = static_cast(*player); + MWWorld::Ptr playerPtr = dedicatedPlayer.getPtr(); + MWBase::World* world = MWBase::Environment::get().getWorld(); + world->moveObject(playerPtr, dedicatedPlayer.position.pos[0], dedicatedPlayer.position.pos[1], dedicatedPlayer.position.pos[2]); + world->rotateObject(playerPtr, dedicatedPlayer.position.rot[0], 0, dedicatedPlayer.position.rot[2]); + MechanicsHelper::processAttack(player->attack, playerPtr); + } } }; } diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index 11eb60f88..12007f93e 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -184,6 +184,39 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) return; osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); + /* + Start of tes3mp addition + + If the actor shooting this is a LocalPlayer or LocalActor, track their projectile origin so it can be sent + in the next PlayerAttack or ActorAttack packet + + Otherwise, set the projectileOrigin for a DedicatedPlayer or DedicatedActor + */ + if (localAttack) + { + localAttack->projectileOrigin.origin[0] = launchPos.x(); + localAttack->projectileOrigin.origin[1] = launchPos.y(); + localAttack->projectileOrigin.origin[2] = launchPos.z(); + localAttack->projectileOrigin.orientation[0] = orient.x(); + localAttack->projectileOrigin.orientation[1] = orient.y(); + localAttack->projectileOrigin.orientation[2] = orient.z(); + localAttack->projectileOrigin.orientation[3] = orient.w(); + } + else + { + mwmp::Attack* dedicatedAttack = MechanicsHelper::getDedicatedAttack(actor); + + if (dedicatedAttack) + { + launchPos = osg::Vec3f(dedicatedAttack->projectileOrigin.origin[0], dedicatedAttack->projectileOrigin.origin[1], dedicatedAttack->projectileOrigin.origin[2]); + orient = osg::Quat(dedicatedAttack->projectileOrigin.orientation[0], dedicatedAttack->projectileOrigin.orientation[1], dedicatedAttack->projectileOrigin.orientation[2], + dedicatedAttack->projectileOrigin.orientation[3]); + } + } + /* + End of tes3mp addition + */ + float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat(); float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat(); float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength; @@ -222,6 +255,39 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) return; osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); + /* + Start of tes3mp addition + + If the actor shooting this is a LocalPlayer or LocalActor, track their projectile origin so it can be sent + in the next PlayerAttack or ActorAttack packet + + Otherwise, set the projectileOrigin for a DedicatedPlayer or DedicatedActor + */ + if (localAttack) + { + localAttack->projectileOrigin.origin[0] = launchPos.x(); + localAttack->projectileOrigin.origin[1] = launchPos.y(); + localAttack->projectileOrigin.origin[2] = launchPos.z(); + localAttack->projectileOrigin.orientation[0] = orient.x(); + localAttack->projectileOrigin.orientation[1] = orient.y(); + localAttack->projectileOrigin.orientation[2] = orient.z(); + localAttack->projectileOrigin.orientation[3] = orient.w(); + } + else + { + mwmp::Attack* dedicatedAttack = MechanicsHelper::getDedicatedAttack(actor); + + if (dedicatedAttack) + { + launchPos = osg::Vec3f(dedicatedAttack->projectileOrigin.origin[0], dedicatedAttack->projectileOrigin.origin[1], dedicatedAttack->projectileOrigin.origin[2]); + orient = osg::Quat(dedicatedAttack->projectileOrigin.orientation[0], dedicatedAttack->projectileOrigin.orientation[1], dedicatedAttack->projectileOrigin.orientation[2], + dedicatedAttack->projectileOrigin.orientation[3]); + } + } + /* + End of tes3mp addition + */ + float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat(); float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength; diff --git a/components/openmw-mp/Base/BaseStructs.hpp b/components/openmw-mp/Base/BaseStructs.hpp index 2c07fd11e..82e7f5782 100644 --- a/components/openmw-mp/Base/BaseStructs.hpp +++ b/components/openmw-mp/Base/BaseStructs.hpp @@ -123,6 +123,7 @@ namespace mwmp std::string rangedAmmoId; ESM::Position hitPosition; + ProjectileOrigin projectileOrigin; float damage = 0; float attackStrength = 0; diff --git a/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp b/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp index 4ce20c026..aa3c70b85 100644 --- a/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp +++ b/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp @@ -40,6 +40,14 @@ void PacketActorAttack::Actor(BaseActor &actor, bool send) RW(actor.attack.attackStrength, send); RW(actor.attack.rangedWeaponId, send, true); RW(actor.attack.rangedAmmoId, send, true); + + RW(actor.attack.projectileOrigin.origin[0], send); + RW(actor.attack.projectileOrigin.origin[1], send); + RW(actor.attack.projectileOrigin.origin[2], send); + RW(actor.attack.projectileOrigin.orientation[0], send); + RW(actor.attack.projectileOrigin.orientation[1], send); + RW(actor.attack.projectileOrigin.orientation[2], send); + RW(actor.attack.projectileOrigin.orientation[3], send); } if (actor.attack.isHit) diff --git a/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp b/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp index 9e11bcdbe..d082fc5ad 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp @@ -41,6 +41,14 @@ void PacketPlayerAttack::Packet(RakNet::BitStream *newBitstream, bool send) RW(player->attack.attackStrength, send); RW(player->attack.rangedWeaponId, send, true); RW(player->attack.rangedAmmoId, send, true); + + RW(player->attack.projectileOrigin.origin[0], send); + RW(player->attack.projectileOrigin.origin[1], send); + RW(player->attack.projectileOrigin.origin[2], send); + RW(player->attack.projectileOrigin.orientation[0], send); + RW(player->attack.projectileOrigin.orientation[1], send); + RW(player->attack.projectileOrigin.orientation[2], send); + RW(player->attack.projectileOrigin.orientation[3], send); } if (player->attack.isHit)