[General] Implement OnObjectSound packet

Many interactions between players and objects now have their sounds sent to other players.
pull/558/head
David Cernat 5 years ago
parent 4b69d1cc51
commit 27d35d73a2

@ -120,10 +120,10 @@ set(PROCESSORS_OBJECT
processors/object/ProcessorObjectLock.hpp processors/object/ProcessorObjectMove.hpp
processors/object/ProcessorObjectPlace.hpp processors/object/ProcessorObjectRestock.hpp
processors/object/ProcessorObjectRotate.hpp processors/object/ProcessorObjectScale.hpp
processors/object/ProcessorObjectSpawn.hpp processors/object/ProcessorObjectState.hpp
processors/object/ProcessorObjectTrap.hpp processors/object/ProcessorClientScriptLocal.hpp
processors/object/ProcessorScriptMemberShort.hpp processors/object/ProcessorScriptMemberFloat.hpp
processors/object/ProcessorVideoPlay.hpp
processors/object/ProcessorObjectSound.hpp processors/object/ProcessorObjectSpawn.hpp
processors/object/ProcessorObjectState.hpp processors/object/ProcessorObjectTrap.hpp
processors/object/ProcessorClientScriptLocal.hpp processors/object/ProcessorScriptMemberShort.hpp
processors/object/ProcessorScriptMemberFloat.hpp processors/object/ProcessorVideoPlay.hpp
)
source_group(tes3mp-server\\processors\\object FILES ${PROCESSORS_OBJECT})

@ -134,6 +134,11 @@ double ObjectFunctions::GetObjectScale(unsigned int index) noexcept
return readObjectList->baseObjects.at(index).scale;
}
const char *ObjectFunctions::GetObjectSoundId(unsigned int index) noexcept
{
return readObjectList->baseObjects.at(index).soundId.c_str();
}
bool ObjectFunctions::GetObjectState(unsigned int index) noexcept
{
return readObjectList->baseObjects.at(index).objectState;
@ -708,6 +713,17 @@ void ObjectFunctions::SendObjectScale(bool sendToOtherPlayers, bool skipAttached
packet->Send(true);
}
void ObjectFunctions::SendObjectSound(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
{
mwmp::ObjectPacket *packet = mwmp::Networking::get().getObjectPacketController()->GetPacket(ID_OBJECT_SOUND);
packet->setObjectList(&writeObjectList);
if (!skipAttachedPlayer)
packet->Send(false);
if (sendToOtherPlayers)
packet->Send(true);
}
void ObjectFunctions::SendObjectState(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
{
mwmp::ObjectPacket *packet = mwmp::Networking::get().getObjectPacketController()->GetPacket(ID_OBJECT_STATE);

@ -27,6 +27,7 @@
{"GetObjectSoul" , ObjectFunctions::GetObjectSoul},\
{"GetObjectGoldValue", ObjectFunctions::GetObjectGoldValue},\
{"GetObjectScale", ObjectFunctions::GetObjectScale},\
{"GetObjectSoundId", ObjectFunctions::GetObjectSoundId},\
{"GetObjectState", ObjectFunctions::GetObjectState},\
{"GetObjectDoorState", ObjectFunctions::GetObjectDoorState},\
{"GetObjectLockLevel", ObjectFunctions::GetObjectLockLevel},\
@ -142,6 +143,7 @@
{"SendObjectRestock", ObjectFunctions::SendObjectRestock},\
{"SendObjectTrap", ObjectFunctions::SendObjectTrap},\
{"SendObjectScale", ObjectFunctions::SendObjectScale},\
{"SendObjectSound", ObjectFunctions::SendObjectSound},\
{"SendObjectState", ObjectFunctions::SendObjectState},\
{"SendDoorState", ObjectFunctions::SendDoorState},\
{"SendDoorDestination", ObjectFunctions::SendDoorDestination},\
@ -346,6 +348,14 @@ public:
*/
static double GetObjectScale(unsigned int index) noexcept;
/**
* \brief Get the object sound ID of the object at a certain index in the read object list.
*
* \param index The index of the object.
* \return The object sound ID.
*/
static const char *GetObjectSoundId(unsigned int index) noexcept;
/**
* \brief Get the object state of the object at a certain index in the read object list.
*
@ -1221,6 +1231,17 @@ public:
*/
static void SendObjectScale(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
/**
* \brief Send an ObjectSound packet.
*
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
* player attached to the packet (false by default).
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
* to the packet (false by default).
* \return void
*/
static void SendObjectSound(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
/**
* \brief Send an ObjectState packet.
*

@ -197,6 +197,7 @@ public:
{"OnObjectLock", Callback<unsigned short, const char*>()},
{"OnObjectRestock", Callback<unsigned short, const char*>()},
{"OnObjectScale", Callback<unsigned short, const char*>()},
{"OnObjectSound", Callback<unsigned short, const char*>()},
{"OnObjectTrap", Callback<unsigned short, const char*>()},
{"OnVideoPlay", Callback<unsigned short, const char*>()},
{"OnActorList", Callback<unsigned short, const char*>()},

@ -68,6 +68,7 @@
#include "object/ProcessorObjectRestock.hpp"
#include "object/ProcessorObjectRotate.hpp"
#include "object/ProcessorObjectScale.hpp"
#include "object/ProcessorObjectSound.hpp"
#include "object/ProcessorObjectSpawn.hpp"
#include "object/ProcessorObjectState.hpp"
#include "object/ProcessorObjectTrap.hpp"
@ -150,6 +151,7 @@ void ProcessorInitializer()
ObjectProcessor::AddProcessor(new ProcessorObjectRestock());
ObjectProcessor::AddProcessor(new ProcessorObjectRotate());
ObjectProcessor::AddProcessor(new ProcessorObjectScale());
ObjectProcessor::AddProcessor(new ProcessorObjectSound());
ObjectProcessor::AddProcessor(new ProcessorObjectSpawn());
ObjectProcessor::AddProcessor(new ProcessorObjectState());
ObjectProcessor::AddProcessor(new ProcessorObjectTrap());

@ -0,0 +1,25 @@
#ifndef OPENMW_PROCESSOROBJECTSOUND_HPP
#define OPENMW_PROCESSOROBJECTSOUND_HPP
#include "../ObjectProcessor.hpp"
namespace mwmp
{
class ProcessorObjectSound : public ObjectProcessor
{
public:
ProcessorObjectSound()
{
BPP_INIT(ID_OBJECT_SOUND)
}
void Do(ObjectPacket &packet, Player &player, BaseObjectList &objectList) override
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received %s from %s", strPacketID.c_str(), player.npc.mName.c_str());
Script::Call<Script::CallbackIdentity("OnObjectSound")>(player.getId(), objectList.cell.getDescription().c_str());
}
};
}
#endif //OPENMW_PROCESSOROBJECTSOUND_HPP

@ -6,6 +6,18 @@
#include <MyGUI_ControllerManager.h>
#include <MyGUI_ControllerRepeatClick.h>
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
#include "../mwmp/Main.hpp"
#include "../mwmp/Networking.hpp"
#include "../mwmp/ObjectList.hpp"
/*
End of tes3mp addition
*/
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
@ -102,6 +114,16 @@ namespace MWGui
MWMechanics::Alchemy::Result result = mAlchemy->create(mNameEdit->getCaption(), count);
MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager();
/*
Start of tes3mp addition
Declare objectList here so we can use it below
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
/*
End of tes3mp addition
*/
switch (result)
{
case MWMechanics::Alchemy::Result_NoName:
@ -115,6 +137,20 @@ namespace MWGui
break;
case MWMechanics::Alchemy::Result_Success:
winMgr->playSound("potion success");
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "potion success", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
if (count == 1)
winMgr->messageBox("#{sPotionSuccess}");
else
@ -124,6 +160,20 @@ namespace MWGui
case MWMechanics::Alchemy::Result_RandomFailure:
winMgr->messageBox("#{sNotifyMessage8}");
winMgr->playSound("potion fail");
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "potion fail", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
break;
}

@ -9,6 +9,18 @@
#include <components/widgets/list.hpp>
#include <components/settings/settings.hpp>
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
#include "../mwmp/Main.hpp"
#include "../mwmp/Networking.hpp"
#include "../mwmp/ObjectList.hpp"
/*
End of tes3mp addition
*/
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/world.hpp"
@ -358,11 +370,40 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->playSound("enchant success");
MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu12}");
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "enchant success", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
else
{
MWBase::Environment::get().getWindowManager()->playSound("enchant fail");
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage34}");
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "enchant fail", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
if (!mEnchanting.getGem().isEmpty() && !mEnchanting.getGem().getRefData().getCount())
{
setSoulGem(MWWorld::Ptr());

@ -97,10 +97,38 @@ bool rechargeItem(const MWWorld::Ptr &item, const MWWorld::Ptr &gem)
MWBase::Environment::get().getWindowManager()->playSound("Enchant Success");
player.getClass().getContainerStore(player).restack(item);
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "Enchant Success", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
else
{
MWBase::Environment::get().getWindowManager()->playSound("Enchant Fail");
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "Enchant Fail", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0);

@ -97,11 +97,39 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
MWBase::Environment::get().getWindowManager()->playSound("Repair");
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairSuccess}");
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "Repair", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
else
{
MWBase::Environment::get().getWindowManager()->playSound("Repair Fail");
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairFailed}");
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time the player makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(MWMechanics::getPlayer(), "Repair Fail", 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
// tool used up?

@ -326,7 +326,7 @@ void ObjectList::activateObjects(MWWorld::CellStore* cellStore)
}
else
{
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Could not find player to activatee!");
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Could not find player to activate!");
}
}
}
@ -758,6 +758,47 @@ void ObjectList::animateObjects(MWWorld::CellStore* cellStore)
}
}
void ObjectList::playObjectSounds(MWWorld::CellStore* cellStore)
{
for (const auto &baseObject : baseObjects)
{
MWWorld::Ptr ptrFound;
std::string objectDescription;
if (baseObject.isPlayer)
{
if (baseObject.guid == Main::get().getLocalPlayer()->guid)
{
objectDescription = "LocalPlayer " + Main::get().getLocalPlayer()->npc.mName;
ptrFound = Main::get().getLocalPlayer()->getPlayerPtr();
}
else
{
DedicatedPlayer *player = PlayerList::getPlayer(baseObject.guid);
if (player != 0)
{
objectDescription = "DedicatedPlayer " + player->npc.mName;
ptrFound = player->getPtr();
}
}
}
else
{
objectDescription = baseObject.refId + " " + std::to_string(baseObject.refNum) + "-" + std::to_string(baseObject.mpNum);
ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
}
if (ptrFound)
{
LOG_APPEND(TimedLog::LOG_VERBOSE, "- Playing sound %s on %s", baseObject.soundId.c_str(), objectDescription.c_str());
MWBase::Environment::get().getSoundManager()->playSound3D(ptrFound, baseObject.soundId,
baseObject.volume, baseObject.pitch, MWSound::Type::Sfx, MWSound::PlayMode::Normal, 0);
}
}
}
void ObjectList::activateDoors(MWWorld::CellStore* cellStore)
{
for (const auto &baseObject : baseObjects)
@ -1130,6 +1171,17 @@ void ObjectList::addObjectScale(const MWWorld::Ptr& ptr, float scale)
addBaseObject(baseObject);
}
void ObjectList::addObjectSound(const MWWorld::Ptr& ptr, std::string soundId, float volume, float pitch)
{
cell = *ptr.getCell()->getCell();
mwmp::BaseObject baseObject = getBaseObjectFromPtr(ptr);
baseObject.soundId = soundId;
baseObject.volume = volume;
baseObject.pitch = pitch;
addBaseObject(baseObject);
}
void ObjectList::addObjectState(const MWWorld::Ptr& ptr, bool objectState)
{
cell = *ptr.getCell()->getCell();
@ -1262,6 +1314,12 @@ void ObjectList::sendObjectRestock()
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_RESTOCK)->Send();
}
void ObjectList::sendObjectSound()
{
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_SOUND)->setObjectList(this);
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_SOUND)->Send();
}
void ObjectList::sendObjectTrap()
{
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_TRAP)->setObjectList(this);

@ -37,6 +37,7 @@ namespace mwmp
void restockObjects(MWWorld::CellStore* cellStore);
void rotateObjects(MWWorld::CellStore* cellStore);
void animateObjects(MWWorld::CellStore* cellStore);
void playObjectSounds(MWWorld::CellStore* cellStore);
void activateDoors(MWWorld::CellStore* cellStore);
void setDoorDestinations(MWWorld::CellStore* cellStore);
void runConsoleCommands(MWWorld::CellStore* cellStore);
@ -60,6 +61,7 @@ namespace mwmp
void addObjectLock(const MWWorld::Ptr& ptr, int lockLevel);
void addObjectTrap(const MWWorld::Ptr& ptr, const ESM::Position& pos, bool isDisarmed);
void addObjectScale(const MWWorld::Ptr& ptr, float scale);
void addObjectSound(const MWWorld::Ptr& ptr, std::string soundId, float volume, float pitch);
void addObjectState(const MWWorld::Ptr& ptr, bool objectState);
void addObjectAnimPlay(const MWWorld::Ptr& ptr, std::string group, int mode);
@ -79,6 +81,7 @@ namespace mwmp
void sendObjectRestock();
void sendObjectTrap();
void sendObjectScale();
void sendObjectSound();
void sendObjectState();
void sendObjectAnimPlay();
void sendDoorState();

@ -17,7 +17,7 @@ namespace mwmp
{
BaseObjectProcessor::Do(packet, objectList);
//objectList.setObjectSounds(ptrCellStore);
objectList.playObjectSounds(ptrCellStore);
}
};

@ -1,5 +1,17 @@
#include "action.hpp"
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
#include "../mwmp/Main.hpp"
#include "../mwmp/Networking.hpp"
#include "../mwmp/ObjectList.hpp"
/*
End of tes3mp addition
*/
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -37,21 +49,69 @@ void MWWorld::Action::execute (const Ptr& actor, bool noSound)
}
if(mKeepSound && actor == MWMechanics::getPlayer())
{
MWBase::Environment::get().getSoundManager()->playSound(mSoundId, 1.0, 1.0,
MWSound::Type::Sfx, envType, mSoundOffset
);
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time an actor makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(actor, mSoundId, 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
else
{
bool local = mTarget.isEmpty() || !mTarget.isInCell(); // no usable target
if(mKeepSound)
{
MWBase::Environment::get().getSoundManager()->playSound3D(
(local ? actor : mTarget).getRefData().getPosition().asVec3(),
mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset
);
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time an actor makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(local ? actor : mTarget, mSoundId, 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
else
{
MWBase::Environment::get().getSoundManager()->playSound3D(local ? actor : mTarget,
mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset
);
/*
Start of tes3mp addition
Send an ID_OBJECT_SOUND packet every time an actor makes a sound here
*/
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectSound(local ? actor : mTarget, mSoundId, 1.0, 1.0);
objectList->sendObjectSound();
/*
End of tes3mp addition
*/
}
}
}

@ -41,6 +41,10 @@ namespace mwmp
int lockLevel;
float scale;
std::string soundId;
float volume;
float pitch;
int doorState;
bool teleportState;
ESM::Cell destinationCell;

@ -9,8 +9,29 @@ PacketObjectSound::PacketObjectSound(RakNet::RakPeerInterface *peer) : ObjectPac
hasCellData = true;
}
void PacketObjectSound::Object(BaseObject &baseObject, bool send)
void PacketObjectSound::Packet(RakNet::BitStream *newBitstream, bool send)
{
ObjectPacket::Object(baseObject, send);
// Placeholder
if (!PacketHeader(newBitstream, send))
return;
BaseObject baseObject;
for (unsigned int i = 0; i < objectList->baseObjectCount; i++)
{
if (send)
baseObject = objectList->baseObjects.at(i);
RW(baseObject.isPlayer, send);
if (baseObject.isPlayer)
RW(baseObject.guid, send);
else
Object(baseObject, send);
RW(baseObject.soundId, send, true);
RW(baseObject.volume, send);
RW(baseObject.pitch, send);
if (!send)
objectList->baseObjects.push_back(baseObject);
}
}

@ -10,7 +10,7 @@ namespace mwmp
public:
PacketObjectSound(RakNet::RakPeerInterface *peer);
virtual void Object(BaseObject &baseObject, bool send);
virtual void Packet(RakNet::BitStream *newBitstream, bool send);
};
}

Loading…
Cancel
Save