[General] Implement PlayerBook packet to track skill books read

This commit is contained in:
David Cernat 2017-06-27 08:27:14 +03:00
parent b3b73c5cd2
commit 813a3c89c4
13 changed files with 182 additions and 20 deletions

View file

@ -77,11 +77,11 @@ set(SERVER
Script/Functions/Actors.cpp Script/Functions/World.cpp Script/Functions/Miscellaneous.cpp Script/Functions/Actors.cpp Script/Functions/World.cpp Script/Functions/Miscellaneous.cpp
Script/Functions/Cells.cpp Script/Functions/CharClass.cpp Script/Functions/Chat.cpp Script/Functions/Books.cpp Script/Functions/Cells.cpp Script/Functions/CharClass.cpp
Script/Functions/Death.cpp Script/Functions/Dialogue.cpp Script/Functions/Factions.cpp Script/Functions/Chat.cpp Script/Functions/Death.cpp Script/Functions/Dialogue.cpp
Script/Functions/GUI.cpp Script/Functions/Items.cpp Script/Functions/Positions.cpp Script/Functions/Factions.cpp Script/Functions/GUI.cpp Script/Functions/Items.cpp
Script/Functions/Quests.cpp Script/Functions/Settings.cpp Script/Functions/Spells.cpp Script/Functions/Positions.cpp Script/Functions/Quests.cpp Script/Functions/Settings.cpp
Script/Functions/Stats.cpp Script/Functions/Timer.cpp Script/Functions/Spells.cpp Script/Functions/Stats.cpp Script/Functions/Timer.cpp
ProcessorInitializer.cpp PlayerProcessor.cpp ActorProcessor.cpp WorldProcessor.cpp ProcessorInitializer.cpp PlayerProcessor.cpp ActorProcessor.cpp WorldProcessor.cpp

View file

@ -77,6 +77,7 @@ public:
mwmp::FactionChanges factionChangesBuffer; mwmp::FactionChanges factionChangesBuffer;
mwmp::TopicChanges topicChangesBuffer; mwmp::TopicChanges topicChangesBuffer;
mwmp::KillChanges killChangesBuffer; mwmp::KillChanges killChangesBuffer;
mwmp::BookChanges bookChangesBuffer;
private: private:
CellController::TContainer cells; CellController::TContainer cells;

View file

@ -0,0 +1,48 @@
#include "Books.hpp"
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
#include <components/openmw-mp/NetworkMessages.hpp>
#include <apps/openmw-mp/Networking.hpp>
using namespace mwmp;
unsigned int BookFunctions::GetBookChangesSize(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->bookChanges.count;
}
void BookFunctions::AddBook(unsigned short pid, const char* bookId) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
mwmp::Book book;
book.bookId = bookId;
player->bookChangesBuffer.books.push_back(book);
}
const char *BookFunctions::GetBookId(unsigned short pid, unsigned int i) noexcept
{
Player *player;
GET_PLAYER(pid, player, "");
if (i >= player->bookChanges.count)
return "invalid";
return player->bookChanges.books.at(i).bookId.c_str();
}
void BookFunctions::SendBookChanges(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
std::swap(player->bookChanges, player->bookChangesBuffer);
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK)->setPlayer(player);
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK)->Send(false);
player->bookChanges = std::move(player->bookChangesBuffer);
player->bookChangesBuffer.books.clear();
}

View file

@ -0,0 +1,28 @@
#ifndef OPENMW_BOOKAPI_HPP
#define OPENMW_BOOKAPI_HPP
#define BOOKAPI \
{"GetBookChangesSize", BookFunctions::GetBookChangesSize},\
\
{"AddBook", BookFunctions::AddBook},\
\
{"GetBookId", BookFunctions::GetBookId},\
\
{"SendBookChanges", BookFunctions::SendBookChanges}
class BookFunctions
{
public:
static unsigned int GetBookChangesSize(unsigned short pid) noexcept;
static void AddBook(unsigned short pid, const char* bookId) noexcept;
static const char *GetBookId(unsigned short pid, unsigned int i) noexcept;
static void SendBookChanges(unsigned short pid) noexcept;
private:
};
#endif //OPENMW_BOOKAPI_HPP

View file

@ -2,7 +2,6 @@
#include <apps/openmw-mp/Script/ScriptFunctions.hpp> #include <apps/openmw-mp/Script/ScriptFunctions.hpp>
#include <components/openmw-mp/NetworkMessages.hpp> #include <components/openmw-mp/NetworkMessages.hpp>
#include <apps/openmw-mp/Networking.hpp> #include <apps/openmw-mp/Networking.hpp>
#include <components/misc/stringops.hpp>
using namespace mwmp; using namespace mwmp;

View file

@ -6,6 +6,7 @@
#define SCRIPTFUNCTIONS_HPP #define SCRIPTFUNCTIONS_HPP
#include <Script/Functions/Actors.hpp> #include <Script/Functions/Actors.hpp>
#include <Script/Functions/Books.hpp>
#include <Script/Functions/Cells.hpp> #include <Script/Functions/Cells.hpp>
#include <Script/Functions/CharClass.hpp> #include <Script/Functions/CharClass.hpp>
#include <Script/Functions/Death.hpp> #include <Script/Functions/Death.hpp>
@ -105,21 +106,22 @@ public:
{"CleanChatByPid", ScriptFunctions::CleanChatByPid}, {"CleanChatByPid", ScriptFunctions::CleanChatByPid},
{"CleanChat", ScriptFunctions::CleanChat}, {"CleanChat", ScriptFunctions::CleanChat},
POSITIONAPI, ACTORAPI,
BOOKAPI,
CELLAPI, CELLAPI,
STATAPI, CHARCLASSAPI,
ITEMAPI,
QUESTAPI,
FACTIONAPI,
DEATHAPI, DEATHAPI,
DIALOGUEAPI, DIALOGUEAPI,
SPELLAPI, FACTIONAPI,
GUIAPI, GUIAPI,
CHARCLASSAPI, ITEMAPI,
WORLDAPI, MISCELLANEOUSAPI,
ACTORAPI, POSITIONAPI,
QUESTAPI,
SETTINGSAPI, SETTINGSAPI,
MISCELLANEOUSAPI SPELLAPI,
STATAPI,
WORLDAPI
}; };
static constexpr ScriptCallbackData callbacks[]{ static constexpr ScriptCallbackData callbacks[]{

View file

@ -17,8 +17,6 @@ namespace mwmp
{ {
DEBUG_PRINTF(strPacketID.c_str()); DEBUG_PRINTF(strPacketID.c_str());
packet.Send(true);
Script::Call<Script::CallbackIdentity("OnPlayerBook")>(player.getId()); Script::Call<Script::CallbackIdentity("OnPlayerBook")>(player.getId());
} }
}; };

View file

@ -1025,6 +1025,20 @@ void LocalPlayer::setKills()
} }
} }
void LocalPlayer::setBooks()
{
MWWorld::Ptr player = getPlayerPtr();
MWMechanics::NpcStats &ptrNpcStats = player.getClass().getNpcStats(player);
for (unsigned int i = 0; i < bookChanges.count; i++)
{
mwmp::Book book = bookChanges.books.at(i);
std::string bookId = book.bookId;
ptrNpcStats.flagAsUsed(bookId);
}
}
void LocalPlayer::sendClass() void LocalPlayer::sendClass()
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1225,6 +1239,21 @@ void LocalPlayer::sendKill(const std::string& refId, int number)
getNetworking()->getPlayerPacket(ID_PLAYER_KILL_COUNT)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_KILL_COUNT)->Send();
} }
void LocalPlayer::sendBook(const std::string& bookId)
{
bookChanges.books.clear();
mwmp::Book book;
book.bookId = bookId;
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_PLAYER_BOOK with book %s", book.bookId.c_str());
bookChanges.books.push_back(book);
getNetworking()->getPlayerPacket(ID_PLAYER_BOOK)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_BOOK)->Send();
}
void LocalPlayer::clearCellStates() void LocalPlayer::clearCellStates()
{ {
cellStateChanges.cellStates.clear(); cellStateChanges.cellStates.clear();

View file

@ -60,6 +60,7 @@ namespace mwmp
void setSpellbook(); void setSpellbook();
void setFactions(); void setFactions();
void setKills(); void setKills();
void setBooks();
void sendClass(); void sendClass();
void sendInventory(); void sendInventory();
@ -74,6 +75,7 @@ namespace mwmp
void sendFaction(const std::string& factionId, int rank, bool isExpelled); void sendFaction(const std::string& factionId, int rank, bool isExpelled);
void sendTopic(const std::string& topic); void sendTopic(const std::string& topic);
void sendKill(const std::string& refId, int number); void sendKill(const std::string& refId, int number);
void sendBook(const std::string& bookId);
void clearCellStates(); void clearCellStates();
void clearCurrentContainer(); void clearCurrentContainer();

View file

@ -15,7 +15,10 @@ namespace mwmp
virtual void Do(PlayerPacket &packet, BasePlayer *player) virtual void Do(PlayerPacket &packet, BasePlayer *player)
{ {
// Placeholder to be filled in later if (isLocal())
{
static_cast<LocalPlayer*>(player)->setBooks();
}
} }
}; };
} }

View file

@ -1,5 +1,16 @@
#include "actionread.hpp" #include "actionread.hpp"
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
#include "../mwmp/Main.hpp"
#include "../mwmp/LocalPlayer.hpp"
/*
End of tes3mp addition
*/
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -57,6 +68,16 @@ namespace MWWorld
npcStats.increaseSkill (ref->mBase->mData.mSkillId, *class_, true); npcStats.increaseSkill (ref->mBase->mData.mSkillId, *class_, true);
npcStats.flagAsUsed (ref->mBase->mId); npcStats.flagAsUsed (ref->mBase->mId);
/*
Start of tes3mp addition
Send an ID_PLAYER_BOOK packet every time a player reads a skill book
*/
mwmp::Main::get().getLocalPlayer()->sendBook(ref->mBase->mId);
/*
End of tes3mp addition
*/
} }
} }

View file

@ -59,6 +59,11 @@ namespace mwmp
int number; int number;
}; };
struct Book
{
std::string bookId;
};
struct CellState struct CellState
{ {
ESM::Cell cell; ESM::Cell cell;
@ -96,6 +101,12 @@ namespace mwmp
unsigned int count; unsigned int count;
}; };
struct BookChanges
{
std::vector<Book> books;
unsigned int count;
};
struct InventoryChanges struct InventoryChanges
{ {
std::vector<Item> items; std::vector<Item> items;
@ -188,7 +199,9 @@ namespace mwmp
FactionChanges factionChanges; FactionChanges factionChanges;
TopicChanges topicChanges; TopicChanges topicChanges;
KillChanges killChanges; KillChanges killChanges;
BookChanges bookChanges;
CellStateChanges cellStateChanges; CellStateChanges cellStateChanges;
ESM::ActiveSpells activeSpells; ESM::ActiveSpells activeSpells;
CurrentContainer currentContainer; CurrentContainer currentContainer;

View file

@ -13,5 +13,23 @@ void PacketPlayerBook::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
// Placeholder to be filled in later if (send)
player->bookChanges.count = (unsigned int)(player->bookChanges.books.size());
else
player->bookChanges.books.clear();
RW(player->bookChanges.count, send);
for (unsigned int i = 0; i < player->bookChanges.count; i++)
{
Book book;
if (send)
book = player->bookChanges.books.at(i);
RW(book.bookId, send, 1);
if (!send)
player->bookChanges.books.push_back(book);
}
} }