diff --git a/apps/openmw-mp/Script/Functions/Mechanics.cpp b/apps/openmw-mp/Script/Functions/Mechanics.cpp index bf499045a..127efe473 100644 --- a/apps/openmw-mp/Script/Functions/Mechanics.cpp +++ b/apps/openmw-mp/Script/Functions/Mechanics.cpp @@ -9,6 +9,65 @@ #include using namespace std; +static std::string tempCellDescription; + +unsigned char MechanicsFunctions::GetMiscellaneousChangeType(unsigned short pid) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0); + + return player->miscellaneousChangeType; +} + +const char *MechanicsFunctions::GetMarkCell(unsigned short pid) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0); + + tempCellDescription = player->cell.getDescription().c_str(); + return tempCellDescription.c_str(); +} + +double MechanicsFunctions::GetMarkPosX(unsigned short pid) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0.0f); + + return player->markPosition.pos[0]; +} + +double MechanicsFunctions::GetMarkPosY(unsigned short pid) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0.0f); + + return player->markPosition.pos[1]; +} + +double MechanicsFunctions::GetMarkPosZ(unsigned short pid) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0.0f); + + return player->markPosition.pos[2]; +} + +double MechanicsFunctions::GetMarkRotX(unsigned short pid) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0.0f); + + return player->markPosition.rot[0]; +} + +double MechanicsFunctions::GetMarkRotZ(unsigned short pid) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0.0f); + + return player->markPosition.rot[2]; +} + bool MechanicsFunctions::IsWerewolf(unsigned short pid) noexcept { Player *player; @@ -17,6 +76,33 @@ bool MechanicsFunctions::IsWerewolf(unsigned short pid) noexcept return player->isWerewolf; } +void MechanicsFunctions::SetMarkCell(unsigned short pid, const char *cellDescription) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ); + + player->markCell = Utils::getCellFromDescription(cellDescription); +} + +void MechanicsFunctions::SetMarkPos(unsigned short pid, double x, double y, double z) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ); + + player->markPosition.pos[0] = x; + player->markPosition.pos[1] = y; + player->markPosition.pos[2] = z; +} + +void MechanicsFunctions::SetMarkRot(unsigned short pid, double x, double z) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ); + + player->markPosition.rot[0] = x; + player->markPosition.rot[2] = z; +} + void MechanicsFunctions::SetWerewolfState(unsigned short pid, bool isWerewolf) { Player *player; @@ -25,6 +111,17 @@ void MechanicsFunctions::SetWerewolfState(unsigned short pid, bool isWerewolf) player->isWerewolf = isWerewolf; } +void MechanicsFunctions::SendMarkLocation(unsigned short pid) +{ + Player *player; + GET_PLAYER(pid, player, ); + + player->miscellaneousChangeType = mwmp::MISCELLANEOUS_CHANGE_TYPE::MARK_LOCATION; + + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MISCELLANEOUS)->setPlayer(player); + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MISCELLANEOUS)->Send(false); +} + void MechanicsFunctions::SendShapeshift(unsigned short pid) { Player *player; diff --git a/apps/openmw-mp/Script/Functions/Mechanics.hpp b/apps/openmw-mp/Script/Functions/Mechanics.hpp index 308793430..d2c4f0ee0 100644 --- a/apps/openmw-mp/Script/Functions/Mechanics.hpp +++ b/apps/openmw-mp/Script/Functions/Mechanics.hpp @@ -4,19 +4,89 @@ #include "../Types.hpp" #define MECHANICSAPI \ - {"IsWerewolf", MechanicsFunctions::IsWerewolf},\ + {"GetMiscellaneousChangeType", MechanicsFunctions::GetMiscellaneousChangeType},\ \ - {"SetWerewolfState", MechanicsFunctions::SetWerewolfState},\ + {"GetMarkCell", MechanicsFunctions::GetMarkCell},\ + {"GetMarkPosX", MechanicsFunctions::GetMarkPosX},\ + {"GetMarkPosY", MechanicsFunctions::GetMarkPosY},\ + {"GetMarkPosZ", MechanicsFunctions::GetMarkPosZ},\ + {"GetMarkRotX", MechanicsFunctions::GetMarkRotX},\ + {"GetMarkRotZ", MechanicsFunctions::GetMarkRotZ},\ \ - {"SendShapeshift", MechanicsFunctions::SendShapeshift},\ + {"IsWerewolf", MechanicsFunctions::IsWerewolf},\ \ - {"Jail", MechanicsFunctions::Jail},\ - {"Resurrect", MechanicsFunctions::Resurrect} + {"SetMarkCell", MechanicsFunctions::SetMarkCell},\ + {"SetMarkPos", MechanicsFunctions::SetMarkPos},\ + {"SetMarkRot", MechanicsFunctions::SetMarkRot},\ + \ + {"SetWerewolfState", MechanicsFunctions::SetWerewolfState},\ + \ + {"SendMarkLocation", MechanicsFunctions::SendMarkLocation},\ + {"SendShapeshift", MechanicsFunctions::SendShapeshift},\ + \ + {"Jail", MechanicsFunctions::Jail},\ + {"Resurrect", MechanicsFunctions::Resurrect} class MechanicsFunctions { public: + /** + * \brief Get the type of a PlayerMiscellaneous packet. + * + * \param pid The player ID. + * \return The type. + */ + static unsigned char GetMiscellaneousChangeType(unsigned short pid) noexcept; + + /** + * \brief Get the cell description of a player's Mark cell. + * + * \param pid The player ID. + * \return The cell description. + */ + static const char *GetMarkCell(unsigned short pid) noexcept; + + /** + * \brief Get the X position of a player's Mark. + * + * \param pid The player ID. + * \return The X position. + */ + static double GetMarkPosX(unsigned short pid) noexcept; + + /** + * \brief Get the Y position of a player's Mark. + * + * \param pid The player ID. + * \return The Y position. + */ + static double GetMarkPosY(unsigned short pid) noexcept; + + /** + * \brief Get the Z position of a player's Mark. + * + * \param pid The player ID. + * \return The Z position. + */ + static double GetMarkPosZ(unsigned short pid) noexcept; + + /** + * \brief Get the X rotation of a player's Mark. + * + * \param pid The player ID. + * \return The X rotation. + */ + static double GetMarkRotX(unsigned short pid) noexcept; + + /** + * \brief Get the Z rotation of a player's Mark. + * + * \param pid The player ID. + * \return The X rotation. + */ + static double GetMarkRotZ(unsigned short pid) noexcept; + /** * \brief Check whether a player is a werewolf. * @@ -27,6 +97,48 @@ public: */ static bool IsWerewolf(unsigned short pid) noexcept; + /** + * \brief Set the Mark cell of a player. + * + * This changes the Mark cell recorded for that player in the server memory, but does not by itself + * send a packet. + * + * The cell is determined to be an exterior cell if it fits the pattern of a number followed + * by a comma followed by another number. + * + * \param pid The player ID. + * \param cellDescription The cell description. + * \return void + */ + static void SetMarkCell(unsigned short pid, const char *cellDescription) noexcept; + + /** + * \brief Set the Mark position of a player. + * + * This changes the Mark positional coordinates recorded for that player in the server memory, but + * does not by itself send a packet. + * + * \param pid The player ID. + * \param x The X position. + * \param y The Y position. + * \param z The Z position. + * \return void + */ + static void SetMarkPos(unsigned short pid, double x, double y, double z) noexcept; + + /** + * \brief Set the Mark rotation of a player. + * + * This changes the Mark positional coordinates recorded for that player in the server memory, but + * does not by itself send a packet. + * + * \param pid The player ID. + * \param x The X rotation. + * \param z The Z rotation. + * \return void + */ + static void SetMarkRot(unsigned short pid, double x, double z) noexcept; + /** * \brief Set the werewolf state of a player. * @@ -39,6 +151,14 @@ public: */ static void SetWerewolfState(unsigned short pid, bool isWerewolf); + /** + * \brief Send a PlayerMiscellaneous packet with a Mark location to a player. + * + * \param pid The player ID. + * \return void + */ + static void SendMarkLocation(unsigned short pid); + /** * \brief Send a PlayerShapeshift packet about a player. * diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 27c83249e..381a1047c 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -755,6 +755,17 @@ namespace MWMechanics { MWBase::Environment::get().getWorld()->getPlayer().markPosition( target.getCell(), target.getRefData().getPosition()); + + /* + Start of tes3mp addition + + Send a PlayerMiscellaneous packet with the player's new mark location + */ + mwmp::Main::get().getLocalPlayer()->sendMarkLocation(*target.getCell()->getCell(), target.getRefData().getPosition()); + /* + End of tes3mp addition + */ + return true; } else if (effectId == ESM::MagicEffect::Recall) diff --git a/apps/openmw/mwmp/CellController.cpp b/apps/openmw/mwmp/CellController.cpp index 83aa32bae..eb89f7b45 100644 --- a/apps/openmw/mwmp/CellController.cpp +++ b/apps/openmw/mwmp/CellController.cpp @@ -364,7 +364,6 @@ void CellController::openContainer(const MWWorld::Ptr &container) /*if (::Misc::StringUtils::ciEqual(name, "gold_001")) cont.remove("gold_001", count, container);*/ } - } void CellController::closeContainer(const MWWorld::Ptr &container) diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index a6528c8ec..781c8d7dd 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -1269,6 +1269,14 @@ void LocalPlayer::setShapeshift() MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptrPlayer, isWerewolf); } +void LocalPlayer::setMarkLocation() +{ + MWWorld::CellStore *ptrCellStore = Main::get().getCellController()->getCellStore(markCell); + + if (ptrCellStore) + MWBase::Environment::get().getWorld()->getPlayer().markPosition(ptrCellStore, markPosition); +} + void LocalPlayer::sendClass() { MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -1555,6 +1563,16 @@ void LocalPlayer::sendShapeshift(bool werewolfState) getNetworking()->getPlayerPacket(ID_PLAYER_SHAPESHIFT)->Send(); } +void LocalPlayer::sendMarkLocation(const ESM::Cell& newMarkCell, const ESM::Position& newMarkPosition) +{ + miscellaneousChangeType = mwmp::MISCELLANEOUS_CHANGE_TYPE::MARK_LOCATION; + markCell = newMarkCell; + markPosition = newMarkPosition; + + getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->setPlayer(this); + getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->Send(); +} + void LocalPlayer::clearCellStates() { cellStateChanges.cellStates.clear(); diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index 3f3da26ef..7f92de89b 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -70,15 +70,16 @@ namespace mwmp void setBooks(); void setMapExplored(); void setShapeshift(); + void setMarkLocation(); void sendClass(); void sendInventory(); void sendSpellbook(); void sendCellStates(); void sendSpellAddition(std::string id); - void sendSpellAddition(const ESM::Spell &spell); + void sendSpellAddition(const ESM::Spell& spell); void sendSpellRemoval(std::string id); - void sendSpellRemoval(const ESM::Spell &spell); + void sendSpellRemoval(const ESM::Spell& spell); void sendQuickKey(unsigned short slot, int type, const std::string& itemId = ""); void sendJournalEntry(const std::string& quest, int index, const MWWorld::Ptr& actor); void sendJournalIndex(const std::string& quest, int index); @@ -89,6 +90,7 @@ namespace mwmp void sendKill(const std::string& refId, int number); void sendBook(const std::string& bookId); void sendShapeshift(bool isWerewolf); + void sendMarkLocation(const ESM::Cell& newMarkCell, const ESM::Position& newMarkPosition); void clearCellStates(); void clearCurrentContainer(); diff --git a/apps/openmw/mwmp/processors/player/ProcessorPlayerMiscellaneous.hpp b/apps/openmw/mwmp/processors/player/ProcessorPlayerMiscellaneous.hpp index f6e06b08b..4dcc8a5be 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorPlayerMiscellaneous.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorPlayerMiscellaneous.hpp @@ -23,7 +23,9 @@ namespace mwmp if (!isRequest()) { LocalPlayer &localPlayer = static_cast(*player); - //localPlayer.setMiscellaneous(); + + if (player->miscellaneousChangeType == mwmp::MISCELLANEOUS_CHANGE_TYPE::MARK_LOCATION) + localPlayer.setMarkLocation(); } } }; diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index 480eb9351..15939ee00 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -184,6 +184,12 @@ namespace mwmp TRIBUNAL_TEMPLE }; + enum MISCELLANEOUS_CHANGE_TYPE + { + MARK_LOCATION = 0, + SELECTED_SPELL + }; + class BasePlayer { public: @@ -292,6 +298,10 @@ namespace mwmp std::string jailEndText; unsigned int resurrectType; + unsigned int miscellaneousChangeType; + + ESM::Cell markCell; + ESM::Position markPosition; bool diedSinceArrestAttempt; bool isReceivingQuickKeys; diff --git a/components/openmw-mp/Packets/Player/PacketPlayerMiscellaneous.cpp b/components/openmw-mp/Packets/Player/PacketPlayerMiscellaneous.cpp index 6a6aa40f8..cffb6a446 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerMiscellaneous.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerMiscellaneous.cpp @@ -12,5 +12,15 @@ void PacketPlayerMiscellaneous::Packet(RakNet::BitStream *bs, bool send) { PlayerPacket::Packet(bs, send); - // Placeholder + RW(player->miscellaneousChangeType, send); + + if (player->miscellaneousChangeType == mwmp::MISCELLANEOUS_CHANGE_TYPE::MARK_LOCATION) + { + RW(player->markCell.mData, send, 1); + RW(player->markCell.mName, send, 1); + + RW(player->markPosition.pos, send); + RW(player->markPosition.rot[0], send); + RW(player->markPosition.rot[2], send); + } }