1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 18:19:55 +00:00

[General] Implement ObjectDialogueChoice packet

This commit is contained in:
David Cernat 2020-10-26 19:48:40 +02:00
parent a6e825bbeb
commit 9dcb0f4c32
22 changed files with 307 additions and 17 deletions

View file

@ -117,14 +117,15 @@ set(PROCESSORS_OBJECT
processors/object/ProcessorConsoleCommand.hpp processors/object/ProcessorContainer.hpp
processors/object/ProcessorDoorState.hpp processors/object/ProcessorMusicPlay.hpp
processors/object/ProcessorObjectActivate.hpp processors/object/ProcessorObjectAnimPlay.hpp
processors/object/ProcessorObjectDelete.hpp processors/object/ProcessorObjectHit.hpp
processors/object/ProcessorObjectLock.hpp processors/object/ProcessorObjectMiscellaneous.hpp
processors/object/ProcessorObjectMove.hpp processors/object/ProcessorObjectPlace.hpp
processors/object/ProcessorObjectRestock.hpp processors/object/ProcessorObjectRotate.hpp
processors/object/ProcessorObjectScale.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/ProcessorVideoPlay.hpp
processors/object/ProcessorObjectDelete.hpp processors/object/ProcessorObjectDialogueChoice.hpp
processors/object/ProcessorObjectHit.hpp processors/object/ProcessorObjectLock.hpp
processors/object/ProcessorObjectMiscellaneous.hpp processors/object/ProcessorObjectMove.hpp
processors/object/ProcessorObjectPlace.hpp processors/object/ProcessorObjectRestock.hpp
processors/object/ProcessorObjectRotate.hpp processors/object/ProcessorObjectScale.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/ProcessorVideoPlay.hpp
)
source_group(tes3mp-server\\processors\\object FILES ${PROCESSORS_OBJECT})

View file

@ -747,6 +747,17 @@ void ObjectFunctions::SendObjectLock(bool sendToOtherPlayers, bool skipAttachedP
packet->Send(true);
}
void ObjectFunctions::SendObjectDialogueChoice(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
{
mwmp::ObjectPacket* packet = mwmp::Networking::get().getObjectPacketController()->GetPacket(ID_OBJECT_DIALOGUE_CHOICE);
packet->setObjectList(&writeObjectList);
if (!skipAttachedPlayer)
packet->Send(false);
if (sendToOtherPlayers)
packet->Send(true);
}
void ObjectFunctions::SendObjectMiscellaneous(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
{
mwmp::ObjectPacket* packet = mwmp::Networking::get().getObjectPacketController()->GetPacket(ID_OBJECT_MISCELLANEOUS);

View file

@ -150,6 +150,7 @@
{"SendObjectSpawn", ObjectFunctions::SendObjectSpawn},\
{"SendObjectDelete", ObjectFunctions::SendObjectDelete},\
{"SendObjectLock", ObjectFunctions::SendObjectLock},\
{"SendObjectDialogueChoice", ObjectFunctions::SendObjectDialogueChoice},\
{"SendObjectMiscellaneous", ObjectFunctions::SendObjectMiscellaneous},\
{"SendObjectRestock", ObjectFunctions::SendObjectRestock},\
{"SendObjectTrap", ObjectFunctions::SendObjectTrap},\
@ -1332,6 +1333,16 @@ public:
* \return void
*/
static void SendObjectLock(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
/**
* \brief Send an ObjectDialogueChoice 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 SendObjectDialogueChoice(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
/**
* \brief Send an ObjectMiscellaneous packet.

View file

@ -196,6 +196,7 @@ public:
{"OnObjectSpawn", Callback<unsigned short, const char*>()},
{"OnObjectDelete", Callback<unsigned short, const char*>()},
{"OnObjectLock", Callback<unsigned short, const char*>()},
{"OnObjectDialogueChoice", Callback<unsigned short, const char*>()},
{"OnObjectMiscellaneous", Callback<unsigned short, const char*>()},
{"OnObjectRestock", Callback<unsigned short, const char*>()},
{"OnObjectScale", Callback<unsigned short, const char*>()},

View file

@ -62,6 +62,7 @@
#include "object/ProcessorObjectActivate.hpp"
#include "object/ProcessorObjectAnimPlay.hpp"
#include "object/ProcessorObjectDelete.hpp"
#include "object/ProcessorObjectDialogueChoice.hpp"
#include "object/ProcessorObjectHit.hpp"
#include "object/ProcessorObjectPlace.hpp"
#include "object/ProcessorObjectLock.hpp"
@ -146,6 +147,7 @@ void ProcessorInitializer()
ObjectProcessor::AddProcessor(new ProcessorObjectActivate());
ObjectProcessor::AddProcessor(new ProcessorObjectAnimPlay());
ObjectProcessor::AddProcessor(new ProcessorObjectDelete());
ObjectProcessor::AddProcessor(new ProcessorObjectDialogueChoice());
ObjectProcessor::AddProcessor(new ProcessorObjectHit());
ObjectProcessor::AddProcessor(new ProcessorObjectLock());
ObjectProcessor::AddProcessor(new ProcessorObjectMiscellaneous());

View file

@ -0,0 +1,26 @@
#ifndef OPENMW_PROCESSOROBJECTDIALOGUECHOICE_HPP
#define OPENMW_PROCESSOROBJECTDIALOGUECHOICE_HPP
#include "../ObjectProcessor.hpp"
#include <apps/openmw-mp/Networking.hpp>
namespace mwmp
{
class ProcessorObjectDialogueChoice : public ObjectProcessor
{
public:
ProcessorObjectDialogueChoice()
{
BPP_INIT(ID_OBJECT_DIALOGUE_CHOICE)
}
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("OnObjectDialogueChoice")>(player.getId(), objectList.cell.getDescription().c_str());
}
};
}
#endif //OPENMW_PROCESSOROBJECTDIALOGUECHOICE_HPP

View file

@ -134,10 +134,11 @@ add_openmw_dir (mwmp/processors/object BaseObjectProcessor
ProcessorConsoleCommand ProcessorContainer ProcessorDoorDestination ProcessorDoorState ProcessorMusicPlay
ProcessorVideoPlay
ProcessorObjectActivate ProcessorObjectAnimPlay ProcessorObjectAttach ProcessorObjectDelete ProcessorObjectHit
ProcessorObjectLock ProcessorObjectMove ProcessorObjectPlace ProcessorObjectRestock ProcessorObjectRotate
ProcessorObjectScale ProcessorObjectSound ProcessorObjectSpawn ProcessorObjectState ProcessorObjectTrap
ProcessorClientScriptLocal ProcessorScriptMemberShort ProcessorObjectMiscellaneous
ProcessorObjectActivate ProcessorObjectAnimPlay ProcessorObjectAttach ProcessorObjectDelete
ProcessorObjectDialogueChoice ProcessorObjectHit ProcessorObjectLock ProcessorObjectMove ProcessorObjectPlace
ProcessorObjectRestock ProcessorObjectRotate ProcessorObjectScale ProcessorObjectSound ProcessorObjectSpawn
ProcessorObjectState ProcessorObjectTrap ProcessorClientScriptLocal ProcessorScriptMemberShort
ProcessorObjectMiscellaneous
)
add_openmw_dir (mwmp/processors/worldstate ProcessorCellReset ProcessorClientScriptGlobal ProcessorClientScriptSettings

View file

@ -158,6 +158,16 @@ namespace MWBase
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to get the DialogueWindow from elsewhere
*/
virtual MWGui::DialogueWindow* getDialogueWindow() = 0;
/*
End of tes3mp addition
*/
/// Make the player use an item, while updating GUI state accordingly
virtual void useItem(const MWWorld::Ptr& item, bool force=false) = 0;

View file

@ -18,6 +18,7 @@
#include "../mwmp/Main.hpp"
#include "../mwmp/Networking.hpp"
#include "../mwmp/ObjectList.hpp"
#include <components/openmw-mp/TimedLog.hpp>
/*
End of tes3mp addition
*/
@ -295,7 +296,16 @@ namespace MWGui
//Topics list
getWidget(mTopicsList, "TopicsList");
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectListItem);
/*
Start of tes3mp change (major)
Instead of running DialogueWindow::onSelectListItem() when clicking a list item, run
onSendDialoguePacket() so the server can approve or deny a dialogue choice
*/
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSendDialoguePacket);
/*
End of tes3mp change (major)
*/
getWidget(mGoodbyeButton, "ByeButton");
mGoodbyeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
@ -372,6 +382,25 @@ namespace MWGui
}
}
/*
Start of tes3mp addition
A different event that should be used in multiplayer when clicking on list items
in the dialogue screen, sending DialogueChoice packets to the server so they can
be approved or denied
*/
void DialogueWindow::onSendDialoguePacket(const std::string& topic, int id)
{
mwmp::ObjectList* objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
objectList->addObjectDialogueChoice(mPtr, topic, id);
objectList->sendObjectDialogueChoice();
}
/*
End of tes3mp addition
*/
void DialogueWindow::onSelectListItem(const std::string& topic, int id)
{
if (mGoodbye || MWBase::Environment::get().getDialogueManager()->isInChoice())
@ -422,6 +451,19 @@ namespace MWGui
updateTopics();
}
/*
Start of tes3mp addition
Make it possible to get the Ptr of the actor involved in the dialogue
*/
MWWorld::Ptr DialogueWindow::getPtr()
{
return mPtr;
}
/*
End of tes3mp addition
*/
void DialogueWindow::setPtr(const MWWorld::Ptr& actor)
{
if (!actor.getClass().isActor())

View file

@ -120,6 +120,16 @@ namespace MWGui
void notifyLinkClicked (TypesetBook::InteractiveId link);
/*
Start of tes3mp addition
Make it possible to get the Ptr of the actor involved in the dialogue
*/
MWWorld::Ptr getPtr();
/*
End of tes3mp addition
*/
void setPtr(const MWWorld::Ptr& actor);
void setKeywords(std::list<std::string> keyWord);
@ -140,7 +150,30 @@ namespace MWGui
bool isCompanion(const MWWorld::Ptr& actor);
bool isCompanion();
/*
Start of tes3mp addition
A different event that should be used in multiplayer when clicking on list items
in the dialogue screen, sending DialogueChoice packets to the server so they can
be approved or denied
*/
void onSendDialoguePacket(const std::string& topic, int id);
/*
End of tes3mp addition
*/
/*
Start of tes3mp change (major)
Turn onSelectListItem() into a public function so it can be used elsewhere when
receiving ObjectDialogueChoice packets
*/
public:
void onSelectListItem(const std::string& topic, int id);
protected:
/*
End of tes3mp change (major)
*/
void onByeClicked(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void onWindowResize(MyGUI::Window* _sender);

View file

@ -1447,6 +1447,16 @@ namespace MWGui
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to get the DialogueWindow from elsewhere
*/
MWGui::DialogueWindow* WindowManager::getDialogueWindow() { return mDialogueWindow; }
/*
End of tes3mp addition
*/
void WindowManager::useItem(const MWWorld::Ptr &item, bool bypassBeastRestrictions)
{
if (mInventoryWindow)

View file

@ -198,6 +198,16 @@ namespace MWGui
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to get the DialogueWindow from elsewhere
*/
virtual MWGui::DialogueWindow* getDialogueWindow();
/*
End of tes3mp addition
*/
/// Make the player use an item, while updating GUI state accordingly
virtual void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions=false);

View file

@ -18,6 +18,7 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwgui/container.hpp"
#include "../mwgui/dialogue.hpp"
#include "../mwgui/inventorywindow.hpp"
#include "../mwgui/windowmanagerimp.hpp"
@ -978,6 +979,46 @@ void ObjectList::runConsoleCommands(MWWorld::CellStore* cellStore)
}
}
void ObjectList::makeDialogueChoices(MWWorld::CellStore* cellStore)
{
for (const auto& baseObject : baseObjects)
{
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
if (ptrFound)
{
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Found %s %i-%i", ptrFound.getCellRef().getRefId().c_str(),
ptrFound.getCellRef().getRefNum(), ptrFound.getCellRef().getMpNum());
if (ptrFound.getClass().isActor())
{
// Ensure the dialogue window has the correct Ptr set for it
if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Dialogue))
{
if (MWBase::Environment::get().getWindowManager()->getDialogueWindow()->getPtr() != ptrFound)
{
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->setPtr(ptrFound);
}
}
else
{
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue, ptrFound);
}
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Making dialogue choice of %s", baseObject.dialogueChoice);
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->onSelectListItem(baseObject.dialogueChoice, baseObject.guiId);
}
else
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_WARN, "Failed to make dialogue choice for %s %i-%i because it is not an actor!",
ptrFound.getCellRef().getRefId().c_str(), ptrFound.getCellRef().getRefNum(), ptrFound.getCellRef().getMpNum());
}
}
}
}
void ObjectList::setClientLocals(MWWorld::CellStore* cellStore)
{
for (const auto &baseObject : baseObjects)
@ -1226,6 +1267,16 @@ void ObjectList::addObjectLock(const MWWorld::Ptr& ptr, int lockLevel)
addBaseObject(baseObject);
}
void ObjectList::addObjectDialogueChoice(const MWWorld::Ptr& ptr, std::string dialogueChoice, int guiId)
{
cell = *ptr.getCell()->getCell();
mwmp::BaseObject baseObject = getBaseObjectFromPtr(ptr);
baseObject.dialogueChoice = dialogueChoice;
baseObject.guiId = guiId;
addBaseObject(baseObject);
}
void ObjectList::addObjectMiscellaneous(const MWWorld::Ptr& ptr, unsigned int goldPool, float lastGoldRestockHour, int lastGoldRestockDay)
{
cell = *ptr.getCell()->getCell();
@ -1399,6 +1450,12 @@ void ObjectList::sendObjectLock()
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_LOCK)->Send();
}
void ObjectList::sendObjectDialogueChoice()
{
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_DIALOGUE_CHOICE)->setObjectList(this);
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_DIALOGUE_CHOICE)->Send();
}
void ObjectList::sendObjectMiscellaneous()
{
mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_MISCELLANEOUS)->setObjectList(this);

View file

@ -42,6 +42,7 @@ namespace mwmp
void activateDoors(MWWorld::CellStore* cellStore);
void setDoorDestinations(MWWorld::CellStore* cellStore);
void runConsoleCommands(MWWorld::CellStore* cellStore);
void makeDialogueChoices(MWWorld::CellStore* cellStore);
void setClientLocals(MWWorld::CellStore* cellStore);
void setMemberShorts();
@ -60,6 +61,7 @@ namespace mwmp
void addObjectSpawn(const MWWorld::Ptr& ptr);
void addObjectSpawn(const MWWorld::Ptr& ptr, const MWWorld::Ptr& master, std::string spellId, int effectId, float duration);
void addObjectLock(const MWWorld::Ptr& ptr, int lockLevel);
void addObjectDialogueChoice(const MWWorld::Ptr& ptr, std::string dialogueChoice, int guiId);
void addObjectMiscellaneous(const MWWorld::Ptr& ptr, unsigned int goldPool, float lastGoldRestockHour, int lastGoldRestockDay);
void addObjectTrap(const MWWorld::Ptr& ptr, const ESM::Position& pos, bool isDisarmed);
void addObjectScale(const MWWorld::Ptr& ptr, float scale);
@ -80,6 +82,7 @@ namespace mwmp
void sendObjectSpawn();
void sendObjectDelete();
void sendObjectLock();
void sendObjectDialogueChoice();
void sendObjectMiscellaneous();
void sendObjectRestock();
void sendObjectTrap();

View file

@ -57,6 +57,7 @@
#include "object/ProcessorObjectAnimPlay.hpp"
#include "object/ProcessorObjectAttach.hpp"
#include "object/ProcessorObjectDelete.hpp"
#include "object/ProcessorObjectDialogueChoice.hpp"
#include "object/ProcessorObjectHit.hpp"
#include "object/ProcessorObjectLock.hpp"
#include "object/ProcessorObjectMiscellaneous.hpp"
@ -160,6 +161,7 @@ void ProcessorInitializer()
ObjectProcessor::AddProcessor(new ProcessorObjectAnimPlay());
ObjectProcessor::AddProcessor(new ProcessorObjectAttach());
ObjectProcessor::AddProcessor(new ProcessorObjectDelete());
ObjectProcessor::AddProcessor(new ProcessorObjectDialogueChoice());
ObjectProcessor::AddProcessor(new ProcessorObjectHit());
ObjectProcessor::AddProcessor(new ProcessorObjectLock());
ObjectProcessor::AddProcessor(new ProcessorObjectMiscellaneous());

View file

@ -0,0 +1,30 @@
#ifndef OPENMW_PROCESSOROBJECTDIALOGUECHOICE_HPP
#define OPENMW_PROCESSOROBJECTDIALOGUECHOICE_HPP
#include "BaseObjectProcessor.hpp"
namespace mwmp
{
class ProcessorObjectDialogueChoice final: public BaseObjectProcessor
{
public:
ProcessorObjectDialogueChoice()
{
BPP_INIT(ID_OBJECT_DIALOGUE_CHOICE)
}
virtual void Do(ObjectPacket &packet, ObjectList &objectList)
{
BaseObjectProcessor::Do(packet, objectList);
ptrCellStore = Main::get().getCellController()->getCellStore(objectList.cell);
if (!ptrCellStore) return;
objectList.makeDialogueChoices(ptrCellStore);
}
};
}
#endif //OPENMW_PROCESSOROBJECTDIALOGUECHOICE_HPP

View file

@ -205,9 +205,10 @@ add_component_dir (openmw-mp/Packets/Object
PacketDoorDestination PacketDoorState
PacketConsoleCommand PacketContainer PacketObjectActivate PacketObjectAnimPlay PacketObjectAttach
PacketObjectDelete PacketObjectHit PacketObjectLock PacketObjectMove PacketObjectPlace PacketObjectRestock
PacketObjectRotate PacketObjectScale PacketObjectSound PacketObjectSpawn PacketObjectState PacketObjectTrap
PacketMusicPlay PacketVideoPlay PacketClientScriptLocal PacketScriptMemberShort PacketObjectMiscellaneous
PacketObjectDelete PacketObjectDialogueChoice PacketObjectHit PacketObjectLock PacketObjectMove PacketObjectPlace
PacketObjectRestock PacketObjectRotate PacketObjectScale PacketObjectSound PacketObjectSpawn PacketObjectState
PacketObjectTrap PacketMusicPlay PacketVideoPlay PacketClientScriptLocal PacketScriptMemberShort
PacketObjectMiscellaneous
)
add_component_dir (openmw-mp/Packets/Worldstate

View file

@ -41,6 +41,9 @@ namespace mwmp
int lockLevel;
float scale;
std::string dialogueChoice;
int guiId;
std::string soundId;
float volume;
float pitch;

View file

@ -2,6 +2,7 @@
#include "../Packets/Object/PacketObjectAnimPlay.hpp"
#include "../Packets/Object/PacketObjectAttach.hpp"
#include "../Packets/Object/PacketObjectDelete.hpp"
#include "../Packets/Object/PacketObjectDialogueChoice.hpp"
#include "../Packets/Object/PacketObjectHit.hpp"
#include "../Packets/Object/PacketObjectLock.hpp"
#include "../Packets/Object/PacketObjectMiscellaneous.hpp"
@ -41,6 +42,7 @@ mwmp::ObjectPacketController::ObjectPacketController(RakNet::RakPeerInterface *p
AddPacket<PacketObjectAnimPlay>(&packets, peer);
AddPacket<PacketObjectAttach>(&packets, peer);
AddPacket<PacketObjectDelete>(&packets, peer);
AddPacket<PacketObjectDialogueChoice>(&packets, peer);
AddPacket<PacketObjectHit>(&packets, peer);
AddPacket<PacketObjectLock>(&packets, peer);
AddPacket<PacketObjectMiscellaneous>(&packets, peer);

View file

@ -90,7 +90,7 @@ enum GameMessages
ID_VIDEO_PLAY,
ID_CLIENT_SCRIPT_LOCAL,
ID_SCRIPT_LOCAL_FLOAT,
ID_OBJECT_DIALOGUE_CHOICE,
ID_SCRIPT_MEMBER_SHORT,
ID_OBJECT_MISCELLANEOUS,
ID_CLIENT_SCRIPT_GLOBAL,

View file

@ -0,0 +1,17 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include "PacketObjectDialogueChoice.hpp"
using namespace mwmp;
PacketObjectDialogueChoice::PacketObjectDialogueChoice(RakNet::RakPeerInterface *peer) : ObjectPacket(peer)
{
packetID = ID_OBJECT_DIALOGUE_CHOICE;
hasCellData = true;
}
void PacketObjectDialogueChoice::Object(BaseObject& baseObject, bool send)
{
ObjectPacket::Object(baseObject, send);
RW(baseObject.dialogueChoice, send, true);
RW(baseObject.guiId, send);
}

View file

@ -0,0 +1,17 @@
#ifndef OPENMW_PACKETOBJECTDIALOGUECHOICE_HPP
#define OPENMW_PACKETOBJECTDIALOGUECHOICE_HPP
#include <components/openmw-mp/Packets/Object/ObjectPacket.hpp>
namespace mwmp
{
class PacketObjectDialogueChoice : public ObjectPacket
{
public:
PacketObjectDialogueChoice(RakNet::RakPeerInterface *peer);
virtual void Object(BaseObject& baseObject, bool send);
};
}
#endif //OPENMW_PACKETOBJECTDIALOGUECHOICE_HPP