forked from mirror/openmw-tes3mp
Implement spellbook
This commit is contained in:
parent
fba4878fee
commit
7595b33461
12 changed files with 121 additions and 24 deletions
|
@ -236,7 +236,22 @@ void Networking::processPlayerPacket(RakNet::Packet *packet)
|
|||
DEBUG_PRINTF("ID_GAME_SPELLBOOK\n");
|
||||
myPacket->Read(player);
|
||||
|
||||
Script::Call<Script::CallbackIdentity("OnPlayerChangeSpellbook")>(player->getId(), player->spellbook.action);
|
||||
string str;
|
||||
for (auto spell : player->spellbook.spells)
|
||||
{
|
||||
str += spell.mId;
|
||||
if (spell.mId != player->spellbook.spells.back().mId)
|
||||
str += ";";
|
||||
if (player->spellbook.action == Spellbook::ADD)
|
||||
player->realSpellbook.push_back(spell);
|
||||
else if (player->spellbook.action == Spellbook::REMOVE)
|
||||
{
|
||||
player->realSpellbook.erase(remove_if(player->realSpellbook.begin(), player->realSpellbook.end(), [&spell](ESM::Spell s)->bool
|
||||
{return spell.mId == s.mId; }), player->realSpellbook.end());
|
||||
}
|
||||
}
|
||||
|
||||
Script::Call<Script::CallbackIdentity("OnPlayerChangeSpellbook")>(player->getId(), player->spellbook.action, str.c_str());
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
public:
|
||||
mwmp::Inventory inventorySendBuffer;
|
||||
mwmp::Spellbook spellbookSendBuffer;
|
||||
std::vector<ESM::Spell> realSpellbook;
|
||||
|
||||
private:
|
||||
bool handshakeState;
|
||||
|
|
|
@ -11,7 +11,7 @@ unsigned int SpellFunctions::GetSpellbookSize(unsigned short pid) noexcept
|
|||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->spellbook.count;
|
||||
return player->realSpellbook.size();
|
||||
}
|
||||
|
||||
void SpellFunctions::AddSpell(unsigned short pid, const char* spellId) noexcept
|
||||
|
@ -19,8 +19,8 @@ void SpellFunctions::AddSpell(unsigned short pid, const char* spellId) noexcept
|
|||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
Spell spell;
|
||||
spell.id = spellId;
|
||||
ESM::Spell spell;
|
||||
spell.mId = spellId;
|
||||
|
||||
player->spellbookSendBuffer.spells.push_back(spell);
|
||||
player->spellbookSendBuffer.action = Spellbook::ADD;
|
||||
|
@ -31,8 +31,8 @@ void SpellFunctions::RemoveSpell(unsigned short pid, const char* spellId) noexce
|
|||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
Spell spell;
|
||||
spell.id = spellId;
|
||||
ESM::Spell spell;
|
||||
spell.mId = spellId;
|
||||
|
||||
player->spellbookSendBuffer.spells.push_back(spell);
|
||||
player->spellbookSendBuffer.action = Spellbook::REMOVE;
|
||||
|
@ -52,8 +52,8 @@ bool SpellFunctions::HasSpell(unsigned short pid, const char* spellId)
|
|||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
for (unsigned int i = 0; i < player->spellbook.count; i++)
|
||||
if (Misc::StringUtils::ciEqual(player->spellbook.spells.at(i).id, spellId))
|
||||
for (unsigned int i = 0; i < player->realSpellbook.size(); i++)
|
||||
if (Misc::StringUtils::ciEqual(player->realSpellbook.at(i).mId, spellId))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -63,16 +63,26 @@ const char *SpellFunctions::GetSpellId(unsigned short pid, unsigned int i) noexc
|
|||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->spellbook.count)
|
||||
if (i >= player->realSpellbook.size())
|
||||
return "invalid";
|
||||
|
||||
return player->spellbook.spells.at(i).id.c_str();
|
||||
return player->realSpellbook.at(i).mId.c_str();
|
||||
}
|
||||
|
||||
void SpellFunctions::SendSpellbook(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
for (auto spell : player->spellbookSendBuffer.spells)
|
||||
{
|
||||
if (player->spellbookSendBuffer.action == Spellbook::ADD)
|
||||
player->realSpellbook.push_back(spell);
|
||||
else if (player->spellbook.action == Spellbook::REMOVE)
|
||||
player->realSpellbook.erase(remove_if(player->realSpellbook.begin(), player->realSpellbook.end(), [&spell](ESM::Spell s)->bool
|
||||
{return spell.mId == s.mId; }), player->realSpellbook.end());
|
||||
}
|
||||
|
||||
std::swap(player->spellbook, player->spellbookSendBuffer);
|
||||
mwmp::Networking::get().getPlayerController()->GetPacket(ID_GAME_SPELLBOOK)->Send(player, false);
|
||||
player->spellbook = std::move(player->spellbookSendBuffer);
|
||||
|
|
|
@ -106,7 +106,7 @@ public:
|
|||
{"OnPlayerChangeLevel", Function<void, unsigned short>()},
|
||||
{"OnPlayerChangeEquipment", Function<void, unsigned short>()},
|
||||
{"OnPlayerChangeInventory", Function<void, unsigned short>()},
|
||||
{"OnPlayerChangeSpellbook", Function<void, unsigned short, int>()},
|
||||
{"OnPlayerChangeSpellbook", Function<void, unsigned short, int, const char*>()},
|
||||
{"OnPlayerSendMessage", Function<bool, unsigned short, const char*>()},
|
||||
{"OnPlayerEndCharGen", Function<void, unsigned short>()},
|
||||
{"OnGUIAction", Function<void, unsigned short, int, const char*>()}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
#include "../mwmp/Main.hpp"
|
||||
#include "../mwmp/LocalPlayer.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
const int SpellBuyingWindow::sLineHeight = 18;
|
||||
|
@ -140,6 +143,12 @@ namespace MWGui
|
|||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
spells.add (mSpellsWidgetMap.find(_sender)->second);
|
||||
|
||||
// Added by tes3mp
|
||||
//
|
||||
// LocalPlayer has gained a spell, so send a packet with it
|
||||
mwmp::Main::get().getLocalPlayer()->sendSpellAddition(mSpellsWidgetMap.find(_sender)->second);
|
||||
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
||||
|
||||
// add gold to NPC trading gold pool
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include <components/esm/records.hpp>
|
||||
#include <components/widgets/list.hpp>
|
||||
|
||||
#include "../mwmp/Main.hpp"
|
||||
#include "../mwmp/LocalPlayer.hpp"
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
@ -404,6 +407,11 @@ namespace MWGui
|
|||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
spells.add (spell->mId);
|
||||
|
||||
// Added by tes3mp
|
||||
//
|
||||
// LocalPlayer has gained a spell, so send a packet with it
|
||||
mwmp::Main::get().getLocalPlayer()->sendSpellAddition(*spell);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_SpellCreation);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include "confirmationdialog.hpp"
|
||||
#include "spellview.hpp"
|
||||
|
||||
#include"../mwmp/Main.hpp"
|
||||
#include"../mwmp/LocalPlayer.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
@ -186,6 +189,11 @@ namespace MWGui
|
|||
|
||||
spells.remove(mSpellToDelete);
|
||||
|
||||
// Added by tes3mp
|
||||
//
|
||||
// LocalPlayer has lost a spell, so send a packet with it
|
||||
mwmp::Main::get().getLocalPlayer()->sendSpellRemoval(mSpellToDelete);
|
||||
|
||||
updateSpells();
|
||||
}
|
||||
|
||||
|
|
|
@ -848,10 +848,13 @@ void LocalPlayer::sendInventory()
|
|||
|
||||
void LocalPlayer::sendSpellAddition(std::string id)
|
||||
{
|
||||
if (id.find("$dynamic") != string::npos) // skip custom spells
|
||||
return;
|
||||
|
||||
spellbook.spells.clear();
|
||||
|
||||
mwmp::Spell spell;
|
||||
spell.id = id;
|
||||
ESM::Spell spell;
|
||||
spell.mId = id;
|
||||
spellbook.spells.push_back(spell);
|
||||
|
||||
spellbook.action = Spellbook::ADD;
|
||||
|
@ -860,16 +863,29 @@ void LocalPlayer::sendSpellAddition(std::string id)
|
|||
|
||||
void LocalPlayer::sendSpellRemoval(std::string id)
|
||||
{
|
||||
if (id.find("$dynamic") != string::npos) // skip custom spells
|
||||
return;
|
||||
|
||||
spellbook.spells.clear();
|
||||
|
||||
mwmp::Spell spell;
|
||||
spell.id = id;
|
||||
ESM::Spell spell;
|
||||
spell.mId = id;
|
||||
spellbook.spells.push_back(spell);
|
||||
|
||||
spellbook.action = Spellbook::REMOVE;
|
||||
Main::get().getNetworking()->getPlayerPacket(ID_GAME_SPELLBOOK)->Send(this);
|
||||
}
|
||||
|
||||
void LocalPlayer::sendSpellAddition(const ESM::Spell &spell)
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Not implemented.");
|
||||
}
|
||||
|
||||
void LocalPlayer::sendSpellRemoval(const ESM::Spell &spell)
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Not implemented.");
|
||||
}
|
||||
|
||||
void LocalPlayer::sendAttack(Attack::TYPE type)
|
||||
{
|
||||
MWMechanics::DrawState_ state = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState();
|
||||
|
|
|
@ -48,7 +48,9 @@ namespace mwmp
|
|||
void sendClass();
|
||||
void sendInventory();
|
||||
void sendSpellAddition(std::string id);
|
||||
void sendSpellAddition(const ESM::Spell &spell);
|
||||
void sendSpellRemoval(std::string id);
|
||||
void sendSpellRemoval(const ESM::Spell &spell);
|
||||
void sendAttack(Attack::TYPE type);
|
||||
|
||||
void prepareAttack(Attack::TYPE type, bool state);
|
||||
|
|
|
@ -345,6 +345,38 @@ void Networking::processPlayerPacket(RakNet::Packet *packet)
|
|||
}
|
||||
case ID_GAME_SPELLBOOK:
|
||||
{
|
||||
if (guid == myGuid)
|
||||
{
|
||||
if (packet->length == myPacket->headerSize())
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
myPacket->Packet(&bsIn, getLocalPlayer(), false);
|
||||
const Spellbook& spellbook = getLocalPlayer()->spellbook;
|
||||
MWWorld::Ptr playerptr = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::Spells &spells = playerptr.getClass().getCreatureStats (playerptr).getSpells();
|
||||
if (spellbook.action == Spellbook::ADD)
|
||||
for (vector<ESM::Spell>::const_iterator spell = spellbook.spells.begin(); spell != spellbook.spells.end(); spell++)
|
||||
spells.add (spell->mId);
|
||||
else if (spellbook.action == Spellbook::REMOVE)
|
||||
for (vector<ESM::Spell>::const_iterator spell = spellbook.spells.begin(); spell != spellbook.spells.end(); spell++)
|
||||
{
|
||||
spells.remove (spell->mId);
|
||||
|
||||
MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager();
|
||||
if (spell->mId == wm->getSelectedSpell())
|
||||
wm->unsetSelectedSpell();
|
||||
}
|
||||
else // Spellbook::UPDATE
|
||||
{
|
||||
spells.clear();
|
||||
for (vector<ESM::Spell>::const_iterator spell = spellbook.spells.begin(); spell != spellbook.spells.end(); spell++)
|
||||
spells.add (spell->mId);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ID_GAME_ATTACK:
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <components/esm/loadnpc.hpp>
|
||||
#include <components/esm/creaturestats.hpp>
|
||||
#include <components/esm/loadclas.hpp>
|
||||
#include <components/esm/loadspel.hpp>
|
||||
#include <RakNetTypes.h>
|
||||
|
||||
namespace mwmp
|
||||
|
@ -58,14 +59,9 @@ namespace mwmp
|
|||
int action; //0 - FullUpdate, 1 - AddItem, 2 - RemoveItem
|
||||
};
|
||||
|
||||
struct Spell
|
||||
{
|
||||
std::string id;
|
||||
};
|
||||
|
||||
struct Spellbook
|
||||
{
|
||||
std::vector<Spell> spells;
|
||||
std::vector<ESM::Spell> spells;
|
||||
unsigned int count;
|
||||
enum ACTION_TYPE
|
||||
{
|
||||
|
|
|
@ -24,16 +24,16 @@ void PacketSpellbook::Packet(RakNet::BitStream *bs, BasePlayer *player, bool sen
|
|||
|
||||
for (unsigned int i = 0; i < player->spellbook.count; i++)
|
||||
{
|
||||
Spell spell;
|
||||
ESM::Spell spell;
|
||||
|
||||
if (send)
|
||||
{
|
||||
spell = player->spellbook.spells[i];
|
||||
RW(spell.id, send);
|
||||
RW(spell.mId, send);
|
||||
}
|
||||
else
|
||||
{
|
||||
RW(spell.id, send);
|
||||
RW(spell.mId, send);
|
||||
player->spellbook.spells.push_back(spell);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue