From 3efe05a88e3baeb8d6b37bb241e5a4c25655ed3b Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 27 May 2018 16:05:40 +0300 Subject: [PATCH] [General] Implement WorldCollisionOverride packet --- .../openmw-mp/Script/Functions/Worldstate.cpp | 35 +++++++++++ .../openmw-mp/Script/Functions/Worldstate.hpp | 62 ++++++++++++++++--- apps/openmw/mwclass/apparatus.cpp | 32 ++++++++++ apps/openmw/mwclass/armor.cpp | 32 ++++++++++ apps/openmw/mwclass/book.cpp | 32 ++++++++++ apps/openmw/mwclass/clothing.cpp | 32 ++++++++++ apps/openmw/mwclass/ingredient.cpp | 32 ++++++++++ apps/openmw/mwclass/misc.cpp | 32 ++++++++++ apps/openmw/mwclass/potion.cpp | 32 ++++++++++ apps/openmw/mwclass/repair.cpp | 32 ++++++++++ apps/openmw/mwclass/weapon.cpp | 32 ++++++++++ apps/openmw/mwmp/Worldstate.cpp | 5 +- apps/openmw/mwphysics/actor.cpp | 34 ++++++++++ components/openmw-mp/Base/BasePlayer.hpp | 4 -- components/openmw-mp/Base/BaseWorldstate.hpp | 5 ++ .../PacketWorldCollisionOverride.cpp | 5 +- 16 files changed, 425 insertions(+), 13 deletions(-) diff --git a/apps/openmw-mp/Script/Functions/Worldstate.cpp b/apps/openmw-mp/Script/Functions/Worldstate.cpp index 3793e034a..2210d4a6c 100644 --- a/apps/openmw-mp/Script/Functions/Worldstate.cpp +++ b/apps/openmw-mp/Script/Functions/Worldstate.cpp @@ -41,6 +41,27 @@ void WorldstateFunctions::SetTimeScale(double timeScale) noexcept { writeWorldstate.timeScale = timeScale; } + +void WorldstateFunctions::SetPlayerCollisionState(bool state) noexcept +{ + writeWorldstate.hasPlayerCollision = state; +} + +void WorldstateFunctions::SetActorCollisionState(bool state) noexcept +{ + writeWorldstate.hasActorCollision = state; +} + +void WorldstateFunctions::SetPlacedObjectCollisionState(bool state) noexcept +{ + writeWorldstate.hasPlacedObjectCollision = state; +} + +void WorldstateFunctions::UseActorCollisionForPlacedObjects(bool useActorCollision) noexcept +{ + writeWorldstate.useActorCollisionForPlacedObjects = useActorCollision; +} + void WorldstateFunctions::SendWorldTime(unsigned short pid, bool toOthers) noexcept { Player *player; @@ -54,3 +75,17 @@ void WorldstateFunctions::SendWorldTime(unsigned short pid, bool toOthers) noexc if (toOthers) mwmp::Networking::get().getWorldstatePacketController()->GetPacket(ID_WORLD_TIME)->Send(true); } + +void WorldstateFunctions::SendWorldCollisionOverride(unsigned short pid, bool toOthers) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ); + + writeWorldstate.guid = player->guid; + + mwmp::Networking::get().getWorldstatePacketController()->GetPacket(ID_WORLD_COLLISION_OVERRIDE)->setWorldstate(&writeWorldstate); + mwmp::Networking::get().getWorldstatePacketController()->GetPacket(ID_WORLD_COLLISION_OVERRIDE)->Send(false); + + if (toOthers) + mwmp::Networking::get().getWorldstatePacketController()->GetPacket(ID_WORLD_COLLISION_OVERRIDE)->Send(true); +} diff --git a/apps/openmw-mp/Script/Functions/Worldstate.hpp b/apps/openmw-mp/Script/Functions/Worldstate.hpp index ff60047df..bbc82e3ea 100644 --- a/apps/openmw-mp/Script/Functions/Worldstate.hpp +++ b/apps/openmw-mp/Script/Functions/Worldstate.hpp @@ -4,15 +4,20 @@ #include "../Types.hpp" #define WORLDSTATEAPI \ - {"SetHour", WorldstateFunctions::SetHour},\ - {"SetDay", WorldstateFunctions::SetDay},\ - {"SetMonth", WorldstateFunctions::SetMonth},\ - {"SetYear", WorldstateFunctions::SetYear},\ + {"SetHour", WorldstateFunctions::SetHour},\ + {"SetDay", WorldstateFunctions::SetDay},\ + {"SetMonth", WorldstateFunctions::SetMonth},\ + {"SetYear", WorldstateFunctions::SetYear},\ + {"SetDaysPassed", WorldstateFunctions::SetDaysPassed},\ + {"SetTimeScale", WorldstateFunctions::SetTimeScale},\ \ - {"SetDaysPassed", WorldstateFunctions::SetDaysPassed},\ - {"SetTimeScale", WorldstateFunctions::SetTimeScale},\ + {"SetPlayerCollisionState", WorldstateFunctions::SetPlayerCollisionState},\ + {"SetActorCollisionState", WorldstateFunctions::SetActorCollisionState},\ + {"SetPlacedObjectCollisionState", WorldstateFunctions::SetPlacedObjectCollisionState},\ + {"UseActorCollisionForPlacedObjects", WorldstateFunctions::UseActorCollisionForPlacedObjects},\ \ - {"SendWorldTime", WorldstateFunctions::SendWorldTime} + {"SendWorldTime", WorldstateFunctions::SendWorldTime},\ + {"SendWorldCollisionOverride", WorldstateFunctions::SendWorldCollisionOverride} class WorldstateFunctions { @@ -67,6 +72,40 @@ public: */ static void SetTimeScale(double timeScale) noexcept; + /** + * \brief Set the collision state for other players. + * + * \param state The collision state. + * \return void + */ + static void SetPlayerCollisionState(bool state) noexcept; + + /** + * \brief Set the collision state for actors. + * + * \param state The collision state. + * \return void + */ + static void SetActorCollisionState(bool state) noexcept; + + /** + * \brief Set the collision state for placed objects. + * + * \param state The collision state. + * \return void + */ + static void SetPlacedObjectCollisionState(bool state) noexcept; + + /** + * \brief Whether placed objects with collision turned on should use + * actor collision, i.e. whether they should be slippery + * and prevent players from standing on them. + * + * \param useActorCollision Whether to use actor collision. + * \return void + */ + static void UseActorCollisionForPlacedObjects(bool useActorCollision) noexcept; + /** * \brief Send a WorldTime packet with the current time and time scale * to a specific player or to all players. @@ -76,6 +115,15 @@ public: */ static void SendWorldTime(unsigned short pid, bool toOthers = false) noexcept; + /** + * \brief Send a WorldCollisionOverride packet with the current collision overrides + * to a specific player or to all players. + * + * \param pid The player ID. + * \return void + */ + static void SendWorldCollisionOverride(unsigned short pid, bool toOthers = false) noexcept; + }; #endif //OPENMW_WORLDSTATEAPI_HPP diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index a271dc5e9..ae16b289a 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -1,5 +1,16 @@ #include "apparatus.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include "../mwbase/environment.hpp" @@ -31,6 +42,27 @@ namespace MWClass void Apparatus::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Apparatus::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 460cd517a..6220c79d5 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -1,5 +1,16 @@ #include "armor.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include #include @@ -37,6 +48,27 @@ namespace MWClass void Armor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Armor::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 3d6455dc6..e16a99398 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -1,5 +1,16 @@ #include "book.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include "../mwbase/environment.hpp" @@ -34,6 +45,27 @@ namespace MWClass void Book::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Book::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index b37d1e90b..2f790e559 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -1,5 +1,16 @@ #include "clothing.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include "../mwbase/environment.hpp" @@ -33,6 +44,27 @@ namespace MWClass void Clothing::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Clothing::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 09d149331..6c03f31ef 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -1,5 +1,16 @@ #include "ingredient.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include "../mwbase/environment.hpp" @@ -34,6 +45,27 @@ namespace MWClass void Ingredient::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Ingredient::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 62b15bc86..0625dfdd6 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -1,5 +1,16 @@ #include "misc.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include @@ -41,6 +52,27 @@ namespace MWClass void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Miscellaneous::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index ffdccf438..475b4ef50 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -1,5 +1,16 @@ #include "potion.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include "../mwbase/environment.hpp" @@ -35,6 +46,27 @@ namespace MWClass void Potion::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Potion::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 566d16106..ec84bb803 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -1,5 +1,16 @@ #include "repair.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include "../mwbase/environment.hpp" @@ -31,6 +42,27 @@ namespace MWClass void Repair::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Repair::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index e59567aac..4d0b7411b 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -1,5 +1,16 @@ #include "weapon.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +/* + End of tes3mp addition +*/ + #include #include @@ -35,6 +46,27 @@ namespace MWClass void Weapon::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects + + /* + Start of tes3mp addition + + Make it possible to enable collision for this object class from a packet + */ + if (!model.empty()) + { + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (worldstate->hasPlacedObjectCollision) + { + if (worldstate->useActorCollisionForPlacedObjects) + physics.addObject(ptr, model, MWPhysics::CollisionType_Actor); + else + physics.addObject(ptr, model, MWPhysics::CollisionType_World); + } + } + /* + End of tes3mp addition + */ } std::string Weapon::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwmp/Worldstate.cpp b/apps/openmw/mwmp/Worldstate.cpp index 19b171417..e3c487445 100644 --- a/apps/openmw/mwmp/Worldstate.cpp +++ b/apps/openmw/mwmp/Worldstate.cpp @@ -7,7 +7,10 @@ using namespace std; Worldstate::Worldstate() { - + hasPlayerCollision = true; + hasActorCollision = true; + hasPlacedObjectCollision = false; + useActorCollisionForPlacedObjects = false; } Worldstate::~Worldstate() diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 6de0d1984..7376a794d 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -1,5 +1,18 @@ #include "actor.hpp" +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +#include "../mwmp/PlayerList.hpp" +/* + End of tes3mp addition +*/ + #include #include #include @@ -53,6 +66,27 @@ Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr updatePosition(); addCollisionMask(getCollisionMask()); + + /* + Start of tes3mp addition + + Make it possible to disable collision for players or regular actors from a packet + */ + mwmp::BaseWorldstate *worldstate = mwmp::Main::get().getNetworking()->getWorldstate(); + + if (mwmp::PlayerList::isDedicatedPlayer(ptr)) + { + if (!worldstate->hasPlayerCollision) + enableCollisionBody(false); + } + else + { + if (!worldstate->hasActorCollision) + enableCollisionBody(false); + } + /* + End of tes3mp addition + */ } Actor::~Actor() diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index 9cc13c71f..30d62a73d 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -1,7 +1,3 @@ -// -// Created by koncord on 07.01.16. -// - #ifndef OPENMW_BASEPLAYER_HPP #define OPENMW_BASEPLAYER_HPP diff --git a/components/openmw-mp/Base/BaseWorldstate.hpp b/components/openmw-mp/Base/BaseWorldstate.hpp index f8549b74e..6e2518c0f 100644 --- a/components/openmw-mp/Base/BaseWorldstate.hpp +++ b/components/openmw-mp/Base/BaseWorldstate.hpp @@ -32,6 +32,11 @@ namespace mwmp int daysPassed; float timeScale; + bool hasPlayerCollision; + bool hasActorCollision; + bool hasPlacedObjectCollision; + bool useActorCollisionForPlacedObjects; + bool isValid; }; } diff --git a/components/openmw-mp/Packets/Worldstate/PacketWorldCollisionOverride.cpp b/components/openmw-mp/Packets/Worldstate/PacketWorldCollisionOverride.cpp index b2b482b92..ee9720600 100644 --- a/components/openmw-mp/Packets/Worldstate/PacketWorldCollisionOverride.cpp +++ b/components/openmw-mp/Packets/Worldstate/PacketWorldCollisionOverride.cpp @@ -13,5 +13,8 @@ void PacketWorldCollisionOverride::Packet(RakNet::BitStream *bs, bool send) { WorldstatePacket::Packet(bs, send); - // Placeholder + RW(worldstate->hasPlayerCollision, send); + RW(worldstate->hasActorCollision, send); + RW(worldstate->hasPlacedObjectCollision, send); + RW(worldstate->useActorCollisionForPlacedObjects, send); }