1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-20 19:39:41 +00:00

[General] Implement WorldDestinationOverride packet, part 1

Destinations for doors with cell transitions are now overridden.
This commit is contained in:
David Cernat 2019-12-04 16:43:56 +02:00
parent 9cb9d4b7ca
commit ecf00af548
12 changed files with 201 additions and 5 deletions

View file

@ -197,6 +197,11 @@ void WorldstateFunctions::AddEnforcedCollisionRefId(const char *refId) noexcept
writeWorldstate.enforcedCollisionRefIds.push_back(refId);
}
void WorldstateFunctions::AddDestinationOverride(const char *oldCellDescription, const char *newCellDescription) noexcept
{
writeWorldstate.destinationOverrides[oldCellDescription] = newCellDescription;
}
void WorldstateFunctions::ClearSynchronizedClientScriptIds() noexcept
{
writeWorldstate.synchronizedClientScriptIds.clear();
@ -212,6 +217,11 @@ void WorldstateFunctions::ClearEnforcedCollisionRefIds() noexcept
writeWorldstate.enforcedCollisionRefIds.clear();
}
void WorldstateFunctions::ClearDestinationOverrides() noexcept
{
writeWorldstate.destinationOverrides.clear();
}
void WorldstateFunctions::SaveMapTileImageFile(unsigned int index, const char *filePath) noexcept
{
if (index >= readWorldstate->mapTiles.size())
@ -342,6 +352,22 @@ void WorldstateFunctions::SendWorldCollisionOverride(unsigned short pid, bool se
packet->Send(true);
}
void WorldstateFunctions::SendWorldDestinationOverride(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
writeWorldstate.guid = player->guid;
mwmp::WorldstatePacket *packet = mwmp::Networking::get().getWorldstatePacketController()->GetPacket(ID_WORLD_DESTINATION_OVERRIDE);
packet->setWorldstate(&writeWorldstate);
if (!skipAttachedPlayer)
packet->Send(false);
if (sendToOtherPlayers)
packet->Send(true);
}
void WorldstateFunctions::SendWorldRegionAuthority(unsigned short pid) noexcept
{
Player *player;

View file

@ -52,10 +52,12 @@
{"AddSynchronizedClientScriptId", WorldstateFunctions::AddSynchronizedClientScriptId},\
{"AddSynchronizedClientGlobalId", WorldstateFunctions::AddSynchronizedClientGlobalId},\
{"AddEnforcedCollisionRefId", WorldstateFunctions::AddEnforcedCollisionRefId},\
{"AddDestinationOverride", WorldstateFunctions::AddDestinationOverride},\
\
{"ClearSynchronizedClientScriptIds", WorldstateFunctions::ClearSynchronizedClientScriptIds},\
{"ClearSynchronizedClientGlobalIds", WorldstateFunctions::ClearSynchronizedClientGlobalIds},\
{"ClearEnforcedCollisionRefIds", WorldstateFunctions::ClearEnforcedCollisionRefIds},\
{"ClearDestinationOverrides", WorldstateFunctions::ClearDestinationOverrides},\
\
{"SaveMapTileImageFile", WorldstateFunctions::SaveMapTileImageFile},\
{"LoadMapTileImageFile", WorldstateFunctions::LoadMapTileImageFile},\
@ -66,6 +68,7 @@
{"SendWorldTime", WorldstateFunctions::SendWorldTime},\
{"SendWorldWeather", WorldstateFunctions::SendWorldWeather},\
{"SendWorldCollisionOverride", WorldstateFunctions::SendWorldCollisionOverride},\
{"SendWorldDestinationOverride", WorldstateFunctions::SendWorldDestinationOverride},\
{"SendWorldRegionAuthority", WorldstateFunctions::SendWorldRegionAuthority},\
\
{"ReadLastWorldstate", WorldstateFunctions::ReadLastWorldstate},\
@ -374,6 +377,16 @@ public:
*/
static void AddEnforcedCollisionRefId(const char* refId) noexcept;
/**
* \brief Add a destination override containing the cell description for the old cell
* and the new cell.
*
* \param oldCellDescription The old cell description.
* \param newCellDescription The new cell description.
* \return void
*/
static void AddDestinationOverride(const char* oldCellDescription, const char* newCellDescription) noexcept;
/**
* \brief Clear the list of script IDs whose variable changes should be sent to the
* the server by clients.
@ -398,6 +411,13 @@ public:
*/
static void ClearEnforcedCollisionRefIds() noexcept;
/**
* \brief Clear the list of destination overrides.
*
* \return void
*/
static void ClearDestinationOverrides() noexcept;
/**
* \brief Save the .png image data of the map tile at a certain index in the read worldstate's
* map changes.
@ -505,6 +525,19 @@ public:
*/
static void SendWorldCollisionOverride(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
/**
* \brief Send a WorldDestinationOverride packet with the current destination overrides in
* the write-only worldstate.
*
* \param pid The player ID attached to the 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 SendWorldDestinationOverride(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
// All methods below are deprecated versions of methods from above

View file

@ -138,8 +138,8 @@ add_openmw_dir (mwmp/processors/object BaseObjectProcessor
)
add_openmw_dir (mwmp/processors/worldstate ProcessorCellReset ProcessorClientScriptSettings ProcessorRecordDynamic
ProcessorWorldCollisionOverride ProcessorWorldKillCount ProcessorWorldMap ProcessorWorldRegionAuthority ProcessorWorldTime
ProcessorWorldWeather
ProcessorWorldCollisionOverride ProcessorWorldDestinationOverride ProcessorWorldKillCount ProcessorWorldMap
ProcessorWorldRegionAuthority ProcessorWorldTime ProcessorWorldWeather
)
# Main executable

View file

@ -257,7 +257,22 @@ namespace MWClass
}
else
{
std::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest(), true));
/*
Start of tes3mp change (major)
If there is a destination override in the mwmp::Worldstate for this door's original
destination, use it
*/
std::string destinationCell = ptr.getCellRef().getDestCell();
if (mwmp::Main::get().getNetworking()->getWorldstate()->destinationOverrides.count(destinationCell) != 0)
destinationCell = mwmp::Main::get().getNetworking()->getWorldstate()->destinationOverrides[destinationCell];
std::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport(destinationCell, ptr.getCellRef().getDoorDest(), true));
/*
End of tes3mp change (major)
*/
action->setSound(openSound);
return action;
}
@ -374,6 +389,18 @@ namespace MWClass
{
// door leads to an interior, use interior name as tooltip
dest = door.mRef.getDestCell();
/*
Start of tes3mp change (major)
If there is a destination override in the mwmp::Worldstate for this door's original
destination, use it
*/
if (mwmp::Main::get().getNetworking()->getWorldstate()->destinationOverrides.count(dest) != 0)
dest = mwmp::Main::get().getNetworking()->getWorldstate()->destinationOverrides[dest];
/*
End of tes3mp change (major)
*/
}
else
{

View file

@ -95,6 +95,7 @@
#include "worldstate/ProcessorClientScriptSettings.hpp"
#include "worldstate/ProcessorRecordDynamic.hpp"
#include "worldstate/ProcessorWorldCollisionOverride.hpp"
#include "worldstate/ProcessorWorldDestinationOverride.hpp"
#include "worldstate/ProcessorWorldKillCount.hpp"
#include "worldstate/ProcessorWorldMap.hpp"
#include "worldstate/ProcessorWorldRegionAuthority.hpp"
@ -191,11 +192,12 @@ void ProcessorInitializer()
ActorProcessor::AddProcessor(new ProcessorActorStatsDynamic());
ActorProcessor::AddProcessor(new ProcessorActorTest());
WorldstateProcessor::AddProcessor(new ProcessorWorldKillCount());
WorldstateProcessor::AddProcessor(new ProcessorCellReset());
WorldstateProcessor::AddProcessor(new ProcessorClientScriptSettings());
WorldstateProcessor::AddProcessor(new ProcessorRecordDynamic());
WorldstateProcessor::AddProcessor(new ProcessorWorldCollisionOverride());
WorldstateProcessor::AddProcessor(new ProcessorWorldDestinationOverride());
WorldstateProcessor::AddProcessor(new ProcessorWorldKillCount());
WorldstateProcessor::AddProcessor(new ProcessorWorldMap());
WorldstateProcessor::AddProcessor(new ProcessorWorldRegionAuthority());
WorldstateProcessor::AddProcessor(new ProcessorWorldTime());

View file

@ -0,0 +1,33 @@
#ifndef OPENMW_PROCESSORWORLDDESTINATIONOVERRIDE_HPP
#define OPENMW_PROCESSORWORLDDESTINATIONOVERRIDE_HPP
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include "../WorldstateProcessor.hpp"
namespace mwmp
{
class ProcessorWorldDestinationOverride final: public WorldstateProcessor
{
public:
ProcessorWorldDestinationOverride()
{
BPP_INIT(ID_WORLD_DESTINATION_OVERRIDE)
}
virtual void Do(WorldstatePacket &packet, Worldstate &worldstate)
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_WORLD_DESTINATION_OVERRIDE with the following overrides:");
for (auto iterator : worldstate.destinationOverrides)
{
LOG_APPEND(TimedLog::LOG_INFO, "- %s now leads to %s", iterator.first.c_str(), iterator.second.c_str());
}
}
};
}
#endif //OPENMW_PROCESSORWORLDDESTINATIONOVERRIDE_HPP

View file

@ -217,7 +217,8 @@ add_component_dir (openmw-mp/Packets/Worldstate
WorldstatePacket
PacketCellCreate PacketCellReset PacketClientScriptSettings PacketRecordDynamic PacketWorldCollisionOverride
PacketWorldKillCount PacketWorldMap PacketWorldRegionAuthority PacketWorldTime PacketWorldWeather
PacketWorldDestinationOverride PacketWorldKillCount PacketWorldMap PacketWorldRegionAuthority PacketWorldTime
PacketWorldWeather
)
add_component_dir (fallback

View file

@ -1,6 +1,7 @@
#ifndef OPENMW_BASEWORLDSTATE_HPP
#define OPENMW_BASEWORLDSTATE_HPP
#include <map>
#include <vector>
#include <components/esm/loadacti.hpp>
@ -359,6 +360,7 @@ namespace mwmp
std::vector<Kill> killChanges;
std::vector<std::string> enforcedCollisionRefIds;
std::map<std::string, std::string> destinationOverrides;
std::vector<MapTile> mapTiles;

View file

@ -2,6 +2,7 @@
#include "../Packets/Worldstate/PacketClientScriptSettings.hpp"
#include "../Packets/Worldstate/PacketRecordDynamic.hpp"
#include "../Packets/Worldstate/PacketWorldCollisionOverride.hpp"
#include "../Packets/Worldstate/PacketWorldDestinationOverride.hpp"
#include "../Packets/Worldstate/PacketWorldKillCount.hpp"
#include "../Packets/Worldstate/PacketWorldMap.hpp"
#include "../Packets/Worldstate/PacketWorldRegionAuthority.hpp"
@ -24,6 +25,7 @@ mwmp::WorldstatePacketController::WorldstatePacketController(RakNet::RakPeerInte
AddPacket<PacketClientScriptSettings>(&packets, peer);
AddPacket<PacketRecordDynamic>(&packets, peer);
AddPacket<PacketWorldCollisionOverride>(&packets, peer);
AddPacket<PacketWorldDestinationOverride>(&packets, peer);
AddPacket<PacketWorldKillCount>(&packets, peer);
AddPacket<PacketWorldMap>(&packets, peer);
AddPacket<PacketWorldRegionAuthority>(&packets, peer);

View file

@ -110,6 +110,7 @@ enum GameMessages
ID_PLAYER_ITEM_USE,
ID_PLAYER_CAST,
ID_PLAYER_TEAM,
ID_WORLD_DESTINATION_OVERRIDE,
ID_PLACEHOLDER
};

View file

@ -0,0 +1,52 @@
#include "PacketWorldDestinationOverride.hpp"
#include <components/openmw-mp/NetworkMessages.hpp>
#include <components/openmw-mp/TimedLog.hpp>
using namespace mwmp;
PacketWorldDestinationOverride::PacketWorldDestinationOverride(RakNet::RakPeerInterface *peer) : WorldstatePacket(peer)
{
packetID = ID_WORLD_DESTINATION_OVERRIDE;
orderChannel = CHANNEL_WORLDSTATE;
}
void PacketWorldDestinationOverride::Packet(RakNet::BitStream *newBitstream, bool send)
{
WorldstatePacket::Packet(newBitstream, send);
uint32_t destinationCount;
if (send)
destinationCount = static_cast<uint32_t>(worldstate->destinationOverrides.size());
RW(destinationCount, send);
if (!send)
{
worldstate->destinationOverrides.clear();
}
std::string mapIndex;
std::string mapValue;
if (send)
{
for (auto &&destinationOverride : worldstate->destinationOverrides)
{
mapIndex = destinationOverride.first;
mapValue = destinationOverride.second;
RW(mapIndex, send, false);
RW(mapValue, send, false);
}
}
else
{
for (unsigned int n = 0; n < destinationCount; n++)
{
RW(mapIndex, send, false);
RW(mapValue, send, false);
worldstate->destinationOverrides[mapIndex] = mapValue;
}
}
}

View file

@ -0,0 +1,17 @@
#ifndef OPENMW_PACKETWORLDDESTINATIONOVERRIDE_HPP
#define OPENMW_PACKETWORLDDESTINATIONOVERRIDE_HPP
#include <components/openmw-mp/Packets/Worldstate/WorldstatePacket.hpp>
namespace mwmp
{
class PacketWorldDestinationOverride : public WorldstatePacket
{
public:
PacketWorldDestinationOverride(RakNet::RakPeerInterface *peer);
virtual void Packet(RakNet::BitStream *newBitstream, bool send);
};
}
#endif //OPENMW_PACKETWORLDDESTINATIONOVERRIDE_HPP